Skip to content

Commit

Permalink
Deeply normalize when computing implied outlives bounds
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Dec 2, 2024
1 parent d49be02 commit abfa5c1
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 4 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl<'tcx> At<'_, 'tcx> {
let value = self
.normalize(value)
.into_value_registering_obligations(self.infcx, &mut *fulfill_cx);
let errors = fulfill_cx.select_where_possible(self.infcx);
let errors = fulfill_cx.select_all_or_error(self.infcx);
let value = self.infcx.resolve_vars_if_possible(value);
if errors.is_empty() { Ok(value) } else { Err(errors) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,13 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
param_env: ty::ParamEnv<'tcx>,
ty: Ty<'tcx>,
) -> Result<Vec<OutlivesBound<'tcx>>, NoSolution> {
let normalize_op = |ty| {
let ty = ocx.normalize(&ObligationCause::dummy(), param_env, ty);
let normalize_op = |ty| -> Result<_, NoSolution> {
let ty = ocx
.deeply_normalize(&ObligationCause::dummy(), param_env, ty)
.map_err(|_| NoSolution)?;
if !ocx.select_all_or_error().is_empty() {
return Err(NoSolution);
}
let ty = ocx.infcx.resolve_vars_if_possible(ty);
let ty = OpportunisticRegionResolver::new(&ocx.infcx).fold_ty(ty);
Ok(ty)
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//@ check-pass
//@ compile-flags: -Znext-solver

// Minimized example from `rustc_type_ir` that demonstrates a missing deep normalization
// in the new solver when computing the implies outlives bounds of an impl.

use std::marker::PhantomData;
use std::ops::Deref;

pub struct SearchGraph<D: Delegate, X = <D as Delegate>::Cx> {
d: PhantomData<D>,
x: PhantomData<X>,
}

pub trait Delegate {
type Cx;
}

struct SearchGraphDelegate<D: SolverDelegate> {
_marker: PhantomData<D>,
}

impl<D> Delegate for SearchGraphDelegate<D>
where
D: SolverDelegate,
{
type Cx = D::Interner;
}

pub trait SolverDelegate {
type Interner;
}

struct EvalCtxt<'a, D, I>
where
D: SolverDelegate<Interner = I>,
{
search_graph: &'a SearchGraph<SearchGraphDelegate<D>>,
}

impl<'a, D, I> EvalCtxt<'a, D, <D as SolverDelegate>::Interner>
where
D: SolverDelegate<Interner = I>
{}

fn main() {}

0 comments on commit abfa5c1

Please sign in to comment.