Skip to content

Commit 2377661

Browse files
Remap explicit item bounds of RPITIT's opaque back to ty::Opaque
1 parent a8be6e0 commit 2377661

File tree

3 files changed

+47
-27
lines changed

3 files changed

+47
-27
lines changed

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

+46-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::astconv::{AstConv, PredicateFilter};
33
use rustc_hir as hir;
44
use rustc_infer::traits::util;
55
use rustc_middle::ty::GenericArgs;
6-
use rustc_middle::ty::{self, Ty, TyCtxt};
6+
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder};
77
use rustc_span::def_id::{DefId, LocalDefId};
88
use rustc_span::Span;
99

@@ -113,14 +113,35 @@ pub(super) fn explicit_item_bounds(
113113
..
114114
}) => associated_type_bounds(tcx, def_id, bounds, *span),
115115
hir::Node::Item(hir::Item {
116-
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }),
116+
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: false, .. }),
117117
span,
118118
..
119119
}) => {
120120
let args = GenericArgs::identity_for_item(tcx, def_id);
121121
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
122122
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span)
123123
}
124+
// Since RPITITs are astconv'd as projections in `ast_ty_to_ty`, when we're asking
125+
// for the item bounds of the *opaques* in a trait's default method signature, we
126+
// need to map these projections back to opaques.
127+
hir::Node::Item(hir::Item {
128+
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: true, origin, .. }),
129+
span,
130+
..
131+
}) => {
132+
let (hir::OpaqueTyOrigin::FnReturn(fn_def_id)
133+
| hir::OpaqueTyOrigin::AsyncFn(fn_def_id)) = *origin
134+
else {
135+
bug!()
136+
};
137+
let args = GenericArgs::identity_for_item(tcx, def_id);
138+
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
139+
tcx.arena.alloc_slice(
140+
&opaque_type_bounds(tcx, def_id, bounds, item_ty, *span)
141+
.to_vec()
142+
.fold_with(&mut AssocTyToOpaque { tcx, fn_def_id: fn_def_id.to_def_id() }),
143+
)
144+
}
124145
hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],
125146
_ => bug!("item_bounds called on {:?}", def_id),
126147
};
@@ -135,3 +156,26 @@ pub(super) fn item_bounds(
135156
tcx.mk_clauses_from_iter(util::elaborate(tcx, bounds.iter().map(|&(bound, _span)| bound)))
136157
})
137158
}
159+
160+
struct AssocTyToOpaque<'tcx> {
161+
tcx: TyCtxt<'tcx>,
162+
fn_def_id: DefId,
163+
}
164+
165+
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTyToOpaque<'tcx> {
166+
fn interner(&self) -> TyCtxt<'tcx> {
167+
self.tcx
168+
}
169+
170+
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
171+
if let ty::Alias(ty::Projection, projection_ty) = ty.kind()
172+
&& let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. })
173+
= self.tcx.opt_rpitit_info(projection_ty.def_id)
174+
&& fn_def_id == self.fn_def_id
175+
{
176+
self.tcx.type_of(projection_ty.def_id).instantiate(self.tcx, projection_ty.args)
177+
} else {
178+
ty
179+
}
180+
}
181+
}

tests/ui/impl-trait/in-trait/default-body-with-rpit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// edition:2021
2-
// known-bug: #108304
2+
// check-pass
33

44
#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)]
55
#![allow(incomplete_features)]

tests/ui/impl-trait/in-trait/default-body-with-rpit.stderr

-24
This file was deleted.

0 commit comments

Comments
 (0)