@@ -1291,47 +1291,67 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics {
1291
1291
// Now create the real type and const parameters.
1292
1292
let type_start = own_start - has_self as u32 + params. len ( ) as u32 ;
1293
1293
let mut i = 0 ;
1294
- params. extend ( ast_generics. params . iter ( ) . filter_map ( |param| {
1295
- let kind = match param. kind {
1296
- GenericParamKind :: Type { ref default, synthetic, .. } => {
1297
- if !allow_defaults && default. is_some ( ) {
1298
- if !tcx. features ( ) . default_type_parameter_fallback {
1299
- tcx. struct_span_lint_hir (
1300
- lint:: builtin:: INVALID_TYPE_PARAM_DEFAULT ,
1301
- param. hir_id ,
1302
- param. span ,
1303
- |lint| {
1304
- lint. build (
1305
- "defaults for type parameters are only allowed in \
1306
- `struct`, `enum`, `type`, or `trait` definitions.",
1307
- )
1308
- . emit ( ) ;
1309
- } ,
1310
- ) ;
1311
- }
1312
- }
1313
1294
1314
- ty:: GenericParamDefKind :: Type {
1315
- has_default : default. is_some ( ) ,
1316
- object_lifetime_default : object_lifetime_defaults
1317
- . as_ref ( )
1318
- . map_or ( rl:: Set1 :: Empty , |o| o[ i] ) ,
1319
- synthetic,
1295
+ // FIXME(const_generics): a few places in the compiler expect generic params
1296
+ // to be in the order lifetimes, then type params, then const params.
1297
+ //
1298
+ // To prevent internal errors in case a const params are supplied in front of
1299
+ // type parameters we first add all type params, then all const params.
1300
+ params. extend ( ast_generics. params . iter ( ) . filter_map ( |param| {
1301
+ if let GenericParamKind :: Type { ref default, synthetic, .. } = param. kind {
1302
+ if !allow_defaults && default. is_some ( ) {
1303
+ if !tcx. features ( ) . default_type_parameter_fallback {
1304
+ tcx. struct_span_lint_hir (
1305
+ lint:: builtin:: INVALID_TYPE_PARAM_DEFAULT ,
1306
+ param. hir_id ,
1307
+ param. span ,
1308
+ |lint| {
1309
+ lint. build (
1310
+ "defaults for type parameters are only allowed in \
1311
+ `struct`, `enum`, `type`, or `trait` definitions.",
1312
+ )
1313
+ . emit ( ) ;
1314
+ } ,
1315
+ ) ;
1320
1316
}
1321
1317
}
1322
- GenericParamKind :: Const { .. } => ty:: GenericParamDefKind :: Const ,
1323
- _ => return None ,
1324
- } ;
1325
1318
1326
- let param_def = ty:: GenericParamDef {
1327
- index : type_start + i as u32 ,
1328
- name : param. name . ident ( ) . name ,
1329
- def_id : tcx. hir ( ) . local_def_id ( param. hir_id ) ,
1330
- pure_wrt_drop : param. pure_wrt_drop ,
1331
- kind,
1332
- } ;
1333
- i += 1 ;
1334
- Some ( param_def)
1319
+ let kind = ty:: GenericParamDefKind :: Type {
1320
+ has_default : default. is_some ( ) ,
1321
+ object_lifetime_default : object_lifetime_defaults
1322
+ . as_ref ( )
1323
+ . map_or ( rl:: Set1 :: Empty , |o| o[ i] ) ,
1324
+ synthetic,
1325
+ } ;
1326
+
1327
+ let param_def = ty:: GenericParamDef {
1328
+ index : type_start + i as u32 ,
1329
+ name : param. name . ident ( ) . name ,
1330
+ def_id : tcx. hir ( ) . local_def_id ( param. hir_id ) ,
1331
+ pure_wrt_drop : param. pure_wrt_drop ,
1332
+ kind,
1333
+ } ;
1334
+ i += 1 ;
1335
+ Some ( param_def)
1336
+ } else {
1337
+ None
1338
+ }
1339
+ } ) ) ;
1340
+
1341
+ params. extend ( ast_generics. params . iter ( ) . filter_map ( |param| {
1342
+ if let GenericParamKind :: Const { .. } = param. kind {
1343
+ let param_def = ty:: GenericParamDef {
1344
+ index : type_start + i as u32 ,
1345
+ name : param. name . ident ( ) . name ,
1346
+ def_id : tcx. hir ( ) . local_def_id ( param. hir_id ) ,
1347
+ pure_wrt_drop : param. pure_wrt_drop ,
1348
+ kind : ty:: GenericParamDefKind :: Const ,
1349
+ } ;
1350
+ i += 1 ;
1351
+ Some ( param_def)
1352
+ } else {
1353
+ None
1354
+ }
1335
1355
} ) ) ;
1336
1356
1337
1357
// provide junk type parameter defs - the only place that
0 commit comments