about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkadmin <julianknodt@gmail.com>2022-12-21 21:53:52 +0000
committerkadmin <julianknodt@gmail.com>2023-01-09 08:41:21 +0000
commit21c5ffe008cce39bcd676ed197f691adbfbf7a2f (patch)
tree6ceecfd80f0d1f1d08de73aa3cbe941af9593f10
parent7c5cb737357518c9a704994e007b32ed0da214f3 (diff)
downloadrust-21c5ffe008cce39bcd676ed197f691adbfbf7a2f.tar.gz
rust-21c5ffe008cce39bcd676ed197f691adbfbf7a2f.zip
Clean up
Simplify match statement

Add multiple tests
- 1 test for checking `N + 1 + 1` does not unify with `N+1`
- 2 tests for checking that a function that uses two parameters only returns the parameter that
  is actually used.
- Check exact repeat predicates
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs32
-rw-r--r--src/test/ui/const-generics/fn_with_two_const_inputs.rs23
-rw-r--r--src/test/ui/const-generics/fn_with_two_const_inputs.stderr18
-rw-r--r--src/test/ui/const-generics/fn_with_two_same_const_inputs.rs22
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.rs4
-rw-r--r--src/test/ui/const-generics/two_matching_preds.rs19
-rw-r--r--src/test/ui/const-generics/unify_with_nested_expr.rs18
-rw-r--r--src/test/ui/const-generics/unify_with_nested_expr.stderr22
8 files changed, 133 insertions, 25 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index c4d5cf0309b..71fb6058cd2 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -186,8 +186,9 @@ fn satisfied_from_param_env<'tcx>(
                     Some(Ok(o)) if o == c => Some(Ok(c)),
                     Some(_) => Some(Err(())),
                 };
-                ControlFlow::CONTINUE
-            } else if let ty::ConstKind::Expr(e) = c.kind() {
+            }
+
+            if let ty::ConstKind::Expr(e) = c.kind() {
                 e.visit_with(self)
             } else {
                 // FIXME(generic_const_exprs): This doesn't recurse into `<T as Trait<U>>::ASSOC`'s substs.
@@ -208,35 +209,20 @@ fn satisfied_from_param_env<'tcx>(
         match pred.kind().skip_binder() {
             ty::PredicateKind::ConstEvaluatable(ce) => {
                 let b_ct = tcx.expand_abstract_consts(ce);
-                let mut v = Visitor { ct, infcx, param_env, single_match: None };
+                let mut v = Visitor { ct, infcx, param_env, single_match };
                 let _ = b_ct.visit_with(&mut v);
 
-                if let Some(inner) = v.single_match {
-                    single_match = if let Ok(inner) = inner {
-                        match single_match {
-                            None => Some(Ok(inner)),
-                            Some(Ok(prev)) if prev == inner => Some(Ok(prev)),
-                            Some(_) => Some(Err(())),
-                        }
-                    } else {
-                        Some(Err(()))
-                    };
-                }
+                single_match = v.single_match;
             }
             _ => {} // don't care
         }
     }
 
     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);
+        let ocx = ObligationCtxt::new(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());
+        assert!(ocx.select_all_or_error().is_empty());
         return true;
     }
 
