about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2021-05-03 00:32:43 +0200
committerGitHub <noreply@github.com>2021-05-03 00:32:43 +0200
commit37ce3321ebcc901d15583b5b0266d945130e123b (patch)
tree22d4ee52b39d4f4bd846e9c056acc26ae5e8728a
parent0133af504b804ecaa6223bc38730020848db5982 (diff)
parent40ffa942444b84336b0d03f3004d7eb9ca36f8ad (diff)
downloadrust-37ce3321ebcc901d15583b5b0266d945130e123b.tar.gz
rust-37ce3321ebcc901d15583b5b0266d945130e123b.zip
Rollup merge of #84811 - scottmcm:rustdoc-trait-alias-fix, r=jyn514
RustDoc: Fix bounds linking trait.Foo instead of traitalias.Foo

Fixes #84782

The code was assuming `Trait` when adding bounds to the cache, so add a check on the DefId to see what its kind really is.

r? `@jyn514`

Before:
![image](https://user-images.githubusercontent.com/18526288/116775611-6a751e80-aa53-11eb-84d0-ed6b7782be3c.png)

After:
![image](https://user-images.githubusercontent.com/18526288/116802227-d19cdc80-ab00-11eb-8133-7b34dd750da2.png)
-rw-r--r--src/librustdoc/clean/inline.rs2
-rw-r--r--src/librustdoc/clean/mod.rs12
-rw-r--r--src/librustdoc/formats/cache.rs46
-rw-r--r--src/test/rustdoc/auxiliary/trait-alias-mention.rs3
-rw-r--r--src/test/rustdoc/trait-alias-mention.rs10
-rw-r--r--src/test/rustdoc/trait_alias.rs2
6 files changed, 58 insertions, 17 deletions
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 5dd9f3f1ebd..f6c13e5f418 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -188,7 +188,7 @@ crate fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemType)
     if did.is_local() {
         cx.cache.exact_paths.insert(did, fqn);
     } else {
-        cx.cache.external_paths.insert(did, (fqn, ItemType::from(kind)));
+        cx.cache.external_paths.insert(did, (fqn, kind));
     }
 }
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 78b76b05018..33df9ea3f3e 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -17,11 +17,11 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
-use rustc_middle::bug;
 use rustc_middle::middle::resolve_lifetime as rl;
 use rustc_middle::ty::fold::TypeFolder;
 use rustc_middle::ty::subst::{InternalSubsts, Subst};
 use rustc_middle::ty::{self, AdtKind, Lift, Ty, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_mir::const_eval::{is_const_fn, is_unstable_const_fn};
 use rustc_span::hygiene::{AstPass, MacroKind};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -158,7 +158,15 @@ impl Clean<GenericBound> for hir::GenericBound<'_> {
 impl Clean<Type> for (ty::TraitRef<'_>, &[TypeBinding]) {
     fn clean(&self, cx: &mut DocContext<'_>) -> Type {
         let (trait_ref, bounds) = *self;
-        inline::record_extern_fqn(cx, trait_ref.def_id, ItemType::Trait);
+        let kind = cx.tcx.def_kind(trait_ref.def_id).into();
+        if !matches!(kind, ItemType::Trait | ItemType::TraitAlias) {
+            span_bug!(
+                cx.tcx.def_span(trait_ref.def_id),
+                "`TraitRef` had unexpected kind {:?}",
+                kind
+            );
+        }
+        inline::record_extern_fqn(cx, trait_ref.def_id, kind);
         let path = external_path(
             cx,
             cx.tcx.item_name(trait_ref.def_id),
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index 8723e47586e..b6b76a96e7f 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -327,6 +327,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
             | clean::EnumItem(..)
             | clean::TypedefItem(..)
             | clean::TraitItem(..)
+            | clean::TraitAliasItem(..)
             | clean::FunctionItem(..)
             | clean::ModuleItem(..)
             | clean::ForeignFunctionItem(..)
@@ -337,26 +338,43 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
             | clean::ForeignTypeItem
             | clean::MacroItem(..)
             | clean::ProcMacroItem(..)
-            | clean::VariantItem(..)
-                if !self.cache.stripped_mod =>
-            {
-                // Re-exported items mean that the same id can show up twice
-                // in the rustdoc ast that we're looking at. We know,
-                // however, that a re-exported item doesn't show up in the
-                // `public_items` map, so we can skip inserting into the
-                // paths map if there was already an entry present and we're
-                // not a public item.
-                if !self.cache.paths.contains_key(&item.def_id)
-                    || self.cache.access_levels.is_public(item.def_id)
-                {
-                    self.cache.paths.insert(item.def_id, (self.cache.stack.clone(), item.type_()));
+            | clean::VariantItem(..) => {
+                if !self.cache.stripped_mod {
+                    // Re-exported items mean that the same id can show up twice
+                    // in the rustdoc ast that we're looking at. We know,
+                    // however, that a re-exported item doesn't show up in the
+                    // `public_items` map, so we can skip inserting into the
+                    // paths map if there was already an entry present and we're
+                    // not a public item.
+                    if !self.cache.paths.contains_key(&item.def_id)
+                        || self.cache.access_levels.is_public(item.def_id)
+                    {
+                        self.cache
+                            .paths
+                            .insert(item.def_id, (self.cache.stack.clone(), item.type_()));
+                    }
                 }
             }
             clean::PrimitiveItem(..) => {
                 self.cache.paths.insert(item.def_id, (self.cache.stack.clone(), item.type_()));
             }
 
-            _ => {}
+            clean::ExternCrateItem { .. }
+            | clean::ImportItem(..)
+            | clean::OpaqueTyItem(..)
+            | clean::ImplItem(..)
+            | clean::TyMethodItem(..)
+            | clean::MethodItem(..)
+            | clean::StructFieldItem(..)
+            | clean::AssocConstItem(..)
+            | clean::AssocTypeItem(..)
+            | clean::StrippedItem(..)
+            | clean::KeywordItem(..) => {
+                // FIXME: Do these need handling?
+                // The person writing this comment doesn't know.
+                // So would rather leave them to an expert,
+                // as at least the list is better than `_ => {}`.
+            }
         }
 
         // Maintain the parent stack
diff --git a/src/test/rustdoc/auxiliary/trait-alias-mention.rs b/src/test/rustdoc/auxiliary/trait-alias-mention.rs
new file mode 100644
index 00000000000..6df06c87a09
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/trait-alias-mention.rs
@@ -0,0 +1,3 @@
+#![feature(trait_alias)]
+
+pub trait SomeAlias = std::fmt::Debug + std::marker::Copy;
diff --git a/src/test/rustdoc/trait-alias-mention.rs b/src/test/rustdoc/trait-alias-mention.rs
new file mode 100644
index 00000000000..6da0dc68785
--- /dev/null
+++ b/src/test/rustdoc/trait-alias-mention.rs
@@ -0,0 +1,10 @@
+// aux-build:trait-alias-mention.rs
+// build-aux-docs
+
+#![crate_name = "foo"]
+
+extern crate trait_alias_mention;
+
+// @has foo/fn.mention_alias_in_bounds.html '//a[@href="../trait_alias_mention/traitalias.SomeAlias.html"]' 'SomeAlias'
+pub fn mention_alias_in_bounds<T: trait_alias_mention::SomeAlias>() {
+}
diff --git a/src/test/rustdoc/trait_alias.rs b/src/test/rustdoc/trait_alias.rs
index 98b8d879ac0..6cd4a1a0afa 100644
--- a/src/test/rustdoc/trait_alias.rs
+++ b/src/test/rustdoc/trait_alias.rs
@@ -19,3 +19,5 @@ pub trait CopyAlias = Copy;
 pub trait Alias2 = Copy + Debug;
 // @has foo/traitalias.Foo.html '//section[@id="main"]/pre' 'trait Foo<T> = Into<T> + Debug;'
 pub trait Foo<T> = Into<T> + Debug;
+// @has foo/fn.bar.html '//a[@href="traitalias.Alias2.html"]' 'Alias2'
+pub fn bar<T>() where T: Alias2 {}