about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustdoc/clean/inline.rs43
-rw-r--r--src/librustdoc/core.rs4
-rw-r--r--src/librustdoc/html/render/print_item.rs5
-rw-r--r--tests/rustdoc/auxiliary/ext-trait-aliases.rs13
-rw-r--r--tests/rustdoc/auxiliary/trait-alias-mention.rs3
-rw-r--r--tests/rustdoc/trait-alias-mention.rs10
-rw-r--r--tests/rustdoc/trait-aliases.rs82
-rw-r--r--tests/rustdoc/trait_alias.rs26
8 files changed, 122 insertions, 64 deletions
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 3a2b6974681..2ea0fd8ad6c 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -67,9 +67,13 @@ pub(crate) fn try_inline(
             record_extern_fqn(cx, did, ItemType::Trait);
             cx.with_param_env(did, |cx| {
                 build_impls(cx, did, attrs_without_docs, &mut ret);
-                clean::TraitItem(Box::new(build_external_trait(cx, did)))
+                clean::TraitItem(Box::new(build_trait(cx, did)))
             })
         }
+        Res::Def(DefKind::TraitAlias, did) => {
+            record_extern_fqn(cx, did, ItemType::TraitAlias);
+            cx.with_param_env(did, |cx| clean::TraitAliasItem(build_trait_alias(cx, did)))
+        }
         Res::Def(DefKind::Fn, did) => {
             record_extern_fqn(cx, did, ItemType::Function);
             cx.with_param_env(did, |cx| {
@@ -251,7 +255,7 @@ pub(crate) fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemT
     }
 }
 
-pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait {
+pub(crate) fn build_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait {
     let trait_items = cx
         .tcx
         .associated_items(did)
@@ -263,11 +267,18 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean
     let predicates = cx.tcx.predicates_of(did);
     let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
     let generics = filter_non_trait_generics(did, generics);
-    let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
+    let (generics, supertrait_bounds) = separate_self_bounds(generics);
     clean::Trait { def_id: did, generics, items: trait_items, bounds: supertrait_bounds }
 }
 
-pub(crate) fn build_function(cx: &mut DocContext<'_>, def_id: DefId) -> Box<clean::Function> {
+fn build_trait_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::TraitAlias {
+    let predicates = cx.tcx.predicates_of(did);
+    let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
+    let (generics, bounds) = separate_self_bounds(generics);
+    clean::TraitAlias { generics, bounds }
+}
+
+pub(super) fn build_function(cx: &mut DocContext<'_>, def_id: DefId) -> Box<clean::Function> {
     let sig = cx.tcx.fn_sig(def_id).instantiate_identity();
     // The generics need to be cleaned before the signature.
     let mut generics =
@@ -788,12 +799,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
     g
 }
 
-/// Supertrait bounds for a trait are also listed in the generics coming from
-/// the metadata for a crate, so we want to separate those out and create a new
-/// list of explicit supertrait bounds to render nicely.
-fn separate_supertrait_bounds(
-    mut g: clean::Generics,
-) -> (clean::Generics, Vec<clean::GenericBound>) {
+fn separate_self_bounds(mut g: clean::Generics) -> (clean::Generics, Vec<clean::GenericBound>) {
     let mut ty_bounds = Vec::new();
     g.where_predicates.retain(|pred| match *pred {
         clean::WherePredicate::BoundPredicate { ty: clean::SelfTy, ref bounds, .. } => {
@@ -806,22 +812,17 @@ fn separate_supertrait_bounds(
 }
 
 pub(crate) fn record_extern_trait(cx: &mut DocContext<'_>, did: DefId) {
-    if did.is_local() {
-        return;
-    }
-
+    if did.is_local()
+        || cx.external_traits.contains_key(&did)
+        || cx.active_extern_traits.contains(&did)
     {
-        if cx.external_traits.contains_key(&did) || cx.active_extern_traits.contains(&did) {
-            return;
-        }
+        return;
     }
 
-    {
-        cx.active_extern_traits.insert(did);
-    }
+    cx.active_extern_traits.insert(did);
 
     debug!("record_extern_trait: {did:?}");
-    let trait_ = build_external_trait(cx, did);
+    let trait_ = build_trait(cx, did);
 
     cx.external_traits.insert(did, trait_);
     cx.active_extern_traits.remove(&did);
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index c4dea79370d..41688b41c6e 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -27,7 +27,7 @@ use rustc_span::source_map;
 use rustc_span::symbol::sym;
 use tracing::{debug, info};
 
-use crate::clean::inline::build_external_trait;
+use crate::clean::inline::build_trait;
 use crate::clean::{self, ItemId};
 use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions};
 use crate::formats::cache::Cache;
@@ -385,7 +385,7 @@ pub(crate) fn run_global_ctxt(
     //
     // Note that in case of `#![no_core]`, the trait is not available.
     if let Some(sized_trait_did) = ctxt.tcx.lang_items().sized_trait() {
-        let sized_trait = build_external_trait(&mut ctxt, sized_trait_did);
+        let sized_trait = build_trait(&mut ctxt, sized_trait_did);
         ctxt.external_traits.insert(sized_trait_did, sized_trait);
     }
 
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 96847f13f65..da33fedaa31 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -1229,12 +1229,13 @@ fn item_trait_alias(
         wrap_item(w, |w| {
             write!(
                 w,
-                "{attrs}trait {name}{generics}{where_b} = {bounds};",
+                "{attrs}trait {name}{generics} = {bounds}{where_clause};",
                 attrs = render_attributes_in_pre(it, "", cx),
                 name = it.name.unwrap(),
                 generics = t.generics.print(cx),
-                where_b = print_where_clause(&t.generics, cx, 0, Ending::Newline).maybe_display(),
                 bounds = bounds(&t.bounds, true, cx),
+                where_clause =
+                    print_where_clause(&t.generics, cx, 0, Ending::NoNewline).maybe_display(),
             )
         })?;
 
diff --git a/tests/rustdoc/auxiliary/ext-trait-aliases.rs b/tests/rustdoc/auxiliary/ext-trait-aliases.rs
new file mode 100644
index 00000000000..8454c04063c
--- /dev/null
+++ b/tests/rustdoc/auxiliary/ext-trait-aliases.rs
@@ -0,0 +1,13 @@
+#![feature(trait_alias)]
+
+pub trait ExtAlias0 = Copy + Iterator<Item = u8>;
+
+pub trait ExtAlias1<'a, T: 'a + Clone, const N: usize> = From<[&'a T; N]>;
+
+pub trait ExtAlias2<T> = where T: From<String>, String: Into<T>;
+
+pub trait ExtAlias3 = Sized;
+
+pub trait ExtAlias4 = where Self: Sized;
+
+pub trait ExtAlias5 = ;
diff --git a/tests/rustdoc/auxiliary/trait-alias-mention.rs b/tests/rustdoc/auxiliary/trait-alias-mention.rs
deleted file mode 100644
index 6df06c87a09..00000000000
--- a/tests/rustdoc/auxiliary/trait-alias-mention.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-#![feature(trait_alias)]
-
-pub trait SomeAlias = std::fmt::Debug + std::marker::Copy;
diff --git a/tests/rustdoc/trait-alias-mention.rs b/tests/rustdoc/trait-alias-mention.rs
deleted file mode 100644
index b6ef926e644..00000000000
--- a/tests/rustdoc/trait-alias-mention.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ 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/tests/rustdoc/trait-aliases.rs b/tests/rustdoc/trait-aliases.rs
new file mode 100644
index 00000000000..1be93f72042
--- /dev/null
+++ b/tests/rustdoc/trait-aliases.rs
@@ -0,0 +1,82 @@
+// Basic testing for trait aliases.
+#![feature(trait_alias)]
+#![crate_name = "it"]
+
+// Check the "local case" (HIR cleaning) //
+
+//@ has it/all.html '//a[@href="traitalias.Alias0.html"]' 'Alias0'
+//@ has it/index.html '//h2[@id="trait-aliases"]' 'Trait Aliases'
+//@ has it/index.html '//a[@class="traitalias"]' 'Alias0'
+//@ has it/traitalias.Alias0.html
+//@ has - '//*[@class="rust item-decl"]//code' 'trait Alias0 = Copy + Iterator<Item = u8>;'
+pub trait Alias0 = Copy + Iterator<Item = u8>;
+
+//@ has it/traitalias.Alias1.html
+//@ has - '//pre[@class="rust item-decl"]' \
+//        "trait Alias1<'a, T: 'a + Clone, const N: usize> = From<[&'a T; N]>;"
+pub trait Alias1<'a, T: 'a + Clone, const N: usize> = From<[&'a T; N]>;
+
+//@ has it/traitalias.Alias2.html
+//@ has - '//pre[@class="rust item-decl"]' \
+//        'trait Alias2<T> = where T: From<String>, String: Into<T>;'
+pub trait Alias2<T> = where T: From<String>, String: Into<T>;
+
+//@ has it/traitalias.Alias3.html
+//@ has - '//pre[@class="rust item-decl"]' 'trait Alias3 = ;'
+pub trait Alias3 =;
+
+//@ has it/traitalias.Alias4.html
+//@ has - '//pre[@class="rust item-decl"]' 'trait Alias4 = ;'
+pub trait Alias4 = where;
+
+//@ has it/fn.usage0.html
+//@ has - '//pre[@class="rust item-decl"]' "pub fn usage0(_: impl Alias0)"
+//@ has - '//a[@href="traitalias.Alias0.html"]' 'Alias0'
+pub fn usage0(_: impl Alias0) {}
+
+// FIXME: One can only "disambiguate" intra-doc links to trait aliases with `type@` but not with
+// `trait@` (fails to resolve) or `traitalias@` (doesn't exist). We should make at least one of
+// the latter two work, right?
+
+//@ has it/link0/index.html
+//@ has - '//a/@href' 'traitalias.Alias0.html'
+//@ has - '//a/@href' 'traitalias.Alias1.html'
+/// [Alias0], [type@Alias1]
+pub mod link0 {}
+
+// Check the "extern case" (middle cleaning) //
+
+//@ aux-build: ext-trait-aliases.rs
+extern crate ext_trait_aliases as ext;
+
+//@ has it/traitalias.ExtAlias0.html
+//@ has - '//pre[@class="rust item-decl"]' 'trait ExtAlias0 = Copy + Iterator<Item = u8>;'
+pub use ext::ExtAlias0;
+
+//@ has it/traitalias.ExtAlias1.html
+//@ has - '//pre[@class="rust item-decl"]' \
+//        "trait ExtAlias1<'a, T, const N: usize> = From<[&'a T; N]> where T: 'a + Clone;"
+pub use ext::ExtAlias1;
+
+//@ has it/traitalias.ExtAlias2.html
+//@ has - '//pre[@class="rust item-decl"]' \
+//        'trait ExtAlias2<T> = where T: From<String>, String: Into<T>;'
+pub use ext::ExtAlias2;
+
+//@ has it/traitalias.ExtAlias3.html
+//@ has - '//pre[@class="rust item-decl"]' 'trait ExtAlias3 = Sized;'
+pub use ext::ExtAlias3;
+
+// NOTE: Middle cleaning can't discern `= Sized` and `= where Self: Sized` and that's okay.
+//@ has it/traitalias.ExtAlias4.html
+//@ has - '//pre[@class="rust item-decl"]' 'trait ExtAlias4 = Sized;'
+pub use ext::ExtAlias4;
+
+//@ has it/traitalias.ExtAlias5.html
+//@ has - '//pre[@class="rust item-decl"]' 'trait ExtAlias5 = ;'
+pub use ext::ExtAlias5;
+
+//@ has it/fn.usage1.html
+//@ has - '//pre[@class="rust item-decl"]' "pub fn usage1(_: impl ExtAlias0)"
+//@ has - '//a[@href="traitalias.ExtAlias0.html"]' 'ExtAlias0'
+pub fn usage1(_: impl ExtAlias0) {}
diff --git a/tests/rustdoc/trait_alias.rs b/tests/rustdoc/trait_alias.rs
deleted file mode 100644
index bfdb9d40e2d..00000000000
--- a/tests/rustdoc/trait_alias.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-#![feature(trait_alias)]
-
-#![crate_name = "foo"]
-
-use std::fmt::Debug;
-
-//@ has foo/all.html '//a[@href="traitalias.CopyAlias.html"]' 'CopyAlias'
-//@ has foo/all.html '//a[@href="traitalias.Alias2.html"]' 'Alias2'
-//@ has foo/all.html '//a[@href="traitalias.Foo.html"]' 'Foo'
-
-//@ has foo/index.html '//h2[@id="trait-aliases"]' 'Trait Aliases'
-//@ has foo/index.html '//a[@class="traitalias"]' 'CopyAlias'
-//@ has foo/index.html '//a[@class="traitalias"]' 'Alias2'
-//@ has foo/index.html '//a[@class="traitalias"]' 'Foo'
-
-//@ has foo/traitalias.CopyAlias.html
-//@ has - '//section[@id="main-content"]/pre[@class="rust item-decl"]' 'trait CopyAlias = Copy;'
-pub trait CopyAlias = Copy;
-//@ has foo/traitalias.Alias2.html
-//@ has - '//section[@id="main-content"]/pre[@class="rust item-decl"]' 'trait Alias2 = Copy + Debug;'
-pub trait Alias2 = Copy + Debug;
-//@ has foo/traitalias.Foo.html
-//@ has - '//section[@id="main-content"]/pre[@class="rust item-decl"]' '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 {}