Skip to content

Commit 95ae8cd

Browse files
committed
Compute implied_bounds for generic types, assoc types, TAITs etc.
1 parent f21b4c0 commit 95ae8cd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2476
-200
lines changed

src/librustdoc/clean/mod.rs

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ pub(crate) fn clean_trait_ref_with_constraints<'tcx>(
264264
path
265265
}
266266

267-
fn clean_poly_trait_ref_with_constraints<'tcx>(
267+
pub(crate) fn clean_poly_trait_ref_with_constraints<'tcx>(
268268
cx: &mut DocContext<'tcx>,
269269
poly_trait_ref: ty::PolyTraitRef<'tcx>,
270270
constraints: ThinVec<AssocItemConstraint>,
@@ -458,7 +458,7 @@ fn clean_type_outlives_predicate<'tcx>(
458458
}
459459
}
460460

461-
fn clean_middle_term<'tcx>(
461+
pub(crate) fn clean_middle_term<'tcx>(
462462
term: ty::Binder<'tcx, ty::Term<'tcx>>,
463463
cx: &mut DocContext<'tcx>,
464464
) -> Term {
@@ -526,7 +526,7 @@ fn should_fully_qualify_path(self_def_id: Option<DefId>, trait_: &Path, self_typ
526526
.map_or(!self_type.is_self_type(), |(id, trait_)| id != trait_)
527527
}
528528

529-
fn projection_to_path_segment<'tcx>(
529+
pub(crate) fn projection_to_path_segment<'tcx>(
530530
proj: ty::Binder<'tcx, ty::AliasTerm<'tcx>>,
531531
cx: &mut DocContext<'tcx>,
532532
) -> PathSegment {
@@ -698,8 +698,13 @@ pub(crate) fn clean_generics<'tcx>(
698698
let param = clean_generic_param(cx, Some(gens), param);
699699
match param.kind {
700700
GenericParamDefKind::Lifetime { .. } => unreachable!(),
701-
GenericParamDefKind::Type { ref bounds, .. } => {
702-
cx.impl_trait_bounds.insert(param.def_id.into(), bounds.to_vec());
701+
GenericParamDefKind::Type { ref bounds, ref synthetic, .. } => {
702+
debug_assert!(*synthetic, "non-synthetic generic for impl trait: {param:?}");
703+
let param_def_id = param.def_id;
704+
cx.impl_trait_bounds.insert(
705+
param_def_id.into(),
706+
(bounds.to_vec(), ImplTraitOrigin::Param { def_id: param_def_id }),
707+
);
703708
}
704709
GenericParamDefKind::Const { .. } => unreachable!(),
705710
}
@@ -819,7 +824,7 @@ fn clean_ty_generics_inner<'tcx>(
819824
) -> Generics {
820825
// Don't populate `cx.impl_trait_bounds` before cleaning where clauses,
821826
// since `clean_predicate` would consume them.
822-
let mut impl_trait = BTreeMap::<u32, Vec<GenericBound>>::default();
827+
let mut impl_trait = BTreeMap::<u32, (DefId, Vec<GenericBound>)>::default();
823828

824829
let params: ThinVec<_> = gens
825830
.own_params
@@ -832,7 +837,7 @@ fn clean_ty_generics_inner<'tcx>(
832837
return false;
833838
}
834839
if synthetic {
835-
impl_trait.insert(param.index, vec![]);
840+
impl_trait.insert(param.index, (param.def_id, vec![]));
836841
return false;
837842
}
838843
true
@@ -873,7 +878,7 @@ fn clean_ty_generics_inner<'tcx>(
873878
};
874879

875880
if let Some(param_idx) = param_idx
876-
&& let Some(bounds) = impl_trait.get_mut(&param_idx)
881+
&& let Some((_, bounds)) = impl_trait.get_mut(&param_idx)
877882
{
878883
let pred = clean_predicate(*pred, cx)?;
879884

@@ -895,7 +900,7 @@ fn clean_ty_generics_inner<'tcx>(
895900
})
896901
.collect::<Vec<_>>();
897902

898-
for (idx, mut bounds) in impl_trait {
903+
for (idx, (param_def_id, mut bounds)) in impl_trait {
899904
let mut has_sized = false;
900905
bounds.retain(|b| {
901906
if b.is_sized_bound(cx) {
@@ -929,7 +934,8 @@ fn clean_ty_generics_inner<'tcx>(
929934
}
930935
}
931936

932-
cx.impl_trait_bounds.insert(idx.into(), bounds);
937+
cx.impl_trait_bounds
938+
.insert(idx.into(), (bounds, ImplTraitOrigin::Param { def_id: param_def_id }));
933939
}
934940

935941
// Now that `cx.impl_trait_bounds` is populated, we can process
@@ -1157,7 +1163,7 @@ fn clean_poly_fn_sig<'tcx>(
11571163
// function isn't async without needing to execute the query `asyncness` at
11581164
// all which gives us a noticeable performance boost.
11591165
if let Some(did) = did
1160-
&& let Type::ImplTrait(_) = output
1166+
&& let Type::ImplTrait { .. } = output
11611167
&& cx.tcx.asyncness(did).is_async()
11621168
{
11631169
output = output.sugared_async_return_type();
@@ -1648,8 +1654,8 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
16481654
if let Some(new_ty) = cx.args.get(&did).and_then(|p| p.as_ty()).cloned() {
16491655
return new_ty;
16501656
}
1651-
if let Some(bounds) = cx.impl_trait_bounds.remove(&did.into()) {
1652-
return ImplTrait(bounds);
1657+
if let Some((bounds, origin)) = cx.impl_trait_bounds.remove(&did.into()) {
1658+
return ImplTrait { bounds, origin };
16531659
}
16541660
}
16551661

@@ -1838,7 +1844,9 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
18381844
}
18391845
TyKind::Tup(tys) => Tuple(tys.iter().map(|ty| clean_ty(ty, cx)).collect()),
18401846
TyKind::OpaqueDef(ty) => {
1841-
ImplTrait(ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect())
1847+
let bounds =
1848+
ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect::<Vec<_>>();
1849+
ImplTrait { bounds, origin: ImplTraitOrigin::Opaque { def_id: ty.def_id.to_def_id() } }
18421850
}
18431851
TyKind::Path(_) => clean_qpath(ty, cx),
18441852
TyKind::TraitObject(bounds, lifetime) => {
@@ -2226,8 +2234,8 @@ pub(crate) fn clean_middle_ty<'tcx>(
22262234
}
22272235

22282236
ty::Param(ref p) => {
2229-
if let Some(bounds) = cx.impl_trait_bounds.remove(&p.index.into()) {
2230-
ImplTrait(bounds)
2237+
if let Some((bounds, origin)) = cx.impl_trait_bounds.remove(&p.index.into()) {
2238+
ImplTrait { bounds, origin }
22312239
} else if p.name == kw::SelfUpper {
22322240
SelfTy
22332241
} else {
@@ -2363,7 +2371,7 @@ fn clean_middle_opaque_bounds<'tcx>(
23632371
));
23642372
}
23652373

2366-
ImplTrait(bounds)
2374+
ImplTrait { bounds, origin: ImplTraitOrigin::Opaque { def_id: impl_trait_def_id } }
23672375
}
23682376

23692377
pub(crate) fn clean_field<'tcx>(field: &hir::FieldDef<'tcx>, cx: &mut DocContext<'tcx>) -> Item {
@@ -3177,7 +3185,7 @@ fn clean_assoc_item_constraint<'tcx>(
31773185
}
31783186
}
31793187

3180-
fn clean_bound_vars<'tcx>(
3188+
pub(crate) fn clean_bound_vars<'tcx>(
31813189
bound_vars: &ty::List<ty::BoundVariableKind<'tcx>>,
31823190
cx: &mut DocContext<'tcx>,
31833191
) -> Vec<GenericParamDef> {

src/librustdoc/clean/types.rs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,15 @@ pub(crate) struct PolyTrait {
12921292
pub(crate) generic_params: Vec<GenericParamDef>,
12931293
}
12941294

1295+
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1296+
pub(crate) enum ImplTraitOrigin {
1297+
/// Synthetic type parameter for `impl Trait` in argument position.
1298+
Param { def_id: DefId },
1299+
1300+
/// Opaque type backing `impl Trait`, such as in RPIT or TAIT.
1301+
Opaque { def_id: DefId },
1302+
}
1303+
12951304
/// Rustdoc's representation of types, mostly based on the [`hir::Ty`].
12961305
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
12971306
pub(crate) enum Type {
@@ -1337,7 +1346,25 @@ pub(crate) enum Type {
13371346
Infer,
13381347

13391348
/// An `impl Trait`: `impl TraitA + TraitB + ...`
1340-
ImplTrait(Vec<GenericBound>),
1349+
ImplTrait {
1350+
/// The bounds that are syntactically present:
1351+
/// ```rust
1352+
/// # trait TraitA {}
1353+
/// # trait TraitB {}
1354+
/// # struct Both;
1355+
/// # impl TraitA for Both {}
1356+
/// # impl TraitB for Both {}
1357+
/// fn example() -> impl TraitA + TraitB {
1358+
/// // ^^^^^^ ^^^^^^
1359+
/// // ...
1360+
/// # Both
1361+
/// }
1362+
/// ```
1363+
bounds: Vec<GenericBound>,
1364+
/// Whether this `impl Trait` is syntactic sugar for an anonymous generic parameter,
1365+
/// or represents an opaque type.
1366+
origin: ImplTraitOrigin,
1367+
},
13411368

13421369
UnsafeBinder(Box<UnsafeBinderTy>),
13431370
}
@@ -1465,8 +1492,8 @@ impl Type {
14651492
/// This function will panic if the return type does not match the expected sugaring for async
14661493
/// functions.
14671494
pub(crate) fn sugared_async_return_type(self) -> Type {
1468-
if let Type::ImplTrait(mut v) = self
1469-
&& let Some(GenericBound::TraitBound(PolyTrait { mut trait_, .. }, _)) = v.pop()
1495+
if let Type::ImplTrait { mut bounds, .. } = self
1496+
&& let Some(GenericBound::TraitBound(PolyTrait { mut trait_, .. }, _)) = bounds.pop()
14701497
&& let Some(segment) = trait_.segments.pop()
14711498
&& let GenericArgs::AngleBracketed { mut constraints, .. } = segment.args
14721499
&& let Some(constraint) = constraints.pop()
@@ -1536,7 +1563,7 @@ impl Type {
15361563
Type::Pat(..) => PrimitiveType::Pat,
15371564
RawPointer(..) => PrimitiveType::RawPointer,
15381565
QPath(box QPathData { self_type, .. }) => return self_type.def_id(cache),
1539-
Generic(_) | SelfTy | Infer | ImplTrait(_) | UnsafeBinder(_) => return None,
1566+
Generic(_) | SelfTy | Infer | ImplTrait { .. } | UnsafeBinder(_) => return None,
15401567
};
15411568
Primitive(t).def_id(cache)
15421569
}
@@ -2392,14 +2419,14 @@ mod size_asserts {
23922419
// tidy-alphabetical-start
23932420
static_assert_size!(Crate, 16); // frequently moved by-value
23942421
static_assert_size!(DocFragment, 48);
2395-
static_assert_size!(GenericArg, 32);
2422+
static_assert_size!(GenericArg, 40);
23962423
static_assert_size!(GenericArgs, 24);
23972424
static_assert_size!(GenericParamDef, 40);
23982425
static_assert_size!(Generics, 16);
23992426
static_assert_size!(Item, 8);
24002427
static_assert_size!(ItemInner, 144);
24012428
static_assert_size!(ItemKind, 48);
24022429
static_assert_size!(PathSegment, 32);
2403-
static_assert_size!(Type, 32);
2430+
static_assert_size!(Type, 40);
24042431
// tidy-alphabetical-end
24052432
}

src/librustdoc/core.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@ pub(crate) struct DocContext<'tcx> {
5454
// therefore wouldn't use the corresp. generic arg anyway. Add support for them.
5555
pub(crate) args: DefIdMap<clean::GenericArg>,
5656
pub(crate) current_type_aliases: DefIdMap<usize>,
57-
/// Table synthetic type parameter for `impl Trait` in argument position -> bounds
58-
pub(crate) impl_trait_bounds: FxHashMap<ImplTraitParam, Vec<clean::GenericBound>>,
57+
/// Table of synthetic type parameter
58+
/// for `impl Trait` in argument position -> (bounds, trait origin)
59+
pub(crate) impl_trait_bounds:
60+
FxHashMap<ImplTraitParam, (Vec<clean::GenericBound>, clean::ImplTraitOrigin)>,
5961
/// Auto-trait or blanket impls processed so far, as `(self_ty, trait_def_id)`.
6062
// FIXME(eddyb) make this a `ty::TraitRef<'tcx>` set.
6163
pub(crate) generated_synthetics: FxHashSet<(Ty<'tcx>, DefId)>,

src/librustdoc/html/format.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,15 +1015,15 @@ fn fmt_type(
10151015
{
10161016
true
10171017
}
1018-
clean::ImplTrait(ref bounds) if bounds.len() > 1 => true,
1018+
clean::ImplTrait { ref bounds, .. } if bounds.len() > 1 => true,
10191019
_ => false,
10201020
};
10211021
Wrapped::with_parens()
10221022
.when(needs_parens)
10231023
.wrap_fn(|f| fmt_type(ty, f, use_absolute, cx))
10241024
.fmt(f)
10251025
}
1026-
clean::ImplTrait(bounds) => {
1026+
clean::ImplTrait { bounds, .. } => {
10271027
f.write_str("impl ")?;
10281028
print_generic_bounds(bounds, cx).fmt(f)
10291029
}

src/librustdoc/html/render/search_index.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2043,7 +2043,7 @@ fn get_index_type_id(
20432043
clean::Type::Pat(..)
20442044
| clean::Generic(_)
20452045
| clean::SelfTy
2046-
| clean::ImplTrait(_)
2046+
| clean::ImplTrait { .. }
20472047
| clean::Infer
20482048
| clean::UnsafeBinder(_) => None,
20492049
}
@@ -2141,7 +2141,7 @@ fn simplify_fn_type<'a, 'tcx>(
21412141
RenderType { id: Some(RenderTypeId::Index(idx)), generics: None, bindings: None }
21422142
})
21432143
}
2144-
Type::ImplTrait(ref bounds) => {
2144+
Type::ImplTrait { ref bounds, .. } => {
21452145
let type_bounds = bounds
21462146
.iter()
21472147
.filter_map(|bound| bound.get_trait_path())

0 commit comments

Comments
 (0)