diff options
| author | Michael Goulet <michael@errs.io> | 2023-07-30 20:31:27 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-07-30 20:31:27 +0000 |
| commit | 23776619a84260536c3fbd39acbcf4c712736557 (patch) | |
| tree | 8cc1d1e05179a859e42a57619a277f2d50a080c6 | |
| parent | a8be6e070f02fca6e5ab851e10e29d45c3a0217c (diff) | |
| download | rust-23776619a84260536c3fbd39acbcf4c712736557.tar.gz rust-23776619a84260536c3fbd39acbcf4c712736557.zip | |
Remap explicit item bounds of RPITIT's opaque back to ty::Opaque
3 files changed, 47 insertions, 27 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 758e9dc7230..4b7743fae53 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -3,7 +3,7 @@ use crate::astconv::{AstConv, PredicateFilter}; use rustc_hir as hir; use rustc_infer::traits::util; use rustc_middle::ty::GenericArgs; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::Span; @@ -113,7 +113,7 @@ pub(super) fn explicit_item_bounds( .. }) => associated_type_bounds(tcx, def_id, bounds, *span), hir::Node::Item(hir::Item { - kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }), + kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: false, .. }), span, .. }) => { @@ -121,6 +121,27 @@ pub(super) fn explicit_item_bounds( let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args); opaque_type_bounds(tcx, def_id, bounds, item_ty, *span) } + // Since RPITITs are astconv'd as projections in `ast_ty_to_ty`, when we're asking + // for the item bounds of the *opaques* in a trait's default method signature, we + // need to map these projections back to opaques. + hir::Node::Item(hir::Item { + kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: true, origin, .. }), + span, + .. + }) => { + let (hir::OpaqueTyOrigin::FnReturn(fn_def_id) + | hir::OpaqueTyOrigin::AsyncFn(fn_def_id)) = *origin + else { + bug!() + }; + let args = GenericArgs::identity_for_item(tcx, def_id); + let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args); + tcx.arena.alloc_slice( + &opaque_type_bounds(tcx, def_id, bounds, item_ty, *span) + .to_vec() + .fold_with(&mut AssocTyToOpaque { tcx, fn_def_id: fn_def_id.to_def_id() }), + ) + } hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[], _ => bug!("item_bounds called on {:?}", def_id), }; @@ -135,3 +156,26 @@ pub(super) fn item_bounds( tcx.mk_clauses_from_iter(util::elaborate(tcx, bounds.iter().map(|&(bound, _span)| bound))) }) } + +struct AssocTyToOpaque<'tcx> { + tcx: TyCtxt<'tcx>, + fn_def_id: DefId, +} + +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTyToOpaque<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + if let ty::Alias(ty::Projection, projection_ty) = ty.kind() + && let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) + = self.tcx.opt_rpitit_info(projection_ty.def_id) + && fn_def_id == self.fn_def_id + { + self.tcx.type_of(projection_ty.def_id).instantiate(self.tcx, projection_ty.args) + } else { + ty + } + } +} diff --git a/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs b/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs index 0558d95128f..25133214dc6 100644 --- a/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs +++ b/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs @@ -1,5 +1,5 @@ // edition:2021 -// known-bug: #108304 +// check-pass #![feature(async_fn_in_trait, return_position_impl_trait_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/impl-trait/in-trait/default-body-with-rpit.stderr b/tests/ui/impl-trait/in-trait/default-body-with-rpit.stderr deleted file mode 100644 index b5fc9d44d36..00000000000 --- a/tests/ui/impl-trait/in-trait/default-body-with-rpit.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error: concrete type differs from previous defining opaque type use - --> $DIR/default-body-with-rpit.rs:11:9 - | -LL | "" - | ^^ expected `impl Debug`, got `&'static str` - | -note: previous use here - --> $DIR/default-body-with-rpit.rs:10:39 - | -LL | async fn baz(&self) -> impl Debug { - | _______________________________________^ -LL | | "" -LL | | } - | |_____^ - -error[E0720]: cannot resolve opaque type - --> $DIR/default-body-with-rpit.rs:10:28 - | -LL | async fn baz(&self) -> impl Debug { - | ^^^^^^^^^^ cannot resolve opaque type - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0720`. |
