Skip to content

Commit 19d1002

Browse files
committed
Fix failures to resolve primitives
Previously, when looking for the associated items for primitives, rustdoc would look for primitives in the current namespace. But all primitives are in the type namespace. To fix this, rustdoc now always looks for primitives in the namespace when considering them as a stepping stone to the associated item. However, fixing that bug caused several duplicate errors because rustdoc now reports the same error in each namespace. To avoid this, rustdoc now ignores all duplicate errors when issuing them.
1 parent e2d69f2 commit 19d1002

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
331331
ErrorKind::Resolve(ResolutionFailure::NotInScope(item_name.to_string().into()))
332332
})?;
333333

334-
if let Some((path, prim)) = is_primitive(&path_root, ns) {
334+
if let Some((path, prim)) = is_primitive(&path_root, TypeNS) {
335335
let impls = primitive_impl(cx, &path).ok_or_else(|| {
336336
ErrorKind::Resolve(ResolutionFailure::NoPrimitiveImpl(prim, path_root.into()))
337337
})?;
@@ -355,6 +355,12 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
355355
return Ok(link);
356356
}
357357
}
358+
debug!(
359+
"returning primitive error for {}::{} in {} namespace",
360+
path,
361+
item_name,
362+
ns.descr()
363+
);
358364
return Err(ErrorKind::Resolve(ResolutionFailure::NoPrimitiveAssocItem {
359365
res: prim,
360366
prim_name: path,
@@ -1404,7 +1410,6 @@ fn resolution_failure(
14041410
&link_range,
14051411
|diag, sp| {
14061412
let in_scope = kinds.iter().any(|kind| kind.res().is_some());
1407-
let mut reported_not_in_scope = false;
14081413
let item = |res: Res| {
14091414
format!("the {} `{}`", res.descr(), cx.tcx.item_name(res.def_id()).to_string())
14101415
};
@@ -1419,14 +1424,19 @@ fn resolution_failure(
14191424
);
14201425
diag.note(&note);
14211426
};
1427+
// ignore duplicates
1428+
let mut variants_seen = SmallVec::<[_; 3]>::new();
14221429
for failure in kinds {
1430+
let variant = std::mem::discriminant(&failure);
1431+
if variants_seen.contains(&variant) {
1432+
continue;
1433+
}
1434+
variants_seen.push(variant);
14231435
match failure {
1424-
// already handled above
14251436
ResolutionFailure::NotInScope(base) => {
1426-
if in_scope || reported_not_in_scope {
1437+
if in_scope {
14271438
continue;
14281439
}
1429-
reported_not_in_scope = true;
14301440
diag.note(&format!("no item named `{}` is in scope", base));
14311441
diag.help(r#"to escape `[` and `]` characters, add '\' before them like `\[` or `\]`"#);
14321442
}

0 commit comments

Comments
 (0)