Skip to content

Commit 1eee039

Browse files
committed
update comment for RPITIT projections
1 parent e2ea771 commit 1eee039

File tree

1 file changed

+22
-15
lines changed

1 file changed

+22
-15
lines changed

compiler/rustc_ty_utils/src/opaque_types.rs

+22-15
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
5454
self.span = old;
5555
}
5656

57-
fn parent_trait_ref(&self) -> Option<ty::TraitRef<'tcx>> {
57+
fn parent_impl_trait_ref(&self) -> Option<ty::TraitRef<'tcx>> {
5858
let parent = self.parent()?;
5959
if matches!(self.tcx.def_kind(parent), DefKind::Impl { .. }) {
6060
Some(self.tcx.impl_trait_ref(parent)?.instantiate_identity())
@@ -217,26 +217,15 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
217217
.instantiate(self.tcx, alias_ty.args)
218218
.visit_with(self);
219219
}
220-
// RPITIT are encoded as projections, not opaque types, make sure to handle these special
221-
// projections independently of the projection handling below.
222-
ty::Alias(ty::Projection, alias_ty)
223-
if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) =
224-
self.tcx.opt_rpitit_info(alias_ty.def_id)
225-
&& fn_def_id == self.item.into() =>
226-
{
227-
let ty = self.tcx.type_of(alias_ty.def_id).instantiate(self.tcx, alias_ty.args);
228-
let ty::Alias(ty::Opaque, alias_ty) = ty.kind() else { bug!("{ty:?}") };
229-
self.visit_opaque_ty(alias_ty);
230-
}
231220
ty::Alias(ty::Projection, alias_ty) => {
232221
// This avoids having to do normalization of `Self::AssocTy` by only
233222
// supporting the case of a method defining opaque types from assoc types
234223
// in the same impl block.
235-
if let Some(parent_trait_ref) = self.parent_trait_ref() {
224+
if let Some(impl_trait_ref) = self.parent_impl_trait_ref() {
236225
// If the trait ref of the associated item and the impl differs,
237226
// then we can't use the impl's identity args below, so
238227
// just skip.
239-
if alias_ty.trait_ref(self.tcx) == parent_trait_ref {
228+
if alias_ty.trait_ref(self.tcx) == impl_trait_ref {
240229
let parent = self.parent().expect("we should have a parent here");
241230

242231
for &assoc in self.tcx.associated_items(parent).in_definition_order() {
@@ -253,7 +242,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
253242

254243
let impl_args = alias_ty.args.rebase_onto(
255244
self.tcx,
256-
parent_trait_ref.def_id,
245+
impl_trait_ref.def_id,
257246
ty::GenericArgs::identity_for_item(self.tcx, parent),
258247
);
259248

@@ -271,6 +260,24 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
271260
}
272261
}
273262
}
263+
} else if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) =
264+
self.tcx.opt_rpitit_info(alias_ty.def_id)
265+
&& fn_def_id == self.item.into()
266+
{
267+
// RPITIT in trait definitions get desugared to an associated type. For
268+
// default methods we also create an opaque type this associated type
269+
// normalizes to. The associated type is only known to normalize to the
270+
// opaque if it is fully concrete. There could otherwise be an impl
271+
// overwriting the default method.
272+
//
273+
// However, we have to be able to normalize the associated type while inside
274+
// of the default method. This is normally handled by adding an unchecked
275+
// `Projection(<Self as Trait>::synthetic_assoc_ty, trait_def::opaque)`
276+
// assumption to the `param_env` of the default method. We also separately
277+
// rely on that assumption here.
278+
let ty = self.tcx.type_of(alias_ty.def_id).instantiate(self.tcx, alias_ty.args);
279+
let ty::Alias(ty::Opaque, alias_ty) = ty.kind() else { bug!("{ty:?}") };
280+
self.visit_opaque_ty(alias_ty);
274281
}
275282
}
276283
ty::Adt(def, _) if def.did().is_local() => {

0 commit comments

Comments
 (0)