Skip to content

Commit 41817ae

Browse files
authored
Rollup merge of rust-lang#80519 - max-heller:issue-80512-fix, r=varkor
Take type defaults into account in suggestions to reorder generic parameters Fixes rust-lang#80512
2 parents bd54e4a + 947b279 commit 41817ae

9 files changed

+53
-35
lines changed

compiler/rustc_ast_passes/src/ast_validation.rs

+31-25
Original file line numberDiff line numberDiff line change
@@ -717,35 +717,46 @@ impl<'a> AstValidator<'a> {
717717

718718
/// Checks that generic parameters are in the correct order,
719719
/// which is lifetimes, then types and then consts. (`<'a, T, const N: usize>`)
720-
fn validate_generic_param_order<'a>(
720+
fn validate_generic_param_order(
721721
sess: &Session,
722722
handler: &rustc_errors::Handler,
723-
generics: impl Iterator<Item = (ParamKindOrd, Option<&'a [GenericBound]>, Span, Option<String>)>,
723+
generics: &[GenericParam],
724724
span: Span,
725725
) {
726726
let mut max_param: Option<ParamKindOrd> = None;
727727
let mut out_of_order = FxHashMap::default();
728728
let mut param_idents = vec![];
729729

730-
for (kind, bounds, span, ident) in generics {
730+
for param in generics {
731+
let ident = Some(param.ident.to_string());
732+
let (kind, bounds, span) = (&param.kind, Some(&*param.bounds), param.ident.span);
733+
let (ord_kind, ident) = match &param.kind {
734+
GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident),
735+
GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident),
736+
GenericParamKind::Const { ref ty, kw_span: _ } => {
737+
let ty = pprust::ty_to_string(ty);
738+
let unordered = sess.features_untracked().const_generics;
739+
(ParamKindOrd::Const { unordered }, Some(format!("const {}: {}", param.ident, ty)))
740+
}
741+
};
731742
if let Some(ident) = ident {
732-
param_idents.push((kind, bounds, param_idents.len(), ident));
743+
param_idents.push((kind, ord_kind, bounds, param_idents.len(), ident));
733744
}
734745
let max_param = &mut max_param;
735746
match max_param {
736-
Some(max_param) if *max_param > kind => {
737-
let entry = out_of_order.entry(kind).or_insert((*max_param, vec![]));
747+
Some(max_param) if *max_param > ord_kind => {
748+
let entry = out_of_order.entry(ord_kind).or_insert((*max_param, vec![]));
738749
entry.1.push(span);
739750
}
740-
Some(_) | None => *max_param = Some(kind),
751+
Some(_) | None => *max_param = Some(ord_kind),
741752
};
742753
}
743754

744755
let mut ordered_params = "<".to_string();
745756
if !out_of_order.is_empty() {
746-
param_idents.sort_by_key(|&(po, _, i, _)| (po, i));
757+
param_idents.sort_by_key(|&(_, po, _, i, _)| (po, i));
747758
let mut first = true;
748-
for (_, bounds, _, ident) in param_idents {
759+
for (kind, _, bounds, _, ident) in param_idents {
749760
if !first {
750761
ordered_params += ", ";
751762
}
@@ -756,6 +767,16 @@ fn validate_generic_param_order<'a>(
756767
ordered_params += &pprust::bounds_to_string(&bounds);
757768
}
758769
}
770+
match kind {
771+
GenericParamKind::Type { default: Some(default) } => {
772+
ordered_params += " = ";
773+
ordered_params += &pprust::ty_to_string(default);
774+
}
775+
GenericParamKind::Type { default: None } => (),
776+
GenericParamKind::Lifetime => (),
777+
// FIXME(const_generics:defaults)
778+
GenericParamKind::Const { ty: _, kw_span: _ } => (),
779+
}
759780
first = false;
760781
}
761782
}
@@ -1150,22 +1171,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11501171
validate_generic_param_order(
11511172
self.session,
11521173
self.err_handler(),
1153-
generics.params.iter().map(|param| {
1154-
let ident = Some(param.ident.to_string());
1155-
let (kind, ident) = match &param.kind {
1156-
GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident),
1157-
GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident),
1158-
GenericParamKind::Const { ref ty, kw_span: _ } => {
1159-
let ty = pprust::ty_to_string(ty);
1160-
let unordered = self.session.features_untracked().const_generics;
1161-
(
1162-
ParamKindOrd::Const { unordered },
1163-
Some(format!("const {}: {}", param.ident, ty)),
1164-
)
1165-
}
1166-
};
1167-
(kind, Some(&*param.bounds), param.ident.span, ident)
1168-
}),
1174+
&generics.params,
11691175
generics.span,
11701176
);
11711177

