Don't give misleading errors for f::A
, where f is in the value namespace
This commit is contained in:
parent
f4e6ebd11a
commit
002d3a922c
3 changed files with 54 additions and 20 deletions
|
@ -57,6 +57,9 @@ enum ResolutionFailure<'a> {
|
||||||
/// This resolved, but with the wrong namespace.
|
/// This resolved, but with the wrong namespace.
|
||||||
/// `Namespace` is the expected namespace (as opposed to the actual).
|
/// `Namespace` is the expected namespace (as opposed to the actual).
|
||||||
WrongNamespace(Res, Namespace),
|
WrongNamespace(Res, Namespace),
|
||||||
|
/// This has a partial resolution, but is not in the TypeNS and so cannot
|
||||||
|
/// have associated items or fields.
|
||||||
|
CannotHaveAssociatedItems(Res, Namespace),
|
||||||
/// `String` is the base name of the path (not necessarily the whole link)
|
/// `String` is the base name of the path (not necessarily the whole link)
|
||||||
NotInScope(Cow<'a, str>),
|
NotInScope(Cow<'a, str>),
|
||||||
/// this is a primitive type without an impls (no associated methods)
|
/// this is a primitive type without an impls (no associated methods)
|
||||||
|
@ -90,7 +93,8 @@ impl ResolutionFailure<'a> {
|
||||||
| NoPrimitiveImpl(res, _)
|
| NoPrimitiveImpl(res, _)
|
||||||
| NotAnEnum(res)
|
| NotAnEnum(res)
|
||||||
| NotAVariant(res, _)
|
| NotAVariant(res, _)
|
||||||
| WrongNamespace(res, _) => Some(*res),
|
| WrongNamespace(res, _)
|
||||||
|
| CannotHaveAssociatedItems(res, _) => Some(*res),
|
||||||
NotInScope(_) | NoParentItem | Dummy => None,
|
NotInScope(_) | NoParentItem | Dummy => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,21 +364,39 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_, ty_res) = cx
|
let ty_res = cx
|
||||||
.enter_resolver(|resolver| {
|
.enter_resolver(|resolver| {
|
||||||
// only types can have associated items
|
// only types can have associated items
|
||||||
resolver.resolve_str_path_error(DUMMY_SP, &path_root, TypeNS, module_id)
|
resolver.resolve_str_path_error(DUMMY_SP, &path_root, TypeNS, module_id)
|
||||||
})
|
})
|
||||||
.map_err(|_| {
|
.map(|(_, res)| res);
|
||||||
ErrorKind::Resolve(ResolutionFailure::NotInScope(path_root.clone().into()))
|
let ty_res = match ty_res {
|
||||||
})?;
|
Err(()) | Ok(Res::Err) => {
|
||||||
if let Res::Err = ty_res {
|
return if ns == Namespace::ValueNS {
|
||||||
return if ns == Namespace::ValueNS {
|
self.variant_field(path_str, current_item, module_id)
|
||||||
self.variant_field(path_str, current_item, module_id)
|
} else {
|
||||||
} else {
|
// See if it only broke because of the namespace.
|
||||||
Err(ErrorKind::Resolve(ResolutionFailure::NotInScope(path_root.into())))
|
let kind = cx.enter_resolver(|resolver| {
|
||||||
};
|
for &ns in &[MacroNS, ValueNS] {
|
||||||
}
|
match resolver
|
||||||
|
.resolve_str_path_error(DUMMY_SP, &path_root, ns, module_id)
|
||||||
|
{
|
||||||
|
Ok((_, Res::Err)) | Err(()) => {}
|
||||||
|
Ok((_, res)) => {
|
||||||
|
let res = res.map_id(|_| panic!("unexpected node_id"));
|
||||||
|
return ResolutionFailure::CannotHaveAssociatedItems(
|
||||||
|
res, ns,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ResolutionFailure::NotInScope(path_root.into())
|
||||||
|
});
|
||||||
|
Err(ErrorKind::Resolve(kind))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Ok(res) => res,
|
||||||
|
};
|
||||||
let ty_res = ty_res.map_id(|_| panic!("unexpected node_id"));
|
let ty_res = ty_res.map_id(|_| panic!("unexpected node_id"));
|
||||||
let res = match ty_res {
|
let res = match ty_res {
|
||||||
Res::Def(
|
Res::Def(
|
||||||
|
@ -1006,14 +1028,12 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
||||||
Ok(res) => (res, extra_fragment),
|
Ok(res) => (res, extra_fragment),
|
||||||
Err(mut kind) => {
|
Err(mut kind) => {
|
||||||
// `macro_resolve` only looks in the macro namespace. Try to give a better error if possible.
|
// `macro_resolve` only looks in the macro namespace. Try to give a better error if possible.
|
||||||
//if kind.res().is_none() {
|
|
||||||
for &ns in &[TypeNS, ValueNS] {
|
for &ns in &[TypeNS, ValueNS] {
|
||||||
if let Some(res) = check_full_res(self, ns) {
|
if let Some(res) = check_full_res(self, ns) {
|
||||||
kind = ResolutionFailure::WrongNamespace(res, MacroNS);
|
kind = ResolutionFailure::WrongNamespace(res, MacroNS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//}
|
|
||||||
resolution_failure(
|
resolution_failure(
|
||||||
cx,
|
cx,
|
||||||
&item,
|
&item,
|
||||||
|
@ -1456,6 +1476,20 @@ fn resolution_failure(
|
||||||
diag.note(¬e);
|
diag.note(¬e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ResolutionFailure::CannotHaveAssociatedItems(res, _) => {
|
||||||
|
let (item, _) = item(res);
|
||||||
|
diag.note(&format!("this link partially resolves to {}", item));
|
||||||
|
if let Res::Def(kind, def_id) = res {
|
||||||
|
let name = cx.tcx.item_name(def_id);
|
||||||
|
let note = format!(
|
||||||
|
"`{}` is {} {}, not a module or type, and cannot have associated items",
|
||||||
|
name,
|
||||||
|
kind.article(),
|
||||||
|
kind.descr(def_id)
|
||||||
|
);
|
||||||
|
diag.note(¬e);
|
||||||
|
}
|
||||||
|
}
|
||||||
// TODO: is there ever a case where this happens?
|
// TODO: is there ever a case where this happens?
|
||||||
ResolutionFailure::NotAnEnum(res) => {
|
ResolutionFailure::NotAnEnum(res) => {
|
||||||
let (item, comma) = item(res);
|
let (item, comma) = item(res);
|
||||||
|
|
|
@ -7,14 +7,14 @@
|
||||||
// FIXME: this could say which path was the first to not be found (in this case, `path`)
|
// FIXME: this could say which path was the first to not be found (in this case, `path`)
|
||||||
/// [path::to::nonexistent::module]
|
/// [path::to::nonexistent::module]
|
||||||
//~^ ERROR unresolved link
|
//~^ ERROR unresolved link
|
||||||
//~| NOTE no item named `path::to::nonexistent` is in scope
|
//~| NOTE no item named `path::to` is in scope
|
||||||
//~| HELP to escape
|
//~| HELP to escape
|
||||||
|
|
||||||
// TODO: why does this say `f` and not `f::A`??
|
// TODO: why does this say `f` and not `f::A`??
|
||||||
/// [f::A]
|
/// [f::A]
|
||||||
//~^ ERROR unresolved link
|
//~^ ERROR unresolved link
|
||||||
//~| NOTE no item named `f` is in scope
|
//~| NOTE this link partially resolves
|
||||||
//~| HELP to escape
|
//~| NOTE `f` is a function, not a module
|
||||||
|
|
||||||
/// [S::A]
|
/// [S::A]
|
||||||
//~^ ERROR unresolved link
|
//~^ ERROR unresolved link
|
||||||
|
|
|
@ -9,7 +9,7 @@ note: the lint level is defined here
|
||||||
|
|
|
|
||||||
LL | #![deny(broken_intra_doc_links)]
|
LL | #![deny(broken_intra_doc_links)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: no item named `path::to::nonexistent` is in scope
|
= note: no item named `path::to` is in scope
|
||||||
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
|
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
|
||||||
|
|
||||||
error: unresolved link to `f::A`
|
error: unresolved link to `f::A`
|
||||||
|
@ -18,8 +18,8 @@ error: unresolved link to `f::A`
|
||||||
LL | /// [f::A]
|
LL | /// [f::A]
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
|
|
||||||
= note: no item named `f` is in scope
|
= note: this link partially resolves to the function `f`
|
||||||
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
|
= note: `f` is a function, not a module or type, and cannot have associated items
|
||||||
|
|
||||||
error: unresolved link to `S::A`
|
error: unresolved link to `S::A`
|
||||||
--> $DIR/intra-link-errors.rs:19:6
|
--> $DIR/intra-link-errors.rs:19:6
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue