Repository: rust-lang/rust
Pull request #138613: Remove E0773 "A builtin-macro was defined more than once."
Author: login: m-ou-se
Labels: name: A-macros
description: Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..)
name: T-compiler
description: Relevant to the compiler team, which will review and decide on the PR/issue.
name: S-waiting-on-bors
description: Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Created: 2025-03-17T16:47:17Z | Merged: 2025-03-20T00:52:26Z

Error E0773 "A builtin-macro was defined more than once" is triggered when using the same `#[rustc_builtin_macro(..)]` twice. However, it can only be triggered in unstable code (using a `rustc_` attribute), and there doesn't seem to be any harm in using the same implementation from `compiler/rustc_builtin_macros/…` for multiple macro definitions.

By changing the Box to an Arc in `SyntaxExtensionKind`, we can throw away the `BuiltinMacroState::{NotYetSeen, AlreadySeen}` logic, simplifying things.



Diff:
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index dab3053d8b0d7..606e85577f7e7 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -23,6 +23,8 @@
 
 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;
@@ -67,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! {
@@ -139,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_error_codes/src/error_codes/E0773.md b/compiler/rustc_error_codes/src/error_codes/E0773.md
index aa65a475a4f9d..5ebb43c6683e5 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0773.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0773.md
@@ -1,40 +1,4 @@
-A builtin-macro was defined more than once.
+#### this error code is no longer emitted by the compiler.
 
-Erroneous code example:
-
-```compile_fail,E0773
-#![feature(decl_macro)]
-#![feature(rustc_attrs)]
-#![allow(internal_features)]
-
-#[rustc_builtin_macro]
-pub macro test($item:item) {
-    /* compiler built-in */
-}
-
-mod inner {
-    #[rustc_builtin_macro]
-    pub macro test($item:item) {
-        /* compiler built-in */
-    }
-}
-```
-
-To fix the issue, remove the duplicate declaration:
-
-```
-#![feature(decl_macro)]
-#![feature(rustc_attrs)]
-#![allow(internal_features)]
-
-#[rustc_builtin_macro]
-pub macro test($item:item) {
-    /* compiler built-in */
-}
-```
-
-In very rare edge cases, this may happen when loading `core` or `std` twice,
-once with `check` metadata and once with `build` metadata.
-For more information, see [#75176].
-
-[#75176]: https://github.com/rust-lang/rust/pull/75176#issuecomment-683234468
+This was triggered when multiple macro definitions used the same
+`#[rustc_builtin_macro(..)]`. This is no longer an error.
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index c4b5396258444..1dd152beb475f 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -681,17 +681,18 @@ impl MacResult for DummyResult {
 }
 
 /// A syntax extension kind.
+#[derive(Clone)]
 pub enum SyntaxExtensionKind {
     /// A token-based function-like macro.
     Bang(
         /// An expander with signature TokenStream -> TokenStream.
-        Box<dyn BangProcMacro + sync::DynSync + sync::DynSend>,
+        Arc<dyn BangProcMacro + sync::DynSync + sync::DynSend>,
     ),
 
     /// An AST-based function-like macro.
     LegacyBang(
         /// An expander with signature TokenStream -> AST.
-        Box<dyn TTMacroExpander + sync::DynSync + sync::DynSend>,
+        Arc<dyn TTMacroExpander + sync::DynSync + sync::DynSend>,
     ),
 
     /// A token-based attribute macro.
@@ -699,7 +700,7 @@ pub enum SyntaxExtensionKind {
         /// An expander with signature (TokenStream, TokenStream) -> TokenStream.
         /// The first TokenStream is the attribute itself, the second is the annotated item.
         /// The produced TokenStream replaces the input TokenStream.
-        Box<dyn AttrProcMacro + sync::DynSync + sync::DynSend>,
+        Arc<dyn AttrProcMacro + sync::DynSync + sync::DynSend>,
     ),
 
     /// An AST-based attribute macro.
@@ -707,7 +708,7 @@ pub enum SyntaxExtensionKind {
         /// An expander with signature (AST, AST) -> AST.
         /// The first AST fragment is the attribute itself, the second is the annotated item.
         /// The produced AST fragment replaces the input AST fragment.
-        Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
+        Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
     ),
 
     /// A trivial attribute "macro" that does nothing,
@@ -724,18 +725,18 @@ pub enum SyntaxExtensionKind {
         /// is handled identically to `LegacyDerive`. It should be migrated to
         /// a token-based representation like `Bang` and `Attr`, instead of
         /// using `MultiItemModifier`.
-        Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
+        Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
     ),
 
     /// An AST-based derive macro.
     LegacyDerive(
         /// An expander with signature AST -> AST.
         /// The produced AST fragment is appended to the input AST fragment.
-        Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
+        Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
     ),
 
     /// A glob delegation.
-    GlobDelegation(Box<dyn GlobDelegationExpander + sync::DynSync + sync::DynSend>),
+    GlobDelegation(Arc<dyn GlobDelegationExpander + sync::DynSync + sync::DynSend>),
 }
 
 /// A struct representing a macro definition in "lowered" form ready for expansion.
@@ -937,7 +938,7 @@ impl SyntaxExtension {
                 cx.dcx().span_delayed_bug(span, "expanded a dummy bang macro"),
             ))
         }
-        SyntaxExtension::default(SyntaxExtensionKind::LegacyBang(Box::new(expander)), edition)
+        SyntaxExtension::default(SyntaxExtensionKind::LegacyBang(Arc::new(expander)), edition)
     }
 
     /// A dummy derive macro `#[derive(Foo)]`.
