rustdoc: render bounds of cross-crate GAT params
This commit is contained in:
parent
d7dd01fe8b
commit
2cc4a0aad7
@ -1201,21 +1201,19 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
|
||||
}
|
||||
|
||||
if let ty::TraitContainer = assoc_item.container {
|
||||
// FIXME(fmease): `tcx.explicit_item_bounds` does not contain the bounds of GATs,
|
||||
// e.g. the bounds `Copy`, `Display` & (implicitly) `Sized` in
|
||||
// `type Assoc<T: Copy> where T: Display`. This also means that we
|
||||
// later incorrectly render `where T: ?Sized`.
|
||||
//
|
||||
// The result of `tcx.explicit_predicates_of` *does* contain them but
|
||||
// it does not contain the other bounds / predicates we need.
|
||||
// Either merge those two interned lists somehow or refactor
|
||||
// `clean_ty_generics` to call `explicit_item_bounds` by itself.
|
||||
let bounds = tcx.explicit_item_bounds(assoc_item.def_id);
|
||||
let predicates = ty::GenericPredicates { parent: None, predicates: bounds };
|
||||
let mut generics =
|
||||
clean_ty_generics(cx, tcx.generics_of(assoc_item.def_id), predicates);
|
||||
// Filter out the bounds that are (likely?) directly attached to the associated type,
|
||||
// as opposed to being located in the where clause.
|
||||
let predicates = tcx.explicit_predicates_of(assoc_item.def_id).predicates;
|
||||
let predicates =
|
||||
tcx.arena.alloc_from_iter(bounds.into_iter().chain(predicates).copied());
|
||||
let mut generics = clean_ty_generics(
|
||||
cx,
|
||||
tcx.generics_of(assoc_item.def_id),
|
||||
ty::GenericPredicates { parent: None, predicates },
|
||||
);
|
||||
// Move bounds that are (likely) directly attached to the associated type
|
||||
// from the where clause to the associated type.
|
||||
// There is no guarantee that this is what the user actually wrote but we have
|
||||
// no way of knowing.
|
||||
let mut bounds = generics
|
||||
.where_predicates
|
||||
.drain_filter(|pred| match *pred {
|
||||
@ -1273,6 +1271,24 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
|
||||
}
|
||||
None => bounds.push(GenericBound::maybe_sized(cx)),
|
||||
}
|
||||
// Move bounds that are (likely) directly attached to the parameters of the
|
||||
// (generic) associated type from the where clause to the respective parameter.
|
||||
// There is no guarantee that this is what the user actually wrote but we have
|
||||
// no way of knowing.
|
||||
let mut where_predicates = Vec::new();
|
||||
for mut pred in generics.where_predicates {
|
||||
if let WherePredicate::BoundPredicate { ty: Generic(arg), bounds, .. } = &mut pred
|
||||
&& let Some(GenericParamDef {
|
||||
kind: GenericParamDefKind::Type { bounds: param_bounds, .. },
|
||||
..
|
||||
}) = generics.params.iter_mut().find(|param| ¶m.name == arg)
|
||||
{
|
||||
param_bounds.extend(mem::take(bounds));
|
||||
} else {
|
||||
where_predicates.push(pred);
|
||||
}
|
||||
}
|
||||
generics.where_predicates = where_predicates;
|
||||
|
||||
if tcx.impl_defaultness(assoc_item.def_id).has_value() {
|
||||
AssocTypeItem(
|
||||
|
@ -0,0 +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><Item = <a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>></h4>
|
@ -0,0 +1 @@
|
||||
<h4 class="code-header">type <a href="#associatedtype.Out2" class="associatedtype">Out2</a><T>: <a class="trait" href="../assoc_item_trait_bounds/trait.Support.html" title="trait assoc_item_trait_bounds::Support">Support</a><Item = T></h4>
|
@ -1,13 +1,10 @@
|
||||
// Regression test for issues #77763, #84579 and #102142.
|
||||
#![crate_name = "main"]
|
||||
|
||||
// aux-build:assoc_item_trait_bounds_with_bindings.rs
|
||||
// aux-build:assoc_item_trait_bounds.rs
|
||||
// build-aux-docs
|
||||
// ignore-cross-compile
|
||||
extern crate assoc_item_trait_bounds_with_bindings as aux;
|
||||
|
||||
// FIXME(fmease): Don't render an incorrect `T: ?Sized` where-clause for parameters
|
||||
// of GATs like `Main::Out{2,4}`. Add a snapshot test once it's fixed.
|
||||
extern crate assoc_item_trait_bounds as aux;
|
||||
|
||||
// @has main/trait.Main.html
|
||||
// @has - '//*[@id="associatedtype.Out0"]' 'type Out0: Support<Item = ()>'
|
||||
@ -24,11 +21,15 @@ extern crate assoc_item_trait_bounds_with_bindings as aux;
|
||||
// @has - '//*[@id="associatedtype.Out11"]' "type Out11: for<'r, 's> Helper<A<'s> = &'s (), B<'r> = ()>"
|
||||
// @has - '//*[@id="associatedtype.Out12"]' "type Out12: for<'w> Helper<B<'w> = Cow<'w, str>, A<'w> = bool>"
|
||||
// @has - '//*[@id="associatedtype.Out13"]' "type Out13: for<'fst, 'snd> Aid<'snd, Result<'fst> = &'fst mut str>"
|
||||
// @has - '//*[@id="associatedtype.Out14"]' "type Out14<P: Copy + Eq, Q: ?Sized>"
|
||||
//
|
||||
// Snapshots: Check that we do not render any where-clauses for those associated types since all of
|
||||
// the trait bounds contained within were moved to the bounds of the respective item.
|
||||
// Snapshots:
|
||||
// Check that we don't render any where-clauses for the following associated types since
|
||||
// all corresponding projection equality predicates should have already been re-sugared
|
||||
// to associated type bindings:
|
||||
//
|
||||
// @snapshot out0 - '//*[@id="associatedtype.Out0"]/*[@class="code-header"]'
|
||||
// @snapshot out2 - '//*[@id="associatedtype.Out2"]/*[@class="code-header"]'
|
||||
// @snapshot out9 - '//*[@id="associatedtype.Out9"]/*[@class="code-header"]'
|
||||
//
|
||||
// @has - '//*[@id="tymethod.make"]' \
|
@ -1 +0,0 @@
|
||||
<h4 class="code-header">type <a href="#associatedtype.Out0" class="associatedtype">Out0</a>: <a class="trait" href="../assoc_item_trait_bounds_with_bindings/trait.Support.html" title="trait assoc_item_trait_bounds_with_bindings::Support">Support</a><Item = <a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>></h4>
|
@ -15,6 +15,7 @@ pub trait Main {
|
||||
type Out11: for<'r, 's> Helper<A<'s> = &'s (), B<'r> = ()>;
|
||||
type Out12: for<'w> Helper<B<'w> = std::borrow::Cow<'w, str>, A<'w> = bool>;
|
||||
type Out13: for<'fst, 'snd> Aid<'snd, Result<'fst> = &'fst mut str>;
|
||||
type Out14<P: Copy + Eq, Q: ?Sized>;
|
||||
|
||||
fn make<F>(_: F, _: impl FnMut(&str) -> bool)
|
||||
where
|
Loading…
x
Reference in New Issue
Block a user