Skip to content

Commit 21917b0

Browse files
committed
Round 3: require binders for substs
1 parent 8b09832 commit 21917b0

File tree

4 files changed

+50
-28
lines changed

4 files changed

+50
-28
lines changed

compiler/rustc_middle/src/ty/sty.rs

+1
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,7 @@ where
980980
/// contain any bound vars that would be bound by the
981981
/// binder. This is commonly used to 'inject' a value T into a
982982
/// different binding level.
983+
#[track_caller]
983984
pub fn dummy(value: T) -> Binder<'tcx, T> {
984985
assert!(!value.has_escaping_bound_vars());
985986
Binder(value, ty::List::empty())

src/librustdoc/clean/mod.rs

+29-17
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ pub(crate) fn clean_trait_ref_with_bindings<'tcx>(
165165
}
166166
inline::record_extern_fqn(cx, trait_ref.def_id(), kind);
167167
let path =
168-
external_path(cx, trait_ref.def_id(), true, bindings, trait_ref.skip_binder().substs);
168+
external_path(cx, trait_ref.def_id(), true, bindings, trait_ref.map_bound(|tr| tr.substs));
169169

170170
debug!(?trait_ref);
171171

@@ -437,7 +437,7 @@ fn clean_projection<'tcx>(
437437
};
438438
let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type);
439439
Type::QPath(Box::new(QPathData {
440-
assoc: projection_to_path_segment(ty.skip_binder(), cx),
440+
assoc: projection_to_path_segment(ty, cx),
441441
should_show_cast,
442442
self_type,
443443
trait_,
@@ -452,15 +452,16 @@ fn compute_should_show_cast(self_def_id: Option<DefId>, trait_: &Path, self_type
452452
}
453453

454454
fn projection_to_path_segment<'tcx>(
455-
ty: ty::ProjectionTy<'tcx>,
455+
ty: ty::Binder<'tcx, ty::ProjectionTy<'tcx>>,
456456
cx: &mut DocContext<'tcx>,
457457
) -> PathSegment {
458-
let item = cx.tcx.associated_item(ty.item_def_id);
459-
let generics = cx.tcx.generics_of(ty.item_def_id);
458+
let item = cx.tcx.associated_item(ty.skip_binder().item_def_id);
459+
let generics = cx.tcx.generics_of(ty.skip_binder().item_def_id);
460460
PathSegment {
461461
name: item.name,
462462
args: GenericArgs::AngleBracketed {
463-
args: substs_to_args(cx, &ty.substs[generics.parent_count..], false).into(),
463+
args: substs_to_args(cx, ty.map_bound(|ty| &ty.substs[generics.parent_count..]), false)
464+
.into(),
464465
bindings: Default::default(),
465466
},
466467
}
@@ -1732,12 +1733,18 @@ pub(crate) fn clean_middle_ty<'tcx>(
17321733
AdtKind::Enum => ItemType::Enum,
17331734
};
17341735
inline::record_extern_fqn(cx, did, kind);
1735-
let path = external_path(cx, did, false, ThinVec::new(), substs);
1736+
let path = external_path(cx, did, false, ThinVec::new(), bound_ty.rebind(substs));
17361737
Type::Path { path }
17371738
}
17381739
ty::Foreign(did) => {
17391740
inline::record_extern_fqn(cx, did, ItemType::ForeignType);
1740-
let path = external_path(cx, did, false, ThinVec::new(), InternalSubsts::empty());
1741+
let path = external_path(
1742+
cx,
1743+
did,
1744+
false,
1745+
ThinVec::new(),
1746+
ty::Binder::dummy(InternalSubsts::empty()),
1747+
);
17411748
Type::Path { path }
17421749
}
17431750
ty::Dynamic(obj, ref reg, _) => {
@@ -1750,9 +1757,9 @@ pub(crate) fn clean_middle_ty<'tcx>(
17501757
.or_else(|| dids.next())
17511758
.unwrap_or_else(|| panic!("found trait object `{bound_ty:?}` with no traits?"));
17521759
let substs = match obj.principal() {
1753-
Some(principal) => principal.skip_binder().substs,
1760+
Some(principal) => principal.map_bound(|p| p.substs),
17541761
// marker traits have no substs.
1755-
_ => cx.tcx.intern_substs(&[]),
1762+
_ => ty::Binder::dummy(InternalSubsts::empty()),
17561763
};
17571764

17581765
inline::record_extern_fqn(cx, did, ItemType::Trait);
@@ -1763,7 +1770,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
17631770
let lifetime = clean_middle_region(*reg);
17641771
let mut bounds = dids
17651772
.map(|did| {
1766-
let empty = cx.tcx.intern_substs(&[]);
1773+
let empty = ty::Binder::dummy(InternalSubsts::empty());
17671774
let path = external_path(cx, did, false, ThinVec::new(), empty);
17681775
inline::record_extern_fqn(cx, did, ItemType::Trait);
17691776
PolyTrait { trait_: path, generic_params: Vec::new() }
@@ -1774,11 +1781,13 @@ pub(crate) fn clean_middle_ty<'tcx>(
17741781
.projection_bounds()
17751782
.map(|pb| TypeBinding {
17761783
assoc: projection_to_path_segment(
1777-
pb.skip_binder()
1778-
// HACK(compiler-errors): Doesn't actually matter what self
1779-
// type we put here, because we're only using the GAT's substs.
1780-
.with_self_ty(cx.tcx, cx.tcx.types.self_param)
1781-
.projection_ty,
1784+
pb.map_bound(|pb| {
1785+
pb
1786+
// HACK(compiler-errors): Doesn't actually matter what self
1787+
// type we put here, because we're only using the GAT's substs.
1788+
.with_self_ty(cx.tcx, cx.tcx.types.self_param)
1789+
.projection_ty
1790+
}),
17821791
cx,
17831792
),
17841793
kind: TypeBindingKind::Equality {
@@ -1883,7 +1892,10 @@ fn clean_middle_opaque_bounds<'tcx>(
18831892
{
18841893
if proj.projection_ty.trait_ref(cx.tcx) == trait_ref.skip_binder() {
18851894
Some(TypeBinding {
1886-
assoc: projection_to_path_segment(proj.projection_ty, cx),
1895+
assoc: projection_to_path_segment(
1896+
bound.kind().rebind(proj.projection_ty),
1897+
cx,
1898+
),
18871899
kind: TypeBindingKind::Equality {
18881900
term: clean_middle_term(bound.kind().rebind(proj.term), cx),
18891901
},

src/librustdoc/clean/types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1343,7 +1343,7 @@ pub(crate) enum GenericBound {
13431343
impl GenericBound {
13441344
pub(crate) fn maybe_sized(cx: &mut DocContext<'_>) -> GenericBound {
13451345
let did = cx.tcx.require_lang_item(LangItem::Sized, None);
1346-
let empty = cx.tcx.intern_substs(&[]);
1346+
let empty = ty::Binder::dummy(ty::InternalSubsts::empty());
13471347
let path = external_path(cx, did, false, ThinVec::new(), empty);
13481348
inline::record_extern_fqn(cx, did, ItemType::Trait);
13491349
GenericBound::TraitBound(

src/librustdoc/clean/utils.rs

+19-10
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,16 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
7878

7979
pub(crate) fn substs_to_args<'tcx>(
8080
cx: &mut DocContext<'tcx>,
81-
substs: &[ty::subst::GenericArg<'tcx>],
81+
substs: ty::Binder<'tcx, &[ty::subst::GenericArg<'tcx>]>,
8282
mut skip_first: bool,
8383
) -> Vec<GenericArg> {
8484
let mut ret_val =
85-
Vec::with_capacity(substs.len().saturating_sub(if skip_first { 1 } else { 0 }));
86-
ret_val.extend(substs.iter().filter_map(|kind| match kind.unpack() {
85+
Vec::with_capacity(substs.skip_binder().len().saturating_sub(if skip_first {
86+
1
87+
} else {
88+
0
89+
}));
90+
ret_val.extend(substs.iter().filter_map(|kind| match kind.skip_binder().unpack() {
8791
GenericArgKind::Lifetime(lt) => {
8892
Some(GenericArg::Lifetime(clean_middle_region(lt).unwrap_or(Lifetime::elided())))
8993
}
@@ -92,10 +96,10 @@ pub(crate) fn substs_to_args<'tcx>(
9296
None
9397
}
9498
GenericArgKind::Type(ty) => {
95-
Some(GenericArg::Type(clean_middle_ty(ty::Binder::dummy(ty), cx, None)))
99+
Some(GenericArg::Type(clean_middle_ty(kind.rebind(ty), cx, None)))
96100
}
97101
GenericArgKind::Const(ct) => {
98-
Some(GenericArg::Const(Box::new(clean_middle_const(ty::Binder::dummy(ct), cx))))
102+
Some(GenericArg::Const(Box::new(clean_middle_const(kind.rebind(ct), cx))))
99103
}
100104
}));
101105
ret_val
@@ -106,15 +110,20 @@ fn external_generic_args<'tcx>(
106110
did: DefId,
107111
has_self: bool,
108112
bindings: ThinVec<TypeBinding>,
109-
substs: SubstsRef<'tcx>,
113+
substs: ty::Binder<'tcx, SubstsRef<'tcx>>,
110114
) -> GenericArgs {
111-
let args = substs_to_args(cx, substs, has_self);
115+
let args = substs_to_args(cx, substs.map_bound(|substs| &substs[..]), has_self);
112116

113117
if cx.tcx.fn_trait_kind_from_def_id(did).is_some() {
118+
let ty = substs
119+
.iter()
120+
.nth(if has_self { 1 } else { 0 })
121+
.unwrap()
122+
.map_bound(|arg| arg.expect_ty());
114123
let inputs =
115124
// The trait's first substitution is the one after self, if there is one.
116-
match substs.iter().nth(if has_self { 1 } else { 0 }).unwrap().expect_ty().kind() {
117-
ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(ty::Binder::dummy(t), cx, None)).collect::<Vec<_>>().into(),
125+
match ty.skip_binder().kind() {
126+
ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(ty.rebind(t), cx, None)).collect::<Vec<_>>().into(),
118127
_ => return GenericArgs::AngleBracketed { args: args.into(), bindings },
119128
};
120129
let output = bindings.into_iter().next().and_then(|binding| match binding.kind {
@@ -134,7 +143,7 @@ pub(super) fn external_path<'tcx>(
134143
did: DefId,
135144
has_self: bool,
136145
bindings: ThinVec<TypeBinding>,
137-
substs: SubstsRef<'tcx>,
146+
substs: ty::Binder<'tcx, SubstsRef<'tcx>>,
138147
) -> Path {
139148
let def_kind = cx.tcx.def_kind(did);
140149
let name = cx.tcx.item_name(did);

0 commit comments

Comments
 (0)