Fix shadowing checking.
This commit is contained in:
parent
6c4b551403
commit
076c5d445b
@ -77,7 +77,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.
|
||||
@ -1077,6 +1077,7 @@ pub struct Resolver<'a> {
|
||||
crate_loader: &'a mut CrateLoader,
|
||||
macro_names: FnvHashSet<Name>,
|
||||
builtin_macros: FnvHashMap<Name, Rc<SyntaxExtension>>,
|
||||
lexical_macro_resolutions: Vec<(Name, LegacyScope<'a>)>,
|
||||
|
||||
// Maps the `Mark` of an expansion to its containing module or block.
|
||||
invocations: FnvHashMap<Mark, &'a InvocationData<'a>>,
|
||||
@ -1267,6 +1268,7 @@ impl<'a> Resolver<'a> {
|
||||
crate_loader: crate_loader,
|
||||
macro_names: FnvHashSet(),
|
||||
builtin_macros: FnvHashMap(),
|
||||
lexical_macro_resolutions: Vec::new(),
|
||||
invocations: invocations,
|
||||
}
|
||||
}
|
||||
@ -3363,9 +3365,13 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
|
||||
fn report_shadowing_errors(&mut self) {
|
||||
for (name, scope) in replace(&mut self.lexical_macro_resolutions, Vec::new()) {
|
||||
self.resolve_macro_name(scope, name);
|
||||
}
|
||||
|
||||
let mut reported_errors = FnvHashSet();
|
||||
for binding in replace(&mut self.disallowed_shadowing, Vec::new()) {
|
||||
if self.resolve_macro_name(binding.parent, binding.name, false).is_some() &&
|
||||
if self.resolve_macro_name(binding.parent, binding.name).is_some() &&
|
||||
reported_errors.insert((binding.name, binding.span)) {
|
||||
let msg = format!("`{}` is already in scope", binding.name);
|
||||
self.session.struct_span_err(binding.span, &msg)
|
||||
|
@ -174,7 +174,7 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||
if let LegacyScope::Expansion(parent) = invocation.legacy_scope.get() {
|
||||
invocation.legacy_scope.set(LegacyScope::simplify_expansion(parent));
|
||||
}
|
||||
self.resolve_macro_name(invocation.legacy_scope.get(), name, true).ok_or_else(|| {
|
||||
self.resolve_macro_name(invocation.legacy_scope.get(), name).ok_or_else(|| {
|
||||
if force {
|
||||
let msg = format!("macro undefined: '{}!'", name);
|
||||
let mut err = self.session.struct_span_err(path.span, &msg);
|
||||
@ -189,17 +189,18 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Resolver<'a> {
|
||||
pub fn resolve_macro_name(&mut self,
|
||||
mut scope: LegacyScope<'a>,
|
||||
name: ast::Name,
|
||||
record_used: bool)
|
||||
pub fn resolve_macro_name(&mut self, mut scope: LegacyScope<'a>, name: ast::Name)
|
||||
-> Option<Rc<SyntaxExtension>> {
|
||||
let mut possible_time_travel = None;
|
||||
let mut relative_depth: u32 = 0;
|
||||
loop {
|
||||
scope = match scope {
|
||||
LegacyScope::Empty => break,
|
||||
LegacyScope::Expansion(invocation) => {
|
||||
if let LegacyScope::Empty = invocation.expansion.get() {
|
||||
if possible_time_travel.is_none() {
|
||||
possible_time_travel = Some(scope);
|
||||
}
|
||||
invocation.legacy_scope.get()
|
||||
} else {
|
||||
relative_depth += 1;
|
||||
@ -212,7 +213,10 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
LegacyScope::Binding(binding) => {
|
||||
if binding.name == name {
|
||||
if record_used && relative_depth > 0 {
|
||||
if let Some(scope) = possible_time_travel {
|
||||
// Check for disallowed shadowing later
|
||||
self.lexical_macro_resolutions.push((name, scope));
|
||||
} else if relative_depth > 0 {
|
||||
self.disallowed_shadowing.push(binding);
|
||||
}
|
||||
return Some(binding.ext.clone());
|
||||
@ -222,6 +226,9 @@ impl<'a> Resolver<'a> {
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(scope) = possible_time_travel {
|
||||
self.lexical_macro_resolutions.push((name, scope));
|
||||
}
|
||||
self.builtin_macros.get(&name).cloned()
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user