Skip to content

Commit 9526c0c

Browse files
committed
Avoid trait_ref when lowering ExistentialProjections
1 parent 0bf1d73 commit 9526c0c

File tree

2 files changed

+44
-36
lines changed
  • compiler

2 files changed

+44
-36
lines changed

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,12 +1477,11 @@ impl<'tcx> ExistentialProjection<'tcx> {
14771477
/// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`,
14781478
/// then this function would return a `exists T. T: Iterator` existential trait
14791479
/// reference.
1480-
pub fn trait_ref(&self, tcx: TyCtxt<'_>) -> ty::ExistentialTraitRef<'tcx> {
1481-
// FIXME(generic_associated_types): substs is the substs of the
1482-
// associated type, which should be truncated to get the correct substs
1483-
// for the trait.
1480+
pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> {
14841481
let def_id = tcx.associated_item(self.item_def_id).container.id();
1485-
ty::ExistentialTraitRef { def_id, substs: self.substs }
1482+
let subst_count = tcx.generics_of(def_id).count() - 1;
1483+
let substs = tcx.intern_substs(&self.substs[..subst_count]);
1484+
ty::ExistentialTraitRef { def_id, substs }
14861485
}
14871486

14881487
pub fn with_self_ty(
@@ -1501,6 +1500,20 @@ impl<'tcx> ExistentialProjection<'tcx> {
15011500
ty: self.ty,
15021501
}
15031502
}
1503+
1504+
pub fn erase_self_ty(
1505+
tcx: TyCtxt<'tcx>,
1506+
projection_predicate: ty::ProjectionPredicate<'tcx>,
1507+
) -> Self {
1508+
// Assert there is a Self.
1509+
projection_predicate.projection_ty.substs.type_at(0);
1510+
1511+
Self {
1512+
item_def_id: projection_predicate.projection_ty.item_def_id,
1513+
substs: tcx.intern_substs(&projection_predicate.projection_ty.substs[1..]),
1514+
ty: projection_predicate.ty,
1515+
}
1516+
}
15041517
}
15051518

15061519
impl<'tcx> PolyExistentialProjection<'tcx> {

compiler/rustc_typeck/src/astconv/mod.rs

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -985,10 +985,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
985985
//
986986
// We want to produce `<B as SuperTrait<i32>>::T == foo`.
987987

988-
debug!(
989-
"add_predicates_for_ast_type_binding(hir_ref_id {:?}, trait_ref {:?}, binding {:?}, bounds {:?}",
990-
hir_ref_id, trait_ref, binding, bounds
991-
);
988+
debug!(?hir_ref_id, ?trait_ref, ?binding, ?bounds, "add_predicates_for_ast_type_binding",);
992989
let tcx = self.tcx();
993990

994991
let candidate =
@@ -1326,37 +1323,35 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
13261323
debug!("regular_traits: {:?}", regular_traits);
13271324
debug!("auto_traits: {:?}", auto_traits);
13281325

1329-
// Transform a `PolyTraitRef` into a `PolyExistentialTraitRef` by
1330-
// removing the dummy `Self` type (`trait_object_dummy_self`).
1331-
let trait_ref_to_existential = |trait_ref: ty::TraitRef<'tcx>| {
1332-
if trait_ref.self_ty() != dummy_self {
1333-
// FIXME: There appears to be a missing filter on top of `expand_trait_aliases`,
1334-
// which picks up non-supertraits where clauses - but also, the object safety
1335-
// completely ignores trait aliases, which could be object safety hazards. We
1336-
// `delay_span_bug` here to avoid an ICE in stable even when the feature is
1337-
// disabled. (#66420)
1338-
tcx.sess.delay_span_bug(
1339-
DUMMY_SP,
1340-
&format!(
1341-
"trait_ref_to_existential called on {:?} with non-dummy Self",
1342-
trait_ref,
1343-
),
1344-
);
1345-
}
1346-
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
1347-
};
1348-
13491326
// Erase the `dummy_self` (`trait_object_dummy_self`) used above.
1350-
let existential_trait_refs =
1351-
regular_traits.iter().map(|i| i.trait_ref().map_bound(trait_ref_to_existential));
1327+
let existential_trait_refs = regular_traits.iter().map(|i| {
1328+
i.trait_ref().map_bound(|trait_ref: ty::TraitRef<'tcx>| {
1329+
if trait_ref.self_ty() != dummy_self {
1330+
// FIXME: There appears to be a missing filter on top of `expand_trait_aliases`,
1331+
// which picks up non-supertraits where clauses - but also, the object safety
1332+
// completely ignores trait aliases, which could be object safety hazards. We
1333+
// `delay_span_bug` here to avoid an ICE in stable even when the feature is
1334+
// disabled. (#66420)
1335+
tcx.sess.delay_span_bug(
1336+
DUMMY_SP,
1337+
&format!(
1338+
"trait_ref_to_existential called on {:?} with non-dummy Self",
1339+
trait_ref,
1340+
),
1341+
);
1342+
}
1343+
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
1344+
})
1345+
});
13521346
let existential_projections = bounds.projection_bounds.iter().map(|(bound, _)| {
13531347
bound.map_bound(|b| {
1354-
let trait_ref = trait_ref_to_existential(b.projection_ty.trait_ref(tcx));
1355-
ty::ExistentialProjection {
1356-
ty: b.ty,
1357-
item_def_id: b.projection_ty.item_def_id,
1358-
substs: trait_ref.substs,
1348+
if b.projection_ty.self_ty() != dummy_self {
1349+
tcx.sess.delay_span_bug(
1350+
DUMMY_SP,
1351+
&format!("trait_ref_to_existential called on {:?} with non-dummy Self", b),
1352+
);
13591353
}
1354+
ty::ExistentialProjection::erase_self_ty(tcx, b)
13601355
})
13611356
});
13621357

0 commit comments

Comments
 (0)