diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index bcb3e57c84428..944a6b5de899d 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -367,6 +367,8 @@ pub(crate) enum HrefError {
Private,
// Not in external cache, href link should be in same page
NotInExternalCache,
+ /// Refers to an unnamable item, such as one defined within a function or const block.
+ UnnamableItem,
}
// Panics if `syms` is empty.
@@ -490,6 +492,20 @@ fn generate_item_def_id_path(
Ok((url_parts, shortty, fqp))
}
+/// Checks if the given defid refers to an item that is unnamable, such as one defined in a const block.
+fn is_unnamable(tcx: TyCtxt<'_>, did: DefId) -> bool {
+ let mut cur_did = did;
+ while let Some(parent) = tcx.opt_parent(cur_did) {
+ match tcx.def_kind(parent) {
+ // items defined in these can be linked to
+ DefKind::Mod | DefKind::Impl { .. } | DefKind::ForeignMod => cur_did = parent,
+ // everything else does not have docs generated for it
+ _ => return true,
+ }
+ }
+ return false;
+}
+
fn to_module_fqp(shortty: ItemType, fqp: &[Symbol]) -> &[Symbol] {
if shortty == ItemType::Module { fqp } else { &fqp[..fqp.len() - 1] }
}
@@ -563,6 +579,9 @@ pub(crate) fn href_with_root_path(
}
_ => original_did,
};
+ if is_unnamable(cx.tcx(), did) {
+ return Err(HrefError::UnnamableItem);
+ }
let cache = cx.cache();
let relative_to = &cx.current;
diff --git a/tests/rustdoc/reexport/auxiliary/wrap-unnamable-type.rs b/tests/rustdoc/reexport/auxiliary/wrap-unnamable-type.rs
new file mode 100644
index 0000000000000..7f8e346c8beac
--- /dev/null
+++ b/tests/rustdoc/reexport/auxiliary/wrap-unnamable-type.rs
@@ -0,0 +1,12 @@
+pub trait Assoc {
+ type Ty;
+}
+
+pub struct Foo(::Ty);
+
+const _X: () = {
+ impl crate::Assoc for Foo {
+ type Ty = Bar;
+ }
+ pub struct Bar;
+};
diff --git a/tests/rustdoc/reexport/wrapped-unnamble-type-143222.rs b/tests/rustdoc/reexport/wrapped-unnamble-type-143222.rs
new file mode 100644
index 0000000000000..9a8893786f5f5
--- /dev/null
+++ b/tests/rustdoc/reexport/wrapped-unnamble-type-143222.rs
@@ -0,0 +1,16 @@
+//@ compile-flags: -Z normalize-docs --document-private-items -Zunstable-options --show-type-layout
+//@ aux-build:wrap-unnamable-type.rs
+//@ build-aux-docs
+
+// regression test for https://github.com/rust-lang/rust/issues/143222
+// makes sure normalizing docs does not cause us to link to unnamable types
+// in cross-crate reexports.
+
+#![crate_name = "foo"]
+
+extern crate wrap_unnamable_type as helper;
+
+//@ has 'foo/struct.Foo.html'
+//@ !hasraw - 'struct.Bar.html'
+#[doc(inline)]
+pub use helper::Foo;