Skip to content
/ rust Public
forked from rust-lang/rust

Commit

Permalink
Rollup merge of rust-lang#121745 - compiler-errors:refining-impl-trai…
Browse files Browse the repository at this point in the history
…t-deeply-norm, r=lcnr

Deeply normalize obligations in `refining_impl_trait`

We somewhat awkwardly use semantic comparison when checking the `refining_impl_trait` lint. This relies on us being able to normalize bounds eagerly to avoid cases where an unnormalized alias is not considered equal to a normalized alias. Since `normalize` in the new solver is a noop, let's use `deeply_normalize` instead.

r? lcnr

cc `@tmandry,` this should fix your bug lol
  • Loading branch information
jhpratt committed Feb 29, 2024
2 parents 4010270 + 75e15f7 commit d9becfb
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_trait_selection/src/traits/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,15 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
self.register_infer_ok_obligations(infer_ok)
}

pub fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>(
&self,
cause: &ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
value: T,
) -> Result<T, Vec<FulfillmentError<'tcx>>> {
self.infcx.at(cause, param_env).deeply_normalize(value, &mut **self.engine.borrow_mut())
}

/// Makes `expected <: actual`.
pub fn eq_exp<T>(
&self,
Expand Down
20 changes: 20 additions & 0 deletions tests/ui/impl-trait/in-trait/refine-normalize.rs
Original file line number Diff line number Diff line change
@@ -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<Item = Self::Item>;
}

impl Foo for () {
type Item = ();

fn hello() -> impl Iterator<Item = ()> { [()].into_iter() }
}

fn main() {}

0 comments on commit d9becfb

Please sign in to comment.