Check for shadowing errors after all invocations have been expanded.
This commit is contained in:
parent
53fd3b0acc
commit
6808b0a2b7
@ -78,7 +78,7 @@ use std::mem::replace;
|
||||
use std::rc::Rc;
|
||||
|
||||
use resolve_imports::{ImportDirective, NameResolution};
|
||||
use macros::{InvocationData, LegacyBinding};
|
||||
use macros::{InvocationData, LegacyBinding, LegacyScope};
|
||||
|
||||
// NB: This module needs to be declared first so diagnostics are
|
||||
// registered before they are used.
|
||||
@ -1073,7 +1073,7 @@ pub struct Resolver<'a> {
|
||||
|
||||
privacy_errors: Vec<PrivacyError<'a>>,
|
||||
ambiguity_errors: Vec<AmbiguityError<'a>>,
|
||||
macro_shadowing_errors: FnvHashSet<Span>,
|
||||
disallowed_shadowing: Vec<(Name, Span, LegacyScope<'a>)>,
|
||||
|
||||
arenas: &'a ResolverArenas<'a>,
|
||||
dummy_binding: &'a NameBinding<'a>,
|
||||
@ -1260,7 +1260,7 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
privacy_errors: Vec::new(),
|
||||
ambiguity_errors: Vec::new(),
|
||||
macro_shadowing_errors: FnvHashSet(),
|
||||
disallowed_shadowing: Vec::new(),
|
||||
|
||||
arenas: arenas,
|
||||
dummy_binding: arenas.alloc_name_binding(NameBinding {
|
||||
@ -3353,7 +3353,8 @@ impl<'a> Resolver<'a> {
|
||||
vis.is_accessible_from(module.normal_ancestor_id.unwrap(), self)
|
||||
}
|
||||
|
||||
fn report_errors(&self) {
|
||||
fn report_errors(&mut self) {
|
||||
self.report_shadowing_errors();
|
||||
let mut reported_spans = FnvHashSet();
|
||||
|
||||
for &AmbiguityError { span, name, b1, b2 } in &self.ambiguity_errors {
|
||||
@ -3381,6 +3382,20 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn report_shadowing_errors(&mut self) {
|
||||
let mut reported_errors = FnvHashSet();
|
||||
for (name, span, scope) in replace(&mut self.disallowed_shadowing, Vec::new()) {
|
||||
if self.resolve_macro_name(scope, name, false).is_some() &&
|
||||
reported_errors.insert((name, span)) {
|
||||
let msg = format!("`{}` is already in scope", name);
|
||||
self.session.struct_span_err(span, &msg)
|
||||
.note("macro-expanded `macro_rules!`s and `#[macro_use]`s \
|
||||
may not shadow existing macros (see RFC 1560)")
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn report_conflict(&self,
|
||||
parent: Module,
|
||||
name: Name,
|
||||
|
@ -207,20 +207,14 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Resolver<'a> {
|
||||
fn resolve_macro_name(&mut self,
|
||||
mut scope: LegacyScope<'a>,
|
||||
name: ast::Name,
|
||||
record_used: bool)
|
||||
-> Option<Rc<SyntaxExtension>> {
|
||||
pub fn resolve_macro_name(&mut self,
|
||||
mut scope: LegacyScope<'a>,
|
||||
name: ast::Name,
|
||||
record_used: bool)
|
||||
-> Option<Rc<SyntaxExtension>> {
|
||||
let check_shadowing = |this: &mut Self, relative_depth, scope, span| {
|
||||
if record_used && relative_depth > 0 &&
|
||||
this.resolve_macro_name(scope, name, false).is_some() &&
|
||||
this.macro_shadowing_errors.insert(span) {
|
||||
let msg = format!("`{}` is already in scope", name);
|
||||
this.session.struct_span_err(span, &msg)
|
||||
.note("macro-expanded `macro_rules!`s and `#[macro_use]`s \
|
||||
may not shadow existing macros (see RFC 1560)")
|
||||
.emit();
|
||||
if record_used && relative_depth > 0 {
|
||||
this.disallowed_shadowing.push((name, span, scope));
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user