about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBastian Kauschke <bastian_kauschke@hotmail.de>2021-01-24 20:08:12 +0100
committerlcnr <rust@lcnr.de>2021-03-27 16:38:23 +0100
commit42150fb8a12cae86ebee3a7734c2d14ed6b1d0a8 (patch)
tree10a92159d7197f7bb0e500faab3b042964dcc63c
parentaef11409b43a533f4e59ffb9b0efcb619c6e6879 (diff)
downloadrust-42150fb8a12cae86ebee3a7734c2d14ed6b1d0a8.tar.gz
rust-42150fb8a12cae86ebee3a7734c2d14ed6b1d0a8.zip
combine: stop eagerly evaluating consts
-rw-r--r--compiler/rustc_infer/src/infer/combine.rs28
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs11
-rw-r--r--src/test/ui/const-generics/issues/issue-69654-run-pass.rs2
-rw-r--r--src/test/ui/const-generics/issues/issue-69654-run-pass.stderr15
-rw-r--r--src/test/ui/const-generics/issues/issue-69654.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-69654.stderr17
-rw-r--r--src/test/ui/const-generics/occurs-check/unused-substs-1.rs3
-rw-r--r--src/test/ui/const-generics/occurs-check/unused-substs-1.stderr17
-rw-r--r--src/test/ui/const-generics/occurs-check/unused-substs-2.rs3
-rw-r--r--src/test/ui/const-generics/occurs-check/unused-substs-2.stderr9
-rw-r--r--src/test/ui/const-generics/occurs-check/unused-substs-3.rs3
-rw-r--r--src/test/ui/const-generics/occurs-check/unused-substs-3.stderr12
-rw-r--r--src/test/ui/const-generics/occurs-check/unused-substs-4.rs3
-rw-r--r--src/test/ui/const-generics/occurs-check/unused-substs-4.stderr9
14 files changed, 106 insertions, 27 deletions
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs
index 5e11932eafc..ffe947d209d 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/combine.rs
@@ -543,10 +543,6 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
         true
     }
 
-    fn visit_ct_substs(&self) -> bool {
-        true
-    }
-
     fn binders<T>(
         &mut self,
         a: ty::Binder<T>,
@@ -737,6 +733,16 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
                     }
                 }
             }
+            ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted })
+                if self.tcx().lazy_normalization() =>
+            {
+                assert_eq!(promoted, None);
+                let substs = self.relate_with_variance(ty::Variance::Invariant, substs, substs)?;
+                Ok(self.tcx().mk_const(ty::Const {
+                    ty: c.ty,
+                    val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }),
+                }))
+            }
             _ => relate::super_relate_consts(self, c, c),
         }
     }
@@ -822,10 +828,6 @@ 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,
@@ -959,6 +961,16 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
                     }
                 }
             }
+            ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted })
+                if self.tcx().lazy_normalization() =>
+            {
+                assert_eq!(promoted, None);
+                let substs = self.relate_with_variance(ty::Variance::Invariant, substs, substs)?;
+                Ok(self.tcx().mk_const(ty::Const {
+                    ty: c.ty,
+                    val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }),
+                }))
+            }
             _ => relate::super_relate_consts(self, c, c),
         }
     }
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index c936c30f456..32a713beef8 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -33,15 +33,6 @@ pub trait TypeRelation<'tcx>: Sized {
     /// relation. Just affects error messages.
     fn a_is_expected(&self) -> bool;
 
