resolve: Merge resolution for macro_rules into the common early in-scope resolution function

`fn resolve_legacy_scope`/`fn resolve_lexical_macro_path_segment` -> `fn early_resolve_ident_in_lexical_scope`
This commit is contained in:
Vadim Petrochenkov 2018-09-18 03:19:26 +03:00
parent 05a46815e4
commit 050bd32958
6 changed files with 173 additions and 253 deletions

View File

@ -10,6 +10,7 @@ crate-type = ["dylib"]
test = false
[dependencies]
bitflags = "1.0"
log = "0.4"
syntax = { path = "../libsyntax" }
rustc = { path = "../librustc" }

View File

@ -17,6 +17,8 @@
#![feature(rustc_diagnostic_macros)]
#![feature(slice_sort_by_cached_key)]
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate log;
#[macro_use]
@ -1210,10 +1212,6 @@ impl<'a> NameBinding<'a> {
}
}
fn get_macro<'b: 'a>(&self, resolver: &mut Resolver<'a, 'b>) -> Lrc<SyntaxExtension> {
resolver.get_macro(self.def_ignoring_ambiguity())
}
// We sometimes need to treat variants as `pub` for backwards compatibility
fn pseudo_vis(&self) -> ty::Visibility {
if self.is_variant() && self.def().def_id().is_local() {
@ -3664,8 +3662,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
self.resolve_ident_in_module(module, ident, ns, record_used, path_span)
} else if opt_ns == Some(MacroNS) {
assert!(ns == TypeNS);
self.resolve_lexical_macro_path_segment(ident, ns, None, parent_scope, record_used,
record_used, path_span).map(|(b, _)| b)
self.early_resolve_ident_in_lexical_scope(ident, ns, None, parent_scope,
record_used, record_used, path_span)
} else {
let record_used_id =
if record_used { crate_lint.node_id().or(Some(CRATE_NODE_ID)) } else { None };

View File

@ -43,9 +43,6 @@ use std::cell::Cell;
use std::mem;
use rustc_data_structures::sync::Lrc;
#[derive(Clone, Copy)]
crate struct FromPrelude(bool);
#[derive(Clone)]
pub struct InvocationData<'a> {
def_index: DefIndex,
@ -503,37 +500,36 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
Err(Determinacy::Determined)
},
};
parent_scope.module.macro_resolutions.borrow_mut()
.push((path.into_boxed_slice(), span));
return def;
}
let result = if let Some(legacy_binding) = self.resolve_legacy_scope(path[0], Some(kind),
parent_scope, false) {
Ok(legacy_binding.def())
def
} else {
match self.resolve_lexical_macro_path_segment(path[0], MacroNS, Some(kind),
parent_scope, false, force, span) {
Ok((binding, _)) => Ok(binding.def_ignoring_ambiguity()),
let def = match self.early_resolve_ident_in_lexical_scope(path[0], MacroNS, Some(kind),
parent_scope, false, force,
span) {
Ok(binding) => Ok(binding.def_ignoring_ambiguity()),
Err(Determinacy::Undetermined) => return Err(Determinacy::Undetermined),
Err(Determinacy::Determined) => {
self.found_unresolved_macro = true;
Err(Determinacy::Determined)
}
}
};
};
parent_scope.module.legacy_macro_resolutions.borrow_mut()
.push((path[0], kind, parent_scope.clone(), result.ok()));
parent_scope.module.legacy_macro_resolutions.borrow_mut()
.push((path[0], kind, parent_scope.clone(), def.ok()));
result
def
}
}
// Resolve the initial segment of a non-global macro path
// (e.g. `foo` in `foo::bar!(); or `foo!();`).
// Resolve an identifier in lexical scope.
// This is a variation of `fn resolve_ident_in_lexical_scope` that can be run during
// expansion and import resolution (perhaps they can be merged in the future).
crate fn resolve_lexical_macro_path_segment(
// The function is used for resolving initial segments of macro paths (e.g. `foo` in
// `foo::bar!(); or `foo!();`) and can be used for "uniform path" imports in the future.
crate fn early_resolve_ident_in_lexical_scope(
&mut self,
mut ident: Ident,
ns: Namespace,
@ -542,7 +538,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
record_used: bool,
force: bool,
path_span: Span,
) -> Result<(&'a NameBinding<'a>, FromPrelude), Determinacy> {
) -> Result<&'a NameBinding<'a>, Determinacy> {
// General principles:
// 1. Not controlled (user-defined) names should have higher priority than controlled names
// built into the language or standard library. This way we can add new names into the
@ -565,21 +561,20 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
// (open, not controlled).
// 3. Standard library prelude (de-facto closed, controlled).
// (Macro NS)
// 0. Derive helpers (open, not controlled). All ambiguities with other names
// are currently reported as errors. They should be higher in priority than preludes
// and probably even names in modules according to the "general principles" above. They
// also should be subject to restricted shadowing because are effectively produced by
// derives (you need to resolve the derive first to add helpers into scope), but they
// should be available before the derive is expanded for compatibility.
// It's mess in general, so we are being conservative for now.
// 1. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
// (open, not controlled).
// 2. `macro_use` prelude (open, the open part is from macro expansions, not controlled).
// 2a. User-defined prelude from macro-use
// 1-2. `macro_rules` (open, not controlled), loop through legacy scopes. Have higher
// priority than prelude macros, but create ambiguities with macros in modules.
// 1-2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
// (open, not controlled). Have higher priority than prelude macros, but create
// ambiguities with `macro_rules`.
// 3. `macro_use` prelude (open, the open part is from macro expansions, not controlled).
// 3a. User-defined prelude from macro-use
// (open, the open part is from macro expansions, not controlled).
// 2b. Standard library prelude is currently implemented as `macro-use` (closed, controlled)
// 3. Language prelude: builtin macros (closed, controlled, except for legacy plugins).
// 4. Language prelude: builtin attributes (closed, controlled).
// 3b. Standard library prelude is currently implemented as `macro-use` (closed, controlled)
// 5. Language prelude: builtin macros (closed, controlled, except for legacy plugins).
// 6. Language prelude: builtin attributes (closed, controlled).
// 3-6. Legacy plugin helpers (open, not controlled). Similar to derive helpers,
// but introduced by legacy plugins using `register_attribute`. Priority is somewhere
// in prelude, not sure where exactly (creates ambiguities with any other prelude names).
// N (unordered). Derive helpers (open, not controlled). All ambiguities with other names
// are currently reported as errors. They should be higher in priority than preludes
// and maybe even names in modules according to the "general principles" above. They
@ -587,8 +582,29 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
// derives (you need to resolve the derive first to add helpers into scope), but they
// should be available before the derive is expanded for compatibility.
// It's mess in general, so we are being conservative for now.
// N (unordered). Legacy plugin helpers (open, not controlled). Similar to derive helpers,
// but introduced by legacy plugins using `register_attribute`.
enum WhereToResolve<'a> {
MacroRules(LegacyScope<'a>),
Module(Module<'a>),
MacroUsePrelude,
BuiltinMacros,
BuiltinAttrs,
DeriveHelpers,
LegacyPluginHelpers,
ExternPrelude,
ToolPrelude,
StdLibPrelude,
BuiltinTypes,
}
bitflags! {
struct Flags: u8 {
const DERIVE_HELPERS = 1 << 0;
const MACRO_RULES = 1 << 1;
const MODULE = 1 << 2;
const PRELUDE = 1 << 3;
}
}
assert!(force || !record_used); // `record_used` implies `force`
ident = ident.modern();
@ -604,26 +620,18 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
// }
// So we have to save the innermost solution and continue searching in outer scopes
// to detect potential ambiguities.
let mut innermost_result: Option<(&NameBinding, FromPrelude)> = None;
enum WhereToResolve<'a> {
Module(Module<'a>),
MacroUsePrelude,
BuiltinMacros,
BuiltinAttrs,
DeriveHelpers,
LegacyPluginHelpers,
ExternPrelude,
ToolPrelude,
StdLibPrelude,
BuiltinTypes,
}
let mut innermost_result: Option<(&NameBinding, Flags, /* conflicts with */ Flags)> = None;
// Go through all the scopes and try to resolve the name.
let mut where_to_resolve = WhereToResolve::DeriveHelpers;
let mut where_to_resolve = WhereToResolve::MacroRules(parent_scope.legacy);
let mut use_prelude = !parent_scope.module.no_implicit_prelude;
loop {
let result = match where_to_resolve {
WhereToResolve::MacroRules(legacy_scope) => match legacy_scope {
LegacyScope::Binding(legacy_binding) if ident == legacy_binding.ident =>
Ok((legacy_binding.binding, Flags::MACRO_RULES, Flags::MODULE)),
_ => Err(Determinacy::Determined),
}
WhereToResolve::Module(module) => {
let orig_current_module = mem::replace(&mut self.current_module, module);
let binding = self.resolve_ident_in_module_unadjusted(
@ -635,17 +643,17 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
path_span,
);
self.current_module = orig_current_module;
binding.map(|binding| (binding, FromPrelude(false)))
binding.map(|binding| (binding, Flags::MODULE, Flags::empty()))
}
WhereToResolve::MacroUsePrelude => {
match self.macro_use_prelude.get(&ident.name).cloned() {
Some(binding) => Ok((binding, FromPrelude(true))),
Some(binding) => Ok((binding, Flags::PRELUDE, Flags::empty())),
None => Err(Determinacy::Determined),
}
}
WhereToResolve::BuiltinMacros => {
match self.builtin_macros.get(&ident.name).cloned() {
Some(binding) => Ok((binding, FromPrelude(true))),
Some(binding) => Ok((binding, Flags::PRELUDE, Flags::empty())),
None => Err(Determinacy::Determined),
}
}
@ -654,7 +662,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
let binding = (Def::NonMacroAttr(NonMacroAttrKind::Builtin),
ty::Visibility::Public, ident.span, Mark::root())
.to_name_binding(self.arenas);
Ok((binding, FromPrelude(true)))
Ok((binding, Flags::PRELUDE, Flags::empty()))
} else {
Err(Determinacy::Determined)
}
@ -671,7 +679,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
(Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
ty::Visibility::Public, derive.span, Mark::root())
.to_name_binding(self.arenas);
result = Ok((binding, FromPrelude(false)));
result = Ok((binding, Flags::DERIVE_HELPERS, Flags::all()));
break;
}
}
@ -685,7 +693,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
let binding = (Def::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper),
ty::Visibility::Public, ident.span, Mark::root())
.to_name_binding(self.arenas);
Ok((binding, FromPrelude(false)))
Ok((binding, Flags::PRELUDE, Flags::PRELUDE))
} else {
Err(Determinacy::Determined)
}
@ -700,7 +708,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
let binding = (crate_root, ty::Visibility::Public,
ident.span, Mark::root()).to_name_binding(self.arenas);
Ok((binding, FromPrelude(true)))
Ok((binding, Flags::PRELUDE, Flags::empty()))
} else {
Err(Determinacy::Determined)
}
@ -709,7 +717,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
if use_prelude && is_known_tool(ident.name) {
let binding = (Def::ToolMod, ty::Visibility::Public,
ident.span, Mark::root()).to_name_binding(self.arenas);
Ok((binding, FromPrelude(true)))
Ok((binding, Flags::PRELUDE, Flags::empty()))
} else {
Err(Determinacy::Determined)
}
@ -726,26 +734,34 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
false,
path_span,
) {
result = Ok((binding, FromPrelude(true)));
result = Ok((binding, Flags::PRELUDE, Flags::empty()));
}
}
}
result
}
WhereToResolve::BuiltinTypes => {
if let Some(prim_ty) =
self.primitive_type_table.primitive_types.get(&ident.name).cloned() {
let binding = (Def::PrimTy(prim_ty), ty::Visibility::Public,
ident.span, Mark::root()).to_name_binding(self.arenas);
Ok((binding, FromPrelude(true)))
} else {
Err(Determinacy::Determined)
match self.primitive_type_table.primitive_types.get(&ident.name).cloned() {
Some(prim_ty) => {
let binding = (Def::PrimTy(prim_ty), ty::Visibility::Public,
ident.span, Mark::root()).to_name_binding(self.arenas);
Ok((binding, Flags::PRELUDE, Flags::empty()))
}
None => Err(Determinacy::Determined)
}
}
};
macro_rules! continue_search { () => {
where_to_resolve = match where_to_resolve {
WhereToResolve::MacroRules(legacy_scope) => match legacy_scope {
LegacyScope::Binding(binding) =>
WhereToResolve::MacroRules(binding.parent_legacy_scope),
LegacyScope::Invocation(invocation) =>
WhereToResolve::MacroRules(invocation.output_legacy_scope.get()),
LegacyScope::Empty => WhereToResolve::Module(parent_scope.module),
LegacyScope::Uninitialized => unreachable!(),
}
WhereToResolve::Module(module) => {
match self.hygienic_lexical_parent(module, &mut ident.span) {
Some(parent_module) => WhereToResolve::Module(parent_module),
@ -778,36 +794,33 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
}}
match result {
Ok(result) => {
if sub_namespace_mismatch(kind, result.0.macro_kind()) {
Ok((binding, flags, ambig_flags)) => {
if sub_namespace_mismatch(kind, binding.macro_kind()) {
continue_search!();
}
if !record_used {
return Ok(result);
return Ok(binding);
}
if let Some(innermost_result) = innermost_result {
if let Some((innermost_binding, innermost_flags, innermost_ambig_flags))
= innermost_result {
// Found another solution, if the first one was "weak", report an error.
let prohibit_ambiguities = |def| {
def == Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper) ||
def == Def::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper)
};
if result.0.def() != innermost_result.0.def() &&
(innermost_result.0.is_glob_import() ||
innermost_result.0.may_appear_after(parent_scope.expansion, result.0) ||
prohibit_ambiguities(innermost_result.0.def()) ||
prohibit_ambiguities(result.0.def())) {
if binding.def() != innermost_binding.def() &&
(innermost_binding.is_glob_import() ||
innermost_binding.may_appear_after(parent_scope.expansion, binding) ||
innermost_flags.intersects(ambig_flags) ||
flags.intersects(innermost_ambig_flags)) {
self.ambiguity_errors.push(AmbiguityError {
ident,
b1: innermost_result.0,
b2: result.0,
b1: innermost_binding,
b2: binding,
});
return Ok(innermost_result);
return Ok(innermost_binding);
}
} else {
// Found the first solution.
innermost_result = Some(result);
innermost_result = Some((binding, flags, ambig_flags));
}
continue_search!();
@ -820,8 +833,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
}
// The first found solution was the only one, return it.
if let Some(innermost_result) = innermost_result {
return Ok(innermost_result);
if let Some((binding, ..)) = innermost_result {
return Ok(binding);
}
let determinacy = Determinacy::determined(force);
@ -833,92 +846,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
let binding = (Def::NonMacroAttr(NonMacroAttrKind::Custom),
ty::Visibility::Public, ident.span, Mark::root())
.to_name_binding(self.arenas);
Ok((binding, FromPrelude(true)))
Ok(binding)
} else {
Err(determinacy)
}
}
fn resolve_legacy_scope(
&mut self,
ident: Ident,
kind: Option<MacroKind>,
parent_scope: &ParentScope<'a>,
record_used: bool,
) -> Option<&'a NameBinding<'a>> {
if sub_namespace_mismatch(kind, Some(MacroKind::Bang)) {
return None;
}
let ident = ident.modern();
// This is *the* result, resolution from the scope closest to the resolved identifier.
// However, sometimes this result is "weak" because it comes from a macro expansion,
// and in this case it cannot shadow names from outer scopes, e.g.
// macro_rules! m { ... } // solution in outer scope
// {
// define_m!(); // generates another `macro_rules! m` - innermost solution
// // weak, cannot shadow the outer `m`, need to report ambiguity error
// m!();
// }
// So we have to save the innermost solution and continue searching in outer scopes
// to detect potential ambiguities.
let mut innermost_result: Option<&NameBinding> = None;
// Go through all the scopes and try to resolve the name.
let mut where_to_resolve = parent_scope.legacy;
loop {
let result = match where_to_resolve {
LegacyScope::Binding(legacy_binding) if ident == legacy_binding.ident =>
Some(legacy_binding.binding),
_ => None,
};
macro_rules! continue_search { () => {
where_to_resolve = match where_to_resolve {
LegacyScope::Empty => break, // nowhere else to search
LegacyScope::Binding(binding) => binding.parent_legacy_scope,
LegacyScope::Invocation(invocation) => invocation.output_legacy_scope.get(),
LegacyScope::Uninitialized => unreachable!(),
};
continue;
}}
match result {
Some(result) => {
if !record_used {
return Some(result);
}
if let Some(innermost_result) = innermost_result {
// Found another solution, if the first one was "weak", report an error.
if result.def() != innermost_result.def() &&
innermost_result.may_appear_after(parent_scope.expansion, result) {
self.ambiguity_errors.push(AmbiguityError {
ident,
b1: innermost_result,
b2: result,
});
return Some(innermost_result);
}
} else {
// Found the first solution.
innermost_result = Some(result);
}
continue_search!();
}
None => {
continue_search!();
}
}
}
// The first found solution was the only one (or there was no solution at all), return it.
innermost_result
}
pub fn finalize_current_module_macro_resolutions(&mut self) {
let module = self.current_module;
for &(ref path, span) in module.macro_resolutions.borrow().iter() {
@ -933,80 +866,51 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
let legacy_macro_resolutions =
mem::replace(&mut *module.legacy_macro_resolutions.borrow_mut(), Vec::new());
for (ident, kind, parent_scope, def) in legacy_macro_resolutions {
let span = ident.span;
let legacy_resolution = self.resolve_legacy_scope(
ident, Some(kind), &parent_scope, true
for (ident, kind, parent_scope, initial_def) in legacy_macro_resolutions {
let binding = self.early_resolve_ident_in_lexical_scope(
ident, MacroNS, Some(kind), &parent_scope, true, true, ident.span
);
let resolution = self.resolve_lexical_macro_path_segment(
ident, MacroNS, Some(kind), &parent_scope, true, true, span
);
let check_consistency = |this: &Self, new_def: Def| {
if let Some(def) = def {
if this.ambiguity_errors.is_empty() && new_def != def && new_def != Def::Err {
// Make sure compilation does not succeed if preferred macro resolution
// has changed after the macro had been expanded. In theory all such
// situations should be reported as ambiguity errors, so this is span-bug.
span_bug!(span, "inconsistent resolution for a macro");
match binding {
Ok(binding) => {
self.record_use(ident, MacroNS, binding);
let def = binding.def_ignoring_ambiguity();
if let Some(initial_def) = initial_def {
if self.ambiguity_errors.is_empty() &&
def != initial_def && def != Def::Err {
// Make sure compilation does not succeed if preferred macro resolution
// has changed after the macro had been expanded. In theory all such
// situations should be reported as ambiguity errors, so this is a bug.
span_bug!(ident.span, "inconsistent resolution for a macro");
}
} else {
// It's possible that the macro was unresolved (indeterminate) and silently
// expanded into a dummy fragment for recovery during expansion.
// Now, post-expansion, the resolution may succeed, but we can't change the
// past and need to report an error.
let msg = format!("cannot determine resolution for the {} `{}`",
kind.descr(), ident);
let msg_note = "import resolution is stuck, try simplifying macro imports";
self.session.struct_span_err(ident.span, &msg).note(msg_note).emit();
}
} else {
// It's possible that the macro was unresolved (indeterminate) and silently
// expanded into a dummy fragment for recovery during expansion.
// Now, post-expansion, the resolution may succeed, but we can't change the
// past and need to report an error.
let msg =
format!("cannot determine resolution for the {} `{}`", kind.descr(), ident);
let msg_note = "import resolution is stuck, try simplifying macro imports";
this.session.struct_span_err(span, &msg).note(msg_note).emit();
}
};
match (legacy_resolution, resolution) {
(None, Err(_)) => {
assert!(def.is_none());
Err(..) => {
assert!(initial_def.is_none());
let bang = if kind == MacroKind::Bang { "!" } else { "" };
let msg =
format!("cannot find {} `{}{}` in this scope", kind.descr(), ident, bang);
let mut err = self.session.struct_span_err(span, &msg);
self.suggest_macro_name(&ident.as_str(), kind, &mut err, span);
let mut err = self.session.struct_span_err(ident.span, &msg);
self.suggest_macro_name(&ident.as_str(), kind, &mut err, ident.span);
err.emit();
},
(Some(legacy_binding), Ok((binding, FromPrelude(from_prelude))))
if legacy_binding.def() != binding.def_ignoring_ambiguity() &&
(!from_prelude &&
!self.disambiguate_legacy_vs_modern(legacy_binding, binding) ||
legacy_binding.may_appear_after(parent_scope.expansion, binding)) => {
self.report_ambiguity_error(ident, legacy_binding, binding);
},
// OK, non-macro-expanded legacy wins over prelude even if defs are different
// Also, non-macro-expanded legacy wins over modern from the same module
// Also, legacy and modern can co-exist if their defs are same
(Some(legacy_binding), Ok(_)) |
// OK, unambiguous resolution
(Some(legacy_binding), Err(_)) => {
check_consistency(self, legacy_binding.def());
}
// OK, unambiguous resolution
(None, Ok((binding, FromPrelude(from_prelude)))) => {
check_consistency(self, binding.def_ignoring_ambiguity());
if from_prelude {
self.record_use(ident, MacroNS, binding);
}
}
};
}
}
let builtin_attrs = mem::replace(&mut *module.builtin_attrs.borrow_mut(), Vec::new());
for (ident, parent_scope) in builtin_attrs {
let resolve_legacy = |this: &mut Self| this.resolve_legacy_scope(
ident, Some(MacroKind::Attr), &parent_scope, true
);
let resolve_modern = |this: &mut Self| this.resolve_lexical_macro_path_segment(
let binding = self.early_resolve_ident_in_lexical_scope(
ident, MacroNS, Some(MacroKind::Attr), &parent_scope, true, true, ident.span
).map(|(binding, _)| binding).ok();
if let Some(binding) = resolve_legacy(self).or_else(|| resolve_modern(self)) {
);
if let Ok(binding) = binding {
if binding.def_ignoring_ambiguity() !=
Def::NonMacroAttr(NonMacroAttrKind::Builtin) {
let builtin_binding = (Def::NonMacroAttr(NonMacroAttrKind::Builtin),

View File

@ -334,7 +334,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
// expansion. With restricted shadowing names from globs and macro expansions cannot
// shadow names from outer scopes, so we can freely fallback from module search to search
// in outer scopes. To continue search in outer scopes we have to lie a bit and return
// `Determined` to `resolve_lexical_macro_path_segment` even if the correct answer
// `Determined` to `early_resolve_ident_in_lexical_scope` even if the correct answer
// for in-module resolution could be `Undetermined`.
if restricted_shadowing {
return Err(Determined);

View File

@ -34,6 +34,23 @@ LL | use two_macros::m;
| ^^^^^^^^^^^^^
= note: macro-expanded macro imports do not shadow
error: aborting due to 2 previous errors
error[E0659]: `m` is ambiguous
--> $DIR/macros.rs:48:5
|
LL | m!(); //~ ERROR ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
--> $DIR/macros.rs:46:5
|
LL | macro_rules! m { () => {} }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `m` could also refer to the name imported here
--> $DIR/macros.rs:47:9
|
LL | use two_macros::m;
| ^^^^^^^^^^^^^
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0659`.

View File

@ -1,20 +1,3 @@
error[E0659]: `panic` is ambiguous
--> $DIR/shadow_builtin_macros.rs:43:5
|
LL | panic!(); //~ ERROR `panic` is ambiguous
| ^^^^^ ambiguous name
|
note: `panic` could refer to the name defined here
--> $DIR/shadow_builtin_macros.rs:40:9
|
LL | macro_rules! panic { () => {} }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | } }
LL | m!();
| ----- in this macro invocation
= note: `panic` is also a builtin macro
= note: macro-expanded macros do not shadow
error[E0659]: `panic` is ambiguous
--> $DIR/shadow_builtin_macros.rs:25:14
|
@ -43,6 +26,23 @@ LL | ::two_macros::m!(use foo::panic;);
= note: `panic` is also a builtin macro
= note: macro-expanded macro imports do not shadow
error[E0659]: `panic` is ambiguous
--> $DIR/shadow_builtin_macros.rs:43:5
|
LL | panic!(); //~ ERROR `panic` is ambiguous
| ^^^^^ ambiguous name
|
note: `panic` could refer to the name defined here
--> $DIR/shadow_builtin_macros.rs:40:9
|
LL | macro_rules! panic { () => {} }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | } }
LL | m!();
| ----- in this macro invocation
= note: `panic` is also a builtin macro
= note: macro-expanded macros do not shadow
error[E0659]: `n` is ambiguous
--> $DIR/shadow_builtin_macros.rs:59:5
|