about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkadmin <julianknodt@gmail.com>2022-12-20 03:36:32 +0000
committerkadmin <julianknodt@gmail.com>2023-01-09 08:41:21 +0000
commitb79a9a0900dd1d29d8bf49e73b5ac75acafd9c3b (patch)
tree63a45beecc6e3a52620d9e6cc62adf7dbfade6c7
parent77b61379b6a808f388b347044b2d37a8968a274e (diff)
downloadrust-b79a9a0900dd1d29d8bf49e73b5ac75acafd9c3b.tar.gz
rust-b79a9a0900dd1d29d8bf49e73b5ac75acafd9c3b.zip
Set !const_evaluatable if ambig. and not inferred
This prevents an ICE due to a value not actually being evaluatable later.
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs22
-rw-r--r--src/test/ui/const-generics/ensure_is_evaluatable.rs20
-rw-r--r--src/test/ui/const-generics/ensure_is_evaluatable.stderr18
3 files changed, 48 insertions, 12 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 4f0b5f59402..8530b96796f 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -215,18 +215,16 @@ fn satisfied_from_param_env<'tcx>(
         }
     }
 
-    if let Some(c) = single_match {
-        if let Ok(c) = c {
-            let is_ok = infcx
-                .commit_if_ok(|_| {
-                    let ocx = ObligationCtxt::new_in_snapshot(infcx);
-                    assert!(ocx.eq(&ObligationCause::dummy(), param_env, c.ty(), ct.ty()).is_ok());
-                    assert!(ocx.eq(&ObligationCause::dummy(), param_env, c, ct).is_ok());
-                    if ocx.select_all_or_error().is_empty() { Ok(()) } else { Err(()) }
-                })
-                .is_ok();
-            assert!(is_ok);
-        }
+    if let Some(Ok(c)) = single_match {
+        let is_ok = infcx
+            .commit_if_ok(|_| {
+                let ocx = ObligationCtxt::new_in_snapshot(infcx);
+                assert!(ocx.eq(&ObligationCause::dummy(), param_env, c.ty(), ct.ty()).is_ok());
+                assert!(ocx.eq(&ObligationCause::dummy(), param_env, c, ct).is_ok());
+                if ocx.select_all_or_error().is_empty() { Ok(()) } else { Err(()) }
+            })
+            .is_ok();
+        assert!(is_ok);
         return true;
     }
 
diff --git a/src/test/ui/const-generics/ensure_is_evaluatable.rs b/src/test/ui/const-generics/ensure_is_evaluatable.rs
new file mode 100644
index 00000000000..1e8d8c3d355
--- /dev/null
+++ b/src/test/ui/const-generics/ensure_is_evaluatable.rs
@@ -0,0 +1,20 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+fn foo<const N: usize, const M: usize>() -> [(); N+2]
+where
+    [(); N + 1]:,
+    [(); M + 1]:,
+{
+    bar()
+    //~^ ERROR: unconstrained
+}
+
+fn bar<const N: usize>() -> [(); N]
+where
+    [(); N + 1]:,
+{
+    [(); N]
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/ensure_is_evaluatable.stderr b/src/test/ui/const-generics/ensure_is_evaluatable.stderr
new file mode 100644
index 00000000000..bf6c35ad8fd
--- /dev/null
+++ b/src/test/ui/const-generics/ensure_is_evaluatable.stderr
@@ -0,0 +1,18 @@
+error: unconstrained generic constant
+  --> $DIR/ensure_is_evaluatable.rs:9:5
+   |
+LL |     bar()
+   |     ^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); N + 1]:`
+note: required by a bound in `bar`
+  --> $DIR/ensure_is_evaluatable.rs:15:10
+   |
+LL | fn bar<const N: usize>() -> [(); N]
+   |    --- required by a bound in this
+LL | where
+LL |     [(); N + 1]:,
+   |          ^^^^^ required by this bound in `bar`
+
+error: aborting due to previous error
+