Skip to content

Commit fb243bd

Browse files
m-ou-sejdonszelmann
authored andcommitted
Allow builtin macros to be used more than once.
This removes E0773 "A builtin-macro was defined more than once."
1 parent b9e1af2 commit fb243bd

File tree

14 files changed

+36
-159
lines changed

14 files changed

+36
-159
lines changed

compiler/rustc_builtin_macros/src/lib.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
extern crate proc_macro;
2626

27+
use std::sync::Arc;
28+
2729
use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind};
2830
use rustc_expand::proc_macro::BangProcMacro;
2931
use rustc_span::sym;
@@ -69,13 +71,13 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
6971
pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
7072
let mut register = |name, kind| resolver.register_builtin_macro(name, kind);
7173
macro register_bang($($name:ident: $f:expr,)*) {
72-
$(register(sym::$name, SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)));)*
74+
$(register(sym::$name, SyntaxExtensionKind::LegacyBang(Arc::new($f as MacroExpanderFn)));)*
7375
}
7476
macro register_attr($($name:ident: $f:expr,)*) {
75-
$(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Box::new($f)));)*
77+
$(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Arc::new($f)));)*
7678
}
7779
macro register_derive($($name:ident: $f:expr,)*) {
78-
$(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f))));)*
80+
$(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Arc::new(BuiltinDerive($f))));)*
7981
}
8082

8183
register_bang! {
@@ -145,9 +147,9 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
145147
}
146148

147149
let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
148-
register(sym::quote, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })));
149-
let requires = SyntaxExtensionKind::Attr(Box::new(contracts::ExpandRequires));
150+
register(sym::quote, SyntaxExtensionKind::Bang(Arc::new(BangProcMacro { client })));
151+
let requires = SyntaxExtensionKind::Attr(Arc::new(contracts::ExpandRequires));
150152
register(sym::contracts_requires, requires);
151-
let ensures = SyntaxExtensionKind::Attr(Box::new(contracts::ExpandEnsures));
153+
let ensures = SyntaxExtensionKind::Attr(Arc::new(contracts::ExpandEnsures));
152154
register(sym::contracts_ensures, ensures);
153155
}

compiler/rustc_error_codes/src/error_codes/E0773.md

Lines changed: 0 additions & 40 deletions
This file was deleted.

compiler/rustc_error_codes/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,6 @@ E0769: 0769,
516516
E0770: 0770,
517517
E0771: 0771,
518518
E0772: 0772,
519-
E0773: 0773,
520519
E0774: 0774,
521520
E0775: 0775,
522521
E0776: 0776,

compiler/rustc_expand/src/base.rs

Lines changed: 11 additions & 10 deletions
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.
@@ -934,7 +935,7 @@ impl SyntaxExtension {
934935
cx.dcx().span_delayed_bug(span, "expanded a dummy bang macro"),
935936
))
936937
}
937-
SyntaxExtension::default(SyntaxExtensionKind::LegacyBang(Box::new(expander)), edition)
938+
SyntaxExtension::default(SyntaxExtensionKind::LegacyBang(Arc::new(expander)), edition)
938939
}
939940

940941
/// A dummy derive macro `#[derive(Foo)]`.
@@ -947,7 +948,7 @@ impl SyntaxExtension {
947948
) -> Vec<Annotatable> {
948949
Vec::new()
949950
}
950-
SyntaxExtension::default(SyntaxExtensionKind::Derive(Box::new(expander)), edition)
951+
SyntaxExtension::default(SyntaxExtensionKind::Derive(Arc::new(expander)), edition)
951952
}
952953

953954
pub fn non_macro_attr(edition: Edition) -> SyntaxExtension {
@@ -977,7 +978,7 @@ impl SyntaxExtension {
977978
}
978979

979980
let expander = GlobDelegationExpanderImpl { trait_def_id, impl_def_id };
980-
SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Box::new(expander)), edition)
981+
SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Arc::new(expander)), edition)
981982
}
982983

983984
pub fn expn_data(

compiler/rustc_expand/src/mbe/macro_rules.rs

Lines changed: 3 additions & 2 deletions
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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,15 +1055,15 @@ impl<'a> CrateMetadataRef<'a> {
10551055
attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
10561056
(
10571057
trait_name,
1058-
SyntaxExtensionKind::Derive(Box::new(DeriveProcMacro { client })),
1058+
SyntaxExtensionKind::Derive(Arc::new(DeriveProcMacro { client })),
10591059
helper_attrs,
10601060
)
10611061
}
10621062
ProcMacro::Attr { name, client } => {
1063-
(name, SyntaxExtensionKind::Attr(Box::new(AttrProcMacro { client })), Vec::new())
1063+
(name, SyntaxExtensionKind::Attr(Arc::new(AttrProcMacro { client })), Vec::new())
10641064
}
10651065
ProcMacro::Bang { name, client } => {
1066-
(name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new())
1066+
(name, SyntaxExtensionKind::Bang(Arc::new(BangProcMacro { client })), Vec::new())
10671067
}
10681068
};
10691069

compiler/rustc_resolve/messages.ftl

Lines changed: 0 additions & 4 deletions
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

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -949,15 +949,6 @@ pub(crate) struct StaticLifetimeIsReserved {
949949
pub(crate) lifetime: Ident,
950950
}
951951

952-
#[derive(Diagnostic)]
953-
#[diag(resolve_attempt_to_define_builtin_macro_twice, code = E0773)]
954-
pub(crate) struct AttemptToDefineBuiltinMacroTwice {
955-
#[primary_span]
956-
pub(crate) span: Span,
957-
#[note]
958-
pub(crate) note_span: Span,
959-
}
960-
961952
#[derive(Diagnostic)]
962953
#[diag(resolve_variable_is_not_bound_in_all_patterns, code = E0408)]
963954
pub(crate) struct VariableIsNotBoundInAllPatterns {

compiler/rustc_resolve/src/lib.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,12 +1008,6 @@ impl ExternPreludeEntry<'_> {
10081008
}
10091009
}
10101010

1011-
/// Used for better errors for E0773
1012-
enum BuiltinMacroState {
1013-
NotYetSeen(SyntaxExtensionKind),
1014-
AlreadySeen(Span),
1015-
}
1016-
10171011
struct DeriveData {
10181012
resolutions: Vec<DeriveResolution>,
10191013
helper_attrs: Vec<(usize, Ident)>,
@@ -1132,7 +1126,7 @@ pub struct Resolver<'ra, 'tcx> {
11321126

11331127
used_extern_options: FxHashSet<Symbol>,
11341128
macro_names: FxHashSet<Ident>,
1135-
builtin_macros: FxHashMap<Symbol, BuiltinMacroState>,
1129+
builtin_macros: FxHashMap<Symbol, SyntaxExtensionKind>,
11361130
registered_tools: &'tcx RegisteredTools,
11371131
macro_use_prelude: FxHashMap<Symbol, NameBinding<'ra>>,
11381132
macro_map: FxHashMap<DefId, MacroData>,

compiler/rustc_resolve/src/macros.rs

Lines changed: 7 additions & 18 deletions
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
}
@@ -1129,20 +1129,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11291129

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

0 commit comments

Comments
 (0)