about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs14
-rw-r--r--src/test/ui/const-generics/type_mismatch.rs9
-rw-r--r--src/test/ui/const-generics/type_mismatch.stderr23
-rw-r--r--src/test/ui/const-generics/type_not_in_scope.rs11
-rw-r--r--src/test/ui/const-generics/type_not_in_scope.stderr24
5 files changed, 76 insertions, 5 deletions
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 436ca4c0578..b41bf70e88e 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -10,6 +10,7 @@ use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
 use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc_hir as ast;
 use rustc_hir::def_id::DefId;
+use rustc_span::DUMMY_SP;
 use rustc_target::spec::abi;
 use std::iter;
 
@@ -499,11 +500,14 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
 
     // FIXME(oli-obk): once const generics can have generic types, this assertion
     // will likely get triggered. Move to `normalize_erasing_regions` at that point.
-    assert_eq!(
-        tcx.erase_regions(a.ty),
-        tcx.erase_regions(b.ty),
-        "cannot relate constants of different types"
-    );
+    let a_ty = tcx.erase_regions(a.ty);
+    let b_ty = tcx.erase_regions(b.ty);
+    if a_ty != b_ty {
+        relation.tcx().sess.delay_span_bug(
+            DUMMY_SP,
+            &format!("cannot relate constants of different types: {} != {}", a_ty, b_ty),
+        );
+    }
 
     let eagerly_eval = |x: &'tcx ty::Const<'tcx>| x.eval(tcx, relation.param_env());
     let a = eagerly_eval(a);
diff --git a/src/test/ui/const-generics/type_mismatch.rs b/src/test/ui/const-generics/type_mismatch.rs
new file mode 100644
index 00000000000..4a7534e3713
--- /dev/null
+++ b/src/test/ui/const-generics/type_mismatch.rs
@@ -0,0 +1,9 @@
+fn foo<const N: usize>() -> [u8; N] {
+    bar::<N>() //~ ERROR mismatched types
+}
+
+fn bar<const N: u8>() -> [u8; N] {}
+//~^ ERROR mismatched types
+//~| ERROR mismatched types
+
+fn main() {}
diff --git a/src/test/ui/const-generics/type_mismatch.stderr b/src/test/ui/const-generics/type_mismatch.stderr
new file mode 100644
index 00000000000..f5053e4c8c8
--- /dev/null
+++ b/src/test/ui/const-generics/type_mismatch.stderr
@@ -0,0 +1,23 @@
+error[E0308]: mismatched types
+  --> $DIR/type_mismatch.rs:2:11
+   |
+LL |     bar::<N>()
+   |           ^ expected `u8`, found `usize`
+
+error[E0308]: mismatched types
+  --> $DIR/type_mismatch.rs:5:31
+   |
+LL | fn bar<const N: u8>() -> [u8; N] {}
+   |                               ^ expected `usize`, found `u8`
+
+error[E0308]: mismatched types
+  --> $DIR/type_mismatch.rs:5:26
+   |
+LL | fn bar<const N: u8>() -> [u8; N] {}
+   |    ---                   ^^^^^^^ expected array `[u8; N]`, found `()`
+   |    |
+   |    implicitly returns `()` as its body has no tail or `return` expression
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/type_not_in_scope.rs b/src/test/ui/const-generics/type_not_in_scope.rs
new file mode 100644
index 00000000000..5933701808b
--- /dev/null
+++ b/src/test/ui/const-generics/type_not_in_scope.rs
@@ -0,0 +1,11 @@
+impl X {
+    //~^ ERROR cannot find type
+    fn getn<const N: usize>() -> [u8; N] {
+        getn::<N>()
+    }
+}
+fn getn<const N: cfg_attr>() -> [u8; N] {}
+//~^ ERROR expected type, found built-in attribute `cfg_attr`
+//~| ERROR mismatched types
+
+fn main() {}
diff --git a/src/test/ui/const-generics/type_not_in_scope.stderr b/src/test/ui/const-generics/type_not_in_scope.stderr
new file mode 100644
index 00000000000..16796acb3d2
--- /dev/null
+++ b/src/test/ui/const-generics/type_not_in_scope.stderr
@@ -0,0 +1,24 @@
+error[E0412]: cannot find type `X` in this scope
+  --> $DIR/type_not_in_scope.rs:1:6
+   |
+LL | impl X {
+   |      ^ not found in this scope
+
+error[E0573]: expected type, found built-in attribute `cfg_attr`
+  --> $DIR/type_not_in_scope.rs:7:18
+   |
+LL | fn getn<const N: cfg_attr>() -> [u8; N] {}
+   |                  ^^^^^^^^ not a type
+
+error[E0308]: mismatched types
+  --> $DIR/type_not_in_scope.rs:7:33
+   |
+LL | fn getn<const N: cfg_attr>() -> [u8; N] {}
+   |    ----                         ^^^^^^^ expected array `[u8; N]`, found `()`
+   |    |
+   |    implicitly returns `()` as its body has no tail or `return` expression
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0308, E0412, E0573.
+For more information about an error, try `rustc --explain E0308`.