mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-24 07:44:10 +00:00
resolve: Use path segment spans in smart_resolve_path
This commit is contained in:
parent
32575a0487
commit
ffdcf74866
@ -407,7 +407,7 @@ enum PathSource<'a> {
|
||||
// Trait paths in bounds or impls.
|
||||
Trait,
|
||||
// Expression paths `path`, with optional parent context.
|
||||
Expr(Option<&'a ExprKind>),
|
||||
Expr(Option<&'a Expr>),
|
||||
// Paths in path patterns `Path`.
|
||||
Pat,
|
||||
// Paths in struct expressions and patterns `Path { .. }`.
|
||||
@ -464,7 +464,7 @@ impl<'a> PathSource<'a> {
|
||||
ValueNS => "method or associated constant",
|
||||
MacroNS => bug!("associated macro"),
|
||||
},
|
||||
PathSource::Expr(parent) => match parent {
|
||||
PathSource::Expr(parent) => match parent.map(|p| &p.node) {
|
||||
// "function" here means "anything callable" rather than `Def::Fn`,
|
||||
// this is not precise but usually more helpful than just "value".
|
||||
Some(&ExprKind::Call(..)) => "function",
|
||||
@ -2194,7 +2194,8 @@ impl<'a> Resolver<'a> {
|
||||
source: PathSource)
|
||||
-> PathResolution {
|
||||
let segments = &path.segments.iter().map(|seg| seg.identifier).collect::<Vec<_>>();
|
||||
self.smart_resolve_path_fragment(id, qself, segments, path.span, source)
|
||||
let ident_span = path.segments.last().map_or(path.span, |seg| seg.span);
|
||||
self.smart_resolve_path_fragment(id, qself, segments, path.span, ident_span, source)
|
||||
}
|
||||
|
||||
fn smart_resolve_path_fragment(&mut self,
|
||||
@ -2202,6 +2203,7 @@ impl<'a> Resolver<'a> {
|
||||
qself: Option<&QSelf>,
|
||||
path: &[Ident],
|
||||
span: Span,
|
||||
ident_span: Span,
|
||||
source: PathSource)
|
||||
-> PathResolution {
|
||||
let ns = source.namespace();
|
||||
@ -2213,9 +2215,9 @@ impl<'a> Resolver<'a> {
|
||||
let expected = source.descr_expected();
|
||||
let path_str = names_to_string(path);
|
||||
let code = source.error_code(def.is_some());
|
||||
let (base_msg, fallback_label) = if let Some(def) = def {
|
||||
let (base_msg, fallback_label, base_span) = if let Some(def) = def {
|
||||
(format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str),
|
||||
format!("not a {}", expected))
|
||||
format!("not a {}", expected), span)
|
||||
} else {
|
||||
let item_str = path[path.len() - 1];
|
||||
let (mod_prefix, mod_str) = if path.len() == 1 {
|
||||
@ -2231,9 +2233,9 @@ impl<'a> Resolver<'a> {
|
||||
(mod_prefix, format!("`{}`", names_to_string(mod_path)))
|
||||
};
|
||||
(format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str),
|
||||
format!("not found in {}", mod_str))
|
||||
format!("not found in {}", mod_str), ident_span)
|
||||
};
|
||||
let mut err = this.session.struct_span_err_with_code(span, &base_msg, code);
|
||||
let mut err = this.session.struct_span_err_with_code(base_span, &base_msg, code);
|
||||
|
||||
// Emit special messages for unresolved `Self` and `self`.
|
||||
if is_self_type(path, ns) {
|
||||
@ -2291,15 +2293,15 @@ impl<'a> Resolver<'a> {
|
||||
err.span_label(span, &format!("type aliases cannot be used for traits"));
|
||||
return err;
|
||||
}
|
||||
(Def::Mod(..), PathSource::Expr(Some(parent))) => match *parent {
|
||||
(Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node {
|
||||
ExprKind::Field(_, ident) => {
|
||||
err.span_label(span, &format!("did you mean `{}::{}`?",
|
||||
path_str, ident.node));
|
||||
err.span_label(parent.span, &format!("did you mean `{}::{}`?",
|
||||
path_str, ident.node));
|
||||
return err;
|
||||
}
|
||||
ExprKind::MethodCall(ident, ..) => {
|
||||
err.span_label(span, &format!("did you mean `{}::{}(...)`?",
|
||||
path_str, ident.node));
|
||||
err.span_label(parent.span, &format!("did you mean `{}::{}(...)`?",
|
||||
path_str, ident.node));
|
||||
return err;
|
||||
}
|
||||
_ => {}
|
||||
@ -2324,12 +2326,12 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
// Try Levenshtein if nothing else worked.
|
||||
if let Some(candidate) = this.lookup_typo_candidate(path, ns, is_expected) {
|
||||
err.span_label(span, &format!("did you mean `{}`?", candidate));
|
||||
err.span_label(ident_span, &format!("did you mean `{}`?", candidate));
|
||||
return err;
|
||||
}
|
||||
|
||||
// Fallback label.
|
||||
err.span_label(span, &fallback_label);
|
||||
err.span_label(base_span, &fallback_label);
|
||||
err
|
||||
};
|
||||
let report_errors = |this: &mut Self, def: Option<Def>| {
|
||||
@ -2449,7 +2451,7 @@ impl<'a> Resolver<'a> {
|
||||
// Make sure `A::B` in `<T as A>::B::C` is a trait item.
|
||||
let ns = if qself.position + 1 == path.len() { ns } else { TypeNS };
|
||||
let res = self.smart_resolve_path_fragment(id, None, &path[..qself.position + 1],
|
||||
span, PathSource::TraitItem(ns));
|
||||
span, span, PathSource::TraitItem(ns));
|
||||
return Some(PathResolution::with_unresolved_segments(
|
||||
res.base_def(), res.unresolved_segments() + path.len() - qself.position - 1
|
||||
));
|
||||
@ -2807,7 +2809,7 @@ impl<'a> Resolver<'a> {
|
||||
path: &[Ident],
|
||||
ns: Namespace,
|
||||
filter_fn: FilterFn)
|
||||
-> Option<String>
|
||||
-> Option<Symbol>
|
||||
where FilterFn: Fn(Def) -> bool
|
||||
{
|
||||
let add_module_candidates = |module: Module, names: &mut Vec<Name>| {
|
||||
@ -2821,7 +2823,7 @@ impl<'a> Resolver<'a> {
|
||||
};
|
||||
|
||||
let mut names = Vec::new();
|
||||
let prefix_str = if path.len() == 1 {
|
||||
if path.len() == 1 {
|
||||
// Search in lexical scope.
|
||||
// Walk backwards up the ribs in scope and collect candidates.
|
||||
for rib in self.ribs[ns].iter().rev() {
|
||||
@ -2855,21 +2857,19 @@ impl<'a> Resolver<'a> {
|
||||
names.push(*name);
|
||||
}
|
||||
}
|
||||
String::new()
|
||||
} else {
|
||||
// Search in module.
|
||||
let mod_path = &path[..path.len() - 1];
|
||||
if let PathResult::Module(module) = self.resolve_path(mod_path, Some(TypeNS), None) {
|
||||
add_module_candidates(module, &mut names);
|
||||
}
|
||||
names_to_string(mod_path) + "::"
|
||||
};
|
||||
}
|
||||
|
||||
let name = path[path.len() - 1].name;
|
||||
// Make sure error reporting is deterministic.
|
||||
names.sort_by_key(|name| name.as_str());
|
||||
match find_best_match_for_name(names.iter(), &name.as_str(), None) {
|
||||
Some(found) if found != name => Some(format!("{}{}", prefix_str, found)),
|
||||
Some(found) if found != name => Some(found),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -2892,7 +2892,7 @@ impl<'a> Resolver<'a> {
|
||||
self.with_resolved_label(label, id, |this| this.visit_block(block));
|
||||
}
|
||||
|
||||
fn resolve_expr(&mut self, expr: &Expr, parent: Option<&ExprKind>) {
|
||||
fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) {
|
||||
// First, record candidate traits for this expression if it could
|
||||
// result in the invocation of a method call.
|
||||
|
||||
@ -2973,11 +2973,11 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
// Equivalent to `visit::walk_expr` + passing some context to children.
|
||||
ExprKind::Field(ref subexpression, _) => {
|
||||
self.resolve_expr(subexpression, Some(&expr.node));
|
||||
self.resolve_expr(subexpression, Some(expr));
|
||||
}
|
||||
ExprKind::MethodCall(_, ref types, ref arguments) => {
|
||||
let mut arguments = arguments.iter();
|
||||
self.resolve_expr(arguments.next().unwrap(), Some(&expr.node));
|
||||
self.resolve_expr(arguments.next().unwrap(), Some(expr));
|
||||
for argument in arguments {
|
||||
self.resolve_expr(argument, None);
|
||||
}
|
||||
@ -2993,7 +2993,7 @@ impl<'a> Resolver<'a> {
|
||||
});
|
||||
}
|
||||
ExprKind::Call(ref callee, ref arguments) => {
|
||||
self.resolve_expr(callee, Some(&expr.node));
|
||||
self.resolve_expr(callee, Some(expr));
|
||||
for argument in arguments {
|
||||
self.resolve_expr(argument, None);
|
||||
}
|
||||
|
@ -502,7 +502,6 @@ impl<'a> Resolver<'a> {
|
||||
};
|
||||
let ident = Ident::from_str(name);
|
||||
self.lookup_typo_candidate(&vec![ident], MacroNS, is_macro)
|
||||
.as_ref().map(|s| Symbol::intern(s))
|
||||
});
|
||||
|
||||
if let Some(suggestion) = suggestion {
|
||||
|
@ -1,26 +1,26 @@
|
||||
error[E0425]: cannot find value `A` in module `namespaced_enums`
|
||||
--> $DIR/enums-are-namespaced-xc.rs:15:13
|
||||
--> $DIR/enums-are-namespaced-xc.rs:15:31
|
||||
|
|
||||
15 | let _ = namespaced_enums::A;
|
||||
| ^^^^^^^^^^^^^^^^^^^ not found in `namespaced_enums`
|
||||
| ^ not found in `namespaced_enums`
|
||||
|
|
||||
= help: possible candidate is found in another module, you can import it into scope:
|
||||
`use namespaced_enums::Foo::A;`
|
||||
|
||||
error[E0425]: cannot find function `B` in module `namespaced_enums`
|
||||
--> $DIR/enums-are-namespaced-xc.rs:18:13
|
||||
--> $DIR/enums-are-namespaced-xc.rs:18:31
|
||||
|
|
||||
18 | let _ = namespaced_enums::B(10);
|
||||
| ^^^^^^^^^^^^^^^^^^^ not found in `namespaced_enums`
|
||||
| ^ not found in `namespaced_enums`
|
||||
|
|
||||
= help: possible candidate is found in another module, you can import it into scope:
|
||||
`use namespaced_enums::Foo::B;`
|
||||
|
||||
error[E0422]: cannot find struct, variant or union type `C` in module `namespaced_enums`
|
||||
--> $DIR/enums-are-namespaced-xc.rs:21:13
|
||||
--> $DIR/enums-are-namespaced-xc.rs:21:31
|
||||
|
|
||||
21 | let _ = namespaced_enums::C { a: 10 };
|
||||
| ^^^^^^^^^^^^^^^^^^^ not found in `namespaced_enums`
|
||||
| ^ not found in `namespaced_enums`
|
||||
|
|
||||
= help: possible candidate is found in another module, you can import it into scope:
|
||||
`use namespaced_enums::Foo::C;`
|
||||
|
@ -14,7 +14,7 @@ error[E0412]: cannot find type `Opiton` in this scope
|
||||
--> $DIR/levenshtein.rs:20:10
|
||||
|
|
||||
20 | type B = Opiton<u8>; // Misspelled type name from the prelude.
|
||||
| ^^^^^^^^^^ did you mean `Option`?
|
||||
| ^^^^^^ did you mean `Option`?
|
||||
|
||||
error[E0412]: cannot find type `Baz` in this scope
|
||||
--> $DIR/levenshtein.rs:23:14
|
||||
@ -35,16 +35,16 @@ error[E0425]: cannot find function `foobar` in this scope
|
||||
| ^^^^^^ did you mean `foo_bar`?
|
||||
|
||||
error[E0412]: cannot find type `first` in module `m`
|
||||
--> $DIR/levenshtein.rs:32:12
|
||||
--> $DIR/levenshtein.rs:32:15
|
||||
|
|
||||
32 | let b: m::first = m::second; // Misspelled item in module.
|
||||
| ^^^^^^^^ did you mean `m::First`?
|
||||
| ^^^^^ did you mean `First`?
|
||||
|
||||
error[E0425]: cannot find value `second` in module `m`
|
||||
--> $DIR/levenshtein.rs:32:23
|
||||
--> $DIR/levenshtein.rs:32:26
|
||||
|
|
||||
32 | let b: m::first = m::second; // Misspelled item in module.
|
||||
| ^^^^^^^^^ did you mean `m::Second`?
|
||||
| ^^^^^^ did you mean `Second`?
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
@ -2,55 +2,73 @@ error[E0423]: expected value, found module `a`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:27:5
|
||||
|
|
||||
27 | a.I
|
||||
| ^ did you mean `a::I`?
|
||||
| ^--
|
||||
| |
|
||||
| did you mean `a::I`?
|
||||
|
||||
error[E0423]: expected value, found module `a`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:33:5
|
||||
|
|
||||
33 | a.g()
|
||||
| ^ did you mean `a::g(...)`?
|
||||
| ^----
|
||||
| |
|
||||
| did you mean `a::g(...)`?
|
||||
|
||||
error[E0423]: expected value, found module `a`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:39:5
|
||||
|
|
||||
39 | a.b.J
|
||||
| ^ did you mean `a::b`?
|
||||
| ^--
|
||||
| |
|
||||
| did you mean `a::b`?
|
||||
|
||||
error[E0423]: expected value, found module `a::b`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:45:5
|
||||
|
|
||||
45 | a::b.J
|
||||
| ^^^^ did you mean `a::b::J`?
|
||||
| ^^^^--
|
||||
| |
|
||||
| did you mean `a::b::J`?
|
||||
|
||||
error[E0423]: expected value, found module `a`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:51:5
|
||||
|
|
||||
51 | a.b.f();
|
||||
| ^ did you mean `a::b`?
|
||||
| ^--
|
||||
| |
|
||||
| did you mean `a::b`?
|
||||
|
||||
error[E0423]: expected value, found module `a::b`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:55:12
|
||||
|
|
||||
55 | v.push(a::b);
|
||||
| ^^^^ did you mean `a::I`?
|
||||
| ^^^-
|
||||
| |
|
||||
| did you mean `I`?
|
||||
|
||||
error[E0423]: expected value, found module `a::b`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:61:5
|
||||
|
|
||||
61 | a::b.f()
|
||||
| ^^^^ did you mean `a::b::f(...)`?
|
||||
| ^^^^----
|
||||
| |
|
||||
| did you mean `a::b::f(...)`?
|
||||
|
||||
error[E0423]: expected value, found module `a::b`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:67:5
|
||||
|
|
||||
67 | a::b
|
||||
| ^^^^ did you mean `a::I`?
|
||||
| ^^^-
|
||||
| |
|
||||
| did you mean `I`?
|
||||
|
||||
error[E0423]: expected function, found module `a::b`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:73:5
|
||||
|
|
||||
73 | a::b()
|
||||
| ^^^^ did you mean `a::I`?
|
||||
| ^^^-
|
||||
| |
|
||||
| did you mean `I`?
|
||||
|
||||
error: main function not found
|
||||
|
||||
|
@ -2,7 +2,7 @@ error[E0405]: cannot find trait `Nonexist` in this scope
|
||||
--> $DIR/unboxed-closure-sugar-nonexistent-trait.rs:11:8
|
||||
|
|
||||
11 | fn f<F:Nonexist(isize) -> isize>(x: F) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
|
||||
| ^^^^^^^^ not found in this scope
|
||||
|
||||
error[E0404]: expected trait, found type alias `Typedef`
|
||||
--> $DIR/unboxed-closure-sugar-nonexistent-trait.rs:17:8
|
||||
|
Loading…
Reference in New Issue
Block a user