@@ -950,7 +951,7 @@ impl SyntaxExtension {
         ) -> Vec<Annotatable> {
             Vec::new()
         }
-        SyntaxExtension::default(SyntaxExtensionKind::Derive(Box::new(expander)), edition)
+        SyntaxExtension::default(SyntaxExtensionKind::Derive(Arc::new(expander)), edition)
     }
 
     pub fn non_macro_attr(edition: Edition) -> SyntaxExtension {
@@ -980,7 +981,7 @@ impl SyntaxExtension {
         }
 
         let expander = GlobDelegationExpanderImpl { trait_def_id, impl_def_id };
-        SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Box::new(expander)), edition)
+        SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Arc::new(expander)), edition)
     }
 
     pub fn expn_data(
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 5577c8902dae8..77ec598e62a17 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -1,5 +1,6 @@
 use std::borrow::Cow;
 use std::collections::hash_map::Entry;
+use std::sync::Arc;
 use std::{mem, slice};
 
 use ast::token::IdentIsRaw;
@@ -388,7 +389,7 @@ pub fn compile_declarative_macro(
             node_id != DUMMY_NODE_ID,
         )
     };
-    let dummy_syn_ext = |guar| (mk_syn_ext(Box::new(DummyExpander(guar))), Vec::new());
+    let dummy_syn_ext = |guar| (mk_syn_ext(Arc::new(DummyExpander(guar))), Vec::new());
 
     let lhs_nm = Ident::new(sym::lhs, span);
     let rhs_nm = Ident::new(sym::rhs, span);
@@ -582,7 +583,7 @@ pub fn compile_declarative_macro(
         })
         .collect();
 
