Skip to content

Commit 188bbf8

Browse files
committed
forbid complex types for generic parameters
1 parent 289e5fc commit 188bbf8

File tree

3 files changed

+80
-13
lines changed

3 files changed

+80
-13
lines changed

src/librustc_typeck/collect/type_of.rs

+28-13
Original file line numberDiff line numberDiff line change
@@ -326,21 +326,36 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
326326
GenericParamKind::Type { default: Some(ref ty), .. } => icx.to_ty(ty),
327327
GenericParamKind::Const { ty: ref hir_ty, .. } => {
328328
let ty = icx.to_ty(hir_ty);
329-
let err = match ty.peel_refs().kind {
330-
ty::FnPtr(_) => Some("function pointers"),
331-
ty::RawPtr(_) => Some("raw pointers"),
332-
_ => None,
329+
let err_ty_str;
330+
let err = if tcx.features().min_const_generics {
331+
match ty.kind {
332+
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None,
333+
_ => {
334+
err_ty_str = format!("`{}`", ty);
335+
Some(err_ty_str.as_str())
336+
}
337+
}
338+
} else {
339+
match ty.peel_refs().kind {
340+
ty::FnPtr(_) => Some("function pointers"),
341+
ty::RawPtr(_) => Some("raw pointers"),
342+
_ => None,
343+
}
333344
};
334345
if let Some(unsupported_type) = err {
335-
tcx.sess
336-
.struct_span_err(
337-
hir_ty.span,
338-
&format!(
339-
"using {} as const generic parameters is forbidden",
340-
unsupported_type
341-
),
342-
)
343-
.emit();
346+
let mut err = tcx.sess.struct_span_err(
347+
hir_ty.span,
348+
&format!(
349+
"using {} as const generic parameters is forbidden",
350+
unsupported_type
351+
),
352+
);
353+
354+
if tcx.features().min_const_generics {
355+
err.note("the only supported types are integers, `bool` and `char`").emit()
356+
} else {
357+
err.emit();
358+
}
344359
};
345360
if traits::search_for_structural_match_violation(param.hir_id, param.span, tcx, ty)
346361
.is_some()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![feature(min_const_generics)]
2+
3+
struct Foo<const N: [u8; 0]>;
4+
//~^ ERROR using `[u8; 0]` as const generic parameters is forbidden
5+
6+
struct Bar<const N: ()>;
7+
//~^ ERROR using `()` as const generic parameters is forbidden
8+
9+
#[derive(PartialEq, Eq)]
10+
struct No;
11+
12+
struct Fez<const N: No>;
13+
//~^ ERROR using `No` as const generic parameters is forbidden
14+
15+
struct Faz<const N: &'static u8>;
16+
//~^ ERROR using `&'static u8` as const generic parameters is forbidden
17+
18+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
error: using `[u8; 0]` as const generic parameters is forbidden
2+
--> $DIR/complex-types.rs:3:21
3+
|
4+
LL | struct Foo<const N: [u8; 0]>;
5+
| ^^^^^^^
6+
|
7+
= note: the only supported types are integers, `bool` and `char`
8+
9+
error: using `()` as const generic parameters is forbidden
10+
--> $DIR/complex-types.rs:6:21
11+
|
12+
LL | struct Bar<const N: ()>;
13+
| ^^
14+
|
15+
= note: the only supported types are integers, `bool` and `char`
16+
17+
error: using `No` as const generic parameters is forbidden
18+
--> $DIR/complex-types.rs:12:21
19+
|
20+
LL | struct Fez<const N: No>;
21+
| ^^
22+
|
23+
= note: the only supported types are integers, `bool` and `char`
24+
25+
error: using `&'static u8` as const generic parameters is forbidden
26+
--> $DIR/complex-types.rs:15:21
27+
|
28+
LL | struct Faz<const N: &'static u8>;
29+
| ^^^^^^^^^^^
30+
|
31+
= note: the only supported types are integers, `bool` and `char`
32+
33+
error: aborting due to 4 previous errors
34+

0 commit comments

Comments
 (0)