Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a1bd385

Browse files
authoredMar 20, 2025
Unrolled build for rust-lang#138613
Rollup merge of rust-lang#138613 - m-ou-se:no-more-e0773, r=jdonszelmann,petrochenkov Remove E0773 "A builtin-macro was defined more than once." 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.
2 parents 1aeb99d + 6c865c1 commit a1bd385

File tree

13 files changed

+40
-149
lines changed

13 files changed

+40
-149
lines changed
 

‎compiler/rustc_builtin_macros/src/lib.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323

2424
extern crate proc_macro;
2525

26+
use std::sync::Arc;
27+
2628
use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind};
2729
use rustc_expand::proc_macro::BangProcMacro;
2830
use rustc_span::sym;
@@ -67,13 +69,13 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
6769
pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
6870
let mut register = |name, kind| resolver.register_builtin_macro(name, kind);
6971
macro register_bang($($name:ident: $f:expr,)*) {
70-
$(register(sym::$name, SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)));)*
72+
$(register(sym::$name, SyntaxExtensionKind::LegacyBang(Arc::new($f as MacroExpanderFn)));)*
7173
}
7274
macro register_attr($($name:ident: $f:expr,)*) {
73-
$(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Box::new($f)));)*
75+
$(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Arc::new($f)));)*
7476
}
7577
macro register_derive($($name:ident: $f:expr,)*) {
76-
$(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f))));)*
78+
$(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Arc::new(BuiltinDerive($f))));)*
7779
}
7880

7981
register_bang! {
@@ -139,9 +141,9 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
139141
}
140142

141143
let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
142-
register(sym::quote, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })));
143-
let requires = SyntaxExtensionKind::Attr(Box::new(contracts::ExpandRequires));
144+
register(sym::quote, SyntaxExtensionKind::Bang(Arc::new(BangProcMacro { client })));
145+
let requires = SyntaxExtensionKind::Attr(Arc::new(contracts::ExpandRequires));
144146
register(sym::contracts_requires, requires);
145-
let ensures = SyntaxExtensionKind::Attr(Box::new(contracts::ExpandEnsures));
147+
let ensures = SyntaxExtensionKind::Attr(Arc::new(contracts::ExpandEnsures));
146148
register(sym::contracts_ensures, ensures);
147149
}
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,4 @@
1-
A builtin-macro was defined more than once.
1+
#### this error code is no longer emitted by the compiler.
22

