Skip to content

Commit cfb6114

Browse files
committed
Auto merge of #74676 - lcnr:generics-no-sort, r=varkor
correctly deal with unsorted generic parameters We now stop sorting generic params and instead correctly handle unsorted params in the rest of the compiler. We still restrict const params to come after type params though, so this PR does not change anything which is visible to users. This might slightly influence perf, so let's prevent any unintentional rollups. @bors rollup=never r? @varkor
2 parents 9008693 + 5f1eea9 commit cfb6114

File tree

5 files changed

+62
-41
lines changed

5 files changed

+62
-41
lines changed

Diff for: src/librustc_ast_lowering/lib.rs

+1-14
Original file line numberDiff line numberDiff line change
@@ -936,20 +936,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
936936
})
937937
});
938938

939-
let mut lowered_params: Vec<_> =
940-
lowered_generics.params.into_iter().chain(in_band_defs).collect();
941-
942-
// FIXME(const_generics): the compiler doesn't always cope with
943-
// unsorted generic parameters at the moment, so we make sure
944-
// that they're ordered correctly here for now. (When we chain
945-
// the `in_band_defs`, we might make the order unsorted.)
946-
lowered_params.sort_by_key(|param| match param.kind {
947-
hir::GenericParamKind::Lifetime { .. } => ParamKindOrd::Lifetime,
948-
hir::GenericParamKind::Type { .. } => ParamKindOrd::Type,
949-
hir::GenericParamKind::Const { .. } => ParamKindOrd::Const,
950-
});
951-
952-
lowered_generics.params = lowered_params.into();
939+
lowered_generics.params.extend(in_band_defs);
953940

954941
let lowered_generics = lowered_generics.into_generics(self.arena);
955942
(lowered_generics, res)

Diff for: src/librustc_resolve/late/lifetimes.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1298,7 +1298,10 @@ fn object_lifetime_defaults_for_item(
12981298
}
12991299
GenericParamKind::Const { .. } => {
13001300
// Generic consts don't impose any constraints.
1301-
None
1301+
//
1302+
// We still store a dummy value here to allow generic parameters
1303+
// in an arbitrary order.
1304+
Some(Set1::Empty)
13021305
}
13031306
})
13041307
.collect()

Diff for: src/librustc_typeck/collect.rs

+23-24
Original file line numberDiff line numberDiff line change
@@ -1362,13 +1362,9 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
13621362
let type_start = own_start - has_self as u32 + params.len() as u32;
13631363
let mut i = 0;
13641364

