about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_middle/src/ty/fast_reject.rs6
-rw-r--r--tests/ui/traits/new-solver/const-param-placeholder.fail.stderr16
-rw-r--r--tests/ui/traits/new-solver/const-param-placeholder.rs21
3 files changed, 42 insertions, 1 deletions
diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs
index 0a6e94248e6..61cde923e9a 100644
--- a/compiler/rustc_middle/src/ty/fast_reject.rs
+++ b/compiler/rustc_middle/src/ty/fast_reject.rs
@@ -312,6 +312,7 @@ impl DeepRejectCtxt {
             // Impls cannot contain these types as these cannot be named directly.
             ty::FnDef(..) | ty::Closure(..) | ty::Generator(..) => false,
 
+            // Placeholder types don't unify with anything on their own
             ty::Placeholder(..) | ty::Bound(..) => false,
 
             // Depending on the value of `treat_obligation_params`, we either
@@ -359,6 +360,9 @@ impl DeepRejectCtxt {
                 TreatParams::AsCandidateKey => true,
             },
 
+            // Placeholder consts don't unify with anything on their own
+            ty::ConstKind::Placeholder(_) => false,
+
             // As we don't necessarily eagerly evaluate constants,
             // they might unify with any value.
             ty::ConstKind::Expr(_) | ty::ConstKind::Unevaluated(_) | ty::ConstKind::Error(_) => {
@@ -371,7 +375,7 @@ impl DeepRejectCtxt {
 
             ty::ConstKind::Infer(_) => true,
 
-            ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => {
+            ty::ConstKind::Bound(..) => {
                 bug!("unexpected obl const: {:?}", obligation_ct)
             }
         }
diff --git a/tests/ui/traits/new-solver/const-param-placeholder.fail.stderr b/tests/ui/traits/new-solver/const-param-placeholder.fail.stderr
new file mode 100644
index 00000000000..4db6e22e57f
--- /dev/null
+++ b/tests/ui/traits/new-solver/const-param-placeholder.fail.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the trait bound `[T; N]: Foo` is not satisfied
+  --> $DIR/const-param-placeholder.rs:17:17
+   |
+LL |     needs_foo::<[T; N]>();
+   |                 ^^^^^^ the trait `Foo` is not implemented for `[T; N]`
+   |
+   = help: the trait `Foo` is implemented for `[T; 1]`
+note: required by a bound in `needs_foo`
+  --> $DIR/const-param-placeholder.rs:8:17
+   |
+LL | fn needs_foo<F: Foo>() {}
+   |                 ^^^ required by this bound in `needs_foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/new-solver/const-param-placeholder.rs b/tests/ui/traits/new-solver/const-param-placeholder.rs
new file mode 100644
index 00000000000..a83102a4cdd
--- /dev/null
+++ b/tests/ui/traits/new-solver/const-param-placeholder.rs
@@ -0,0 +1,21 @@
+// compile-flags: -Ztrait-solver=next
+// revisions: pass fail
+//[pass] check-pass
+
+struct Wrapper<T, const N: usize>([T; N]);
+
+trait Foo {}
+fn needs_foo<F: Foo>() {}
+
+#[cfg(fail)]
+impl<T> Foo for [T; 1] {}
+
+#[cfg(pass)]
+impl<T, const N: usize> Foo for [T; N] {}
+
+fn test<T, const N: usize>() {
+    needs_foo::<[T; N]>();
+    //[fail]~^ ERROR the trait bound `[T; N]: Foo` is not satisfied
+}
+
+fn main() {}