Skip to content

Commit 7a4525c

Browse files
authored
Rollup merge of #139943 - fmease:rustdoc-ixcre-trait-aliases, r=GuillaumeGomez
rustdoc: Support inlined cross-crate re-exported trait aliases Previously we'd just drop them. As a result of this PR, [`core::ptr::Thin`](https://doc.rust-lang.org/nightly/core/ptr/traitalias.Thin.html) will be admitted into the `std` façade! Also, render the where clause *after* the bounds / the `=`, not before them, as it should be. r? rustdoc
2 parents b79996d + 9f548e2 commit 7a4525c

File tree

8 files changed

+122
-64
lines changed

8 files changed

+122
-64
lines changed

Diff for: src/librustdoc/clean/inline.rs

+22-21
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,13 @@ pub(crate) fn try_inline(
6767
record_extern_fqn(cx, did, ItemType::Trait);
6868
cx.with_param_env(did, |cx| {
6969
build_impls(cx, did, attrs_without_docs, &mut ret);
70-
clean::TraitItem(Box::new(build_external_trait(cx, did)))
70+
clean::TraitItem(Box::new(build_trait(cx, did)))
7171
})
7272
}
73+
Res::Def(DefKind::TraitAlias, did) => {
74+
record_extern_fqn(cx, did, ItemType::TraitAlias);
75+
cx.with_param_env(did, |cx| clean::TraitAliasItem(build_trait_alias(cx, did)))
76+
}
7377
Res::Def(DefKind::Fn, did) => {
7478
record_extern_fqn(cx, did, ItemType::Function);
7579
cx.with_param_env(did, |cx| {
@@ -251,7 +255,7 @@ pub(crate) fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemT
251255
}
252256
}
253257

254-
pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait {
258+
pub(crate) fn build_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait {
255259
let trait_items = cx
256260
.tcx
257261
.associated_items(did)
@@ -263,11 +267,18 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean
263267
let predicates = cx.tcx.predicates_of(did);
264268
let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
265269
let generics = filter_non_trait_generics(did, generics);
266-
let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
270+
let (generics, supertrait_bounds) = separate_self_bounds(generics);
267271
clean::Trait { def_id: did, generics, items: trait_items, bounds: supertrait_bounds }
268272
}
269273

270-
pub(crate) fn build_function(cx: &mut DocContext<'_>, def_id: DefId) -> Box<clean::Function> {
274+
fn build_trait_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::TraitAlias {
275+
let predicates = cx.tcx.predicates_of(did);
276+
let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
277+
let (generics, bounds) = separate_self_bounds(generics);
278+
clean::TraitAlias { generics, bounds }
279+
}
280+
281+
pub(super) fn build_function(cx: &mut DocContext<'_>, def_id: DefId) -> Box<clean::Function> {
271282
let sig = cx.tcx.fn_sig(def_id).instantiate_identity();
272283
// The generics need to be cleaned before the signature.
273284
let mut generics =
@@ -788,12 +799,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
788799
g
789800
}
790801

791-
/// Supertrait bounds for a trait are also listed in the generics coming from
792-
/// the metadata for a crate, so we want to separate those out and create a new
793-
/// list of explicit supertrait bounds to render nicely.
794-
fn separate_supertrait_bounds(
795-
mut g: clean::Generics,
796-
) -> (clean::Generics, Vec<clean::GenericBound>) {
802+
fn separate_self_bounds(mut g: clean::Generics) -> (clean::Generics, Vec<clean::GenericBound>) {
797803
let mut ty_bounds = Vec::new();
798804
g.where_predicates.retain(|pred| match *pred {
799805
clean::WherePredicate::BoundPredicate { ty: clean::SelfTy, ref bounds, .. } => {
@@ -806,22 +812,17 @@ fn separate_supertrait_bounds(
806812
}
807813

808814
pub(crate) fn record_extern_trait(cx: &mut DocContext<'_>, did: DefId) {
809-
if did.is_local() {
810-
return;
811-
}
812-
815+
if did.is_local()
816+
|| cx.external_traits.contains_key(&did)
817+
|| cx.active_extern_traits.contains(&did)
813818
{
814-
if cx.external_traits.contains_key(&did) || cx.active_extern_traits.contains(&did) {
815-
return;
816-
}
819+
return;
817820
}
818821

819-
{
820-
cx.active_extern_traits.insert(did);
821-
}
822+
cx.active_extern_traits.insert(did);
822823

823824
debug!("record_extern_trait: {did:?}");
824-
let trait_ = build_external_trait(cx, did);
825+
let trait_ = build_trait(cx, did);
825826

826827
cx.external_traits.insert(did, trait_);
827828
cx.active_extern_traits.remove(&did);

Diff for: src/librustdoc/core.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use rustc_span::source_map;
2727
use rustc_span::symbol::sym;
2828
use tracing::{debug, info};
2929

30-
use crate::clean::inline::build_external_trait;
30+
use crate::clean::inline::build_trait;
3131
use crate::clean::{self, ItemId};
3232
use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions};
3333
use crate::formats::cache::Cache;
@@ -385,7 +385,7 @@ pub(crate) fn run_global_ctxt(
385385
//
386386
// Note that in case of `#![no_core]`, the trait is not available.
387387
if let Some(sized_trait_did) = ctxt.tcx.lang_items().sized_trait() {
388-
let sized_trait = build_external_trait(&mut ctxt, sized_trait_did);
388+
let sized_trait = build_trait(&mut ctxt, sized_trait_did);
389389
ctxt.external_traits.insert(sized_trait_did, sized_trait);
390390
}
391391

Diff for: src/librustdoc/html/render/print_item.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1232,12 +1232,13 @@ fn item_trait_alias(
12321232
wrap_item(w, |w| {
12331233
write!(
12341234
w,
1235-
"{attrs}trait {name}{generics}{where_b} = {bounds};",
1235+
"{attrs}trait {name}{generics} = {bounds}{where_clause};",
12361236
attrs = render_attributes_in_pre(it, "", cx),
12371237
name = it.name.unwrap(),
12381238
generics = t.generics.print(cx),
1239-
where_b = print_where_clause(&t.generics, cx, 0, Ending::Newline).maybe_display(),
12401239
bounds = bounds(&t.bounds, true, cx),
1240+
where_clause =
1241+
print_where_clause(&t.generics, cx, 0, Ending::NoNewline).maybe_display(),
12411242
)
12421243
})?;
12431244

Diff for: tests/rustdoc/auxiliary/ext-trait-aliases.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![feature(trait_alias)]
2+
3+
pub trait ExtAlias0 = Copy + Iterator<Item = u8>;
4+
5+
pub trait ExtAlias1<'a, T: 'a + Clone, const N: usize> = From<[&'a T; N]>;
6+
7+
pub trait ExtAlias2<T> = where T: From<String>, String: Into<T>;
8+
9+
pub trait ExtAlias3 = Sized;
10+
11+
pub trait ExtAlias4 = where Self: Sized;
12+
13+
pub trait ExtAlias5 = ;

Diff for: tests/rustdoc/auxiliary/trait-alias-mention.rs

-3
This file was deleted.

Diff for: tests/rustdoc/trait-alias-mention.rs

-10
This file was deleted.

Diff for: tests/rustdoc/trait-aliases.rs

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Basic testing for trait aliases.
2+
#![feature(trait_alias)]
3+
#![crate_name = "it"]
4+
5+
// Check the "local case" (HIR cleaning) //
6+
7+
//@ has it/all.html '//a[@href="traitalias.Alias0.html"]' 'Alias0'
8+
//@ has it/index.html '//h2[@id="trait-aliases"]' 'Trait Aliases'
9+
//@ has it/index.html '//a[@class="traitalias"]' 'Alias0'
10+
//@ has it/traitalias.Alias0.html
11+
//@ has - '//*[@class="rust item-decl"]//code' 'trait Alias0 = Copy + Iterator<Item = u8>;'
12+
pub trait Alias0 = Copy + Iterator<Item = u8>;
13+
14+
//@ has it/traitalias.Alias1.html
15+
//@ has - '//pre[@class="rust item-decl"]' \
16+
// "trait Alias1<'a, T: 'a + Clone, const N: usize> = From<[&'a T; N]>;"
17+
pub trait Alias1<'a, T: 'a + Clone, const N: usize> = From<[&'a T; N]>;
18+
19+
//@ has it/traitalias.Alias2.html
20+
//@ has - '//pre[@class="rust item-decl"]' \
21+
// 'trait Alias2<T> = where T: From<String>, String: Into<T>;'
22+
pub trait Alias2<T> = where T: From<String>, String: Into<T>;
23+
24+
//@ has it/traitalias.Alias3.html
25+
//@ has - '//pre[@class="rust item-decl"]' 'trait Alias3 = ;'
26+
pub trait Alias3 =;
27+
28+
//@ has it/traitalias.Alias4.html
29+
//@ has - '//pre[@class="rust item-decl"]' 'trait Alias4 = ;'
30+
pub trait Alias4 = where;
31+
32+
//@ has it/fn.usage0.html
33+
//@ has - '//pre[@class="rust item-decl"]' "pub fn usage0(_: impl Alias0)"
34+
//@ has - '//a[@href="traitalias.Alias0.html"]' 'Alias0'
35+
pub fn usage0(_: impl Alias0) {}
36+
37+
// FIXME: One can only "disambiguate" intra-doc links to trait aliases with `type@` but not with
38+
// `trait@` (fails to resolve) or `traitalias@` (doesn't exist). We should make at least one of
39+
// the latter two work, right?
40+
41+
//@ has it/link0/index.html
42+
//@ has - '//a/@href' 'traitalias.Alias0.html'
43+
//@ has - '//a/@href' 'traitalias.Alias1.html'
44+
/// [Alias0], [type@Alias1]
45+
pub mod link0 {}
46+
47+
// Check the "extern case" (middle cleaning) //
48+
49+
//@ aux-build: ext-trait-aliases.rs
50+
extern crate ext_trait_aliases as ext;
51+
52+
//@ has it/traitalias.ExtAlias0.html
53+
//@ has - '//pre[@class="rust item-decl"]' 'trait ExtAlias0 = Copy + Iterator<Item = u8>;'
54+
pub use ext::ExtAlias0;
55+
56+
//@ has it/traitalias.ExtAlias1.html
57+
//@ has - '//pre[@class="rust item-decl"]' \
58+
// "trait ExtAlias1<'a, T, const N: usize> = From<[&'a T; N]> where T: 'a + Clone;"
59+
pub use ext::ExtAlias1;
60+
61+
//@ has it/traitalias.ExtAlias2.html
62+
//@ has - '//pre[@class="rust item-decl"]' \
63+
// 'trait ExtAlias2<T> = where T: From<String>, String: Into<T>;'
64+
pub use ext::ExtAlias2;
65+
66+
//@ has it/traitalias.ExtAlias3.html
67+
//@ has - '//pre[@class="rust item-decl"]' 'trait ExtAlias3 = Sized;'
68+
pub use ext::ExtAlias3;
69+
70+
// NOTE: Middle cleaning can't discern `= Sized` and `= where Self: Sized` and that's okay.
71+
//@ has it/traitalias.ExtAlias4.html
72+
//@ has - '//pre[@class="rust item-decl"]' 'trait ExtAlias4 = Sized;'
73+
pub use ext::ExtAlias4;
74+
75+
//@ has it/traitalias.ExtAlias5.html
76+
//@ has - '//pre[@class="rust item-decl"]' 'trait ExtAlias5 = ;'
77+
pub use ext::ExtAlias5;
78+
79+
//@ has it/fn.usage1.html
80+
//@ has - '//pre[@class="rust item-decl"]' "pub fn usage1(_: impl ExtAlias0)"
81+
//@ has - '//a[@href="traitalias.ExtAlias0.html"]' 'ExtAlias0'
82+
pub fn usage1(_: impl ExtAlias0) {}

Diff for: tests/rustdoc/trait_alias.rs

-26
This file was deleted.

0 commit comments

Comments
 (0)