Skip to content

Commit 988153c

Browse files
authored
Rollup merge of rust-lang#103190 - fmease:rustdoc-render-bounds-of-cross-crate-gat-params, r=GuillaumeGomez
rustdoc: render bounds of cross-crate GAT params Follow-up to rust-lang#102439. Render the trait bounds of type parameters of cross-crate (generic) associated types. `````@rustbot````` label T-rustdoc A-cross-crate-reexports r? `````@GuillaumeGomez`````
2 parents 16c3b64 + 2cc4a0a commit 988153c

7 files changed

+41
-22
lines changed

src/librustdoc/clean/mod.rs

+30-14
Original file line numberDiff line numberDiff line change
@@ -1201,21 +1201,19 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
12011201
}
12021202

12031203
if let ty::TraitContainer = assoc_item.container {
1204-
// FIXME(fmease): `tcx.explicit_item_bounds` does not contain the bounds of GATs,
1205-
// e.g. the bounds `Copy`, `Display` & (implicitly) `Sized` in
1206-
// `type Assoc<T: Copy> where T: Display`. This also means that we
1207-
// later incorrectly render `where T: ?Sized`.
1208-
//
1209-
// The result of `tcx.explicit_predicates_of` *does* contain them but
1210-
// it does not contain the other bounds / predicates we need.
1211-
// Either merge those two interned lists somehow or refactor
1212-
// `clean_ty_generics` to call `explicit_item_bounds` by itself.
12131204
let bounds = tcx.explicit_item_bounds(assoc_item.def_id);
1214-
let predicates = ty::GenericPredicates { parent: None, predicates: bounds };
1215-
let mut generics =
1216-
clean_ty_generics(cx, tcx.generics_of(assoc_item.def_id), predicates);
1217-
// Filter out the bounds that are (likely?) directly attached to the associated type,
1218-
// as opposed to being located in the where clause.
1205+
let predicates = tcx.explicit_predicates_of(assoc_item.def_id).predicates;
1206+
let predicates =
1207+
tcx.arena.alloc_from_iter(bounds.into_iter().chain(predicates).copied());
1208+
let mut generics = clean_ty_generics(
1209+
cx,
1210+
tcx.generics_of(assoc_item.def_id),
1211+
ty::GenericPredicates { parent: None, predicates },
1212+
);
1213+
// Move bounds that are (likely) directly attached to the associated type
1214+
// from the where clause to the associated type.
1215+
// There is no guarantee that this is what the user actually wrote but we have
1216+
// no way of knowing.
12191217
let mut bounds = generics
12201218
.where_predicates
12211219
.drain_filter(|pred| match *pred {
@@ -1273,6 +1271,24 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
12731271
}
12741272
None => bounds.push(GenericBound::maybe_sized(cx)),
12751273
}
1274+
// Move bounds that are (likely) directly attached to the parameters of the
1275+
// (generic) associated type from the where clause to the respective parameter.
1276+
// There is no guarantee that this is what the user actually wrote but we have
1277+
// no way of knowing.
1278+
let mut where_predicates = Vec::new();
1279+
for mut pred in generics.where_predicates {
1280+
if let WherePredicate::BoundPredicate { ty: Generic(arg), bounds, .. } = &mut pred
1281+
&& let Some(GenericParamDef {
1282+
kind: GenericParamDefKind::Type { bounds: param_bounds, .. },
1283+
..
1284+
}) = generics.params.iter_mut().find(|param| &param.name == arg)
1285+
{
1286+
param_bounds.extend(mem::take(bounds));
1287+
} else {
1288+
where_predicates.push(pred);
1289+
}
1290+
}
1291+
generics.where_predicates = where_predicates;
12761292

12771293
if tcx.impl_defaultness(assoc_item.def_id).has_value() {
12781294
AssocTypeItem(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h4 class="code-header">type <a href="#associatedtype.Out0" class="associatedtype">Out0</a>: <a class="trait" href="../assoc_item_trait_bounds/trait.Support.html" title="trait assoc_item_trait_bounds::Support">Support</a>&lt;Item = <a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>&gt;</h4>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h4 class="code-header">type <a href="#associatedtype.Out2" class="associatedtype">Out2</a>&lt;T&gt;: <a class="trait" href="../assoc_item_trait_bounds/trait.Support.html" title="trait assoc_item_trait_bounds::Support">Support</a>&lt;Item = T&gt;</h4>

src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.rs src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
// Regression test for issues #77763, #84579 and #102142.
22
#![crate_name = "main"]
33

4-
// aux-build:assoc_item_trait_bounds_with_bindings.rs
4+
// aux-build:assoc_item_trait_bounds.rs
55
// build-aux-docs
66
// ignore-cross-compile
7-
extern crate assoc_item_trait_bounds_with_bindings as aux;
8-
9-
// FIXME(fmease): Don't render an incorrect `T: ?Sized` where-clause for parameters
10-
// of GATs like `Main::Out{2,4}`. Add a snapshot test once it's fixed.
7+
extern crate assoc_item_trait_bounds as aux;
118

129
// @has main/trait.Main.html
1310
// @has - '//*[@id="associatedtype.Out0"]' 'type Out0: Support<Item = ()>'
@@ -24,11 +21,15 @@ extern crate assoc_item_trait_bounds_with_bindings as aux;
2421
// @has - '//*[@id="associatedtype.Out11"]' "type Out11: for<'r, 's> Helper<A<'s> = &'s (), B<'r> = ()>"
2522
// @has - '//*[@id="associatedtype.Out12"]' "type Out12: for<'w> Helper<B<'w> = Cow<'w, str>, A<'w> = bool>"
2623
// @has - '//*[@id="associatedtype.Out13"]' "type Out13: for<'fst, 'snd> Aid<'snd, Result<'fst> = &'fst mut str>"
24+
// @has - '//*[@id="associatedtype.Out14"]' "type Out14<P: Copy + Eq, Q: ?Sized>"
2725
//
28-
// Snapshots: Check that we do not render any where-clauses for those associated types since all of
29-
// the trait bounds contained within were moved to the bounds of the respective item.
26+
// Snapshots:
27+
// Check that we don't render any where-clauses for the following associated types since
28+
// all corresponding projection equality predicates should have already been re-sugared
29+
// to associated type bindings:
3030
//
3131
// @snapshot out0 - '//*[@id="associatedtype.Out0"]/*[@class="code-header"]'
32+
// @snapshot out2 - '//*[@id="associatedtype.Out2"]/*[@class="code-header"]'
3233
// @snapshot out9 - '//*[@id="associatedtype.Out9"]/*[@class="code-header"]'
3334
//
3435
// @has - '//*[@id="tymethod.make"]' \

src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out0.html

-1
This file was deleted.

src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds_with_bindings.rs src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub trait Main {
1515
type Out11: for<'r, 's> Helper<A<'s> = &'s (), B<'r> = ()>;
1616
type Out12: for<'w> Helper<B<'w> = std::borrow::Cow<'w, str>, A<'w> = bool>;
1717
type Out13: for<'fst, 'snd> Aid<'snd, Result<'fst> = &'fst mut str>;
18+
type Out14<P: Copy + Eq, Q: ?Sized>;
1819

1920
fn make<F>(_: F, _: impl FnMut(&str) -> bool)
2021
where

0 commit comments

Comments
 (0)