From d3cefda2ef99ddd7359d749a7d3259ec84853789 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 5 Oct 2026 14:46:36 -0700 Subject: [PATCH 1/8] Inline `Cow::to_mut` This avoids needing the overhead of a call before discovering that the `Cow` is already owned. --- library/alloc/src/borrow.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs index b6a7a1eae2a70..4b4445d329ff5 100644 --- a/library/alloc/src/borrow.rs +++ b/library/alloc/src/borrow.rs @@ -280,6 +280,7 @@ impl Cow<'_, B> { /// ); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn to_mut(&mut self) -> &mut ::Owned { match *self { Borrowed(borrowed) => { From 48c4946b23c936a549b8297e7bf9125a81b390b4 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 5 Oct 2026 14:49:25 -0700 Subject: [PATCH 2/8] Inline `Vec` fold operations These show up in hot paths, and inlining should allow optimizing them. --- library/alloc/src/vec/into_iter.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 48b1db0d5bf49..345fb02759d7f 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -364,6 +364,7 @@ impl Iterator for IntoIter { } } + #[inline] fn fold(mut self, mut accum: B, mut f: F) -> B where F: FnMut(B, Self::Item) -> B, @@ -396,6 +397,7 @@ impl Iterator for IntoIter { accum } + #[inline] fn try_fold(&mut self, mut accum: B, mut f: F) -> R where Self: Sized, From 3e910527df9a854518673b7da6f0b9d296034681 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 5 Oct 2026 14:50:41 -0700 Subject: [PATCH 3/8] Inline `Copied` fold operations These are simple wrappers but nonetheless don't get inlined and show up in hot paths. --- library/core/src/iter/adapters/copied.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index ba87fb7216059..be4685f877a88 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -65,6 +65,7 @@ where self.it.size_hint() } + #[inline] fn try_fold(&mut self, init: B, f: F) -> R where Self: Sized, @@ -74,6 +75,7 @@ where self.it.try_fold(init, copy_try_fold(f)) } + #[inline] fn fold(self, init: Acc, f: F) -> Acc where F: FnMut(Acc, Self::Item) -> Acc, @@ -118,6 +120,7 @@ where self.it.next_back().copied() } + #[inline] fn try_rfold(&mut self, init: B, f: F) -> R where Self: Sized, @@ -127,6 +130,7 @@ where self.it.try_rfold(init, copy_try_fold(f)) } + #[inline] fn rfold(self, init: Acc, f: F) -> Acc where F: FnMut(Acc, Self::Item) -> Acc, From d136cc46b0a385883927178b8b97c1e04d8e3440 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 5 Oct 2026 14:51:51 -0700 Subject: [PATCH 4/8] Inline `Cloned` fold operations These are simple wrappers. --- library/core/src/iter/adapters/cloned.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/core/src/iter/adapters/cloned.rs b/library/core/src/iter/adapters/cloned.rs index c0b6a4053c825..4de3af3f78510 100644 --- a/library/core/src/iter/adapters/cloned.rs +++ b/library/core/src/iter/adapters/cloned.rs @@ -25,6 +25,7 @@ impl Cloned { } } +#[inline] fn clone_try_fold(mut f: impl FnMut(Acc, T) -> R) -> impl FnMut(Acc, &T) -> R { move |acc, elt| f(acc, elt.clone()) } @@ -45,6 +46,7 @@ where self.it.size_hint() } + #[inline] fn try_fold(&mut self, init: B, f: F) -> R where Self: Sized, @@ -54,6 +56,7 @@ where self.it.try_fold(init, clone_try_fold(f)) } + #[inline] fn fold(self, init: Acc, f: F) -> Acc where F: FnMut(Acc, Self::Item) -> Acc, @@ -81,6 +84,7 @@ where self.it.next_back().cloned() } + #[inline] fn try_rfold(&mut self, init: B, f: F) -> R where Self: Sized, @@ -90,6 +94,7 @@ where self.it.try_rfold(init, clone_try_fold(f)) } + #[inline] fn rfold(self, init: Acc, f: F) -> Acc where F: FnMut(Acc, Self::Item) -> Acc, From 39c28802355a02fe6a892c1517c8bf7703d4300f Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sun, 4 Oct 2026 18:57:58 -0700 Subject: [PATCH 5/8] Inline fold operations for Chain and Map, for performance --- library/core/src/iter/adapters/chain.rs | 4 ++++ library/core/src/iter/adapters/map.rs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs index d143b67fd4353..5ece905f4aabf 100644 --- a/library/core/src/iter/adapters/chain.rs +++ b/library/core/src/iter/adapters/chain.rs @@ -96,6 +96,7 @@ where a_count + b_count } + #[inline] fn try_fold(&mut self, mut acc: Acc, mut f: F) -> R where Self: Sized, @@ -113,6 +114,7 @@ where try { acc } } + #[inline] fn fold(self, mut acc: Acc, mut f: F) -> Acc where F: FnMut(Acc, Self::Item) -> Acc, @@ -256,6 +258,7 @@ where .or_else(|| self.a.as_mut()?.rfind(predicate)) } + #[inline] fn try_rfold(&mut self, mut acc: Acc, mut f: F) -> R where Self: Sized, @@ -273,6 +276,7 @@ where try { acc } } + #[inline] fn rfold(self, mut acc: Acc, mut f: F) -> Acc where F: FnMut(Acc, Self::Item) -> Acc, diff --git a/library/core/src/iter/adapters/map.rs b/library/core/src/iter/adapters/map.rs index 75f70dcd9b58f..e80a156f1ed11 100644 --- a/library/core/src/iter/adapters/map.rs +++ b/library/core/src/iter/adapters/map.rs @@ -112,6 +112,7 @@ where self.iter.size_hint() } + #[inline] fn try_fold(&mut self, init: Acc, g: G) -> R where Self: Sized, @@ -121,6 +122,7 @@ where self.iter.try_fold(init, map_try_fold(&mut self.f, g)) } + #[inline] fn fold(self, init: Acc, g: G) -> Acc where G: FnMut(Acc, Self::Item) -> Acc, @@ -149,6 +151,7 @@ where self.iter.next_back().map(&mut self.f) } + #[inline] fn try_rfold(&mut self, init: Acc, g: G) -> R where Self: Sized, @@ -158,6 +161,7 @@ where self.iter.try_rfold(init, map_try_fold(&mut self.f, g)) } + #[inline] fn rfold(self, init: Acc, g: G) -> Acc where G: FnMut(Acc, Self::Item) -> Acc, From 81900216ce9ee0b48f2c563c696bfca98cfba755 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 14 Oct 2026 15:13:24 +0900 Subject: [PATCH 6/8] deduplicate DefId encodings in the query cache --- .../rustc_middle/src/query/on_disk_cache.rs | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs index 7383ad23273be..1ec31a0d8fb62 100644 --- a/compiler/rustc_middle/src/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/query/on_disk_cache.rs @@ -48,6 +48,9 @@ const SYMBOL_STR: u8 = 0; const SYMBOL_OFFSET: u8 = 1; const SYMBOL_PREDEFINED: u8 = 2; +const DEF_ID_FULL: u8 = 0; +const DEF_ID_OFFSET: u8 = 1; + /// Provides an interface to incremental compilation data cached from the /// previous compilation session. This data will eventually include the results /// of a few selected queries (like `typeck` and `mir_optimized`) and @@ -231,6 +234,7 @@ impl OnDiskCache { encoder, type_shorthands: Default::default(), predicate_shorthands: Default::default(), + def_id_shorthands: Default::default(), interpret_allocs: Default::default(), caching_source_map_view: CachingSourceMapView::new(tcx.sess.source_map()), file_to_file_index, @@ -652,7 +656,14 @@ impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> { // sessions, to map the old `DefId` to the new one. fn decode_def_id(&mut self) -> DefId { // Load the `DefPathHash` which is was we encoded the `DefId` as. - let def_path_hash = DefPathHash::decode(self); + let def_path_hash = match self.read_u8() { + DEF_ID_FULL => DefPathHash::decode(self), + DEF_ID_OFFSET => { + let pos = self.read_usize(); + self.opaque.with_position(pos, |decoder| DefPathHash::decode(decoder)) + } + _ => unreachable!(), + }; // Using the `DefPathHash`, we can lookup the new `DefId`. // Subtle: We only encode a `DefId` as part of a query result. @@ -748,6 +759,7 @@ pub struct CacheEncoder<'tcx> { encoder: FileEncoder<'static>, type_shorthands: FxHashMap, usize>, predicate_shorthands: FxHashMap, usize>, + def_id_shorthands: FxHashMap, interpret_allocs: FxIndexSet, caching_source_map_view: CachingSourceMapView<'tcx>, file_to_file_index: FxHashMap<*const SourceFile, SourceFileIndex>, @@ -908,7 +920,19 @@ impl<'tcx> SpanEncoder for CacheEncoder<'tcx> { } fn encode_def_id(&mut self, def_id: DefId) { - self.tcx.def_path_hash(def_id).encode(self); + match self.def_id_shorthands.entry(def_id) { + Entry::Vacant(entry) => { + self.encoder.emit_u8(DEF_ID_FULL); + let pos = self.encoder.position(); + entry.insert(pos); + self.tcx.def_path_hash(def_id).encode(self); + } + Entry::Occupied(entry) => { + let pos = *entry.get(); + self.emit_u8(DEF_ID_OFFSET); + self.emit_usize(pos); + } + } } fn encode_def_index(&mut self, _def_index: DefIndex) { From e1663b69bf6e0f5b69c3490b7f66cb8a2113bb99 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Mon, 19 Oct 2026 16:54:00 +0200 Subject: [PATCH 7/8] Don't emit allow attributes in try/contract desugaring --- compiler/rustc_ast_lowering/src/contract.rs | 5 --- compiler/rustc_ast_lowering/src/expr.rs | 35 +++++------------ .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 + ...ible_struct_drop.build.ElaborateDrops.diff | 38 +++++-------------- ....test.ElaborateDrops.after.panic-abort.mir | 6 +-- ...test.ElaborateDrops.after.panic-unwind.mir | 6 +-- ...ng.identity.JumpThreading.panic-abort.diff | 26 ++++++------- ...g.identity.JumpThreading.panic-unwind.diff | 26 ++++++------- ...ts.runtime-optimized.after.panic-abort.mir | 6 +-- ...s.runtime-optimized.after.panic-unwind.mir | 6 +-- ..._question_mark.runtime-optimized.after.mir | 16 +++----- ...e_const_switch.identity.JumpThreading.diff | 24 +++++------- tests/ui/inference/issue-71309.stderr | 4 +- tests/ui/unpretty/exhaustive.hir.stdout | 20 ++-------- 14 files changed, 68 insertions(+), 152 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/contract.rs b/compiler/rustc_ast_lowering/src/contract.rs index cbfeda33040e7..9ceec41533d8e 100644 --- a/compiler/rustc_ast_lowering/src/contract.rs +++ b/compiler/rustc_ast_lowering/src/contract.rs @@ -1,9 +1,7 @@ use std::sync::Arc; use rustc_attr_ir::lang_items::LangItem; -use rustc_attr_ir::target::Target; use rustc_span::sym; -use thin_vec::thin_vec; use crate::LoweringContext; @@ -351,9 +349,6 @@ impl<'hir> LoweringContext<'_, 'hir> { ), )); - let attrs: rustc_ast::AttrVec = thin_vec![self.unreachable_code_attr(span)]; - self.lower_attrs(contract_check.hir_id, &attrs, span, Target::Expression); - let ret_block = self.block_all(span, arena_vec![self; ret_stmt], Some(contract_check)); self.arena.alloc(self.expr_block(self.arena.alloc(ret_block))) } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index f4bfec24e3b1b..c10ad4b2a398c 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -16,7 +16,7 @@ use rustc_session::diagnostics::report_lit_error; use rustc_span::{ ByteSymbol, DUMMY_SP, DesugaringKind, Ident, Span, Spanned, Symbol, respan, span_bug, sym, }; -use thin_vec::{ThinVec, thin_vec}; +use thin_vec::ThinVec; mod closure; use crate::diagnostics::{ @@ -1933,13 +1933,14 @@ impl<'hir> LoweringContext<'_, 'hir> { /// Desugar `ExprKind::Try` from: `?` into: /// ```ignore (pseudo-rust) /// match Try::branch() { - /// ControlFlow::Continue(val) => #[allow(unreachable_code)] val,, + /// ControlFlow::Continue(val) => val, /// ControlFlow::Break(residual) => - /// #[allow(unreachable_code)] - /// // If there is an enclosing `try {...}`: - /// break 'catch_target Residual::into_try_type(residual), + /// // If there is an enclosing homogeneous `try {...}`: + /// break 'catch_target residual_into_try_type(residual), + /// // If there is an enclosing heterogeneous`try {...}`: + /// break 'catch_target FromResidual::from_residual(residual), /// // Otherwise: - /// return Try::from_residual(residual), + /// return FromResidual::from_residual(residual), /// } /// ``` fn lower_expr_try(&mut self, span: Span, sub_expr: &Expr) -> hir::ExprKind<'hir> { @@ -1967,21 +1968,16 @@ impl<'hir> LoweringContext<'_, 'hir> { ) }; - let attrs: AttrVec = thin_vec![self.unreachable_code_attr(try_span)]; - - // `ControlFlow::Continue(val) => #[allow(unreachable_code)] val,` + // `ControlFlow::Continue(val) => val,` let continue_arm = { let val_ident = Ident::with_dummy_span(sym::val); let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident); let val_expr = self.expr_ident(span, val_ident, val_pat_nid); - self.lower_attrs(val_expr.hir_id, &attrs, span, Target::Expression); let continue_pat = self.pat_cf_continue(unstable_span, val_pat); self.arm(continue_pat, val_expr, try_span) }; - // `ControlFlow::Break(residual) => - // #[allow(unreachable_code)] - // return Try::from_residual(residual),` + // `ControlFlow::Break(residual) => (residual),` let break_arm = { let residual_ident = Ident::with_dummy_span(sym::residual); let (residual_local, residual_local_nid) = self.pat_ident(try_span, residual_ident); @@ -2016,7 +2012,6 @@ impl<'hir> LoweringContext<'_, 'hir> { let ret_expr = self.checked_return(Some(from_residual_expr)); self.arena.alloc(self.expr(try_span, ret_expr)) }; - self.lower_attrs(ret_expr.hir_id, &attrs, span, Target::Expression); let break_pat = self.pat_cf_break(try_span, residual_local); self.arm(break_pat, ret_expr, try_span) @@ -2357,18 +2352,6 @@ impl<'hir> LoweringContext<'_, 'hir> { body: expr, } } - - /// `#[allow(unreachable_code)]` - pub(super) fn unreachable_code_attr(&mut self, span: Span) -> Attribute { - let attr = attr::mk_attr_nested_word( - &self.tcx.sess.psess.attr_id_generator, - AttrStyle::Outer, - sym::allow, - sym::unreachable_code, - span, - ); - attr - } } /// Used by [`LoweringContext::make_lowered_await`] to customize the desugaring based on what kind diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 9e3e3d810345e..e3fffc04246f8 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -84,6 +84,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // `.await` operator. Some(DesugaringKind::Await) => return, + // Don't lint *within* contract attrs + Some(DesugaringKind::Contract) => return, _ => {} } diff --git a/tests/mir-opt/building/fallible_struct_drop.build.ElaborateDrops.diff b/tests/mir-opt/building/fallible_struct_drop.build.ElaborateDrops.diff index b6085e6c9b23b..94ff83194794f 100644 --- a/tests/mir-opt/building/fallible_struct_drop.build.ElaborateDrops.diff +++ b/tests/mir-opt/building/fallible_struct_drop.build.ElaborateDrops.diff @@ -61,53 +61,33 @@ + let mut _56: bool; scope 1 { debug residual => _9; - scope 2 { - } } - scope 3 { + scope 2 { debug val => _12; - scope 4 { - } } - scope 5 { + scope 3 { debug residual => _19; - scope 6 { - } } - scope 7 { + scope 4 { debug val => _22; - scope 8 { - } } - scope 9 { + scope 5 { debug residual => _29; - scope 10 { - } } - scope 11 { + scope 6 { debug val => _32; - scope 12 { - } } - scope 13 { + scope 7 { debug residual => _39; - scope 14 { - } } - scope 15 { + scope 8 { debug val => _42; - scope 16 { - } } - scope 17 { + scope 9 { debug residual => _49; - scope 18 { - } } - scope 19 { + scope 10 { debug val => _52; - scope 20 { - } } bb0: { diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.after.panic-abort.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.after.panic-abort.mir index e8efb9b7c3483..e637c79b33ff7 100644 --- a/tests/mir-opt/issue_62289.test.ElaborateDrops.after.panic-abort.mir +++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.after.panic-abort.mir @@ -15,13 +15,9 @@ fn test() -> Option> { let _11: u32; scope 1 { debug residual => _8; - scope 2 { - } } - scope 3 { + scope 2 { debug val => _11; - scope 4 { - } } bb0: { diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.after.panic-unwind.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.after.panic-unwind.mir index 4da1eed4484bb..d99f5f8fcafb6 100644 --- a/tests/mir-opt/issue_62289.test.ElaborateDrops.after.panic-unwind.mir +++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.after.panic-unwind.mir @@ -15,13 +15,9 @@ fn test() -> Option> { let _11: u32; scope 1 { debug residual => _8; - scope 2 { - } } - scope 3 { + scope 2 { debug val => _11; - scope 4 { - } } bb0: { diff --git a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff index a822ca20a8e80..c3525ea8e368e 100644 --- a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff +++ b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff @@ -14,32 +14,28 @@ let _9: i32; scope 1 { debug residual => _6; - scope 2 { - scope 8 (inlined #[track_caller] as FromResidual>>::from_residual) { - let mut _14: isize; - let _15: i32; - let mut _16: i32; - let mut _17: bool; - scope 9 { - scope 10 (inlined >::from) { - } + scope 6 (inlined #[track_caller] as FromResidual>>::from_residual) { + let mut _14: isize; + let _15: i32; + let mut _16: i32; + let mut _17: bool; + scope 7 { + scope 8 (inlined >::from) { } } } } - scope 3 { + scope 2 { debug val => _9; - scope 4 { - } } - scope 5 (inlined as Try>::branch) { + scope 3 (inlined as Try>::branch) { let mut _10: isize; let _11: i32; let _12: i32; let mut _13: std::result::Result; - scope 6 { + scope 4 { } - scope 7 { + scope 5 { } } diff --git a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff index a822ca20a8e80..c3525ea8e368e 100644 --- a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff +++ b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff @@ -14,32 +14,28 @@ let _9: i32; scope 1 { debug residual => _6; - scope 2 { - scope 8 (inlined #[track_caller] as FromResidual>>::from_residual) { - let mut _14: isize; - let _15: i32; - let mut _16: i32; - let mut _17: bool; - scope 9 { - scope 10 (inlined >::from) { - } + scope 6 (inlined #[track_caller] as FromResidual>>::from_residual) { + let mut _14: isize; + let _15: i32; + let mut _16: i32; + let mut _17: bool; + scope 7 { + scope 8 (inlined >::from) { } } } } - scope 3 { + scope 2 { debug val => _9; - scope 4 { - } } - scope 5 (inlined as Try>::branch) { + scope 3 (inlined as Try>::branch) { let mut _10: isize; let _11: i32; let _12: i32; let mut _13: std::result::Result; - scope 6 { + scope 4 { } - scope 7 { + scope 5 { } } diff --git a/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.runtime-optimized.after.panic-abort.mir b/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.runtime-optimized.after.panic-abort.mir index 5a9f8b2cc466b..36a0b991ef5dc 100644 --- a/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.runtime-optimized.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.runtime-optimized.after.panic-abort.mir @@ -9,13 +9,9 @@ fn option_traits(_1: Option) -> Option { let mut _5: u32; scope 1 { debug residual => const Option::::None; - scope 2 { - } } - scope 3 { + scope 2 { debug val => _4; - scope 4 { - } } bb0: { diff --git a/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.runtime-optimized.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.runtime-optimized.after.panic-unwind.mir index 8d272ac3485f1..8f785ce59d58d 100644 --- a/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.runtime-optimized.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.runtime-optimized.after.panic-unwind.mir @@ -9,13 +9,9 @@ fn option_traits(_1: Option) -> Option { let mut _5: u32; scope 1 { debug residual => const Option::::None; - scope 2 { - } } - scope 3 { + scope 2 { debug val => _4; - scope 4 { - } } bb0: { diff --git a/tests/mir-opt/pre-codegen/simple_option_map.map_via_question_mark.runtime-optimized.after.mir b/tests/mir-opt/pre-codegen/simple_option_map.map_via_question_mark.runtime-optimized.after.mir index 3c559614e9863..cde5538f54ad5 100644 --- a/tests/mir-opt/pre-codegen/simple_option_map.map_via_question_mark.runtime-optimized.after.mir +++ b/tests/mir-opt/pre-codegen/simple_option_map.map_via_question_mark.runtime-optimized.after.mir @@ -9,22 +9,18 @@ fn map_via_question_mark(_1: Option) -> Option { let mut _9: i32; scope 1 { debug residual => const Option::::None; - scope 2 { - scope 7 (inlined as FromResidual>>::from_residual) { - let mut _3: isize; - let mut _5: bool; - } + scope 5 (inlined as FromResidual>>::from_residual) { + let mut _3: isize; + let mut _5: bool; } } - scope 3 { + scope 2 { debug val => _8; - scope 4 { - } } - scope 5 (inlined as Try>::branch) { + scope 3 (inlined as Try>::branch) { let mut _2: isize; let _6: i32; - scope 6 { + scope 4 { } } diff --git a/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff b/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff index be29296044837..a115cb21e7d7c 100644 --- a/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff +++ b/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff @@ -10,31 +10,27 @@ let _5: i32; scope 1 { debug residual => _4; - scope 2 { - scope 8 (inlined #[track_caller] as FromResidual>>::from_residual) { - let mut _10: isize; - let _11: i32; - let mut _12: bool; - scope 9 { - scope 10 (inlined >::from) { - } + scope 6 (inlined #[track_caller] as FromResidual>>::from_residual) { + let mut _10: isize; + let _11: i32; + let mut _12: bool; + scope 7 { + scope 8 (inlined >::from) { } } } } - scope 3 { + scope 2 { debug val => _5; - scope 4 { - } } - scope 5 (inlined as Try>::branch) { + scope 3 (inlined as Try>::branch) { let mut _6: isize; let _7: i32; let _8: i32; let mut _9: std::result::Result; - scope 6 { + scope 4 { } - scope 7 { + scope 5 { } } diff --git a/tests/ui/inference/issue-71309.stderr b/tests/ui/inference/issue-71309.stderr index a96cbccf02708..673649c767e3d 100644 --- a/tests/ui/inference/issue-71309.stderr +++ b/tests/ui/inference/issue-71309.stderr @@ -7,8 +7,8 @@ LL | let y: u32 = x?; = note: `?` operator cannot convert from `i32` to `u32` help: you can convert an `i32` to a `u32` and panic if the converted value doesn't fit | -LL | let y: u32 = (x?).try_into().unwrap(); - | + +++++++++++++++++++++ +LL | let y: u32 = x?.try_into().unwrap(); + | ++++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout index 34c5c7e589bc5..7fb3f85b7f5ce 100644 --- a/tests/ui/unpretty/exhaustive.hir.stdout +++ b/tests/ui/unpretty/exhaustive.hir.stdout @@ -236,14 +236,8 @@ mod expressions { type_ascribe!({ from_output(()) }, Option<_>); type_ascribe!({ from_output(match branch(None) { - Break { 0: residual } => - #[attr = LintCheck([LintCheck {lint_name: "unreachable_code", - kind: Allow}])] - break from_residual(residual), - Continue { 0: val } => - #[attr = LintCheck([LintCheck {lint_name: "unreachable_code", - kind: Allow}])] - val, + Break { 0: residual } => break from_residual(residual), + Continue { 0: val } => val, }) }, Option) } @@ -364,14 +358,8 @@ mod expressions { fn expr_try() { let expr; match branch(expr) { - Break { 0: residual } => - #[attr = LintCheck([LintCheck {lint_name: "unreachable_code", - kind: Allow}])] - return from_residual(residual), - Continue { 0: val } => - #[attr = LintCheck([LintCheck {lint_name: "unreachable_code", - kind: Allow}])] - val, + Break { 0: residual } => return from_residual(residual), + Continue { 0: val } => val, }; } /// ExprKind::Yield From db2155baf9fb849c23af90a7b8c59a79a477dca2 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Sun, 25 Oct 2026 15:38:40 +0100 Subject: [PATCH 8/8] create fast path for attributes created in builtin macro expansions --- compiler/rustc_ast/src/ast.rs | 148 +++++++++++++++++- compiler/rustc_ast/src/ast_traits.rs | 8 +- compiler/rustc_ast/src/attr/mod.rs | 60 +++++-- compiler/rustc_ast/src/visit.rs | 1 + .../rustc_ast_passes/src/ast_validation.rs | 4 +- compiler/rustc_ast_pretty/src/pprust/state.rs | 3 +- compiler/rustc_attr_parsing/src/generated.rs | 54 +++++++ compiler/rustc_attr_parsing/src/interface.rs | 6 + compiler/rustc_attr_parsing/src/lib.rs | 1 + .../rustc_attr_parsing/src/validate_attr.rs | 4 +- .../src/deriving/clone.rs | 2 +- .../src/deriving/coerce_pointee.rs | 2 +- .../src/deriving/debug.rs | 2 +- .../src/deriving/default.rs | 2 +- .../rustc_builtin_macros/src/deriving/eq.rs | 6 +- .../rustc_builtin_macros/src/deriving/from.rs | 2 +- .../src/deriving/generic/mod.rs | 42 +---- .../rustc_builtin_macros/src/deriving/hash.rs | 2 +- .../rustc_builtin_macros/src/deriving/ord.rs | 2 +- .../src/deriving/partial_eq.rs | 2 +- .../src/deriving/partial_ord.rs | 2 +- .../src/deriving/reborrow.rs | 2 +- compiler/rustc_builtin_macros/src/eii.rs | 1 + compiler/rustc_builtin_macros/src/test.rs | 12 +- .../rustc_builtin_macros/src/test_harness.rs | 6 +- compiler/rustc_expand/src/build.rs | 9 ++ compiler/rustc_expand/src/expand.rs | 2 +- compiler/rustc_lint/src/builtin.rs | 2 +- .../rustc_parse/src/parser/attr_wrapper.rs | 1 + compiler/rustc_passes/src/input_stats.rs | 2 +- compiler/rustc_resolve/src/def_collector.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 - .../src/attrs/mixed_attributes_style.rs | 1 + .../clippy_lints/src/empty_line_after.rs | 2 +- .../clippy_utils/src/check_proc_macro.rs | 2 +- tests/ui/stats/macro-stats.stderr | 18 +-- 36 files changed, 319 insertions(+), 98 deletions(-) create mode 100644 compiler/rustc_attr_parsing/src/generated.rs diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index c86d6366e0753..53df848459e32 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -17,6 +17,7 @@ //! - [`MacroDef`], [`MacStmtStyle`], [`MacCall`]: Macro definition and invocation. //! - [`Attribute`]: Metadata associated with item. //! - [`UnOp`], [`BinOp`], and [`BinOpKind`]: Unary and binary operators. +// ignore-tidy-file-filelength use std::borrow::{Borrow, Cow}; use std::{cmp, fmt}; @@ -33,12 +34,13 @@ use rustc_span::{ ByteSymbol, DUMMY_SP, ErrorGuaranteed, Ident, LocalExpnId, Span, Spanned, Symbol, kw, respan, sym, }; +use smallvec::{SmallVec, smallvec}; use thin_vec::{ThinVec, thin_vec}; use crate::attr::data_structures::CfgEntry; pub use crate::format::*; use crate::token::{self, CommentKind, Delimiter}; -use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream}; +use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream, TokenTree}; use crate::util::parser::{ExprPrecedence, Fixity}; use crate::visit::{AssocCtxt, BoundKind, LifetimeCtxt}; @@ -3464,13 +3466,151 @@ pub enum AttrKind { /// A normal attribute. Normal(Box), - /// A synthetic attribute inserted by the compiler. - Synthetic(Box), - /// A doc comment (e.g. `/// ...`, `//! ...`, `/** ... */`, `/*! ... */`). + /// /// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal` /// variant (which is much less compact and thus more expensive). DocComment(CommentKind, Symbol), + + /// A synthetic attribute inserted by the compiler. + /// + /// See [`SyntheticAttr`] for the semantics of "synthetic" attributes. + Synthetic(Box), + + /// A macro generated attribute inserted by a builtin macro. + /// + /// See [`GeneratedAttr`] for the semantics of "generated" attributes. + Generated(GeneratedAttr), +} + +/// An attribute created by a macro expansion. +/// +/// This attribute has no tokens, which means it cannot be allowed to re-enter the parser. This +/// means it can only be added to items that cannot later be observed by other macros. +#[derive(Clone, Encodable, Decodable, Debug, Walkable)] +pub enum GeneratedAttr { + AutomaticallyDerived, + RustcConstUnstableDerived, + Inline, + DocHidden, + CoverageOff, + RustcTestMarker(Symbol), +} + +impl GeneratedAttr { + pub fn descr(&self) -> String { + match self { + GeneratedAttr::AutomaticallyDerived => "#[automatically_derived]".into(), + GeneratedAttr::RustcConstUnstableDerived => { + "#[rustc_const_unstable(feature = \"derive_const\", issue = \"143874\")]".into() + } + GeneratedAttr::Inline => "#[inline]".into(), + GeneratedAttr::DocHidden => "#[doc(hidden)]".into(), + GeneratedAttr::CoverageOff => "#[coverage(off)]".into(), + GeneratedAttr::RustcTestMarker(test_path) => { + format!("#[rustc_test_marker = \"{test_path}\"]") + } + } + } + pub fn value_span(&self) -> Option { + match self { + GeneratedAttr::AutomaticallyDerived => None, + GeneratedAttr::RustcConstUnstableDerived => None, + GeneratedAttr::Inline => None, + GeneratedAttr::DocHidden => None, + GeneratedAttr::CoverageOff => None, + GeneratedAttr::RustcTestMarker(_) => None, + } + } + + pub fn is_doc_comment(&self) -> Option { + match self { + GeneratedAttr::AutomaticallyDerived => None, + GeneratedAttr::RustcConstUnstableDerived => None, + GeneratedAttr::Inline => None, + GeneratedAttr::DocHidden => None, + GeneratedAttr::CoverageOff => None, + GeneratedAttr::RustcTestMarker(_) => None, + } + } + + pub fn name(&self) -> Option { + match self { + GeneratedAttr::AutomaticallyDerived => Some(sym::automatically_derived), + GeneratedAttr::RustcConstUnstableDerived => Some(sym::rustc_const_unstable), + GeneratedAttr::Inline => Some(sym::inline), + GeneratedAttr::DocHidden => Some(sym::doc), + GeneratedAttr::CoverageOff => Some(sym::coverage), + GeneratedAttr::RustcTestMarker(_) => Some(sym::rustc_test_marker), + } + } + + pub fn path_matches(&self, name: &[Symbol]) -> bool { + let path = match self { + GeneratedAttr::AutomaticallyDerived => &[sym::automatically_derived], + GeneratedAttr::RustcConstUnstableDerived => &[sym::rustc_const_unstable], + GeneratedAttr::Inline => &[sym::inline], + GeneratedAttr::DocHidden => &[sym::doc], + GeneratedAttr::CoverageOff => &[sym::coverage], + GeneratedAttr::RustcTestMarker(_) => &[sym::rustc_test_marker], + }; + + path == name + } + + pub fn symbol_path(&self) -> Option> { + self.name().map(|n| smallvec![n]) + } + + pub fn path_span(&self) -> Option { + match self { + GeneratedAttr::AutomaticallyDerived => None, + GeneratedAttr::RustcConstUnstableDerived => None, + GeneratedAttr::Inline => None, + GeneratedAttr::DocHidden => None, + GeneratedAttr::CoverageOff => None, + GeneratedAttr::RustcTestMarker(_) => None, + } + } + + pub fn is_word(&self) -> bool { + match self { + GeneratedAttr::AutomaticallyDerived => true, + GeneratedAttr::RustcConstUnstableDerived => false, + GeneratedAttr::Inline => true, + GeneratedAttr::DocHidden => false, + GeneratedAttr::CoverageOff => false, + GeneratedAttr::RustcTestMarker(_) => false, + } + } + pub fn value_str(&self) -> Option { + match self { + GeneratedAttr::AutomaticallyDerived => None, + GeneratedAttr::RustcConstUnstableDerived => None, + GeneratedAttr::Inline => None, + GeneratedAttr::DocHidden => None, + GeneratedAttr::CoverageOff => None, + GeneratedAttr::RustcTestMarker(test_path) => Some(*test_path), + } + } + + pub fn doc_str_and_fragment_kind(&self) -> Option { + match self { + GeneratedAttr::AutomaticallyDerived => None, + GeneratedAttr::RustcConstUnstableDerived => None, + GeneratedAttr::Inline => None, + GeneratedAttr::DocHidden => None, + GeneratedAttr::CoverageOff => None, + GeneratedAttr::RustcTestMarker(_) => None, + } + } + + pub fn token_trees(&self) -> Vec { + unimplemented!( + "generated attribute `{}` cannot re-enter the parser at this time", + self.descr() + ) + } } #[derive(Clone, Encodable, Decodable, Debug, Walkable)] diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index 3b0478e24b195..c1514337742ce 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -170,13 +170,17 @@ impl HasTokens for Attribute { fn tokens(&self) -> Option<&LazyAttrTokenStream> { match &self.kind { AttrKind::Normal(normal) => normal.tokens.as_ref(), - AttrKind::Synthetic(..) | AttrKind::DocComment(..) => unreachable!(), + AttrKind::Synthetic(..) | AttrKind::DocComment(..) | AttrKind::Generated(..) => { + unreachable!() + } } } fn tokens_mut(&mut self) -> Option<&mut Option> { Some(match &mut self.kind { AttrKind::Normal(normal) => &mut normal.tokens, - AttrKind::Synthetic(..) | AttrKind::DocComment(..) => unreachable!(), + AttrKind::Synthetic(..) | AttrKind::DocComment(..) | AttrKind::Generated(..) => { + unreachable!() + } }) } } diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 9e3e021e3ee95..780e1b43412a6 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -11,6 +11,7 @@ use rustc_span::{Ident, Span, Symbol, sym}; use smallvec::{SmallVec, smallvec}; use thin_vec::{ThinVec, thin_vec}; +use crate::GeneratedAttr; use crate::ast::{ AttrArgs, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute, DUMMY_NODE_ID, DelimArgs, Expr, ExprKind, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NormalAttr, Path, @@ -62,7 +63,9 @@ impl Attribute { pub fn get_normal_item(&self) -> &AttrItem { match &self.kind { AttrKind::Normal(normal) => &normal.item, - AttrKind::Synthetic(..) | AttrKind::DocComment(..) => unreachable!(), + AttrKind::Synthetic(..) | AttrKind::DocComment(..) | AttrKind::Generated(..) => { + unreachable!() + } } } @@ -71,7 +74,9 @@ impl Attribute { AttrKind::Normal(..) => { Attribute { kind: AttrKind::Synthetic(Box::new(synthetic_attr)), ..self } } - AttrKind::Synthetic(..) | AttrKind::DocComment(..) => unreachable!(), + AttrKind::Synthetic(..) | AttrKind::DocComment(..) | AttrKind::Generated(..) => { + unreachable!() + } } } } @@ -84,6 +89,7 @@ impl AttributeExt for Attribute { _ => None, }, AttrKind::Synthetic(..) | AttrKind::DocComment(..) => None, + AttrKind::Generated(generated) => generated.value_span(), } } @@ -91,9 +97,10 @@ impl AttributeExt for Attribute { /// So `#[doc = "doc"]` (which is a doc comment) and `#[doc(...)]` (which is not /// a doc comment) will return `false`. fn is_doc_comment(&self) -> Option { - match self.kind { + match &self.kind { AttrKind::Normal(..) | AttrKind::Synthetic(..) => None, AttrKind::DocComment(..) => Some(self.span), + AttrKind::Generated(generated) => generated.is_doc_comment(), } } @@ -104,6 +111,7 @@ impl AttributeExt for Attribute { AttrKind::Normal(normal) => normal.item.name(), AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) => None, AttrKind::DocComment(..) => None, + AttrKind::Generated(generated) => generated.name(), } } @@ -115,6 +123,7 @@ impl AttributeExt for Attribute { } AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) => None, AttrKind::DocComment(_, _) => None, + AttrKind::Generated(generated) => generated.symbol_path(), } } @@ -123,6 +132,7 @@ impl AttributeExt for Attribute { AttrKind::Normal(attr) => Some(attr.item.path.span), AttrKind::Synthetic(..) => unreachable!(), AttrKind::DocComment(_, _) => None, + AttrKind::Generated(generated) => generated.path_span(), } } @@ -139,6 +149,7 @@ impl AttributeExt for Attribute { .all(|(s, n)| s.args.is_none() && s.ident.name == *n) } AttrKind::Synthetic(..) | AttrKind::DocComment(..) => false, + AttrKind::Generated(generated) => generated.path_matches(name), } } @@ -147,6 +158,7 @@ impl AttributeExt for Attribute { AttrKind::Normal(normal) => matches!(normal.item.args, AttrArgs::Empty), AttrKind::Synthetic(..) => unreachable!(), AttrKind::DocComment(..) => false, + AttrKind::Generated(generated) => generated.is_word(), } } @@ -160,7 +172,7 @@ impl AttributeExt for Attribute { fn meta_item_list(&self) -> Option> { match &self.kind { AttrKind::Normal(normal) => normal.item.meta_item_list(), - AttrKind::Synthetic(..) | AttrKind::DocComment(..) => None, + AttrKind::Synthetic(..) | AttrKind::DocComment(..) | AttrKind::Generated(..) => None, } } @@ -184,6 +196,7 @@ impl AttributeExt for Attribute { AttrKind::Normal(normal) => normal.item.value_str(), AttrKind::Synthetic(..) => unreachable!(), AttrKind::DocComment(..) => None, + AttrKind::Generated(generated) => generated.value_str(), } } @@ -207,6 +220,7 @@ impl AttributeExt for Attribute { Some((value, DocFragmentKind::Raw(value_span), self.span)) } AttrKind::Normal(..) | AttrKind::Synthetic(..) => None, + AttrKind::Generated(generated) => generated.doc_str_and_fragment_kind()?, } } @@ -239,20 +253,32 @@ impl AttributeExt for Attribute { } fn is_doc_hidden(&self) -> bool { - self.has_name(sym::doc) - && self.meta_item_list().is_some_and(|l| list_contains_name(&l, sym::hidden)) + match &self.kind { + AttrKind::Normal(_) => { + self.has_name(sym::doc) + && self.meta_item_list().is_some_and(|l| list_contains_name(&l, sym::hidden)) + } + AttrKind::Generated(GeneratedAttr::DocHidden) => true, + _ => false, + } } fn is_doc_keyword_or_attribute(&self) -> bool { - if self.has_name(sym::doc) - && let Some(items) = self.meta_item_list() - { - for item in items { - if item.has_name(sym::keyword) || item.has_name(sym::attribute) { - return true; + match &self.kind { + AttrKind::Normal(_) => { + if self.has_name(sym::doc) + && let Some(items) = self.meta_item_list() + { + for item in items { + if item.has_name(sym::keyword) || item.has_name(sym::attribute) { + return true; + } + } } } + _ => {} } + false } @@ -283,7 +309,7 @@ impl Attribute { pub fn meta(&self) -> Option { match &self.kind { AttrKind::Normal(normal) => normal.item.meta(self.span), - AttrKind::Synthetic(..) | AttrKind::DocComment(..) => None, + AttrKind::Synthetic(..) | AttrKind::DocComment(..) | AttrKind::Generated(..) => None, } } @@ -292,12 +318,13 @@ impl Attribute { AttrKind::Normal(normal) => normal.item.meta_kind(), AttrKind::Synthetic(..) => unreachable!(), AttrKind::DocComment(..) => None, + AttrKind::Generated(..) => None, } } pub fn token_trees(&self) -> Vec { - match self.kind { - AttrKind::Normal(ref normal) => normal + match &self.kind { + AttrKind::Normal(normal) => normal .tokens .as_ref() .unwrap_or_else(|| panic!("attribute is missing tokens: {self:?}")) @@ -305,8 +332,9 @@ impl Attribute { .to_token_trees(), // Empty tokens here ensures synthetic attributes are invisible to proc macros. AttrKind::Synthetic(..) => vec![], + AttrKind::Generated(generated) => generated.token_trees(), AttrKind::DocComment(comment_kind, data) => vec![TokenTree::token_alone( - token::DocComment(comment_kind, self.style, data), + token::DocComment(*comment_kind, self.style, *data), self.span, )], } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index e4813b9588409..e6305995016fe 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -432,6 +432,7 @@ macro_rules! common_visitor_and_walkers { impl_visitable_noop! { // tidy-alphabetical-start AttrId, + GeneratedAttr, Movability, Mutability, Pinnedness, diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index bd869a72f91dd..ef411f495f9f5 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -535,7 +535,9 @@ impl<'a> AstValidator<'a> { ]; !attr.has_any_name(&arr) && rustc_attr_parsing::is_builtin_attr(&normal.item) } - AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) => false, + AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) | AttrKind::Generated(..) => { + false + } AttrKind::DocComment(..) => true, }) .for_each(|attr| { diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index e767f9623c2fd..a082300bb47ed 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -667,7 +667,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere // to keep the printed code reasonably parse-able. return false; } - AttrKind::Normal(_) | AttrKind::DocComment(..) => {} + AttrKind::Normal(_) | AttrKind::DocComment(..) | AttrKind::Generated(..) => {} } if !is_inline { self.hardbreak_if_not_bol(); @@ -691,6 +691,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere )); self.hardbreak() } + AttrKind::Generated(generated) => self.word(generated.descr()), } true } diff --git a/compiler/rustc_attr_parsing/src/generated.rs b/compiler/rustc_attr_parsing/src/generated.rs new file mode 100644 index 0000000000000..3f2e4eec226fb --- /dev/null +++ b/compiler/rustc_attr_parsing/src/generated.rs @@ -0,0 +1,54 @@ +use std::num::NonZero; + +use rustc_ast::GeneratedAttr; +use rustc_attr_ir::{ + Attribute, AttributeKind, CoverageAttrKind, DocAttribute, InlineAttr, PartialConstStability, + StabilityLevel, UnstableReason, +}; +use rustc_span::{Span, sym}; +use thin_vec::ThinVec; + +/// Contains the state necessary to convert generated attributes to parsed attributes. + +#[derive(Default)] +pub(crate) struct GeneratedAttrState { + state: ThinVec, +} + +impl GeneratedAttrState { + pub(crate) fn accept_generated_attr(&mut self, span: Span, generated: &GeneratedAttr) { + let attr = match *generated { + GeneratedAttr::AutomaticallyDerived => AttributeKind::AutomaticallyDerived, + GeneratedAttr::RustcConstUnstableDerived => AttributeKind::RustcConstStability { + stability: PartialConstStability { + feature: sym::derive_const, + promotable: false, + level: StabilityLevel::Unstable { + reason: UnstableReason::None, + implied_by: None, + issue: NonZero::new(143874), + old_name: None, + }, + }, + span, + }, + GeneratedAttr::Inline => AttributeKind::Inline(InlineAttr::Hint, span), + GeneratedAttr::DocHidden => AttributeKind::Doc(Box::new({ + let mut d = DocAttribute::default(); + d.hidden = Some(span); + d + })), + GeneratedAttr::CoverageOff => AttributeKind::Coverage(CoverageAttrKind::Off), + GeneratedAttr::RustcTestMarker(test_marker) => { + AttributeKind::RustcTestMarker(test_marker) + } + }; + self.state.push(attr); + } + + pub(crate) fn finalize_generated_attrs(self, attributes: &mut Vec) { + for attr in self.state { + attributes.push(Attribute::Parsed(attr)) + } + } +} diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index 567fa622725bc..6895dda06cb6a 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -21,6 +21,7 @@ use crate::context::{ FinalizeFn, FinalizeOutput, SharedContext, }; use crate::diagnostics::ParsedDescription; +use crate::generated::GeneratedAttrState; use crate::parser::{AllowExprMetavar, ArgParser, PathParser, RefPathParser}; use crate::synthetic::SyntheticAttrState; use crate::{AttributeTemplate, ShouldEmit}; @@ -325,6 +326,7 @@ impl<'sess> AttributeParser<'sess> { let mut attributes = Vec::new(); let mut attr_paths: Vec> = Vec::new(); let mut synthetic_attr_state = SyntheticAttrState::default(); + let mut generated_attr_state = GeneratedAttrState::default(); let mut finalizers: Vec = Vec::with_capacity(attrs.len()); @@ -349,6 +351,9 @@ impl<'sess> AttributeParser<'sess> { ast::AttrKind::Synthetic(synthetic) => { synthetic_attr_state.accept_synthetic_attr(attr_span, lower_span, synthetic); } + ast::AttrKind::Generated(generated) => { + generated_attr_state.accept_generated_attr(attr_span, generated) + } ast::AttrKind::Normal(n) => { attr_paths.push(PathParser(&n.item.path)); let attr_path = AttrPath::from_ast(&n.item.path, lower_span); @@ -471,6 +476,7 @@ impl<'sess> AttributeParser<'sess> { } synthetic_attr_state.finalize_synthetic_attrs(&mut attributes); + generated_attr_state.finalize_generated_attrs(&mut attributes); // First, run all finalizers to produce the parsed attributes. Cross-attribute // checks that need to inspect the fully parsed attributes are deferred until all diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index c0ed62dd51b59..4e6b8b2d38f3b 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -101,6 +101,7 @@ mod attributes; mod check_cfg; mod context; mod diagnostics; +mod generated; mod interface; pub mod parser; mod safety; diff --git a/compiler/rustc_attr_parsing/src/validate_attr.rs b/compiler/rustc_attr_parsing/src/validate_attr.rs index 4719ee5103877..4e73f5dc9ea1b 100644 --- a/compiler/rustc_attr_parsing/src/validate_attr.rs +++ b/compiler/rustc_attr_parsing/src/validate_attr.rs @@ -24,7 +24,9 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) { use ast::SyntheticAttr::*; match &attr.kind { AttrKind::Normal(_) => {} - AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) | AttrKind::DocComment(..) => return, + AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) + | AttrKind::DocComment(..) + | AttrKind::Generated(..) => return, } let builtin_attr_info = attr.name().and_then(|name| BUILTIN_ATTRIBUTE_SET.get(&name)); diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index 6503c34966415..c0ebb2f20fa86 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -92,7 +92,7 @@ pub(crate) fn expand_deriving_clone( nonself_args: SmallVec::new(), has_other_selflike_arg: false, ret_ty: cx.ty_self(span), - attributes: thin_vec![cx.attr_word(sym::inline, span)], + attributes: thin_vec![cx.generated_attr(span, ast::GeneratedAttr::Inline)], fieldless_variants_strategy: FieldlessVariantsStrategy::Default, combine_substructure: substructure, }], diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index d9a47ef3e2708..ebd1173851bde 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -86,7 +86,7 @@ pub(crate) fn expand_deriving_coerce_pointee( // Declare helper function that adds implementation blocks. // FIXME(dingxiangfei2009): Investigate the set of attributes on target struct to be propagated to impls - let attrs = thin_vec![cx.attr_word(sym::automatically_derived, span),]; + let attrs = thin_vec![cx.generated_attr(span, ast::GeneratedAttr::AutomaticallyDerived)]; // # Validity assertion which will be checked later in `rustc_hir_analysis::coherence::builtins`. { let trait_path = path_std!(cx, span, marker::CoercePointeeValidated); diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 5343f043e6478..0be5f36de980b 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -42,7 +42,7 @@ pub(crate) fn expand_deriving_debug( nonself_args: smallvec![(fmtr, sym::f)], has_other_selflike_arg: false, ret_ty: cx.ty_path(path_std!(cx, span, fmt::Result)), - attributes: thin_vec![cx.attr_word(sym::inline, span)], + attributes: thin_vec![cx.generated_attr(span, ast::GeneratedAttr::Inline)], fieldless_variants_strategy: FieldlessVariantsStrategy::Default, combine_substructure: combine_substructure(|cx, span, substr| show_substructure( cx, diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 11955b1df9ef2..ea990b4524d72 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -33,7 +33,7 @@ pub(crate) fn expand_deriving_default( nonself_args: SmallVec::new(), has_other_selflike_arg: false, ret_ty: cx.ty_self(span), - attributes: thin_vec![cx.attr_word(sym::inline, span)], + attributes: thin_vec![cx.generated_attr(span, ast::GeneratedAttr::Inline)], fieldless_variants_strategy: FieldlessVariantsStrategy::Default, combine_substructure: combine_substructure(|cx, trait_span, substr| { match substr { diff --git a/compiler/rustc_builtin_macros/src/deriving/eq.rs b/compiler/rustc_builtin_macros/src/deriving/eq.rs index 8659b761f25c5..dc932d76b51c1 100644 --- a/compiler/rustc_builtin_macros/src/deriving/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/eq.rs @@ -32,9 +32,9 @@ pub(crate) fn expand_deriving_eq( attributes: thin_vec![ // This method will never be called, so doing codegen etc. for it is unnecessary. // We prevent this by adding `#[inline]`, which improves compile-time. - cx.attr_word(sym::inline, span), - cx.attr_nested_word(sym::doc, sym::hidden, span), - cx.attr_nested_word(sym::coverage, sym::off, span), + cx.generated_attr(span, ast::GeneratedAttr::Inline), + cx.generated_attr(span, ast::GeneratedAttr::DocHidden), + cx.generated_attr(span, ast::GeneratedAttr::CoverageOff), ], fieldless_variants_strategy: FieldlessVariantsStrategy::Unify, combine_substructure: combine_substructure(cs_total_eq_assert), diff --git a/compiler/rustc_builtin_macros/src/deriving/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index c7d06a3cdfb35..20867e8e063aa 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -81,7 +81,7 @@ pub(crate) fn expand_deriving_from( nonself_args: smallvec![(from_type, sym::value)], has_other_selflike_arg: false, ret_ty: cx.ty_self(span), - attributes: thin_vec![cx.attr_word(sym::inline, span)], + attributes: thin_vec![cx.generated_attr(span, ast::GeneratedAttr::Inline)], fieldless_variants_strategy: FieldlessVariantsStrategy::Default, combine_substructure: combine_substructure(|cx, span, substructure| { let field = match field { diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 37e9c99d1acae..372df146960a8 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -178,11 +178,8 @@ use std::ops::Not; pub(crate) use Substructure::*; pub(crate) use rustc_ast as ast; -use rustc_ast::token::{IdentKind, LitKind, Token, TokenKind}; -use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenTree}; use rustc_ast::{ - AttrArgs, DelimArgs, EnumDef, Expr, GenericArg, GenericParam, GenericParamKind, Generics, - Safety, VariantData, + EnumDef, Expr, GenericArg, GenericParam, GenericParamKind, Generics, Safety, VariantData, }; use rustc_attr_ir::{Attribute, AttributeKind, ReprPacked}; use rustc_attr_parsing::AttributeParser; @@ -705,47 +702,18 @@ impl<'a> TraitDef<'a> { let path = cx.path_all(type_ident.span.with_ctxt(ctxt), &[type_ident], self_params); let self_type = cx.ty_path(path); - let mut attrs = thin_vec![cx.attr_word(sym::automatically_derived, self.span),]; + let mut attrs = + thin_vec![cx.generated_attr(self.span, ast::GeneratedAttr::AutomaticallyDerived)]; // Only add `rustc_const_unstable` attributes if `derive_const` is used within libcore/libstd, // Other crates don't need stability attributes, so adding them is not useful, but libcore needs them // on all const trait impls. if self.is_const && cx.ecfg.features.staged_api() { - let rustc_const_unstable = cx.path_name(self.span, sym::rustc_const_unstable); - - // #[rustc_const_unstable(feature = "derive_const", issue = "143874")] - attrs.push( - cx.attr_nested( - rustc_ast::AttrItem { - unsafety: Safety::Default, - path: rustc_const_unstable, - args: AttrArgs::Delimited(DelimArgs { - dspan: DelimSpan::from_single(self.span), - delim: rustc_ast::token::Delimiter::Parenthesis, - tokens: [ - TokenKind::Ident(sym::feature, IdentKind::Normal), - TokenKind::Eq, - TokenKind::lit(LitKind::Str, sym::derive_const, None), - TokenKind::Comma, - TokenKind::Ident(sym::issue, IdentKind::Normal), - TokenKind::Eq, - TokenKind::lit(LitKind::Str, sym::derive_const_issue, None), - ] - .into_iter() - .map(|kind| { - TokenTree::Token(Token { kind, span: self.span }, Spacing::Alone) - }) - .collect(), - }), - span: self.span, - }, - self.span, - ), - ) + attrs.push(cx.generated_attr(self.span, ast::GeneratedAttr::RustcConstUnstableDerived)); } if !self.document { - attrs.push(cx.attr_nested_word(sym::doc, sym::hidden, self.span)); + attrs.push(cx.generated_attr(self.span, ast::GeneratedAttr::DocHidden)); } cx.item_trait_impl( diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index a38a63b8e5cdd..c351d2955870f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -41,7 +41,7 @@ pub(crate) fn expand_deriving_hash( nonself_args: smallvec![(cx.ty_ref(span, arg, None, Mutability::Mut), sym::state)], has_other_selflike_arg: false, ret_ty: cx.ty_unit(span), - attributes: thin_vec![cx.attr_word(sym::inline, span)], + attributes: thin_vec![cx.generated_attr(span, ast::GeneratedAttr::Inline)], fieldless_variants_strategy: FieldlessVariantsStrategy::Unify, combine_substructure: combine_substructure(hash_substructure), }], diff --git a/compiler/rustc_builtin_macros/src/deriving/ord.rs b/compiler/rustc_builtin_macros/src/deriving/ord.rs index 6f86216daa80f..d8e5259f5b438 100644 --- a/compiler/rustc_builtin_macros/src/deriving/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/ord.rs @@ -28,7 +28,7 @@ pub(crate) fn expand_deriving_ord( nonself_args: smallvec![(cx.ty_self_ref(span), sym::other)], has_other_selflike_arg: true, ret_ty: cx.ty_path(path_std!(cx, span, cmp::Ordering)), - attributes: thin_vec![cx.attr_word(sym::inline, span)], + attributes: thin_vec![cx.generated_attr(span, ast::GeneratedAttr::Inline)], fieldless_variants_strategy: FieldlessVariantsStrategy::Unify, combine_substructure: combine_substructure(|cx, span, substr| cs_cmp( cx, diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs index 81dbf357e0ec3..d82384ae3cd92 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs @@ -42,7 +42,7 @@ pub(crate) fn expand_deriving_partial_eq( nonself_args: smallvec![(cx.ty_self_ref(span), sym::other)], has_other_selflike_arg: true, ret_ty: cx.ty_name(span, sym::bool), - attributes: thin_vec![cx.attr_word(sym::inline, span)], + attributes: thin_vec![cx.generated_attr(span, ast::GeneratedAttr::Inline)], fieldless_variants_strategy: FieldlessVariantsStrategy::Unify, combine_substructure: combine_substructure(get_substructure_equality_expr), }]; diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs index 70d2877ec9afa..4a7905f81ae50 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs @@ -60,7 +60,7 @@ pub(crate) fn expand_deriving_partial_ord( nonself_args: smallvec![(cx.ty_self_ref(span), sym::other)], has_other_selflike_arg: true, ret_ty, - attributes: thin_vec![cx.attr_word(sym::inline, span)], + attributes: thin_vec![cx.generated_attr(span, ast::GeneratedAttr::Inline)], fieldless_variants_strategy: FieldlessVariantsStrategy::Unify, combine_substructure: if is_simple { simple_substructure } else { default_substructure }, }; diff --git a/compiler/rustc_builtin_macros/src/deriving/reborrow.rs b/compiler/rustc_builtin_macros/src/deriving/reborrow.rs index 5380d1eae3ace..ec063c926fafb 100644 --- a/compiler/rustc_builtin_macros/src/deriving/reborrow.rs +++ b/compiler/rustc_builtin_macros/src/deriving/reborrow.rs @@ -124,7 +124,7 @@ fn push_marker_impl( push(cx.item_trait_impl( span, - thin_vec::thin_vec![cx.attr_word(sym::automatically_derived, span)], + thin_vec::thin_vec![cx.generated_attr(span, ast::GeneratedAttr::AutomaticallyDerived)], generics_without_defaults(generics), ast::Safety::Default, false, diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index a6f7d3c244045..6cb6e0df869e9 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -241,6 +241,7 @@ fn split_attrs( } } } + AttrKind::Generated(..) => unreachable!(), } } diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 65c905212bee9..5f86842ae75e8 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -3,7 +3,7 @@ use std::{assert_matches, iter}; -use rustc_ast::{self as ast, GenericParamKind, Mutability, attr, join_path_idents}; +use rustc_ast::{self as ast, GeneratedAttr, GenericParamKind, Mutability, attr, join_path_idents}; use rustc_ast_pretty::pprust; use rustc_attr_ir::{Attribute, AttributeKind}; use rustc_attr_parsing::AttributeParser; @@ -65,7 +65,9 @@ pub(crate) fn expand_test_case( ident, )); item.vis = ast::Visibility { span: item.vis.span, kind: ast::VisibilityKind::Public }; - item.attrs.push(ecx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, sp)); + item.attrs.push( + ecx.generated_attr(attr_sp, GeneratedAttr::RustcTestMarker(test_path_symbol)), + ); } _ => {} } @@ -188,7 +190,7 @@ pub(crate) fn expand_test_or_bench( // corresponding macro declaration in `core::macros`. let coverage_off = |mut expr: Box| { assert_matches!(expr.kind, ast::ExprKind::Closure(_)); - expr.attrs.push(cx.attr_nested_word(sym::coverage, sym::off, sp)); + expr.attrs.push(cx.generated_attr(sp, GeneratedAttr::CoverageOff)); expr }; @@ -266,9 +268,9 @@ pub(crate) fn expand_test_or_bench( // #[cfg(test)] cx.attr_nested_word(sym::cfg, sym::test, attr_sp), // #[rustc_test_marker = "test_case_sort_key"] - cx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, attr_sp), + cx.generated_attr(attr_sp, GeneratedAttr::RustcTestMarker(test_path_symbol)), // #[doc(hidden)] - cx.attr_nested_word(sym::doc, sym::hidden, attr_sp), + cx.generated_attr(attr_sp, GeneratedAttr::DocHidden), ], Ident::new(fn_.ident.name, sp), cx.ty_path(test_path("TestDescAndFn")), diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 7c19ffc331364..11c5e388f5ade 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -8,7 +8,7 @@ use rustc_ast::attr::contains_name; use rustc_ast::entry::EntryPointType; use rustc_ast::mut_visit::*; use rustc_ast::visit::Visitor; -use rustc_ast::{ModKind, attr}; +use rustc_ast::{GeneratedAttr, ModKind, attr}; use rustc_attr_ir::AttributeKind; use rustc_attr_parsing::AttributeParser; use rustc_expand::base::{ExtCtxt, ResolverExpand}; @@ -317,9 +317,9 @@ fn add_main(cx: &mut TestCtxt<'_>, c: &mut ast::Crate) { // #[rustc_main] let main_attr = ecx.attr_word(sym::rustc_main, sp); // #[coverage(off)] - let coverage_attr = ecx.attr_nested_word(sym::coverage, sym::off, sp); + let coverage_attr = ecx.generated_attr(sp, GeneratedAttr::CoverageOff); // #[doc(hidden)] - let doc_hidden_attr = ecx.attr_nested_word(sym::doc, sym::hidden, sp); + let doc_hidden_attr = ecx.generated_attr(sp, GeneratedAttr::DocHidden); // pub fn main() -> ExitCode { ... } let main_ret_ty = if cx.test_runner.is_none() { diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 1c9c4b6a7c303..34b4697c572c4 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -786,4 +786,13 @@ impl<'a> ExtCtxt<'a> { span, } } + pub fn generated_attr(&self, span: Span, generated: ast::GeneratedAttr) -> ast::Attribute { + let id = self.sess.psess.attr_id_generator.mk_attr_id(); + ast::Attribute { + kind: ast::AttrKind::Generated(generated), + id, + span, + style: ast::AttrStyle::Outer, + } + } } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 09335b42958c7..1909712888828 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -2297,7 +2297,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { ); } AttrKind::Normal(_) => {} - AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) => {} + AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) | AttrKind::Generated(..) => {} AttrKind::DocComment(..) => unreachable!(), // handled above } } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 2b1e0a24294d2..d19d6a0da98ac 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -771,7 +771,7 @@ fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: & AttrKind::DocComment(CommentKind::Block, _) => { BuiltinUnusedDocCommentSub::BlockHelp } - AttrKind::Synthetic(..) => unreachable!(), + AttrKind::Synthetic(..) | AttrKind::Generated(..) => unreachable!(), }; cx.emit_span_lint( UNUSED_DOC_COMMENTS, diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index fe34d9951dc5f..99fe984401ef8 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -423,5 +423,6 @@ fn needs_tokens(attrs: &[ast::Attribute]) -> bool { // because they have no token form. AttrKind::Synthetic(_) => unreachable!(), AttrKind::DocComment(..) => false, + AttrKind::Generated(..) => unreachable!(), }) } diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index d8524efb35bc2..bdd300aee372a 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -781,7 +781,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { fn visit_attribute(&mut self, attr: &'v ast::Attribute) { record_variants!( (self, attr, attr.kind, None, ast, Attribute, AttrKind), - [Normal, Synthetic, DocComment] + [Normal, Synthetic, DocComment, Generated] ); ast_visit::walk_attribute(self, attr) } diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 3cf8be2fcbc0d..1b0045d4e02f3 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -570,6 +570,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { } AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) => {} AttrKind::DocComment(..) => {} + AttrKind::Generated(..) => {} } visit::walk_attribute(self, attr); self.invocation_parent.in_attr = orig_in_attr; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 89deeb44cf1b2..95197e6c98a9f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -836,7 +836,6 @@ symbols! { deref_target, derive, derive_const, - derive_const_issue: "143874", derive_default_enum, derive_from, derive_smart_pointer, diff --git a/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs b/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs index c9cbf29f2b670..fbd2d7b95c42b 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs @@ -34,6 +34,7 @@ impl From<&AttrKind> for SimpleAttrKind { SyntheticAttr::CfgAttrTrace(_) => Self::CfgAttrTrace, }, AttrKind::DocComment(..) => Self::Doc, + AttrKind::Generated(generated) => Self::Normal(vec![generated.name().unwrap()]) } } } diff --git a/src/tools/clippy/clippy_lints/src/empty_line_after.rs b/src/tools/clippy/clippy_lints/src/empty_line_after.rs index 805f5dca1bf5d..4deea3e1b786b 100644 --- a/src/tools/clippy/clippy_lints/src/empty_line_after.rs +++ b/src/tools/clippy/clippy_lints/src/empty_line_after.rs @@ -250,7 +250,7 @@ impl Stop { Some(Self { span: attr.span, kind: match attr.kind { - AttrKind::Normal(_) | AttrKind::Synthetic(_) => StopKind::Attr, + AttrKind::Normal(_) | AttrKind::Synthetic(_) | AttrKind::Generated(..) => StopKind::Attr, AttrKind::DocComment(comment_kind, _) => StopKind::Doc(comment_kind), }, first: file.lookup_line(file.relative_position(lo))?, diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs index 828fb1d3313b4..9e7cff58d9aca 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -370,7 +370,7 @@ fn attr_search_pat(attr: &Attribute) -> (Pat, Pat) { (Pat::Str("#"), Pat::Str("]")) } }, - AttrKind::Synthetic(..) => unreachable!(), + AttrKind::Synthetic(..) | AttrKind::Generated (..) => unreachable!(), AttrKind::DocComment(_kind @ CommentKind::Line, ..) => { if attr.style == AttrStyle::Outer { (Pat::Str("///"), Pat::Str("")) diff --git a/tests/ui/stats/macro-stats.stderr b/tests/ui/stats/macro-stats.stderr index e549d315e7fdb..e4f5a95ac7fad 100644 --- a/tests/ui/stats/macro-stats.stderr +++ b/tests/ui/stats/macro-stats.stderr @@ -2,16 +2,16 @@ macro-stats ==================================================================== macro-stats MACRO EXPANSION STATS: macro_stats macro-stats Macro Name Uses Lines Avg Lines Bytes Avg Bytes macro-stats ----------------------------------------------------------------------------------- -macro-stats #[derive(Clone)] 8 67 8.4 1_895 236.9 -macro-stats #[derive(Hash)] 2 17 8.5 536 268.0 +macro-stats #[derive(Clone)] 8 59 7.4 1_889 236.1 +macro-stats #[derive(Hash)] 2 15 7.5 534 267.0 macro-stats q! 1 26 26.0 519 519.0 -macro-stats #[derive(Ord)] 1 15 15.0 505 505.0 -macro-stats #[derive(Default)] 2 16 8.0 407 203.5 -macro-stats #[derive(Eq)] 1 11 11.0 312 312.0 -macro-stats #[derive(Debug)] 1 8 8.0 277 277.0 -macro-stats #[derive(PartialEq)] 1 9 9.0 269 269.0 -macro-stats #[derive(PartialOrd)] 1 8 8.0 256 256.0 -macro-stats #[derive(Copy)] 1 2 2.0 61 61.0 +macro-stats #[derive(Ord)] 1 14 14.0 504 504.0 +macro-stats #[derive(Default)] 2 14 7.0 405 202.5 +macro-stats #[derive(Eq)] 1 10 10.0 311 311.0 +macro-stats #[derive(Debug)] 1 7 7.0 276 276.0 +macro-stats #[derive(PartialEq)] 1 7 7.0 267 267.0 +macro-stats #[derive(PartialOrd)] 1 7 7.0 255 255.0 +macro-stats #[derive(Copy)] 1 1 1.0 60 60.0 macro-stats p! 1 3 3.0 32 32.0 macro-stats trait_impl_tys! 1 2 2.0 28 28.0 macro-stats foreign_item! 1 1 1.0 21 21.0