diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index cdb618e030a..b25b4bd4fe3 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -574,8 +574,8 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( /// it. pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( relation: &mut R, - a: ty::Const<'tcx>, - b: ty::Const<'tcx>, + mut a: ty::Const<'tcx>, + mut b: ty::Const<'tcx>, ) -> RelateResult<'tcx, ty::Const<'tcx>> { debug!("{}.super_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b); let tcx = relation.tcx(); @@ -596,6 +596,17 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( ); } + // HACK(const_generics): We still need to eagerly evaluate consts when + // relating them because during `normalize_param_env_or_error`, + // we may relate an evaluated constant in a obligation against + // an unnormalized (i.e. unevaluated) const in the param-env. + // FIXME(generic_const_exprs): Once we always lazily unify unevaluated constants + // these `eval` calls can be removed. + if !relation.tcx().features().generic_const_exprs { + a = a.eval(tcx, relation.param_env()); + b = b.eval(tcx, relation.param_env()); + } + // Currently, the values that can be unified are primitive types, // and those that derive both `PartialEq` and `Eq`, corresponding // to structural-match types. diff --git a/src/test/ui/consts/unnormalized-param-env.rs b/src/test/ui/consts/unnormalized-param-env.rs new file mode 100644 index 00000000000..a7bbe4db992 --- /dev/null +++ b/src/test/ui/consts/unnormalized-param-env.rs @@ -0,0 +1,31 @@ +// check-pass + +pub trait CSpace { + type Traj; +} + +pub struct Const; + +pub trait Obstacle { + fn trajectory_free(&self, t: &FT) + where + CS::Traj: Sized, + CS: CSpace; +} + +// ----- + +const N: usize = 4; + +struct ObstacleSpace2df32; + +impl Obstacle for ObstacleSpace2df32 { + fn trajectory_free(&self, t: &TF) + where + CS::Traj: Sized, + CS: CSpace, + { + } +} + +fn main() {}