Round 3: require binders for substs
This commit is contained in:
parent
8b098325ec
commit
21917b0866
@ -980,6 +980,7 @@ impl<'tcx, T> Binder<'tcx, T>
|
||||
/// contain any bound vars that would be bound by the
|
||||
/// binder. This is commonly used to 'inject' a value T into a
|
||||
/// different binding level.
|
||||
#[track_caller]
|
||||
pub fn dummy(value: T) -> Binder<'tcx, T> {
|
||||
assert!(!value.has_escaping_bound_vars());
|
||||
Binder(value, ty::List::empty())
|
||||
|
@ -165,7 +165,7 @@ pub(crate) fn clean_trait_ref_with_bindings<'tcx>(
|
||||
}
|
||||
inline::record_extern_fqn(cx, trait_ref.def_id(), kind);
|
||||
let path =
|
||||
external_path(cx, trait_ref.def_id(), true, bindings, trait_ref.skip_binder().substs);
|
||||
external_path(cx, trait_ref.def_id(), true, bindings, trait_ref.map_bound(|tr| tr.substs));
|
||||
|
||||
debug!(?trait_ref);
|
||||
|
||||
@ -437,7 +437,7 @@ fn clean_projection<'tcx>(
|
||||
};
|
||||
let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type);
|
||||
Type::QPath(Box::new(QPathData {
|
||||
assoc: projection_to_path_segment(ty.skip_binder(), cx),
|
||||
assoc: projection_to_path_segment(ty, cx),
|
||||
should_show_cast,
|
||||
self_type,
|
||||
trait_,
|
||||
@ -452,15 +452,16 @@ fn compute_should_show_cast(self_def_id: Option<DefId>, trait_: &Path, self_type
|
||||
}
|
||||
|
||||
fn projection_to_path_segment<'tcx>(
|
||||
ty: ty::ProjectionTy<'tcx>,
|
||||
ty: ty::Binder<'tcx, ty::ProjectionTy<'tcx>>,
|
||||
cx: &mut DocContext<'tcx>,
|
||||
) -> PathSegment {
|
||||
let item = cx.tcx.associated_item(ty.item_def_id);
|
||||
let generics = cx.tcx.generics_of(ty.item_def_id);
|
||||
let item = cx.tcx.associated_item(ty.skip_binder().item_def_id);
|
||||
let generics = cx.tcx.generics_of(ty.skip_binder().item_def_id);
|
||||
PathSegment {
|
||||
name: item.name,
|
||||
args: GenericArgs::AngleBracketed {
|
||||
args: substs_to_args(cx, &ty.substs[generics.parent_count..], false).into(),
|
||||
args: substs_to_args(cx, ty.map_bound(|ty| &ty.substs[generics.parent_count..]), false)
|
||||
.into(),
|
||||
bindings: Default::default(),
|
||||
},
|
||||
}
|
||||
@ -1732,12 +1733,18 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
||||
AdtKind::Enum => ItemType::Enum,
|
||||
};
|
||||
inline::record_extern_fqn(cx, did, kind);
|
||||
let path = external_path(cx, did, false, ThinVec::new(), substs);
|
||||
let path = external_path(cx, did, false, ThinVec::new(), bound_ty.rebind(substs));
|
||||
Type::Path { path }
|
||||
}
|
||||
ty::Foreign(did) => {
|
||||
inline::record_extern_fqn(cx, did, ItemType::ForeignType);
|
||||
let path = external_path(cx, did, false, ThinVec::new(), InternalSubsts::empty());
|
||||
let path = external_path(
|
||||
cx,
|
||||
did,
|
||||
false,
|
||||
ThinVec::new(),
|
||||
ty::Binder::dummy(InternalSubsts::empty()),
|
||||
);
|
||||
Type::Path { path }
|
||||
}
|
||||
ty::Dynamic(obj, ref reg, _) => {
|
||||
@ -1750,9 +1757,9 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
||||
.or_else(|| dids.next())
|
||||
.unwrap_or_else(|| panic!("found trait object `{bound_ty:?}` with no traits?"));
|
||||
let substs = match obj.principal() {
|
||||
Some(principal) => principal.skip_binder().substs,
|
||||
Some(principal) => principal.map_bound(|p| p.substs),
|
||||
// marker traits have no substs.
|
||||
_ => cx.tcx.intern_substs(&[]),
|
||||
_ => ty::Binder::dummy(InternalSubsts::empty()),
|
||||
};
|
||||
|
||||
inline::record_extern_fqn(cx, did, ItemType::Trait);
|
||||
@ -1763,7 +1770,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
||||
let lifetime = clean_middle_region(*reg);
|
||||
let mut bounds = dids
|
||||
.map(|did| {
|
||||
let empty = cx.tcx.intern_substs(&[]);
|
||||
let empty = ty::Binder::dummy(InternalSubsts::empty());
|
||||
let path = external_path(cx, did, false, ThinVec::new(), empty);
|
||||
inline::record_extern_fqn(cx, did, ItemType::Trait);
|
||||
PolyTrait { trait_: path, generic_params: Vec::new() }
|
||||
@ -1774,11 +1781,13 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
||||
.projection_bounds()
|
||||
.map(|pb| TypeBinding {
|
||||
assoc: projection_to_path_segment(
|
||||
pb.skip_binder()
|
||||
// HACK(compiler-errors): Doesn't actually matter what self
|
||||
// type we put here, because we're only using the GAT's substs.
|
||||
.with_self_ty(cx.tcx, cx.tcx.types.self_param)
|
||||
.projection_ty,
|
||||
pb.map_bound(|pb| {
|
||||
pb
|
||||
// HACK(compiler-errors): Doesn't actually matter what self
|
||||
// type we put here, because we're only using the GAT's substs.
|
||||
.with_self_ty(cx.tcx, cx.tcx.types.self_param)
|
||||
.projection_ty
|
||||
}),
|
||||
cx,
|
||||
),
|
||||
kind: TypeBindingKind::Equality {
|
||||
@ -1883,7 +1892,10 @@ fn clean_middle_opaque_bounds<'tcx>(
|
||||
{
|
||||
if proj.projection_ty.trait_ref(cx.tcx) == trait_ref.skip_binder() {
|
||||
Some(TypeBinding {
|
||||
assoc: projection_to_path_segment(proj.projection_ty, cx),
|
||||
assoc: projection_to_path_segment(
|
||||
bound.kind().rebind(proj.projection_ty),
|
||||
cx,
|
||||
),
|
||||
kind: TypeBindingKind::Equality {
|
||||
term: clean_middle_term(bound.kind().rebind(proj.term), cx),
|
||||
},
|
||||
|
@ -1343,7 +1343,7 @@ pub(crate) enum GenericBound {
|
||||
impl GenericBound {
|
||||
pub(crate) fn maybe_sized(cx: &mut DocContext<'_>) -> GenericBound {
|
||||
let did = cx.tcx.require_lang_item(LangItem::Sized, None);
|
||||
let empty = cx.tcx.intern_substs(&[]);
|
||||
let empty = ty::Binder::dummy(ty::InternalSubsts::empty());
|
||||
let path = external_path(cx, did, false, ThinVec::new(), empty);
|
||||
inline::record_extern_fqn(cx, did, ItemType::Trait);
|
||||
GenericBound::TraitBound(
|
||||
|
@ -78,12 +78,16 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
|
||||
|
||||
pub(crate) fn substs_to_args<'tcx>(
|
||||
cx: &mut DocContext<'tcx>,
|
||||
substs: &[ty::subst::GenericArg<'tcx>],
|
||||
substs: ty::Binder<'tcx, &[ty::subst::GenericArg<'tcx>]>,
|
||||
mut skip_first: bool,
|
||||
) -> Vec<GenericArg> {
|
||||
let mut ret_val =
|
||||
Vec::with_capacity(substs.len().saturating_sub(if skip_first { 1 } else { 0 }));
|
||||
ret_val.extend(substs.iter().filter_map(|kind| match kind.unpack() {
|
||||
Vec::with_capacity(substs.skip_binder().len().saturating_sub(if skip_first {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}));
|
||||
ret_val.extend(substs.iter().filter_map(|kind| match kind.skip_binder().unpack() {
|
||||
GenericArgKind::Lifetime(lt) => {
|
||||
Some(GenericArg::Lifetime(clean_middle_region(lt).unwrap_or(Lifetime::elided())))
|
||||
}
|
||||
@ -92,10 +96,10 @@ pub(crate) fn substs_to_args<'tcx>(
|
||||
None
|
||||
}
|
||||
GenericArgKind::Type(ty) => {
|
||||
Some(GenericArg::Type(clean_middle_ty(ty::Binder::dummy(ty), cx, None)))
|
||||
Some(GenericArg::Type(clean_middle_ty(kind.rebind(ty), cx, None)))
|
||||
}
|
||||
GenericArgKind::Const(ct) => {
|
||||
Some(GenericArg::Const(Box::new(clean_middle_const(ty::Binder::dummy(ct), cx))))
|
||||
Some(GenericArg::Const(Box::new(clean_middle_const(kind.rebind(ct), cx))))
|
||||
}
|
||||
}));
|
||||
ret_val
|
||||
@ -106,15 +110,20 @@ fn external_generic_args<'tcx>(
|
||||
did: DefId,
|
||||
has_self: bool,
|
||||
bindings: ThinVec<TypeBinding>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
substs: ty::Binder<'tcx, SubstsRef<'tcx>>,
|
||||
) -> GenericArgs {
|
||||
let args = substs_to_args(cx, substs, has_self);
|
||||
let args = substs_to_args(cx, substs.map_bound(|substs| &substs[..]), has_self);
|
||||
|
||||
if cx.tcx.fn_trait_kind_from_def_id(did).is_some() {
|
||||
let ty = substs
|
||||
.iter()
|
||||
.nth(if has_self { 1 } else { 0 })
|
||||
.unwrap()
|
||||
.map_bound(|arg| arg.expect_ty());
|
||||
let inputs =
|
||||
// The trait's first substitution is the one after self, if there is one.
|
||||
match substs.iter().nth(if has_self { 1 } else { 0 }).unwrap().expect_ty().kind() {
|
||||
ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(ty::Binder::dummy(t), cx, None)).collect::<Vec<_>>().into(),
|
||||
match ty.skip_binder().kind() {
|
||||
ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(ty.rebind(t), cx, None)).collect::<Vec<_>>().into(),
|
||||
_ => return GenericArgs::AngleBracketed { args: args.into(), bindings },
|
||||
};
|
||||
let output = bindings.into_iter().next().and_then(|binding| match binding.kind {
|
||||
@ -134,7 +143,7 @@ pub(super) fn external_path<'tcx>(
|
||||
did: DefId,
|
||||
has_self: bool,
|
||||
bindings: ThinVec<TypeBinding>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
substs: ty::Binder<'tcx, SubstsRef<'tcx>>,
|
||||
) -> Path {
|
||||
let def_kind = cx.tcx.def_kind(did);
|
||||
let name = cx.tcx.item_name(did);
|
||||
|
Loading…
Reference in New Issue
Block a user