Show the first path segment which failed to resolve.

Before, it would arbitrarily pick the third-to-last if the last three or
more did not resolve.
This commit is contained in:
Joshua Nelson 2020-08-25 18:45:57 -04:00
parent bb9d157604
commit f2826d9e9b
3 changed files with 36 additions and 13 deletions

View file

@ -156,15 +156,35 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
.ok_or(ErrorKind::Resolve(ResolutionFailure::NotInScope(
variant_name.to_string().into(),
)))?;
let (_, ty_res) = cx
let ty_res = cx
.enter_resolver(|resolver| {
resolver.resolve_str_path_error(DUMMY_SP, &path, TypeNS, module_id)
})
.map_err(|_| {
ErrorKind::Resolve(ResolutionFailure::NotInScope(path.to_string().into()))
})?;
.map(|(_, res)| res)
.unwrap_or(Res::Err);
// This code only gets hit if three path segments in a row don't get resolved.
// It's a good time to check if _any_ parent of the path gets resolved.
// If so, report it and say the first which failed; if not, say the first path segment didn't resolve.
if let Res::Err = ty_res {
return Err(ErrorKind::Resolve(ResolutionFailure::NotInScope(path.to_string().into())));
let mut current = path.as_str();
while let Some(parent) = current.rsplitn(2, "::").nth(1) {
current = parent;
if let Some(res) = self.check_full_res(
TypeNS,
&current,
Some(module_id),
current_item,
extra_fragment,
) {
return Err(ErrorKind::Resolve(ResolutionFailure::NoAssocItem(
res,
Symbol::intern(&path),
)));
}
}
return Err(ErrorKind::Resolve(ResolutionFailure::NotInScope(
current.to_string().into(),
)));
}
let ty_res = ty_res.map_id(|_| panic!("unexpected node_id"));
match ty_res {

View file

@ -4,10 +4,9 @@
// FIXME: this should say that it was skipped (maybe an allowed by default lint?)
/// [<invalid syntax>]
// FIXME: this could say which path was the first to not be found (in this case, `path`)
/// [path::to::nonexistent::module]
//~^ ERROR unresolved link
//~| NOTE no item named `path::to` is in scope
//~| NOTE no item named `path` is in scope
//~| HELP to escape
/// [std::io::not::here]
@ -44,7 +43,7 @@
/// [S!]
//~^ ERROR unresolved link
//~| HELP to link to the struct, use its disambiguator
//~| HELP to link to the struct, prefix with the item kind
//~| NOTE this link resolves to the struct `S`
pub fn f() {}
#[derive(Debug)]

View file

@ -9,7 +9,7 @@ note: the lint level is defined here
|
LL | #![deny(broken_intra_doc_links)]
| ^^^^^^^^^^^^^^^^^^^^^^
= note: no item named `path::to` is in scope
= note: no item named `path` is in scope
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
error: unresolved link to `std::io::not::here`
@ -80,15 +80,19 @@ error: unresolved link to `S`
--> $DIR/intra-link-errors.rs:45:6
|
LL | /// [S!]
| ^^ help: to link to the struct, use its disambiguator: `struct@S`
| ^^
|
= note: this link resolves to the struct `S`, which is not in the macro namespace
help: to link to the struct, prefix with the item kind
|
LL | /// [struct@S]
| ^^^^^^^^
error: unresolved link to `T::g`
--> $DIR/intra-link-errors.rs:63:6
|
LL | /// [type@T::g]
| ^^^^^^^^^ help: to link to the associated function, use its disambiguator: `T::g()`
| ^^^^^^^^^ help: to link to the associated function, add parentheses: `T::g()`
|
= note: this link resolves to the associated function `g`, which is not in the type namespace
@ -105,7 +109,7 @@ error: unresolved link to `S::h`
--> $DIR/intra-link-errors.rs:55:6
|
LL | /// [type@S::h]
| ^^^^^^^^^ help: to link to the associated function, use its disambiguator: `S::h()`
| ^^^^^^^^^ help: to link to the associated function, add parentheses: `S::h()`
|
= note: this link resolves to the associated function `h`, which is not in the type namespace
@ -113,7 +117,7 @@ error: unresolved link to `m`
--> $DIR/intra-link-errors.rs:76:6
|
LL | /// [m()]
| ^^^ help: to link to the macro, use its disambiguator: `m!`
| ^^^ help: to link to the macro, add an exclamation mark: `m!`
|
= note: this link resolves to the macro `m`, which is not in the value namespace