Skip to content

Commit 266801d

Browse files
authored
Rollup merge of #70032 - lcnr:issue69970, r=varkor
put type params in front of const params in generics_of fixes #69970 r? @varkor
2 parents 276b54e + 17c94c6 commit 266801d

File tree

4 files changed

+84
-37
lines changed

4 files changed

+84
-37
lines changed

src/librustc_ast_passes/ast_validation.rs

+2
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,8 @@ impl<'a> AstValidator<'a> {
645645
}
646646
}
647647

648+
/// Checks that generic parameters are in the correct order,
649+
/// which is lifetimes, then types and then consts. (`<'a, T, const N: usize>`)
648650
fn validate_generic_param_order<'a>(
649651
sess: &Session,
650652
handler: &rustc_errors::Handler,

src/librustc_typeck/collect.rs

+57-37
Original file line numberDiff line numberDiff line change
@@ -1306,47 +1306,67 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics {
13061306
// Now create the real type and const parameters.
13071307
let type_start = own_start - has_self as u32 + params.len() as u32;
13081308
let mut i = 0;
1309-
params.extend(ast_generics.params.iter().filter_map(|param| {
1310-
let kind = match param.kind {
1311-
GenericParamKind::Type { ref default, synthetic, .. } => {
1312-
if !allow_defaults && default.is_some() {
1313-
if !tcx.features().default_type_parameter_fallback {
1314-
tcx.struct_span_lint_hir(
1315-
lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
1316-
param.hir_id,
1317-
param.span,
1318-
|lint| {
1319-
lint.build(
1320-
"defaults for type parameters are only allowed in \
1321-
`struct`, `enum`, `type`, or `trait` definitions.",
1322-
)
1323-
.emit();
1324-
},
1325-
);
1326-
}
1327-
}
13281309

1329-
ty::GenericParamDefKind::Type {
1330-
has_default: default.is_some(),
1331-
object_lifetime_default: object_lifetime_defaults
1332-
.as_ref()
1333-
.map_or(rl::Set1::Empty, |o| o[i]),
1334-
synthetic,
1310+
// FIXME(const_generics): a few places in the compiler expect generic params
1311+
// to be in the order lifetimes, then type params, then const params.
1312+
//
1313+
// To prevent internal errors in case const parameters are supplied before
1314+
// type parameters we first add all type params, then all const params.
1315+
params.extend(ast_generics.params.iter().filter_map(|param| {
1316+
if let GenericParamKind::Type { ref default, synthetic, .. } = param.kind {
1317+
if !allow_defaults && default.is_some() {
1318+
if !tcx.features().default_type_parameter_fallback {
1319+
tcx.struct_span_lint_hir(
1320+
lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
1321+
param.hir_id,
1322+
param.span,
1323+
|lint| {
1324+
lint.build(
1325+
"defaults for type parameters are only allowed in \
1326+
`struct`, `enum`, `type`, or `trait` definitions.",
1327+
)
1328+
.emit();
1329+
},
1330+
);
13351331
}
13361332
}
1337-
GenericParamKind::Const { .. } => ty::GenericParamDefKind::Const,
1338-
_ => return None,
1339-
};
13401333

1341-
let param_def = ty::GenericParamDef {
1342-
index: type_start + i as u32,
1343-
name: param.name.ident().name,
1344-
def_id: tcx.hir().local_def_id(param.hir_id),
1345-
pure_wrt_drop: param.pure_wrt_drop,
1346-
kind,
1347-
};
1348-
i += 1;
1349-
Some(param_def)
1334+
let kind = ty::GenericParamDefKind::Type {
1335+
has_default: default.is_some(),
1336+
object_lifetime_default: object_lifetime_defaults
1337+
.as_ref()
1338+
.map_or(rl::Set1::Empty, |o| o[i]),
1339+
synthetic,
1340+
};
1341+
1342+
let param_def = ty::GenericParamDef {
1343+
index: type_start + i as u32,
1344+
name: param.name.ident().name,
1345+
def_id: tcx.hir().local_def_id(param.hir_id),
1346+
pure_wrt_drop: param.pure_wrt_drop,
1347+
kind,
1348+
};
1349+
i += 1;
1350+
Some(param_def)
1351+
} else {
1352+
None
1353+
}
1354+
}));
1355+
1356+
params.extend(ast_generics.params.iter().filter_map(|param| {
1357+
if let GenericParamKind::Const { .. } = param.kind {
1358+
let param_def = ty::GenericParamDef {
1359+
index: type_start + i as u32,
1360+
name: param.name.ident().name,
1361+
def_id: tcx.hir().local_def_id(param.hir_id),
1362+
pure_wrt_drop: param.pure_wrt_drop,
1363+
kind: ty::GenericParamDefKind::Const,
1364+
};
1365+
i += 1;
1366+
Some(param_def)
1367+
} else {
1368+
None
1369+
}
13501370
}));
13511371

13521372
// provide junk type parameter defs - the only place that
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#![feature(const_generics)]
2+
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
3+
4+
struct Bad<const N: usize, T> { //~ ERROR type parameters must be declared prior
5+
arr: [u8; { N }],
6+
another: T,
7+
}
8+
9+
fn main() { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error: type parameters must be declared prior to const parameters
2+
--> $DIR/argument_order.rs:4:28
3+
|
4+
LL | struct Bad<const N: usize, T> {
5+
| -----------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>`
6+
7+
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
8+
--> $DIR/argument_order.rs:1:12
9+
|
10+
LL | #![feature(const_generics)]
11+
| ^^^^^^^^^^^^^^
12+
|
13+
= note: `#[warn(incomplete_features)]` on by default
14+
15+
error: aborting due to previous error
16+

0 commit comments

Comments
 (0)