-    /// Whether we should look into the substs of unevaluated constants
-    /// even if `feature(const_evaluatable_checked)` is active.
-    ///
-    /// This is needed in `combine` to prevent accidentially creating
-    /// infinite types as we abuse `TypeRelation` to walk a type there.
-    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,
@@ -532,7 +523,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
         }
 
         (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
-            if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() =>
+            if tcx.features().const_evaluatable_checked =>
         {
             tcx.try_unify_abstract_consts(((au.def, au.substs), (bu.def, bu.substs)))
         }
diff --git a/src/test/ui/const-generics/issues/issue-69654-run-pass.rs b/src/test/ui/const-generics/issues/issue-69654-run-pass.rs
index bbfd2183b06..8c0398e8a13 100644
--- a/src/test/ui/const-generics/issues/issue-69654-run-pass.rs
+++ b/src/test/ui/const-generics/issues/issue-69654-run-pass.rs
@@ -1,4 +1,3 @@
-// run-pass
 #![feature(const_generics)]
 #![allow(incomplete_features, unused_braces)]
 
@@ -15,4 +14,5 @@ where
 
 fn main() {
     Foo::foo();
+    //~^ ERROR no function or associated item
 }
diff --git a/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr b/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr
new file mode 100644
index 00000000000..a95cc0f2a1c
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr
@@ -0,0 +1,15 @@
+error[E0599]: no function or associated item named `foo` found for struct `Foo<{_: usize}>` in the current scope
+  --> $DIR/issue-69654-run-pass.rs:16:10
+   |
+LL | struct Foo<const N: usize> {}
+   | -------------------------- function or associated item `foo` not found for this
+...
+LL |     Foo::foo();
+   |          ^^^ function or associated item not found in `Foo<{_: usize}>`
+   |
+   = note: the method `foo` exists but the following trait bounds were not satisfied:
+           `[u8; _]: Bar<[(); _]>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/const-generics/issues/issue-69654.rs b/src/test/ui/const-generics/issues/issue-69654.rs
index 7e775999ebd..38fca98ad4f 100644
--- a/src/test/ui/const-generics/issues/issue-69654.rs
+++ b/src/test/ui/const-generics/issues/issue-69654.rs
@@ -15,4 +15,5 @@ where
 
 fn main() {
     Foo::foo();
+    //~^ ERROR no function or associated item
 }
diff --git a/src/test/ui/const-generics/issues/issue-69654.stderr b/src/test/ui/const-generics/issues/issue-69654.stderr
index 70af7bf25d8..69cd0806fcd 100644
--- a/src/test/ui/const-generics/issues/issue-69654.stderr
+++ b/src/test/ui/const-generics/issues/issue-69654.stderr
@@ -4,6 +4,19 @@ error[E0423]: expected value, found type parameter `T`
 LL | impl<T> Bar<T> for [u8; T] {}
    |                         ^ not a value
 
-error: aborting due to previous error
+error[E0599]: no function or associated item named `foo` found for struct `Foo<{_: usize}>` in the current scope
+  --> $DIR/issue-69654.rs:17:10
+   |
+LL | struct Foo<const N: usize> {}
+   | -------------------------- function or associated item `foo` not found for this
+...
+LL |     Foo::foo();
+   |          ^^^ function or associated item not found in `Foo<{_: usize}>`
+   |
+   = note: the method `foo` exists but the following trait bounds were not satisfied:
+           `[u8; _]: Bar<[(); _]>`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0423`.
+Some errors have detailed explanations: E0423, E0599.
+For more information about an error, try `rustc --explain E0423`.
diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-1.rs b/src/test/ui/const-generics/occurs-check/unused-substs-1.rs
index f56687ecd93..6ded9f13bc4 100644
--- a/src/test/ui/const-generics/occurs-check/unused-substs-1.rs
+++ b/src/test/ui/const-generics/occurs-check/unused-substs-1.rs
@@ -1,4 +1,3 @@
-// build-pass
 #![feature(const_generics)]
 #![allow(incomplete_features)]
 
@@ -10,5 +9,5 @@ where
     A<N>: Bar<N>;
 
 fn main() {
-    let _ = A;
+    let _ = A; //~ERROR the trait bound
 }
diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr
new file mode 100644
index 00000000000..6830288acc0
--- /dev/null
+++ b/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr
@@ -0,0 +1,17 @@
+error[E0277]: the trait bound `A<{_: usize}>: Bar<{_: usize}>` is not satisfied
+  --> $DIR/unused-substs-1.rs:12:13
+   |
+LL | / struct A<const N: usize>
+LL | | where
+LL | |     A<N>: Bar<N>;
+   | |_________________- required by `A`
+...
+LL |       let _ = A;
+   |               ^ the trait `Bar<{_: usize}>` is not implemented for `A<{_: usize}>`
+   |
+   = help: the following implementations were found:
+             <A<7_usize> as Bar<N>>
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-2.rs b/src/test/ui/const-generics/occurs-check/unused-substs-2.rs
index 12444ec5312..2d00141fbf7 100644
--- a/src/test/ui/const-generics/occurs-check/unused-substs-2.rs
+++ b/src/test/ui/const-generics/occurs-check/unused-substs-2.rs
@@ -1,4 +1,3 @@
-// check-pass
 #![feature(const_generics)]
 #![allow(incomplete_features)]
 
@@ -24,4 +23,6 @@ fn main() {
     // `t` is `ty::Infer(TyVar(_#1t))`
     // `foo` contains `ty::Infer(TyVar(_#1t))` in its substs
     t = foo;
+    //~^ ERROR mismatched types
+    //~| NOTE cyclic type
 }
diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-2.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-2.stderr
new file mode 100644
index 00000000000..9532fc21a31
--- /dev/null
+++ b/src/test/ui/const-generics/occurs-check/unused-substs-2.stderr
@@ -0,0 +1,9 @@
+error[E0308]: mismatched types
+  --> $DIR/unused-substs-2.rs:25:9
+   |
+LL |     t = foo;
+   |         ^^^ cyclic type of infinite size
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-3.rs b/src/test/ui/const-generics/occurs-check/unused-substs-3.rs
index 187e27382fc..2e306f8c4c8 100644
--- a/src/test/ui/const-generics/occurs-check/unused-substs-3.rs
+++ b/src/test/ui/const-generics/occurs-check/unused-substs-3.rs
@@ -1,4 +1,3 @@
-// check-pass
 #![feature(const_generics)]
 #![allow(incomplete_features)]
 
@@ -15,4 +14,6 @@ fn main() {
     // `t` is `ty::Infer(TyVar(_#1t))`
     // `foo` contains `ty::Infer(TyVar(_#1t))` in its substs
     t = foo;
+    //~^ ERROR mismatched types
+    //~| NOTE cyclic type
 }
diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr
new file mode 100644
index 00000000000..2551d68f974
--- /dev/null
+++ b/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/unused-substs-3.rs:16:9
+   |
+LL |     t = foo;
+   |         ^^^
+   |         |
+   |         cyclic type of infinite size
+   |         help: try using a conversion method: `foo.to_vec()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-4.rs b/src/test/ui/const-generics/occurs-check/unused-substs-4.rs
index 8e42ceb6d70..9c7f5ab91ed 100644
--- a/src/test/ui/const-generics/occurs-check/unused-substs-4.rs
+++ b/src/test/ui/const-generics/occurs-check/unused-substs-4.rs
@@ -1,4 +1,3 @@
-// build-pass
 #![feature(const_generics)]
 #![allow(incomplete_features)]
 
@@ -8,5 +7,5 @@ fn bind<const N: usize>(value: [u8; N]) -> [u8; 3 + 4] {
 
 fn main() {
     let mut arr = Default::default();
-    arr = bind(arr);
+    arr = bind(arr); //~ ERROR mismatched type
 }
diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-4.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-4.stderr
new file mode 100644
index 00000000000..5685eedbdec
--- /dev/null
+++ b/src/test/ui/const-generics/occurs-check/unused-substs-4.stderr
@@ -0,0 +1,9 @@
+error[E0308]: mismatched types
+  --> $DIR/unused-substs-4.rs:10:11
+   |
+LL |     arr = bind(arr);
+   |           ^^^^^^^^^ encountered a self-referencing constant
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.