3-
Erroneous code example:
4-
5-
```compile_fail,E0773
6-
#![feature(decl_macro)]
7-
#![feature(rustc_attrs)]
8-
#![allow(internal_features)]
9-
10-
#[rustc_builtin_macro]
11-
pub macro test($item:item) {
12-
/* compiler built-in */
13-
}
14-
15-
mod inner {
16-
#[rustc_builtin_macro]
17-
pub macro test($item:item) {
18-
/* compiler built-in */
19-
}
20-
}
21-
```
22-
23-
To fix the issue, remove the duplicate declaration:
24-
25-
```
26-
#![feature(decl_macro)]
27-
#![feature(rustc_attrs)]
28-
#![allow(internal_features)]
29-
30-
#[rustc_builtin_macro]
31-
pub macro test($item:item) {
32-
/* compiler built-in */
33-
}
34-
```
35-
36-
In very rare edge cases, this may happen when loading `core` or `std` twice,
37-
once with `check` metadata and once with `build` metadata.
38-
For more information, see [#75176].
39-
40-
[#75176]: https://github.com/rust-lang/rust/pull/75176#issuecomment-683234468
3+
This was triggered when multiple macro definitions used the same
4+
`#[rustc_builtin_macro(..)]`. This is no longer an error.

‎compiler/rustc_expand/src/base.rs

+11-10
Original file line numberDiff line numberDiff line change
@@ -681,33 +681,34 @@ impl MacResult for DummyResult {
681681
}
682682

683683
/// A syntax extension kind.
684+
#[derive(Clone)]
684685
pub enum SyntaxExtensionKind {
685686
/// A token-based function-like macro.
686687
Bang(
687688
/// An expander with signature TokenStream -> TokenStream.
688-
Box<dyn BangProcMacro + sync::DynSync + sync::DynSend>,
689+
Arc<dyn BangProcMacro + sync::DynSync + sync::DynSend>,
689690
),
690691

691692
/// An AST-based function-like macro.
692693
LegacyBang(
693694
/// An expander with signature TokenStream -> AST.
694-
Box<dyn TTMacroExpander + sync::DynSync + sync::DynSend>,
695+
Arc<dyn TTMacroExpander + sync::DynSync + sync::DynSend>,
695696
),
696697

697698
/// A token-based attribute macro.
698699
Attr(
699700
/// An expander with signature (TokenStream, TokenStream) -> TokenStream.
700701
/// The first TokenStream is the attribute itself, the second is the annotated item.
701702
/// The produced TokenStream replaces the input TokenStream.
702-
Box<dyn AttrProcMacro + sync::DynSync + sync::DynSend>,
703+
Arc<dyn AttrProcMacro + sync::DynSync + sync::DynSend>,
703704
),
704705

705706
/// An AST-based attribute macro.
706707
LegacyAttr(
707708
/// An expander with signature (AST, AST) -> AST.
708709
/// The first AST fragment is the attribute itself, the second is the annotated item.
709710
/// The produced AST fragment replaces the input AST fragment.
710-
Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
711+
Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
711712
),
712713

713714
/// A trivial attribute "macro" that does nothing,
@@ -724,18 +725,18 @@ pub enum SyntaxExtensionKind {
724725
/// is handled identically to `LegacyDerive`. It should be migrated to
725726
/// a token-based representation like `Bang` and `Attr`, instead of
726727
/// using `MultiItemModifier`.
727-
Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
728+
Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
728729
),
729730

730731
/// An AST-based derive macro.
731732
LegacyDerive(
732733
/// An expander with signature AST -> AST.
733734
/// The produced AST fragment is appended to the input AST fragment.
734-
Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
735+
Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
735736
),
736737

737738
/// A glob delegation.
738-
GlobDelegation(Box<dyn GlobDelegationExpander + sync::DynSync + sync::DynSend>),
739+
GlobDelegation(Arc<dyn GlobDelegationExpander + sync::DynSync + sync::DynSend>),
739740
}
740741

741742
/// A struct representing a macro definition in "lowered" form ready for expansion.
@@ -937,7 +938,7 @@ impl SyntaxExtension {
937938
cx.dcx().span_delayed_bug(span, "expanded a dummy bang macro"),
938939
))
939940
}
940-
SyntaxExtension::default(SyntaxExtensionKind::LegacyBang(Box::new(expander)), edition)
941+
SyntaxExtension::default(SyntaxExtensionKind::LegacyBang(Arc::new(expander)), edition)
941942
}
942943

943944
/// A dummy derive macro `#[derive(Foo)]`.
@@ -950,7 +951,7 @@ impl SyntaxExtension {
950951
) -> Vec<Annotatable> {
951952
Vec::new()
952953
}
953-
SyntaxExtension::default(SyntaxExtensionKind::Derive(Box::new(expander)), edition)
954+
SyntaxExtension::default(SyntaxExtensionKind::Derive(Arc::new(expander)), edition)
954955
}
955956

956957
pub fn non_macro_attr(edition: Edition) -> SyntaxExtension {
@@ -980,7 +981,7 @@ impl SyntaxExtension {
980981
}
981982

982983
let expander = GlobDelegationExpanderImpl { trait_def_id, impl_def_id };
983-
SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Box::new(expander)), edition)
984+
SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Arc::new(expander)), edition)
984985
}
985986

986987
pub fn expn_data(

‎compiler/rustc_expand/src/mbe/macro_rules.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::borrow::Cow;
22
use std::collections::hash_map::Entry;
3+
use std::sync::Arc;
34
use std::{mem, slice};
45

56
use ast::token::IdentIsRaw;
@@ -388,7 +389,7 @@ pub fn compile_declarative_macro(
388389
node_id != DUMMY_NODE_ID,
389390
)
390391
};
391-
let dummy_syn_ext = |guar| (mk_syn_ext(Box::new(DummyExpander(guar))), Vec::new());
392+
let dummy_syn_ext = |guar| (mk_syn_ext(Arc::new(DummyExpander(guar))), Vec::new());
392393

