Skip to content

Commit fcb2199

Browse files
committed
Report if the thing exists in another namespace
1 parent 4ace4e7 commit fcb2199

File tree

2 files changed

+43
-23
lines changed

2 files changed

+43
-23
lines changed

src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ enum ResolutionFailure<'a> {
8181
}
8282

8383
impl ResolutionFailure<'a> {
84+
// A partial or full resolution
8485
fn res(&self) -> Option<Res> {
8586
use ResolutionFailure::*;
8687
match self {
@@ -93,6 +94,14 @@ impl ResolutionFailure<'a> {
9394
NotInScope(_) | NoParentItem | Dummy => None,
9495
}
9596
}
97+
98+
// This resolved fully (not just partially) but is erroneous for some other reason
99+
fn full_res(&self) -> Option<Res> {
100+
match self {
101+
Self::WrongNamespace(res, _) => Some(*res),
102+
_ => None,
103+
}
104+
}
96105
}
97106

98107
enum AnchorFailure {
@@ -128,6 +137,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
128137
) -> Result<(Res, Option<String>), ErrorKind<'path>> {
129138
let cx = self.cx;
130139

140+
debug!("looking for enum variant {}", path_str);
131141
let mut split = path_str.rsplitn(3, "::");
132142
let variant_field_name = split
133143
.next()
@@ -260,7 +270,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
260270
debug!("{} resolved to {:?} in namespace {:?}", path_str, result, ns);
261271
let result = match result {
262272
Ok((_, Res::Err)) => Err(()),
263-
_ => result.map_err(|_| ()),
273+
x => x,
264274
};
265275

266276
if let Ok((_, res)) = result {
@@ -419,6 +429,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
419429
Ok((ty_res, Some(format!("{}.{}", out, item_name))))
420430
})
421431
} else if ns == Namespace::ValueNS {
432+
debug!("looking for variants or fields named {} for {:?}", item_name, did);
422433
match cx.tcx.type_of(did).kind() {
423434
ty::Adt(def, _) => {
424435
let field = if def.is_enum() {
@@ -838,12 +849,36 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
838849
}
839850
}
840851

852+
// used for reporting better errors
853+
let check_full_res = |this: &mut Self, ns| {
854+
match this.resolve(path_str, ns, &current_item, base_node, &extra_fragment) {
855+
Ok(res) => {
856+
debug!(
857+
"check_full_res: saw res for {} in {:?} ns: {:?}",
858+
path_str, ns, res.0
859+
);
860+
Some(res.0)
861+
}
862+
Err(ErrorKind::Resolve(kind)) => kind.full_res(),
863+
// TODO: add `Res` to AnchorFailure
864+
Err(ErrorKind::AnchorFailure(_)) => None,
865+
}
866+
};
867+
841868
match disambiguator.map(Disambiguator::ns) {
842869
Some(ns @ (ValueNS | TypeNS)) => {
843870
match self.resolve(path_str, ns, &current_item, base_node, &extra_fragment)
844871
{
845872
Ok(res) => res,
846-
Err(ErrorKind::Resolve(kind)) => {
873+
Err(ErrorKind::Resolve(mut kind)) => {
874+
// We only looked in one namespace. Try to give a better error if possible.
875+
// TODO: handle MacroNS too
876+
if kind.full_res().is_none() {
877+
let other_ns = if ns == ValueNS { TypeNS } else { ValueNS };
878+
if let Some(res) = check_full_res(self, other_ns) {
879+
kind = ResolutionFailure::WrongNamespace(res, other_ns);
880+
}
881+
}
847882
resolution_failure(
848883
cx,
849884
&item,
@@ -965,30 +1000,14 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
9651000
Ok(res) => (res, extra_fragment),
9661001
Err(mut kind) => {
9671002
// `macro_resolve` only looks in the macro namespace. Try to give a better error if possible.
1003+
//if kind.res().is_none() {
9681004
for &ns in &[TypeNS, ValueNS] {
969-
match self.resolve(
970-
path_str,
971-
ns,
972-
&current_item,
973-
base_node,
974-
&extra_fragment,
975-
) {
976-
Ok(res) => {
977-
kind = ResolutionFailure::WrongNamespace(res.0, MacroNS)
978-
}
979-
// This will show up in the other namespace, no need to handle it here
980-
Err(ErrorKind::Resolve(
981-
ResolutionFailure::WrongNamespace(..),
982-
)) => {}
983-
Err(ErrorKind::AnchorFailure(_)) => {}
984-
Err(ErrorKind::Resolve(inner_kind)) => {
985-
if let Some(res) = inner_kind.res() {
986-
kind =
987-
ResolutionFailure::WrongNamespace(res, MacroNS);
988-
}
989-
}
1005+
if let Some(res) = check_full_res(self, ns) {
1006+
kind = ResolutionFailure::WrongNamespace(res, MacroNS);
1007+
break;
9901008
}
9911009
}
1010+
//}
9921011
resolution_failure(
9931012
cx,
9941013
&item,

src/test/rustdoc-ui/intra-link-errors.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ impl S {
5454
}
5555

5656
/// [type@T::g]
57+
/// [T::h!]
5758
pub trait T {
5859
fn g() {}
5960
}

0 commit comments

Comments
 (0)