1365-
// FIXME(const_generics): a few places in the compiler expect generic params
1366-
// to be in the order lifetimes, then type params, then const params.
1367-
//
1368-
// To prevent internal errors in case const parameters are supplied before
1369-
// type parameters we first add all type params, then all const params.
1370-
params.extend(ast_generics.params.iter().filter_map(|param| {
1371-
if let GenericParamKind::Type { ref default, synthetic, .. } = param.kind {
1365+
params.extend(ast_generics.params.iter().filter_map(|param| match param.kind {
1366+
GenericParamKind::Lifetime { .. } => None,
1367+
GenericParamKind::Type { ref default, synthetic, .. } => {
13721368
if !allow_defaults && default.is_some() {
13731369
if !tcx.features().default_type_parameter_fallback {
13741370
tcx.struct_span_lint_hir(
@@ -1378,7 +1374,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
13781374
|lint| {
13791375
lint.build(
13801376
"defaults for type parameters are only allowed in \
1381-
`struct`, `enum`, `type`, or `trait` definitions.",
1377+
`struct`, `enum`, `type`, or `trait` definitions.",
13821378
)
13831379
.emit();
13841380
},
@@ -1403,13 +1399,8 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
14031399
};
14041400
i += 1;
14051401
Some(param_def)
1406-
} else {
1407-
None
14081402
}
1409-
}));
1410-
1411-
params.extend(ast_generics.params.iter().filter_map(|param| {
1412-
if let GenericParamKind::Const { .. } = param.kind {
1403+
GenericParamKind::Const { .. } => {
14131404
let param_def = ty::GenericParamDef {
14141405
index: type_start + i as u32,
14151406
name: param.name.ident().name,
@@ -1419,8 +1410,6 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
14191410
};
14201411
i += 1;
14211412
Some(param_def)
1422-
} else {
1423-
None
14241413
}
14251414
}));
14261415

@@ -1899,14 +1888,24 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
18991888
// Collect the predicates that were written inline by the user on each
19001889
// type parameter (e.g., `<T: Foo>`).
19011890
for param in ast_generics.params {
1902-
if let GenericParamKind::Type { .. } = param.kind {
1903-
let name = param.name.ident().name;
1904-
let param_ty = ty::ParamTy::new(index, name).to_ty(tcx);
1905-
index += 1;
1906-
1907-
let sized = SizedByDefault::Yes;
1908-
let bounds = AstConv::compute_bounds(&icx, param_ty, &param.bounds, sized, param.span);
1909-
predicates.extend(bounds.predicates(tcx, param_ty));
1891+
match param.kind {
1892+
// We already dealt with early bound lifetimes above.
1893+
GenericParamKind::Lifetime { .. } => (),
1894+
GenericParamKind::Type { .. } => {
1895+
let name = param.name.ident().name;
1896+
let param_ty = ty::ParamTy::new(index, name).to_ty(tcx);
1897+
index += 1;
1898+
1899+
let sized = SizedByDefault::Yes;
1900+
let bounds =
1901+
AstConv::compute_bounds(&icx, param_ty, &param.bounds, sized, param.span);
1902+
predicates.extend(bounds.predicates(tcx, param_ty));
1903+
}
1904+
GenericParamKind::Const { .. } => {
1905+
// Bounds on const parameters are currently not possible.
1906+
debug_assert!(param.bounds.is_empty());
1907+
index += 1;
1908+
}
19101909
}
19111910
}
19121911

Diff for: src/test/ui/const-generics/argument_order.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,14 @@ struct Bad<const N: usize, T> { //~ ERROR type parameters must be declared prior
66
another: T,
77
}
88

9-
fn main() { }
9+
struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
10+
//~^ ERROR type parameters must be declared prior
11+
//~| ERROR lifetime parameters must be declared prior
12+
a: &'a T,
13+
b: &'b U,
14+
}
15+
16+
fn main() {
17+
let _: AlsoBad<7, 'static, u32, 'static, 17, u16>;
18+
//~^ ERROR lifetime provided when a type was expected
19+
}

Diff for: src/test/ui/const-generics/argument_order.stderr

+23-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@ error: type parameters must be declared prior to const parameters
44
LL | struct Bad<const N: usize, T> {
55
| -----------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>`
66

7+
error: lifetime parameters must be declared prior to const parameters
8+
--> $DIR/argument_order.rs:9:32
9+
|
10+
LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
11+
| -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T, U, const N: usize, const M: usize>`
12+
13+
error: type parameters must be declared prior to const parameters
14+
--> $DIR/argument_order.rs:9:36
15+
|
16+
LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
17+
| ---------------------^----------------------^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T, U, const N: usize, const M: usize>`
18+
719
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
820
--> $DIR/argument_order.rs:1:12
921
|
@@ -13,5 +25,15 @@ LL | #![feature(const_generics)]
1325
= note: `#[warn(incomplete_features)]` on by default
1426
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
1527

16-
error: aborting due to previous error; 1 warning emitted
28+
error[E0747]: lifetime provided when a type was expected
29+
--> $DIR/argument_order.rs:17:23
30+
|
31+
LL | let _: AlsoBad<7, 'static, u32, 'static, 17, u16>;
32+
| ^^^^^^^
33+
|
34+
= note: lifetime arguments must be provided before type arguments
35+
= help: reorder the arguments: lifetimes, then types, then consts: `<'a, 'b, T, U, N, M>`
36+
37+
error: aborting due to 4 previous errors; 1 warning emitted
1738

39+
For more information about this error, try `rustc --explain E0747`.

0 commit comments

Comments
 (0)