src/test/ui/const-generics/defaults/complex-unord-param.min.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: type parameters must be declared prior to const parameters
22
--> $DIR/complex-unord-param.rs:8:41
33
|
44
LL | struct NestedArrays<'a, const N: usize, A: 'a, const M: usize, T:'a =u32> {
5-
| ---------------------^----------------------^--------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, A: 'a, T: 'a, const N: usize, const M: usize>`
5+
| ---------------------^----------------------^--------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, A: 'a, T: 'a = u32, const N: usize, const M: usize>`
66

77
error: aborting due to previous error
88

src/test/ui/const-generics/defaults/intermixed-lifetime.full.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error: lifetime parameters must be declared prior to const parameters
22
--> $DIR/intermixed-lifetime.rs:6:28
33
|
44
LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
5-
| -----------------^^---------- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T>`
5+
| -----------------^^---------- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T = u32>`
66

77
error: lifetime parameters must be declared prior to type parameters
88
--> $DIR/intermixed-lifetime.rs:10:37
99
|
1010
LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
11-
| --------------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T>`
11+
| --------------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T = u32>`
1212

1313
error: aborting due to 2 previous errors
1414

src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,25 @@ error: lifetime parameters must be declared prior to const parameters
22
--> $DIR/intermixed-lifetime.rs:6:28
33
|
44
LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
5-
| -----------------^^---------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
5+
| -----------------^^---------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>`
66

77
error: type parameters must be declared prior to const parameters
88
--> $DIR/intermixed-lifetime.rs:6:32
99
|
1010
LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
11-
| ---------------------^------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
11+
| ---------------------^------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>`
1212

1313
error: lifetime parameters must be declared prior to const parameters
1414
--> $DIR/intermixed-lifetime.rs:10:37
1515
|
1616
LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
17-
| --------------------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
17+
| --------------------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>`
1818

1919
error: type parameters must be declared prior to const parameters
2020
--> $DIR/intermixed-lifetime.rs:10:28
2121
|
2222
LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
23-
| -----------------^----------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
23+
| -----------------^----------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>`
2424

2525
error: aborting due to 4 previous errors
2626

src/test/ui/const-generics/defaults/needs-feature.min.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: type parameters must be declared prior to const parameters
22
--> $DIR/needs-feature.rs:9:26
33
|
44
LL | struct A<const N: usize, T=u32>(T);
5-
| -----------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>`
5+
| -----------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<T = u32, const N: usize>`
66

77
error: aborting due to previous error
88

src/test/ui/const-generics/defaults/needs-feature.none.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: type parameters must be declared prior to const parameters
22
--> $DIR/needs-feature.rs:9:26
33
|
44
LL | struct A<const N: usize, T=u32>(T);
5-
| -----------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>`
5+
| -----------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<T = u32, const N: usize>`
66

77
error: aborting due to previous error
88

src/test/ui/const-generics/defaults/simple-defaults.min.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: type parameters must be declared prior to const parameters
22
--> $DIR/simple-defaults.rs:8:40
33
|
44
LL | struct FixedOutput<'a, const N: usize, T=u32> {
5-
| ---------------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
5+
| ---------------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>`
66

77
error: aborting due to previous error
88

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#![crate_type = "lib"]
2+
3+
struct S<T = (), 'a>(&'a T);
4+
//~^ ERROR lifetime parameters must be declared prior to type parameters
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: lifetime parameters must be declared prior to type parameters
2+
--> $DIR/issue-80512-param-reordering-with-defaults.rs:3:18
3+
|
4+
LL | struct S<T = (), 'a>(&'a T);
5+
| ---------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = ()>`
6+
7+
error: aborting due to previous error
8+

0 commit comments

Comments
 (0)