Skip to content

Commit

Permalink
forbid complex types for generic parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
lcnr committed Aug 5, 2020
1 parent 289e5fc commit 188bbf8
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 13 deletions.
41 changes: 28 additions & 13 deletions src/librustc_typeck/collect/type_of.rs
Expand Up @@ -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()
Expand Down
18 changes: 18 additions & 0 deletions 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() {}
34 changes: 34 additions & 0 deletions 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

0 comments on commit 188bbf8

Please sign in to comment.