diff options
| author | Michael Goulet <michael@errs.io> | 2023-03-15 22:55:00 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-03-16 01:56:49 +0000 |
| commit | 0949da8f4e309ac5e5035250bd662dfdbd5c32b4 (patch) | |
| tree | d4143cf7115dc3a2667551d13f6b56a813052c2c | |
| parent | c5c43407603599f4ff2b217cc09be2cc5f39967d (diff) | |
| download | rust-0949da8f4e309ac5e5035250bd662dfdbd5c32b4.tar.gz rust-0949da8f4e309ac5e5035250bd662dfdbd5c32b4.zip | |
Install projection from RPITIT to default trait method opaque correctly
| -rw-r--r-- | compiler/rustc_hir_analysis/src/collect/item_bounds.rs | 36 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/ty.rs | 17 | ||||
| -rw-r--r-- | tests/ui/async-await/in-trait/async-default-fn-overridden.current.stderr (renamed from tests/ui/async-await/in-trait/async-default-fn-overridden.stderr) | 2 | ||||
| -rw-r--r-- | tests/ui/async-await/in-trait/async-default-fn-overridden.next.stderr | 11 | ||||
| -rw-r--r-- | tests/ui/async-await/in-trait/async-default-fn-overridden.rs | 2 | ||||
| -rw-r--r-- | tests/ui/impl-trait/in-trait/default-method-constraint.current.stderr (renamed from tests/ui/impl-trait/in-trait/default-method-constraint.stderr) | 2 | ||||
| -rw-r--r-- | tests/ui/impl-trait/in-trait/default-method-constraint.next.stderr | 11 | ||||
| -rw-r--r-- | tests/ui/impl-trait/in-trait/default-method-constraint.rs | 2 |
8 files changed, 64 insertions, 19 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 7dce29cc0bb..df0258ff7a3 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; use rustc_hir as hir; use rustc_infer::traits::util; use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::{self, ImplTraitInTraitData, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::DefId; use rustc_span::Span; @@ -76,18 +76,26 @@ pub(super) fn explicit_item_bounds( tcx: TyCtxt<'_>, def_id: DefId, ) -> &'_ [(ty::Predicate<'_>, Span)] { - // If the def_id is about an RPITIT, delegate explicit_item_bounds to the opaque_def_id that - // generated the synthesized associate type. - let rpitit_info = if let Some(ImplTraitInTraitData::Trait { opaque_def_id, .. }) = - tcx.opt_rpitit_info(def_id) - { - Some(opaque_def_id) - } else { - None - }; + match tcx.opt_rpitit_info(def_id) { + // RPITIT's bounds are the same as opaque type bounds, but with + // a projection self type. + Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => { + let item = tcx.hir().get_by_def_id(opaque_def_id.expect_local()).expect_item(); + let opaque_ty = item.expect_opaque_ty(); + return opaque_type_bounds( + tcx, + opaque_def_id, + opaque_ty.bounds, + tcx.mk_projection(def_id, ty::InternalSubsts::identity_for_item(tcx, def_id)), + item.span, + ); + } + // These should have been fed! + Some(ty::ImplTraitInTraitData::Impl { .. }) => unreachable!(), + None => {} + } - let bounds_def_id = rpitit_info.unwrap_or(def_id); - let hir_id = tcx.hir().local_def_id_to_hir_id(bounds_def_id.expect_local()); + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); match tcx.hir().get(hir_id) { hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(bounds, _), @@ -100,12 +108,12 @@ pub(super) fn explicit_item_bounds( .. }) => { let substs = InternalSubsts::identity_for_item(tcx, def_id); - let item_ty = if *in_trait || rpitit_info.is_some() { + let item_ty = if *in_trait && !tcx.lower_impl_trait_in_trait_to_assoc_ty() { tcx.mk_projection(def_id, substs) } else { tcx.mk_opaque(def_id, substs) }; - opaque_type_bounds(tcx, bounds_def_id, bounds, item_ty, *span) + opaque_type_bounds(tcx, def_id, bounds, item_ty, *span) } _ => bug!("item_bounds called on {:?}", def_id), } diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index ad05b68f1b4..df4b8543ba6 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -268,8 +268,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> { fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> { if let ty::Alias(ty::Projection, alias_ty) = *ty.kind() - // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) need to project to the opaque, could - // get it via type_of + subst. && self.tcx.is_impl_trait_in_trait(alias_ty.def_id) && self.tcx.impl_trait_in_trait_parent_fn(alias_ty.def_id) == self.fn_def_id && self.seen.insert(alias_ty.def_id) @@ -284,11 +282,24 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> { re } }); + + // If we're lowering to associated item, install the opaque type which is just + // the `type_of` of the trait's associated item. If we're using the old lowering + // strategy, then just reinterpret the associated type like an opaque :^) + let default_ty = if self.tcx.lower_impl_trait_in_trait_to_assoc_ty() { + self + .tcx + .type_of(alias_ty.def_id) + .subst(self.tcx, alias_ty.substs) + } else { + self.tcx.mk_alias(ty::Opaque, alias_ty) + }; + self.predicates.push( ty::Binder::bind_with_vars( ty::ProjectionPredicate { projection_ty: alias_ty, - term: self.tcx.mk_alias(ty::Opaque, alias_ty).into(), + term: default_ty.into(), }, self.bound_vars, ) diff --git a/tests/ui/async-await/in-trait/async-default-fn-overridden.stderr b/tests/ui/async-await/in-trait/async-default-fn-overridden.current.stderr index 61a826258d0..2142ee232ca 100644 --- a/tests/ui/async-await/in-trait/async-default-fn-overridden.stderr +++ b/tests/ui/async-await/in-trait/async-default-fn-overridden.current.stderr @@ -1,5 +1,5 @@ warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/async-default-fn-overridden.rs:4:12 + --> $DIR/async-default-fn-overridden.rs:6:12 | LL | #![feature(async_fn_in_trait)] | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/async-await/in-trait/async-default-fn-overridden.next.stderr b/tests/ui/async-await/in-trait/async-default-fn-overridden.next.stderr new file mode 100644 index 00000000000..2142ee232ca --- /dev/null +++ b/tests/ui/async-await/in-trait/async-default-fn-overridden.next.stderr @@ -0,0 +1,11 @@ +warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/async-default-fn-overridden.rs:6:12 + | +LL | #![feature(async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/async-await/in-trait/async-default-fn-overridden.rs b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs index 0fd1a2703db..dd1af93d706 100644 --- a/tests/ui/async-await/in-trait/async-default-fn-overridden.rs +++ b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs @@ -1,5 +1,7 @@ // run-pass // edition:2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] //~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use diff --git a/tests/ui/impl-trait/in-trait/default-method-constraint.stderr b/tests/ui/impl-trait/in-trait/default-method-constraint.current.stderr index 5e18605aa4c..7bb79911f56 100644 --- a/tests/ui/impl-trait/in-trait/default-method-constraint.stderr +++ b/tests/ui/impl-trait/in-trait/default-method-constraint.current.stderr @@ -1,5 +1,5 @@ warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default-method-constraint.rs:5:12 + --> $DIR/default-method-constraint.rs:7:12 | LL | #![feature(return_position_impl_trait_in_trait)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/in-trait/default-method-constraint.next.stderr b/tests/ui/impl-trait/in-trait/default-method-constraint.next.stderr new file mode 100644 index 00000000000..7bb79911f56 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/default-method-constraint.next.stderr @@ -0,0 +1,11 @@ +warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/default-method-constraint.rs:7:12 + | +LL | #![feature(return_position_impl_trait_in_trait)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/impl-trait/in-trait/default-method-constraint.rs b/tests/ui/impl-trait/in-trait/default-method-constraint.rs index 8c50cc29586..e85fe3c8626 100644 --- a/tests/ui/impl-trait/in-trait/default-method-constraint.rs +++ b/tests/ui/impl-trait/in-trait/default-method-constraint.rs @@ -1,4 +1,6 @@ // check-pass +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next // This didn't work in the previous default RPITIT method hack attempt |
