diff --git a/RELEASES.md b/RELEASES.md
index 2124195bcb20..c0851a1506e1 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -10,8 +10,7 @@ Language
Compiler
--------
-- [Added tier 3\* support for `powerpc-unknown-freebsd`.][87370]
-- [Added tier 3 support for `powerpc64le-unknown-freebsd`.][83572]
+- [Added tier 3\* support for `powerpc64le-unknown-freebsd`.][83572]
\* Refer to Rust's [platform support page][platform-support-doc] for more
information on Rust's tiered platform support.
@@ -24,17 +23,6 @@ Libraries
no longer reject certain valid floating point values, and reduce
the produced code size for non-stripped artifacts.
- [`string::Drain` now implements `AsRef` and `AsRef<[u8]>`.][86858]
-- [`collections::{BinaryHeap, BTreeSet, HashSet, LinkedList, VecDeque}` now
- implement `From<[T; N]>`.][84111]
-- [`collections::{BTreeMap, HashMap}` now implement `From<[(K, V); N]>`.][84111]
- This allows you to write the following;
- ```rust
- let highscores = std::collections::HashMap::from([
- ("Alice", 9000u32),
- ("Bob", 7250),
- ("Charlie", 5500),
- ]);
- ```
Stabilised APIs
---------------
@@ -60,7 +48,6 @@ Stabilised APIs
The following previously stable functions are now `const`.
- [`str::from_utf8_unchecked`]
-- [`mem::transmute`]
Cargo
@@ -131,7 +118,6 @@ Compatibility Notes
[`MaybeUninit::assume_init_ref`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init_ref
[`MaybeUninit::write`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.write
[`Seek::rewind`]: https://doc.rust-lang.org/stable/std/io/trait.Seek.html#method.rewind
-[`mem::transmute`]: https://doc.rust-lang.org/stable/std/mem/fn.transmute.html
[`ops::ControlFlow`]: https://doc.rust-lang.org/stable/std/ops/enum.ControlFlow.html
[`str::from_utf8_unchecked`]: https://doc.rust-lang.org/stable/std/str/fn.from_utf8_unchecked.html
[`x86::_bittest`]: https://doc.rust-lang.org/stable/core/arch/x86/fn._bittest.html
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 710a592e258b..3a65ffe41ae8 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -586,6 +586,13 @@ pub fn is_bool_lit(&self) -> bool {
self.is_non_raw_ident_where(|id| id.name.is_bool_lit())
}
+ pub fn is_numeric_lit(&self) -> bool {
+ matches!(
+ self.kind,
+ Literal(Lit { kind: LitKind::Integer, .. }) | Literal(Lit { kind: LitKind::Float, .. })
+ )
+ }
+
/// Returns `true` if the token is a non-raw identifier for which `pred` holds.
pub fn is_non_raw_ident_where(&self, pred: impl FnOnce(Ident) -> bool) -> bool {
match self.ident() {
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index 8e498a5446ea..efab0200ff50 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -104,7 +104,7 @@ macro_rules! declare_features {
(removed, quote, "1.33.0", Some(29601), None, None),
/// Allows const generic types (e.g. `struct Foo(...);`).
(removed, const_generics, "1.34.0", Some(44580), None,
- Some("removed in favor of `#![feature(adt_const_params]` and `#![feature(generic_const_exprs)]`")),
+ Some("removed in favor of `#![feature(adt_const_params)]` and `#![feature(generic_const_exprs)]`")),
/// Allows `[x; N]` where `x` is a constant (RFC 2203).
(removed, const_in_array_repeat_expressions, "1.37.0", Some(49147), None,
Some("removed due to causing promotable bugs")),
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index a1d3e9adba01..05156745105a 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -516,6 +516,26 @@ macro_rules! make_it {
token::BinOp(token::And) | token::AndAnd => {
make_it!(this, attrs, |this, _| this.parse_borrow_expr(lo))
}
+ token::BinOp(token::Plus) if this.look_ahead(1, |tok| tok.is_numeric_lit()) => {
+ let mut err = this.struct_span_err(lo, "leading `+` is not supported");
+ err.span_label(lo, "unexpected `+`");
+
+ // a block on the LHS might have been intended to be an expression instead
+ if let Some(sp) = this.sess.ambiguous_block_expr_parse.borrow().get(&lo) {
+ this.sess.expr_parentheses_needed(&mut err, *sp);
+ } else {
+ err.span_suggestion_verbose(
+ lo,
+ "try removing the `+`",
+ "".to_string(),
+ Applicability::MachineApplicable,
+ );
+ }
+ err.emit();
+
+ this.bump();
+ this.parse_prefix_expr(None)
+ } // `+expr`
token::Ident(..) if this.token.is_keyword(kw::Box) => {
make_it!(this, attrs, |this, _| this.parse_box_expr(lo))
}
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 46e64c33b84d..b6bb06f9d64b 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -1924,7 +1924,8 @@ pub const fn next_multiple_of(self, rhs: Self) -> Self {
}
/// Calculates the smallest value greater than or equal to `self` that
- /// is a multiple of `rhs`. If `rhs` is negative,
+ /// is a multiple of `rhs`. Returns `None` is `rhs` is zero or the
+ /// operation would result in overflow.
///
/// # Examples
///
diff --git a/library/core/src/ops/bit.rs b/library/core/src/ops/bit.rs
index 51f804381734..92f45ac9e7ea 100644
--- a/library/core/src/ops/bit.rs
+++ b/library/core/src/ops/bit.rs
@@ -30,6 +30,7 @@
/// ```
#[lang = "not"]
#[stable(feature = "rust1", since = "1.0.0")]
+#[doc(alias = "!")]
pub trait Not {
/// The resulting type after applying the `!` operator.
#[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 9d5e03dd0de7..907726f0c345 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -1173,7 +1173,7 @@ pub fn xor(self, optb: Option) -> Option {
// Entry-like operations to insert a value and return a reference
/////////////////////////////////////////////////////////////////////////
- /// Inserts `value` into the option then returns a mutable reference to it.
+ /// Inserts `value` into the option, then returns a mutable reference to it.
///
/// If the option already contains a value, the old value is dropped.
///
@@ -1397,7 +1397,7 @@ pub fn zip_with(self, other: Option, f: F) -> Option
}
impl Option<(T, U)> {
- /// Unzips an option containing a tuple of two options
+ /// Unzips an option containing a tuple of two options.
///
/// If `self` is `Some((a, b))` this method returns `(Some(a), Some(b))`.
/// Otherwise, `(None, None)` is returned.
@@ -1500,7 +1500,7 @@ pub fn cloned(self) -> Option {
}
impl Option {
- /// Returns the contained [`Some`] value or a default
+ /// Returns the contained [`Some`] value or a default.
///
/// Consumes the `self` argument then, if [`Some`], returns the contained
/// value, otherwise if [`None`], returns the [default value] for that
@@ -1561,7 +1561,7 @@ impl Option {
/// Converts from `Option` (or `&mut Option`) to `Option<&mut T::Target>`.
///
/// Leaves the original `Option` in-place, creating a new one containing a mutable reference to
- /// the inner type's `Deref::Target` type.
+ /// the inner type's [`Deref::Target`] type.
///
/// # Examples
///
@@ -1701,7 +1701,7 @@ fn into_iter(self) -> IterMut<'a, T> {
#[stable(since = "1.12.0", feature = "option_from")]
impl From for Option {
- /// Copies `val` into a new `Some`.
+ /// Moves `val` into a new [`Some`].
///
/// # Examples
///
@@ -1942,8 +1942,8 @@ unsafe impl TrustedLen for IntoIter {}
impl> FromIterator
"
);
- if ty_layout.layout.abi.is_unsized() {
- writeln!(w, "Size: (unsized)
");
- } else {
- let bytes = ty_layout.layout.size.bytes();
- writeln!(
- w,
- "Size: {size} byte{pl}
",
- size = bytes,
- pl = if bytes == 1 { "" } else { "s" },
- );
+ w.write_str("Size: ");
+ write_size_of_layout(w, ty_layout.layout, 0);
+ writeln!(w, "
");
+ if let Variants::Multiple { variants, tag, tag_encoding, .. } =
+ &ty_layout.layout.variants
+ {
+ if !variants.is_empty() {
+ w.write_str(
+ "Size for each variant:
\
+ ",
+ );
+
+ let adt = if let Adt(adt, _) = ty_layout.ty.kind() {
+ adt
+ } else {
+ span_bug!(tcx.def_span(ty_def_id), "not an adt")
+ };
+
+ let tag_size = if let TagEncoding::Niche { .. } = tag_encoding {
+ 0
+ } else if let Primitive::Int(i, _) = tag.value {
+ i.size().bytes()
+ } else {
+ span_bug!(tcx.def_span(ty_def_id), "tag is neither niche nor int")
+ };
+
+ for (index, layout) in variants.iter_enumerated() {
+ let ident = adt.variants[index].ident;
+ write!(w, "{name}: ", name = ident);
+ write_size_of_layout(w, layout, tag_size);
+ writeln!(w, " ");
+ }
+ w.write_str("
");
+ }
}
}
// This kind of layout error can occur with valid code, e.g. if you try to
diff --git a/src/test/rustdoc/type-layout.rs b/src/test/rustdoc/type-layout.rs
index 272911de6815..0868486fa59c 100644
--- a/src/test/rustdoc/type-layout.rs
+++ b/src/test/rustdoc/type-layout.rs
@@ -52,3 +52,21 @@ pub union Baz {
// @!has type_layout/trait.MyTrait.html 'Size: '
pub trait MyTrait {}
+
+// @has type_layout/enum.Variants.html 'Size: '
+// @has - '2 bytes'
+// @has - 'A: 0 bytes'
+// @has - 'B: 1 byte'
+pub enum Variants {
+ A,
+ B(u8),
+}
+
+// @has type_layout/enum.WithNiche.html 'Size: '
+// @has - //p '4 bytes'
+// @has - 'None: 0 bytes'
+// @has - 'Some: 4 bytes'
+pub enum WithNiche {
+ None,
+ Some(std::num::NonZeroU32),
+}
diff --git a/src/test/ui/associated-types/issue-36499.stderr b/src/test/ui/associated-types/issue-36499.stderr
index ff450f60acc6..610798d880f0 100644
--- a/src/test/ui/associated-types/issue-36499.stderr
+++ b/src/test/ui/associated-types/issue-36499.stderr
@@ -1,8 +1,14 @@
-error: expected expression, found `+`
+error: leading `+` is not supported
--> $DIR/issue-36499.rs:4:9
|
LL | 2 + +2;
- | ^ expected expression
+ | ^ unexpected `+`
+ |
+help: try removing the `+`
+ |
+LL - 2 + +2;
+LL + 2 + 2;
+ |
error: aborting due to previous error
diff --git a/src/test/ui/consts/issue-88649.rs b/src/test/ui/consts/issue-88649.rs
new file mode 100644
index 000000000000..43e562b5a7da
--- /dev/null
+++ b/src/test/ui/consts/issue-88649.rs
@@ -0,0 +1,18 @@
+// check-pass
+#![crate_type = "lib"]
+
+enum Foo {
+ Variant1(bool),
+ Variant2(bool),
+}
+
+const _: () = {
+ let mut n = 0;
+ while n < 2 {
+ match Foo::Variant1(true) {
+ Foo::Variant1(x) | Foo::Variant2(x) if x => {}
+ _ => {}
+ }
+ n += 1;
+ }
+};
diff --git a/src/test/ui/lifetimes/lifetime-errors/issue_74400.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/issue_74400.nll.stderr
new file mode 100644
index 000000000000..5a1294f948f1
--- /dev/null
+++ b/src/test/ui/lifetimes/lifetime-errors/issue_74400.nll.stderr
@@ -0,0 +1,30 @@
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/issue_74400.rs:12:5
+ |
+LL | f(data, identity)
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `T: 'static`...
+
+error[E0308]: mismatched types
+ --> $DIR/issue_74400.rs:12:5
+ |
+LL | f(data, identity)
+ | ^^^^^^^^^^^^^^^^^ one type is more general than the other
+ |
+ = note: expected type `for<'r> Fn<(&'r T,)>`
+ found type `Fn<(&T,)>`
+
+error: implementation of `FnOnce` is not general enough
+ --> $DIR/issue_74400.rs:12:5
+ |
+LL | f(data, identity)
+ | ^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
+ |
+ = note: `fn(&'2 T) -> &'2 T {identity::<&'2 T>}` must implement `FnOnce<(&'1 T,)>`, for any lifetime `'1`...
+ = note: ...but it actually implements `FnOnce<(&'2 T,)>`, for some specific lifetime `'2`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0308, E0310.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/lifetimes/lifetime-errors/issue_74400.rs b/src/test/ui/lifetimes/lifetime-errors/issue_74400.rs
new file mode 100644
index 000000000000..f83384524f71
--- /dev/null
+++ b/src/test/ui/lifetimes/lifetime-errors/issue_74400.rs
@@ -0,0 +1,13 @@
+//! Regression test for #74400: Type mismatch in function arguments E0631, E0271 are falsely
+//! recognized as E0308 mismatched types.
+
+use std::convert::identity;
+
+fn main() {}
+
+fn f(data: &[T], key: impl Fn(&T) -> S) {
+}
+
+fn g(data: &[T]) {
+ f(data, identity) //~ ERROR implementation of `FnOnce` is not general
+}
diff --git a/src/test/ui/lifetimes/lifetime-errors/issue_74400.stderr b/src/test/ui/lifetimes/lifetime-errors/issue_74400.stderr
new file mode 100644
index 000000000000..d972861a2b56
--- /dev/null
+++ b/src/test/ui/lifetimes/lifetime-errors/issue_74400.stderr
@@ -0,0 +1,11 @@
+error: implementation of `FnOnce` is not general enough
+ --> $DIR/issue_74400.rs:12:5
+ |
+LL | f(data, identity)
+ | ^ implementation of `FnOnce` is not general enough
+ |
+ = note: `fn(&'2 T) -> &'2 T {identity::<&'2 T>}` must implement `FnOnce<(&'1 T,)>`, for any lifetime `'1`...
+ = note: ...but it actually implements `FnOnce<(&'2 T,)>`, for some specific lifetime `'2`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/expr-as-stmt.fixed b/src/test/ui/parser/expr-as-stmt.fixed
index c217ab9774fd..5f5e25991e0c 100644
--- a/src/test/ui/parser/expr-as-stmt.fixed
+++ b/src/test/ui/parser/expr-as-stmt.fixed
@@ -10,7 +10,7 @@ fn foo() -> i32 {
}
fn bar() -> i32 {
- ({2}) + 2 //~ ERROR expected expression, found `+`
+ ({2}) + 2 //~ ERROR leading `+` is not supported
//~^ ERROR mismatched types
}
diff --git a/src/test/ui/parser/expr-as-stmt.rs b/src/test/ui/parser/expr-as-stmt.rs
index b04025faaec6..5428e1c32fed 100644
--- a/src/test/ui/parser/expr-as-stmt.rs
+++ b/src/test/ui/parser/expr-as-stmt.rs
@@ -10,7 +10,7 @@ fn foo() -> i32 {
}
fn bar() -> i32 {
- {2} + 2 //~ ERROR expected expression, found `+`
+ {2} + 2 //~ ERROR leading `+` is not supported
//~^ ERROR mismatched types
}
diff --git a/src/test/ui/parser/expr-as-stmt.stderr b/src/test/ui/parser/expr-as-stmt.stderr
index ba5cd01abfcc..d99e9be0000c 100644
--- a/src/test/ui/parser/expr-as-stmt.stderr
+++ b/src/test/ui/parser/expr-as-stmt.stderr
@@ -9,11 +9,11 @@ help: parentheses are required to parse this as an expression
LL | ({2}) + {2}
| + +
-error: expected expression, found `+`
+error: leading `+` is not supported
--> $DIR/expr-as-stmt.rs:13:9
|
LL | {2} + 2
- | ^ expected expression
+ | ^ unexpected `+`
|
help: parentheses are required to parse this as an expression
|
diff --git a/src/test/ui/parser/issue-88276-unary-plus.fixed b/src/test/ui/parser/issue-88276-unary-plus.fixed
new file mode 100644
index 000000000000..25b7c340f600
--- /dev/null
+++ b/src/test/ui/parser/issue-88276-unary-plus.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+#[allow(unused_parens)]
+fn main() {
+ let _ = 1; //~ ERROR leading `+` is not supported
+ let _ = (1.0 + 2.0) * 3.0; //~ ERROR leading `+` is not supported
+ //~| ERROR leading `+` is not supported
+ let _ = [3, 4+6]; //~ ERROR leading `+` is not supported
+}
diff --git a/src/test/ui/parser/issue-88276-unary-plus.rs b/src/test/ui/parser/issue-88276-unary-plus.rs
new file mode 100644
index 000000000000..11b2e9d60165
--- /dev/null
+++ b/src/test/ui/parser/issue-88276-unary-plus.rs
@@ -0,0 +1,8 @@
+// run-rustfix
+#[allow(unused_parens)]
+fn main() {
+ let _ = +1; //~ ERROR leading `+` is not supported
+ let _ = (1.0 + +2.0) * +3.0; //~ ERROR leading `+` is not supported
+ //~| ERROR leading `+` is not supported
+ let _ = [+3, 4+6]; //~ ERROR leading `+` is not supported
+}
diff --git a/src/test/ui/parser/issue-88276-unary-plus.stderr b/src/test/ui/parser/issue-88276-unary-plus.stderr
new file mode 100644
index 000000000000..b26761729a83
--- /dev/null
+++ b/src/test/ui/parser/issue-88276-unary-plus.stderr
@@ -0,0 +1,50 @@
+error: leading `+` is not supported
+ --> $DIR/issue-88276-unary-plus.rs:4:13
+ |
+LL | let _ = +1;
+ | ^ unexpected `+`
+ |
+help: try removing the `+`
+ |
+LL - let _ = +1;
+LL + let _ = 1;
+ |
+
+error: leading `+` is not supported
+ --> $DIR/issue-88276-unary-plus.rs:5:20
+ |
+LL | let _ = (1.0 + +2.0) * +3.0;
+ | ^ unexpected `+`
+ |
+help: try removing the `+`
+ |
+LL - let _ = (1.0 + +2.0) * +3.0;
+LL + let _ = (1.0 + 2.0) * +3.0;
+ |
+
+error: leading `+` is not supported
+ --> $DIR/issue-88276-unary-plus.rs:5:28
+ |
+LL | let _ = (1.0 + +2.0) * +3.0;
+ | ^ unexpected `+`
+ |
+help: try removing the `+`
+ |
+LL - let _ = (1.0 + +2.0) * +3.0;
+LL + let _ = (1.0 + +2.0) * 3.0;
+ |
+
+error: leading `+` is not supported
+ --> $DIR/issue-88276-unary-plus.rs:7:14
+ |
+LL | let _ = [+3, 4+6];
+ | ^ unexpected `+`
+ |
+help: try removing the `+`
+ |
+LL - let _ = [+3, 4+6];
+LL + let _ = [3, 4+6];
+ |
+
+error: aborting due to 4 previous errors
+