Weave the span of an import through the resolve code

This commit is contained in:
Oliver Schneider 2017-05-12 11:21:11 +02:00
parent 644ce5e535
commit a54bbf2cb3
4 changed files with 101 additions and 64 deletions

View File

@ -608,7 +608,8 @@ impl<'a> Resolver<'a> {
} else { } else {
for (name, span) in legacy_imports.imports { for (name, span) in legacy_imports.imports {
let ident = Ident::with_empty_ctxt(name); let ident = Ident::with_empty_ctxt(name);
let result = self.resolve_ident_in_module(module, ident, MacroNS, false, None); let result = self.resolve_ident_in_module(module, ident, MacroNS,
false, false, span);
if let Ok(binding) = result { if let Ok(binding) = result {
let directive = macro_use_directive(span); let directive = macro_use_directive(span);
self.potentially_unused_imports.push(directive); self.potentially_unused_imports.push(directive);
@ -622,7 +623,7 @@ impl<'a> Resolver<'a> {
for (name, span) in legacy_imports.reexports { for (name, span) in legacy_imports.reexports {
self.session.cstore.export_macros(module.def_id().unwrap().krate); self.session.cstore.export_macros(module.def_id().unwrap().krate);
let ident = Ident::with_empty_ctxt(name); let ident = Ident::with_empty_ctxt(name);
let result = self.resolve_ident_in_module(module, ident, MacroNS, false, None); let result = self.resolve_ident_in_module(module, ident, MacroNS, false, false, span);
if let Ok(binding) = result { if let Ok(binding) = result {
self.macro_exports.push(Export { name: name, def: binding.def(), span: span }); self.macro_exports.push(Export { name: name, def: binding.def(), span: span });
} else { } else {

View File

@ -613,7 +613,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type); self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type);
} else if let TyKind::ImplicitSelf = ty.node { } else if let TyKind::ImplicitSelf = ty.node {
let self_ty = keywords::SelfType.ident(); let self_ty = keywords::SelfType.ident();
let def = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.span)) let def = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, true, ty.span)
.map_or(Def::Err, |d| d.def()); .map_or(Def::Err, |d| d.def());
self.record_def(ty.id, PathResolution::new(def)); self.record_def(ty.id, PathResolution::new(def));
} else if let TyKind::Array(ref element, ref length) = ty.node { } else if let TyKind::Array(ref element, ref length) = ty.node {
@ -1267,11 +1267,11 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
let namespace = if is_value { ValueNS } else { TypeNS }; let namespace = if is_value { ValueNS } else { TypeNS };
let hir::Path { ref segments, span, ref mut def } = *path; let hir::Path { ref segments, span, ref mut def } = *path;
let path: Vec<_> = segments.iter().map(|seg| Ident::with_empty_ctxt(seg.name)).collect(); let path: Vec<_> = segments.iter().map(|seg| Ident::with_empty_ctxt(seg.name)).collect();
match self.resolve_path(&path, Some(namespace), Some(span)) { match self.resolve_path(&path, Some(namespace), true, span) {
PathResult::Module(module) => *def = module.def().unwrap(), PathResult::Module(module) => *def = module.def().unwrap(),
PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 =>
*def = path_res.base_def(), *def = path_res.base_def(),
PathResult::NonModule(..) => match self.resolve_path(&path, None, Some(span)) { PathResult::NonModule(..) => match self.resolve_path(&path, None, true, span) {
PathResult::Failed(msg, _) => { PathResult::Failed(msg, _) => {
resolve_error(self, span, ResolutionError::FailedToResolve(&msg)); resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
} }
@ -1502,7 +1502,8 @@ impl<'a> Resolver<'a> {
fn resolve_ident_in_lexical_scope(&mut self, fn resolve_ident_in_lexical_scope(&mut self,
mut ident: Ident, mut ident: Ident,
ns: Namespace, ns: Namespace,
record_used: Option<Span>) record_used: bool,
path_span: Span)
-> Option<LexicalScopeBinding<'a>> { -> Option<LexicalScopeBinding<'a>> {
if ns == TypeNS { if ns == TypeNS {
ident = ident.unhygienize(); ident = ident.unhygienize();
@ -1513,12 +1514,13 @@ impl<'a> Resolver<'a> {
if let Some(def) = self.ribs[ns][i].bindings.get(&ident).cloned() { if let Some(def) = self.ribs[ns][i].bindings.get(&ident).cloned() {
// The ident resolves to a type parameter or local variable. // The ident resolves to a type parameter or local variable.
return Some(LexicalScopeBinding::Def( return Some(LexicalScopeBinding::Def(
self.adjust_local_def(ns, i, def, record_used) self.adjust_local_def(ns, i, def, record_used, path_span)
)); ));
} }
if let ModuleRibKind(module) = self.ribs[ns][i].kind { if let ModuleRibKind(module) = self.ribs[ns][i].kind {
let item = self.resolve_ident_in_module(module, ident, ns, false, record_used); let item = self.resolve_ident_in_module(module, ident, ns, false,
record_used, path_span);
if let Ok(binding) = item { if let Ok(binding) = item {
// The ident resolves to an item. // The ident resolves to an item.
return Some(LexicalScopeBinding::Item(binding)); return Some(LexicalScopeBinding::Item(binding));
@ -1527,7 +1529,8 @@ impl<'a> Resolver<'a> {
if let ModuleKind::Block(..) = module.kind { // We can see through blocks if let ModuleKind::Block(..) = module.kind { // We can see through blocks
} else if !module.no_implicit_prelude { } else if !module.no_implicit_prelude {
return self.prelude.and_then(|prelude| { return self.prelude.and_then(|prelude| {
self.resolve_ident_in_module(prelude, ident, ns, false, None).ok() self.resolve_ident_in_module(prelude, ident, ns, false,
false, path_span).ok()
}).map(LexicalScopeBinding::Item) }).map(LexicalScopeBinding::Item)
} else { } else {
return None; return None;
@ -2147,7 +2150,8 @@ impl<'a> Resolver<'a> {
PatKind::Ident(bmode, ref ident, ref opt_pat) => { PatKind::Ident(bmode, ref ident, ref opt_pat) => {
// First try to resolve the identifier as some existing // First try to resolve the identifier as some existing
// entity, then fall back to a fresh binding. // entity, then fall back to a fresh binding.
let binding = self.resolve_ident_in_lexical_scope(ident.node, ValueNS, None) let binding = self.resolve_ident_in_lexical_scope(ident.node, ValueNS,
false, pat.span)
.and_then(LexicalScopeBinding::item); .and_then(LexicalScopeBinding::item);
let resolution = binding.map(NameBinding::def).and_then(|def| { let resolution = binding.map(NameBinding::def).and_then(|def| {
let always_binding = !pat_src.is_refutable() || opt_pat.is_some() || let always_binding = !pat_src.is_refutable() || opt_pat.is_some() ||
@ -2253,7 +2257,7 @@ impl<'a> Resolver<'a> {
(format!(""), format!("the crate root")) (format!(""), format!("the crate root"))
} else { } else {
let mod_path = &path[..path.len() - 1]; let mod_path = &path[..path.len() - 1];
let mod_prefix = match this.resolve_path(mod_path, Some(TypeNS), None) { let mod_prefix = match this.resolve_path(mod_path, Some(TypeNS), false, span) {
PathResult::Module(module) => module.def(), PathResult::Module(module) => module.def(),
_ => None, _ => None,
}.map_or(format!(""), |def| format!("{} ", def.kind_name())); }.map_or(format!(""), |def| format!("{} ", def.kind_name()));
@ -2303,9 +2307,9 @@ impl<'a> Resolver<'a> {
} }
} }
} }
if path.len() == 1 && this.self_type_is_available() { if path.len() == 1 && this.self_type_is_available(span) {
if let Some(candidate) = this.lookup_assoc_candidate(name, ns, is_expected) { if let Some(candidate) = this.lookup_assoc_candidate(name, ns, is_expected) {
let self_is_available = this.self_value_is_available(path[0].ctxt); let self_is_available = this.self_value_is_available(path[0].ctxt, span);
match candidate { match candidate {
AssocSuggestion::Field => { AssocSuggestion::Field => {
err.span_label(span, format!("did you mean `self.{}`?", path_str)); err.span_label(span, format!("did you mean `self.{}`?", path_str));
@ -2329,7 +2333,7 @@ impl<'a> Resolver<'a> {
let mut levenshtein_worked = false; let mut levenshtein_worked = false;
// Try Levenshtein. // Try Levenshtein.
if let Some(candidate) = this.lookup_typo_candidate(path, ns, is_expected) { if let Some(candidate) = this.lookup_typo_candidate(path, ns, is_expected, span) {
err.span_label(ident_span, format!("did you mean `{}`?", candidate)); err.span_label(ident_span, format!("did you mean `{}`?", candidate));
levenshtein_worked = true; levenshtein_worked = true;
} }
@ -2434,14 +2438,15 @@ impl<'a> Resolver<'a> {
resolution resolution
} }
fn self_type_is_available(&mut self) -> bool { fn self_type_is_available(&mut self, span: Span) -> bool {
let binding = self.resolve_ident_in_lexical_scope(keywords::SelfType.ident(), TypeNS, None); let binding = self.resolve_ident_in_lexical_scope(keywords::SelfType.ident(),
TypeNS, false, span);
if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false } if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false }
} }
fn self_value_is_available(&mut self, ctxt: SyntaxContext) -> bool { fn self_value_is_available(&mut self, ctxt: SyntaxContext, span: Span) -> bool {
let ident = Ident { name: keywords::SelfValue.name(), ctxt: ctxt }; let ident = Ident { name: keywords::SelfValue.name(), ctxt: ctxt };
let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None); let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, false, span);
if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false } if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false }
} }
@ -2505,7 +2510,7 @@ impl<'a> Resolver<'a> {
)); ));
} }
let result = match self.resolve_path(&path, Some(ns), Some(span)) { let result = match self.resolve_path(&path, Some(ns), true, span) {
PathResult::NonModule(path_res) => path_res, PathResult::NonModule(path_res) => path_res,
PathResult::Module(module) if !module.is_normal() => { PathResult::Module(module) if !module.is_normal() => {
PathResolution::new(module.def().unwrap()) PathResolution::new(module.def().unwrap())
@ -2551,7 +2556,7 @@ impl<'a> Resolver<'a> {
if path.len() > 1 && !global_by_default && result.base_def() != Def::Err && if path.len() > 1 && !global_by_default && result.base_def() != Def::Err &&
path[0].name != keywords::CrateRoot.name() && path[0].name != "$crate" { path[0].name != keywords::CrateRoot.name() && path[0].name != "$crate" {
let unqualified_result = { let unqualified_result = {
match self.resolve_path(&[*path.last().unwrap()], Some(ns), None) { match self.resolve_path(&[*path.last().unwrap()], Some(ns), false, span) {
PathResult::NonModule(path_res) => path_res.base_def(), PathResult::NonModule(path_res) => path_res.base_def(),
PathResult::Module(module) => module.def().unwrap(), PathResult::Module(module) => module.def().unwrap(),
_ => return Some(result), _ => return Some(result),
@ -2569,7 +2574,8 @@ impl<'a> Resolver<'a> {
fn resolve_path(&mut self, fn resolve_path(&mut self,
path: &[Ident], path: &[Ident],
opt_ns: Option<Namespace>, // `None` indicates a module path opt_ns: Option<Namespace>, // `None` indicates a module path
record_used: Option<Span>) record_used: bool,
path_span: Span)
-> PathResult<'a> { -> PathResult<'a> {
let mut module = None; let mut module = None;
let mut allow_super = true; let mut allow_super = true;
@ -2603,12 +2609,12 @@ impl<'a> Resolver<'a> {
} }
let binding = if let Some(module) = module { let binding = if let Some(module) = module {
self.resolve_ident_in_module(module, ident, ns, false, record_used) self.resolve_ident_in_module(module, ident, ns, false, record_used, path_span)
} else if opt_ns == Some(MacroNS) { } else if opt_ns == Some(MacroNS) {
self.resolve_lexical_macro_path_segment(ident, ns, record_used) self.resolve_lexical_macro_path_segment(ident, ns, record_used, path_span)
.map(MacroBinding::binding) .map(MacroBinding::binding)
} else { } else {
match self.resolve_ident_in_lexical_scope(ident, ns, record_used) { match self.resolve_ident_in_lexical_scope(ident, ns, record_used, path_span) {
Some(LexicalScopeBinding::Item(binding)) => Ok(binding), Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
Some(LexicalScopeBinding::Def(def)) Some(LexicalScopeBinding::Def(def))
if opt_ns == Some(TypeNS) || opt_ns == Some(ValueNS) => { if opt_ns == Some(TypeNS) || opt_ns == Some(ValueNS) => {
@ -2616,7 +2622,7 @@ impl<'a> Resolver<'a> {
def, path.len() - 1 def, path.len() - 1
)); ));
} }
_ => Err(if record_used.is_some() { Determined } else { Undetermined }), _ => Err(if record_used { Determined } else { Undetermined }),
} }
}; };
@ -2673,12 +2679,13 @@ impl<'a> Resolver<'a> {
ns: Namespace, ns: Namespace,
rib_index: usize, rib_index: usize,
mut def: Def, mut def: Def,
record_used: Option<Span>) -> Def { record_used: bool,
span: Span) -> Def {
let ribs = &self.ribs[ns][rib_index + 1..]; let ribs = &self.ribs[ns][rib_index + 1..];
// An invalid forward use of a type parameter from a previous default. // An invalid forward use of a type parameter from a previous default.
if let ForwardTyParamBanRibKind = self.ribs[ns][rib_index].kind { if let ForwardTyParamBanRibKind = self.ribs[ns][rib_index].kind {
if let Some(span) = record_used { if record_used {
resolve_error(self, span, resolve_error(self, span,
ResolutionError::ForwardDeclaredTyParam); ResolutionError::ForwardDeclaredTyParam);
} }
@ -2688,7 +2695,7 @@ impl<'a> Resolver<'a> {
match def { match def {
Def::Upvar(..) => { Def::Upvar(..) => {
span_bug!(record_used.unwrap_or(DUMMY_SP), "unexpected {:?} in bindings", def) span_bug!(span, "unexpected {:?} in bindings", def)
} }
Def::Local(def_id) => { Def::Local(def_id) => {
for rib in ribs { for rib in ribs {
@ -2714,7 +2721,7 @@ impl<'a> Resolver<'a> {
let depth = vec.len(); let depth = vec.len();
def = Def::Upvar(def_id, depth, function_id); def = Def::Upvar(def_id, depth, function_id);
if let Some(span) = record_used { if record_used {
vec.push(Freevar { vec.push(Freevar {
def: prev_def, def: prev_def,
span: span, span: span,
@ -2726,7 +2733,7 @@ impl<'a> Resolver<'a> {
// This was an attempt to access an upvar inside a // This was an attempt to access an upvar inside a
// named function item. This is not allowed, so we // named function item. This is not allowed, so we
// report an error. // report an error.
if let Some(span) = record_used { if record_used {
resolve_error(self, span, resolve_error(self, span,
ResolutionError::CannotCaptureDynamicEnvironmentInFnItem); ResolutionError::CannotCaptureDynamicEnvironmentInFnItem);
} }
@ -2734,7 +2741,7 @@ impl<'a> Resolver<'a> {
} }
ConstantItemRibKind => { ConstantItemRibKind => {
// Still doesn't deal with upvars // Still doesn't deal with upvars
if let Some(span) = record_used { if record_used {
resolve_error(self, span, resolve_error(self, span,
ResolutionError::AttemptToUseNonConstantValueInConstant); ResolutionError::AttemptToUseNonConstantValueInConstant);
} }
@ -2753,7 +2760,7 @@ impl<'a> Resolver<'a> {
ItemRibKind => { ItemRibKind => {
// This was an attempt to use a type parameter outside // This was an attempt to use a type parameter outside
// its scope. // its scope.
if let Some(span) = record_used { if record_used {
resolve_error(self, span, resolve_error(self, span,
ResolutionError::TypeParametersFromOuterFunction); ResolutionError::TypeParametersFromOuterFunction);
} }
@ -2761,7 +2768,7 @@ impl<'a> Resolver<'a> {
} }
ConstantItemRibKind => { ConstantItemRibKind => {
// see #9186 // see #9186
if let Some(span) = record_used { if record_used {
resolve_error(self, span, resolve_error(self, span,
ResolutionError::OuterTypeParameterContext); ResolutionError::OuterTypeParameterContext);
} }
@ -2857,7 +2864,8 @@ impl<'a> Resolver<'a> {
fn lookup_typo_candidate<FilterFn>(&mut self, fn lookup_typo_candidate<FilterFn>(&mut self,
path: &[Ident], path: &[Ident],
ns: Namespace, ns: Namespace,
filter_fn: FilterFn) filter_fn: FilterFn,
span: Span)
-> Option<Symbol> -> Option<Symbol>
where FilterFn: Fn(Def) -> bool where FilterFn: Fn(Def) -> bool
{ {
@ -2909,7 +2917,8 @@ impl<'a> Resolver<'a> {
} else { } else {
// Search in module. // Search in module.
let mod_path = &path[..path.len() - 1]; let mod_path = &path[..path.len() - 1];
if let PathResult::Module(module) = self.resolve_path(mod_path, Some(TypeNS), None) { if let PathResult::Module(module) = self.resolve_path(mod_path, Some(TypeNS),
false, span) {
add_module_candidates(module, &mut names); add_module_candidates(module, &mut names);
} }
} }
@ -3410,7 +3419,10 @@ impl<'a> Resolver<'a> {
continue continue
} }
let ident = attr.path.segments[0].identifier; let ident = attr.path.segments[0].identifier;
let result = self.resolve_lexical_macro_path_segment(ident, MacroNS, None); let result = self.resolve_lexical_macro_path_segment(ident,
MacroNS,
false,
attr.path.span);
if let Ok(binding) = result { if let Ok(binding) = result {
if let SyntaxExtension::AttrProcMacro(..) = *binding.binding().get_macro(self) { if let SyntaxExtension::AttrProcMacro(..) = *binding.binding().get_macro(self) {
attr::mark_known(attr); attr::mark_known(attr);

View File

@ -379,7 +379,7 @@ impl<'a> Resolver<'a> {
return Err(Determinacy::Determined); return Err(Determinacy::Determined);
} }
let def = match self.resolve_path(&path, Some(MacroNS), None) { let def = match self.resolve_path(&path, Some(MacroNS), false, span) {
PathResult::NonModule(path_res) => match path_res.base_def() { PathResult::NonModule(path_res) => match path_res.base_def() {
Def::Err => Err(Determinacy::Determined), Def::Err => Err(Determinacy::Determined),
def @ _ => Ok(def), def @ _ => Ok(def),
@ -401,7 +401,7 @@ impl<'a> Resolver<'a> {
let result = if let Some(MacroBinding::Legacy(binding)) = legacy_resolution { let result = if let Some(MacroBinding::Legacy(binding)) = legacy_resolution {
Ok(Def::Macro(binding.def_id, MacroKind::Bang)) Ok(Def::Macro(binding.def_id, MacroKind::Bang))
} else { } else {
match self.resolve_lexical_macro_path_segment(path[0], MacroNS, None) { match self.resolve_lexical_macro_path_segment(path[0], MacroNS, false, span) {
Ok(binding) => Ok(binding.binding().def_ignoring_ambiguity()), Ok(binding) => Ok(binding.binding().def_ignoring_ambiguity()),
Err(Determinacy::Undetermined) if !force => return Err(Determinacy::Undetermined), Err(Determinacy::Undetermined) if !force => return Err(Determinacy::Undetermined),
Err(_) => { Err(_) => {
@ -421,18 +421,19 @@ impl<'a> Resolver<'a> {
pub fn resolve_lexical_macro_path_segment(&mut self, pub fn resolve_lexical_macro_path_segment(&mut self,
ident: Ident, ident: Ident,
ns: Namespace, ns: Namespace,
record_used: Option<Span>) record_used: bool,
path_span: Span)
-> Result<MacroBinding<'a>, Determinacy> { -> Result<MacroBinding<'a>, Determinacy> {
let mut module = Some(self.current_module); let mut module = Some(self.current_module);
let mut potential_illegal_shadower = Err(Determinacy::Determined); let mut potential_illegal_shadower = Err(Determinacy::Determined);
let determinacy = let determinacy =
if record_used.is_some() { Determinacy::Determined } else { Determinacy::Undetermined }; if record_used { Determinacy::Determined } else { Determinacy::Undetermined };
loop { loop {
let result = if let Some(module) = module { let result = if let Some(module) = module {
// Since expanded macros may not shadow the lexical scope and // Since expanded macros may not shadow the lexical scope and
// globs may not shadow global macros (both enforced below), // globs may not shadow global macros (both enforced below),
// we resolve with restricted shadowing (indicated by the penultimate argument). // we resolve with restricted shadowing (indicated by the penultimate argument).
self.resolve_ident_in_module(module, ident, ns, true, record_used) self.resolve_ident_in_module(module, ident, ns, true, record_used, path_span)
.map(MacroBinding::Modern) .map(MacroBinding::Modern)
} else { } else {
self.global_macros.get(&ident.name).cloned().ok_or(determinacy) self.global_macros.get(&ident.name).cloned().ok_or(determinacy)
@ -441,15 +442,18 @@ impl<'a> Resolver<'a> {
match result.map(MacroBinding::binding) { match result.map(MacroBinding::binding) {
Ok(binding) => { Ok(binding) => {
let span = match record_used { if !record_used {
Some(span) => span, return result;
None => return result, }
};
if let Ok(MacroBinding::Modern(shadower)) = potential_illegal_shadower { if let Ok(MacroBinding::Modern(shadower)) = potential_illegal_shadower {
if shadower.def() != binding.def() { if shadower.def() != binding.def() {
let name = ident.name; let name = ident.name;
self.ambiguity_errors.push(AmbiguityError { self.ambiguity_errors.push(AmbiguityError {
span: span, name: name, b1: shadower, b2: binding, lexical: true, span: path_span,
name: name,
b1: shadower,
b2: binding,
lexical: true,
legacy: false, legacy: false,
}); });
return potential_illegal_shadower; return potential_illegal_shadower;
@ -543,7 +547,7 @@ impl<'a> Resolver<'a> {
pub fn finalize_current_module_macro_resolutions(&mut self) { pub fn finalize_current_module_macro_resolutions(&mut self) {
let module = self.current_module; let module = self.current_module;
for &(ref path, span) in module.macro_resolutions.borrow().iter() { for &(ref path, span) in module.macro_resolutions.borrow().iter() {
match self.resolve_path(path, Some(MacroNS), Some(span)) { match self.resolve_path(path, Some(MacroNS), true, span) {
PathResult::NonModule(_) => {}, PathResult::NonModule(_) => {},
PathResult::Failed(msg, _) => { PathResult::Failed(msg, _) => {
resolve_error(self, span, ResolutionError::FailedToResolve(&msg)); resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
@ -555,7 +559,7 @@ impl<'a> Resolver<'a> {
for &(mark, ident, span, kind) in module.legacy_macro_resolutions.borrow().iter() { for &(mark, ident, span, kind) in module.legacy_macro_resolutions.borrow().iter() {
let legacy_scope = &self.invocations[&mark].legacy_scope; let legacy_scope = &self.invocations[&mark].legacy_scope;
let legacy_resolution = self.resolve_legacy_scope(legacy_scope, ident.name, true); let legacy_resolution = self.resolve_legacy_scope(legacy_scope, ident.name, true);
let resolution = self.resolve_lexical_macro_path_segment(ident, MacroNS, Some(span)); let resolution = self.resolve_lexical_macro_path_segment(ident, MacroNS, true, span);
match (legacy_resolution, resolution) { match (legacy_resolution, resolution) {
(Some(MacroBinding::Legacy(legacy_binding)), Ok(MacroBinding::Modern(binding))) => { (Some(MacroBinding::Legacy(legacy_binding)), Ok(MacroBinding::Modern(binding))) => {
let msg1 = format!("`{}` could refer to the macro defined here", ident); let msg1 = format!("`{}` could refer to the macro defined here", ident);
@ -579,7 +583,7 @@ impl<'a> Resolver<'a> {
format!("cannot find derive macro `{}` in this scope", ident), format!("cannot find derive macro `{}` in this scope", ident),
}; };
let mut err = self.session.struct_span_err(span, &msg); let mut err = self.session.struct_span_err(span, &msg);
self.suggest_macro_name(&ident.name.as_str(), kind, &mut err); self.suggest_macro_name(&ident.name.as_str(), kind, &mut err, span);
err.emit(); err.emit();
}, },
_ => {}, _ => {},
@ -588,7 +592,7 @@ impl<'a> Resolver<'a> {
} }
fn suggest_macro_name(&mut self, name: &str, kind: MacroKind, fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
err: &mut DiagnosticBuilder<'a>) { err: &mut DiagnosticBuilder<'a>, span: Span) {
// First check if this is a locally-defined bang macro. // First check if this is a locally-defined bang macro.
let suggestion = if let MacroKind::Bang = kind { let suggestion = if let MacroKind::Bang = kind {
find_best_match_for_name(self.macro_names.iter(), name, None) find_best_match_for_name(self.macro_names.iter(), name, None)
@ -619,7 +623,7 @@ impl<'a> Resolver<'a> {
} }
}; };
let ident = Ident::from_str(name); let ident = Ident::from_str(name);
self.lookup_typo_candidate(&vec![ident], MacroNS, is_macro) self.lookup_typo_candidate(&vec![ident], MacroNS, is_macro, span)
}); });
if let Some(suggestion) = suggestion { if let Some(suggestion) = suggestion {

View File

@ -146,7 +146,8 @@ impl<'a> Resolver<'a> {
ident: Ident, ident: Ident,
ns: Namespace, ns: Namespace,
restricted_shadowing: bool, restricted_shadowing: bool,
record_used: Option<Span>) record_used: bool,
path_span: Span)
-> Result<&'a NameBinding<'a>, Determinacy> { -> Result<&'a NameBinding<'a>, Determinacy> {
self.populate_module_if_necessary(module); self.populate_module_if_necessary(module);
@ -154,7 +155,7 @@ impl<'a> Resolver<'a> {
.try_borrow_mut() .try_borrow_mut()
.map_err(|_| Determined)?; // This happens when there is a cycle of imports .map_err(|_| Determined)?; // This happens when there is a cycle of imports
if let Some(span) = record_used { if record_used {
if let Some(binding) = resolution.binding { if let Some(binding) = resolution.binding {
if let Some(shadowed_glob) = resolution.shadows_glob { if let Some(shadowed_glob) = resolution.shadows_glob {
let name = ident.name; let name = ident.name;
@ -164,16 +165,20 @@ impl<'a> Resolver<'a> {
ns != MacroNS && // In MacroNS, `try_define` always forbids this shadowing ns != MacroNS && // In MacroNS, `try_define` always forbids this shadowing
binding.def() != shadowed_glob.def() { binding.def() != shadowed_glob.def() {
self.ambiguity_errors.push(AmbiguityError { self.ambiguity_errors.push(AmbiguityError {
span: span, name: name, lexical: false, b1: binding, b2: shadowed_glob, span: path_span,
name: name,
lexical: false,
b1: binding,
b2: shadowed_glob,
legacy: false, legacy: false,
}); });
} }
} }
if self.record_use(ident, ns, binding, span) { if self.record_use(ident, ns, binding, path_span) {
return Ok(self.dummy_binding); return Ok(self.dummy_binding);
} }
if !self.is_accessible(binding.vis) { if !self.is_accessible(binding.vis) {
self.privacy_errors.push(PrivacyError(span, ident.name, binding)); self.privacy_errors.push(PrivacyError(path_span, ident.name, binding));
} }
} }
@ -205,7 +210,7 @@ impl<'a> Resolver<'a> {
SingleImport { source, .. } => source, SingleImport { source, .. } => source,
_ => unreachable!(), _ => unreachable!(),
}; };
match self.resolve_ident_in_module(module, ident, ns, false, None) { match self.resolve_ident_in_module(module, ident, ns, false, false, path_span) {
Err(Determined) => {} Err(Determined) => {}
_ => return Err(Undetermined), _ => return Err(Undetermined),
} }
@ -230,7 +235,12 @@ impl<'a> Resolver<'a> {
for directive in module.globs.borrow().iter() { for directive in module.globs.borrow().iter() {
if self.is_accessible(directive.vis.get()) { if self.is_accessible(directive.vis.get()) {
if let Some(module) = directive.imported_module.get() { if let Some(module) = directive.imported_module.get() {
let result = self.resolve_ident_in_module(module, ident, ns, false, None); let result = self.resolve_ident_in_module(module,
ident,
ns,
false,
false,
path_span);
if let Err(Undetermined) = result { if let Err(Undetermined) = result {
return Err(Undetermined); return Err(Undetermined);
} }
@ -499,7 +509,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
// For better failure detection, pretend that the import will not define any names // For better failure detection, pretend that the import will not define any names
// while resolving its module path. // while resolving its module path.
directive.vis.set(ty::Visibility::Invisible); directive.vis.set(ty::Visibility::Invisible);
let result = self.resolve_path(&directive.module_path, None, None); let result = self.resolve_path(&directive.module_path, None, false, directive.span);
directive.vis.set(vis); directive.vis.set(vis);
match result { match result {
@ -523,7 +533,12 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
let mut indeterminate = false; let mut indeterminate = false;
self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS { self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
if let Err(Undetermined) = result[ns].get() { if let Err(Undetermined) = result[ns].get() {
result[ns].set(this.resolve_ident_in_module(module, source, ns, false, None)); result[ns].set(this.resolve_ident_in_module(module,
source,
ns,
false,
false,
directive.span));
} else { } else {
return return
}; };
@ -563,14 +578,14 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
self.current_module = directive.parent; self.current_module = directive.parent;
let ImportDirective { ref module_path, span, .. } = *directive; let ImportDirective { ref module_path, span, .. } = *directive;
let module_result = self.resolve_path(&module_path, None, Some(span)); let module_result = self.resolve_path(&module_path, None, true, span);
let module = match module_result { let module = match module_result {
PathResult::Module(module) => module, PathResult::Module(module) => module,
PathResult::Failed(msg, _) => { PathResult::Failed(msg, _) => {
let (mut self_path, mut self_result) = (module_path.clone(), None); let (mut self_path, mut self_result) = (module_path.clone(), None);
if !self_path.is_empty() && !token::Ident(self_path[0]).is_path_segment_keyword() { if !self_path.is_empty() && !token::Ident(self_path[0]).is_path_segment_keyword() {
self_path[0].name = keywords::SelfValue.name(); self_path[0].name = keywords::SelfValue.name();
self_result = Some(self.resolve_path(&self_path, None, None)); self_result = Some(self.resolve_path(&self_path, None, false, span));
} }
return if let Some(PathResult::Module(..)) = self_result { return if let Some(PathResult::Module(..)) = self_result {
Some(format!("Did you mean `{}`?", names_to_string(&self_path))) Some(format!("Did you mean `{}`?", names_to_string(&self_path)))
@ -609,7 +624,12 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
Some(this.dummy_binding); Some(this.dummy_binding);
} }
} }
} else if let Ok(binding) = this.resolve_ident_in_module(module, ident, ns, false, None) { } else if let Ok(binding) = this.resolve_ident_in_module(module,
ident,
ns,
false,
false,
directive.span) {
legacy_self_import = Some(directive); legacy_self_import = Some(directive);
let binding = this.arenas.alloc_name_binding(NameBinding { let binding = this.arenas.alloc_name_binding(NameBinding {
kind: NameBindingKind::Import { kind: NameBindingKind::Import {
@ -630,7 +650,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
} }
let mut all_ns_failed = true; let mut all_ns_failed = true;
self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS { self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
match this.resolve_ident_in_module(module, ident, ns, false, Some(span)) { match this.resolve_ident_in_module(module, ident, ns, false, true, span) {
Ok(_) => all_ns_failed = false, Ok(_) => all_ns_failed = false,
_ => {} _ => {}
} }