diff options
Diffstat (limited to 'compiler/rustc_builtin_macros/src')
14 files changed, 235 insertions, 104 deletions
diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index 78bf2195975..1c1b2c88f76 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -88,6 +88,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span generics: Generics::default(), contract: None, body, + define_opaque: None, })); let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)]; diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index bb9dc651cec..a949ab94f3a 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -297,6 +297,7 @@ impl<'cx, 'a> Context<'cx, 'a> { | ExprKind::AssignOp(_, _, _) | ExprKind::Gen(_, _, _, _) | ExprKind::Await(_, _) + | ExprKind::Use(_, _) | ExprKind::Block(_, _) | ExprKind::Break(_, _) | ExprKind::Closure(_) diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 6d9c3575657..6591ed151cf 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -8,7 +8,8 @@ mod llvm_enzyme { use std::string::String; use rustc_ast::expand::autodiff_attrs::{ - AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ty_for_activity, + AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ret_activity, + valid_ty_for_activity, }; use rustc_ast::ptr::P; use rustc_ast::token::{Token, TokenKind}; @@ -25,6 +26,16 @@ mod llvm_enzyme { use crate::errors; + pub(crate) fn outer_normal_attr( + kind: &P<rustc_ast::NormalAttr>, + id: rustc_ast::AttrId, + span: Span, + ) -> rustc_ast::Attribute { + let style = rustc_ast::AttrStyle::Outer; + let kind = rustc_ast::AttrKind::Normal(kind.clone()); + rustc_ast::Attribute { kind, id, style, span } + } + // If we have a default `()` return type or explicitley `()` return type, // then we often can skip doing some work. fn has_ret(ty: &FnRetTy) -> bool { @@ -223,20 +234,8 @@ mod llvm_enzyme { .filter(|a| **a == DiffActivity::Active || **a == DiffActivity::ActiveOnly) .count() as u32; let (d_sig, new_args, idents, errored) = gen_enzyme_decl(ecx, &sig, &x, span); - let new_decl_span = d_sig.span; let d_body = gen_enzyme_body( - ecx, - &x, - n_active, - &sig, - &d_sig, - primal, - &new_args, - span, - sig_span, - new_decl_span, - idents, - errored, + ecx, &x, n_active, &sig, &d_sig, primal, &new_args, span, sig_span, idents, errored, ); let d_ident = first_ident(&meta_item_vec[0]); @@ -247,6 +246,7 @@ mod llvm_enzyme { generics: Generics::default(), contract: None, body: Some(d_body), + define_opaque: None, }); let mut rustc_ad_attr = P(ast::NormalAttr::from_ident(Ident::with_dummy_span(sym::rustc_autodiff))); @@ -268,36 +268,39 @@ mod llvm_enzyme { }; let inline_never_attr = P(ast::NormalAttr { item: inline_item, tokens: None }); let new_id = ecx.sess.psess.attr_id_generator.mk_attr_id(); - let attr: ast::Attribute = ast::Attribute { - kind: ast::AttrKind::Normal(rustc_ad_attr.clone()), - id: new_id, - style: ast::AttrStyle::Outer, - span, - }; + let attr = outer_normal_attr(&rustc_ad_attr, new_id, span); let new_id = ecx.sess.psess.attr_id_generator.mk_attr_id(); - let inline_never: ast::Attribute = ast::Attribute { - kind: ast::AttrKind::Normal(inline_never_attr), - id: new_id, - style: ast::AttrStyle::Outer, - span, - }; + let inline_never = outer_normal_attr(&inline_never_attr, new_id, span); + + // We're avoid duplicating the attributes `#[rustc_autodiff]` and `#[inline(never)]`. + fn same_attribute(attr: &ast::AttrKind, item: &ast::AttrKind) -> bool { + match (attr, item) { + (ast::AttrKind::Normal(a), ast::AttrKind::Normal(b)) => { + let a = &a.item.path; + let b = &b.item.path; + a.segments.len() == b.segments.len() + && a.segments.iter().zip(b.segments.iter()).all(|(a, b)| a.ident == b.ident) + } + _ => false, + } + } // Don't add it multiple times: let orig_annotatable: Annotatable = match item { Annotatable::Item(ref mut iitem) => { - if !iitem.attrs.iter().any(|a| a.id == attr.id) { - iitem.attrs.push(attr.clone()); + if !iitem.attrs.iter().any(|a| same_attribute(&a.kind, &attr.kind)) { + iitem.attrs.push(attr); } - if !iitem.attrs.iter().any(|a| a.id == inline_never.id) { + if !iitem.attrs.iter().any(|a| same_attribute(&a.kind, &inline_never.kind)) { iitem.attrs.push(inline_never.clone()); } Annotatable::Item(iitem.clone()) } Annotatable::AssocItem(ref mut assoc_item, i @ Impl) => { - if !assoc_item.attrs.iter().any(|a| a.id == attr.id) { - assoc_item.attrs.push(attr.clone()); + if !assoc_item.attrs.iter().any(|a| same_attribute(&a.kind, &attr.kind)) { + assoc_item.attrs.push(attr); } - if !assoc_item.attrs.iter().any(|a| a.id == inline_never.id) { + if !assoc_item.attrs.iter().any(|a| same_attribute(&a.kind, &inline_never.kind)) { assoc_item.attrs.push(inline_never.clone()); } Annotatable::AssocItem(assoc_item.clone(), i) @@ -312,17 +315,11 @@ mod llvm_enzyme { delim: rustc_ast::token::Delimiter::Parenthesis, tokens: ts, }); - let d_attr: ast::Attribute = ast::Attribute { - kind: ast::AttrKind::Normal(rustc_ad_attr.clone()), - id: new_id, - style: ast::AttrStyle::Outer, - span, - }; - + let d_attr = outer_normal_attr(&rustc_ad_attr, new_id, span); let d_annotatable = if is_impl { let assoc_item: AssocItemKind = ast::AssocItemKind::Fn(asdf); let d_fn = P(ast::AssocItem { - attrs: thin_vec![d_attr.clone(), inline_never], + attrs: thin_vec![d_attr, inline_never], id: ast::DUMMY_NODE_ID, span, vis, @@ -332,12 +329,8 @@ mod llvm_enzyme { }); Annotatable::AssocItem(d_fn, Impl) } else { - let mut d_fn = ecx.item( - span, - d_ident, - thin_vec![d_attr.clone(), inline_never], - ItemKind::Fn(asdf), - ); + let mut d_fn = + ecx.item(span, d_ident, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf)); d_fn.vis = vis; Annotatable::Item(d_fn) }; @@ -363,30 +356,27 @@ mod llvm_enzyme { ty } - /// We only want this function to type-check, since we will replace the body - /// later on llvm level. Using `loop {}` does not cover all return types anymore, - /// so instead we build something that should pass. We also add a inline_asm - /// line, as one more barrier for rustc to prevent inlining of this function. - /// FIXME(ZuseZ4): We still have cases of incorrect inlining across modules, see - /// <https://github.com/EnzymeAD/rust/issues/173>, so this isn't sufficient. - /// It also triggers an Enzyme crash if we due to a bug ever try to differentiate - /// this function (which should never happen, since it is only a placeholder). - /// Finally, we also add back_box usages of all input arguments, to prevent rustc - /// from optimizing any arguments away. - fn gen_enzyme_body( + // Will generate a body of the type: + // ``` + // { + // unsafe { + // asm!("NOP"); + // } + // ::core::hint::black_box(primal(args)); + // ::core::hint::black_box((args, ret)); + // <This part remains to be done by following function> + // } + // ``` + fn init_body_helper( ecx: &ExtCtxt<'_>, - x: &AutoDiffAttrs, - n_active: u32, - sig: &ast::FnSig, - d_sig: &ast::FnSig, + span: Span, primal: Ident, new_names: &[String], - span: Span, sig_span: Span, new_decl_span: Span, - idents: Vec<Ident>, + idents: &[Ident], errored: bool, - ) -> P<ast::Block> { + ) -> (P<ast::Block>, P<ast::Expr>, P<ast::Expr>, P<ast::Expr>) { let blackbox_path = ecx.std_path(&[sym::hint, sym::black_box]); let noop = ast::InlineAsm { asm_macro: ast::AsmMacro::Asm, @@ -435,6 +425,51 @@ mod llvm_enzyme { } body.stmts.push(ecx.stmt_semi(black_box_remaining_args)); + (body, primal_call, black_box_primal_call, blackbox_call_expr) + } + + /// We only want this function to type-check, since we will replace the body + /// later on llvm level. Using `loop {}` does not cover all return types anymore, + /// so instead we manually build something that should pass the type checker. + /// We also add a inline_asm line, as one more barrier for rustc to prevent inlining + /// or const propagation. inline_asm will also triggers an Enzyme crash if due to another + /// bug would ever try to accidentially differentiate this placeholder function body. + /// Finally, we also add back_box usages of all input arguments, to prevent rustc + /// from optimizing any arguments away. + fn gen_enzyme_body( + ecx: &ExtCtxt<'_>, + x: &AutoDiffAttrs, + n_active: u32, + sig: &ast::FnSig, + d_sig: &ast::FnSig, + primal: Ident, + new_names: &[String], + span: Span, + sig_span: Span, + idents: Vec<Ident>, + errored: bool, + ) -> P<ast::Block> { + let new_decl_span = d_sig.span; + + // Just adding some default inline-asm and black_box usages to prevent early inlining + // and optimizations which alter the function signature. + // + // The bb_primal_call is the black_box call of the primal function. We keep it around, + // since it has the convenient property of returning the type of the primal function, + // Remember, we only care to match types here. + // No matter which return we pick, we always wrap it into a std::hint::black_box call, + // to prevent rustc from propagating it into the caller. + let (mut body, primal_call, bb_primal_call, bb_call_expr) = init_body_helper( + ecx, + span, + primal, + new_names, + sig_span, + new_decl_span, + &idents, + errored, + ); + if !has_ret(&d_sig.decl.output) { // there is no return type that we have to match, () works fine. return body; @@ -446,7 +481,7 @@ mod llvm_enzyme { if primal_ret && n_active == 0 && x.mode.is_rev() { // We only have the primal ret. - body.stmts.push(ecx.stmt_expr(black_box_primal_call.clone())); + body.stmts.push(ecx.stmt_expr(bb_primal_call)); return body; } @@ -471,7 +506,7 @@ mod llvm_enzyme { if primal_ret { // We have both primal ret and active floats. // primal ret is first, by construction. - exprs.push(primal_call.clone()); + exprs.push(primal_call); } // Now construct default placeholder for each active float. @@ -538,16 +573,11 @@ mod llvm_enzyme { return body; } [arg] => { - ret = ecx.expr_call( - new_decl_span, - blackbox_call_expr.clone(), - thin_vec![arg.clone()], - ); + ret = ecx.expr_call(new_decl_span, bb_call_expr, thin_vec![arg.clone()]); } args => { let ret_tuple: P<ast::Expr> = ecx.expr_tuple(span, args.into()); - ret = - ecx.expr_call(new_decl_span, blackbox_call_expr.clone(), thin_vec![ret_tuple]); + ret = ecx.expr_call(new_decl_span, bb_call_expr, thin_vec![ret_tuple]); } } assert!(has_ret(&d_sig.decl.output)); @@ -560,14 +590,14 @@ mod llvm_enzyme { ecx: &ExtCtxt<'_>, span: Span, primal: Ident, - idents: Vec<Ident>, + idents: &[Ident], ) -> P<ast::Expr> { let has_self = idents.len() > 0 && idents[0].name == kw::SelfLower; if has_self { let args: ThinVec<_> = idents[1..].iter().map(|arg| ecx.expr_path(ecx.path_ident(span, *arg))).collect(); let self_expr = ecx.expr_self(span); - ecx.expr_method_call(span, self_expr, primal, args.clone()) + ecx.expr_method_call(span, self_expr, primal, args) } else { let args: ThinVec<_> = idents.iter().map(|arg| ecx.expr_path(ecx.path_ident(span, *arg))).collect(); @@ -585,6 +615,8 @@ mod llvm_enzyme { // // Error handling: If the user provides an invalid configuration (incorrect numbers, types, or // both), we emit an error and return the original signature. This allows us to continue parsing. + // FIXME(Sa4dUs): make individual activities' span available so errors + // can point to only the activity instead of the entire attribute fn gen_enzyme_decl( ecx: &ExtCtxt<'_>, sig: &ast::FnSig, @@ -632,10 +664,22 @@ mod llvm_enzyme { errors = true; } } + + if has_ret && !valid_ret_activity(x.mode, x.ret_activity) { + dcx.emit_err(errors::AutoDiffInvalidRetAct { + span, + mode: x.mode.to_string(), + act: x.ret_activity.to_string(), + }); + // We don't set `errors = true` to avoid annoying type errors relative + // to the expanded macro type signature + } + if errors { // This is not the right signature, but we can continue parsing. return (sig.clone(), new_inputs, idents, true); } + let unsafe_activities = x .input_activity .iter() diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index 53c61831b42..5788966b6e7 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -140,8 +140,9 @@ impl CfgEval<'_> { Annotatable::ForeignItem(self.flat_map_foreign_item(item).pop().unwrap()) } Annotatable::Stmt(_) => { - let stmt = - parser.parse_stmt_without_recovery(false, ForceCollect::Yes)?.unwrap(); + let stmt = parser + .parse_stmt_without_recovery(false, ForceCollect::Yes, false)? + .unwrap(); Annotatable::Stmt(P(self.flat_map_stmt(stmt).pop().unwrap())) } Annotatable::Expr(_) => { diff --git a/compiler/rustc_builtin_macros/src/define_opaque.rs b/compiler/rustc_builtin_macros/src/define_opaque.rs new file mode 100644 index 00000000000..9777e772cf2 --- /dev/null +++ b/compiler/rustc_builtin_macros/src/define_opaque.rs @@ -0,0 +1,54 @@ +use rustc_ast::{DUMMY_NODE_ID, ast}; +use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_span::Span; + +pub(crate) fn expand( + ecx: &mut ExtCtxt<'_>, + _expand_span: Span, + meta_item: &ast::MetaItem, + mut item: Annotatable, +) -> Vec<Annotatable> { + let define_opaque = match &mut item { + Annotatable::Item(p) => match &mut p.kind { + ast::ItemKind::Fn(f) => Some(&mut f.define_opaque), + _ => None, + }, + Annotatable::AssocItem(i, _assoc_ctxt) => match &mut i.kind { + ast::AssocItemKind::Fn(func) => Some(&mut func.define_opaque), + _ => None, + }, + Annotatable::Stmt(s) => match &mut s.kind { + ast::StmtKind::Item(p) => match &mut p.kind { + ast::ItemKind::Fn(f) => Some(&mut f.define_opaque), + _ => None, + }, + _ => None, + }, + _ => None, + }; + + let Some(list) = meta_item.meta_item_list() else { + ecx.dcx().span_err(meta_item.span, "expected list of type aliases"); + return vec![item]; + }; + + if let Some(define_opaque) = define_opaque { + *define_opaque = Some( + list.iter() + .filter_map(|entry| match entry { + ast::MetaItemInner::MetaItem(meta_item) if meta_item.is_word() => { + Some((DUMMY_NODE_ID, meta_item.path.clone())) + } + _ => { + ecx.dcx().span_err(entry.span(), "expected path to type alias"); + None + } + }) + .collect(), + ); + } else { + ecx.dcx().span_err(meta_item.span, "only functions and methods can define opaque types"); + } + + vec![item] +} diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 5aed9f76f14..46b79e09780 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -300,13 +300,16 @@ pub(crate) fn expand_deriving_coerce_pointee( to_ty: &s_ty, rewritten: false, }; - let mut predicate = ast::WherePredicate { - kind: ast::WherePredicateKind::BoundPredicate(bound.clone()), - span: predicate.span, - id: ast::DUMMY_NODE_ID, - }; - substitution.visit_where_predicate(&mut predicate); + let mut kind = ast::WherePredicateKind::BoundPredicate(bound.clone()); + substitution.visit_where_predicate_kind(&mut kind); if substitution.rewritten { + let predicate = ast::WherePredicate { + attrs: predicate.attrs.clone(), + kind, + span: predicate.span, + id: ast::DUMMY_NODE_ID, + is_placeholder: false, + }; impl_generics.where_clause.predicates.push(predicate); } } @@ -388,8 +391,8 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> { } } - fn visit_where_predicate(&mut self, where_predicate: &mut ast::WherePredicate) { - match &mut where_predicate.kind { + fn visit_where_predicate_kind(&mut self, kind: &mut ast::WherePredicateKind) { + match kind { rustc_ast::WherePredicateKind::BoundPredicate(bound) => { bound .bound_generic_params diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 6b59ac25827..03ee59de70e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -687,9 +687,11 @@ impl<'a> TraitDef<'a> { // and similarly for where clauses where_clause.predicates.extend(generics.where_clause.predicates.iter().map(|clause| { ast::WherePredicate { + attrs: clause.attrs.clone(), kind: clause.kind.clone(), id: ast::DUMMY_NODE_ID, span: clause.span.with_ctxt(ctxt), + is_placeholder: false, } })); @@ -744,8 +746,13 @@ impl<'a> TraitDef<'a> { }; let kind = ast::WherePredicateKind::BoundPredicate(predicate); - let predicate = - ast::WherePredicate { kind, id: ast::DUMMY_NODE_ID, span: self.span }; + let predicate = ast::WherePredicate { + attrs: ThinVec::new(), + kind, + id: ast::DUMMY_NODE_ID, + span: self.span, + is_placeholder: false, + }; where_clause.predicates.push(predicate); } } @@ -1033,6 +1040,7 @@ impl<'a> MethodDef<'a> { generics: fn_generics, contract: None, body: Some(body_block), + define_opaque: None, })), tokens: None, }) diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index ab1e0d8ee89..30597944124 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -186,6 +186,15 @@ mod autodiff { } #[derive(Diagnostic)] + #[diag(builtin_macros_autodiff_ret_activity)] + pub(crate) struct AutoDiffInvalidRetAct { + #[primary_span] + pub(crate) span: Span, + pub(crate) mode: String, + pub(crate) act: String, + } + + #[derive(Diagnostic)] #[diag(builtin_macros_autodiff_mode)] pub(crate) struct AutoDiffInvalidMode { #[primary_span] diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 90447da6680..12654001a1e 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -190,7 +190,8 @@ fn make_format_args( && let [stmt] = block.stmts.as_slice() && let StmtKind::Expr(expr) = &stmt.kind && let ExprKind::Path(None, path) = &expr.kind - && path.is_potential_trivial_const_arg() + && path.segments.len() == 1 + && path.segments[0].args.is_none() { err.multipart_suggestion( "quote your inlined format argument to use as string literal", @@ -710,11 +711,9 @@ fn report_missing_placeholders( }; let pos = sub.position(); - let sub = String::from(sub.as_str()); - if explained.contains(&sub) { + if !explained.insert(sub.to_string()) { continue; } - explained.insert(sub); if !found_foreign { found_foreign = true; diff --git a/compiler/rustc_builtin_macros/src/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs index 866ec72f116..13d5b42942a 100644 --- a/compiler/rustc_builtin_macros/src/format_foreign.rs +++ b/compiler/rustc_builtin_macros/src/format_foreign.rs @@ -12,14 +12,16 @@ pub(crate) mod printf { Escape((usize, usize)), } - impl<'a> Substitution<'a> { - pub(crate) fn as_str(&self) -> &str { + impl ToString for Substitution<'_> { + fn to_string(&self) -> String { match self { - Substitution::Format(fmt) => fmt.span, - Substitution::Escape(_) => "%%", + Substitution::Format(fmt) => fmt.span.into(), + Substitution::Escape(_) => "%%".into(), } } + } + impl Substitution<'_> { pub(crate) fn position(&self) -> InnerSpan { match self { Substitution::Format(fmt) => fmt.position, @@ -627,15 +629,17 @@ pub(crate) mod shell { Escape((usize, usize)), } - impl Substitution<'_> { - pub(crate) fn as_str(&self) -> String { + impl ToString for Substitution<'_> { + fn to_string(&self) -> String { match self { Substitution::Ordinal(n, _) => format!("${n}"), Substitution::Name(n, _) => format!("${n}"), Substitution::Escape(_) => "$$".into(), } } + } + impl Substitution<'_> { pub(crate) fn position(&self) -> InnerSpan { let (Self::Ordinal(_, pos) | Self::Name(_, pos) | Self::Escape(pos)) = self; InnerSpan::new(pos.0, pos.1) diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index 8fdbbf8e704..90d79235820 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -83,6 +83,7 @@ impl AllocFnFactory<'_, '_> { generics: Generics::default(), contract: None, body, + define_opaque: None, })); let item = self.cx.item( self.span, diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index ca16583a45d..606e85577f7 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -5,6 +5,7 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(assert_matches)] @@ -18,11 +19,12 @@ #![feature(rustdoc_internals)] #![feature(string_from_utf8_lossy_owned)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate proc_macro; +use std::sync::Arc; + use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind}; use rustc_expand::proc_macro::BangProcMacro; use rustc_span::sym; @@ -39,6 +41,7 @@ mod compile_error; mod concat; mod concat_bytes; mod concat_idents; +mod define_opaque; mod derive; mod deriving; mod edition_panic; @@ -66,13 +69,13 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" } pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { let mut register = |name, kind| resolver.register_builtin_macro(name, kind); macro register_bang($($name:ident: $f:expr,)*) { - $(register(sym::$name, SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)));)* + $(register(sym::$name, SyntaxExtensionKind::LegacyBang(Arc::new($f as MacroExpanderFn)));)* } macro register_attr($($name:ident: $f:expr,)*) { - $(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Box::new($f)));)* + $(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Arc::new($f)));)* } macro register_derive($($name:ident: $f:expr,)*) { - $(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f))));)* + $(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Arc::new(BuiltinDerive($f))));)* } register_bang! { @@ -114,6 +117,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { bench: test::expand_bench, cfg_accessible: cfg_accessible::Expander, cfg_eval: cfg_eval::expand, + define_opaque: define_opaque::expand, derive: derive::Expander { is_const: false }, derive_const: derive::Expander { is_const: true }, global_allocator: global_allocator::expand, @@ -137,9 +141,9 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { } let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote); - register(sym::quote, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client }))); - let requires = SyntaxExtensionKind::Attr(Box::new(contracts::ExpandRequires)); + register(sym::quote, SyntaxExtensionKind::Bang(Arc::new(BangProcMacro { client }))); + let requires = SyntaxExtensionKind::Attr(Arc::new(contracts::ExpandRequires)); register(sym::contracts_requires, requires); - let ensures = SyntaxExtensionKind::Attr(Box::new(contracts::ExpandEnsures)); + let ensures = SyntaxExtensionKind::Attr(Arc::new(contracts::ExpandEnsures)); register(sym::contracts_ensures, ensures); } diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs index 6933ca09349..ba63b185e09 100644 --- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs +++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs @@ -60,6 +60,7 @@ pub fn inject( Edition2018 => sym::rust_2018, Edition2021 => sym::rust_2021, Edition2024 => sym::rust_2024, + EditionFuture => sym::rust_future, }]) .map(|&symbol| Ident::new(symbol, span)) .collect(); diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 472e16e62d5..768b459ec5e 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -346,6 +346,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> { generics: ast::Generics::default(), contract: None, body: Some(main_body), + define_opaque: None, })); // Honor the reexport_test_harness_main attribute |
