From 75e15f7cf4e55ed9572781930ee8babcaa256a47 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 28 Feb 2024 16:09:06 +0000 Subject: [PATCH] Deeply normalize obligations in refining_impl_trait --- .../src/check/compare_impl_item/refine.rs | 14 ++++++++----- .../src/traits/engine.rs | 9 +++++++++ .../impl-trait/in-trait/refine-normalize.rs | 20 +++++++++++++++++++ 3 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 tests/ui/impl-trait/in-trait/refine-normalize.rs diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index b5e69b8e3766e..29dc434ab4532 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -136,11 +136,15 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>( // 1. Project the RPITIT projections from the trait to the opaques on the impl, // which means that they don't need to be mapped manually. // - // 2. Project any other projections that show up in the bound. That makes sure that - // we don't consider `tests/ui/async-await/in-trait/async-associated-types.rs` - // to be refining. - let (trait_bounds, impl_bounds) = - ocx.normalize(&ObligationCause::dummy(), param_env, (trait_bounds, impl_bounds)); + // 2. Deeply normalize any other projections that show up in the bound. That makes sure + // that we don't consider `tests/ui/async-await/in-trait/async-associated-types.rs` + // or `tests/ui/impl-trait/in-trait/refine-normalize.rs` to be refining. + let Ok((trait_bounds, impl_bounds)) = + ocx.deeply_normalize(&ObligationCause::dummy(), param_env, (trait_bounds, impl_bounds)) + else { + tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (selection)"); + return; + }; // Since we've normalized things, we need to resolve regions, since we'll // possibly have introduced region vars during projection. We don't expect diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 1aaadf6cf044a..e789e9c2b6e16 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -107,6 +107,15 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { self.register_infer_ok_obligations(infer_ok) } + pub fn deeply_normalize>>( + &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + value: T, + ) -> Result>> { + self.infcx.at(cause, param_env).deeply_normalize(value, &mut **self.engine.borrow_mut()) + } + /// Makes `expected <: actual`. pub fn eq_exp( &self, diff --git a/tests/ui/impl-trait/in-trait/refine-normalize.rs b/tests/ui/impl-trait/in-trait/refine-normalize.rs new file mode 100644 index 0000000000000..95f2cda6a7495 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/refine-normalize.rs @@ -0,0 +1,20 @@ +//@ check-pass +//@ edition: 2021 +//@ revisions: current next +//@[next] compile-flags: -Znext-solver + +#![deny(refining_impl_trait)] + +pub trait Foo { + type Item; + + fn hello() -> impl Iterator; +} + +impl Foo for () { + type Item = (); + + fn hello() -> impl Iterator { [()].into_iter() } +} + +fn main() {}