393394
let lhs_nm = Ident::new(sym::lhs, span);
394395
let rhs_nm = Ident::new(sym::rhs, span);
@@ -582,7 +583,7 @@ pub fn compile_declarative_macro(
582583
})
583584
.collect();
584585

585-
let expander = Box::new(MacroRulesMacroExpander {
586+
let expander = Arc::new(MacroRulesMacroExpander {
586587
name: ident,
587588
span,
588589
node_id,

‎compiler/rustc_metadata/src/rmeta/decoder.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1053,15 +1053,15 @@ impl<'a> CrateMetadataRef<'a> {
10531053
attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
10541054
(
10551055
trait_name,
1056-
SyntaxExtensionKind::Derive(Box::new(DeriveProcMacro { client })),
1056+
SyntaxExtensionKind::Derive(Arc::new(DeriveProcMacro { client })),
10571057
helper_attrs,
10581058
)
10591059
}
10601060
ProcMacro::Attr { name, client } => {
1061-
(name, SyntaxExtensionKind::Attr(Box::new(AttrProcMacro { client })), Vec::new())
1061+
(name, SyntaxExtensionKind::Attr(Arc::new(AttrProcMacro { client })), Vec::new())
10621062
}
10631063
ProcMacro::Bang { name, client } => {
1064-
(name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new())
1064+
(name, SyntaxExtensionKind::Bang(Arc::new(BangProcMacro { client })), Vec::new())
10651065
}
10661066
};
10671067

‎compiler/rustc_resolve/messages.ftl

-4
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ resolve_associated_fn_with_similar_name_exists =
2626
resolve_associated_type_with_similar_name_exists =
2727
there is an associated type with a similar name
2828
29-
resolve_attempt_to_define_builtin_macro_twice =
30-
attempted to define built-in macro more than once
31-
.note = previously defined here
32-
3329
resolve_attempt_to_use_non_constant_value_in_constant =
3430
attempt to use a non-constant value in a constant
3531

‎compiler/rustc_resolve/src/errors.rs

-9
Original file line numberDiff line numberDiff line change
@@ -965,15 +965,6 @@ pub(crate) struct StaticLifetimeIsReserved {
965965
pub(crate) lifetime: Ident,
966966
}
967967

968-
#[derive(Diagnostic)]
969-
#[diag(resolve_attempt_to_define_builtin_macro_twice, code = E0773)]
970-
pub(crate) struct AttemptToDefineBuiltinMacroTwice {
971-
#[primary_span]
972-
pub(crate) span: Span,
973-
#[note]
974-
pub(crate) note_span: Span,
975-
}
976-
977968
#[derive(Diagnostic)]
978969
#[diag(resolve_variable_is_not_bound_in_all_patterns, code = E0408)]
979970
pub(crate) struct VariableIsNotBoundInAllPatterns {

‎compiler/rustc_resolve/src/lib.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -1010,12 +1010,6 @@ impl ExternPreludeEntry<'_> {
10101010
}
10111011
}
10121012

1013-
/// Used for better errors for E0773
1014-
enum BuiltinMacroState {
1015-
NotYetSeen(SyntaxExtensionKind),
1016-
AlreadySeen(Span),
1017-
}
1018-
10191013
struct DeriveData {
10201014
resolutions: Vec<DeriveResolution>,
10211015
helper_attrs: Vec<(usize, Ident)>,
@@ -1134,7 +1128,7 @@ pub struct Resolver<'ra, 'tcx> {
11341128

11351129
used_extern_options: FxHashSet<Symbol>,
11361130
macro_names: FxHashSet<Ident>,
1137-
builtin_macros: FxHashMap<Symbol, BuiltinMacroState>,
1131+
builtin_macros: FxHashMap<Symbol, SyntaxExtensionKind>,
11381132
registered_tools: &'tcx RegisteredTools,
11391133
macro_use_prelude: FxIndexMap<Symbol, NameBinding<'ra>>,
11401134
macro_map: FxHashMap<DefId, MacroData>,

‎compiler/rustc_resolve/src/macros.rs

+7-16
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ use crate::errors::{
4040
};
4141
use crate::imports::Import;
4242
use crate::{
43-
BindingKey, BuiltinMacroState, DeriveData, Determinacy, Finalize, InvocationParent, MacroData,
44-
ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult,
45-
ResolutionError, Resolver, ScopeSet, Segment, ToNameBinding, Used,
43+
BindingKey, DeriveData, Determinacy, Finalize, InvocationParent, MacroData, ModuleKind,
44+
ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, ResolutionError,
45+
Resolver, ScopeSet, Segment, ToNameBinding, Used,
4646
};
4747

4848
type Res = def::Res<NodeId>;
@@ -194,7 +194,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
194194
}
195195

196196
fn register_builtin_macro(&mut self, name: Symbol, ext: SyntaxExtensionKind) {
197-
if self.builtin_macros.insert(name, BuiltinMacroState::NotYetSeen(ext)).is_some() {
197+
if self.builtin_macros.insert(name, ext).is_some() {
198198
self.dcx().bug(format!("built-in macro `{name}` was already registered"));
199199
}
200200
}
@@ -1127,20 +1127,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11271127

11281128
if let Some(builtin_name) = ext.builtin_name {
11291129
// The macro was marked with `#[rustc_builtin_macro]`.
1130-
if let Some(builtin_macro) = self.builtin_macros.get_mut(&builtin_name) {
1130+
if let Some(builtin_ext_kind) = self.builtin_macros.get(&builtin_name) {
11311131
// The macro is a built-in, replace its expander function
11321132
// while still taking everything else from the source code.
1133-
// If we already loaded this builtin macro, give a better error message than 'no such builtin macro'.
1134-
match mem::replace(builtin_macro, BuiltinMacroState::AlreadySeen(span)) {
1135-
BuiltinMacroState::NotYetSeen(builtin_ext) => {
1136-
ext.kind = builtin_ext;
1137-
rule_spans = Vec::new();
1138-
}
1139-
BuiltinMacroState::AlreadySeen(note_span) => {
1140-
self.dcx()
1141-
.emit_err(errors::AttemptToDefineBuiltinMacroTwice { span, note_span });
1142-
}
1143-
}
1133+
ext.kind = builtin_ext_kind.clone();
1134+
rule_spans = Vec::new();
11441135
} else {
11451136
self.dcx().emit_err(errors::CannotFindBuiltinMacroWithName { span, ident });
11461137
}

‎tests/ui/macros/duplicate-builtin.rs

-17
This file was deleted.

‎tests/ui/macros/duplicate-builtin.stderr

-21
This file was deleted.

‎tests/ui/macros/unknown-builtin.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
//@ error-pattern: attempted to define built-in macro more than once
2-
31
#![feature(rustc_attrs)]
42

53
#[rustc_builtin_macro]
64
macro_rules! unknown { () => () } //~ ERROR cannot find a built-in macro with name `unknown`
75

6+
// Defining another `line` builtin macro should not cause an error.
87
#[rustc_builtin_macro]
9-
macro_rules! line { () => () } //~ NOTE previously defined here
8+
macro_rules! line { () => () }
109

1110
fn main() {
1211
line!();
+2-12
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,8 @@
11
error: cannot find a built-in macro with name `unknown`
2-
--> $DIR/unknown-builtin.rs:6:1
2+
--> $DIR/unknown-builtin.rs:4:1
33
|
44
LL | macro_rules! unknown { () => () }
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66

7-
error[E0773]: attempted to define built-in macro more than once
8-
--> $SRC_DIR/core/src/macros/mod.rs:LL:COL
9-
|
10-
note: previously defined here
11-
--> $DIR/unknown-builtin.rs:9:1
12-
|
13-
LL | macro_rules! line { () => () }
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15-
16-
error: aborting due to 2 previous errors
7+
error: aborting due to 1 previous error
178

18-
For more information about this error, try `rustc --explain E0773`.

0 commit comments

Comments
 (0)
Failed to load comments.