about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBastian Kauschke <bastian_kauschke@hotmail.de>2020-12-02 14:33:26 +0100
committerBastian Kauschke <bastian_kauschke@hotmail.de>2020-12-02 15:31:27 +0100
commit71d75503506880efa89c902465cdcb205d0eb9e5 (patch)
treed654ca21cc5a6c58285bdfe628b8191dd3c5c06b
parent92e4fb073245a42559e357a3002c596b8b38edf6 (diff)
downloadrust-71d75503506880efa89c902465cdcb205d0eb9e5.tar.gz
rust-71d75503506880efa89c902465cdcb205d0eb9e5.zip
const_evaluatable_checked: fix occurs check
-rw-r--r--compiler/rustc_infer/src/infer/combine.rs16
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs6
-rw-r--r--src/test/ui/const-generics/occurs-check/unused-substs-5.rs20
-rw-r--r--src/test/ui/const-generics/occurs-check/unused-substs-5.stderr12
4 files changed, 52 insertions, 2 deletions
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs
index 6a1715ef818..594e2c6205f 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/combine.rs
@@ -543,6 +543,10 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
         true
     }
 
+    fn visit_ct_substs(&self) -> bool {
+        true
+    }
+
     fn binders<T>(
         &mut self,
         a: ty::Binder<T>,
@@ -716,7 +720,10 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
                 let variable_table = &mut inner.const_unification_table();
                 let var_value = variable_table.probe_value(vid);
                 match var_value.val {
-                    ConstVariableValue::Known { value: u } => self.relate(u, u),
+                    ConstVariableValue::Known { value: u } => {
+                        drop(inner);
+                        self.relate(u, u)
+                    }
                     ConstVariableValue::Unknown { universe } => {
                         if self.for_universe.can_name(universe) {
                             Ok(c)
@@ -815,6 +822,10 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
         true
     }
 
+    fn visit_ct_substs(&self) -> bool {
+        true
+    }
+
     fn relate_with_variance<T: Relate<'tcx>>(
         &mut self,
         _variance: ty::Variance,
@@ -870,6 +881,9 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
                     }
                 }
             }
+            ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => {
+                Ok(t)
+            }
             _ => relate::super_relate_tys(self, t, t),
         }
     }
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index ef5034e218d..80dc7d89d18 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -33,6 +33,10 @@ pub trait TypeRelation<'tcx>: Sized {
     /// relation. Just affects error messages.
     fn a_is_expected(&self) -> bool;
 
+    fn visit_ct_substs(&self) -> bool {
+        false
+    }
+
     fn with_cause<F, R>(&mut self, _cause: Cause, f: F) -> R
     where
         F: FnOnce(&mut Self) -> R,
@@ -579,7 +583,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
         (
             ty::ConstKind::Unevaluated(a_def, a_substs, None),
             ty::ConstKind::Unevaluated(b_def, b_substs, None),
-        ) if tcx.features().const_evaluatable_checked => {
+        ) if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() => {
             if tcx.try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs))) {
                 Ok(a.val)
             } else {
diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-5.rs b/src/test/ui/const-generics/occurs-check/unused-substs-5.rs
new file mode 100644
index 00000000000..e5d487d89b9
--- /dev/null
+++ b/src/test/ui/const-generics/occurs-check/unused-substs-5.rs
@@ -0,0 +1,20 @@
+#![feature(const_generics, const_evaluatable_checked)]
+#![allow(incomplete_features)]
+
+// `N + 1` also depends on `T` here even if it doesn't use it.
+fn q<T, const N: usize>(_: T) -> [u8; N + 1] {
+    todo!()
+}
+
+fn supplier<T>() -> T {
+    todo!()
+}
+
+fn catch_me<const N: usize>() where [u8; N + 1]: Default {
+    let mut x = supplier();
+    x = q::<_, N>(x); //~ ERROR mismatched types
+}
+
+fn main() {
+    catch_me::<3>();
+}
diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr
new file mode 100644
index 00000000000..239569dab09
--- /dev/null
+++ b/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/unused-substs-5.rs:15:9
+   |
+LL |     x = q::<_, N>(x);
+   |         ^^^^^^^^^^^^
+   |         |
+   |         cyclic type of infinite size
+   |         help: try using a conversion method: `q::<_, N>(x).to_vec()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.