From 25a7d2d540656e0499a43bfd01243250f2a25d7a Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 10 Mar 2022 08:47:53 -0600 Subject: [PATCH 01/14] Fix `cargo run tidy` When I implemented rust-only bootstrapping in https://github.com/rust-lang/rust/pull/92260, I neglected to test stage0 tools - it turns out they were broken because they couldn't find the sysroot of the initial bootstrap compiler. This fixes stage0 tools by using `rustc --print sysroot` instead of assuming rustc is already in a sysroot and hard-coding the relative directory. --- src/bootstrap/lib.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 2ae63858ff61..91a0e40ca183 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -117,6 +117,7 @@ use std::os::unix::fs::symlink as symlink_file; use std::os::windows::fs::symlink_file; use filetime::FileTime; +use once_cell::sync::OnceCell; use crate::builder::Kind; use crate::config::{LlvmLibunwind, TargetSelection}; @@ -892,7 +893,12 @@ impl Build { /// Returns the sysroot of the snapshot compiler. fn rustc_snapshot_sysroot(&self) -> &Path { - self.initial_rustc.parent().unwrap().parent().unwrap() + static SYSROOT_CACHE: OnceCell = once_cell::sync::OnceCell::new(); + SYSROOT_CACHE.get_or_init(|| { + let mut rustc = Command::new(&self.initial_rustc); + rustc.args(&["--print", "sysroot"]); + output(&mut rustc).trim().into() + }) } /// Runs a command, printing out nice contextual information if it fails. From 38e0ae590caab982a4305da58a0a62385c2dd880 Mon Sep 17 00:00:00 2001 From: Grisha Vartanyan Date: Wed, 23 Mar 2022 22:13:55 +0100 Subject: [PATCH 02/14] Reduce max hash in raw strings from u16 to u8 --- compiler/rustc_lexer/src/lib.rs | 14 +++++++------- compiler/rustc_lexer/src/tests.rs | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index 5b8300ab530f..a41e0374f410 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -161,15 +161,15 @@ pub enum LiteralKind { /// "b"abc"", "b"abc" ByteStr { terminated: bool }, /// "r"abc"", "r#"abc"#", "r####"ab"###"c"####", "r#"a" - RawStr { n_hashes: u16, err: Option }, + RawStr { n_hashes: u8, err: Option }, /// "br"abc"", "br#"abc"#", "br####"ab"###"c"####", "br#"a" - RawByteStr { n_hashes: u16, err: Option }, + RawByteStr { n_hashes: u8, err: Option }, } /// Error produced validating a raw string. Represents cases like: /// - `r##~"abcde"##`: `InvalidStarter` /// - `r###"abcde"##`: `NoTerminator { expected: 3, found: 2, possible_terminator_offset: Some(11)` -/// - Too many `#`s (>65535): `TooManyDelimiters` +/// - Too many `#`s (>255): `TooManyDelimiters` // perf note: It doesn't matter that this makes `Token` 36 bytes bigger. See #77629 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum RawStrError { @@ -178,7 +178,7 @@ pub enum RawStrError { /// The string was never terminated. `possible_terminator_offset` is the number of characters after `r` or `br` where they /// may have intended to terminate it. NoTerminator { expected: usize, found: usize, possible_terminator_offset: Option }, - /// More than 65535 `#`s exist. + /// More than 255 `#`s exist. TooManyDelimiters { found: usize }, } @@ -698,12 +698,12 @@ impl Cursor<'_> { } /// Eats the double-quoted string and returns `n_hashes` and an error if encountered. - fn raw_double_quoted_string(&mut self, prefix_len: usize) -> (u16, Option) { + fn raw_double_quoted_string(&mut self, prefix_len: usize) -> (u8, Option) { // Wrap the actual function to handle the error with too many hashes. // This way, it eats the whole raw string. let (n_hashes, err) = self.raw_string_unvalidated(prefix_len); - // Only up to 65535 `#`s are allowed in raw strings - match u16::try_from(n_hashes) { + // Only up to 255 `#`s are allowed in raw strings + match u8::try_from(n_hashes) { Ok(num) => (num, err), // We lie about the number of hashes here :P Err(_) => (0, Some(RawStrError::TooManyDelimiters { found: n_hashes })), diff --git a/compiler/rustc_lexer/src/tests.rs b/compiler/rustc_lexer/src/tests.rs index 548de67449ab..07daee06f0f8 100644 --- a/compiler/rustc_lexer/src/tests.rs +++ b/compiler/rustc_lexer/src/tests.rs @@ -2,7 +2,7 @@ use super::*; use expect_test::{expect, Expect}; -fn check_raw_str(s: &str, expected_hashes: u16, expected_err: Option) { +fn check_raw_str(s: &str, expected_hashes: u8, expected_err: Option) { let s = &format!("r{}", s); let mut cursor = Cursor::new(s); cursor.bump(); @@ -68,13 +68,13 @@ fn test_unterminated_no_pound() { #[test] fn test_too_many_hashes() { - let max_count = u16::MAX; + let max_count = u8::MAX; let mut hashes: String = "#".repeat(max_count.into()); - // Valid number of hashes (65535 = 2^16 - 1), but invalid string. + // Valid number of hashes (255 = 2^8 - 1 = u8::MAX), but invalid string. check_raw_str(&hashes, max_count, Some(RawStrError::InvalidStarter { bad_char: '\u{0}' })); - // One more hash sign (65536 = 2^16) becomes too many. + // One more hash sign (256 = 2^8) becomes too many. hashes.push('#'); check_raw_str( &hashes, From b51f20eaf5cc311ca601643306ec2ee0c8a714e8 Mon Sep 17 00:00:00 2001 From: Grisha Vartanyan Date: Wed, 23 Mar 2022 23:07:39 +0100 Subject: [PATCH 03/14] Update syntax tree definition --- compiler/rustc_ast/src/ast.rs | 2 +- compiler/rustc_ast/src/token.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index f5c4affdce2d..75ccbc92be1f 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1616,7 +1616,7 @@ pub enum StrStyle { /// A raw string, like `r##"foo"##`. /// /// The value is the number of `#` symbols used. - Raw(u16), + Raw(u8), } /// An AST literal. diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index c367573de8a9..b860612f4309 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -60,9 +60,9 @@ pub enum LitKind { Integer, Float, Str, - StrRaw(u16), // raw string delimited by `n` hash symbols + StrRaw(u8), // raw string delimited by `n` hash symbols ByteStr, - ByteStrRaw(u16), // raw byte string delimited by `n` hash symbols + ByteStrRaw(u8), // raw byte string delimited by `n` hash symbols Err, } From 0cf606177e79bc580fa27a82eb9c8b56e7253f46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Horstmann?= Date: Fri, 25 Mar 2022 11:39:11 +0100 Subject: [PATCH 04/14] Fix double drop of allocator in IntoIter impl of Vec --- library/alloc/src/vec/into_iter.rs | 15 +++++++++------ library/alloc/src/vec/mod.rs | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index f17b8d71b3a1..471042cd7177 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -8,7 +8,8 @@ use core::iter::{ FusedIterator, InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccessNoCoerce, }; use core::marker::PhantomData; -use core::mem::{self}; +use core::mem::{self, ManuallyDrop}; +use core::ops::Deref; use core::ptr::{self, NonNull}; use core::slice::{self}; @@ -32,7 +33,9 @@ pub struct IntoIter< pub(super) buf: NonNull, pub(super) phantom: PhantomData, pub(super) cap: usize, - pub(super) alloc: A, + // the drop impl reconstructs a RawVec from buf, cap and alloc + // to avoid dropping the allocator twice we need to wrap it into ManuallyDrop + pub(super) alloc: ManuallyDrop, pub(super) ptr: *const T, pub(super) end: *const T, } @@ -295,11 +298,11 @@ where impl Clone for IntoIter { #[cfg(not(test))] fn clone(&self) -> Self { - self.as_slice().to_vec_in(self.alloc.clone()).into_iter() + self.as_slice().to_vec_in(self.alloc.deref().clone()).into_iter() } #[cfg(test)] fn clone(&self) -> Self { - crate::slice::to_vec(self.as_slice(), self.alloc.clone()).into_iter() + crate::slice::to_vec(self.as_slice(), self.alloc.deref().clone()).into_iter() } } @@ -311,8 +314,8 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for IntoIter { impl Drop for DropGuard<'_, T, A> { fn drop(&mut self) { unsafe { - // `IntoIter::alloc` is not used anymore after this - let alloc = ptr::read(&self.0.alloc); + // `IntoIter::alloc` is not used anymore after this and will be dropped by RawVec + let alloc = ManuallyDrop::into_inner(ptr::read(&self.0.alloc)); // RawVec handles deallocation let _ = RawVec::from_raw_parts_in(self.0.buf.as_ptr(), self.0.cap, alloc); } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 9a66e69bdc06..96857c4bd6ff 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2575,7 +2575,7 @@ impl IntoIterator for Vec { fn into_iter(self) -> IntoIter { unsafe { let mut me = ManuallyDrop::new(self); - let alloc = ptr::read(me.allocator()); + let alloc = ManuallyDrop::new(ptr::read(me.allocator())); let begin = me.as_mut_ptr(); let end = if mem::size_of::() == 0 { arith_offset(begin as *const i8, me.len() as isize) as *const T From d14c0d2acb3ff1d0111920185109c9697a3cd460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Horstmann?= Date: Fri, 25 Mar 2022 13:27:18 +0100 Subject: [PATCH 05/14] Use ManuallyDrop::take instead of into_inner Co-authored-by: Daniel Henry-Mantilla --- library/alloc/src/vec/into_iter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 471042cd7177..1f9398faf226 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -315,7 +315,7 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for IntoIter { fn drop(&mut self) { unsafe { // `IntoIter::alloc` is not used anymore after this and will be dropped by RawVec - let alloc = ManuallyDrop::into_inner(ptr::read(&self.0.alloc)); + let alloc = ManuallyDrop::take(&mut self.0.alloc); // RawVec handles deallocation let _ = RawVec::from_raw_parts_in(self.0.buf.as_ptr(), self.0.cap, alloc); } From 4b53f563bd5b0f0e9cad26dbf2514f9a72c3fa2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Horstmann?= Date: Fri, 25 Mar 2022 13:00:49 +0100 Subject: [PATCH 06/14] Add a test verifying the number of drop calls --- library/alloc/tests/vec.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index ca0fcc855c7b..ab2414a6dc0b 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1,3 +1,6 @@ +use core::alloc::{Allocator, Layout}; +use core::ptr::NonNull; +use std::alloc::System; use std::assert_matches::assert_matches; use std::borrow::Cow; use std::cell::Cell; @@ -991,6 +994,27 @@ fn test_into_iter_advance_by() { assert_eq!(i.len(), 0); } +#[test] +fn test_into_iter_drop_allocator() { + struct ReferenceCountedAllocator<'a>(DropCounter<'a>); + + unsafe impl Allocator for ReferenceCountedAllocator<'_> { + fn allocate(&self, layout: Layout) -> Result, core::alloc::AllocError> { + System.allocate(layout) + } + + unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { + System.deallocate(ptr, layout) + } + } + + let mut drop_count = 0; + let allocator = ReferenceCountedAllocator(DropCounter { count: &mut drop_count }); + let _ = Vec::::new_in(allocator).into_iter(); + + assert_eq!(drop_count, 1); +} + #[test] fn test_from_iter_specialization() { let src: Vec = vec![0usize; 1]; From c3840c9ea142c80107067869143192498beec3d2 Mon Sep 17 00:00:00 2001 From: Grisha Vartanyan Date: Fri, 25 Mar 2022 15:05:27 +0100 Subject: [PATCH 07/14] Update clippy helper function types --- src/tools/clippy/clippy_lints/src/regex.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy/clippy_lints/src/regex.rs b/src/tools/clippy/clippy_lints/src/regex.rs index b6d04334de9e..a92097e1d24c 100644 --- a/src/tools/clippy/clippy_lints/src/regex.rs +++ b/src/tools/clippy/clippy_lints/src/regex.rs @@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for Regex { #[allow(clippy::cast_possible_truncation)] // truncation very unlikely here #[must_use] -fn str_span(base: Span, c: regex_syntax::ast::Span, offset: u16) -> Span { +fn str_span(base: Span, c: regex_syntax::ast::Span, offset: u8) -> Span { let offset = u32::from(offset); let end = base.lo() + BytePos(u32::try_from(c.end.offset).expect("offset too large") + offset); let start = base.lo() + BytePos(u32::try_from(c.start.offset).expect("offset too large") + offset); From d9a438dc73de6ff146ae3e6bc4050b7cea41b09e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Horstmann?= Date: Fri, 25 Mar 2022 16:57:59 +0100 Subject: [PATCH 08/14] Add another assertion without into_iter --- library/alloc/tests/vec.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index ab2414a6dc0b..19e39ebf910b 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1009,10 +1009,14 @@ fn test_into_iter_drop_allocator() { } let mut drop_count = 0; - let allocator = ReferenceCountedAllocator(DropCounter { count: &mut drop_count }); - let _ = Vec::::new_in(allocator).into_iter(); + let allocator = ReferenceCountedAllocator(DropCounter { count: &mut drop_count }); + let _ = Vec::::new_in(allocator); assert_eq!(drop_count, 1); + + let allocator = ReferenceCountedAllocator(DropCounter { count: &mut drop_count }); + let _ = Vec::::new_in(allocator).into_iter(); + assert_eq!(drop_count, 2); } #[test] From 78e27e2c7a85021a0b72253c17d0d99a383e8385 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 16 Mar 2022 15:52:21 +0100 Subject: [PATCH 09/14] async: Give predictable, reserved name to binding generated from .await expressions. This name makes it to debuginfo and allows debuggers to identify such bindings and their captured versions in suspended async fns. --- compiler/rustc_ast_lowering/src/expr.rs | 29 ++++++++++--------- compiler/rustc_span/src/symbol.rs | 2 +- .../codegen/async-fn-debug-awaitee-field.rs | 23 +++++++++++++++ 3 files changed, 40 insertions(+), 14 deletions(-) create mode 100644 src/test/codegen/async-fn-debug-awaitee-field.rs diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index d64f1a05712a..9442e0f1a1f3 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -618,9 +618,9 @@ impl<'hir> LoweringContext<'_, 'hir> { /// Desugar `.await` into: /// ```rust /// match ::std::future::IntoFuture::into_future() { - /// mut pinned => loop { + /// mut __awaitee => loop { /// match unsafe { ::std::future::Future::poll( - /// <::std::pin::Pin>::new_unchecked(&mut pinned), + /// <::std::pin::Pin>::new_unchecked(&mut __awaitee), /// ::std::future::get_context(task_context), /// ) } { /// ::std::task::Poll::Ready(result) => break result, @@ -657,21 +657,24 @@ impl<'hir> LoweringContext<'_, 'hir> { let expr = self.lower_expr_mut(expr); let expr_hir_id = expr.hir_id; - let pinned_ident = Ident::with_dummy_span(sym::pinned); - let (pinned_pat, pinned_pat_hid) = - self.pat_ident_binding_mode(span, pinned_ident, hir::BindingAnnotation::Mutable); + // Note that the name of this binding must not be changed to something else because + // debuggers and debugger extensions expect it to be called `__awaitee`. They use + // this name to identify what is being awaited by a suspended async functions. + let awaitee_ident = Ident::with_dummy_span(sym::__awaitee); + let (awaitee_pat, awaitee_pat_hid) = + self.pat_ident_binding_mode(span, awaitee_ident, hir::BindingAnnotation::Mutable); let task_context_ident = Ident::with_dummy_span(sym::_task_context); // unsafe { // ::std::future::Future::poll( - // ::std::pin::Pin::new_unchecked(&mut pinned), + // ::std::pin::Pin::new_unchecked(&mut __awaitee), // ::std::future::get_context(task_context), // ) // } let poll_expr = { - let pinned = self.expr_ident(span, pinned_ident, pinned_pat_hid); - let ref_mut_pinned = self.expr_mut_addr_of(span, pinned); + let awaitee = self.expr_ident(span, awaitee_ident, awaitee_pat_hid); + let ref_mut_awaitee = self.expr_mut_addr_of(span, awaitee); let task_context = if let Some(task_context_hid) = self.task_context { self.expr_ident_mut(span, task_context_ident, task_context_hid) } else { @@ -681,7 +684,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let new_unchecked = self.expr_call_lang_item_fn_mut( span, hir::LangItem::PinNewUnchecked, - arena_vec![self; ref_mut_pinned], + arena_vec![self; ref_mut_awaitee], Some(expr_hir_id), ); let get_context = self.expr_call_lang_item_fn_mut( @@ -782,8 +785,8 @@ impl<'hir> LoweringContext<'_, 'hir> { span: self.lower_span(span), }); - // mut pinned => loop { ... } - let pinned_arm = self.arm(pinned_pat, loop_expr); + // mut __awaitee => loop { ... } + let awaitee_arm = self.arm(awaitee_pat, loop_expr); // `match ::std::future::IntoFuture::into_future() { ... }` let into_future_span = self.mark_span_with_reason( @@ -799,11 +802,11 @@ impl<'hir> LoweringContext<'_, 'hir> { ); // match { - // mut pinned => loop { .. } + // mut __awaitee => loop { .. } // } hir::ExprKind::Match( into_future_expr, - arena_vec![self; pinned_arm], + arena_vec![self; awaitee_arm], hir::MatchSource::AwaitDesugar, ) } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4dd1c3fed6b3..774cf6a19c76 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -272,6 +272,7 @@ symbols! { __D, __H, __S, + __awaitee, __try_var, _d, _e, @@ -1022,7 +1023,6 @@ symbols! { pattern_parentheses, phantom_data, pin, - pinned, platform_intrinsics, plugin, plugin_registrar, diff --git a/src/test/codegen/async-fn-debug-awaitee-field.rs b/src/test/codegen/async-fn-debug-awaitee-field.rs new file mode 100644 index 000000000000..efb345fa9f3e --- /dev/null +++ b/src/test/codegen/async-fn-debug-awaitee-field.rs @@ -0,0 +1,23 @@ +// This test makes sure that the generator field capturing the awaitee in a `.await` expression +// is called "__awaitee" in debuginfo. This name must not be changed since debuggers and debugger +// extensions rely on the field having this name. + +// ignore-tidy-linelength +// compile-flags: -C debuginfo=2 --edition=2018 + +async fn foo() {} + +async fn async_fn_test() { + foo().await; +} + +// NONMSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}", +// MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$", +// CHECK: [[SUSPEND_STRUCT:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend0", scope: [[GEN]], +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__awaitee", scope: [[SUSPEND_STRUCT]], {{.*}}, baseType: [[AWAITEE_TYPE:![0-9]*]], +// NONMSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture", +// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture >", + +fn main() { + let _fn = async_fn_test(); +} From 11446779b006b25300eb2b4ad6707d6d3303da5e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 30 Mar 2022 13:17:46 +0000 Subject: [PATCH 10/14] Don't ICE when opaque types get their hidden type constrained again. Contrary to popular belief, `codegen_fulfill_obligation` does not get used solely in codegen, so we cannot rely on `param_env` being set to RevealAll and thus revealing the hidden types instead of constraining them. --- .../src/traits/codegen.rs | 19 +++++---------- .../assoc-projection-ice.rs | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+), 13 deletions(-) create mode 100644 src/test/ui/type-alias-impl-trait/assoc-projection-ice.rs diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_trait_selection/src/traits/codegen.rs index 4b6784aee978..866bb6109e05 100644 --- a/compiler/rustc_trait_selection/src/traits/codegen.rs +++ b/compiler/rustc_trait_selection/src/traits/codegen.rs @@ -19,6 +19,7 @@ use rustc_middle::ty::{self, TyCtxt}; /// obligations *could be* resolved if we wanted to. /// /// This also expects that `trait_ref` is fully normalized. +#[instrument(level = "debug", skip(tcx))] pub fn codegen_fulfill_obligation<'tcx>( tcx: TyCtxt<'tcx>, (param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>), @@ -27,11 +28,6 @@ pub fn codegen_fulfill_obligation<'tcx>( let trait_ref = tcx.erase_regions(trait_ref); // We expect the input to be fully normalized. debug_assert_eq!(trait_ref, tcx.normalize_erasing_regions(param_env, trait_ref)); - debug!( - "codegen_fulfill_obligation(trait_ref={:?}, def_id={:?})", - (param_env, trait_ref), - trait_ref.def_id() - ); // Do the initial selection for the obligation. This yields the // shallow result we are looking for -- that is, what specific impl. @@ -80,25 +76,22 @@ pub fn codegen_fulfill_obligation<'tcx>( } }; - debug!("fulfill_obligation: selection={:?}", selection); + debug!(?selection); // Currently, we use a fulfillment context to completely resolve // all nested obligations. This is because they can inform the // inference of the impl's type parameters. let mut fulfill_cx = FulfillmentContext::new(); let impl_source = selection.map(|predicate| { - debug!("fulfill_obligation: register_predicate_obligation {:?}", predicate); fulfill_cx.register_predicate_obligation(&infcx, predicate); }); let impl_source = drain_fulfillment_cx_or_panic(&infcx, &mut fulfill_cx, impl_source); - // There should be no opaque types during codegen, they all get revealed. - let opaque_types = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); - if !opaque_types.is_empty() { - bug!("{:#?}", opaque_types); - } + // Opaque types may have gotten their hidden types constrained, but we can ignore them safely + // as they will get constrained elsewhere, too. + let _opaque_types = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); - debug!("Cache miss: {:?} => {:?}", trait_ref, impl_source); + debug!("Cache miss: {trait_ref:?} => {impl_source:?}"); Ok(&*tcx.arena.alloc(impl_source)) }) } diff --git a/src/test/ui/type-alias-impl-trait/assoc-projection-ice.rs b/src/test/ui/type-alias-impl-trait/assoc-projection-ice.rs new file mode 100644 index 000000000000..703e3e8693e8 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/assoc-projection-ice.rs @@ -0,0 +1,24 @@ +#![feature(type_alias_impl_trait)] + +// build-pass + +trait T { type Item; } + +type Alias<'a> = impl T; + +struct S; +impl<'a> T for &'a S { + type Item = &'a (); +} + +fn filter_positive<'a>() -> Alias<'a> { + &S +} + +fn with_positive(fun: impl Fn(Alias<'_>)) { + fun(filter_positive()); +} + +fn main() { + with_positive(|_| ()); +} From f0b12f4e78c6e69af01a8608bb11d46d07bc21cc Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 17 Mar 2022 11:04:48 +0100 Subject: [PATCH 11/14] Remove unused #![feature]s from std. --- library/std/src/lib.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 133ced5f26cf..a58c31a5c070 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -229,9 +229,7 @@ #![feature(allow_internal_unstable)] #![feature(array_error_internals)] #![feature(assert_matches)] -#![feature(associated_type_bounds)] #![feature(async_iterator)] -#![feature(atomic_mut_ptr)] #![feature(bench_black_box)] #![feature(box_syntax)] #![feature(c_unwind)] @@ -251,7 +249,6 @@ #![feature(const_ipv4)] #![feature(const_ipv6)] #![feature(const_mut_refs)] -#![feature(const_option)] #![feature(const_socketaddr)] #![feature(const_trait_impl)] #![feature(c_size_t)] @@ -307,7 +304,6 @@ #![feature(raw_os_nonzero)] #![feature(rustc_attrs)] #![feature(saturating_int_impl)] -#![feature(slice_internals)] #![feature(slice_ptr_get)] #![feature(staged_api)] #![feature(std_internals)] From e4248fe182506012946765a9291c9dbba393c358 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 17 Mar 2022 11:05:32 +0100 Subject: [PATCH 12/14] Categorize and sort unstable features in std. --- library/std/src/lib.rs | 133 ++++++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 61 deletions(-) diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index a58c31a5c070..4057db4f991f 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -218,107 +218,118 @@ feature(slice_index_methods, coerce_unsized, sgx_platform) )] #![deny(rustc::existing_doc_keyword)] -// std is implemented with unstable features, many of which are internal -// compiler details that will never be stable -// NB: the following list is sorted to minimize merge conflicts. +// +// Language features: #![feature(alloc_error_handler)] -#![feature(alloc_layout_extra)] -#![feature(allocator_api)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] -#![feature(array_error_internals)] -#![feature(assert_matches)] -#![feature(async_iterator)] -#![feature(bench_black_box)] #![feature(box_syntax)] #![feature(c_unwind)] -#![feature(c_variadic)] -#![feature(cfg_accessible)] -#![feature(cfg_eval)] #![feature(cfg_target_thread_local)] -#![feature(char_error_internals)] -#![feature(char_internals)] -#![feature(concat_bytes)] #![feature(concat_idents)] #![cfg_attr(bootstrap, feature(const_fn_fn_ptr_basics))] #![cfg_attr(bootstrap, feature(const_fn_trait_bound))] -#![feature(const_format_args)] -#![feature(const_io_structs)] -#![feature(const_ip)] -#![feature(const_ipv4)] -#![feature(const_ipv6)] #![feature(const_mut_refs)] -#![feature(const_socketaddr)] #![feature(const_trait_impl)] -#![feature(c_size_t)] -#![feature(core_ffi_c)] -#![feature(core_intrinsics)] -#![feature(core_panic)] -#![feature(custom_test_frameworks)] #![feature(decl_macro)] +#![cfg_attr(not(bootstrap), feature(deprecated_suggestion))] #![feature(doc_cfg)] #![feature(doc_cfg_hide)] -#![feature(rustdoc_internals)] -#![cfg_attr(not(bootstrap), feature(deprecated_suggestion))] #![feature(doc_masked)] #![feature(doc_notable_trait)] #![feature(dropck_eyepatch)] -#![feature(duration_checked_float)] -#![feature(duration_constants)] -#![feature(edition_panic)] -#![feature(exact_size_is_empty)] #![feature(exhaustive_patterns)] -#![feature(extend_one)] -#![feature(float_minimum_maximum)] -#![feature(format_args_nl)] -#![feature(strict_provenance)] -#![feature(get_mut_unchecked)] -#![feature(hashmap_internals)] -#![feature(int_error_internals)] #![feature(intra_doc_pointers)] #![feature(lang_items)] #![feature(linkage)] -#![feature(log_syntax)] -#![feature(map_try_insert)] -#![feature(maybe_uninit_slice)] -#![feature(maybe_uninit_write_slice)] #![feature(min_specialization)] -#![feature(mixed_integer_ops)] #![feature(must_not_suspend)] #![feature(needs_panic_runtime)] #![feature(negative_impls)] #![feature(never_type)] -#![feature(new_uninit)] #![feature(nll)] +#![feature(platform_intrinsics)] +#![feature(prelude_import)] +#![feature(rustc_attrs)] +#![feature(rustdoc_internals)] +#![feature(staged_api)] +#![feature(thread_local)] +#![feature(try_blocks)] +// +// Library features (core): +#![feature(array_error_internals)] +#![feature(char_error_internals)] +#![feature(char_internals)] +#![feature(core_intrinsics)] +#![feature(duration_checked_float)] +#![feature(duration_constants)] +#![feature(exact_size_is_empty)] +#![feature(extend_one)] +#![feature(float_minimum_maximum)] +#![feature(hashmap_internals)] +#![feature(int_error_internals)] +#![feature(maybe_uninit_slice)] +#![feature(maybe_uninit_write_slice)] +#![feature(mixed_integer_ops)] #![feature(nonnull_slice_from_raw_parts)] -#![feature(once_cell)] +#![feature(panic_can_unwind)] #![feature(panic_info_message)] #![feature(panic_internals)] -#![feature(panic_can_unwind)] -#![feature(panic_unwind)] -#![feature(platform_intrinsics)] #![feature(portable_simd)] -#![feature(prelude_import)] #![feature(ptr_as_uninit)] #![feature(raw_os_nonzero)] -#![feature(rustc_attrs)] -#![feature(saturating_int_impl)] #![feature(slice_ptr_get)] -#![feature(staged_api)] #![feature(std_internals)] -#![feature(stdsimd)] #![feature(str_internals)] -#![feature(test)] -#![feature(thread_local)] -#![feature(thread_local_internals)] -#![feature(toowned_clone_into)] +#![feature(strict_provenance)] #![feature(total_cmp)] -#![feature(trace_macros)] -#![feature(try_blocks)] +// +// Library features (alloc): +#![feature(alloc_layout_extra)] +#![feature(allocator_api)] +#![feature(get_mut_unchecked)] +#![feature(map_try_insert)] +#![feature(new_uninit)] +#![feature(toowned_clone_into)] #![feature(try_reserve_kind)] #![feature(vec_into_raw_parts)] -// NB: the above list is sorted to minimize merge conflicts. +// +// Library features (unwind): +#![feature(panic_unwind)] +// +// Only for re-exporting: +#![feature(assert_matches)] +#![feature(async_iterator)] +#![feature(c_size_t)] +#![feature(c_variadic)] +#![feature(cfg_accessible)] +#![feature(cfg_eval)] +#![feature(concat_bytes)] +#![feature(const_format_args)] +#![feature(core_ffi_c)] +#![feature(core_panic)] +#![feature(custom_test_frameworks)] +#![feature(edition_panic)] +#![feature(format_args_nl)] +#![feature(log_syntax)] +#![feature(once_cell)] +#![feature(saturating_int_impl)] +#![feature(stdsimd)] +#![feature(test)] +#![feature(trace_macros)] +// +// Only used in tests/benchmarks: +#![feature(bench_black_box)] +// +// Only for const-ness: +#![feature(const_io_structs)] +#![feature(const_ip)] +#![feature(const_ipv4)] +#![feature(const_ipv6)] +#![feature(const_socketaddr)] +#![feature(thread_local_internals)] +// #![default_lib_allocator] // Explicitly import the prelude. The compiler uses this same unstable attribute From 39a8442d34d0f7623ee830176bdb95aad25e0da0 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 30 Mar 2022 15:08:13 +0200 Subject: [PATCH 13/14] Put back std #![feature]s that were not unused. --- library/std/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 4057db4f991f..d4420cc42304 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -279,6 +279,7 @@ #![feature(portable_simd)] #![feature(ptr_as_uninit)] #![feature(raw_os_nonzero)] +#![feature(slice_internals)] #![feature(slice_ptr_get)] #![feature(std_internals)] #![feature(str_internals)] @@ -327,6 +328,7 @@ #![feature(const_ip)] #![feature(const_ipv4)] #![feature(const_ipv6)] +#![feature(const_option)] #![feature(const_socketaddr)] #![feature(thread_local_internals)] // From 759d1e6af8610cdfdbf091a5d3d825b05c1fc6a2 Mon Sep 17 00:00:00 2001 From: Grisha Vartanyan Date: Wed, 30 Mar 2022 18:20:30 +0200 Subject: [PATCH 14/14] Update error message & remove outdated test comment --- compiler/rustc_parse/src/lexer/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 601a39e69ab9..d688d37c1cf3 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -589,15 +589,13 @@ impl<'a> StringReader<'a> { } } - /// Note: It was decided to not add a test case, because it would be too big. - /// fn report_too_many_hashes(&self, start: BytePos, found: usize) -> ! { self.fatal_span_( start, self.pos, &format!( "too many `#` symbols: raw strings may be delimited \ - by up to 65535 `#` symbols, but found {}", + by up to 255 `#` symbols, but found {}", found ), )