Allow builtin macros to be used more than once.
This removes E0773 "A builtin-macro was defined more than once."
This commit is contained in:
parent
1370611c0a
commit
6c865c1e14
13 changed files with 40 additions and 149 deletions
|
@ -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 {
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue