From 3f3d8ba2734b316e5566e34032e956c1db5aa74e Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 18 Sep 2026 11:30:03 -0300 Subject: [PATCH 1/3] Add AllowInternalUnstable enum to avoid Arc clones for static desugaring feature lists --- compiler/rustc_ast_lowering/src/contract.rs | 7 ++- compiler/rustc_ast_lowering/src/expr.rs | 26 ++++++----- compiler/rustc_ast_lowering/src/lib.rs | 20 ++++---- compiler/rustc_ast_lowering/src/pat.rs | 7 ++- compiler/rustc_ast_lowering/src/path.rs | 11 ++--- compiler/rustc_expand/src/base.rs | 14 ++++-- compiler/rustc_resolve/src/macros.rs | 8 ++-- compiler/rustc_span/src/hygiene.rs | 52 +++++++++++++++++++-- 8 files changed, 100 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/contract.rs b/compiler/rustc_ast_lowering/src/contract.rs index eaebff521cb68..a7a6c390d82fd 100644 --- a/compiler/rustc_ast_lowering/src/contract.rs +++ b/compiler/rustc_ast_lowering/src/contract.rs @@ -1,6 +1,5 @@ -use std::sync::Arc; - use rustc_hir::attrs::lang_items::LangItem; +use rustc_span::hygiene::AllowInternalUnstable; use thin_vec::thin_vec; use crate::LoweringContext; @@ -143,7 +142,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let req_span = self.mark_span_with_reason( rustc_span::DesugaringKind::Contract, lowered_req.span, - Some(Arc::clone(&crate::ALLOW_CONTRACTS)), + Some(AllowInternalUnstable::Static(crate::ALLOW_CONTRACTS)), ); let precond = self.expr_call_lang_item_fn_mut( req_span, @@ -161,7 +160,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let ens_span = self.mark_span_with_reason( rustc_span::DesugaringKind::Contract, ens_span, - Some(Arc::clone(&crate::ALLOW_CONTRACTS)), + Some(AllowInternalUnstable::Static(crate::ALLOW_CONTRACTS)), ); let lowered_ens = self.lower_expr_mut(&ens); self.expr_call_lang_item_fn( diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 1c1b9a247f7a2..2236d49087f5a 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1,6 +1,5 @@ use std::mem; use std::ops::ControlFlow; -use std::sync::Arc; use rustc_ast::node_id::NodeMap; use rustc_ast::visit::{Visitor, walk_expr}; @@ -13,6 +12,7 @@ use rustc_hir::HirId; use rustc_hir::def::{DefKind, Res}; use rustc_middle::ty::TyCtxt; use rustc_session::diagnostics::report_lit_error; +use rustc_span::hygiene::AllowInternalUnstable; use rustc_span::{ ByteSymbol, DUMMY_SP, DesugaringKind, Ident, Span, Spanned, Symbol, respan, span_bug, sym, }; @@ -742,7 +742,7 @@ impl<'hir> LoweringContext<'_, 'hir> { this.mark_span_with_reason( DesugaringKind::TryBlock, expr.span, - Some(Arc::clone(&crate::ALLOW_TRY_TRAIT)), + Some(AllowInternalUnstable::Static(crate::ALLOW_TRY_TRAIT)), ), expr, ) @@ -750,7 +750,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let try_span = this.mark_span_with_reason( DesugaringKind::TryBlock, this.tcx.sess.source_map().end_point(body.span), - Some(Arc::clone(&crate::ALLOW_TRY_TRAIT)), + Some(AllowInternalUnstable::Static(crate::ALLOW_TRY_TRAIT)), ); (try_span, this.expr_unit(try_span)) @@ -878,7 +878,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let unstable_span = self.mark_span_with_reason( DesugaringKind::Async, self.lower_span(span), - Some(Arc::clone(self.allow_gen_future())), + Some(self.allow_gen_future()), ); let resume_ty = self.make_lang_item_qpath(LangItem::ResumeTy, unstable_span, None); let input_ty = hir::Ty { @@ -1037,15 +1037,19 @@ impl<'hir> LoweringContext<'_, 'hir> { }; let features = match await_kind { - FutureKind::Future if is_async_gen => Some(Arc::clone(&crate::ALLOW_ASYNC_GEN)), + FutureKind::Future if is_async_gen => { + Some(AllowInternalUnstable::Static(crate::ALLOW_ASYNC_GEN)) + } FutureKind::Future => None, - FutureKind::AsyncIterator => Some(Arc::clone(&crate::ALLOW_FOR_AWAIT)), + FutureKind::AsyncIterator => { + Some(AllowInternalUnstable::Static(crate::ALLOW_FOR_AWAIT)) + } }; let span = self.mark_span_with_reason(DesugaringKind::Await, await_kw_span, features); let gen_future_span = self.mark_span_with_reason( DesugaringKind::Await, full_span, - Some(Arc::clone(self.allow_gen_future())), + Some(self.allow_gen_future()), ); let expr_hir_id = expr.hir_id; @@ -1727,7 +1731,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let desugar_span = self.mark_span_with_reason( DesugaringKind::Async, span, - Some(Arc::clone(&crate::ALLOW_ASYNC_GEN)), + Some(AllowInternalUnstable::Static(crate::ALLOW_ASYNC_GEN)), ); let wrapped_yielded = self.expr_call_lang_item_fn( desugar_span, @@ -1946,13 +1950,13 @@ impl<'hir> LoweringContext<'_, 'hir> { let unstable_span = self.mark_span_with_reason( DesugaringKind::QuestionMark, span, - Some(Arc::clone(&crate::ALLOW_TRY_TRAIT)), + Some(AllowInternalUnstable::Static(crate::ALLOW_TRY_TRAIT)), ); let try_span = self.tcx.sess.source_map().end_point(span); let try_span = self.mark_span_with_reason( DesugaringKind::QuestionMark, try_span, - Some(Arc::clone(&crate::ALLOW_TRY_TRAIT)), + Some(AllowInternalUnstable::Static(crate::ALLOW_TRY_TRAIT)), ); // `Try::branch()` @@ -2049,7 +2053,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let unstable_span = self.mark_span_with_reason( DesugaringKind::YeetExpr, span, - Some(Arc::clone(&crate::ALLOW_TRY_TRAIT)), + Some(AllowInternalUnstable::Static(crate::ALLOW_TRY_TRAIT)), ); let from_yeet_expr = self.wrap_in_try_constructor( diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 19c37f4a76065..a3f9bd649d471 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -39,7 +39,7 @@ // tidy-alphabetical-end use std::mem; -use std::sync::{Arc, LazyLock}; +use std::sync::Arc; use rustc_ast::mut_visit::{self, MutVisitor}; use rustc_ast::node_id::NodeMap; @@ -71,6 +71,7 @@ use rustc_middle::middle::resolve::{ use rustc_middle::queries::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::diagnostics::add_feature_diagnostics; +use rustc_span::hygiene::AllowInternalUnstable; use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_span::{DUMMY_SP, DesugaringKind, Span, span_bug}; use smallvec::{SmallVec, smallvec}; @@ -327,7 +328,7 @@ struct LoweringContext<'a, 'hir> { macro_rules! allow { ($($name:ident: $list:expr;)*) => { - $( static $name: LazyLock> = LazyLock::new(|| $list.into()); )* + $( const $name: &[Symbol] = &$list; )* } } @@ -383,11 +384,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.tcx.dcx() } - fn allow_gen_future(&self) -> &Arc<[Symbol]> { + fn allow_gen_future(&self) -> AllowInternalUnstable { if self.tcx.features().async_fn_track_caller() { - &ALLOW_GEN_FUTURE_WITH_ASYNC_FN_TRACK_CALLER + AllowInternalUnstable::Static(ALLOW_GEN_FUTURE_WITH_ASYNC_FN_TRACK_CALLER) } else { - &ALLOW_GEN_FUTURE + AllowInternalUnstable::Static(ALLOW_GEN_FUTURE) } } } @@ -1053,7 +1054,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &self, reason: DesugaringKind, span: Span, - allow_internal_unstable: Option>, + allow_internal_unstable: Option, ) -> Span { self.tcx.with_stable_hashing_context(|hcx| { span.mark_with_reason(allow_internal_unstable, reason, span.edition(), hcx) @@ -2094,9 +2095,10 @@ impl<'hir> LoweringContext<'_, 'hir> { let (opaque_ty_node_id, allowed_features) = match coro.kind { CoroutineKind::Async | CoroutineKind::Gen => (coro.return_impl_trait_id, None), - CoroutineKind::AsyncGen => { - (coro.return_impl_trait_id, Some(Arc::clone(&ALLOW_ASYNC_ITERATOR))) - } + CoroutineKind::AsyncGen => ( + coro.return_impl_trait_id, + Some(AllowInternalUnstable::Static(ALLOW_ASYNC_ITERATOR)), + ), }; let opaque_ty_span = diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 0edba3fe0cd14..dd6bfc9a764ea 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -1,9 +1,8 @@ -use std::sync::Arc; - use rustc_ast::*; use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{self as hir, Target}; +use rustc_span::hygiene::AllowInternalUnstable; use rustc_span::{DesugaringKind, Ident, Span, Spanned, respan, span_bug}; use crate::diagnostics::{ @@ -482,7 +481,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let unstable_span = self.mark_span_with_reason( DesugaringKind::PatTyRange, span, - Some(Arc::clone(&crate::ALLOW_PATTERN_TYPE)), + Some(AllowInternalUnstable::Static(crate::ALLOW_PATTERN_TYPE)), ); let anon_const = self.with_new_scopes(span, |this| { let def_id = this.local_def_id(e.id); @@ -535,7 +534,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let unstable_span = self.mark_span_with_reason( DesugaringKind::PatTyRange, self.lower_span(span), - Some(Arc::clone(&crate::ALLOW_PATTERN_TYPE)), + Some(AllowInternalUnstable::Static(crate::ALLOW_PATTERN_TYPE)), ); let span = self.lower_span(base_type); diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 14f10e2b1c416..e6484c31e9c9b 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -1,5 +1,3 @@ -use std::sync::Arc; - use rustc_ast::{self as ast, *}; use rustc_errors::StashKey; use rustc_hir::def::{DefKind, PerNS, Res}; @@ -8,7 +6,8 @@ use rustc_hir::{self as hir, GenericArg}; use rustc_middle::middle::resolve::PartialRes; use rustc_middle::ty; use rustc_session::diagnostics::add_feature_diagnostics; -use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Ident, Span, Symbol, span_bug, sym}; +use rustc_span::hygiene::AllowInternalUnstable; +use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Ident, Span, span_bug, sym}; use smallvec::smallvec; use tracing::{debug, instrument}; @@ -75,7 +74,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let bound_modifier_allowed_features = if let Res::Def(DefKind::Trait, async_def_id) = res && self.tcx.async_fn_trait_kind_from_def_id(async_def_id).is_some() { - Some(Arc::clone(&crate::ALLOW_ASYNC_FN_TRAITS)) + Some(AllowInternalUnstable::Static(crate::ALLOW_ASYNC_FN_TRAITS)) } else { None }; @@ -260,7 +259,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Additional features ungated with a bound modifier like `async`. // This is passed down to the implicit associated type binding in // parenthesized bounds. - bound_modifier_allowed_features: Option>, + bound_modifier_allowed_features: Option, ) -> hir::PathSegment<'hir> { debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment); let (mut generic_args, infer_args) = if let Some(generic_args) = segment.args.as_deref() { @@ -507,7 +506,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, data: &ParenthesizedArgs, itctx: ImplTraitContext, - bound_modifier_allowed_features: Option>, + bound_modifier_allowed_features: Option, ) -> (GenericArgsCtor<'hir>, bool) { // Switch to `PassThrough` mode for anonymous lifetimes; this // means that we permit things like `&Ref`, where `Ref` has diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index fda75319b087b..fb6ed4196f187 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -22,7 +22,9 @@ use rustc_session::Session; use rustc_session::parse::ParseSess; use rustc_span::def_id::{CrateNum, DefId, LocalDefId, ModId}; use rustc_span::edition::Edition; -use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind}; +use rustc_span::hygiene::{ + AllowInternalUnstable, AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind, +}; use rustc_span::source_map::SourceMap; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw}; use rustc_structures::{CollapseMacroDebuginfo, Limit}; @@ -777,7 +779,7 @@ pub struct SyntaxExtension { /// Span of the macro definition. pub span: Span, /// List of unstable features that are treated as stable inside this macro. - pub allow_internal_unstable: Option>, + pub allow_internal_unstable: Option, /// The macro's stability info. pub stability: Option, /// The macro's deprecation info. @@ -913,7 +915,11 @@ impl SyntaxExtension { span, allow_internal_unstable: (!allow_internal_unstable.is_empty()) // FIXME(jdonszelmann): avoid the into_iter/collect? - .then(|| allow_internal_unstable.iter().map(|i| i.0).collect::>().into()), + .then(|| { + AllowInternalUnstable::Dynamic( + allow_internal_unstable.iter().map(|i| i.0).collect::>().into(), + ) + }), stability, deprecation: find_attr!( attrs, @@ -1045,7 +1051,7 @@ pub trait ResolverExpand { &mut self, call_site: Span, pass: AstPass, - features: &[Symbol], + features: &'static [Symbol], parent_module_id: Option, ) -> LocalExpnId; diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 24a52d4143493..4f85ba8ef155e 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -30,7 +30,9 @@ use rustc_session::Session; use rustc_session::diagnostics::feature_err; use rustc_span::def_id::ModId; use rustc_span::edition::Edition; -use rustc_span::hygiene::{self, AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind}; +use rustc_span::hygiene::{ + self, AllowInternalUnstable, AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind, +}; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; use crate::Namespace::*; @@ -226,7 +228,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { &mut self, call_site: Span, pass: AstPass, - features: &[Symbol], + features: &'static [Symbol], parent_module_id: Option, ) -> LocalExpnId { let parent_module = parent_module_id @@ -237,7 +239,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { ExpnKind::AstPass(pass), call_site, self.tcx.sess.edition(), - features.into(), + AllowInternalUnstable::Static(features), None, parent_module, ), diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index a081bd1b65e92..1584e9057e08f 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -26,6 +26,7 @@ use std::cell::RefCell; use std::hash::Hash; +use std::ops::Deref; use std::sync::Arc; use std::{fmt, iter, mem}; @@ -963,7 +964,7 @@ impl Span { /// allowed inside this span. pub fn mark_with_reason( self, - allow_internal_unstable: Option>, + allow_internal_unstable: Option, reason: DesugaringKind, edition: Edition, hcx: impl StableHashCtxt, @@ -977,6 +978,49 @@ impl Span { } } +#[derive(Clone)] +pub enum AllowInternalUnstable { + Static(&'static [Symbol]), + Dynamic(Arc<[Symbol]>), +} + +impl Deref for AllowInternalUnstable { + type Target = [Symbol]; + + #[inline] + fn deref(&self) -> &[Symbol] { + match self { + AllowInternalUnstable::Static(s) => s, + AllowInternalUnstable::Dynamic(s) => s, + } + } +} + +impl fmt::Debug for AllowInternalUnstable { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&**self, f) + } +} + +impl StableHash for AllowInternalUnstable { + #[inline] + fn stable_hash(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + (**self).stable_hash(hcx, hasher); + } +} + +impl Encodable for AllowInternalUnstable { + fn encode(&self, e: &mut E) { + (**self).encode(e); + } +} + +impl Decodable for AllowInternalUnstable { + fn decode(d: &mut D) -> AllowInternalUnstable { + AllowInternalUnstable::Dynamic(Decodable::decode(d)) + } +} + /// A subset of properties from both macro definition and macro call available through global data. /// Avoid using this if you have access to the original definition or call structures. #[derive(Clone, Debug, Encodable, Decodable, StableHash)] @@ -1019,7 +1063,7 @@ pub struct ExpnData { /// List of `#[unstable]`/feature-gated features that the macro is allowed to use /// internally without forcing the whole crate to opt-in /// to them. - pub allow_internal_unstable: Option>, + pub allow_internal_unstable: Option, /// Edition of the crate in which the macro is defined. pub edition: Edition, /// The `DefId` of the macro being invoked, @@ -1048,7 +1092,7 @@ impl ExpnData { parent: ExpnId, call_site: Span, def_site: Span, - allow_internal_unstable: Option>, + allow_internal_unstable: Option, edition: Edition, macro_def_id: Option, parent_module: Option, @@ -1103,7 +1147,7 @@ impl ExpnData { kind: ExpnKind, call_site: Span, edition: Edition, - allow_internal_unstable: Arc<[Symbol]>, + allow_internal_unstable: AllowInternalUnstable, macro_def_id: Option, parent_module: Option, ) -> ExpnData { From f9410dbf2f875c53e48670a7b2555c3390b285d8 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 18 Sep 2026 11:34:01 -0300 Subject: [PATCH 2/3] Remove allow macro from ast_lowering and inline const declarations --- compiler/rustc_ast_lowering/src/lib.rs | 32 +++++++++++--------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a3f9bd649d471..658e222f319a8 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -326,25 +326,19 @@ struct LoweringContext<'a, 'hir> { attribute_parser: AttributeParser<'hir>, } -macro_rules! allow { - ($($name:ident: $list:expr;)*) => { - $( const $name: &[Symbol] = &$list; )* - } -} - -allow! { - ALLOW_CONTRACTS: [sym::contracts_internals]; - ALLOW_TRY_TRAIT: [sym::try_trait_v2, sym::try_trait_v2_residual, sym::yeet_desugar_details]; - ALLOW_PATTERN_TYPE: [sym::pattern_types, sym::pattern_type_range_trait]; - ALLOW_GEN_FUTURE: [sym::gen_future]; - ALLOW_GEN_FUTURE_WITH_ASYNC_FN_TRACK_CALLER: [sym::gen_future, sym::closure_track_caller]; - ALLOW_FOR_AWAIT: [sym::async_gen_internals, sym::async_iterator]; - ALLOW_ASYNC_FN_TRAITS: [sym::async_fn_traits]; - ALLOW_ASYNC_GEN: [sym::async_gen_internals]; - // FIXME(gen_blocks): how does `closure_track_caller`/`async_fn_track_caller` - // interact with `gen`/`async gen` blocks - ALLOW_ASYNC_ITERATOR: [sym::gen_future, sym::async_iterator]; -} +const ALLOW_CONTRACTS: &[Symbol] = &[sym::contracts_internals]; +const ALLOW_TRY_TRAIT: &[Symbol] = + &[sym::try_trait_v2, sym::try_trait_v2_residual, sym::yeet_desugar_details]; +const ALLOW_PATTERN_TYPE: &[Symbol] = &[sym::pattern_types, sym::pattern_type_range_trait]; +const ALLOW_GEN_FUTURE: &[Symbol] = &[sym::gen_future]; +const ALLOW_GEN_FUTURE_WITH_ASYNC_FN_TRACK_CALLER: &[Symbol] = + &[sym::gen_future, sym::closure_track_caller]; +const ALLOW_FOR_AWAIT: &[Symbol] = &[sym::async_gen_internals, sym::async_iterator]; +const ALLOW_ASYNC_FN_TRAITS: &[Symbol] = &[sym::async_fn_traits]; +const ALLOW_ASYNC_GEN: &[Symbol] = &[sym::async_gen_internals]; +// FIXME(gen_blocks): how does `closure_track_caller`/`async_fn_track_caller` +// interact with `gen`/`async gen` blocks +const ALLOW_ASYNC_ITERATOR: &[Symbol] = &[sym::gen_future, sym::async_iterator]; impl<'a, 'hir> LoweringContext<'a, 'hir> { fn new(tcx: TyCtxt<'hir>, resolver: &'a ResolverAstLowering<'hir>, owner: NodeId) -> Self { From 0384e80e4c661c57a73cfee947d26ef0f0a42659 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 23 Sep 2026 12:39:22 -0300 Subject: [PATCH 3/3] Let's try Cow --- compiler/rustc_ast_lowering/src/contract.rs | 7 +-- compiler/rustc_ast_lowering/src/expr.rs | 22 ++++---- compiler/rustc_ast_lowering/src/lib.rs | 17 +++--- compiler/rustc_ast_lowering/src/pat.rs | 7 +-- compiler/rustc_ast_lowering/src/path.rs | 11 ++-- .../rustc_data_structures/src/stable_hash.rs | 7 +++ compiler/rustc_expand/src/base.rs | 11 ++-- compiler/rustc_resolve/src/macros.rs | 7 ++- compiler/rustc_span/src/hygiene.rs | 54 ++----------------- 9 files changed, 50 insertions(+), 93 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/contract.rs b/compiler/rustc_ast_lowering/src/contract.rs index a7a6c390d82fd..2969db2d1d5a9 100644 --- a/compiler/rustc_ast_lowering/src/contract.rs +++ b/compiler/rustc_ast_lowering/src/contract.rs @@ -1,5 +1,6 @@ +use std::borrow::Cow; + use rustc_hir::attrs::lang_items::LangItem; -use rustc_span::hygiene::AllowInternalUnstable; use thin_vec::thin_vec; use crate::LoweringContext; @@ -142,7 +143,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let req_span = self.mark_span_with_reason( rustc_span::DesugaringKind::Contract, lowered_req.span, - Some(AllowInternalUnstable::Static(crate::ALLOW_CONTRACTS)), + Some(Cow::Borrowed(crate::ALLOW_CONTRACTS)), ); let precond = self.expr_call_lang_item_fn_mut( req_span, @@ -160,7 +161,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let ens_span = self.mark_span_with_reason( rustc_span::DesugaringKind::Contract, ens_span, - Some(AllowInternalUnstable::Static(crate::ALLOW_CONTRACTS)), + Some(Cow::Borrowed(crate::ALLOW_CONTRACTS)), ); let lowered_ens = self.lower_expr_mut(&ens); self.expr_call_lang_item_fn( diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 2236d49087f5a..8de21291a63e7 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::mem; use std::ops::ControlFlow; @@ -12,7 +13,6 @@ use rustc_hir::HirId; use rustc_hir::def::{DefKind, Res}; use rustc_middle::ty::TyCtxt; use rustc_session::diagnostics::report_lit_error; -use rustc_span::hygiene::AllowInternalUnstable; use rustc_span::{ ByteSymbol, DUMMY_SP, DesugaringKind, Ident, Span, Spanned, Symbol, respan, span_bug, sym, }; @@ -742,7 +742,7 @@ impl<'hir> LoweringContext<'_, 'hir> { this.mark_span_with_reason( DesugaringKind::TryBlock, expr.span, - Some(AllowInternalUnstable::Static(crate::ALLOW_TRY_TRAIT)), + Some(Cow::Borrowed(crate::ALLOW_TRY_TRAIT)), ), expr, ) @@ -750,7 +750,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let try_span = this.mark_span_with_reason( DesugaringKind::TryBlock, this.tcx.sess.source_map().end_point(body.span), - Some(AllowInternalUnstable::Static(crate::ALLOW_TRY_TRAIT)), + Some(Cow::Borrowed(crate::ALLOW_TRY_TRAIT)), ); (try_span, this.expr_unit(try_span)) @@ -1037,13 +1037,9 @@ impl<'hir> LoweringContext<'_, 'hir> { }; let features = match await_kind { - FutureKind::Future if is_async_gen => { - Some(AllowInternalUnstable::Static(crate::ALLOW_ASYNC_GEN)) - } + FutureKind::Future if is_async_gen => Some(Cow::Borrowed(crate::ALLOW_ASYNC_GEN)), FutureKind::Future => None, - FutureKind::AsyncIterator => { - Some(AllowInternalUnstable::Static(crate::ALLOW_FOR_AWAIT)) - } + FutureKind::AsyncIterator => Some(Cow::Borrowed(crate::ALLOW_FOR_AWAIT)), }; let span = self.mark_span_with_reason(DesugaringKind::Await, await_kw_span, features); let gen_future_span = self.mark_span_with_reason( @@ -1731,7 +1727,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let desugar_span = self.mark_span_with_reason( DesugaringKind::Async, span, - Some(AllowInternalUnstable::Static(crate::ALLOW_ASYNC_GEN)), + Some(Cow::Borrowed(crate::ALLOW_ASYNC_GEN)), ); let wrapped_yielded = self.expr_call_lang_item_fn( desugar_span, @@ -1950,13 +1946,13 @@ impl<'hir> LoweringContext<'_, 'hir> { let unstable_span = self.mark_span_with_reason( DesugaringKind::QuestionMark, span, - Some(AllowInternalUnstable::Static(crate::ALLOW_TRY_TRAIT)), + Some(Cow::Borrowed(crate::ALLOW_TRY_TRAIT)), ); let try_span = self.tcx.sess.source_map().end_point(span); let try_span = self.mark_span_with_reason( DesugaringKind::QuestionMark, try_span, - Some(AllowInternalUnstable::Static(crate::ALLOW_TRY_TRAIT)), + Some(Cow::Borrowed(crate::ALLOW_TRY_TRAIT)), ); // `Try::branch()` @@ -2053,7 +2049,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let unstable_span = self.mark_span_with_reason( DesugaringKind::YeetExpr, span, - Some(AllowInternalUnstable::Static(crate::ALLOW_TRY_TRAIT)), + Some(Cow::Borrowed(crate::ALLOW_TRY_TRAIT)), ); let from_yeet_expr = self.wrap_in_try_constructor( diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 658e222f319a8..561a979171cc7 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -38,6 +38,7 @@ #![recursion_limit = "256"] // tidy-alphabetical-end +use std::borrow::Cow; use std::mem; use std::sync::Arc; @@ -71,7 +72,6 @@ use rustc_middle::middle::resolve::{ use rustc_middle::queries::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::diagnostics::add_feature_diagnostics; -use rustc_span::hygiene::AllowInternalUnstable; use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_span::{DUMMY_SP, DesugaringKind, Span, span_bug}; use smallvec::{SmallVec, smallvec}; @@ -378,11 +378,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.tcx.dcx() } - fn allow_gen_future(&self) -> AllowInternalUnstable { + fn allow_gen_future(&self) -> Cow<'static, [Symbol]> { if self.tcx.features().async_fn_track_caller() { - AllowInternalUnstable::Static(ALLOW_GEN_FUTURE_WITH_ASYNC_FN_TRACK_CALLER) + Cow::Borrowed(ALLOW_GEN_FUTURE_WITH_ASYNC_FN_TRACK_CALLER) } else { - AllowInternalUnstable::Static(ALLOW_GEN_FUTURE) + Cow::Borrowed(ALLOW_GEN_FUTURE) } } } @@ -1048,7 +1048,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &self, reason: DesugaringKind, span: Span, - allow_internal_unstable: Option, + allow_internal_unstable: Option>, ) -> Span { self.tcx.with_stable_hashing_context(|hcx| { span.mark_with_reason(allow_internal_unstable, reason, span.edition(), hcx) @@ -2089,10 +2089,9 @@ impl<'hir> LoweringContext<'_, 'hir> { let (opaque_ty_node_id, allowed_features) = match coro.kind { CoroutineKind::Async | CoroutineKind::Gen => (coro.return_impl_trait_id, None), - CoroutineKind::AsyncGen => ( - coro.return_impl_trait_id, - Some(AllowInternalUnstable::Static(ALLOW_ASYNC_ITERATOR)), - ), + CoroutineKind::AsyncGen => { + (coro.return_impl_trait_id, Some(Cow::Borrowed(ALLOW_ASYNC_ITERATOR))) + } }; let opaque_ty_span = diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index dd6bfc9a764ea..d2b0b2e994ab5 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -1,8 +1,9 @@ +use std::borrow::Cow; + use rustc_ast::*; use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{self as hir, Target}; -use rustc_span::hygiene::AllowInternalUnstable; use rustc_span::{DesugaringKind, Ident, Span, Spanned, respan, span_bug}; use crate::diagnostics::{ @@ -481,7 +482,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let unstable_span = self.mark_span_with_reason( DesugaringKind::PatTyRange, span, - Some(AllowInternalUnstable::Static(crate::ALLOW_PATTERN_TYPE)), + Some(Cow::Borrowed(crate::ALLOW_PATTERN_TYPE)), ); let anon_const = self.with_new_scopes(span, |this| { let def_id = this.local_def_id(e.id); @@ -534,7 +535,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let unstable_span = self.mark_span_with_reason( DesugaringKind::PatTyRange, self.lower_span(span), - Some(AllowInternalUnstable::Static(crate::ALLOW_PATTERN_TYPE)), + Some(Cow::Borrowed(crate::ALLOW_PATTERN_TYPE)), ); let span = self.lower_span(base_type); diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index e6484c31e9c9b..01e42437521cf 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; + use rustc_ast::{self as ast, *}; use rustc_errors::StashKey; use rustc_hir::def::{DefKind, PerNS, Res}; @@ -6,8 +8,7 @@ use rustc_hir::{self as hir, GenericArg}; use rustc_middle::middle::resolve::PartialRes; use rustc_middle::ty; use rustc_session::diagnostics::add_feature_diagnostics; -use rustc_span::hygiene::AllowInternalUnstable; -use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Ident, Span, span_bug, sym}; +use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Ident, Span, Symbol, span_bug, sym}; use smallvec::smallvec; use tracing::{debug, instrument}; @@ -74,7 +75,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let bound_modifier_allowed_features = if let Res::Def(DefKind::Trait, async_def_id) = res && self.tcx.async_fn_trait_kind_from_def_id(async_def_id).is_some() { - Some(AllowInternalUnstable::Static(crate::ALLOW_ASYNC_FN_TRAITS)) + Some(Cow::Borrowed(crate::ALLOW_ASYNC_FN_TRAITS)) } else { None }; @@ -259,7 +260,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Additional features ungated with a bound modifier like `async`. // This is passed down to the implicit associated type binding in // parenthesized bounds. - bound_modifier_allowed_features: Option, + bound_modifier_allowed_features: Option>, ) -> hir::PathSegment<'hir> { debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment); let (mut generic_args, infer_args) = if let Some(generic_args) = segment.args.as_deref() { @@ -506,7 +507,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, data: &ParenthesizedArgs, itctx: ImplTraitContext, - bound_modifier_allowed_features: Option, + bound_modifier_allowed_features: Option>, ) -> (GenericArgsCtor<'hir>, bool) { // Switch to `PassThrough` mode for anonymous lifetimes; this // means that we permit things like `&Ref`, where `Ref` has diff --git a/compiler/rustc_data_structures/src/stable_hash.rs b/compiler/rustc_data_structures/src/stable_hash.rs index 0513c90831c8c..00e4de492a028 100644 --- a/compiler/rustc_data_structures/src/stable_hash.rs +++ b/compiler/rustc_data_structures/src/stable_hash.rs @@ -428,6 +428,13 @@ impl StableHash for ::std::sync::Arc { } } +impl StableHash for ::std::borrow::Cow<'_, B> { + #[inline] + fn stable_hash(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + (**self).stable_hash(hcx, hasher); + } +} + impl StableHash for str { #[inline] fn stable_hash(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index fb6ed4196f187..f49340d6e0c24 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1,4 +1,5 @@ use std::any::Any; +use std::borrow::Cow; use std::default::Default; use std::iter; use std::path::PathBuf; @@ -22,9 +23,7 @@ use rustc_session::Session; use rustc_session::parse::ParseSess; use rustc_span::def_id::{CrateNum, DefId, LocalDefId, ModId}; use rustc_span::edition::Edition; -use rustc_span::hygiene::{ - AllowInternalUnstable, AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind, -}; +use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind}; use rustc_span::source_map::SourceMap; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw}; use rustc_structures::{CollapseMacroDebuginfo, Limit}; @@ -779,7 +778,7 @@ pub struct SyntaxExtension { /// Span of the macro definition. pub span: Span, /// List of unstable features that are treated as stable inside this macro. - pub allow_internal_unstable: Option, + pub allow_internal_unstable: Option>, /// The macro's stability info. pub stability: Option, /// The macro's deprecation info. @@ -916,9 +915,7 @@ impl SyntaxExtension { allow_internal_unstable: (!allow_internal_unstable.is_empty()) // FIXME(jdonszelmann): avoid the into_iter/collect? .then(|| { - AllowInternalUnstable::Dynamic( - allow_internal_unstable.iter().map(|i| i.0).collect::>().into(), - ) + Cow::Owned(allow_internal_unstable.iter().map(|i| i.0).collect::>()) }), stability, deprecation: find_attr!( diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 4f85ba8ef155e..137491dfafe7c 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -1,6 +1,7 @@ //! A bunch of methods and structures more or less related to resolving macros and //! interface provided by `Resolver` to macro expander. +use std::borrow::Cow; use std::mem; use std::sync::Arc; @@ -30,9 +31,7 @@ use rustc_session::Session; use rustc_session::diagnostics::feature_err; use rustc_span::def_id::ModId; use rustc_span::edition::Edition; -use rustc_span::hygiene::{ - self, AllowInternalUnstable, AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind, -}; +use rustc_span::hygiene::{self, AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind}; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; use crate::Namespace::*; @@ -239,7 +238,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { ExpnKind::AstPass(pass), call_site, self.tcx.sess.edition(), - AllowInternalUnstable::Static(features), + Cow::Borrowed(features), None, parent_module, ), diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 1584e9057e08f..768464d8527e9 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -24,10 +24,9 @@ // because getting it wrong can lead to nested `HygieneData::with` calls that // trigger runtime aborts. (Fortunately these are obvious and easy to fix.) +use std::borrow::Cow; use std::cell::RefCell; use std::hash::Hash; -use std::ops::Deref; -use std::sync::Arc; use std::{fmt, iter, mem}; use rustc_data_structures::fingerprint::Fingerprint; @@ -964,7 +963,7 @@ impl Span { /// allowed inside this span. pub fn mark_with_reason( self, - allow_internal_unstable: Option, + allow_internal_unstable: Option>, reason: DesugaringKind, edition: Edition, hcx: impl StableHashCtxt, @@ -978,49 +977,6 @@ impl Span { } } -#[derive(Clone)] -pub enum AllowInternalUnstable { - Static(&'static [Symbol]), - Dynamic(Arc<[Symbol]>), -} - -impl Deref for AllowInternalUnstable { - type Target = [Symbol]; - - #[inline] - fn deref(&self) -> &[Symbol] { - match self { - AllowInternalUnstable::Static(s) => s, - AllowInternalUnstable::Dynamic(s) => s, - } - } -} - -impl fmt::Debug for AllowInternalUnstable { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -impl StableHash for AllowInternalUnstable { - #[inline] - fn stable_hash(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { - (**self).stable_hash(hcx, hasher); - } -} - -impl Encodable for AllowInternalUnstable { - fn encode(&self, e: &mut E) { - (**self).encode(e); - } -} - -impl Decodable for AllowInternalUnstable { - fn decode(d: &mut D) -> AllowInternalUnstable { - AllowInternalUnstable::Dynamic(Decodable::decode(d)) - } -} - /// A subset of properties from both macro definition and macro call available through global data. /// Avoid using this if you have access to the original definition or call structures. #[derive(Clone, Debug, Encodable, Decodable, StableHash)] @@ -1063,7 +1019,7 @@ pub struct ExpnData { /// List of `#[unstable]`/feature-gated features that the macro is allowed to use /// internally without forcing the whole crate to opt-in /// to them. - pub allow_internal_unstable: Option, + pub allow_internal_unstable: Option>, /// Edition of the crate in which the macro is defined. pub edition: Edition, /// The `DefId` of the macro being invoked, @@ -1092,7 +1048,7 @@ impl ExpnData { parent: ExpnId, call_site: Span, def_site: Span, - allow_internal_unstable: Option, + allow_internal_unstable: Option>, edition: Edition, macro_def_id: Option, parent_module: Option, @@ -1147,7 +1103,7 @@ impl ExpnData { kind: ExpnKind, call_site: Span, edition: Edition, - allow_internal_unstable: AllowInternalUnstable, + allow_internal_unstable: Cow<'static, [Symbol]>, macro_def_id: Option, parent_module: Option, ) -> ExpnData {