diff --git a/src/test/ui/const-generics/fn_with_two_const_inputs.rs b/src/test/ui/const-generics/fn_with_two_const_inputs.rs
new file mode 100644
index 00000000000..0d6246a9f02
--- /dev/null
+++ b/src/test/ui/const-generics/fn_with_two_const_inputs.rs
@@ -0,0 +1,23 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+const fn both(_: usize, b: usize) -> usize {
+    b
+}
+
+fn foo<const N: usize, const M: usize>() -> [(); N + 2]
+where
+    [(); both(N + 1, M + 1)]:,
+{
+    bar()
+    //~^ ERROR: unconstrained generic constant
+}
+
+fn bar<const N: usize>() -> [(); N]
+where
+    [(); N + 1]:,
+{
+    [(); N]
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/fn_with_two_const_inputs.stderr b/src/test/ui/const-generics/fn_with_two_const_inputs.stderr
new file mode 100644
index 00000000000..614e7e0d2fc
--- /dev/null
+++ b/src/test/ui/const-generics/fn_with_two_const_inputs.stderr
@@ -0,0 +1,18 @@
+error: unconstrained generic constant
+  --> $DIR/fn_with_two_const_inputs.rs:12:5
+   |
+LL |     bar()
+   |     ^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); N + 1]:`
+note: required by a bound in `bar`
+  --> $DIR/fn_with_two_const_inputs.rs:18: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
+
diff --git a/src/test/ui/const-generics/fn_with_two_same_const_inputs.rs b/src/test/ui/const-generics/fn_with_two_same_const_inputs.rs
new file mode 100644
index 00000000000..f0ce093e07a
--- /dev/null
+++ b/src/test/ui/const-generics/fn_with_two_same_const_inputs.rs
@@ -0,0 +1,22 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+const fn both(_: usize, b: usize) -> usize {
+    b
+}
+
+fn foo<const N: usize>()
+where
+    [(); both(N + 1, N + 1)]:,
+{
+    bar::<N>();
+}
+
+fn bar<const N: usize>()
+where
+    [(); N + 1]:,
+{
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.rs b/src/test/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.rs
index d64468767eb..6093fc70b16 100644
--- a/src/test/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.rs
+++ b/src/test/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.rs
@@ -15,8 +15,8 @@ where
     [(); (L - 1) + 1 + L]:,
 {
     foo::<_, L>([(); L + 1 + L]);
-    //~^ ERROR: unconstrained generic constant
-    //~| ERROR: mismatched types
+    //~^ ERROR: mismatched types
+    //~^^ ERROR: unconstrained generic constant
 }
 
 fn main() {}
diff --git a/src/test/ui/const-generics/two_matching_preds.rs b/src/test/ui/const-generics/two_matching_preds.rs
new file mode 100644
index 00000000000..de608f73e2c
--- /dev/null
+++ b/src/test/ui/const-generics/two_matching_preds.rs
@@ -0,0 +1,19 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+fn foo<const N: usize>()
+where
+    [(); N + 1]:,
+    [(); N + 1]:,
+{
+    bar::<N>();
+}
+
+fn bar<const N: usize>()
+where
+    [(); N + 1]:,
+{
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/unify_with_nested_expr.rs b/src/test/ui/const-generics/unify_with_nested_expr.rs
new file mode 100644
index 00000000000..1271e0902a3
--- /dev/null
+++ b/src/test/ui/const-generics/unify_with_nested_expr.rs
@@ -0,0 +1,18 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+fn foo<const N: usize>()
+where
+    [(); N + 1 + 1]:,
+{
+    bar();
+    //~^ ERROR: type annotations
+}
+
+fn bar<const N: usize>()
+where
+    [(); N + 1]:,
+{
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/unify_with_nested_expr.stderr b/src/test/ui/const-generics/unify_with_nested_expr.stderr
new file mode 100644
index 00000000000..8bab0dff7f2
--- /dev/null
+++ b/src/test/ui/const-generics/unify_with_nested_expr.stderr
@@ -0,0 +1,22 @@
+error[E0284]: type annotations needed
+  --> $DIR/unify_with_nested_expr.rs:8:5
+   |
+LL |     bar();
+   |     ^^^ cannot infer the value of the const parameter `N` declared on the function `bar`
+   |
+note: required by a bound in `bar`
+  --> $DIR/unify_with_nested_expr.rs:14:10
+   |
+LL | fn bar<const N: usize>()
+   |    --- required by a bound in this
+LL | where
+LL |     [(); N + 1]:,
+   |          ^^^^^ required by this bound in `bar`
+help: consider specifying the generic argument
+   |
+LL |     bar::<N>();
+   |        +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0284`.