about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs15
-rw-r--r--src/test/ui/consts/unnormalized-param-env.rs31
2 files changed, 44 insertions, 2 deletions
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<const N: usize> {
+    type Traj;
+}
+
+pub struct Const<const R: usize>;
+
+pub trait Obstacle<CS, const N: usize> {
+    fn trajectory_free<FT, S1>(&self, t: &FT)
+    where
+        CS::Traj: Sized,
+        CS: CSpace<N>;
+}
+
+// -----
+
+const N: usize = 4;
+
+struct ObstacleSpace2df32;
+
+impl<CS> Obstacle<CS, N> for ObstacleSpace2df32 {
+    fn trajectory_free<TF, S1>(&self, t: &TF)
+    where
+        CS::Traj: Sized,
+        CS: CSpace<N>,
+    {
+    }
+}
+
+fn main() {}