From 4e5e0454598b3b81525274b39ea9f57d5f988435 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 28 Aug 2018 00:56:11 +0300 Subject: [PATCH 01/11] resolve: Partially unify bindings from macro_rules and from other items --- src/librustc_resolve/lib.rs | 46 ++++++++++--------------- src/librustc_resolve/macros.rs | 40 ++++++++------------- src/librustc_resolve/resolve_imports.rs | 1 - 3 files changed, 32 insertions(+), 55 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 65fe01ff96aa5..101395e7ac252 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1166,7 +1166,6 @@ struct UseError<'a> { struct AmbiguityError<'a> { span: Span, name: Name, - lexical: bool, b1: &'a NameBinding<'a>, b2: &'a NameBinding<'a>, } @@ -1816,7 +1815,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { NameBindingKind::Import { .. } => false, NameBindingKind::Ambiguity { b1, b2 } => { self.ambiguity_errors.push(AmbiguityError { - span, name: ident.name, lexical: false, b1, b2, + span, name: ident.name, b1, b2, }); true } @@ -4501,35 +4500,32 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { vis.is_accessible_from(module.normal_ancestor_id, self) } - fn report_ambiguity_error( - &self, name: Name, span: Span, _lexical: bool, - def1: Def, is_import1: bool, is_glob1: bool, from_expansion1: bool, span1: Span, - def2: Def, is_import2: bool, _is_glob2: bool, _from_expansion2: bool, span2: Span, - ) { + fn report_ambiguity_error(&self, name: Name, span: Span, b1: &NameBinding, b2: &NameBinding) { let participle = |is_import: bool| if is_import { "imported" } else { "defined" }; - let msg1 = format!("`{}` could refer to the name {} here", name, participle(is_import1)); + let msg1 = + format!("`{}` could refer to the name {} here", name, participle(b1.is_import())); let msg2 = - format!("`{}` could also refer to the name {} here", name, participle(is_import2)); - let note = if from_expansion1 { - Some(if let Def::Macro(..) = def1 { + format!("`{}` could also refer to the name {} here", name, participle(b2.is_import())); + let note = if b1.expansion != Mark::root() { + Some(if let Def::Macro(..) = b1.def() { format!("macro-expanded {} do not shadow", - if is_import1 { "macro imports" } else { "macros" }) + if b1.is_import() { "macro imports" } else { "macros" }) } else { format!("macro-expanded {} do not shadow when used in a macro invocation path", - if is_import1 { "imports" } else { "items" }) + if b1.is_import() { "imports" } else { "items" }) }) - } else if is_glob1 { + } else if b1.is_glob_import() { Some(format!("consider adding an explicit import of `{}` to disambiguate", name)) } else { None }; let mut err = struct_span_err!(self.session, span, E0659, "`{}` is ambiguous", name); - err.span_note(span1, &msg1); - match def2 { - Def::Macro(..) if span2.is_dummy() => + err.span_note(b1.span, &msg1); + match b2.def() { + Def::Macro(..) if b2.span.is_dummy() => err.note(&format!("`{}` is also a builtin macro", name)), - _ => err.span_note(span2, &msg2), + _ => err.span_note(b2.span, &msg2), }; if let Some(note) = note { err.note(¬e); @@ -4554,15 +4550,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ); } - for &AmbiguityError { span, name, b1, b2, lexical } in &self.ambiguity_errors { + for &AmbiguityError { span, name, b1, b2 } in &self.ambiguity_errors { if reported_spans.insert(span) { - self.report_ambiguity_error( - name, span, lexical, - b1.def(), b1.is_import(), b1.is_glob_import(), - b1.expansion != Mark::root(), b1.span, - b2.def(), b2.is_import(), b2.is_glob_import(), - b2.expansion != Mark::root(), b2.span, - ); + self.report_ambiguity_error(name, span, b1, b2); } } @@ -4586,9 +4576,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { let mut reported_errors = FxHashSet(); for binding in replace(&mut self.disallowed_shadowing, Vec::new()) { if self.resolve_legacy_scope(&binding.parent, binding.ident, false).is_some() && - reported_errors.insert((binding.ident, binding.span)) { + reported_errors.insert((binding.ident, binding.binding.span)) { let msg = format!("`{}` is already in scope", binding.ident); - self.session.struct_span_err(binding.span, &msg) + self.session.struct_span_err(binding.binding.span, &msg) .note("macro-expanded `macro_rules!`s may not shadow \ existing macros (see RFC 1560)") .emit(); diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index f403e09b7f768..f240deb1b4c06 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -78,17 +78,12 @@ pub enum LegacyScope<'a> { Binding(&'a LegacyBinding<'a>), } +// Binding produced by a `macro_rules` item. +// Not modularized, can shadow previous legacy bindings, etc. pub struct LegacyBinding<'a> { + pub binding: &'a NameBinding<'a>, pub parent: Cell>, pub ident: Ident, - def_id: DefId, - pub span: Span, -} - -impl<'a> LegacyBinding<'a> { - fn def(&self) -> Def { - Def::Macro(self.def_id, MacroKind::Bang) - } } pub struct ProcMacError { @@ -745,7 +740,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> { name: ident.name, b1: previous_result.0, b2: result.0, - lexical: true, }); return Ok(previous_result); } @@ -794,7 +788,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { mut scope: &'a Cell>, ident: Ident, record_used: bool) - -> Option<(&'a LegacyBinding<'a>, FromExpansion)> { + -> Option<(&'a NameBinding<'a>, FromExpansion)> { let ident = ident.modern(); let mut relative_depth: u32 = 0; loop { @@ -821,7 +815,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { if record_used && relative_depth > 0 { self.disallowed_shadowing.push(potential_binding); } - return Some((potential_binding, FromExpansion(relative_depth > 0))); + return Some((potential_binding.binding, FromExpansion(relative_depth > 0))); } scope = &potential_binding.parent; } @@ -881,18 +875,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> { self.suggest_macro_name(&ident.as_str(), kind, &mut err, span); err.emit(); }, - (Some((legacy_binding, FromExpansion(from_expansion))), - Ok((binding, FromPrelude(false)))) | - (Some((legacy_binding, FromExpansion(from_expansion @ true))), - Ok((binding, FromPrelude(true)))) => { - if legacy_binding.def() != binding.def_ignoring_ambiguity() { - self.report_ambiguity_error( - ident.name, span, true, - legacy_binding.def(), false, false, - from_expansion, legacy_binding.span, - binding.def(), binding.is_import(), binding.is_glob_import(), - binding.expansion != Mark::root(), binding.span, - ); + (Some((legacy_binding, FromExpansion(_))), Ok((binding, FromPrelude(false)))) | + (Some((legacy_binding, FromExpansion(true))), Ok((binding, FromPrelude(true)))) => { + if legacy_binding.def_ignoring_ambiguity() != binding.def_ignoring_ambiguity() { + self.report_ambiguity_error(ident.name, span, legacy_binding, binding); } }, // OK, non-macro-expanded legacy wins over macro prelude even if defs are different @@ -1013,10 +999,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> { if def.legacy { let ident = ident.modern(); self.macro_names.insert(ident); - *legacy_scope = LegacyScope::Binding(self.arenas.alloc_legacy_binding(LegacyBinding { - parent: Cell::new(*legacy_scope), ident: ident, def_id: def_id, span: item.span, - })); let def = Def::Macro(def_id, MacroKind::Bang); + let vis = ty::Visibility::Invisible; // Doesn't matter for legacy bindings + let binding = (def, vis, item.span, expansion).to_name_binding(self.arenas); + *legacy_scope = LegacyScope::Binding(self.arenas.alloc_legacy_binding( + LegacyBinding { parent: Cell::new(*legacy_scope), binding, ident } + )); self.all_macros.insert(ident.name, def); if attr::contains_name(&item.attrs, "macro_export") { let module = self.graph_root; diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 73c9af0d11c47..9d2e51069c7b7 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -251,7 +251,6 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { self.ambiguity_errors.push(AmbiguityError { span: path_span, name, - lexical: false, b1: binding, b2: shadowed_glob, }); From 83a51deef5b92d9131b19e53b0fc5a1bcf98f565 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 28 Aug 2018 01:41:07 +0300 Subject: [PATCH 02/11] resolve: Model `resolve_legacy_scope` after `resolve_lexical_macro_path_segment` --- src/librustc_resolve/lib.rs | 18 ---- src/librustc_resolve/macros.rs | 124 ++++++++++++++++------ src/test/ui/macros/macro-shadowing.rs | 4 +- src/test/ui/macros/macro-shadowing.stderr | 17 ++- src/test/ui/out-of-order-shadowing.rs | 3 +- src/test/ui/out-of-order-shadowing.stderr | 15 ++- 6 files changed, 121 insertions(+), 60 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 101395e7ac252..26756e2992600 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1402,8 +1402,6 @@ pub struct Resolver<'a, 'b: 'a> { proc_mac_errors: Vec, /// crate-local macro expanded `macro_export` referred to by a module-relative path macro_expanded_macro_export_errors: BTreeSet<(Span, Span)>, - /// macro-expanded `macro_rules` shadowing existing macros - disallowed_shadowing: Vec<&'a LegacyBinding<'a>>, arenas: &'a ResolverArenas<'a>, dummy_binding: &'a NameBinding<'a>, @@ -1715,7 +1713,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ambiguity_errors: Vec::new(), use_injections: Vec::new(), proc_mac_errors: Vec::new(), - disallowed_shadowing: Vec::new(), macro_expanded_macro_export_errors: BTreeSet::new(), arenas, @@ -4534,7 +4531,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } fn report_errors(&mut self, krate: &Crate) { - self.report_shadowing_errors(); self.report_with_use_injections(krate); self.report_proc_macro_import(krate); let mut reported_spans = FxHashSet(); @@ -4572,20 +4568,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } } - fn report_shadowing_errors(&mut self) { - let mut reported_errors = FxHashSet(); - for binding in replace(&mut self.disallowed_shadowing, Vec::new()) { - if self.resolve_legacy_scope(&binding.parent, binding.ident, false).is_some() && - reported_errors.insert((binding.ident, binding.binding.span)) { - let msg = format!("`{}` is already in scope", binding.ident); - self.session.struct_span_err(binding.binding.span, &msg) - .note("macro-expanded `macro_rules!`s may not shadow \ - existing macros (see RFC 1560)") - .emit(); - } - } - } - fn report_conflict<'b>(&mut self, parent: Module, ident: Ident, diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index f240deb1b4c06..3baf581c0dec0 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -81,9 +81,9 @@ pub enum LegacyScope<'a> { // Binding produced by a `macro_rules` item. // Not modularized, can shadow previous legacy bindings, etc. pub struct LegacyBinding<'a> { - pub binding: &'a NameBinding<'a>, - pub parent: Cell>, - pub ident: Ident, + binding: &'a NameBinding<'a>, + parent: Cell>, + ident: Ident, } pub struct ProcMacError { @@ -784,42 +784,101 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } } - crate fn resolve_legacy_scope(&mut self, - mut scope: &'a Cell>, - ident: Ident, - record_used: bool) - -> Option<(&'a NameBinding<'a>, FromExpansion)> { + fn resolve_legacy_scope(&mut self, + scope: &'a Cell>, + ident: Ident, + record_used: bool) + -> Option<(&'a NameBinding<'a>, FromExpansion)> { let ident = ident.modern(); - let mut relative_depth: u32 = 0; + + // Names from inner scope that can't shadow names from outer scopes, e.g. + // macro_rules! mac { ... } + // { + // define_mac!(); // if this generates another `macro_rules! mac`, then it can't shadow + // // the outer `mac` and we have and ambiguity error + // mac!(); + // } + let mut potentially_ambiguous_result: Option<(&NameBinding, FromExpansion)> = None; + + // Go through all the scopes and try to resolve the name. + let mut where_to_resolve = scope; + let mut relative_depth = 0u32; loop { - match scope.get() { - LegacyScope::Empty => break, - LegacyScope::Expansion(invocation) => { - match invocation.expansion.get() { - LegacyScope::Invocation(_) => scope.set(invocation.legacy_scope.get()), - LegacyScope::Empty => { - scope = &invocation.legacy_scope; - } - _ => { + let result = match where_to_resolve.get() { + LegacyScope::Binding(legacy_binding) => if ident == legacy_binding.ident { + Some((legacy_binding.binding, FromExpansion(relative_depth > 0))) + } else { + None + } + _ => None, + }; + + macro_rules! continue_search { () => { + where_to_resolve = match where_to_resolve.get() { + LegacyScope::Binding(binding) => &binding.parent, + LegacyScope::Invocation(invocation) => { + relative_depth = relative_depth.saturating_sub(1); + &invocation.legacy_scope + } + LegacyScope::Expansion(invocation) => match invocation.expansion.get() { + LegacyScope::Empty => &invocation.legacy_scope, + LegacyScope::Binding(..) | LegacyScope::Expansion(..) => { relative_depth += 1; - scope = &invocation.expansion; + &invocation.expansion + } + LegacyScope::Invocation(..) => { + where_to_resolve.set(invocation.legacy_scope.get()); + where_to_resolve } } - } - LegacyScope::Invocation(invocation) => { - relative_depth = relative_depth.saturating_sub(1); - scope = &invocation.legacy_scope; - } - LegacyScope::Binding(potential_binding) => { - if potential_binding.ident == ident { - if record_used && relative_depth > 0 { - self.disallowed_shadowing.push(potential_binding); + LegacyScope::Empty => break, // nowhere else to search + }; + + continue; + }} + + match result { + Some(result) => { + if !record_used { + return Some(result); + } + + // Found a solution that is ambiguous with a previously found solution. + // Push an ambiguity error for later reporting and + // return something for better recovery. + if let Some(previous_result) = potentially_ambiguous_result { + if result.0.def() != previous_result.0.def() { + self.ambiguity_errors.push(AmbiguityError { + span: ident.span, + name: ident.name, + b1: previous_result.0, + b2: result.0, + }); + return Some(previous_result); } - return Some((potential_binding.binding, FromExpansion(relative_depth > 0))); } - scope = &potential_binding.parent; + + // Found a solution that's not an ambiguity yet, but is "suspicious" and + // can participate in ambiguities later on. + // Remember it and go search for other solutions in outer scopes. + if (result.1).0 { + potentially_ambiguous_result = Some(result); + + continue_search!(); + } + + // Found a solution that can't be ambiguous. + return Some(result); } - }; + None => { + continue_search!(); + } + } + } + + // Previously found potentially ambiguous result turned out to not be ambiguous after all. + if let Some(previous_result) = potentially_ambiguous_result { + return Some(previous_result); } None @@ -846,8 +905,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let check_consistency = |this: &Self, new_def: Def| { if let Some(def) = def { - if this.ambiguity_errors.is_empty() && this.disallowed_shadowing.is_empty() && - new_def != def && new_def != Def::Err { + 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. diff --git a/src/test/ui/macros/macro-shadowing.rs b/src/test/ui/macros/macro-shadowing.rs index 61abaf8a2ddf8..bf0a7fa21d37a 100644 --- a/src/test/ui/macros/macro-shadowing.rs +++ b/src/test/ui/macros/macro-shadowing.rs @@ -17,14 +17,14 @@ macro_rules! macro_one { () => {} } #[macro_use(macro_two)] extern crate two_macros; macro_rules! m1 { () => { - macro_rules! foo { () => {} } //~ ERROR `foo` is already in scope + macro_rules! foo { () => {} } #[macro_use] //~ ERROR `macro_two` is already in scope extern crate two_macros as __; }} m1!(); -foo!(); +foo!(); //~ ERROR `foo` is ambiguous macro_rules! m2 { () => { macro_rules! foo { () => {} } diff --git a/src/test/ui/macros/macro-shadowing.stderr b/src/test/ui/macros/macro-shadowing.stderr index 28f09509a6233..04f4abc401337 100644 --- a/src/test/ui/macros/macro-shadowing.stderr +++ b/src/test/ui/macros/macro-shadowing.stderr @@ -9,16 +9,27 @@ LL | m1!(); | = note: macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560) -error: `foo` is already in scope +error[E0659]: `foo` is ambiguous + --> $DIR/macro-shadowing.rs:27:1 + | +LL | foo!(); //~ ERROR `foo` is ambiguous + | ^^^ + | +note: `foo` could refer to the name defined here --> $DIR/macro-shadowing.rs:20:5 | -LL | macro_rules! foo { () => {} } //~ ERROR `foo` is already in scope +LL | macro_rules! foo { () => {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | m1!(); | ------ in this macro invocation +note: `foo` could also refer to the name defined here + --> $DIR/macro-shadowing.rs:15:1 | - = note: macro-expanded `macro_rules!`s may not shadow existing macros (see RFC 1560) +LL | macro_rules! foo { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: macro-expanded macros do not shadow error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/out-of-order-shadowing.rs b/src/test/ui/out-of-order-shadowing.rs index 1fafaf85112be..977b475b11340 100644 --- a/src/test/ui/out-of-order-shadowing.rs +++ b/src/test/ui/out-of-order-shadowing.rs @@ -9,11 +9,10 @@ // except according to those terms. // aux-build:define_macro.rs -// error-pattern: `bar` is already in scope macro_rules! bar { () => {} } define_macro!(bar); -bar!(); +bar!(); //~ ERROR `bar` is ambiguous macro_rules! m { () => { #[macro_use] extern crate define_macro; } } m!(); diff --git a/src/test/ui/out-of-order-shadowing.stderr b/src/test/ui/out-of-order-shadowing.stderr index 78e32e23ff636..424c194d8fce0 100644 --- a/src/test/ui/out-of-order-shadowing.stderr +++ b/src/test/ui/out-of-order-shadowing.stderr @@ -1,11 +1,22 @@ -error: `bar` is already in scope +error[E0659]: `bar` is ambiguous --> $DIR/out-of-order-shadowing.rs:15:1 | +LL | bar!(); //~ ERROR `bar` is ambiguous + | ^^^ + | +note: `bar` could refer to the name defined here + --> $DIR/out-of-order-shadowing.rs:14:1 + | LL | define_macro!(bar); | ^^^^^^^^^^^^^^^^^^^ +note: `bar` could also refer to the name defined here + --> $DIR/out-of-order-shadowing.rs:13:1 | - = note: macro-expanded `macro_rules!`s may not shadow existing macros (see RFC 1560) +LL | macro_rules! bar { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: macro-expanded macros do not shadow = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to previous error +For more information about this error, try `rustc --explain E0659`. From f34ac26114b9fa91167d135c2788e1e5c3d3140e Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 28 Aug 2018 02:20:59 +0300 Subject: [PATCH 03/11] resolve: Model shadowing restriction for macro_rules after modern macros This is a regression for legacy macros that will be fixed in the next commit --- src/librustc_resolve/macros.rs | 39 ++++++++++------------- src/libunwind/libunwind.rs | 6 ++-- src/test/ui/macros/macro-shadowing.rs | 2 +- src/test/ui/macros/macro-shadowing.stderr | 26 ++++++++++++++- 4 files changed, 45 insertions(+), 28 deletions(-) diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 3baf581c0dec0..7494e7e4ce5a3 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -46,7 +46,6 @@ use rustc_data_structures::sync::Lrc; use rustc_data_structures::small_vec::ExpectOne; crate struct FromPrelude(bool); -crate struct FromExpansion(bool); #[derive(Clone)] pub struct InvocationData<'a> { @@ -481,7 +480,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } let legacy_resolution = self.resolve_legacy_scope(&invocation.legacy_scope, path[0], false); - let result = if let Some((legacy_binding, _)) = legacy_resolution { + let result = if let Some(legacy_binding) = legacy_resolution { Ok(legacy_binding.def()) } else { match self.resolve_lexical_macro_path_segment(path[0], MacroNS, false, force, @@ -788,7 +787,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { scope: &'a Cell>, ident: Ident, record_used: bool) - -> Option<(&'a NameBinding<'a>, FromExpansion)> { + -> Option<&'a NameBinding<'a>> { let ident = ident.modern(); // Names from inner scope that can't shadow names from outer scopes, e.g. @@ -798,15 +797,14 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // // the outer `mac` and we have and ambiguity error // mac!(); // } - let mut potentially_ambiguous_result: Option<(&NameBinding, FromExpansion)> = None; + let mut potentially_ambiguous_result: Option<&NameBinding> = None; // Go through all the scopes and try to resolve the name. let mut where_to_resolve = scope; - let mut relative_depth = 0u32; loop { let result = match where_to_resolve.get() { LegacyScope::Binding(legacy_binding) => if ident == legacy_binding.ident { - Some((legacy_binding.binding, FromExpansion(relative_depth > 0))) + Some(legacy_binding.binding) } else { None } @@ -816,16 +814,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> { macro_rules! continue_search { () => { where_to_resolve = match where_to_resolve.get() { LegacyScope::Binding(binding) => &binding.parent, - LegacyScope::Invocation(invocation) => { - relative_depth = relative_depth.saturating_sub(1); - &invocation.legacy_scope - } + LegacyScope::Invocation(invocation) => &invocation.legacy_scope, LegacyScope::Expansion(invocation) => match invocation.expansion.get() { LegacyScope::Empty => &invocation.legacy_scope, - LegacyScope::Binding(..) | LegacyScope::Expansion(..) => { - relative_depth += 1; - &invocation.expansion - } + LegacyScope::Binding(..) | + LegacyScope::Expansion(..) => &invocation.expansion, LegacyScope::Invocation(..) => { where_to_resolve.set(invocation.legacy_scope.get()); where_to_resolve @@ -847,12 +840,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // Push an ambiguity error for later reporting and // return something for better recovery. if let Some(previous_result) = potentially_ambiguous_result { - if result.0.def() != previous_result.0.def() { + if result.def() != previous_result.def() { self.ambiguity_errors.push(AmbiguityError { span: ident.span, name: ident.name, - b1: previous_result.0, - b2: result.0, + b1: previous_result, + b2: result, }); return Some(previous_result); } @@ -861,7 +854,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // Found a solution that's not an ambiguity yet, but is "suspicious" and // can participate in ambiguities later on. // Remember it and go search for other solutions in outer scopes. - if (result.1).0 { + if result.expansion != Mark::root() { potentially_ambiguous_result = Some(result); continue_search!(); @@ -933,16 +926,16 @@ impl<'a, 'cl> Resolver<'a, 'cl> { self.suggest_macro_name(&ident.as_str(), kind, &mut err, span); err.emit(); }, - (Some((legacy_binding, FromExpansion(_))), Ok((binding, FromPrelude(false)))) | - (Some((legacy_binding, FromExpansion(true))), Ok((binding, FromPrelude(true)))) => { + (Some(legacy_binding), Ok((binding, FromPrelude(from_prelude)))) + if !from_prelude || legacy_binding.expansion != Mark::root() => { if legacy_binding.def_ignoring_ambiguity() != binding.def_ignoring_ambiguity() { self.report_ambiguity_error(ident.name, span, legacy_binding, binding); } }, - // OK, non-macro-expanded legacy wins over macro prelude even if defs are different - (Some((legacy_binding, FromExpansion(false))), Ok((_, FromPrelude(true)))) | + // OK, non-macro-expanded legacy wins over prelude even if defs are different + (Some(legacy_binding), Ok(_)) | // OK, unambiguous resolution - (Some((legacy_binding, _)), Err(_)) => { + (Some(legacy_binding), Err(_)) => { check_consistency(self, legacy_binding.def()); } // OK, unambiguous resolution diff --git a/src/libunwind/libunwind.rs b/src/libunwind/libunwind.rs index 43c3e1e766623..d9c18408ac9ae 100644 --- a/src/libunwind/libunwind.rs +++ b/src/libunwind/libunwind.rs @@ -10,7 +10,7 @@ #![allow(nonstandard_style)] -macro_rules! cfg_if { +macro_rules! cfg_if2 { ( $( if #[cfg( $meta:meta )] { $($it1:item)* } else { $($it2:item)* } )* ) => ( $( $( #[cfg($meta)] $it1)* $( #[cfg(not($meta))] $it2)* )* ) } @@ -92,7 +92,7 @@ extern "C" { pub fn _Unwind_GetDataRelBase(ctx: *mut _Unwind_Context) -> _Unwind_Ptr; } -cfg_if! { +cfg_if2! { if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm"))))] { // Not ARM EHABI #[repr(C)] @@ -238,4 +238,4 @@ if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] { _Unwind_SjLj_RaiseException(exc) } } -} // cfg_if! +} // cfg_if2! diff --git a/src/test/ui/macros/macro-shadowing.rs b/src/test/ui/macros/macro-shadowing.rs index bf0a7fa21d37a..85d8f29fe28b6 100644 --- a/src/test/ui/macros/macro-shadowing.rs +++ b/src/test/ui/macros/macro-shadowing.rs @@ -28,7 +28,7 @@ foo!(); //~ ERROR `foo` is ambiguous macro_rules! m2 { () => { macro_rules! foo { () => {} } - foo!(); + foo!(); //~ ERROR `foo` is ambiguous }} m2!(); //^ Since `foo` is not used outside this expansion, it is not a shadowing error. diff --git a/src/test/ui/macros/macro-shadowing.stderr b/src/test/ui/macros/macro-shadowing.stderr index 04f4abc401337..0f28f123b43d9 100644 --- a/src/test/ui/macros/macro-shadowing.stderr +++ b/src/test/ui/macros/macro-shadowing.stderr @@ -30,6 +30,30 @@ LL | macro_rules! foo { () => {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: macro-expanded macros do not shadow -error: aborting due to 2 previous errors +error[E0659]: `foo` is ambiguous + --> $DIR/macro-shadowing.rs:31:5 + | +LL | foo!(); //~ ERROR `foo` is ambiguous + | ^^^ + | +note: `foo` could refer to the name defined here + --> $DIR/macro-shadowing.rs:30:5 + | +LL | macro_rules! foo { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | m2!(); + | ------ in this macro invocation +note: `foo` could also refer to the name defined here + --> $DIR/macro-shadowing.rs:20:5 + | +LL | macro_rules! foo { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | m1!(); + | ------ in this macro invocation + = note: macro-expanded macros do not shadow + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0659`. From 9a539ade9fa450bc5653309499a87e71a2fe9286 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 28 Aug 2018 03:27:41 +0300 Subject: [PATCH 04/11] resolve: Cleanup two main macro resolution functions, tweak some comments --- src/librustc_resolve/macros.rs | 114 +++++++++++++++------------------ 1 file changed, 50 insertions(+), 64 deletions(-) diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 7494e7e4ce5a3..26499551af686 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -45,6 +45,7 @@ use std::mem; use rustc_data_structures::sync::Lrc; use rustc_data_structures::small_vec::ExpectOne; +#[derive(Clone, Copy)] crate struct FromPrelude(bool); #[derive(Clone)] @@ -578,15 +579,18 @@ impl<'a, 'cl> Resolver<'a, 'cl> { assert!(force || !record_used); // `record_used` implies `force` ident = ident.modern(); - // Names from inner scope that can't shadow names from outer scopes, e.g. - // mod m { ... } + // This is *the* result, resolution from the scope closest to the resolved identifier. + // However, sometimes this result is "weak" because it comes from a glob import or + // a macro expansion, and in this case it cannot shadow names from outer scopes, e.g. + // mod m { ... } // solution in outer scope // { - // use prefix::*; // if this imports another `m`, then it can't shadow the outer `m` - // // and we have and ambiguity error + // use prefix::*; // imports another `m` - innermost solution + // // weak, cannot shadow the outer `m`, need to report ambiguity error // m::mac!(); // } - // This includes names from globs and from macro expansions. - let mut potentially_ambiguous_result: Option<(&NameBinding, FromPrelude)> = None; + // 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>), @@ -729,32 +733,25 @@ impl<'a, 'cl> Resolver<'a, 'cl> { return Ok(result); } - // Found a solution that is ambiguous with a previously found solution. - // Push an ambiguity error for later reporting and - // return something for better recovery. - if let Some(previous_result) = potentially_ambiguous_result { - if result.0.def() != previous_result.0.def() { + if let Some(innermost_result) = innermost_result { + // Found another solution, if the first one was "weak", report an error. + if result.0.def() != innermost_result.0.def() && + (innermost_result.0.is_glob_import() || + innermost_result.0.expansion != Mark::root()) { self.ambiguity_errors.push(AmbiguityError { span: path_span, name: ident.name, - b1: previous_result.0, + b1: innermost_result.0, b2: result.0, }); - return Ok(previous_result); + return Ok(innermost_result); } + } else { + // Found the first solution. + innermost_result = Some(result); } - // Found a solution that's not an ambiguity yet, but is "suspicious" and - // can participate in ambiguities later on. - // Remember it and go search for other solutions in outer scopes. - if result.0.is_glob_import() || result.0.expansion != Mark::root() { - potentially_ambiguous_result = Some(result); - - continue_search!(); - } - - // Found a solution that can't be ambiguous, great success. - return Ok(result); + continue_search!(); }, Err(Determinacy::Determined) => { continue_search!(); @@ -763,9 +760,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } } - // Previously found potentially ambiguous result turned out to not be ambiguous after all. - if let Some(previous_result) = potentially_ambiguous_result { - return Ok(previous_result); + // The first found solution was the only one, return it. + if let Some(innermost_result) = innermost_result { + return Ok(innermost_result); } let determinacy = Determinacy::determined(force); @@ -784,30 +781,31 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } fn resolve_legacy_scope(&mut self, - scope: &'a Cell>, + invocation_legacy_scope: &'a Cell>, ident: Ident, record_used: bool) -> Option<&'a NameBinding<'a>> { let ident = ident.modern(); - // Names from inner scope that can't shadow names from outer scopes, e.g. - // macro_rules! mac { ... } + // 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_mac!(); // if this generates another `macro_rules! mac`, then it can't shadow - // // the outer `mac` and we have and ambiguity error - // mac!(); + // define_m!(); // generates another `macro_rules! m` - innermost solution + // // weak, cannot shadow the outer `m`, need to report ambiguity error + // m!(); // } - let mut potentially_ambiguous_result: Option<&NameBinding> = None; + // 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 = scope; + let mut where_to_resolve = invocation_legacy_scope; loop { let result = match where_to_resolve.get() { - LegacyScope::Binding(legacy_binding) => if ident == legacy_binding.ident { - Some(legacy_binding.binding) - } else { - None - } + LegacyScope::Binding(legacy_binding) if ident == legacy_binding.ident => + Some(legacy_binding.binding), _ => None, }; @@ -836,32 +834,24 @@ impl<'a, 'cl> Resolver<'a, 'cl> { return Some(result); } - // Found a solution that is ambiguous with a previously found solution. - // Push an ambiguity error for later reporting and - // return something for better recovery. - if let Some(previous_result) = potentially_ambiguous_result { - if result.def() != previous_result.def() { + 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.expansion != Mark::root() { self.ambiguity_errors.push(AmbiguityError { span: ident.span, name: ident.name, - b1: previous_result, + b1: innermost_result, b2: result, }); - return Some(previous_result); + return Some(innermost_result); } + } else { + // Found the first solution. + innermost_result = Some(result); } - // Found a solution that's not an ambiguity yet, but is "suspicious" and - // can participate in ambiguities later on. - // Remember it and go search for other solutions in outer scopes. - if result.expansion != Mark::root() { - potentially_ambiguous_result = Some(result); - - continue_search!(); - } - - // Found a solution that can't be ambiguous. - return Some(result); + continue_search!(); } None => { continue_search!(); @@ -869,12 +859,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } } - // Previously found potentially ambiguous result turned out to not be ambiguous after all. - if let Some(previous_result) = potentially_ambiguous_result { - return Some(previous_result); - } - - None + // 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) { From 27235698f5c73b12539e4765e8dccfec8e27c533 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 28 Aug 2018 04:07:31 +0300 Subject: [PATCH 05/11] resolve: Introduce "may appear after" abstraction for macro path resolutions --- src/librustc_resolve/lib.rs | 28 +++++++++++++++++++++-- src/librustc_resolve/macros.rs | 42 +++++++++++++++++++--------------- src/libsyntax_pos/hygiene.rs | 5 ++++ 3 files changed, 54 insertions(+), 21 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 26756e2992600..e1f532232f559 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1269,6 +1269,15 @@ impl<'a> NameBinding<'a> { fn descr(&self) -> &'static str { if self.is_extern_crate() { "extern crate" } else { self.def().kind_name() } } + + // Suppose that we resolved macro invocation with `invoc_id` to binding `binding` at some + // expansion round `max(invoc_id, binding)` when they both emerged from macros. + // Then this function returns `true` if `self` may emerge from a macro *after* that + // in some later round and screw up our previously found resolution. + fn may_appear_after(&self, _invoc_id: Mark, _binding: &NameBinding) -> bool { + // FIXME: This is a very conservative estimation. + self.expansion != Mark::root() + } } /// Interns the names of the primitive types. @@ -3466,6 +3475,20 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { record_used: bool, path_span: Span, crate_lint: CrateLint, + ) -> PathResult<'a> { + self.resolve_path_with_invoc_id(base_module, path, opt_ns, Mark::root(), + record_used, path_span, crate_lint) + } + + fn resolve_path_with_invoc_id( + &mut self, + base_module: Option>, + path: &[Ident], + opt_ns: Option, // `None` indicates a module path + invoc_id: Mark, + record_used: bool, + path_span: Span, + crate_lint: CrateLint, ) -> PathResult<'a> { let mut module = base_module; let mut allow_super = true; @@ -3555,8 +3578,9 @@ 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, record_used, record_used, - false, path_span).map(|(b, _)| b) + self.resolve_lexical_macro_path_segment(ident, ns, invoc_id, record_used, + record_used, false, path_span) + .map(|(binding, _)| binding) } else { let record_used_id = if record_used { crate_lint.node_id().or(Some(CRATE_NODE_ID)) } else { None }; diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 26499551af686..af9959c808435 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -431,12 +431,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> { Ok((def, self.get_macro(def))) } - pub fn resolve_macro_to_def_inner(&mut self, path: &ast::Path, kind: MacroKind, scope: Mark, + pub fn resolve_macro_to_def_inner(&mut self, path: &ast::Path, kind: MacroKind, invoc_id: Mark, derives_in_scope: &[ast::Path], force: bool) -> Result { let ast::Path { ref segments, span } = *path; let mut path: Vec<_> = segments.iter().map(|seg| seg.ident).collect(); - let invocation = self.invocations[&scope]; + let invocation = self.invocations[&invoc_id]; let module = invocation.module.get(); self.current_module = if module.is_trait() { module.parent.unwrap() } else { module }; @@ -448,8 +448,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } if path.len() > 1 { - let res = self.resolve_path(None, &path, Some(MacroNS), false, span, CrateLint::No); - let def = match res { + let def = match self.resolve_path_with_invoc_id(None, &path, Some(MacroNS), invoc_id, + false, span, CrateLint::No) { PathResult::NonModule(path_res) => match path_res.base_def() { Def::Err => Err(Determinacy::Determined), def @ _ => { @@ -480,11 +480,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } } - let legacy_resolution = self.resolve_legacy_scope(&invocation.legacy_scope, path[0], false); + let legacy_resolution = + self.resolve_legacy_scope(path[0], invoc_id, &invocation.legacy_scope, false); let result = if let Some(legacy_binding) = legacy_resolution { Ok(legacy_binding.def()) } else { - match self.resolve_lexical_macro_path_segment(path[0], MacroNS, false, force, + match self.resolve_lexical_macro_path_segment(path[0], MacroNS, invoc_id, false, force, kind == MacroKind::Attr, span) { Ok((binding, _)) => Ok(binding.def_ignoring_ambiguity()), Err(Determinacy::Undetermined) => return Err(Determinacy::Undetermined), @@ -496,7 +497,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { }; self.current_module.nearest_item_scope().legacy_macro_resolutions.borrow_mut() - .push((scope, path[0], kind, result.ok())); + .push((invoc_id, path[0], kind, result.ok())); if let Ok(Def::NonMacroAttr(NonMacroAttrKind::Custom)) = result {} else { return result; @@ -515,7 +516,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { enum ConvertToDeriveHelper { Yes, No, DontKnow } let mut convert_to_derive_helper = ConvertToDeriveHelper::No; for derive in derives_in_scope { - match self.resolve_macro_path(derive, MacroKind::Derive, scope, &[], force) { + match self.resolve_macro_path(derive, MacroKind::Derive, invoc_id, &[], force) { Ok(ext) => if let SyntaxExtension::ProcMacroDerive(_, ref inert_attrs, _) = *ext { if inert_attrs.contains(&path[0].name) { convert_to_derive_helper = ConvertToDeriveHelper::Yes; @@ -543,10 +544,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> { &mut self, mut ident: Ident, ns: Namespace, + invoc_id: Mark, record_used: bool, force: bool, is_attr: bool, - path_span: Span + path_span: Span, ) -> Result<(&'a NameBinding<'a>, FromPrelude), Determinacy> { // General principles: // 1. Not controlled (user-defined) names should have higher priority than controlled names @@ -737,7 +739,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // Found another solution, if the first one was "weak", report an error. if result.0.def() != innermost_result.0.def() && (innermost_result.0.is_glob_import() || - innermost_result.0.expansion != Mark::root()) { + innermost_result.0.may_appear_after(invoc_id, result.0)) { self.ambiguity_errors.push(AmbiguityError { span: path_span, name: ident.name, @@ -781,8 +783,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } fn resolve_legacy_scope(&mut self, - invocation_legacy_scope: &'a Cell>, ident: Ident, + invoc_id: Mark, + invoc_parent_legacy_scope: &'a Cell>, record_used: bool) -> Option<&'a NameBinding<'a>> { let ident = ident.modern(); @@ -801,7 +804,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let mut innermost_result: Option<&NameBinding> = None; // Go through all the scopes and try to resolve the name. - let mut where_to_resolve = invocation_legacy_scope; + let mut where_to_resolve = invoc_parent_legacy_scope; loop { let result = match where_to_resolve.get() { LegacyScope::Binding(legacy_binding) if ident == legacy_binding.ident => @@ -837,7 +840,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { 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.expansion != Mark::root() { + innermost_result.may_appear_after(invoc_id, result) { self.ambiguity_errors.push(AmbiguityError { span: ident.span, name: ident.name, @@ -875,12 +878,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } } - for &(mark, ident, kind, def) in module.legacy_macro_resolutions.borrow().iter() { + for &(invoc_id, ident, kind, def) in module.legacy_macro_resolutions.borrow().iter() { let span = ident.span; - let legacy_scope = &self.invocations[&mark].legacy_scope; - let legacy_resolution = self.resolve_legacy_scope(legacy_scope, ident, true); - let resolution = self.resolve_lexical_macro_path_segment(ident, MacroNS, true, true, - kind == MacroKind::Attr, span); + let legacy_scope = &self.invocations[&invoc_id].legacy_scope; + let legacy_resolution = self.resolve_legacy_scope(ident, invoc_id, legacy_scope, true); + let resolution = self.resolve_lexical_macro_path_segment( + ident, MacroNS, invoc_id, true, true, kind == MacroKind::Attr, span + ); let check_consistency = |this: &Self, new_def: Def| { if let Some(def) = def { @@ -913,7 +917,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { err.emit(); }, (Some(legacy_binding), Ok((binding, FromPrelude(from_prelude)))) - if !from_prelude || legacy_binding.expansion != Mark::root() => { + if !from_prelude || legacy_binding.may_appear_after(invoc_id, binding) => { if legacy_binding.def_ignoring_ambiguity() != binding.def_ignoring_ambiguity() { self.report_ambiguity_error(ident.name, span, legacy_binding, binding); } diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 7e985cf52f550..f053cb10d0649 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -100,6 +100,11 @@ impl Mark { Mark(raw) } + #[inline] + pub fn parent(self) -> Mark { + HygieneData::with(|data| data.marks[self.0 as usize].parent) + } + #[inline] pub fn expn_info(self) -> Option { HygieneData::with(|data| data.marks[self.0 as usize].expn_info.clone()) From c057d579abb3a6614e38fa6f93f7f5f22a5e7f13 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 29 Aug 2018 03:23:28 +0300 Subject: [PATCH 06/11] resolve: Relax shadowing restriction on macro-expanded macros ... for both legacy and modern macros. Fix previously introduced regressions, add tests. --- src/librustc_resolve/lib.rs | 15 ++++++-- src/libunwind/libunwind.rs | 6 ++-- .../macros/auxiliary/macro-in-other-crate.rs | 5 +++ src/test/ui/macros/macro-shadowing-relaxed.rs | 35 +++++++++++++++++++ src/test/ui/macros/macro-shadowing.rs | 2 +- src/test/ui/macros/macro-shadowing.stderr | 26 +------------- 6 files changed, 57 insertions(+), 32 deletions(-) create mode 100644 src/test/ui/macros/macro-shadowing-relaxed.rs diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index e1f532232f559..b690f305f169a 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1274,9 +1274,18 @@ impl<'a> NameBinding<'a> { // expansion round `max(invoc_id, binding)` when they both emerged from macros. // Then this function returns `true` if `self` may emerge from a macro *after* that // in some later round and screw up our previously found resolution. - fn may_appear_after(&self, _invoc_id: Mark, _binding: &NameBinding) -> bool { - // FIXME: This is a very conservative estimation. - self.expansion != Mark::root() + fn may_appear_after(&self, invoc_id: Mark, binding: &NameBinding) -> bool { + // self > max(invoc_id, binding) => !(self <= invoc_id || self <= binding) + // Expansions are partially ordered, so "may appear after" is an inversion of + // "certainly appears before or simultaneously" and includes unordered cases. + let self_parent_expansion = self.expansion; + let other_parent_expansion = binding.expansion; + let invoc_parent_expansion = invoc_id.parent(); + let certainly_before_other_or_simultaneously = + other_parent_expansion.is_descendant_of(self_parent_expansion); + let certainly_before_invoc_or_simultaneously = + invoc_parent_expansion.is_descendant_of(self_parent_expansion); + !(certainly_before_other_or_simultaneously || certainly_before_invoc_or_simultaneously) } } diff --git a/src/libunwind/libunwind.rs b/src/libunwind/libunwind.rs index d9c18408ac9ae..43c3e1e766623 100644 --- a/src/libunwind/libunwind.rs +++ b/src/libunwind/libunwind.rs @@ -10,7 +10,7 @@ #![allow(nonstandard_style)] -macro_rules! cfg_if2 { +macro_rules! cfg_if { ( $( if #[cfg( $meta:meta )] { $($it1:item)* } else { $($it2:item)* } )* ) => ( $( $( #[cfg($meta)] $it1)* $( #[cfg(not($meta))] $it2)* )* ) } @@ -92,7 +92,7 @@ extern "C" { pub fn _Unwind_GetDataRelBase(ctx: *mut _Unwind_Context) -> _Unwind_Ptr; } -cfg_if2! { +cfg_if! { if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm"))))] { // Not ARM EHABI #[repr(C)] @@ -238,4 +238,4 @@ if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] { _Unwind_SjLj_RaiseException(exc) } } -} // cfg_if2! +} // cfg_if! diff --git a/src/test/ui/macros/auxiliary/macro-in-other-crate.rs b/src/test/ui/macros/auxiliary/macro-in-other-crate.rs index c787cedc2d0ea..7f716c5012efd 100644 --- a/src/test/ui/macros/auxiliary/macro-in-other-crate.rs +++ b/src/test/ui/macros/auxiliary/macro-in-other-crate.rs @@ -17,3 +17,8 @@ macro_rules! mac { macro_rules! inline { () => () } + +#[macro_export] +macro_rules! from_prelude { + () => () +} diff --git a/src/test/ui/macros/macro-shadowing-relaxed.rs b/src/test/ui/macros/macro-shadowing-relaxed.rs new file mode 100644 index 0000000000000..8d5b03b098f29 --- /dev/null +++ b/src/test/ui/macros/macro-shadowing-relaxed.rs @@ -0,0 +1,35 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-pass +// aux-build:macro-in-other-crate.rs + +#![feature(decl_macro)] + +macro_rules! my_include {() => { + // Outer + macro m() {} + #[macro_use(from_prelude)] extern crate macro_in_other_crate; + + fn inner() { + // Inner + macro m() {} + macro_rules! from_prelude { () => {} } + + // OK, both `m` and `from_prelude` are macro-expanded, + // but no more macro-expanded than their counterpart from outer scope. + m!(); + from_prelude!(); + } +}} + +my_include!(); + +fn main() {} diff --git a/src/test/ui/macros/macro-shadowing.rs b/src/test/ui/macros/macro-shadowing.rs index 85d8f29fe28b6..bf0a7fa21d37a 100644 --- a/src/test/ui/macros/macro-shadowing.rs +++ b/src/test/ui/macros/macro-shadowing.rs @@ -28,7 +28,7 @@ foo!(); //~ ERROR `foo` is ambiguous macro_rules! m2 { () => { macro_rules! foo { () => {} } - foo!(); //~ ERROR `foo` is ambiguous + foo!(); }} m2!(); //^ Since `foo` is not used outside this expansion, it is not a shadowing error. diff --git a/src/test/ui/macros/macro-shadowing.stderr b/src/test/ui/macros/macro-shadowing.stderr index 0f28f123b43d9..04f4abc401337 100644 --- a/src/test/ui/macros/macro-shadowing.stderr +++ b/src/test/ui/macros/macro-shadowing.stderr @@ -30,30 +30,6 @@ LL | macro_rules! foo { () => {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: macro-expanded macros do not shadow -error[E0659]: `foo` is ambiguous - --> $DIR/macro-shadowing.rs:31:5 - | -LL | foo!(); //~ ERROR `foo` is ambiguous - | ^^^ - | -note: `foo` could refer to the name defined here - --> $DIR/macro-shadowing.rs:30:5 - | -LL | macro_rules! foo { () => {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | m2!(); - | ------ in this macro invocation -note: `foo` could also refer to the name defined here - --> $DIR/macro-shadowing.rs:20:5 - | -LL | macro_rules! foo { () => {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | m1!(); - | ------ in this macro invocation - = note: macro-expanded macros do not shadow - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0659`. From d26ae20507b1ebdb51c48d4799edaa45c290bfe5 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 29 Aug 2018 04:48:02 +0300 Subject: [PATCH 07/11] resolve: Rename some fields related to legacy macro scopes --- src/librustc_resolve/build_reduced_graph.rs | 24 +++--- src/librustc_resolve/macros.rs | 87 +++++++++++---------- 2 files changed, 60 insertions(+), 51 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 37868a83e3421..423817d1be21d 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -950,7 +950,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { pub struct BuildReducedGraphVisitor<'a, 'b: 'a, 'c: 'b> { pub resolver: &'a mut Resolver<'b, 'c>, - pub legacy_scope: LegacyScope<'b>, + pub current_legacy_scope: LegacyScope<'b>, pub expansion: Mark, } @@ -960,7 +960,7 @@ impl<'a, 'b, 'cl> BuildReducedGraphVisitor<'a, 'b, 'cl> { self.resolver.current_module.unresolved_invocations.borrow_mut().insert(mark); let invocation = self.resolver.invocations[&mark]; invocation.module.set(self.resolver.current_module); - invocation.legacy_scope.set(self.legacy_scope); + invocation.parent_legacy_scope.set(self.current_legacy_scope); invocation } } @@ -986,29 +986,30 @@ impl<'a, 'b, 'cl> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b, 'cl> { fn visit_item(&mut self, item: &'a Item) { let macro_use = match item.node { ItemKind::MacroDef(..) => { - self.resolver.define_macro(item, self.expansion, &mut self.legacy_scope); + self.resolver.define_macro(item, self.expansion, &mut self.current_legacy_scope); return } ItemKind::Mac(..) => { - self.legacy_scope = LegacyScope::Expansion(self.visit_invoc(item.id)); + self.current_legacy_scope = LegacyScope::Expansion(self.visit_invoc(item.id)); return } ItemKind::Mod(..) => self.resolver.contains_macro_use(&item.attrs), _ => false, }; - let (parent, legacy_scope) = (self.resolver.current_module, self.legacy_scope); + let orig_current_module = self.resolver.current_module; + let orig_current_legacy_scope = self.current_legacy_scope; self.resolver.build_reduced_graph_for_item(item, self.expansion); visit::walk_item(self, item); - self.resolver.current_module = parent; + self.resolver.current_module = orig_current_module; if !macro_use { - self.legacy_scope = legacy_scope; + self.current_legacy_scope = orig_current_legacy_scope; } } fn visit_stmt(&mut self, stmt: &'a ast::Stmt) { if let ast::StmtKind::Mac(..) = stmt.node { - self.legacy_scope = LegacyScope::Expansion(self.visit_invoc(stmt.id)); + self.current_legacy_scope = LegacyScope::Expansion(self.visit_invoc(stmt.id)); } else { visit::walk_stmt(self, stmt); } @@ -1025,11 +1026,12 @@ impl<'a, 'b, 'cl> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b, 'cl> { } fn visit_block(&mut self, block: &'a Block) { - let (parent, legacy_scope) = (self.resolver.current_module, self.legacy_scope); + let orig_current_module = self.resolver.current_module; + let orig_current_legacy_scope = self.current_legacy_scope; self.resolver.build_reduced_graph_for_block(block, self.expansion); visit::walk_block(self, block); - self.resolver.current_module = parent; - self.legacy_scope = legacy_scope; + self.resolver.current_module = orig_current_module; + self.current_legacy_scope = orig_current_legacy_scope; } fn visit_trait_item(&mut self, item: &'a TraitItem) { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index af9959c808435..baff58ccee382 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -50,13 +50,15 @@ crate struct FromPrelude(bool); #[derive(Clone)] pub struct InvocationData<'a> { - pub module: Cell>, - pub def_index: DefIndex, - // The scope in which the invocation path is resolved. - pub legacy_scope: Cell>, - // The smallest scope that includes this invocation's expansion, - // or `Empty` if this invocation has not been expanded yet. - pub expansion: Cell>, + crate module: Cell>, + def_index: DefIndex, + // Legacy scope in which the macro was invoked. + // The invocation path is resolved in this scope. + crate parent_legacy_scope: Cell>, + // Legacy scope *produced* by expanding this macro invocation, + // includes all the macro_rules items, other invocations, etc generated by it. + // `Empty` is used if for invocations that has not been expanded yet. + output_legacy_scope: Cell>, } impl<'a> InvocationData<'a> { @@ -64,12 +66,21 @@ impl<'a> InvocationData<'a> { InvocationData { module: Cell::new(graph_root), def_index: CRATE_DEF_INDEX, - legacy_scope: Cell::new(LegacyScope::Empty), - expansion: Cell::new(LegacyScope::Empty), + parent_legacy_scope: Cell::new(LegacyScope::Empty), + output_legacy_scope: Cell::new(LegacyScope::Empty), } } } +// Binding produced by a `macro_rules` item. +// Not modularized, can shadow previous legacy bindings, etc. +pub struct LegacyBinding<'a> { + binding: &'a NameBinding<'a>, + // Legacy scope into which the `macro_rules` item was planted. + parent_legacy_scope: Cell>, + ident: Ident, +} + #[derive(Copy, Clone)] pub enum LegacyScope<'a> { Empty, @@ -78,14 +89,6 @@ pub enum LegacyScope<'a> { Binding(&'a LegacyBinding<'a>), } -// Binding produced by a `macro_rules` item. -// Not modularized, can shadow previous legacy bindings, etc. -pub struct LegacyBinding<'a> { - binding: &'a NameBinding<'a>, - parent: Cell>, - ident: Ident, -} - pub struct ProcMacError { crate_name: Symbol, name: Symbol, @@ -105,8 +108,8 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> { self.invocations.insert(mark, self.arenas.alloc_invocation_data(InvocationData { module: Cell::new(module), def_index: module.def_id().unwrap().index, - legacy_scope: Cell::new(LegacyScope::Empty), - expansion: Cell::new(LegacyScope::Empty), + parent_legacy_scope: Cell::new(LegacyScope::Empty), + output_legacy_scope: Cell::new(LegacyScope::Empty), })); mark } @@ -178,11 +181,11 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> { } let mut visitor = BuildReducedGraphVisitor { resolver: self, - legacy_scope: LegacyScope::Invocation(invocation), + current_legacy_scope: LegacyScope::Invocation(invocation), expansion: mark, }; fragment.visit_with(&mut visitor); - invocation.expansion.set(visitor.legacy_scope); + invocation.output_legacy_scope.set(visitor.current_legacy_scope); } fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc) { @@ -481,7 +484,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } let legacy_resolution = - self.resolve_legacy_scope(path[0], invoc_id, &invocation.legacy_scope, false); + self.resolve_legacy_scope(path[0], invoc_id, &invocation.parent_legacy_scope, false); let result = if let Some(legacy_binding) = legacy_resolution { Ok(legacy_binding.def()) } else { @@ -814,18 +817,20 @@ impl<'a, 'cl> Resolver<'a, 'cl> { macro_rules! continue_search { () => { where_to_resolve = match where_to_resolve.get() { - LegacyScope::Binding(binding) => &binding.parent, - LegacyScope::Invocation(invocation) => &invocation.legacy_scope, - LegacyScope::Expansion(invocation) => match invocation.expansion.get() { - LegacyScope::Empty => &invocation.legacy_scope, - LegacyScope::Binding(..) | - LegacyScope::Expansion(..) => &invocation.expansion, - LegacyScope::Invocation(..) => { - where_to_resolve.set(invocation.legacy_scope.get()); - where_to_resolve + LegacyScope::Empty => break, // nowhere else to search + LegacyScope::Binding(binding) => &binding.parent_legacy_scope, + LegacyScope::Invocation(invocation) => &invocation.parent_legacy_scope, + LegacyScope::Expansion(invocation) => { + match invocation.output_legacy_scope.get() { + LegacyScope::Empty => &invocation.parent_legacy_scope, + LegacyScope::Binding(..) | + LegacyScope::Expansion(..) => &invocation.output_legacy_scope, + LegacyScope::Invocation(..) => { + where_to_resolve.set(invocation.parent_legacy_scope.get()); + where_to_resolve + } } } - LegacyScope::Empty => break, // nowhere else to search }; continue; @@ -880,8 +885,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> { for &(invoc_id, ident, kind, def) in module.legacy_macro_resolutions.borrow().iter() { let span = ident.span; - let legacy_scope = &self.invocations[&invoc_id].legacy_scope; - let legacy_resolution = self.resolve_legacy_scope(ident, invoc_id, legacy_scope, true); + let invoc_parent_legacy_scope = &self.invocations[&invoc_id].parent_legacy_scope; + let legacy_resolution = + self.resolve_legacy_scope(ident, invoc_id, invoc_parent_legacy_scope, true); let resolution = self.resolve_lexical_macro_path_segment( ident, MacroNS, invoc_id, true, true, kind == MacroKind::Attr, span ); @@ -1007,8 +1013,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> { arenas.alloc_invocation_data(InvocationData { def_index: invoc.def_index, module: Cell::new(graph_root), - expansion: Cell::new(LegacyScope::Empty), - legacy_scope: Cell::new(LegacyScope::Empty), + parent_legacy_scope: Cell::new(LegacyScope::Empty), + output_legacy_scope: Cell::new(LegacyScope::Empty), }) }); }; @@ -1023,7 +1029,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { pub fn define_macro(&mut self, item: &ast::Item, expansion: Mark, - legacy_scope: &mut LegacyScope<'a>) { + current_legacy_scope: &mut LegacyScope<'a>) { self.local_macro_def_scopes.insert(item.id, self.current_module); let ident = item.ident; if ident.name == "macro_rules" { @@ -1043,9 +1049,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let def = Def::Macro(def_id, MacroKind::Bang); let vis = ty::Visibility::Invisible; // Doesn't matter for legacy bindings let binding = (def, vis, item.span, expansion).to_name_binding(self.arenas); - *legacy_scope = LegacyScope::Binding(self.arenas.alloc_legacy_binding( - LegacyBinding { parent: Cell::new(*legacy_scope), binding, ident } - )); + let legacy_binding = self.arenas.alloc_legacy_binding(LegacyBinding { + parent_legacy_scope: Cell::new(*current_legacy_scope), binding, ident + }); + *current_legacy_scope = LegacyScope::Binding(legacy_binding); self.all_macros.insert(ident.name, def); if attr::contains_name(&item.attrs, "macro_export") { let module = self.graph_root; From e00993a1abacc2bf211892af1e8012b55ad1ed9b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 30 Aug 2018 04:56:55 +0300 Subject: [PATCH 08/11] Add test cases for possible restricted shadowing configurations Whitelist `#[rustc_transparent_macro]` so it's not interpreted as a potential attribute macro --- src/libsyntax/feature_gate.rs | 4 + .../ui/macros/restricted-shadowing-legacy.rs | 281 ++++++++++++++++++ .../macros/restricted-shadowing-legacy.stderr | 195 ++++++++++++ .../ui/macros/restricted-shadowing-modern.rs | 235 +++++++++++++++ .../macros/restricted-shadowing-modern.stderr | 165 ++++++++++ 5 files changed, 880 insertions(+) create mode 100644 src/test/ui/macros/restricted-shadowing-legacy.rs create mode 100644 src/test/ui/macros/restricted-shadowing-legacy.stderr create mode 100644 src/test/ui/macros/restricted-shadowing-modern.rs create mode 100644 src/test/ui/macros/restricted-shadowing-modern.stderr diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index e3ea3563d853b..cee6f3e261c4f 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -966,6 +966,10 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG "the `#[rustc_test_marker]` attribute \ is used internally to track tests", cfg_fn!(rustc_attrs))), + ("rustc_transparent_macro", Whitelisted, Gated(Stability::Unstable, + "rustc_attrs", + "used internally for testing macro hygiene", + cfg_fn!(rustc_attrs))), // RFC #2094 ("nll", Whitelisted, Gated(Stability::Unstable, diff --git a/src/test/ui/macros/restricted-shadowing-legacy.rs b/src/test/ui/macros/restricted-shadowing-legacy.rs new file mode 100644 index 0000000000000..7950dce25a67e --- /dev/null +++ b/src/test/ui/macros/restricted-shadowing-legacy.rs @@ -0,0 +1,281 @@ +// Legend: +// `+` - possible configuration +// `-` - configuration impossible due to properties of partial ordering +// `-?` - configuration impossible due to block/scope syntax +// `+?` - configuration possible only with legacy scoping + +// N | Outer ~ Invoc | Invoc ~ Inner | Outer ~ Inner | Possible | +// 1 | < | < | < | + | +// 2 | < | < | = | - | +// 3 | < | < | > | - | +// 4 | < | < | Unordered | - | +// 5 | < | = | < | + | +// 6 | < | = | = | - | +// 7 | < | = | > | - | +// 8 | < | = | Unordered | - | +// 9 | < | > | < | + | +// 10 | < | > | = | + | +// 11 | < | > | > | -? | +// 12 | < | > | Unordered | -? | +// 13 | < | Unordered | < | + | +// 14 | < | Unordered | = | - | +// 15 | < | Unordered | > | - | +// 16 | < | Unordered | Unordered | -? | +// 17 | = | < | < | + | +// 18 | = | < | = | - | +// 19 | = | < | > | - | +// 20 | = | < | Unordered | - | +// 21 | = | = | < | - | +// 22 | = | = | = | + | +// 23 | = | = | > | - | +// 24 | = | = | Unordered | - | +// 25 | = | > | < | - | +// 26 | = | > | = | - | +// 27 | = | > | > | -? | +// 28 | = | > | Unordered | - | +// 29 | = | Unordered | < | - | +// 30 | = | Unordered | = | - | +// 31 | = | Unordered | > | - | +// 32 | = | Unordered | Unordered | -? | +// 33 | > | < | < | +? | +// 34 | > | < | = | +? | +// 35 | > | < | > | +? | +// 36 | > | < | Unordered | + | +// 37 | > | = | < | - | +// 38 | > | = | = | - | +// 39 | > | = | > | + | +// 40 | > | = | Unordered | - | +// 41 | > | > | < | - | +// 42 | > | > | = | - | +// 43 | > | > | > | -? | +// 44 | > | > | Unordered | - | +// 45 | > | Unordered | < | - | +// 46 | > | Unordered | = | - | +// 47 | > | Unordered | > | -? | +// 48 | > | Unordered | Unordered | -? | +// 49 | Unordered | < | < | -? | +// 50 | Unordered | < | = | - | +// 51 | Unordered | < | > | - | +// 52 | Unordered | < | Unordered | + | +// 53 | Unordered | = | < | - | +// 54 | Unordered | = | = | - | +// 55 | Unordered | = | > | - | +// 56 | Unordered | = | Unordered | + | +// 57 | Unordered | > | < | - | +// 58 | Unordered | > | = | - | +// 59 | Unordered | > | > | + | +// 60 | Unordered | > | Unordered | + | +// 61 | Unordered | Unordered | < | +? | +// 62 | Unordered | Unordered | = | +? | +// 63 | Unordered | Unordered | > | +? | +// 64 | Unordered | Unordered | Unordered | + | + +#![feature(decl_macro, rustc_attrs)] + +macro_rules! include { () => { + macro_rules! gen_outer { () => { + macro_rules! m { () => {} } + }} + macro_rules! gen_inner { () => { + macro_rules! m { () => {} } + }} + macro_rules! gen_invoc { () => { + m!() + }} + + // ----------------------------------------------------------- + + fn check1() { + macro_rules! m { () => {} } + + macro_rules! gen_gen_inner_invoc { () => { + gen_inner!(); + m!(); //~ ERROR `m` is ambiguous + }} + gen_gen_inner_invoc!(); + } + + fn check5() { + macro_rules! m { () => {} } + + macro_rules! gen_inner_invoc { () => { + macro_rules! m { () => {} } + m!(); // OK + }} + gen_inner_invoc!(); + } + + fn check9() { + macro_rules! m { () => {} } + + macro_rules! gen_inner_gen_invoc { () => { + macro_rules! m { () => {} } + gen_invoc!(); // OK + }} + gen_inner_gen_invoc!(); + } + + fn check10() { + macro_rules! m { () => {} } + + macro_rules! m { () => {} } + + gen_invoc!(); // OK + } + + fn check13() { + macro_rules! m { () => {} } + + gen_inner!(); + + macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous + gen_invoc!(); + } + + fn check17() { + macro_rules! m { () => {} } + + gen_inner!(); + + m!(); //~ ERROR `m` is ambiguous + } + + fn check22() { + macro_rules! m { () => {} } + + macro_rules! m { () => {} } + + m!(); // OK + } + + fn check36() { + gen_outer!(); + + gen_inner!(); + + m!(); //~ ERROR `m` is ambiguous + } + + fn check39() { + gen_outer!(); + + macro_rules! m { () => {} } + + m!(); // OK + } + + fn check52() { + gen_outer!(); + + macro_rules! gen_gen_inner_invoc { () => { + gen_inner!(); + m!(); //~ ERROR `m` is ambiguous + }} + gen_gen_inner_invoc!(); + } + + fn check56() { + gen_outer!(); + + macro_rules! gen_inner_invoc { () => { + macro_rules! m { () => {} } + m!(); // OK + }} + gen_inner_invoc!(); + } + + fn check59() { + gen_outer!(); + + macro_rules! m { () => {} } + + gen_invoc!(); // OK + } + + fn check60() { + gen_outer!(); + + macro_rules! gen_inner_gen_invoc { () => { + macro_rules! m { () => {} } + gen_invoc!(); // OK + }} + gen_inner_gen_invoc!(); + } + + fn check64() { + gen_outer!(); + + gen_inner!(); + + macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous + gen_invoc!(); + } + + // ----------------------------------------------------------- + // These configurations are only possible with legacy macro scoping + + fn check33() { + macro_rules! gen_outer_gen_inner { () => { + macro_rules! m { () => {} } + gen_inner!(); + }} + gen_outer_gen_inner!(); + + m!(); //~ ERROR `m` is ambiguous + } + + fn check34() { + macro_rules! gen_outer_inner { () => { + macro_rules! m { () => {} } + macro_rules! m { () => {} } + }} + gen_outer_inner!(); + + m!(); // OK + } + + fn check35() { + macro_rules! gen_gen_outer_inner { () => { + gen_outer!(); + macro_rules! m { () => {} } + }} + gen_gen_outer_inner!(); + + m!(); // OK + } + + fn check61() { + macro_rules! gen_outer_gen_inner { () => { + macro_rules! m { () => {} } + gen_inner!(); + }} + gen_outer_gen_inner!(); + + macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous + gen_invoc!(); + } + + fn check62() { + macro_rules! gen_outer_inner { () => { + macro_rules! m { () => {} } + macro_rules! m { () => {} } + }} + gen_outer_inner!(); + + gen_invoc!(); // OK + } + + fn check63() { + macro_rules! gen_gen_outer_inner { () => { + gen_outer!(); + macro_rules! m { () => {} } + }} + gen_gen_outer_inner!(); + + gen_invoc!(); // OK + } +}} + +include!(); + +fn main() {} diff --git a/src/test/ui/macros/restricted-shadowing-legacy.stderr b/src/test/ui/macros/restricted-shadowing-legacy.stderr new file mode 100644 index 0000000000000..cd069343c0b68 --- /dev/null +++ b/src/test/ui/macros/restricted-shadowing-legacy.stderr @@ -0,0 +1,195 @@ +error[E0659]: `m` is ambiguous + --> $DIR/restricted-shadowing-legacy.rs:93:13 + | +LL | m!(); //~ ERROR `m` is ambiguous + | ^ + | +note: `m` could refer to the name defined here + --> $DIR/restricted-shadowing-legacy.rs:80:9 + | +LL | macro_rules! m { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation +note: `m` could also refer to the name defined here + --> $DIR/restricted-shadowing-legacy.rs:89:9 + | +LL | macro_rules! m { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation + = note: macro-expanded macros do not shadow + +error[E0659]: `m` is ambiguous + --> $DIR/restricted-shadowing-legacy.rs:131:42 + | +LL | macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous + | ^ + | +note: `m` could refer to the name defined here + --> $DIR/restricted-shadowing-legacy.rs:80:9 + | +LL | macro_rules! m { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation +note: `m` could also refer to the name defined here + --> $DIR/restricted-shadowing-legacy.rs:127:9 + | +LL | macro_rules! m { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation + = note: macro-expanded macros do not shadow + +error[E0659]: `m` is ambiguous + --> $DIR/restricted-shadowing-legacy.rs:140:9 + | +LL | m!(); //~ ERROR `m` is ambiguous + | ^ + | +note: `m` could refer to the name defined here + --> $DIR/restricted-shadowing-legacy.rs:80:9 + | +LL | macro_rules! m { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation +note: `m` could also refer to the name defined here + --> $DIR/restricted-shadowing-legacy.rs:136:9 + | +LL | macro_rules! m { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation + = note: macro-expanded macros do not shadow + +error[E0659]: `m` is ambiguous + --> $DIR/restricted-shadowing-legacy.rs:156:9 + | +LL | m!(); //~ ERROR `m` is ambiguous + | ^ + | +note: `m` could refer to the name defined here + --> $DIR/restricted-shadowing-legacy.rs:80:9 + | +LL | macro_rules! m { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation +note: `m` could also refer to the name defined here + --> $DIR/restricted-shadowing-legacy.rs:77:9 + | +LL | macro_rules! m { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation + = note: macro-expanded macros do not shadow + +error[E0659]: `m` is ambiguous + --> $DIR/restricted-shadowing-legacy.rs:172:13 + | +LL | m!(); //~ ERROR `m` is ambiguous + | ^ + | +note: `m` could refer to the name defined here + --> $DIR/restricted-shadowing-legacy.rs:80:9 + | +LL | macro_rules! m { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation +note: `m` could also refer to the name defined here + --> $DIR/restricted-shadowing-legacy.rs:77:9 + | +LL | macro_rules! m { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation + = note: macro-expanded macros do not shadow + +error[E0659]: `m` is ambiguous + --> $DIR/restricted-shadowing-legacy.rs:210:42 + | +LL | macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous + | ^ + | +note: `m` could refer to the name defined here + --> $DIR/restricted-shadowing-legacy.rs:80:9 + | +LL | macro_rules! m { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation +note: `m` could also refer to the name defined here + --> $DIR/restricted-shadowing-legacy.rs:77:9 + | +LL | macro_rules! m { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation + = note: macro-expanded macros do not shadow + +error[E0659]: `m` is ambiguous + --> $DIR/restricted-shadowing-legacy.rs:224:9 + | +LL | m!(); //~ ERROR `m` is ambiguous + | ^ + | +note: `m` could refer to the name defined here + --> $DIR/restricted-shadowing-legacy.rs:80:9 + | +LL | macro_rules! m { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation +note: `m` could also refer to the name defined here + --> $DIR/restricted-shadowing-legacy.rs:219:13 + | +LL | macro_rules! m { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation + = note: macro-expanded macros do not shadow + +error[E0659]: `m` is ambiguous + --> $DIR/restricted-shadowing-legacy.rs:254:42 + | +LL | macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous + | ^ + | +note: `m` could refer to the name defined here + --> $DIR/restricted-shadowing-legacy.rs:80:9 + | +LL | macro_rules! m { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation +note: `m` could also refer to the name defined here + --> $DIR/restricted-shadowing-legacy.rs:249:13 + | +LL | macro_rules! m { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation + = note: macro-expanded macros do not shadow + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/macros/restricted-shadowing-modern.rs b/src/test/ui/macros/restricted-shadowing-modern.rs new file mode 100644 index 0000000000000..2052810161499 --- /dev/null +++ b/src/test/ui/macros/restricted-shadowing-modern.rs @@ -0,0 +1,235 @@ +// Legend: +// `+` - possible configuration +// `-` - configuration impossible due to properties of partial ordering +// `-?` - configuration impossible due to block/scope syntax +// `+?` - configuration possible only with legacy scoping + +// N | Outer ~ Invoc | Invoc ~ Inner | Outer ~ Inner | Possible | +// 1 | < | < | < | + | +// 2 | < | < | = | - | +// 3 | < | < | > | - | +// 4 | < | < | Unordered | - | +// 5 | < | = | < | + | +// 6 | < | = | = | - | +// 7 | < | = | > | - | +// 8 | < | = | Unordered | - | +// 9 | < | > | < | + | +// 10 | < | > | = | + | +// 11 | < | > | > | -? | +// 12 | < | > | Unordered | -? | +// 13 | < | Unordered | < | + | +// 14 | < | Unordered | = | - | +// 15 | < | Unordered | > | - | +// 16 | < | Unordered | Unordered | -? | +// 17 | = | < | < | + | +// 18 | = | < | = | - | +// 19 | = | < | > | - | +// 20 | = | < | Unordered | - | +// 21 | = | = | < | - | +// 22 | = | = | = | + | +// 23 | = | = | > | - | +// 24 | = | = | Unordered | - | +// 25 | = | > | < | - | +// 26 | = | > | = | - | +// 27 | = | > | > | -? | +// 28 | = | > | Unordered | - | +// 29 | = | Unordered | < | - | +// 30 | = | Unordered | = | - | +// 31 | = | Unordered | > | - | +// 32 | = | Unordered | Unordered | -? | +// 33 | > | < | < | -? | +// 34 | > | < | = | -? | +// 35 | > | < | > | -? | +// 36 | > | < | Unordered | + | +// 37 | > | = | < | - | +// 38 | > | = | = | - | +// 39 | > | = | > | + | +// 40 | > | = | Unordered | - | +// 41 | > | > | < | - | +// 42 | > | > | = | - | +// 43 | > | > | > | -? | +// 44 | > | > | Unordered | - | +// 45 | > | Unordered | < | - | +// 46 | > | Unordered | = | - | +// 47 | > | Unordered | > | -? | +// 48 | > | Unordered | Unordered | -? | +// 49 | Unordered | < | < | -? | +// 50 | Unordered | < | = | - | +// 51 | Unordered | < | > | - | +// 52 | Unordered | < | Unordered | + | +// 53 | Unordered | = | < | - | +// 54 | Unordered | = | = | - | +// 55 | Unordered | = | > | - | +// 56 | Unordered | = | Unordered | + | +// 57 | Unordered | > | < | - | +// 58 | Unordered | > | = | - | +// 59 | Unordered | > | > | + | +// 60 | Unordered | > | Unordered | + | +// 61 | Unordered | Unordered | < | -? | +// 62 | Unordered | Unordered | = | -? | +// 63 | Unordered | Unordered | > | -? | +// 64 | Unordered | Unordered | Unordered | + | + +#![feature(decl_macro, rustc_attrs)] + +#[rustc_transparent_macro] +macro include() { + #[rustc_transparent_macro] + macro gen_outer() { + macro m() {} + } + #[rustc_transparent_macro] + macro gen_inner() { + macro m() {} + } + #[rustc_transparent_macro] + macro gen_invoc() { + m!() + } + + // ----------------------------------------------------------- + + fn check1() { + macro m() {} + { + #[rustc_transparent_macro] + macro gen_gen_inner_invoc() { + gen_inner!(); + m!(); //~ ERROR `m` is ambiguous + } + gen_gen_inner_invoc!(); + } + } + + fn check5() { + macro m() {} + { + #[rustc_transparent_macro] + macro gen_inner_invoc() { + macro m() {} + m!(); // OK + } + gen_inner_invoc!(); + } + } + + fn check9() { + macro m() {} + { + #[rustc_transparent_macro] + macro gen_inner_gen_invoc() { + macro m() {} + gen_invoc!(); // OK + } + gen_inner_gen_invoc!(); + } + } + + fn check10() { + macro m() {} + { + macro m() {} + gen_invoc!(); // OK + } + } + + fn check13() { + macro m() {} + { + gen_inner!(); + #[rustc_transparent_macro] + macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous + gen_invoc!(); + } + } + + fn check17() { + macro m() {} + { + gen_inner!(); + m!(); //~ ERROR `m` is ambiguous + } + } + + fn check22() { + macro m() {} + { + macro m() {} + m!(); // OK + } + } + + fn check36() { + gen_outer!(); + { + gen_inner!(); + m!(); //~ ERROR `m` is ambiguous + } + } + + fn check39() { + gen_outer!(); + { + macro m() {} + m!(); // OK + } + } + + fn check52() { + gen_outer!(); + { + #[rustc_transparent_macro] + macro gen_gen_inner_invoc() { + gen_inner!(); + m!(); //~ ERROR `m` is ambiguous + } + gen_gen_inner_invoc!(); + } + } + + fn check56() { + gen_outer!(); + { + #[rustc_transparent_macro] + macro gen_inner_invoc() { + macro m() {} + m!(); // OK + } + gen_inner_invoc!(); + } + } + + fn check59() { + gen_outer!(); + { + macro m() {} + gen_invoc!(); // OK + } + } + + fn check60() { + gen_outer!(); + { + #[rustc_transparent_macro] + macro gen_inner_gen_invoc() { + macro m() {} + gen_invoc!(); // OK + } + gen_inner_gen_invoc!(); + } + } + + fn check64() { + gen_outer!(); + { + gen_inner!(); + #[rustc_transparent_macro] + macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous + gen_invoc!(); + } + } +} + +include!(); + +fn main() {} diff --git a/src/test/ui/macros/restricted-shadowing-modern.stderr b/src/test/ui/macros/restricted-shadowing-modern.stderr new file mode 100644 index 0000000000000..8d64c6c47699f --- /dev/null +++ b/src/test/ui/macros/restricted-shadowing-modern.stderr @@ -0,0 +1,165 @@ +error[E0659]: `m` is ambiguous + --> $DIR/restricted-shadowing-modern.rs:98:17 + | +LL | m!(); //~ ERROR `m` is ambiguous + | ^ +... +LL | include!(); + | ----------- in this macro invocation + | +note: `m` could refer to the name defined here + --> $DIR/restricted-shadowing-modern.rs:83:9 + | +LL | macro m() {} + | ^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation +note: `m` could also refer to the name defined here + --> $DIR/restricted-shadowing-modern.rs:93:9 + | +LL | macro m() {} + | ^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation + = note: macro-expanded macros do not shadow + +error[E0659]: `m` is ambiguous + --> $DIR/restricted-shadowing-modern.rs:141:33 + | +LL | macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous + | ^ +... +LL | include!(); + | ----------- in this macro invocation + | +note: `m` could refer to the name defined here + --> $DIR/restricted-shadowing-modern.rs:83:9 + | +LL | macro m() {} + | ^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation +note: `m` could also refer to the name defined here + --> $DIR/restricted-shadowing-modern.rs:137:9 + | +LL | macro m() {} + | ^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation + = note: macro-expanded macros do not shadow + +error[E0659]: `m` is ambiguous + --> $DIR/restricted-shadowing-modern.rs:150:13 + | +LL | m!(); //~ ERROR `m` is ambiguous + | ^ +... +LL | include!(); + | ----------- in this macro invocation + | +note: `m` could refer to the name defined here + --> $DIR/restricted-shadowing-modern.rs:83:9 + | +LL | macro m() {} + | ^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation +note: `m` could also refer to the name defined here + --> $DIR/restricted-shadowing-modern.rs:147:9 + | +LL | macro m() {} + | ^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation + = note: macro-expanded macros do not shadow + +error[E0659]: `m` is ambiguous + --> $DIR/restricted-shadowing-modern.rs:166:13 + | +LL | m!(); //~ ERROR `m` is ambiguous + | ^ +... +LL | include!(); + | ----------- in this macro invocation + | +note: `m` could refer to the name defined here + --> $DIR/restricted-shadowing-modern.rs:83:9 + | +LL | macro m() {} + | ^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation +note: `m` could also refer to the name defined here + --> $DIR/restricted-shadowing-modern.rs:79:9 + | +LL | macro m() {} + | ^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation + = note: macro-expanded macros do not shadow + +error[E0659]: `m` is ambiguous + --> $DIR/restricted-shadowing-modern.rs:184:17 + | +LL | m!(); //~ ERROR `m` is ambiguous + | ^ +... +LL | include!(); + | ----------- in this macro invocation + | +note: `m` could refer to the name defined here + --> $DIR/restricted-shadowing-modern.rs:83:9 + | +LL | macro m() {} + | ^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation +note: `m` could also refer to the name defined here + --> $DIR/restricted-shadowing-modern.rs:79:9 + | +LL | macro m() {} + | ^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation + = note: macro-expanded macros do not shadow + +error[E0659]: `m` is ambiguous + --> $DIR/restricted-shadowing-modern.rs:227:33 + | +LL | macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous + | ^ +... +LL | include!(); + | ----------- in this macro invocation + | +note: `m` could refer to the name defined here + --> $DIR/restricted-shadowing-modern.rs:83:9 + | +LL | macro m() {} + | ^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation +note: `m` could also refer to the name defined here + --> $DIR/restricted-shadowing-modern.rs:79:9 + | +LL | macro m() {} + | ^^^^^^^^^^^^ +... +LL | include!(); + | ----------- in this macro invocation + = note: macro-expanded macros do not shadow + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0659`. From ae2e5aa1c7a926d663d9bc7ef46d1c0ffdc71e77 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 31 Aug 2018 22:53:08 +0300 Subject: [PATCH 09/11] resolve: Further simplify legacy scopes, add comments --- src/librustc_resolve/build_reduced_graph.rs | 5 +- src/librustc_resolve/macros.rs | 80 +++++++++++---------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 423817d1be21d..c5d1f63f70a84 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -961,6 +961,7 @@ impl<'a, 'b, 'cl> BuildReducedGraphVisitor<'a, 'b, 'cl> { let invocation = self.resolver.invocations[&mark]; invocation.module.set(self.resolver.current_module); invocation.parent_legacy_scope.set(self.current_legacy_scope); + invocation.output_legacy_scope.set(self.current_legacy_scope); invocation } } @@ -990,7 +991,7 @@ impl<'a, 'b, 'cl> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b, 'cl> { return } ItemKind::Mac(..) => { - self.current_legacy_scope = LegacyScope::Expansion(self.visit_invoc(item.id)); + self.current_legacy_scope = LegacyScope::Invocation(self.visit_invoc(item.id)); return } ItemKind::Mod(..) => self.resolver.contains_macro_use(&item.attrs), @@ -1009,7 +1010,7 @@ impl<'a, 'b, 'cl> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b, 'cl> { fn visit_stmt(&mut self, stmt: &'a ast::Stmt) { if let ast::StmtKind::Mac(..) = stmt.node { - self.current_legacy_scope = LegacyScope::Expansion(self.visit_invoc(stmt.id)); + self.current_legacy_scope = LegacyScope::Invocation(self.visit_invoc(stmt.id)); } else { visit::walk_stmt(self, stmt); } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index baff58ccee382..0359d62104c33 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -50,15 +50,16 @@ crate struct FromPrelude(bool); #[derive(Clone)] pub struct InvocationData<'a> { - crate module: Cell>, def_index: DefIndex, - // Legacy scope in which the macro was invoked. - // The invocation path is resolved in this scope. + /// Module in which the macro was invoked. + crate module: Cell>, + /// Legacy scope in which the macro was invoked. + /// The invocation path is resolved in this scope. crate parent_legacy_scope: Cell>, - // Legacy scope *produced* by expanding this macro invocation, - // includes all the macro_rules items, other invocations, etc generated by it. - // `Empty` is used if for invocations that has not been expanded yet. - output_legacy_scope: Cell>, + /// Legacy scope *produced* by expanding this macro invocation, + /// includes all the macro_rules items, other invocations, etc generated by it. + /// Set to the parent scope if the macro is not expanded yet (as if the macro produced nothing). + crate output_legacy_scope: Cell>, } impl<'a> InvocationData<'a> { @@ -72,21 +73,32 @@ impl<'a> InvocationData<'a> { } } -// Binding produced by a `macro_rules` item. -// Not modularized, can shadow previous legacy bindings, etc. +/// Binding produced by a `macro_rules` item. +/// Not modularized, can shadow previous legacy bindings, etc. pub struct LegacyBinding<'a> { binding: &'a NameBinding<'a>, - // Legacy scope into which the `macro_rules` item was planted. - parent_legacy_scope: Cell>, + /// Legacy scope into which the `macro_rules` item was planted. + parent_legacy_scope: LegacyScope<'a>, ident: Ident, } +/// Scope introduced by a `macro_rules!` macro. +/// Starts at the macro's definition and ends at the end of the macro's parent module +/// (named or unnamed), or even further if it escapes with `#[macro_use]`. +/// Some macro invocations need to introduce legacy scopes too because they +/// potentially can expand into macro definitions. #[derive(Copy, Clone)] pub enum LegacyScope<'a> { + /// Created when invocation data is allocated in the arena, + /// must be replaced with a proper scope later. + Uninitialized, + /// Empty "root" scope at the crate start containing no names. Empty, - Invocation(&'a InvocationData<'a>), // The scope of the invocation, not including its expansion - Expansion(&'a InvocationData<'a>), // The scope of the invocation, including its expansion + /// Scope introduced by a `macro_rules!` macro definition. Binding(&'a LegacyBinding<'a>), + /// Scope introduced by a macro invocation that can potentially + /// create a `macro_rules!` macro definition. + Invocation(&'a InvocationData<'a>), } pub struct ProcMacError { @@ -181,7 +193,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> { } let mut visitor = BuildReducedGraphVisitor { resolver: self, - current_legacy_scope: LegacyScope::Invocation(invocation), + current_legacy_scope: invocation.parent_legacy_scope.get(), expansion: mark, }; fragment.visit_with(&mut visitor); @@ -483,8 +495,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } } - let legacy_resolution = - self.resolve_legacy_scope(path[0], invoc_id, &invocation.parent_legacy_scope, false); + let legacy_resolution = self.resolve_legacy_scope( + path[0], invoc_id, invocation.parent_legacy_scope.get(), false + ); let result = if let Some(legacy_binding) = legacy_resolution { Ok(legacy_binding.def()) } else { @@ -788,7 +801,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { fn resolve_legacy_scope(&mut self, ident: Ident, invoc_id: Mark, - invoc_parent_legacy_scope: &'a Cell>, + invoc_parent_legacy_scope: LegacyScope<'a>, record_used: bool) -> Option<&'a NameBinding<'a>> { let ident = ident.modern(); @@ -809,28 +822,18 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // Go through all the scopes and try to resolve the name. let mut where_to_resolve = invoc_parent_legacy_scope; loop { - let result = match where_to_resolve.get() { + 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.get() { + 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.parent_legacy_scope, - LegacyScope::Expansion(invocation) => { - match invocation.output_legacy_scope.get() { - LegacyScope::Empty => &invocation.parent_legacy_scope, - LegacyScope::Binding(..) | - LegacyScope::Expansion(..) => &invocation.output_legacy_scope, - LegacyScope::Invocation(..) => { - where_to_resolve.set(invocation.parent_legacy_scope.get()); - where_to_resolve - } - } - } + LegacyScope::Binding(binding) => binding.parent_legacy_scope, + LegacyScope::Invocation(invocation) => invocation.output_legacy_scope.get(), + LegacyScope::Uninitialized => unreachable!(), }; continue; @@ -885,9 +888,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> { for &(invoc_id, ident, kind, def) in module.legacy_macro_resolutions.borrow().iter() { let span = ident.span; - let invoc_parent_legacy_scope = &self.invocations[&invoc_id].parent_legacy_scope; - let legacy_resolution = - self.resolve_legacy_scope(ident, invoc_id, invoc_parent_legacy_scope, true); + let invocation = self.invocations[&invoc_id]; + let legacy_resolution = self.resolve_legacy_scope( + ident, invoc_id, invocation.parent_legacy_scope.get(), true + ); let resolution = self.resolve_lexical_macro_path_segment( ident, MacroNS, invoc_id, true, true, kind == MacroKind::Attr, span ); @@ -1013,8 +1017,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> { arenas.alloc_invocation_data(InvocationData { def_index: invoc.def_index, module: Cell::new(graph_root), - parent_legacy_scope: Cell::new(LegacyScope::Empty), - output_legacy_scope: Cell::new(LegacyScope::Empty), + parent_legacy_scope: Cell::new(LegacyScope::Uninitialized), + output_legacy_scope: Cell::new(LegacyScope::Uninitialized), }) }); }; @@ -1050,7 +1054,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let vis = ty::Visibility::Invisible; // Doesn't matter for legacy bindings let binding = (def, vis, item.span, expansion).to_name_binding(self.arenas); let legacy_binding = self.arenas.alloc_legacy_binding(LegacyBinding { - parent_legacy_scope: Cell::new(*current_legacy_scope), binding, ident + parent_legacy_scope: *current_legacy_scope, binding, ident }); *current_legacy_scope = LegacyScope::Binding(legacy_binding); self.all_macros.insert(ident.name, def); From 9beb5c3ef3062226783529f626fb8c4a7eb7f936 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 8 Sep 2018 02:50:57 +0300 Subject: [PATCH 10/11] Add checks for expected macro output in restricted shadowing tests --- src/librustc_resolve/lib.rs | 2 + .../ui/macros/restricted-shadowing-legacy.rs | 48 ++++++---- .../macros/restricted-shadowing-legacy.stderr | 92 +++++++++---------- .../ui/macros/restricted-shadowing-modern.rs | 36 +++++--- .../macros/restricted-shadowing-modern.stderr | 72 +++++++-------- 5 files changed, 134 insertions(+), 116 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index b690f305f169a..6c9a924081aeb 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1274,6 +1274,8 @@ impl<'a> NameBinding<'a> { // expansion round `max(invoc_id, binding)` when they both emerged from macros. // Then this function returns `true` if `self` may emerge from a macro *after* that // in some later round and screw up our previously found resolution. + // See more detailed explanation in + // https://github.com/rust-lang/rust/pull/53778#issuecomment-419224049 fn may_appear_after(&self, invoc_id: Mark, binding: &NameBinding) -> bool { // self > max(invoc_id, binding) => !(self <= invoc_id || self <= binding) // Expansions are partially ordered, so "may appear after" is an inversion of diff --git a/src/test/ui/macros/restricted-shadowing-legacy.rs b/src/test/ui/macros/restricted-shadowing-legacy.rs index 7950dce25a67e..f5cac2dfbfb41 100644 --- a/src/test/ui/macros/restricted-shadowing-legacy.rs +++ b/src/test/ui/macros/restricted-shadowing-legacy.rs @@ -1,4 +1,9 @@ // Legend: +// `N` - number of combination, from 0 to 4*4*4=64 +// `Outer < Invoc` means that expansion that produced macro definition `Outer` +// is a strict ancestor of expansion that produced macro definition `Inner`. +// `>`, `=` and `Unordered` mean "strict descendant", "same" and +// "not in ordering relation" for parent expansions. // `+` - possible configuration // `-` - configuration impossible due to properties of partial ordering // `-?` - configuration impossible due to block/scope syntax @@ -72,12 +77,15 @@ #![feature(decl_macro, rustc_attrs)] +struct Right; +// struct Wrong; // not defined + macro_rules! include { () => { macro_rules! gen_outer { () => { - macro_rules! m { () => {} } + macro_rules! m { () => { Wrong } } }} macro_rules! gen_inner { () => { - macro_rules! m { () => {} } + macro_rules! m { () => { Right } } }} macro_rules! gen_invoc { () => { m!() @@ -96,29 +104,29 @@ macro_rules! include { () => { } fn check5() { - macro_rules! m { () => {} } + macro_rules! m { () => { Wrong } } macro_rules! gen_inner_invoc { () => { - macro_rules! m { () => {} } + macro_rules! m { () => { Right } } m!(); // OK }} gen_inner_invoc!(); } fn check9() { - macro_rules! m { () => {} } + macro_rules! m { () => { Wrong } } macro_rules! gen_inner_gen_invoc { () => { - macro_rules! m { () => {} } + macro_rules! m { () => { Right } } gen_invoc!(); // OK }} gen_inner_gen_invoc!(); } fn check10() { - macro_rules! m { () => {} } + macro_rules! m { () => { Wrong } } - macro_rules! m { () => {} } + macro_rules! m { () => { Right } } gen_invoc!(); // OK } @@ -141,9 +149,9 @@ macro_rules! include { () => { } fn check22() { - macro_rules! m { () => {} } + macro_rules! m { () => { Wrong } } - macro_rules! m { () => {} } + macro_rules! m { () => { Right } } m!(); // OK } @@ -159,7 +167,7 @@ macro_rules! include { () => { fn check39() { gen_outer!(); - macro_rules! m { () => {} } + macro_rules! m { () => { Right } } m!(); // OK } @@ -178,7 +186,7 @@ macro_rules! include { () => { gen_outer!(); macro_rules! gen_inner_invoc { () => { - macro_rules! m { () => {} } + macro_rules! m { () => { Right } } m!(); // OK }} gen_inner_invoc!(); @@ -187,7 +195,7 @@ macro_rules! include { () => { fn check59() { gen_outer!(); - macro_rules! m { () => {} } + macro_rules! m { () => { Right } } gen_invoc!(); // OK } @@ -196,7 +204,7 @@ macro_rules! include { () => { gen_outer!(); macro_rules! gen_inner_gen_invoc { () => { - macro_rules! m { () => {} } + macro_rules! m { () => { Right } } gen_invoc!(); // OK }} gen_inner_gen_invoc!(); @@ -226,8 +234,8 @@ macro_rules! include { () => { fn check34() { macro_rules! gen_outer_inner { () => { - macro_rules! m { () => {} } - macro_rules! m { () => {} } + macro_rules! m { () => { Wrong } } + macro_rules! m { () => { Right } } }} gen_outer_inner!(); @@ -237,7 +245,7 @@ macro_rules! include { () => { fn check35() { macro_rules! gen_gen_outer_inner { () => { gen_outer!(); - macro_rules! m { () => {} } + macro_rules! m { () => { Right } } }} gen_gen_outer_inner!(); @@ -257,8 +265,8 @@ macro_rules! include { () => { fn check62() { macro_rules! gen_outer_inner { () => { - macro_rules! m { () => {} } - macro_rules! m { () => {} } + macro_rules! m { () => { Wrong } } + macro_rules! m { () => { Right } } }} gen_outer_inner!(); @@ -268,7 +276,7 @@ macro_rules! include { () => { fn check63() { macro_rules! gen_gen_outer_inner { () => { gen_outer!(); - macro_rules! m { () => {} } + macro_rules! m { () => { Right } } }} gen_gen_outer_inner!(); diff --git a/src/test/ui/macros/restricted-shadowing-legacy.stderr b/src/test/ui/macros/restricted-shadowing-legacy.stderr index cd069343c0b68..c1a01956998b4 100644 --- a/src/test/ui/macros/restricted-shadowing-legacy.stderr +++ b/src/test/ui/macros/restricted-shadowing-legacy.stderr @@ -1,19 +1,19 @@ error[E0659]: `m` is ambiguous - --> $DIR/restricted-shadowing-legacy.rs:93:13 + --> $DIR/restricted-shadowing-legacy.rs:101:13 | LL | m!(); //~ ERROR `m` is ambiguous | ^ | note: `m` could refer to the name defined here - --> $DIR/restricted-shadowing-legacy.rs:80:9 + --> $DIR/restricted-shadowing-legacy.rs:88:9 | -LL | macro_rules! m { () => {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | macro_rules! m { () => { Right } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation note: `m` could also refer to the name defined here - --> $DIR/restricted-shadowing-legacy.rs:89:9 + --> $DIR/restricted-shadowing-legacy.rs:97:9 | LL | macro_rules! m { () => {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,21 +23,21 @@ LL | include!(); = note: macro-expanded macros do not shadow error[E0659]: `m` is ambiguous - --> $DIR/restricted-shadowing-legacy.rs:131:42 + --> $DIR/restricted-shadowing-legacy.rs:139:42 | LL | macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous | ^ | note: `m` could refer to the name defined here - --> $DIR/restricted-shadowing-legacy.rs:80:9 + --> $DIR/restricted-shadowing-legacy.rs:88:9 | -LL | macro_rules! m { () => {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | macro_rules! m { () => { Right } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation note: `m` could also refer to the name defined here - --> $DIR/restricted-shadowing-legacy.rs:127:9 + --> $DIR/restricted-shadowing-legacy.rs:135:9 | LL | macro_rules! m { () => {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -47,21 +47,21 @@ LL | include!(); = note: macro-expanded macros do not shadow error[E0659]: `m` is ambiguous - --> $DIR/restricted-shadowing-legacy.rs:140:9 + --> $DIR/restricted-shadowing-legacy.rs:148:9 | LL | m!(); //~ ERROR `m` is ambiguous | ^ | note: `m` could refer to the name defined here - --> $DIR/restricted-shadowing-legacy.rs:80:9 + --> $DIR/restricted-shadowing-legacy.rs:88:9 | -LL | macro_rules! m { () => {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | macro_rules! m { () => { Right } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation note: `m` could also refer to the name defined here - --> $DIR/restricted-shadowing-legacy.rs:136:9 + --> $DIR/restricted-shadowing-legacy.rs:144:9 | LL | macro_rules! m { () => {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -71,93 +71,93 @@ LL | include!(); = note: macro-expanded macros do not shadow error[E0659]: `m` is ambiguous - --> $DIR/restricted-shadowing-legacy.rs:156:9 + --> $DIR/restricted-shadowing-legacy.rs:164:9 | LL | m!(); //~ ERROR `m` is ambiguous | ^ | note: `m` could refer to the name defined here - --> $DIR/restricted-shadowing-legacy.rs:80:9 + --> $DIR/restricted-shadowing-legacy.rs:88:9 | -LL | macro_rules! m { () => {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | macro_rules! m { () => { Right } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation note: `m` could also refer to the name defined here - --> $DIR/restricted-shadowing-legacy.rs:77:9 + --> $DIR/restricted-shadowing-legacy.rs:85:9 | -LL | macro_rules! m { () => {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | macro_rules! m { () => { Wrong } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation = note: macro-expanded macros do not shadow error[E0659]: `m` is ambiguous - --> $DIR/restricted-shadowing-legacy.rs:172:13 + --> $DIR/restricted-shadowing-legacy.rs:180:13 | LL | m!(); //~ ERROR `m` is ambiguous | ^ | note: `m` could refer to the name defined here - --> $DIR/restricted-shadowing-legacy.rs:80:9 + --> $DIR/restricted-shadowing-legacy.rs:88:9 | -LL | macro_rules! m { () => {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | macro_rules! m { () => { Right } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation note: `m` could also refer to the name defined here - --> $DIR/restricted-shadowing-legacy.rs:77:9 + --> $DIR/restricted-shadowing-legacy.rs:85:9 | -LL | macro_rules! m { () => {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | macro_rules! m { () => { Wrong } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation = note: macro-expanded macros do not shadow error[E0659]: `m` is ambiguous - --> $DIR/restricted-shadowing-legacy.rs:210:42 + --> $DIR/restricted-shadowing-legacy.rs:218:42 | LL | macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous | ^ | note: `m` could refer to the name defined here - --> $DIR/restricted-shadowing-legacy.rs:80:9 + --> $DIR/restricted-shadowing-legacy.rs:88:9 | -LL | macro_rules! m { () => {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | macro_rules! m { () => { Right } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation note: `m` could also refer to the name defined here - --> $DIR/restricted-shadowing-legacy.rs:77:9 + --> $DIR/restricted-shadowing-legacy.rs:85:9 | -LL | macro_rules! m { () => {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | macro_rules! m { () => { Wrong } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation = note: macro-expanded macros do not shadow error[E0659]: `m` is ambiguous - --> $DIR/restricted-shadowing-legacy.rs:224:9 + --> $DIR/restricted-shadowing-legacy.rs:232:9 | LL | m!(); //~ ERROR `m` is ambiguous | ^ | note: `m` could refer to the name defined here - --> $DIR/restricted-shadowing-legacy.rs:80:9 + --> $DIR/restricted-shadowing-legacy.rs:88:9 | -LL | macro_rules! m { () => {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | macro_rules! m { () => { Right } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation note: `m` could also refer to the name defined here - --> $DIR/restricted-shadowing-legacy.rs:219:13 + --> $DIR/restricted-shadowing-legacy.rs:227:13 | LL | macro_rules! m { () => {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -167,21 +167,21 @@ LL | include!(); = note: macro-expanded macros do not shadow error[E0659]: `m` is ambiguous - --> $DIR/restricted-shadowing-legacy.rs:254:42 + --> $DIR/restricted-shadowing-legacy.rs:262:42 | LL | macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous | ^ | note: `m` could refer to the name defined here - --> $DIR/restricted-shadowing-legacy.rs:80:9 + --> $DIR/restricted-shadowing-legacy.rs:88:9 | -LL | macro_rules! m { () => {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | macro_rules! m { () => { Right } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation note: `m` could also refer to the name defined here - --> $DIR/restricted-shadowing-legacy.rs:249:13 + --> $DIR/restricted-shadowing-legacy.rs:257:13 | LL | macro_rules! m { () => {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/macros/restricted-shadowing-modern.rs b/src/test/ui/macros/restricted-shadowing-modern.rs index 2052810161499..448f623c2208f 100644 --- a/src/test/ui/macros/restricted-shadowing-modern.rs +++ b/src/test/ui/macros/restricted-shadowing-modern.rs @@ -1,4 +1,9 @@ // Legend: +// `N` - number of combination, from 0 to 4*4*4=64 +// `Outer < Invoc` means that expansion that produced macro definition `Outer` +// is a strict ancestor of expansion that produced macro definition `Inner`. +// `>`, `=` and `Unordered` mean "strict descendant", "same" and +// "not in ordering relation" for parent expansions. // `+` - possible configuration // `-` - configuration impossible due to properties of partial ordering // `-?` - configuration impossible due to block/scope syntax @@ -72,15 +77,18 @@ #![feature(decl_macro, rustc_attrs)] +struct Right; +// struct Wrong; // not defined + #[rustc_transparent_macro] macro include() { #[rustc_transparent_macro] macro gen_outer() { - macro m() {} + macro m() { Wrong } } #[rustc_transparent_macro] macro gen_inner() { - macro m() {} + macro m() { Right } } #[rustc_transparent_macro] macro gen_invoc() { @@ -102,11 +110,11 @@ macro include() { } fn check5() { - macro m() {} + macro m() { Wrong } { #[rustc_transparent_macro] macro gen_inner_invoc() { - macro m() {} + macro m() { Right } m!(); // OK } gen_inner_invoc!(); @@ -114,11 +122,11 @@ macro include() { } fn check9() { - macro m() {} + macro m() { Wrong } { #[rustc_transparent_macro] macro gen_inner_gen_invoc() { - macro m() {} + macro m() { Right } gen_invoc!(); // OK } gen_inner_gen_invoc!(); @@ -126,9 +134,9 @@ macro include() { } fn check10() { - macro m() {} + macro m() { Wrong } { - macro m() {} + macro m() { Right } gen_invoc!(); // OK } } @@ -152,9 +160,9 @@ macro include() { } fn check22() { - macro m() {} + macro m() { Wrong } { - macro m() {} + macro m() { Right } m!(); // OK } } @@ -170,7 +178,7 @@ macro include() { fn check39() { gen_outer!(); { - macro m() {} + macro m() { Right } m!(); // OK } } @@ -192,7 +200,7 @@ macro include() { { #[rustc_transparent_macro] macro gen_inner_invoc() { - macro m() {} + macro m() { Right } m!(); // OK } gen_inner_invoc!(); @@ -202,7 +210,7 @@ macro include() { fn check59() { gen_outer!(); { - macro m() {} + macro m() { Right } gen_invoc!(); // OK } } @@ -212,7 +220,7 @@ macro include() { { #[rustc_transparent_macro] macro gen_inner_gen_invoc() { - macro m() {} + macro m() { Right } gen_invoc!(); // OK } gen_inner_gen_invoc!(); diff --git a/src/test/ui/macros/restricted-shadowing-modern.stderr b/src/test/ui/macros/restricted-shadowing-modern.stderr index 8d64c6c47699f..af4a93a407945 100644 --- a/src/test/ui/macros/restricted-shadowing-modern.stderr +++ b/src/test/ui/macros/restricted-shadowing-modern.stderr @@ -1,5 +1,5 @@ error[E0659]: `m` is ambiguous - --> $DIR/restricted-shadowing-modern.rs:98:17 + --> $DIR/restricted-shadowing-modern.rs:106:17 | LL | m!(); //~ ERROR `m` is ambiguous | ^ @@ -8,15 +8,15 @@ LL | include!(); | ----------- in this macro invocation | note: `m` could refer to the name defined here - --> $DIR/restricted-shadowing-modern.rs:83:9 + --> $DIR/restricted-shadowing-modern.rs:91:9 | -LL | macro m() {} - | ^^^^^^^^^^^^ +LL | macro m() { Right } + | ^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation note: `m` could also refer to the name defined here - --> $DIR/restricted-shadowing-modern.rs:93:9 + --> $DIR/restricted-shadowing-modern.rs:101:9 | LL | macro m() {} | ^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | include!(); = note: macro-expanded macros do not shadow error[E0659]: `m` is ambiguous - --> $DIR/restricted-shadowing-modern.rs:141:33 + --> $DIR/restricted-shadowing-modern.rs:149:33 | LL | macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous | ^ @@ -35,15 +35,15 @@ LL | include!(); | ----------- in this macro invocation | note: `m` could refer to the name defined here - --> $DIR/restricted-shadowing-modern.rs:83:9 + --> $DIR/restricted-shadowing-modern.rs:91:9 | -LL | macro m() {} - | ^^^^^^^^^^^^ +LL | macro m() { Right } + | ^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation note: `m` could also refer to the name defined here - --> $DIR/restricted-shadowing-modern.rs:137:9 + --> $DIR/restricted-shadowing-modern.rs:145:9 | LL | macro m() {} | ^^^^^^^^^^^^ @@ -53,7 +53,7 @@ LL | include!(); = note: macro-expanded macros do not shadow error[E0659]: `m` is ambiguous - --> $DIR/restricted-shadowing-modern.rs:150:13 + --> $DIR/restricted-shadowing-modern.rs:158:13 | LL | m!(); //~ ERROR `m` is ambiguous | ^ @@ -62,15 +62,15 @@ LL | include!(); | ----------- in this macro invocation | note: `m` could refer to the name defined here - --> $DIR/restricted-shadowing-modern.rs:83:9 + --> $DIR/restricted-shadowing-modern.rs:91:9 | -LL | macro m() {} - | ^^^^^^^^^^^^ +LL | macro m() { Right } + | ^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation note: `m` could also refer to the name defined here - --> $DIR/restricted-shadowing-modern.rs:147:9 + --> $DIR/restricted-shadowing-modern.rs:155:9 | LL | macro m() {} | ^^^^^^^^^^^^ @@ -80,7 +80,7 @@ LL | include!(); = note: macro-expanded macros do not shadow error[E0659]: `m` is ambiguous - --> $DIR/restricted-shadowing-modern.rs:166:13 + --> $DIR/restricted-shadowing-modern.rs:174:13 | LL | m!(); //~ ERROR `m` is ambiguous | ^ @@ -89,25 +89,25 @@ LL | include!(); | ----------- in this macro invocation | note: `m` could refer to the name defined here - --> $DIR/restricted-shadowing-modern.rs:83:9 + --> $DIR/restricted-shadowing-modern.rs:91:9 | -LL | macro m() {} - | ^^^^^^^^^^^^ +LL | macro m() { Right } + | ^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation note: `m` could also refer to the name defined here - --> $DIR/restricted-shadowing-modern.rs:79:9 + --> $DIR/restricted-shadowing-modern.rs:87:9 | -LL | macro m() {} - | ^^^^^^^^^^^^ +LL | macro m() { Wrong } + | ^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation = note: macro-expanded macros do not shadow error[E0659]: `m` is ambiguous - --> $DIR/restricted-shadowing-modern.rs:184:17 + --> $DIR/restricted-shadowing-modern.rs:192:17 | LL | m!(); //~ ERROR `m` is ambiguous | ^ @@ -116,25 +116,25 @@ LL | include!(); | ----------- in this macro invocation | note: `m` could refer to the name defined here - --> $DIR/restricted-shadowing-modern.rs:83:9 + --> $DIR/restricted-shadowing-modern.rs:91:9 | -LL | macro m() {} - | ^^^^^^^^^^^^ +LL | macro m() { Right } + | ^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation note: `m` could also refer to the name defined here - --> $DIR/restricted-shadowing-modern.rs:79:9 + --> $DIR/restricted-shadowing-modern.rs:87:9 | -LL | macro m() {} - | ^^^^^^^^^^^^ +LL | macro m() { Wrong } + | ^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation = note: macro-expanded macros do not shadow error[E0659]: `m` is ambiguous - --> $DIR/restricted-shadowing-modern.rs:227:33 + --> $DIR/restricted-shadowing-modern.rs:235:33 | LL | macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous | ^ @@ -143,18 +143,18 @@ LL | include!(); | ----------- in this macro invocation | note: `m` could refer to the name defined here - --> $DIR/restricted-shadowing-modern.rs:83:9 + --> $DIR/restricted-shadowing-modern.rs:91:9 | -LL | macro m() {} - | ^^^^^^^^^^^^ +LL | macro m() { Right } + | ^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation note: `m` could also refer to the name defined here - --> $DIR/restricted-shadowing-modern.rs:79:9 + --> $DIR/restricted-shadowing-modern.rs:87:9 | -LL | macro m() {} - | ^^^^^^^^^^^^ +LL | macro m() { Wrong } + | ^^^^^^^^^^^^^^^^^^^ ... LL | include!(); | ----------- in this macro invocation From 2dce3779bbc0353ff9fb544774417a851027fcab Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 8 Sep 2018 02:51:20 +0300 Subject: [PATCH 11/11] resolve: More precise spans for ambiguous resolution errors Add labels to ambiguous resolution errors --- src/librustc_resolve/lib.rs | 32 +++++++++---------- src/librustc_resolve/macros.rs | 10 +++--- src/librustc_resolve/resolve_imports.rs | 8 ++--- src/test/ui/error-codes/E0659.stderr | 4 +-- src/test/ui/imports/duplicate.stderr | 14 ++++---- src/test/ui/imports/glob-shadowing.stderr | 6 ++-- src/test/ui/imports/issue-53269.stderr | 2 +- .../local-modularized-tricky-fail-1.rs | 1 - .../local-modularized-tricky-fail-1.stderr | 15 ++++----- src/test/ui/imports/macro-paths.stderr | 4 +-- src/test/ui/imports/macros.stderr | 6 ++-- .../ui/imports/rfc-1560-warning-cycle.stderr | 2 +- .../ui/imports/shadow_builtin_macros.stderr | 8 ++--- .../macro-path-prelude-shadowing.stderr | 2 +- src/test/ui/macros/macro-shadowing.stderr | 2 +- .../macros/restricted-shadowing-legacy.stderr | 16 +++++----- .../macros/restricted-shadowing-modern.stderr | 30 ++++------------- src/test/ui/out-of-order-shadowing.stderr | 2 +- 18 files changed, 69 insertions(+), 95 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 6c9a924081aeb..b57a8a4d271e8 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1164,8 +1164,7 @@ struct UseError<'a> { } struct AmbiguityError<'a> { - span: Span, - name: Name, + ident: Ident, b1: &'a NameBinding<'a>, b2: &'a NameBinding<'a>, } @@ -1818,7 +1817,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { self.arenas.alloc_module(module) } - fn record_use(&mut self, ident: Ident, ns: Namespace, binding: &'a NameBinding<'a>, span: Span) + fn record_use(&mut self, ident: Ident, ns: Namespace, binding: &'a NameBinding<'a>) -> bool /* true if an error was reported */ { match binding.kind { NameBindingKind::Import { directive, binding, ref used } @@ -1827,13 +1826,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { directive.used.set(true); self.used_imports.insert((directive.id, ns)); self.add_to_glob_map(directive.id, ident); - self.record_use(ident, ns, binding, span) + self.record_use(ident, ns, binding) } NameBindingKind::Import { .. } => false, NameBindingKind::Ambiguity { b1, b2 } => { - self.ambiguity_errors.push(AmbiguityError { - span, name: ident.name, b1, b2, - }); + self.ambiguity_errors.push(AmbiguityError { ident, b1, b2 }); true } _ => false @@ -2853,7 +2850,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { Def::Const(..) if is_syntactic_ambiguity => { // Disambiguate in favor of a unit struct/variant // or constant pattern. - self.record_use(ident, ValueNS, binding.unwrap(), ident.span); + self.record_use(ident, ValueNS, binding.unwrap()); Some(PathResolution::new(def)) } Def::StructCtor(..) | Def::VariantCtor(..) | @@ -4532,12 +4529,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { vis.is_accessible_from(module.normal_ancestor_id, self) } - fn report_ambiguity_error(&self, name: Name, span: Span, b1: &NameBinding, b2: &NameBinding) { + fn report_ambiguity_error(&self, ident: Ident, b1: &NameBinding, b2: &NameBinding) { let participle = |is_import: bool| if is_import { "imported" } else { "defined" }; let msg1 = - format!("`{}` could refer to the name {} here", name, participle(b1.is_import())); + format!("`{}` could refer to the name {} here", ident, participle(b1.is_import())); let msg2 = - format!("`{}` could also refer to the name {} here", name, participle(b2.is_import())); + format!("`{}` could also refer to the name {} here", ident, participle(b2.is_import())); let note = if b1.expansion != Mark::root() { Some(if let Def::Macro(..) = b1.def() { format!("macro-expanded {} do not shadow", @@ -4547,16 +4544,17 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { if b1.is_import() { "imports" } else { "items" }) }) } else if b1.is_glob_import() { - Some(format!("consider adding an explicit import of `{}` to disambiguate", name)) + Some(format!("consider adding an explicit import of `{}` to disambiguate", ident)) } else { None }; - let mut err = struct_span_err!(self.session, span, E0659, "`{}` is ambiguous", name); + let mut err = struct_span_err!(self.session, ident.span, E0659, "`{}` is ambiguous", ident); + err.span_label(ident.span, "ambiguous name"); err.span_note(b1.span, &msg1); match b2.def() { Def::Macro(..) if b2.span.is_dummy() => - err.note(&format!("`{}` is also a builtin macro", name)), + err.note(&format!("`{}` is also a builtin macro", ident)), _ => err.span_note(b2.span, &msg2), }; if let Some(note) = note { @@ -4581,9 +4579,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ); } - for &AmbiguityError { span, name, b1, b2 } in &self.ambiguity_errors { - if reported_spans.insert(span) { - self.report_ambiguity_error(name, span, b1, b2); + for &AmbiguityError { ident, b1, b2 } in &self.ambiguity_errors { + if reported_spans.insert(ident.span) { + self.report_ambiguity_error(ident, b1, b2); } } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 0359d62104c33..96c2e0a6ba7a0 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -757,8 +757,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { (innermost_result.0.is_glob_import() || innermost_result.0.may_appear_after(invoc_id, result.0)) { self.ambiguity_errors.push(AmbiguityError { - span: path_span, - name: ident.name, + ident, b1: innermost_result.0, b2: result.0, }); @@ -850,8 +849,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { if result.def() != innermost_result.def() && innermost_result.may_appear_after(invoc_id, result) { self.ambiguity_errors.push(AmbiguityError { - span: ident.span, - name: ident.name, + ident, b1: innermost_result, b2: result, }); @@ -929,7 +927,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { (Some(legacy_binding), Ok((binding, FromPrelude(from_prelude)))) if !from_prelude || legacy_binding.may_appear_after(invoc_id, binding) => { if legacy_binding.def_ignoring_ambiguity() != binding.def_ignoring_ambiguity() { - self.report_ambiguity_error(ident.name, span, legacy_binding, binding); + self.report_ambiguity_error(ident, legacy_binding, binding); } }, // OK, non-macro-expanded legacy wins over prelude even if defs are different @@ -942,7 +940,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { (None, Ok((binding, FromPrelude(from_prelude)))) => { check_consistency(self, binding.def_ignoring_ambiguity()); if from_prelude { - self.record_use(ident, MacroNS, binding, span); + self.record_use(ident, MacroNS, binding); self.err_if_macro_use_proc_macro(ident.name, span, binding); } } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 9d2e51069c7b7..ef7b5c58fdd18 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -242,21 +242,19 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { if record_used { if let Some(binding) = resolution.binding { if let Some(shadowed_glob) = resolution.shadowed_glob { - let name = ident.name; // Forbid expanded shadowing to avoid time travel. if restricted_shadowing && binding.expansion != Mark::root() && ns != MacroNS && // In MacroNS, `try_define` always forbids this shadowing binding.def() != shadowed_glob.def() { self.ambiguity_errors.push(AmbiguityError { - span: path_span, - name, + ident, b1: binding, b2: shadowed_glob, }); } } - if self.record_use(ident, ns, binding, path_span) { + if self.record_use(ident, ns, binding) { return Ok(self.dummy_binding); } if !self.is_accessible(binding.vis) { @@ -936,7 +934,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS { if let Ok(binding) = result[ns].get() { all_ns_err = false; - if this.record_use(ident, ns, binding, directive.span) { + if this.record_use(ident, ns, binding) { if let ModuleOrUniformRoot::Module(module) = module { this.resolution(module, ident, ns).borrow_mut().binding = Some(this.dummy_binding); diff --git a/src/test/ui/error-codes/E0659.stderr b/src/test/ui/error-codes/E0659.stderr index 06176085b3813..f168b7797ca6d 100644 --- a/src/test/ui/error-codes/E0659.stderr +++ b/src/test/ui/error-codes/E0659.stderr @@ -1,8 +1,8 @@ error[E0659]: `foo` is ambiguous - --> $DIR/E0659.rs:25:5 + --> $DIR/E0659.rs:25:15 | LL | collider::foo(); //~ ERROR E0659 - | ^^^^^^^^^^^^^ + | ^^^ ambiguous name | note: `foo` could refer to the name imported here --> $DIR/E0659.rs:20:13 diff --git a/src/test/ui/imports/duplicate.stderr b/src/test/ui/imports/duplicate.stderr index 452e3e1e2008f..9cdd7aa88f18e 100644 --- a/src/test/ui/imports/duplicate.stderr +++ b/src/test/ui/imports/duplicate.stderr @@ -13,10 +13,10 @@ LL | use a::foo as other_foo; //~ ERROR the name `foo` is defined multiple t | ^^^^^^^^^^^^^^^^^^^ error[E0659]: `foo` is ambiguous - --> $DIR/duplicate.rs:56:9 + --> $DIR/duplicate.rs:56:15 | LL | use self::foo::bar; //~ ERROR `foo` is ambiguous - | ^^^^^^^^^^^^^^ + | ^^^ ambiguous name | note: `foo` could refer to the name imported here --> $DIR/duplicate.rs:53:9 @@ -31,10 +31,10 @@ LL | use self::m2::*; = note: consider adding an explicit import of `foo` to disambiguate error[E0659]: `foo` is ambiguous - --> $DIR/duplicate.rs:45:5 + --> $DIR/duplicate.rs:45:8 | LL | f::foo(); //~ ERROR `foo` is ambiguous - | ^^^^^^ + | ^^^ ambiguous name | note: `foo` could refer to the name imported here --> $DIR/duplicate.rs:34:13 @@ -49,10 +49,10 @@ LL | pub use b::*; = note: consider adding an explicit import of `foo` to disambiguate error[E0659]: `foo` is ambiguous - --> $DIR/duplicate.rs:46:5 + --> $DIR/duplicate.rs:46:8 | LL | g::foo(); //~ ERROR `foo` is ambiguous - | ^^^^^^ + | ^^^ ambiguous name | note: `foo` could refer to the name imported here --> $DIR/duplicate.rs:39:13 @@ -70,7 +70,7 @@ error[E0659]: `foo` is ambiguous --> $DIR/duplicate.rs:59:9 | LL | foo::bar(); //~ ERROR `foo` is ambiguous - | ^^^^^^^^ + | ^^^ ambiguous name | note: `foo` could refer to the name imported here --> $DIR/duplicate.rs:53:9 diff --git a/src/test/ui/imports/glob-shadowing.stderr b/src/test/ui/imports/glob-shadowing.stderr index 7f61cd6c76d6a..33a2963fa2947 100644 --- a/src/test/ui/imports/glob-shadowing.stderr +++ b/src/test/ui/imports/glob-shadowing.stderr @@ -2,7 +2,7 @@ error[E0659]: `env` is ambiguous --> $DIR/glob-shadowing.rs:21:17 | LL | let x = env!("PATH"); //~ ERROR `env` is ambiguous - | ^^^ + | ^^^ ambiguous name | note: `env` could refer to the name imported here --> $DIR/glob-shadowing.rs:19:9 @@ -16,7 +16,7 @@ error[E0659]: `env` is ambiguous --> $DIR/glob-shadowing.rs:29:21 | LL | let x = env!("PATH"); //~ ERROR `env` is ambiguous - | ^^^ + | ^^^ ambiguous name | note: `env` could refer to the name imported here --> $DIR/glob-shadowing.rs:27:13 @@ -30,7 +30,7 @@ error[E0659]: `fenv` is ambiguous --> $DIR/glob-shadowing.rs:39:21 | LL | let x = fenv!(); //~ ERROR `fenv` is ambiguous - | ^^^^ + | ^^^^ ambiguous name | note: `fenv` could refer to the name imported here --> $DIR/glob-shadowing.rs:37:13 diff --git a/src/test/ui/imports/issue-53269.stderr b/src/test/ui/imports/issue-53269.stderr index 0036d71107a95..e125983151d2b 100644 --- a/src/test/ui/imports/issue-53269.stderr +++ b/src/test/ui/imports/issue-53269.stderr @@ -8,7 +8,7 @@ error[E0659]: `mac` is ambiguous --> $DIR/issue-53269.rs:18:5 | LL | mac!(); //~ ERROR `mac` is ambiguous - | ^^^ + | ^^^ ambiguous name | note: `mac` could refer to the name defined here --> $DIR/issue-53269.rs:13:1 diff --git a/src/test/ui/imports/local-modularized-tricky-fail-1.rs b/src/test/ui/imports/local-modularized-tricky-fail-1.rs index 445344732f7bd..fb05b95a96dc6 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-1.rs +++ b/src/test/ui/imports/local-modularized-tricky-fail-1.rs @@ -43,7 +43,6 @@ mod inner2 { fn main() { panic!(); //~ ERROR `panic` is ambiguous - //~^ ERROR `panic` is ambiguous } mod inner3 { diff --git a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr index e9a81e7ae4c4c..cce1fd30f1d6d 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr +++ b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr @@ -2,7 +2,7 @@ error[E0659]: `exported` is ambiguous --> $DIR/local-modularized-tricky-fail-1.rs:38:1 | LL | exported!(); //~ ERROR `exported` is ambiguous - | ^^^^^^^^ + | ^^^^^^^^ ambiguous name | note: `exported` could refer to the name defined here --> $DIR/local-modularized-tricky-fail-1.rs:15:5 @@ -22,10 +22,10 @@ LL | use inner1::*; = note: macro-expanded macros do not shadow error[E0659]: `include` is ambiguous - --> $DIR/local-modularized-tricky-fail-1.rs:57:1 + --> $DIR/local-modularized-tricky-fail-1.rs:56:1 | LL | include!(); //~ ERROR `include` is ambiguous - | ^^^^^^^ + | ^^^^^^^ ambiguous name | note: `include` could refer to the name defined here --> $DIR/local-modularized-tricky-fail-1.rs:27:5 @@ -44,7 +44,7 @@ error[E0659]: `panic` is ambiguous --> $DIR/local-modularized-tricky-fail-1.rs:45:5 | LL | panic!(); //~ ERROR `panic` is ambiguous - | ^^^^^ + | ^^^^^ ambiguous name | note: `panic` could refer to the name defined here --> $DIR/local-modularized-tricky-fail-1.rs:21:5 @@ -60,10 +60,10 @@ LL | define_panic!(); = note: macro-expanded macros do not shadow error[E0659]: `panic` is ambiguous - --> $DIR/local-modularized-tricky-fail-1.rs:45:5 + --> :1:13 | -LL | panic!(); //~ ERROR `panic` is ambiguous - | ^^^^^^^^^ +LL | ( ) => ( { panic ! ( "explicit panic" ) } ) ; ( $ msg : expr ) => ( + | ^^^^^ ambiguous name | note: `panic` could refer to the name defined here --> $DIR/local-modularized-tricky-fail-1.rs:21:5 @@ -77,7 +77,6 @@ LL | define_panic!(); | ---------------- in this macro invocation = note: `panic` is also a builtin macro = note: macro-expanded macros do not shadow - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/imports/macro-paths.stderr b/src/test/ui/imports/macro-paths.stderr index 08f45e1a57530..a612c64c2f470 100644 --- a/src/test/ui/imports/macro-paths.stderr +++ b/src/test/ui/imports/macro-paths.stderr @@ -2,7 +2,7 @@ error[E0659]: `bar` is ambiguous --> $DIR/macro-paths.rs:23:5 | LL | bar::m! { //~ ERROR ambiguous - | ^^^^^^ + | ^^^ ambiguous name | note: `bar` could refer to the name defined here --> $DIR/macro-paths.rs:24:9 @@ -20,7 +20,7 @@ error[E0659]: `baz` is ambiguous --> $DIR/macro-paths.rs:33:5 | LL | baz::m! { //~ ERROR ambiguous - | ^^^^^^ + | ^^^ ambiguous name | note: `baz` could refer to the name defined here --> $DIR/macro-paths.rs:34:9 diff --git a/src/test/ui/imports/macros.stderr b/src/test/ui/imports/macros.stderr index 2c0c4642067ac..c54101fc6e6a8 100644 --- a/src/test/ui/imports/macros.stderr +++ b/src/test/ui/imports/macros.stderr @@ -2,7 +2,7 @@ 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 @@ -19,7 +19,7 @@ error[E0659]: `m` is ambiguous --> $DIR/macros.rs:26:5 | LL | m! { //~ ERROR ambiguous - | ^ + | ^ ambiguous name | note: `m` could refer to the name imported here --> $DIR/macros.rs:27:13 @@ -37,7 +37,7 @@ error[E0659]: `m` is ambiguous --> $DIR/macros.rs:39:9 | LL | m! { //~ ERROR ambiguous - | ^ + | ^ ambiguous name | note: `m` could refer to the name imported here --> $DIR/macros.rs:40:17 diff --git a/src/test/ui/imports/rfc-1560-warning-cycle.stderr b/src/test/ui/imports/rfc-1560-warning-cycle.stderr index 5a01680fc1921..91af3a4b6ac73 100644 --- a/src/test/ui/imports/rfc-1560-warning-cycle.stderr +++ b/src/test/ui/imports/rfc-1560-warning-cycle.stderr @@ -2,7 +2,7 @@ error[E0659]: `Foo` is ambiguous --> $DIR/rfc-1560-warning-cycle.rs:19:17 | LL | fn f(_: Foo) {} //~ ERROR `Foo` is ambiguous - | ^^^ + | ^^^ ambiguous name | note: `Foo` could refer to the name imported here --> $DIR/rfc-1560-warning-cycle.rs:17:13 diff --git a/src/test/ui/imports/shadow_builtin_macros.stderr b/src/test/ui/imports/shadow_builtin_macros.stderr index 5c7f15b6fe26f..e554bbb4f3146 100644 --- a/src/test/ui/imports/shadow_builtin_macros.stderr +++ b/src/test/ui/imports/shadow_builtin_macros.stderr @@ -2,7 +2,7 @@ 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 @@ -19,7 +19,7 @@ error[E0659]: `panic` is ambiguous --> $DIR/shadow_builtin_macros.rs:25:14 | LL | fn f() { panic!(); } //~ ERROR ambiguous - | ^^^^^ + | ^^^^^ ambiguous name | note: `panic` could refer to the name imported here --> $DIR/shadow_builtin_macros.rs:24:9 @@ -33,7 +33,7 @@ error[E0659]: `panic` is ambiguous --> $DIR/shadow_builtin_macros.rs:30:14 | LL | fn f() { panic!(); } //~ ERROR ambiguous - | ^^^^^ + | ^^^^^ ambiguous name | note: `panic` could refer to the name imported here --> $DIR/shadow_builtin_macros.rs:29:26 @@ -47,7 +47,7 @@ error[E0659]: `n` is ambiguous --> $DIR/shadow_builtin_macros.rs:59:5 | LL | n!(); //~ ERROR ambiguous - | ^ + | ^ ambiguous name | note: `n` could refer to the name imported here --> $DIR/shadow_builtin_macros.rs:58:9 diff --git a/src/test/ui/macros/macro-path-prelude-shadowing.stderr b/src/test/ui/macros/macro-path-prelude-shadowing.stderr index c0892f97376e3..607d3e100aa25 100644 --- a/src/test/ui/macros/macro-path-prelude-shadowing.stderr +++ b/src/test/ui/macros/macro-path-prelude-shadowing.stderr @@ -2,7 +2,7 @@ error[E0659]: `std` is ambiguous --> $DIR/macro-path-prelude-shadowing.rs:39:9 | LL | std::panic!(); //~ ERROR `std` is ambiguous - | ^^^^^^^^^^ + | ^^^ ambiguous name | note: `std` could refer to the name imported here --> $DIR/macro-path-prelude-shadowing.rs:37:9 diff --git a/src/test/ui/macros/macro-shadowing.stderr b/src/test/ui/macros/macro-shadowing.stderr index 04f4abc401337..d996f3a704195 100644 --- a/src/test/ui/macros/macro-shadowing.stderr +++ b/src/test/ui/macros/macro-shadowing.stderr @@ -13,7 +13,7 @@ error[E0659]: `foo` is ambiguous --> $DIR/macro-shadowing.rs:27:1 | LL | foo!(); //~ ERROR `foo` is ambiguous - | ^^^ + | ^^^ ambiguous name | note: `foo` could refer to the name defined here --> $DIR/macro-shadowing.rs:20:5 diff --git a/src/test/ui/macros/restricted-shadowing-legacy.stderr b/src/test/ui/macros/restricted-shadowing-legacy.stderr index c1a01956998b4..9e0d40c44b683 100644 --- a/src/test/ui/macros/restricted-shadowing-legacy.stderr +++ b/src/test/ui/macros/restricted-shadowing-legacy.stderr @@ -2,7 +2,7 @@ error[E0659]: `m` is ambiguous --> $DIR/restricted-shadowing-legacy.rs:101:13 | LL | m!(); //~ ERROR `m` is ambiguous - | ^ + | ^ ambiguous name | note: `m` could refer to the name defined here --> $DIR/restricted-shadowing-legacy.rs:88:9 @@ -26,7 +26,7 @@ error[E0659]: `m` is ambiguous --> $DIR/restricted-shadowing-legacy.rs:139:42 | LL | macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous - | ^ + | ^ ambiguous name | note: `m` could refer to the name defined here --> $DIR/restricted-shadowing-legacy.rs:88:9 @@ -50,7 +50,7 @@ error[E0659]: `m` is ambiguous --> $DIR/restricted-shadowing-legacy.rs:148:9 | LL | m!(); //~ ERROR `m` is ambiguous - | ^ + | ^ ambiguous name | note: `m` could refer to the name defined here --> $DIR/restricted-shadowing-legacy.rs:88:9 @@ -74,7 +74,7 @@ error[E0659]: `m` is ambiguous --> $DIR/restricted-shadowing-legacy.rs:164:9 | LL | m!(); //~ ERROR `m` is ambiguous - | ^ + | ^ ambiguous name | note: `m` could refer to the name defined here --> $DIR/restricted-shadowing-legacy.rs:88:9 @@ -98,7 +98,7 @@ error[E0659]: `m` is ambiguous --> $DIR/restricted-shadowing-legacy.rs:180:13 | LL | m!(); //~ ERROR `m` is ambiguous - | ^ + | ^ ambiguous name | note: `m` could refer to the name defined here --> $DIR/restricted-shadowing-legacy.rs:88:9 @@ -122,7 +122,7 @@ error[E0659]: `m` is ambiguous --> $DIR/restricted-shadowing-legacy.rs:218:42 | LL | macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous - | ^ + | ^ ambiguous name | note: `m` could refer to the name defined here --> $DIR/restricted-shadowing-legacy.rs:88:9 @@ -146,7 +146,7 @@ error[E0659]: `m` is ambiguous --> $DIR/restricted-shadowing-legacy.rs:232:9 | LL | m!(); //~ ERROR `m` is ambiguous - | ^ + | ^ ambiguous name | note: `m` could refer to the name defined here --> $DIR/restricted-shadowing-legacy.rs:88:9 @@ -170,7 +170,7 @@ error[E0659]: `m` is ambiguous --> $DIR/restricted-shadowing-legacy.rs:262:42 | LL | macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous - | ^ + | ^ ambiguous name | note: `m` could refer to the name defined here --> $DIR/restricted-shadowing-legacy.rs:88:9 diff --git a/src/test/ui/macros/restricted-shadowing-modern.stderr b/src/test/ui/macros/restricted-shadowing-modern.stderr index af4a93a407945..0462438be7807 100644 --- a/src/test/ui/macros/restricted-shadowing-modern.stderr +++ b/src/test/ui/macros/restricted-shadowing-modern.stderr @@ -2,10 +2,7 @@ error[E0659]: `m` is ambiguous --> $DIR/restricted-shadowing-modern.rs:106:17 | LL | m!(); //~ ERROR `m` is ambiguous - | ^ -... -LL | include!(); - | ----------- in this macro invocation + | ^ ambiguous name | note: `m` could refer to the name defined here --> $DIR/restricted-shadowing-modern.rs:91:9 @@ -29,10 +26,7 @@ error[E0659]: `m` is ambiguous --> $DIR/restricted-shadowing-modern.rs:149:33 | LL | macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous - | ^ -... -LL | include!(); - | ----------- in this macro invocation + | ^ ambiguous name | note: `m` could refer to the name defined here --> $DIR/restricted-shadowing-modern.rs:91:9 @@ -56,10 +50,7 @@ error[E0659]: `m` is ambiguous --> $DIR/restricted-shadowing-modern.rs:158:13 | LL | m!(); //~ ERROR `m` is ambiguous - | ^ -... -LL | include!(); - | ----------- in this macro invocation + | ^ ambiguous name | note: `m` could refer to the name defined here --> $DIR/restricted-shadowing-modern.rs:91:9 @@ -83,10 +74,7 @@ error[E0659]: `m` is ambiguous --> $DIR/restricted-shadowing-modern.rs:174:13 | LL | m!(); //~ ERROR `m` is ambiguous - | ^ -... -LL | include!(); - | ----------- in this macro invocation + | ^ ambiguous name | note: `m` could refer to the name defined here --> $DIR/restricted-shadowing-modern.rs:91:9 @@ -110,10 +98,7 @@ error[E0659]: `m` is ambiguous --> $DIR/restricted-shadowing-modern.rs:192:17 | LL | m!(); //~ ERROR `m` is ambiguous - | ^ -... -LL | include!(); - | ----------- in this macro invocation + | ^ ambiguous name | note: `m` could refer to the name defined here --> $DIR/restricted-shadowing-modern.rs:91:9 @@ -137,10 +122,7 @@ error[E0659]: `m` is ambiguous --> $DIR/restricted-shadowing-modern.rs:235:33 | LL | macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous - | ^ -... -LL | include!(); - | ----------- in this macro invocation + | ^ ambiguous name | note: `m` could refer to the name defined here --> $DIR/restricted-shadowing-modern.rs:91:9 diff --git a/src/test/ui/out-of-order-shadowing.stderr b/src/test/ui/out-of-order-shadowing.stderr index 424c194d8fce0..d96a802cb3f8f 100644 --- a/src/test/ui/out-of-order-shadowing.stderr +++ b/src/test/ui/out-of-order-shadowing.stderr @@ -2,7 +2,7 @@ error[E0659]: `bar` is ambiguous --> $DIR/out-of-order-shadowing.rs:15:1 | LL | bar!(); //~ ERROR `bar` is ambiguous - | ^^^ + | ^^^ ambiguous name | note: `bar` could refer to the name defined here --> $DIR/out-of-order-shadowing.rs:14:1