From 2326f42ce2529330ffbd1b865b90338bd4bf17fd Mon Sep 17 00:00:00 2001 From: Dylan DPC Date: Tue, 25 Oct 2022 18:07:21 +0530 Subject: [PATCH 01/19] stabilise array methods --- library/alloc/src/lib.rs | 1 - library/core/src/array/mod.rs | 9 ++------- library/core/tests/lib.rs | 1 - src/librustdoc/lib.rs | 1 - 4 files changed, 2 insertions(+), 10 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index ce36b116f139b..a222871a84650 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -92,7 +92,6 @@ #![feature(allocator_api)] #![feature(array_chunks)] #![feature(array_into_iter_constructors)] -#![feature(array_methods)] #![feature(array_windows)] #![feature(assert_matches)] #![feature(async_iterator)] diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index eae0e1c761866..5fbf15f1a28ba 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -592,8 +592,6 @@ impl [T; N] { /// # Example /// /// ``` - /// #![feature(array_methods)] - /// /// let floats = [3.1, 2.7, -1.0]; /// let float_refs: [&f64; 3] = floats.each_ref(); /// assert_eq!(float_refs, [&3.1, &2.7, &-1.0]); @@ -604,8 +602,6 @@ impl [T; N] { /// array if its elements are not [`Copy`]. /// /// ``` - /// #![feature(array_methods)] - /// /// let strings = ["Ferris".to_string(), "♥".to_string(), "Rust".to_string()]; /// let is_ascii = strings.each_ref().map(|s| s.is_ascii()); /// assert_eq!(is_ascii, [true, false, true]); @@ -613,7 +609,7 @@ impl [T; N] { /// // We can still access the original array: it has not been moved. /// assert_eq!(strings.len(), 3); /// ``` - #[unstable(feature = "array_methods", issue = "76118")] + #[stable(feature = "array_methods", since = "CURRENT_RUSTC_VERSION")] pub fn each_ref(&self) -> [&T; N] { // SAFETY: we know for certain that this iterator will yield exactly `N` // items. @@ -627,7 +623,6 @@ impl [T; N] { /// # Example /// /// ``` - /// #![feature(array_methods)] /// /// let mut floats = [3.1, 2.7, -1.0]; /// let float_refs: [&mut f64; 3] = floats.each_mut(); @@ -635,7 +630,7 @@ impl [T; N] { /// assert_eq!(float_refs, [&mut 0.0, &mut 2.7, &mut -1.0]); /// assert_eq!(floats, [0.0, 2.7, -1.0]); /// ``` - #[unstable(feature = "array_methods", issue = "76118")] + #[stable(feature = "array_methods", since = "CURRENT_RUSTC_VERSION")] pub fn each_mut(&mut self) -> [&mut T; N] { // SAFETY: we know for certain that this iterator will yield exactly `N` // items. diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 3012a78b9c98e..dda8d27605b7e 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -1,6 +1,5 @@ #![feature(alloc_layout_extra)] #![feature(array_chunks)] -#![feature(array_methods)] #![feature(array_windows)] #![feature(bigint_helper_methods)] #![feature(cell_update)] diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 793061a9f7a06..f6b065505530c 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -3,7 +3,6 @@ html_playground_url = "https://play.rust-lang.org/" )] #![feature(rustc_private)] -#![feature(array_methods)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(control_flow_enum)] From bab8d29887a0d801fe72f922dafe75a635bc9198 Mon Sep 17 00:00:00 2001 From: Tristan Guichaoua Date: Sat, 8 Jul 2023 19:55:33 +0200 Subject: [PATCH 02/19] impl `From<&[T; N]>` for `Cow<[T]>` --- library/alloc/src/vec/cow.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/library/alloc/src/vec/cow.rs b/library/alloc/src/vec/cow.rs index 2c799605b7b67..7d2462ee32e0c 100644 --- a/library/alloc/src/vec/cow.rs +++ b/library/alloc/src/vec/cow.rs @@ -15,6 +15,19 @@ impl<'a, T: Clone> From<&'a [T]> for Cow<'a, [T]> { } } +#[unstable(feature = "cow_from_array_ref", issue = "none")] +impl<'a, T: Clone, const N: usize> From<&'a [T; N]> for Cow<'a, [T]> { + /// Creates a [`Borrowed`] variant of [`Cow`] + /// from a reference to an array. + /// + /// This conversion does not allocate or clone the data. + /// + /// [`Borrowed`]: crate::borrow::Cow::Borrowed + fn from(s: &'a [T; N]) -> Cow<'a, [T]> { + Cow::Borrowed(s as &[_]) + } +} + #[stable(feature = "cow_from_vec", since = "1.8.0")] impl<'a, T: Clone> From> for Cow<'a, [T]> { /// Creates an [`Owned`] variant of [`Cow`] From 6bfad315265cc36d461dedf19f64e445c872da0c Mon Sep 17 00:00:00 2001 From: Tristan Guichaoua Date: Sat, 8 Jul 2023 20:11:47 +0200 Subject: [PATCH 03/19] mark as stable --- library/alloc/src/vec/cow.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/vec/cow.rs b/library/alloc/src/vec/cow.rs index 7d2462ee32e0c..b12910f3690b5 100644 --- a/library/alloc/src/vec/cow.rs +++ b/library/alloc/src/vec/cow.rs @@ -15,7 +15,7 @@ impl<'a, T: Clone> From<&'a [T]> for Cow<'a, [T]> { } } -#[unstable(feature = "cow_from_array_ref", issue = "none")] +#[stable(feature = "cow_from_array_ref", since = "CURRENT_RUSTC_VERSION")] impl<'a, T: Clone, const N: usize> From<&'a [T; N]> for Cow<'a, [T]> { /// Creates a [`Borrowed`] variant of [`Cow`] /// from a reference to an array. From 6dd0772707eb50a8129eb0a748cd9ef3de6a754a Mon Sep 17 00:00:00 2001 From: sjwang05 <63834813+sjwang05@users.noreply.github.com> Date: Fri, 22 Dec 2023 21:56:58 -0800 Subject: [PATCH 04/19] Emit suggestion when trying to write exclusive ranges as `..<` --- .../rustc_parse/src/parser/diagnostics.rs | 25 ++++++++-- compiler/rustc_parse/src/parser/expr.rs | 10 +++- tests/ui/parser/range-exclusive-dotdotlt.rs | 43 +++++++++++++++++ .../ui/parser/range-exclusive-dotdotlt.stderr | 46 +++++++++++++++++++ 4 files changed, 117 insertions(+), 7 deletions(-) create mode 100644 tests/ui/parser/range-exclusive-dotdotlt.rs create mode 100644 tests/ui/parser/range-exclusive-dotdotlt.stderr diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index a9cf26d991c71..dc7a4d5aa3831 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -23,7 +23,7 @@ use crate::parser; use crate::parser::attr::InnerAttrPolicy; use rustc_ast as ast; use rustc_ast::ptr::P; -use rustc_ast::token::{self, Delimiter, Lit, LitKind, TokenKind}; +use rustc_ast::token::{self, Delimiter, Lit, LitKind, Token, TokenKind}; use rustc_ast::tokenstream::AttrTokenTree; use rustc_ast::util::parser::AssocOp; use rustc_ast::{ @@ -448,12 +448,11 @@ impl<'a> Parser<'a> { }) } - let mut expected = edible + self.expected_tokens.extend(edible.iter().chain(inedible).cloned().map(TokenType::Token)); + let mut expected = self + .expected_tokens .iter() - .chain(inedible) .cloned() - .map(TokenType::Token) - .chain(self.expected_tokens.iter().cloned()) .filter(|token| { // Filter out suggestions that suggest the same token which was found and deemed incorrect. fn is_ident_eq_keyword(found: &TokenKind, expected: &TokenType) -> bool { @@ -2927,6 +2926,22 @@ impl<'a> Parser<'a> { Ok(()) } + /// Check for exclusive ranges written as `..<` + pub(crate) fn maybe_err_dotdotlt_syntax(&self, maybe_lt: Token, mut err: PErr<'a>) -> PErr<'a> { + if maybe_lt == token::Lt + && (self.expected_tokens.contains(&TokenType::Token(token::Gt)) + || matches!(self.token.kind, token::Literal(..))) + { + err.span_suggestion( + maybe_lt.span, + "remove the `<` to write an exclusive range", + "", + Applicability::MachineApplicable, + ); + } + err + } + pub fn is_diff_marker(&mut self, long_kind: &TokenKind, short_kind: &TokenKind) -> bool { (0..3).all(|i| self.look_ahead(i, |tok| tok == long_kind)) && self.look_ahead(3, |tok| tok == short_kind) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index db777266b59d2..7f4d26b370f1a 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -483,7 +483,11 @@ impl<'a> Parser<'a> { cur_op_span: Span, ) -> PResult<'a, P> { let rhs = if self.is_at_start_of_range_notation_rhs() { - Some(self.parse_expr_assoc_with(prec + 1, LhsExpr::NotYetParsed)?) + let maybe_lt = self.token.clone(); + Some( + self.parse_expr_assoc_with(prec + 1, LhsExpr::NotYetParsed) + .map_err(|err| self.maybe_err_dotdotlt_syntax(maybe_lt, err))?, + ) } else { None }; @@ -532,11 +536,13 @@ impl<'a> Parser<'a> { let attrs = self.parse_or_use_outer_attributes(attrs)?; self.collect_tokens_for_expr(attrs, |this, attrs| { let lo = this.token.span; + let maybe_lt = this.look_ahead(1, |t| t.clone()); this.bump(); let (span, opt_end) = if this.is_at_start_of_range_notation_rhs() { // RHS must be parsed with more associativity than the dots. this.parse_expr_assoc_with(op.unwrap().precedence() + 1, LhsExpr::NotYetParsed) - .map(|x| (lo.to(x.span), Some(x)))? + .map(|x| (lo.to(x.span), Some(x))) + .map_err(|err| this.maybe_err_dotdotlt_syntax(maybe_lt, err))? } else { (lo, None) }; diff --git a/tests/ui/parser/range-exclusive-dotdotlt.rs b/tests/ui/parser/range-exclusive-dotdotlt.rs new file mode 100644 index 0000000000000..5752566026f02 --- /dev/null +++ b/tests/ui/parser/range-exclusive-dotdotlt.rs @@ -0,0 +1,43 @@ +fn foo() { + let _ = 0..<10; + //~^ ERROR: expected type, found `10` + //~| HELP: remove the `<` to write an exclusive range +} + +fn bar() { + let _ = 0..`, or `as`, found `;` + //~| HELP: remove the `<` to write an exclusive range +} + +fn baz() { + let _ = ; + //~^ ERROR: expected `::`, found `;` +} + +fn qux() { + let _ = [1, 2, 3][..<1]; + //~^ ERROR: expected type, found `1` + //~| HELP: remove the `<` to write an exclusive range +} + +fn quux() { + let _ = [1, 2, 3][..`, or `as`, found `]` + //~| HELP: remove the `<` to write an exclusive range +} + +fn foobar() { + let _ = [1, 2, 3][..]; + //~^ ERROR: expected `::`, found `]` +} + +fn ok1() { + let _ = [1, 2, 3][..::default()]; +} + +fn ok2() { + let _ = 0..::default(); +} + +fn main() {} diff --git a/tests/ui/parser/range-exclusive-dotdotlt.stderr b/tests/ui/parser/range-exclusive-dotdotlt.stderr new file mode 100644 index 0000000000000..af25e1df343de --- /dev/null +++ b/tests/ui/parser/range-exclusive-dotdotlt.stderr @@ -0,0 +1,46 @@ +error: expected type, found `10` + --> $DIR/range-exclusive-dotdotlt.rs:2:17 + | +LL | let _ = 0..<10; + | -^^ expected type + | | + | help: remove the `<` to write an exclusive range + +error: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `;` + --> $DIR/range-exclusive-dotdotlt.rs:8:20 + | +LL | let _ = 0.. $DIR/range-exclusive-dotdotlt.rs:14:18 + | +LL | let _ = ; + | ^ expected `::` + +error: expected type, found `1` + --> $DIR/range-exclusive-dotdotlt.rs:19:26 + | +LL | let _ = [1, 2, 3][..<1]; + | -^ expected type + | | + | help: remove the `<` to write an exclusive range + +error: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `]` + --> $DIR/range-exclusive-dotdotlt.rs:25:29 + | +LL | let _ = [1, 2, 3][.. $DIR/range-exclusive-dotdotlt.rs:31:30 + | +LL | let _ = [1, 2, 3][..]; + | ^ expected `::` + +error: aborting due to 6 previous errors + From 281ceb2bd2b2dd5f6ac201f585a2de2d21a41250 Mon Sep 17 00:00:00 2001 From: ardi Date: Wed, 10 Jan 2024 10:26:18 +0100 Subject: [PATCH 05/19] Document the struct and a few methods --- compiler/rustc_index/src/vec.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 66c5cc774b224..3148b054790fc 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -12,10 +12,26 @@ use std::vec; use crate::{Idx, IndexSlice}; /// An owned contiguous collection of `T`s, indexed by `I` rather than by `usize`. +/// Its purpose is to avoid mixing indexes. /// /// While it's possible to use `u32` or `usize` directly for `I`, /// you almost certainly want to use a [`newtype_index!`]-generated type instead. /// +/// This allows to index the IndexVec with the new index type: +/// +/// ``` +/// use crate as rustc_index; +/// use rustc_index::{IndexVec, newtype_index}; +/// +/// newtype_index! { +/// pub struct MyIdx {} +/// } +/// +/// let my_index_vec: IndexVec = IndexVec::from_raw(vec![0,1,2,3]); +/// let idx: MyIdx = MyIdx::from_u32(2); +/// assert_eq!(my_index_vec[idx], 2); +/// ``` +/// /// [`newtype_index!`]: ../macro.newtype_index.html #[derive(Clone, PartialEq, Eq, Hash)] #[repr(transparent)] @@ -25,11 +41,13 @@ pub struct IndexVec { } impl IndexVec { + /// Constructs a new, empty `IndexVec`. #[inline] pub const fn new() -> Self { IndexVec::from_raw(Vec::new()) } + /// Constructs a new `IndexVec` from a `Vec` #[inline] pub const fn from_raw(raw: Vec) -> Self { IndexVec { raw, _marker: PhantomData } @@ -59,6 +77,7 @@ impl IndexVec { IndexVec::from_raw(vec![elem; universe.len()]) } + /// Creates a new `IndexVec` with n copies of `elem` #[inline] pub fn from_elem_n(elem: T, n: usize) -> Self where From 1bf3aee3811b92d5833154fd35b98159a233b938 Mon Sep 17 00:00:00 2001 From: ardi Date: Wed, 10 Jan 2024 11:17:46 +0100 Subject: [PATCH 06/19] Oh well --- compiler/rustc_index/src/vec.rs | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 3148b054790fc..3c66e6dde1c2e 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -17,27 +17,15 @@ use crate::{Idx, IndexSlice}; /// While it's possible to use `u32` or `usize` directly for `I`, /// you almost certainly want to use a [`newtype_index!`]-generated type instead. /// -/// This allows to index the IndexVec with the new index type: +/// This allows to index the IndexVec with the new index type /// -/// ``` -/// use crate as rustc_index; -/// use rustc_index::{IndexVec, newtype_index}; -/// -/// newtype_index! { -/// pub struct MyIdx {} -/// } -/// -/// let my_index_vec: IndexVec = IndexVec::from_raw(vec![0,1,2,3]); -/// let idx: MyIdx = MyIdx::from_u32(2); -/// assert_eq!(my_index_vec[idx], 2); -/// ``` /// /// [`newtype_index!`]: ../macro.newtype_index.html #[derive(Clone, PartialEq, Eq, Hash)] #[repr(transparent)] pub struct IndexVec { pub raw: Vec, - _marker: PhantomData, + _marker: PhantomData, } impl IndexVec { @@ -77,7 +65,7 @@ impl IndexVec { IndexVec::from_raw(vec![elem; universe.len()]) } - /// Creates a new `IndexVec` with n copies of `elem` + /// Creates a new IndexVec #[inline] pub fn from_elem_n(elem: T, n: usize) -> Self where From ee8510e4e13e723639e904cdc218e6f3013f0bb4 Mon Sep 17 00:00:00 2001 From: ardi Date: Wed, 10 Jan 2024 18:28:42 +0100 Subject: [PATCH 07/19] Fix some mistakes + new doc --- compiler/rustc_index/src/vec.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 3c66e6dde1c2e..73265eb89961c 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -17,15 +17,13 @@ use crate::{Idx, IndexSlice}; /// While it's possible to use `u32` or `usize` directly for `I`, /// you almost certainly want to use a [`newtype_index!`]-generated type instead. /// -/// This allows to index the IndexVec with the new index type -/// -/// +/// This allows to index the IndexVec with the new index type. /// [`newtype_index!`]: ../macro.newtype_index.html #[derive(Clone, PartialEq, Eq, Hash)] #[repr(transparent)] pub struct IndexVec { pub raw: Vec, - _marker: PhantomData, + _marker: PhantomData, } impl IndexVec { @@ -35,7 +33,7 @@ impl IndexVec { IndexVec::from_raw(Vec::new()) } - /// Constructs a new `IndexVec` from a `Vec` + /// Constructs a new `IndexVec` from a `Vec`. #[inline] pub const fn from_raw(raw: Vec) -> Self { IndexVec { raw, _marker: PhantomData } @@ -65,7 +63,7 @@ impl IndexVec { IndexVec::from_raw(vec![elem; universe.len()]) } - /// Creates a new IndexVec + /// Creates a new IndexVec with n copies of the `elem`. #[inline] pub fn from_elem_n(elem: T, n: usize) -> Self where @@ -92,6 +90,7 @@ impl IndexVec { IndexSlice::from_raw_mut(&mut self.raw) } + /// Pushes an element to the array returning the index where it was pushed to. #[inline] pub fn push(&mut self, d: T) -> I { let idx = self.next_index(); From bc3fb5245a248070b76e535be4f342e2be12a9b5 Mon Sep 17 00:00:00 2001 From: LegionMammal978 Date: Tue, 16 Jan 2024 14:58:42 -0500 Subject: [PATCH 08/19] Rename `pointer` field on `Pin` The internal, unstable field of `Pin` can conflict with fields from the inner type accessed via the `Deref` impl. Rename it from `pointer` to `__pointer`, to make it less likely to conflict with anything else. --- .../src/fn_ctxt/suggestions.rs | 2 +- library/core/src/pin.rs | 46 +++++++++++-------- src/etc/natvis/libcore.natvis | 4 +- ...ine_coroutine.main.Inline.panic-abort.diff | 2 +- ...ne_coroutine.main.Inline.panic-unwind.diff | 2 +- .../feature-gate-unsafe_pin_internals.rs | 2 +- tests/ui/pin-macro/cant_access_internals.rs | 2 +- .../ui/pin-macro/cant_access_internals.stderr | 4 +- 8 files changed, 35 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 81b7de7f63497..83c544a9605bd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -2038,7 +2038,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let field_is_local = sole_field.did.is_local(); let field_is_accessible = sole_field.vis.is_accessible_from(expr.hir_id.owner.def_id, self.tcx) - // Skip suggestions for unstable public fields (for example `Pin::pointer`) + // Skip suggestions for unstable public fields (for example `Pin::__pointer`) && matches!(self.tcx.eval_stability(sole_field.did, None, expr.span, None), EvalResult::Allow | EvalResult::Unmarked); if !field_is_local && !field_is_accessible { diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index bb6c81a486a59..a0227d9130bb7 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -1092,14 +1092,20 @@ pub struct Pin { // - deter downstream users from accessing it (which would be unsound!), // - let the `pin!` macro access it (such a macro requires using struct // literal syntax in order to benefit from lifetime extension). - // Long-term, `unsafe` fields or macro hygiene are expected to offer more robust alternatives. + // + // However, if the `Deref` impl exposes a field with the same name as this + // field, then the two will collide, resulting in a confusing error when the + // user attempts to access the field through a `Pin`. Therefore, the + // name `__pointer` is designed to be unlikely to collide with any other + // field. Long-term, macro hygiene is expected to offer a more robust + // alternative, alongside `unsafe` fields. #[unstable(feature = "unsafe_pin_internals", issue = "none")] #[doc(hidden)] - pub pointer: Ptr, + pub __pointer: Ptr, } // The following implementations aren't derived in order to avoid soundness -// issues. `&self.pointer` should not be accessible to untrusted trait +// issues. `&self.__pointer` should not be accessible to untrusted trait // implementations. // // See for more details. @@ -1212,7 +1218,7 @@ impl> Pin { #[rustc_const_unstable(feature = "const_pin", issue = "76654")] #[stable(feature = "pin_into_inner", since = "1.39.0")] pub const fn into_inner(pin: Pin) -> Ptr { - pin.pointer + pin.__pointer } } @@ -1349,7 +1355,7 @@ impl Pin { #[rustc_const_unstable(feature = "const_pin", issue = "76654")] #[stable(feature = "pin", since = "1.33.0")] pub const unsafe fn new_unchecked(pointer: Ptr) -> Pin { - Pin { pointer } + Pin { __pointer: pointer } } /// Gets a shared reference to the pinned value this [`Pin`] points to. @@ -1363,7 +1369,7 @@ impl Pin { #[inline(always)] pub fn as_ref(&self) -> Pin<&Ptr::Target> { // SAFETY: see documentation on this function - unsafe { Pin::new_unchecked(&*self.pointer) } + unsafe { Pin::new_unchecked(&*self.__pointer) } } /// Unwraps this `Pin`, returning the underlying `Ptr`. @@ -1388,7 +1394,7 @@ impl Pin { #[rustc_const_unstable(feature = "const_pin", issue = "76654")] #[stable(feature = "pin_into_inner", since = "1.39.0")] pub const unsafe fn into_inner_unchecked(pin: Pin) -> Ptr { - pin.pointer + pin.__pointer } } @@ -1426,7 +1432,7 @@ impl Pin { #[inline(always)] pub fn as_mut(&mut self) -> Pin<&mut Ptr::Target> { // SAFETY: see documentation on this function - unsafe { Pin::new_unchecked(&mut *self.pointer) } + unsafe { Pin::new_unchecked(&mut *self.__pointer) } } /// Assigns a new value to the memory location pointed to by the `Pin`. @@ -1455,7 +1461,7 @@ impl Pin { where Ptr::Target: Sized, { - *(self.pointer) = value; + *(self.__pointer) = value; } } @@ -1481,7 +1487,7 @@ impl<'a, T: ?Sized> Pin<&'a T> { U: ?Sized, F: FnOnce(&T) -> &U, { - let pointer = &*self.pointer; + let pointer = &*self.__pointer; let new_pointer = func(pointer); // SAFETY: the safety contract for `new_unchecked` must be @@ -1511,7 +1517,7 @@ impl<'a, T: ?Sized> Pin<&'a T> { #[rustc_const_unstable(feature = "const_pin", issue = "76654")] #[stable(feature = "pin", since = "1.33.0")] pub const fn get_ref(self) -> &'a T { - self.pointer + self.__pointer } } @@ -1522,7 +1528,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { #[rustc_const_unstable(feature = "const_pin", issue = "76654")] #[stable(feature = "pin", since = "1.33.0")] pub const fn into_ref(self) -> Pin<&'a T> { - Pin { pointer: self.pointer } + Pin { __pointer: self.__pointer } } /// Gets a mutable reference to the data inside of this `Pin`. @@ -1542,7 +1548,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { where T: Unpin, { - self.pointer + self.__pointer } /// Gets a mutable reference to the data inside of this `Pin`. @@ -1560,7 +1566,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { #[stable(feature = "pin", since = "1.33.0")] #[rustc_const_unstable(feature = "const_pin", issue = "76654")] pub const unsafe fn get_unchecked_mut(self) -> &'a mut T { - self.pointer + self.__pointer } /// Construct a new pin by mapping the interior value. @@ -1684,21 +1690,21 @@ impl Receiver for Pin {} #[stable(feature = "pin", since = "1.33.0")] impl fmt::Debug for Pin { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&self.pointer, f) + fmt::Debug::fmt(&self.__pointer, f) } } #[stable(feature = "pin", since = "1.33.0")] impl fmt::Display for Pin { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.pointer, f) + fmt::Display::fmt(&self.__pointer, f) } } #[stable(feature = "pin", since = "1.33.0")] impl fmt::Pointer for Pin { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Pointer::fmt(&self.pointer, f) + fmt::Pointer::fmt(&self.__pointer, f) } } @@ -1941,16 +1947,16 @@ pub macro pin($value:expr $(,)?) { // instead, dropped _at the end of the enscoping block_. // For instance, // ```rust - // let p = Pin { pointer: &mut }; + // let p = Pin { __pointer: &mut }; // ``` // becomes: // ```rust // let mut anon = ; - // let p = Pin { pointer: &mut anon }; + // let p = Pin { __pointer: &mut anon }; // ``` // which is *exactly* what we want. // // See https://doc.rust-lang.org/1.58.1/reference/destructors.html#temporary-lifetime-extension // for more info. - $crate::pin::Pin::<&mut _> { pointer: &mut { $value } } + $crate::pin::Pin::<&mut _> { __pointer: &mut { $value } } } diff --git a/src/etc/natvis/libcore.natvis b/src/etc/natvis/libcore.natvis index 624d8cc5cc55a..f8569ef2594b4 100644 --- a/src/etc/natvis/libcore.natvis +++ b/src/etc/natvis/libcore.natvis @@ -99,9 +99,9 @@ - Pin({(void*)pointer}: {pointer}) + Pin({(void*)__pointer}: {__pointer}) - pointer + __pointer diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff index 8e53427e7e060..a38b8246bdef2 100644 --- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff @@ -36,7 +36,7 @@ - _4 = g() -> [return: bb1, unwind unreachable]; + _4 = {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8 (#0)}; + _3 = &mut _4; -+ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { pointer: _3 }; ++ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { __pointer: _3 }; + StorageDead(_3); + StorageLive(_5); + _5 = const false; diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff index b06db41af9d40..dc6628ab44c5f 100644 --- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff @@ -36,7 +36,7 @@ - _4 = g() -> [return: bb1, unwind continue]; + _4 = {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8 (#0)}; + _3 = &mut _4; -+ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { pointer: _3 }; ++ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { __pointer: _3 }; + StorageDead(_3); + StorageLive(_5); + _5 = const false; diff --git a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs b/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs index 134ea25b75afb..594a2672d435d 100644 --- a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs +++ b/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs @@ -7,7 +7,7 @@ use core::{marker::PhantomPinned, pin::Pin}; /// The `unsafe_pin_internals` is indeed unsound. fn non_unsafe_pin_new_unchecked(pointer: &mut T) -> Pin<&mut T> { - Pin { pointer } + Pin { __pointer: pointer } } fn main() { diff --git a/tests/ui/pin-macro/cant_access_internals.rs b/tests/ui/pin-macro/cant_access_internals.rs index 5826a18b5718b..4aeb6a643d959 100644 --- a/tests/ui/pin-macro/cant_access_internals.rs +++ b/tests/ui/pin-macro/cant_access_internals.rs @@ -8,5 +8,5 @@ use core::{ fn main() { let mut phantom_pinned = pin!(PhantomPinned); - mem::take(phantom_pinned.pointer); //~ ERROR use of unstable library feature 'unsafe_pin_internals' + mem::take(phantom_pinned.__pointer); //~ ERROR use of unstable library feature 'unsafe_pin_internals' } diff --git a/tests/ui/pin-macro/cant_access_internals.stderr b/tests/ui/pin-macro/cant_access_internals.stderr index 2737b84f5995b..444314a9d8bb3 100644 --- a/tests/ui/pin-macro/cant_access_internals.stderr +++ b/tests/ui/pin-macro/cant_access_internals.stderr @@ -1,8 +1,8 @@ error[E0658]: use of unstable library feature 'unsafe_pin_internals' --> $DIR/cant_access_internals.rs:11:15 | -LL | mem::take(phantom_pinned.pointer); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | mem::take(phantom_pinned.__pointer); + | ^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add `#![feature(unsafe_pin_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date From 27a6e6e67b6585e0f9bebc00617c22709c0d4a7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=AE=87=E9=80=B8?= Date: Wed, 24 Jan 2024 02:43:06 +0800 Subject: [PATCH 09/19] Wrap `HeapAlloc` and never inline --- library/std/src/sys/pal/windows/alloc.rs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/library/std/src/sys/pal/windows/alloc.rs b/library/std/src/sys/pal/windows/alloc.rs index d53ea16005fab..270eca37b14d6 100644 --- a/library/std/src/sys/pal/windows/alloc.rs +++ b/library/std/src/sys/pal/windows/alloc.rs @@ -95,7 +95,7 @@ static HEAP: AtomicPtr = AtomicPtr::new(ptr::null_mut()); #[inline] fn init_or_get_process_heap() -> c::HANDLE { let heap = HEAP.load(Ordering::Relaxed); - if heap.is_null() { + if core::intrinsics::unlikely(heap.is_null()) { // `HEAP` has not yet been successfully initialized let heap = unsafe { GetProcessHeap() }; if !heap.is_null() { @@ -115,6 +115,16 @@ fn init_or_get_process_heap() -> c::HANDLE { } } +#[inline(never)] +fn process_heap_alloc(flags: c::DWORD, dwBytes: c::SIZE_T) -> c::LPVOID { + let heap = init_or_get_process_heap(); + if core::intrinsics::unlikely(heap.is_null()) { + return ptr::null_mut(); + } + // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`. + unsafe { HeapAlloc(heap, flags, dwBytes) } +} + // Get a non-null handle to the default heap of the current process. // SAFETY: `HEAP` must have been successfully initialized. #[inline] @@ -133,25 +143,17 @@ struct Header(*mut u8); // initialized. #[inline] unsafe fn allocate(layout: Layout, zeroed: bool) -> *mut u8 { - let heap = init_or_get_process_heap(); - if heap.is_null() { - // Allocation has failed, could not get the current process heap. - return ptr::null_mut(); - } - // Allocated memory will be either zeroed or uninitialized. let flags = if zeroed { HEAP_ZERO_MEMORY } else { 0 }; if layout.align() <= MIN_ALIGN { - // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`. // The returned pointer points to the start of an allocated block. - unsafe { HeapAlloc(heap, flags, layout.size()) as *mut u8 } + process_heap_alloc(flags, layout.size()) as *mut u8 } else { // Allocate extra padding in order to be able to satisfy the alignment. let total = layout.align() + layout.size(); - // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`. - let ptr = unsafe { HeapAlloc(heap, flags, total) as *mut u8 }; + let ptr = process_heap_alloc(flags, total) as *mut u8; if ptr.is_null() { // Allocation has failed. return ptr::null_mut(); From abf45ae0b21d460a3bfd374e39034105b6cab08e Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Wed, 24 Jan 2024 16:03:44 +0100 Subject: [PATCH 10/19] core: add `From` implementations Introduce `From` implementations for all unsigned numeric types and `char`. This matches the API of `char` type. Issue: https://github.com/rust-lang/rust/issues/110998 --- library/core/src/ascii/ascii_char.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs index cc872a5343d6a..5f758af162477 100644 --- a/library/core/src/ascii/ascii_char.rs +++ b/library/core/src/ascii/ascii_char.rs @@ -537,6 +537,22 @@ impl AsciiChar { } } +macro_rules! into_int_impl { + ($($ty:ty)*) => { + $( + #[unstable(feature = "ascii_char", issue = "110998")] + impl From for $ty { + #[inline] + fn from(chr: AsciiChar) -> $ty { + chr as u8 as $ty + } + } + )* + } +} + +into_int_impl!(u8 u16 u32 u64 u128 char); + impl [AsciiChar] { /// Views this slice of ASCII characters as a UTF-8 `str`. #[unstable(feature = "ascii_char", issue = "110998")] From c4208fad3ce9d851fe5d54ba030b07a5aa3e0a89 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Thu, 25 Jan 2024 16:32:44 +0100 Subject: [PATCH 11/19] bless --- tests/ui/traits/issue-77982.stderr | 1 + tests/ui/try-trait/bad-interconversion.stderr | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/ui/traits/issue-77982.stderr b/tests/ui/traits/issue-77982.stderr index 592cfd970c64a..b130b7620fc0d 100644 --- a/tests/ui/traits/issue-77982.stderr +++ b/tests/ui/traits/issue-77982.stderr @@ -44,6 +44,7 @@ LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect( | type must be known at this point | = note: multiple `impl`s satisfying `u32: From<_>` found in the `core` crate: + - impl From for u32; - impl From for u32; - impl From for u32; - impl From for u32; diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr index 97fbbdbf8f8a8..4d046635d6442 100644 --- a/tests/ui/try-trait/bad-interconversion.stderr +++ b/tests/ui/try-trait/bad-interconversion.stderr @@ -12,6 +12,7 @@ LL | Ok(Err(123_i32)?) = help: the following other types implement trait `From`: > > + > = note: required for `Result` to implement `FromResidual>` error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result` From 5dd6418010b9f47f536710bbc03adca786e03920 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 26 Jan 2024 07:44:18 +0100 Subject: [PATCH 12/19] mark a doctest with UB as no_run --- library/core/src/intrinsics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 76a53a9366a72..43124535ab5d8 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2531,7 +2531,7 @@ extern "rust-intrinsic" { /// or `false`, and the caller has to ensure sound behavior for both cases. /// In other words, the following code has *Undefined Behavior*: /// - /// ``` + /// ```no_run /// #![feature(is_val_statically_known)] /// #![feature(core_intrinsics)] /// # #![allow(internal_features)] From 00ada8e30cb32a45dcac70630a8d4645a3ab393b Mon Sep 17 00:00:00 2001 From: Ardi <47633543+dev-ardi@users.noreply.github.com> Date: Fri, 26 Jan 2024 08:37:37 +0100 Subject: [PATCH 13/19] Update compiler/rustc_index/src/vec.rs Co-authored-by: Wesley Wiser --- compiler/rustc_index/src/vec.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 73265eb89961c..d876174e620f4 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -18,6 +18,7 @@ use crate::{Idx, IndexSlice}; /// you almost certainly want to use a [`newtype_index!`]-generated type instead. /// /// This allows to index the IndexVec with the new index type. +/// /// [`newtype_index!`]: ../macro.newtype_index.html #[derive(Clone, PartialEq, Eq, Hash)] #[repr(transparent)] From a39a2f73d6eb912902ca62d160b158e8907b6622 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 26 Jan 2024 15:26:03 +0100 Subject: [PATCH 14/19] next-solver: normalize in `LoweredTy::from_raw` --- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 10 +++++++++- tests/ui/for/issue-20605.next.stderr | 20 +++++++++---------- .../next-solver/normalize-path-for-method.rs | 18 +++++++++++++++++ .../recursive-self-normalization-2.rs | 1 + .../recursive-self-normalization-2.stderr | 11 +++++++++- .../overflow/recursive-self-normalization.rs | 1 + .../recursive-self-normalization.stderr | 11 +++++++++- 7 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 tests/ui/traits/next-solver/normalize-path-for-method.rs diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 18f547be2a71c..449de631f5a20 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -369,6 +369,14 @@ pub struct LoweredTy<'tcx> { impl<'tcx> LoweredTy<'tcx> { pub fn from_raw(fcx: &FnCtxt<'_, 'tcx>, span: Span, raw: Ty<'tcx>) -> LoweredTy<'tcx> { - LoweredTy { raw, normalized: fcx.normalize(span, raw) } + // FIXME(-Znext-solver): We're still figuring out how to best handle + // normalization and this doesn't feel too great. We should look at this + // code again before stabilizing it. + let normalized = if fcx.next_trait_solver() { + fcx.try_structurally_resolve_type(span, raw) + } else { + fcx.normalize(span, raw) + }; + LoweredTy { raw, normalized } } } diff --git a/tests/ui/for/issue-20605.next.stderr b/tests/ui/for/issue-20605.next.stderr index 28dbdf4c374c0..3d753b9c8b884 100644 --- a/tests/ui/for/issue-20605.next.stderr +++ b/tests/ui/for/issue-20605.next.stderr @@ -34,15 +34,11 @@ error: the type `&mut as IntoIterator>::IntoIte LL | for item in *things { *item = 0 } | ^^^^^^^ -error[E0277]: the size for values of type `< as IntoIterator>::IntoIter as Iterator>::Item` cannot be known at compilation time - --> $DIR/issue-20605.rs:5:9 +error: the type `Option<< as IntoIterator>::IntoIter as Iterator>::Item>` is not well-formed + --> $DIR/issue-20605.rs:5:17 | LL | for item in *things { *item = 0 } - | ^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `< as IntoIterator>::IntoIter as Iterator>::Item` - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature + | ^^^^^^^ error[E0277]: the size for values of type `< as IntoIterator>::IntoIter as Iterator>::Item` cannot be known at compilation time --> $DIR/issue-20605.rs:5:5 @@ -54,11 +50,15 @@ LL | for item in *things { *item = 0 } note: required by a bound in `None` --> $SRC_DIR/core/src/option.rs:LL:COL -error: the type `Option<< as IntoIterator>::IntoIter as Iterator>::Item>` is not well-formed - --> $DIR/issue-20605.rs:5:17 +error[E0277]: the size for values of type `< as IntoIterator>::IntoIter as Iterator>::Item` cannot be known at compilation time + --> $DIR/issue-20605.rs:5:9 | LL | for item in *things { *item = 0 } - | ^^^^^^^ + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `< as IntoIterator>::IntoIter as Iterator>::Item` + = note: all local variables must have a statically known size + = help: unsized locals are gated as an unstable feature error[E0614]: type `< as IntoIterator>::IntoIter as Iterator>::Item` cannot be dereferenced --> $DIR/issue-20605.rs:5:27 diff --git a/tests/ui/traits/next-solver/normalize-path-for-method.rs b/tests/ui/traits/next-solver/normalize-path-for-method.rs new file mode 100644 index 0000000000000..b95454306cd69 --- /dev/null +++ b/tests/ui/traits/next-solver/normalize-path-for-method.rs @@ -0,0 +1,18 @@ +// compile-flags: -Znext-solver +// check-pass + +trait Mirror { + type Assoc; +} +impl Mirror for T { + type Assoc = T; +} + +struct Foo; +impl Foo { + fn new() -> Self { Foo } +} + +fn main() { + ::Assoc::new(); +} diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs index 71b1502d775fc..932826519b7d2 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs @@ -16,6 +16,7 @@ fn test::Assoc2> + Foo2::Assoc //~^ ERROR overflow evaluating the requirement `::Assoc1 == _` //~| ERROR overflow evaluating the requirement `::Assoc1 == _` //~| ERROR overflow evaluating the requirement `::Assoc1 == _` + //~| ERROR overflow evaluating the requirement `::Assoc1 == _` //~| ERROR overflow evaluating the requirement `::Assoc1: Bar` } diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr index bad6820f7389d..e4f1f9cf02255 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr @@ -1,3 +1,11 @@ +error[E0275]: overflow evaluating the requirement `::Assoc1 == _` + --> $DIR/recursive-self-normalization-2.rs:15:17 + | +LL | needs_bar::(); + | ^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`) + error[E0275]: overflow evaluating the requirement `::Assoc1: Bar` --> $DIR/recursive-self-normalization-2.rs:15:17 | @@ -35,7 +43,8 @@ LL | needs_bar::(); | ^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`) + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs index 809a6a59ca6aa..32672c08c7e07 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs @@ -12,6 +12,7 @@ fn test::Assoc>>() { //~^ ERROR overflow evaluating the requirement `::Assoc == _` //~| ERROR overflow evaluating the requirement `::Assoc == _` //~| ERROR overflow evaluating the requirement `::Assoc == _` + //~| ERROR overflow evaluating the requirement `::Assoc == _` //~| ERROR overflow evaluating the requirement `::Assoc: Bar` } diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr index 80005d344ba39..da5c8bde568d2 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr @@ -1,3 +1,11 @@ +error[E0275]: overflow evaluating the requirement `::Assoc == _` + --> $DIR/recursive-self-normalization.rs:11:17 + | +LL | needs_bar::(); + | ^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`) + error[E0275]: overflow evaluating the requirement `::Assoc: Bar` --> $DIR/recursive-self-normalization.rs:11:17 | @@ -35,7 +43,8 @@ LL | needs_bar::(); | ^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`) + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0275`. From e87b8c7f34b9890503f59c93fa4805d1920f2b9c Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 26 Jan 2024 15:49:05 +0100 Subject: [PATCH 15/19] move alias-relate tests --- .../{ => alias-relate}/alias_eq_cant_be_furthur_normalized.rs | 0 .../alias_eq_dont_use_normalizes_to_if_substs_eq.rs | 0 .../ui/traits/next-solver/{ => alias-relate}/alias_eq_simple.rs | 0 .../{ => alias-relate}/alias_eq_substs_eq_not_intercrate.rs | 0 .../{ => alias-relate}/alias_eq_substs_eq_not_intercrate.stderr | 0 .../ui/traits/next-solver/{ => alias-relate}/tait-eq-proj-2.rs | 2 +- tests/ui/traits/next-solver/{ => alias-relate}/tait-eq-proj.rs | 0 tests/ui/traits/next-solver/{ => alias-relate}/tait-eq-tait.rs | 0 8 files changed, 1 insertion(+), 1 deletion(-) rename tests/ui/traits/next-solver/{ => alias-relate}/alias_eq_cant_be_furthur_normalized.rs (100%) rename tests/ui/traits/next-solver/{ => alias-relate}/alias_eq_dont_use_normalizes_to_if_substs_eq.rs (100%) rename tests/ui/traits/next-solver/{ => alias-relate}/alias_eq_simple.rs (100%) rename tests/ui/traits/next-solver/{ => alias-relate}/alias_eq_substs_eq_not_intercrate.rs (100%) rename tests/ui/traits/next-solver/{ => alias-relate}/alias_eq_substs_eq_not_intercrate.stderr (100%) rename tests/ui/traits/next-solver/{ => alias-relate}/tait-eq-proj-2.rs (84%) rename tests/ui/traits/next-solver/{ => alias-relate}/tait-eq-proj.rs (100%) rename tests/ui/traits/next-solver/{ => alias-relate}/tait-eq-tait.rs (100%) diff --git a/tests/ui/traits/next-solver/alias_eq_cant_be_furthur_normalized.rs b/tests/ui/traits/next-solver/alias-relate/alias_eq_cant_be_furthur_normalized.rs similarity index 100% rename from tests/ui/traits/next-solver/alias_eq_cant_be_furthur_normalized.rs rename to tests/ui/traits/next-solver/alias-relate/alias_eq_cant_be_furthur_normalized.rs diff --git a/tests/ui/traits/next-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs b/tests/ui/traits/next-solver/alias-relate/alias_eq_dont_use_normalizes_to_if_substs_eq.rs similarity index 100% rename from tests/ui/traits/next-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs rename to tests/ui/traits/next-solver/alias-relate/alias_eq_dont_use_normalizes_to_if_substs_eq.rs diff --git a/tests/ui/traits/next-solver/alias_eq_simple.rs b/tests/ui/traits/next-solver/alias-relate/alias_eq_simple.rs similarity index 100% rename from tests/ui/traits/next-solver/alias_eq_simple.rs rename to tests/ui/traits/next-solver/alias-relate/alias_eq_simple.rs diff --git a/tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.rs b/tests/ui/traits/next-solver/alias-relate/alias_eq_substs_eq_not_intercrate.rs similarity index 100% rename from tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.rs rename to tests/ui/traits/next-solver/alias-relate/alias_eq_substs_eq_not_intercrate.rs diff --git a/tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.stderr b/tests/ui/traits/next-solver/alias-relate/alias_eq_substs_eq_not_intercrate.stderr similarity index 100% rename from tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.stderr rename to tests/ui/traits/next-solver/alias-relate/alias_eq_substs_eq_not_intercrate.stderr diff --git a/tests/ui/traits/next-solver/tait-eq-proj-2.rs b/tests/ui/traits/next-solver/alias-relate/tait-eq-proj-2.rs similarity index 84% rename from tests/ui/traits/next-solver/tait-eq-proj-2.rs rename to tests/ui/traits/next-solver/alias-relate/tait-eq-proj-2.rs index a3df053dd8325..915643f1d2a89 100644 --- a/tests/ui/traits/next-solver/tait-eq-proj-2.rs +++ b/tests/ui/traits/next-solver/alias-relate/tait-eq-proj-2.rs @@ -3,7 +3,7 @@ #![feature(type_alias_impl_trait)] -// Similar to tests/ui/traits/next-solver/tait-eq-proj.rs +// Similar to tests/ui/traits/next-solver/alias-relate/tait-eq-proj.rs // but check the alias-sub relation in the other direction. type Tait = impl Iterator; diff --git a/tests/ui/traits/next-solver/tait-eq-proj.rs b/tests/ui/traits/next-solver/alias-relate/tait-eq-proj.rs similarity index 100% rename from tests/ui/traits/next-solver/tait-eq-proj.rs rename to tests/ui/traits/next-solver/alias-relate/tait-eq-proj.rs diff --git a/tests/ui/traits/next-solver/tait-eq-tait.rs b/tests/ui/traits/next-solver/alias-relate/tait-eq-tait.rs similarity index 100% rename from tests/ui/traits/next-solver/tait-eq-tait.rs rename to tests/ui/traits/next-solver/alias-relate/tait-eq-tait.rs From 7b6ac8bf21d6346c90bc8ea1d2557690a63fbf86 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 26 Jan 2024 15:51:20 +0100 Subject: [PATCH 16/19] remove unnecessary test --- .../traits/next-solver/temporary-ambiguity.rs | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 tests/ui/traits/next-solver/temporary-ambiguity.rs diff --git a/tests/ui/traits/next-solver/temporary-ambiguity.rs b/tests/ui/traits/next-solver/temporary-ambiguity.rs deleted file mode 100644 index 6102de7e446d6..0000000000000 --- a/tests/ui/traits/next-solver/temporary-ambiguity.rs +++ /dev/null @@ -1,22 +0,0 @@ -// compile-flags: -Znext-solver -// check-pass - -// Checks that we don't explode when we assemble >1 candidate for a goal. - -struct Wrapper(T); - -trait Foo {} - -impl Foo for Wrapper {} - -impl Foo for Wrapper<()> {} - -fn needs_foo(_: impl Foo) {} - -fn main() { - let mut x = Default::default(); - let w = Wrapper(x); - needs_foo(w); - x = 1; - let _ = x; -} From e17f91dd8b49a319ec034a6d738e7b396e3ec879 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Fri, 26 Jan 2024 23:53:51 +0800 Subject: [PATCH 17/19] Classify closure arguments in refutable pattern in argument error --- .../rustc_mir_build/src/thir/pattern/check_match.rs | 11 ++++++++++- .../pattern/usefulness/refutable-pattern-in-fn-arg.rs | 2 +- .../usefulness/refutable-pattern-in-fn-arg.stderr | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index ce75a2831a51e..435ea3dc3bbc7 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -47,9 +47,18 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), Err }; visitor.visit_expr(&thir[expr]); + let origin = match tcx.def_kind(def_id) { + DefKind::AssocFn | DefKind::Fn => "function argument", + DefKind::Closure => "closure argument", + // other types of MIR don't have function parameters, and we don't need to + // categorize those for the irrefutable check. + _ if thir.params.is_empty() => "", + kind => bug!("unexpected function parameters in THIR: {kind:?} {def_id:?}"), + }; + for param in thir.params.iter() { if let Some(box ref pattern) = param.pat { - visitor.check_binding_is_irrefutable(pattern, "function argument", None, None); + visitor.check_binding_is_irrefutable(pattern, origin, None, None); } } visitor.error diff --git a/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs b/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs index 4203dd94d43aa..51ff641509df5 100644 --- a/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs +++ b/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs @@ -1,6 +1,6 @@ fn main() { let f = |3: isize| println!("hello"); - //~^ ERROR refutable pattern in function argument + //~^ ERROR refutable pattern in closure argument //~| `..=2_isize` and `4_isize..` not covered f(4); } diff --git a/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.stderr b/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.stderr index bd6c5002e63e8..be119d27ab254 100644 --- a/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.stderr +++ b/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.stderr @@ -1,4 +1,4 @@ -error[E0005]: refutable pattern in function argument +error[E0005]: refutable pattern in closure argument --> $DIR/refutable-pattern-in-fn-arg.rs:2:14 | LL | let f = |3: isize| println!("hello"); From f941247bddff8343cc813b46ec219873e0e33807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 26 Jan 2024 18:26:36 +0100 Subject: [PATCH 18/19] Add fmease to the compiler review rotation --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index a9ddd1b99c72a..ab2fe033e7294 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -650,6 +650,7 @@ compiler-team-contributors = [ "@TaKO8Ki", "@b-naber", "@nnethercote", + "@fmease", ] compiler = [ "compiler-team", From 866364cc5d79b26ec1ab58eca0cc4c3416b5a1bc Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 23 Jan 2024 19:09:12 +0000 Subject: [PATCH 19/19] Normalize field types before checking validity --- .../src/transform/validate.rs | 23 ++++++++------ .../struct-assignment-validity.rs | 31 +++++++++++++++++++ 2 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 tests/ui/type-alias-impl-trait/struct-assignment-validity.rs diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 5564902396eda..21bdb66a27631 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -810,13 +810,18 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let adt_def = self.tcx.adt_def(def_id); assert!(adt_def.is_union()); assert_eq!(idx, FIRST_VARIANT); - let dest = adt_def.non_enum_variant().fields[field].ty(self.tcx, args); - if fields.len() != 1 { + let dest_ty = self.tcx.normalize_erasing_regions( + self.param_env, + adt_def.non_enum_variant().fields[field].ty(self.tcx, args), + ); + if fields.len() == 1 { + let src_ty = fields.raw[0].ty(self.body, self.tcx); + if !self.mir_assign_valid_types(src_ty, dest_ty) { + self.fail(location, "union field has the wrong type"); + } + } else { self.fail(location, "unions should have one initialized field"); } - if !self.mir_assign_valid_types(fields.raw[0].ty(self.body, self.tcx), dest) { - self.fail(location, "union field has the wrong type"); - } } AggregateKind::Adt(def_id, idx, args, _, None) => { let adt_def = self.tcx.adt_def(def_id); @@ -826,10 +831,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.fail(location, "adt has the wrong number of initialized fields"); } for (src, dest) in std::iter::zip(fields, &variant.fields) { - if !self.mir_assign_valid_types( - src.ty(self.body, self.tcx), - dest.ty(self.tcx, args), - ) { + let dest_ty = self + .tcx + .normalize_erasing_regions(self.param_env, dest.ty(self.tcx, args)); + if !self.mir_assign_valid_types(src.ty(self.body, self.tcx), dest_ty) { self.fail(location, "adt field has the wrong type"); } } diff --git a/tests/ui/type-alias-impl-trait/struct-assignment-validity.rs b/tests/ui/type-alias-impl-trait/struct-assignment-validity.rs new file mode 100644 index 0000000000000..39f0b9a02eeae --- /dev/null +++ b/tests/ui/type-alias-impl-trait/struct-assignment-validity.rs @@ -0,0 +1,31 @@ +// compile-flags: -Zvalidate-mir +// check-pass + +// Check that we don't cause cycle errors when validating pre-`Reveal::All` MIR +// that assigns opaques through normalized projections. + +#![feature(impl_trait_in_assoc_type)] + +struct Bar; + +trait Trait { + type Assoc; + fn foo() -> Foo; +} + +impl Trait for Bar { + type Assoc = impl std::fmt::Debug; + fn foo() -> Foo + where + Self::Assoc:, + { + let x: ::Assoc = (); + Foo { field: () } + } +} + +struct Foo { + field: ::Assoc, +} + +fn main() {}