Skip to content

Commit

Permalink
Weave the span of an import through the resolve code
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed May 12, 2017
1 parent 644ce5e commit a54bbf2
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 64 deletions.
5 changes: 3 additions & 2 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,8 @@ impl<'a> Resolver<'a> {
} else {
for (name, span) in legacy_imports.imports {
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 {
let directive = macro_use_directive(span);
self.potentially_unused_imports.push(directive);
Expand All @@ -622,7 +623,7 @@ impl<'a> Resolver<'a> {
for (name, span) in legacy_imports.reexports {
self.session.cstore.export_macros(module.def_id().unwrap().krate);
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 {
self.macro_exports.push(Export { name: name, def: binding.def(), span: span });
} else {
Expand Down
80 changes: 46 additions & 34 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type);
} else if let TyKind::ImplicitSelf = ty.node {
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());
self.record_def(ty.id, PathResolution::new(def));
} else if let TyKind::Array(ref element, ref length) = ty.node {
Expand Down Expand Up @@ -1267,11 +1267,11 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
let namespace = if is_value { ValueNS } else { TypeNS };
let hir::Path { ref segments, span, ref mut def } = *path;
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::NonModule(path_res) if path_res.unresolved_segments() == 0 =>
*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, _) => {
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
}
Expand Down Expand Up @@ -1502,7 +1502,8 @@ impl<'a> Resolver<'a> {
fn resolve_ident_in_lexical_scope(&mut self,
mut ident: Ident,
ns: Namespace,
record_used: Option<Span>)
record_used: bool,
path_span: Span)
-> Option<LexicalScopeBinding<'a>> {
if ns == TypeNS {
ident = ident.unhygienize();
Expand All @@ -1513,12 +1514,13 @@ impl<'a> Resolver<'a> {
if let Some(def) = self.ribs[ns][i].bindings.get(&ident).cloned() {
// The ident resolves to a type parameter or local variable.
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 {
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 {
// The ident resolves to an item.
return Some(LexicalScopeBinding::Item(binding));
Expand All @@ -1527,7 +1529,8 @@ impl<'a> Resolver<'a> {
if let ModuleKind::Block(..) = module.kind { // We can see through blocks
} else if !module.no_implicit_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)
} else {
return None;
Expand Down Expand Up @@ -2147,7 +2150,8 @@ impl<'a> Resolver<'a> {
PatKind::Ident(bmode, ref ident, ref opt_pat) => {
// First try to resolve the identifier as some existing
// 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);
let resolution = binding.map(NameBinding::def).and_then(|def| {
let always_binding = !pat_src.is_refutable() || opt_pat.is_some() ||
Expand Down Expand Up @@ -2253,7 +2257,7 @@ impl<'a> Resolver<'a> {
(format!(""), format!("the crate root"))
} else {
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(),
_ => None,
}.map_or(format!(""), |def| format!("{} ", def.kind_name()));
Expand Down Expand Up @@ -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) {
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 {
AssocSuggestion::Field => {
err.span_label(span, format!("did you mean `self.{}`?", path_str));
Expand All @@ -2329,7 +2333,7 @@ impl<'a> Resolver<'a> {
let mut levenshtein_worked = false;

// 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));
levenshtein_worked = true;
}
Expand Down Expand Up @@ -2434,14 +2438,15 @@ impl<'a> Resolver<'a> {
resolution
}

fn self_type_is_available(&mut self) -> bool {
let binding = self.resolve_ident_in_lexical_scope(keywords::SelfType.ident(), TypeNS, None);
fn self_type_is_available(&mut self, span: Span) -> bool {
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 }
}

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 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 }
}

Expand Down Expand Up @@ -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::Module(module) if !module.is_normal() => {
PathResolution::new(module.def().unwrap())
Expand Down Expand Up @@ -2551,7 +2556,7 @@ impl<'a> Resolver<'a> {
if path.len() > 1 && !global_by_default && result.base_def() != Def::Err &&
path[0].name != keywords::CrateRoot.name() && path[0].name != "$crate" {
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::Module(module) => module.def().unwrap(),
_ => return Some(result),
Expand All @@ -2569,7 +2574,8 @@ impl<'a> Resolver<'a> {
fn resolve_path(&mut self,
path: &[Ident],
opt_ns: Option<Namespace>, // `None` indicates a module path
record_used: Option<Span>)
record_used: bool,
path_span: Span)
-> PathResult<'a> {
let mut module = None;
let mut allow_super = true;
Expand Down Expand Up @@ -2603,20 +2609,20 @@ impl<'a> Resolver<'a> {
}

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) {
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)
} 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::Def(def))
if opt_ns == Some(TypeNS) || opt_ns == Some(ValueNS) => {
return PathResult::NonModule(PathResolution::with_unresolved_segments(
def, path.len() - 1
));
}
_ => Err(if record_used.is_some() { Determined } else { Undetermined }),
_ => Err(if record_used { Determined } else { Undetermined }),
}
};

Expand Down Expand Up @@ -2673,12 +2679,13 @@ impl<'a> Resolver<'a> {
ns: Namespace,
rib_index: usize,
mut def: Def,
record_used: Option<Span>) -> Def {
record_used: bool,
span: Span) -> Def {
let ribs = &self.ribs[ns][rib_index + 1..];

// An invalid forward use of a type parameter from a previous default.
if let ForwardTyParamBanRibKind = self.ribs[ns][rib_index].kind {
if let Some(span) = record_used {
if record_used {
resolve_error(self, span,
ResolutionError::ForwardDeclaredTyParam);
}
Expand All @@ -2688,7 +2695,7 @@ impl<'a> Resolver<'a> {

match def {
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) => {
for rib in ribs {
Expand All @@ -2714,7 +2721,7 @@ impl<'a> Resolver<'a> {
let depth = vec.len();
def = Def::Upvar(def_id, depth, function_id);

if let Some(span) = record_used {
if record_used {
vec.push(Freevar {
def: prev_def,
span: span,
Expand All @@ -2726,15 +2733,15 @@ impl<'a> Resolver<'a> {
// This was an attempt to access an upvar inside a
// named function item. This is not allowed, so we
// report an error.
if let Some(span) = record_used {
if record_used {
resolve_error(self, span,
ResolutionError::CannotCaptureDynamicEnvironmentInFnItem);
}
return Def::Err;
}
ConstantItemRibKind => {
// Still doesn't deal with upvars
if let Some(span) = record_used {
if record_used {
resolve_error(self, span,
ResolutionError::AttemptToUseNonConstantValueInConstant);
}
Expand All @@ -2753,15 +2760,15 @@ impl<'a> Resolver<'a> {
ItemRibKind => {
// This was an attempt to use a type parameter outside
// its scope.
if let Some(span) = record_used {
if record_used {
resolve_error(self, span,
ResolutionError::TypeParametersFromOuterFunction);
}
return Def::Err;
}
ConstantItemRibKind => {
// see #9186
if let Some(span) = record_used {
if record_used {
resolve_error(self, span,
ResolutionError::OuterTypeParameterContext);
}
Expand Down Expand Up @@ -2857,7 +2864,8 @@ impl<'a> Resolver<'a> {
fn lookup_typo_candidate<FilterFn>(&mut self,
path: &[Ident],
ns: Namespace,
filter_fn: FilterFn)
filter_fn: FilterFn,
span: Span)
-> Option<Symbol>
where FilterFn: Fn(Def) -> bool
{
Expand Down Expand Up @@ -2909,7 +2917,8 @@ impl<'a> Resolver<'a> {
} else {
// Search in module.
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);
}
}
Expand Down Expand Up @@ -3410,7 +3419,10 @@ impl<'a> Resolver<'a> {
continue
}
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 SyntaxExtension::AttrProcMacro(..) = *binding.binding().get_macro(self) {
attr::mark_known(attr);
Expand Down
Loading

0 comments on commit a54bbf2

Please sign in to comment.