forbid complex types for generic parameters

This commit is contained in:
Bastian Kauschke 2020-07-28 16:18:11 +02:00
parent 289e5fca7e
commit 188bbf840d
3 changed files with 80 additions and 13 deletions

View File

@ -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()

View File

@ -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() {}

View File

@ -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