-    let expander = Box::new(MacroRulesMacroExpander {
+    let expander = Arc::new(MacroRulesMacroExpander {
         name: ident,
         span,
         node_id,
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index e60904eebeb8b..f6cf218db9d0b 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1053,15 +1053,15 @@ impl<'a> CrateMetadataRef<'a> {
                     attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
                 (
                     trait_name,
-                    SyntaxExtensionKind::Derive(Box::new(DeriveProcMacro { client })),
+                    SyntaxExtensionKind::Derive(Arc::new(DeriveProcMacro { client })),
                     helper_attrs,
                 )
             }
             ProcMacro::Attr { name, client } => {
-                (name, SyntaxExtensionKind::Attr(Box::new(AttrProcMacro { client })), Vec::new())
+                (name, SyntaxExtensionKind::Attr(Arc::new(AttrProcMacro { client })), Vec::new())
             }
             ProcMacro::Bang { name, client } => {
-                (name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new())
+                (name, SyntaxExtensionKind::Bang(Arc::new(BangProcMacro { client })), Vec::new())
             }
         };
 
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index 817aa5b43852b..558a01713dc7c 100644
--- a/compiler/rustc_resolve/messages.ftl
+++ b/compiler/rustc_resolve/messages.ftl
@@ -26,10 +26,6 @@ resolve_associated_fn_with_similar_name_exists =
 resolve_associated_type_with_similar_name_exists =
     there is an associated type with a similar name
 
-resolve_attempt_to_define_builtin_macro_twice =
-    attempted to define built-in macro more than once
-    .note = previously defined here
-
 resolve_attempt_to_use_non_constant_value_in_constant =
     attempt to use a non-constant value in a constant
 
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index 2ae6892bc93e6..e26b300f13ef7 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -965,15 +965,6 @@ pub(crate) struct StaticLifetimeIsReserved {
     pub(crate) lifetime: Ident,
 }
 
-#[derive(Diagnostic)]
-#[diag(resolve_attempt_to_define_builtin_macro_twice, code = E0773)]
-pub(crate) struct AttemptToDefineBuiltinMacroTwice {
-    #[primary_span]
-    pub(crate) span: Span,
-    #[note]
-    pub(crate) note_span: Span,
-}
-
 #[derive(Diagnostic)]
 #[diag(resolve_variable_is_not_bound_in_all_patterns, code = E0408)]
 pub(crate) struct VariableIsNotBoundInAllPatterns {
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 447d5283e27ec..ff31af0025b54 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1010,12 +1010,6 @@ impl ExternPreludeEntry<'_> {
     }
 }
 
-/// Used for better errors for E0773
-enum BuiltinMacroState {
-    NotYetSeen(SyntaxExtensionKind),
-    AlreadySeen(Span),
-}
-
 struct DeriveData {
     resolutions: Vec<DeriveResolution>,
     helper_attrs: Vec<(usize, Ident)>,
@@ -1134,7 +1128,7 @@ pub struct Resolver<'ra, 'tcx> {
 
     used_extern_options: FxHashSet<Symbol>,
     macro_names: FxHashSet<Ident>,
-    builtin_macros: FxHashMap<Symbol, BuiltinMacroState>,
+    builtin_macros: FxHashMap<Symbol, SyntaxExtensionKind>,
     registered_tools: &'tcx RegisteredTools,
     macro_use_prelude: FxIndexMap<Symbol, NameBinding<'ra>>,
     macro_map: FxHashMap<DefId, MacroData>,
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 7100d89ad61a8..c94846e95d424 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -40,9 +40,9 @@ use crate::errors::{
 };
 use crate::imports::Import;
 use crate::{
-    BindingKey, BuiltinMacroState, DeriveData, Determinacy, Finalize, InvocationParent, MacroData,
-    ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult,
-    ResolutionError, Resolver, ScopeSet, Segment, ToNameBinding, Used,
+    BindingKey, DeriveData, Determinacy, Finalize, InvocationParent, MacroData, ModuleKind,
+    ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, ResolutionError,
+    Resolver, ScopeSet, Segment, ToNameBinding, Used,
 };
 
 type Res = def::Res<NodeId>;
@@ -194,7 +194,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
     }
 
     fn register_builtin_macro(&mut self, name: Symbol, ext: SyntaxExtensionKind) {
-        if self.builtin_macros.insert(name, BuiltinMacroState::NotYetSeen(ext)).is_some() {
+        if self.builtin_macros.insert(name, ext).is_some() {
             self.dcx().bug(format!("built-in macro `{name}` was already registered"));
         }
     }
@@ -1127,20 +1127,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
 
         if let Some(builtin_name) = ext.builtin_name {
             // The macro was marked with `#[rustc_builtin_macro]`.
-            if let Some(builtin_macro) = self.builtin_macros.get_mut(&builtin_name) {
+            if let Some(builtin_ext_kind) = self.builtin_macros.get(&builtin_name) {
                 // The macro is a built-in, replace its expander function
                 // while still taking everything else from the source code.
-                // If we already loaded this builtin macro, give a better error message than 'no such builtin macro'.
-                match mem::replace(builtin_macro, BuiltinMacroState::AlreadySeen(span)) {
-                    BuiltinMacroState::NotYetSeen(builtin_ext) => {
-                        ext.kind = builtin_ext;
-                        rule_spans = Vec::new();
-                    }
-                    BuiltinMacroState::AlreadySeen(note_span) => {
-                        self.dcx()
-                            .emit_err(errors::AttemptToDefineBuiltinMacroTwice { span, note_span });
-                    }
-                }
+                ext.kind = builtin_ext_kind.clone();
+                rule_spans = Vec::new();
             } else {
                 self.dcx().emit_err(errors::CannotFindBuiltinMacroWithName { span, ident });
             }
diff --git a/tests/ui/macros/duplicate-builtin.rs b/tests/ui/macros/duplicate-builtin.rs
deleted file mode 100644
index c75782128f425..0000000000000
--- a/tests/ui/macros/duplicate-builtin.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ compile-flags:--crate-type lib
-#![feature(decl_macro)]
-#![feature(rustc_attrs)]
-
-#[rustc_builtin_macro]
-pub macro test($item:item) {
-//~^ NOTE previously defined
-    /* compiler built-in */
-}
-
-mod inner {
-    #[rustc_builtin_macro]
-    pub macro test($item:item) {
-    //~^ ERROR attempted to define built-in macro more than once [E0773]
-        /* compiler built-in */
-    }
-}
diff --git a/tests/ui/macros/duplicate-builtin.stderr b/tests/ui/macros/duplicate-builtin.stderr
deleted file mode 100644
index 887a4fbbdc8e0..0000000000000
--- a/tests/ui/macros/duplicate-builtin.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0773]: attempted to define built-in macro more than once
-  --> $DIR/duplicate-builtin.rs:13:5
-   |
-LL | /     pub macro test($item:item) {
-LL | |
-LL | |         /* compiler built-in */
-LL | |     }
-   | |_____^
-   |
-note: previously defined here
-  --> $DIR/duplicate-builtin.rs:6:1
-   |
-LL | / pub macro test($item:item) {
-LL | |
-LL | |     /* compiler built-in */
-LL | | }
-   | |_^
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0773`.
diff --git a/tests/ui/macros/unknown-builtin.rs b/tests/ui/macros/unknown-builtin.rs
index 048f5d68d3421..aa6e04d3fb859 100644
--- a/tests/ui/macros/unknown-builtin.rs
+++ b/tests/ui/macros/unknown-builtin.rs
@@ -1,12 +1,11 @@
-//@ error-pattern: attempted to define built-in macro more than once
-
 #![feature(rustc_attrs)]
 
 #[rustc_builtin_macro]
 macro_rules! unknown { () => () } //~ ERROR cannot find a built-in macro with name `unknown`
 
+// Defining another `line` builtin macro should not cause an error.
 #[rustc_builtin_macro]
-macro_rules! line { () => () } //~ NOTE previously defined here
+macro_rules! line { () => () }
 
 fn main() {
     line!();
diff --git a/tests/ui/macros/unknown-builtin.stderr b/tests/ui/macros/unknown-builtin.stderr
index 22f54e04e54c3..1a83398891b9f 100644
--- a/tests/ui/macros/unknown-builtin.stderr
+++ b/tests/ui/macros/unknown-builtin.stderr
@@ -1,18 +1,8 @@
 error: cannot find a built-in macro with name `unknown`
-  --> $DIR/unknown-builtin.rs:6:1
+  --> $DIR/unknown-builtin.rs:4:1
    |
 LL | macro_rules! unknown { () => () }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0773]: attempted to define built-in macro more than once
-  --> $SRC_DIR/core/src/macros/mod.rs:LL:COL
-   |
-note: previously defined here
-  --> $DIR/unknown-builtin.rs:9:1
-   |
-LL | macro_rules! line { () => () }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0773`.


Reviews:
user: login: jdonszelmann
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T16:54:52Z
user: login: petrochenkov
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T21:35:54Z

Review comments:
diff_hunk: @@ -515,7 +515,6 @@ E0769: 0769,
 E0770: 0770,
 E0771: 0771,
 E0772: 0772,
-E0773: 0773,
path: compiler/rustc_error_codes/src/lib.rs
user: login: jdonszelmann
body: below there's a list of retired error codes (often with a reason). Same for the fact that I've seen examples of error code descriptions not being removed but simply deprecated. This last thing seems unnecessary as this was unstable anyway, but could be nice to list the error code at the bottom as removed.
created_at: 2025-03-17T16:54:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1127,20 +1127,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
 
         if let Some(builtin_name) = ext.builtin_name {
             // The macro was marked with `#[rustc_builtin_macro]`.
-            if let Some(builtin_macro) = self.builtin_macros.get_mut(&builtin_name) {
-                // The macro is a built-in, replace its expander function
-                // while still taking everything else from the source code.
path: compiler/rustc_resolve/src/macros.rs
user: login: petrochenkov
body: Could you keep this part of the comment? It's still relevant.
created_at: 2025-03-18T21:35:23Z
author_association: CONTRIBUTOR

PR comments:
user: login: rustbot
created_at: 2025-03-17T16:47:22Z
body: r? @cjgillot

rustbot has assigned @cjgillot.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use `r?` to explicitly pick a reviewer
author_association: COLLABORATOR
user: login: rustbot
created_at: 2025-03-17T16:47:24Z
body: Some changes occurred in diagnostic error codes

cc @GuillaumeGomez
author_association: COLLABORATOR
user: login: m-ou-se
created_at: 2025-03-17T16:54:52Z
body: cc @jyn514 who originally added this error in https://github.com/rust-lang/rust/pull/76143
author_association: MEMBER
user: login: jdonszelmann
created_at: 2025-03-17T17:00:18Z
body: I reviewed the changes and they look reasonable to me. I just can't quite judge how important this check was. The check feels to me like just a sanity check, and there's now a good usecase for actually doing the thing the error tries to prevent. 
author_association: CONTRIBUTOR
user: login: m-ou-se
created_at: 2025-03-17T17:00:58Z
body: Originally, the macro was just removed from `builtin_macros` when `#[rustc_builtin_macro]` was used, resuting in a confusing "not found" error when used more than once.

To avoid that confusion, https://github.com/rust-lang/rust/pull/76143 added logic to keep track of the already used builtin macros to give a better error. I think the better/simpler strategy is to just use Arc instead of Box such that you don't have to remove or track anything, lifting the 'only one definition' limitation.

author_association: MEMBER
user: login: jdonszelmann
created_at: 2025-03-17T17:06:50Z
body: right, so by making things an Arc, we solve the issue for which the error was initially added. Then I don't think there's much reason *not* to do this :)
author_association: CONTRIBUTOR
user: login: jdonszelmann
created_at: 2025-03-17T17:16:17Z
body: alright then, first @bors r+ rollup here we go!
author_association: CONTRIBUTOR
user: login: bors
created_at: 2025-03-17T17:16:20Z
body: :pushpin: Commit 97d870e9bed23a8380bb6569dd5000889f8853b7 has been approved by `jdonszelmann`

It is now in the [queue](https://bors.rust-lang.org/homu/queue/rust) for this repository.

<!-- @bors r=jdonszelmann 97d870e9bed23a8380bb6569dd5000889f8853b7 -->
<!-- homu: {"type":"Approved","sha":"97d870e9bed23a8380bb6569dd5000889f8853b7","approver":"jdonszelmann","queue":"https://bors.rust-lang.org/homu/queue/rust"} -->
author_association: COLLABORATOR
user: login: rust-log-analyzer
created_at: 2025-03-17T17:24:33Z
body: 
The job **`mingw-check`** failed! Check out the build log: [(web)](https://github.com/rust-lang/rust/actions/runs/13905279580/job/38906822283) [(plain)](https://github.com/rust-lang/rust/commit/97d870e9bed23a8380bb6569dd5000889f8853b7/checks/38906822283/logs)

<details><summary><i>Click to see the possible cause of the failure (guessed by this bot)</i></summary>

```plain

```

</details>

author_association: COLLABORATOR
user: login: jyn514
created_at: 2025-03-17T17:39:29Z
body: i don't quite follow why it's useful to define a macro more than once, but as long as it works i have no objection. people shouldn't be using rustc_builtin_macro outside of std anyway.
author_association: MEMBER
user: login: jyn514
created_at: 2025-03-17T17:40:41Z
body: wait, you also removed the test? please don't do that, please test that duplicate macros work.
author_association: MEMBER
user: login: jdonszelmann
created_at: 2025-03-17T18:09:17Z
body: this is useful when you want multiple macros with different names implemented by the same definition in `rustc_builtin_macros`
author_association: CONTRIBUTOR
user: login: m-ou-se
created_at: 2025-03-17T18:11:29Z
body: It's also useful when making a quick test/example while working on rustc, to not get conflicts with core when testing something with rustc_builtin_macro.

author_association: MEMBER
user: login: m-ou-se
created_at: 2025-03-17T18:13:01Z
body: > i don't quite follow why it's useful to define a macro more than once

I don't see why it's useful to limit it to one use either. (Which caused some hard to debug issues in the past.)
author_association: MEMBER
user: login: workingjubilee
created_at: 2025-03-17T18:21:11Z
body: > this is useful when you want multiple macros with different names implemented by the same definition in rustc_builtin_macros

Is there a problem with having the other macros forward to that builtin one?
author_association: MEMBER
user: login: m-ou-se
created_at: 2025-03-17T18:31:56Z
body: > Is there a problem with having the other macros forward to that builtin one?

That's not as easy for attribute and derive macros.
author_association: MEMBER
user: login: workingjubilee
created_at: 2025-03-17T18:36:03Z
body: Ooh, yeah. Doable but still, gotcha.
author_association: MEMBER
user: login: jdonszelmann
created_at: 2025-03-17T19:03:20Z
body: @jyn514 's comment of adding a test sounds like a good one. After that I'm willing to r+ again :)
author_association: CONTRIBUTOR
user: login: fmease
created_at: 2025-03-17T19:29:17Z
body: could you also squash :)

@bors r-
author_association: MEMBER
user: login: petrochenkov
created_at: 2025-03-17T21:53:28Z
body: From the description, this sounds strange, I'll look tomorrow.
r? @petrochenkov 
author_association: CONTRIBUTOR
user: login: petrochenkov
created_at: 2025-03-18T12:34:50Z
body: The `Box` -> `Arc` change doesn't affect just built-in macros, it affects all macros, so let's check the perf first.
@bors try @rust-timer queue
author_association: CONTRIBUTOR
user: login: rust-timer
created_at: 2025-03-18T12:34:53Z
body: Awaiting bors try build completion.

@rustbot label: +S-waiting-on-perf

<!-- rust-timer: temporary -->
author_association: COLLABORATOR
user: login: bors
created_at: 2025-03-18T12:36:01Z
body: :hourglass: Trying commit c9eda62abd7a5adb7840ae0ec3e7aec9b1c4b36d with merge cfeb4659d0a4e3cac73a43d4b6e3b8b4c08da529...
<!-- homu: {"type":"TryBuildStarted","head_sha":"c9eda62abd7a5adb7840ae0ec3e7aec9b1c4b36d","merge_sha":"cfeb4659d0a4e3cac73a43d4b6e3b8b4c08da529"} -->
author_association: COLLABORATOR
user: login: bors
created_at: 2025-03-18T14:42:50Z
body: :sunny: Try build successful - [checks-actions](https://github.com/rust-lang-ci/rust/actions/runs/13923344898/job/38970746494)
Build commit: cfeb4659d0a4e3cac73a43d4b6e3b8b4c08da529 (`cfeb4659d0a4e3cac73a43d4b6e3b8b4c08da529`)
<!-- homu: {"type":"TryBuildCompleted","builders":{"checks-actions":"https://github.com/rust-lang-ci/rust/actions/runs/13923344898/job/38970746494"},"merge_sha":"cfeb4659d0a4e3cac73a43d4b6e3b8b4c08da529"} -->
author_association: COLLABORATOR
user: login: rust-timer
created_at: 2025-03-18T14:42:54Z
body: Queued cfeb4659d0a4e3cac73a43d4b6e3b8b4c08da529 with parent 75530e9f72a1990ed2305e16fd51d02f47048f12, future [comparison URL](https://perf.rust-lang.org/compare.html?start=75530e9f72a1990ed2305e16fd51d02f47048f12&end=cfeb4659d0a4e3cac73a43d4b6e3b8b4c08da529).
There are currently 4 preceding artifacts in the [queue](https://perf.rust-lang.org/status.html).
It will probably take at least ~5.3 hours until the benchmark run finishes.
<!-- rust-timer: temporary -->
author_association: COLLABORATOR
user: login: rust-timer
created_at: 2025-03-18T21:23:27Z
body: Finished benchmarking commit (cfeb4659d0a4e3cac73a43d4b6e3b8b4c08da529): [comparison URL](https://perf.rust-lang.org/compare.html?start=75530e9f72a1990ed2305e16fd51d02f47048f12&end=cfeb4659d0a4e3cac73a43d4b6e3b8b4c08da529&stat=instructions:u).

### Overall result: ❌ regressions - no action needed


Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf.

@bors rollup=never
@rustbot label: -S-waiting-on-perf -perf-regression


### [Instruction count](https://perf.rust-lang.org/compare.html?start=75530e9f72a1990ed2305e16fd51d02f47048f12&end=cfeb4659d0a4e3cac73a43d4b6e3b8b4c08da529&stat=instructions:u)
This is the most reliable metric that we have; it was used to determine the overall result at the top of this comment. However, even this metric can sometimes exhibit noise.

|                                    | mean | range        | count |
|:----------------------------------:|:----:|:------------:|:-----:|
| Regressions ❌ <br /> (primary)    | -    | -            | 0     |
| Regressions ❌ <br /> (secondary)  | 0.2% | [0.2%, 0.2%] | 1     |
| Improvements ✅ <br /> (primary)   | -    | -            | 0     |
| Improvements ✅ <br /> (secondary) | -    | -            | 0     |
| All ❌✅ (primary)                 | -    | -            | 0     |

### [Max RSS (memory usage)](https://perf.rust-lang.org/compare.html?start=75530e9f72a1990ed2305e16fd51d02f47048f12&end=cfeb4659d0a4e3cac73a43d4b6e3b8b4c08da529&stat=max-rss)
<details>
<summary>Results (primary 2.5%, secondary -1.8%)</summary>

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

|                                    | mean  | range          | count |
|:----------------------------------:|:-----:|:--------------:|:-----:|
| Regressions ❌ <br /> (primary)    | 2.5%  | [2.5%, 2.5%]   | 1     |
| Regressions ❌ <br /> (secondary)  | 1.5%  | [1.5%, 1.5%]   | 1     |
| Improvements ✅ <br /> (primary)   | -     | -              | 0     |
| Improvements ✅ <br /> (secondary) | -2.9% | [-3.7%, -2.1%] | 3     |
| All ❌✅ (primary)                 | 2.5%  | [2.5%, 2.5%]   | 1     |
</details>

### [Cycles](https://perf.rust-lang.org/compare.html?start=75530e9f72a1990ed2305e16fd51d02f47048f12&end=cfeb4659d0a4e3cac73a43d4b6e3b8b4c08da529&stat=cycles:u)
This benchmark run did not return any relevant results for this metric.

### [Binary size](https://perf.rust-lang.org/compare.html?start=75530e9f72a1990ed2305e16fd51d02f47048f12&end=cfeb4659d0a4e3cac73a43d4b6e3b8b4c08da529&stat=size:linked_artifact)
This benchmark run did not return any relevant results for this metric.

**Bootstrap**: 776.359s -> 775.772s (-0.08%)
**Artifact size**: 365.12 MiB -> 365.09 MiB (-0.01%)
author_association: COLLABORATOR
user: login: petrochenkov
created_at: 2025-03-18T21:37:13Z
body: The change itself makes sense.
r=me after restoring the comment (https://github.com/rust-lang/rust/pull/138613#discussion_r2002059325) and tests (https://github.com/rust-lang/rust/pull/138613#issuecomment-2730366010), and squashing commits.
@rustbot author
@bors rollup=maybe
author_association: CONTRIBUTOR
user: login: jdonszelmann
created_at: 2025-03-19T15:09:16Z
body: @bors r=jdonszelmann,petrochenkov then :)
author_association: CONTRIBUTOR
user: login: bors
created_at: 2025-03-19T15:09:19Z
body: :pushpin: Commit 6c865c1e14d5bd76b4ffe1e7ed2e60b3261d03a9 has been approved by `jdonszelmann,petrochenkov`

It is now in the [queue](https://bors.rust-lang.org/homu/queue/rust) for this repository.

<!-- @bors r=jdonszelmann,petrochenkov 6c865c1e14d5bd76b4ffe1e7ed2e60b3261d03a9 -->
<!-- homu: {"type":"Approved","sha":"6c865c1e14d5bd76b4ffe1e7ed2e60b3261d03a9","approver":"jdonszelmann,petrochenkov","queue":"https://bors.rust-lang.org/homu/queue/rust"} -->
author_association: COLLABORATOR