about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBastian Kauschke <bastian_kauschke@hotmail.de>2020-07-28 16:18:11 +0200
committerBastian Kauschke <bastian_kauschke@hotmail.de>2020-08-05 18:30:37 +0200
commit188bbf840dd858edb929459bd3536219fa062077 (patch)
tree112d1de6447da00075df2050c28b8e0490188100 /src
parent289e5fca7ecdb03db97be9d89ae908f253a3f263 (diff)
downloadrust-188bbf840dd858edb929459bd3536219fa062077.tar.gz
rust-188bbf840dd858edb929459bd3536219fa062077.zip
forbid complex types for generic parameters
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/collect/type_of.rs41
-rw-r--r--src/test/ui/const-generics/min_const_generics/complex-types.rs18
-rw-r--r--src/test/ui/const-generics/min_const_generics/complex-types.stderr34
3 files changed, 80 insertions, 13 deletions
diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs
index 8c9cd50a17d..981437c5e84 100644
--- a/src/librustc_typeck/collect/type_of.rs
+++ b/src/librustc_typeck/collect/type_of.rs
@@ -326,21 +326,36 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
             GenericParamKind::Type { default: Some(ref ty), .. } => icx.to_ty(ty),
             GenericParamKind::Const { ty: ref hir_ty, .. } => {
                 let ty = icx.to_ty(hir_ty);
-                let err = match ty.peel_refs().kind {
-                    ty::FnPtr(_) => Some("function pointers"),
-                    ty::RawPtr(_) => Some("raw pointers"),
-                    _ => None,
+                let err_ty_str;
+                let err = if tcx.features().min_const_generics {
+                    match ty.kind {
+                        ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None,
+                        _ => {
+                            err_ty_str = format!("`{}`", ty);
+                            Some(err_ty_str.as_str())
+                        }
+                    }
+                } else {
+                    match ty.peel_refs().kind {
+                        ty::FnPtr(_) => Some("function pointers"),
+                        ty::RawPtr(_) => Some("raw pointers"),
+                        _ => None,
+                    }
                 };
                 if let Some(unsupported_type) = err {
-                    tcx.sess
-                        .struct_span_err(
-                            hir_ty.span,
-                            &format!(
-                                "using {} as const generic parameters is forbidden",
-                                unsupported_type
-                            ),
-                        )
-                        .emit();
+                    let mut err = tcx.sess.struct_span_err(
+                        hir_ty.span,
+                        &format!(
+                            "using {} as const generic parameters is forbidden",
+                            unsupported_type
+                        ),
+                    );
+
+                    if tcx.features().min_const_generics {
+                        err.note("the only supported types are integers, `bool` and `char`").emit()
+                    } else {
+                        err.emit();
+                    }
                 };
                 if traits::search_for_structural_match_violation(param.hir_id, param.span, tcx, ty)
                     .is_some()
diff --git a/src/test/ui/const-generics/min_const_generics/complex-types.rs b/src/test/ui/const-generics/min_const_generics/complex-types.rs
new file mode 100644
index 00000000000..a396fa83aa6
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/complex-types.rs
@@ -0,0 +1,18 @@
+#![feature(min_const_generics)]
+
+struct Foo<const N: [u8; 0]>;
+//~^ ERROR using `[u8; 0]` as const generic parameters is forbidden
+
+struct Bar<const N: ()>;
+//~^ ERROR using `()` as const generic parameters is forbidden
+
+#[derive(PartialEq, Eq)]
+struct No;
+
+struct Fez<const N: No>;
+//~^ ERROR using `No` as const generic parameters is forbidden
+
+struct Faz<const N: &'static u8>;
+//~^ ERROR using `&'static u8` as const generic parameters is forbidden
+
+fn main() {}
diff --git a/src/test/ui/const-generics/min_const_generics/complex-types.stderr b/src/test/ui/const-generics/min_const_generics/complex-types.stderr
new file mode 100644
index 00000000000..65c7aec36d6
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/complex-types.stderr
@@ -0,0 +1,34 @@
+error: using `[u8; 0]` as const generic parameters is forbidden
+  --> $DIR/complex-types.rs:3:21
+   |
+LL | struct Foo<const N: [u8; 0]>;
+   |                     ^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+
+error: using `()` as const generic parameters is forbidden
+  --> $DIR/complex-types.rs:6:21
+   |
+LL | struct Bar<const N: ()>;
+   |                     ^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+
+error: using `No` as const generic parameters is forbidden
+  --> $DIR/complex-types.rs:12:21
+   |
+LL | struct Fez<const N: No>;
+   |                     ^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+
+error: using `&'static u8` as const generic parameters is forbidden
+  --> $DIR/complex-types.rs:15:21
+   |
+LL | struct Faz<const N: &'static u8>;
+   |                     ^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+
+error: aborting due to 4 previous errors
+