Skip to content

Commit 4b547e3

Browse files
authored
Rollup merge of rust-lang#59572 - davidtwco:issue-59508, r=varkor
Include bounds in generic re-ordering diagnostic Fixes rust-lang#59508. r? @estebank cc @varkor
2 parents 5cffe3a + 0270d56 commit 4b547e3

13 files changed

+140
-38
lines changed

src/librustc_passes/ast_validation.rs

+55-25
Original file line numberDiff line numberDiff line change
@@ -352,18 +352,26 @@ enum GenericPosition {
352352
}
353353

354354
fn validate_generics_order<'a>(
355+
sess: &Session,
355356
handler: &errors::Handler,
356-
generics: impl Iterator<Item = (ParamKindOrd, Span, Option<String>)>,
357+
generics: impl Iterator<
358+
Item = (
359+
ParamKindOrd,
360+
Option<&'a [GenericBound]>,
361+
Span,
362+
Option<String>
363+
),
364+
>,
357365
pos: GenericPosition,
358366
span: Span,
359367
) {
360368
let mut max_param: Option<ParamKindOrd> = None;
361369
let mut out_of_order = FxHashMap::default();
362370
let mut param_idents = vec![];
363371

364-
for (kind, span, ident) in generics {
372+
for (kind, bounds, span, ident) in generics {
365373
if let Some(ident) = ident {
366-
param_idents.push((kind, param_idents.len(), ident));
374+
param_idents.push((kind, bounds, param_idents.len(), ident));
367375
}
368376
let max_param = &mut max_param;
369377
match max_param {
@@ -377,13 +385,19 @@ fn validate_generics_order<'a>(
377385

378386
let mut ordered_params = "<".to_string();
379387
if !out_of_order.is_empty() {
380-
param_idents.sort_by_key(|&(po, i, _)| (po, i));
388+
param_idents.sort_by_key(|&(po, _, i, _)| (po, i));
381389
let mut first = true;
382-
for (_, _, ident) in param_idents {
390+
for (_, bounds, _, ident) in param_idents {
383391
if !first {
384392
ordered_params += ", ";
385393
}
386394
ordered_params += &ident;
395+
if let Some(bounds) = bounds {
396+
if !bounds.is_empty() {
397+
ordered_params += ": ";
398+
ordered_params += &pprust::bounds_to_string(&bounds);
399+
}
400+
}
387401
first = false;
388402
}
389403
}
@@ -405,7 +419,11 @@ fn validate_generics_order<'a>(
405419
if let GenericPosition::Param = pos {
406420
err.span_suggestion(
407421
span,
408-
&format!("reorder the {}s: lifetimes, then types, then consts", pos_str),
422+
&format!(
423+
"reorder the {}s: lifetimes, then types{}",
424+
pos_str,
425+
if sess.features_untracked().const_generics { ", then consts" } else { "" },
426+
),
409427
ordered_params.clone(),
410428
Applicability::MachineApplicable,
411429
);
@@ -687,13 +705,19 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
687705
match *generic_args {
688706
GenericArgs::AngleBracketed(ref data) => {
689707
walk_list!(self, visit_generic_arg, &data.args);
690-
validate_generics_order(self.err_handler(), data.args.iter().map(|arg| {
691-
(match arg {
692-
GenericArg::Lifetime(..) => ParamKindOrd::Lifetime,
693-
GenericArg::Type(..) => ParamKindOrd::Type,
694-
GenericArg::Const(..) => ParamKindOrd::Const,
695-
}, arg.span(), None)
696-
}), GenericPosition::Arg, generic_args.span());
708+
validate_generics_order(
709+
self.session,
710+
self.err_handler(),
711+
data.args.iter().map(|arg| {
712+
(match arg {
713+
GenericArg::Lifetime(..) => ParamKindOrd::Lifetime,
714+
GenericArg::Type(..) => ParamKindOrd::Type,
715+
GenericArg::Const(..) => ParamKindOrd::Const,
716+
}, None, arg.span(), None)
717+
}),
718+
GenericPosition::Arg,
719+
generic_args.span(),
720+
);
697721

698722
// Type bindings such as `Item=impl Debug` in `Iterator<Item=Debug>`
699723
// are allowed to contain nested `impl Trait`.
@@ -726,18 +750,24 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
726750
}
727751
}
728752

729-
validate_generics_order(self.err_handler(), generics.params.iter().map(|param| {
730-
let span = param.ident.span;
731-
let ident = Some(param.ident.to_string());
732-
match &param.kind {
733-
GenericParamKind::Lifetime { .. } => (ParamKindOrd::Lifetime, span, ident),
734-
GenericParamKind::Type { .. } => (ParamKindOrd::Type, span, ident),
735-
GenericParamKind::Const { ref ty } => {
736-
let ty = pprust::ty_to_string(ty);
737-
(ParamKindOrd::Const, span, Some(format!("const {}: {}", param.ident, ty)))
738-
}
739-
}
740-
}), GenericPosition::Param, generics.span);
753+
validate_generics_order(
754+
self.session,
755+
self.err_handler(),
756+
generics.params.iter().map(|param| {
757+
let ident = Some(param.ident.to_string());
758+
let (kind, ident) = match &param.kind {
759+
GenericParamKind::Lifetime { .. } => (ParamKindOrd::Lifetime, ident),
760+
GenericParamKind::Type { .. } => (ParamKindOrd::Type, ident),
761+
GenericParamKind::Const { ref ty } => {
762+
let ty = pprust::ty_to_string(ty);
763+
(ParamKindOrd::Const, Some(format!("const {}: {}", param.ident, ty)))
764+
}
765+
};
766+
(kind, Some(&*param.bounds), param.ident.span, ident)
767+
}),
768+
GenericPosition::Param,
769+
generics.span,
770+
);
741771

742772
for predicate in &generics.where_clause.predicates {
743773
if let WherePredicate::EqPredicate(ref predicate) = *predicate {

src/test/ui/issue-59508-1.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![allow(dead_code)]
2+
#![feature(const_generics)]
3+
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
4+
5+
// This test checks that generic parameter re-ordering diagnostic suggestions mention that
6+
// consts come after types and lifetimes when the `const_generics` feature is enabled.
7+
// We cannot run rustfix on this test because of the above const generics warning.
8+
9+
struct A;
10+
11+
impl A {
12+
pub fn do_things<T, 'a, 'b: 'a>() {
13+
//~^ ERROR lifetime parameters must be declared prior to type parameters
14+
println!("panic");
15+
}
16+
}
17+
18+
fn main() {}

src/test/ui/issue-59508-1.stderr

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
2+
--> $DIR/issue-59508-1.rs:2:12
3+
|
4+
LL | #![feature(const_generics)]
5+
| ^^^^^^^^^^^^^^
6+
7+
error: lifetime parameters must be declared prior to type parameters
8+
--> $DIR/issue-59508-1.rs:12:25
9+
|
10+
LL | pub fn do_things<T, 'a, 'b: 'a>() {
11+
| ----^^--^^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b: 'a, T>`
12+
13+
error: aborting due to previous error
14+

src/test/ui/issue-59508.fixed

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// run-rustfix
2+
3+
#![allow(dead_code)]
4+
5+
// This test checks that generic parameter re-ordering diagnostic suggestions contain bounds.
6+
7+
struct A;
8+
9+
impl A {
10+
pub fn do_things<'a, 'b: 'a, T>() {
11+
//~^ ERROR lifetime parameters must be declared prior to type parameters
12+
println!("panic");
13+
}
14+
}
15+
16+
fn main() {}

src/test/ui/issue-59508.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// run-rustfix
2+
3+
#![allow(dead_code)]
4+
5+
// This test checks that generic parameter re-ordering diagnostic suggestions contain bounds.
6+
7+
struct A;
8+
9+
impl A {
10+
pub fn do_things<T, 'a, 'b: 'a>() {
11+
//~^ ERROR lifetime parameters must be declared prior to type parameters
12+
println!("panic");
13+
}
14+
}
15+
16+
fn main() {}

src/test/ui/issue-59508.stderr

+8
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-59508.rs:10:25
3+
|
4+
LL | pub fn do_things<T, 'a, 'b: 'a>() {
5+
| ----^^--^^----- help: reorder the parameters: lifetimes, then types: `<'a, 'b: 'a, T>`
6+
7+
error: aborting due to previous error
8+

src/test/ui/lifetime-before-type-params.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,25 @@ error: lifetime parameters must be declared prior to type parameters
22
--> $DIR/lifetime-before-type-params.rs:2:13
33
|
44
LL | fn first<T, 'a, 'b>() {}
5-
| ----^^--^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
5+
| ----^^--^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
66

77
error: lifetime parameters must be declared prior to type parameters
88
--> $DIR/lifetime-before-type-params.rs:4:18
99
|
1010
LL | fn second<'a, T, 'b>() {}
11-
| --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
11+
| --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
1212

1313
error: lifetime parameters must be declared prior to type parameters
1414
--> $DIR/lifetime-before-type-params.rs:6:16
1515
|
1616
LL | fn third<T, U, 'a>() {}
17-
| -------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, U>`
17+
| -------^^- help: reorder the parameters: lifetimes, then types: `<'a, T, U>`
1818

1919
error: lifetime parameters must be declared prior to type parameters
2020
--> $DIR/lifetime-before-type-params.rs:8:18
2121
|
2222
LL | fn fourth<'a, T, 'b, U, 'c, V>() {}
23-
| --------^^-----^^---- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, 'c, T, U, V>`
23+
| --------^^-----^^---- help: reorder the parameters: lifetimes, then types: `<'a, 'b, 'c, T, U, V>`
2424

2525
error[E0601]: `main` function not found in crate `lifetime_before_type_params`
2626
|

src/test/ui/parser/issue-14303-enum.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to type parameters
22
--> $DIR/issue-14303-enum.rs:1:15
33
|
44
LL | enum X<'a, T, 'b> {
5-
| --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
5+
| --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
66

77
error: aborting due to previous error
88

src/test/ui/parser/issue-14303-fn-def.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to type parameters
22
--> $DIR/issue-14303-fn-def.rs:1:15
33
|
44
LL | fn foo<'a, T, 'b>(x: &'a T) {}
5-
| --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
5+
| --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
66

77
error: aborting due to previous error
88

src/test/ui/parser/issue-14303-impl.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to type parameters
22
--> $DIR/issue-14303-impl.rs:3:13
33
|
44
LL | impl<'a, T, 'b> X<T> {}
5-
| --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
5+
| --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
66

77
error: aborting due to previous error
88

src/test/ui/parser/issue-14303-struct.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to type parameters
22
--> $DIR/issue-14303-struct.rs:1:17
33
|
44
LL | struct X<'a, T, 'b> {
5-
| --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
5+
| --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
66

77
error: aborting due to previous error
88

src/test/ui/parser/issue-14303-trait.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to type parameters
22
--> $DIR/issue-14303-trait.rs:1:18
33
|
44
LL | trait Foo<'a, T, 'b> {}
5-
| --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
5+
| --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
66

77
error: aborting due to previous error
88

src/test/ui/suggestions/suggest-move-lifetimes.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,25 @@ error: lifetime parameters must be declared prior to type parameters
22
--> $DIR/suggest-move-lifetimes.rs:1:13
33
|
44
LL | struct A<T, 'a> {
5-
| ----^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T>`
5+
| ----^^- help: reorder the parameters: lifetimes, then types: `<'a, T>`
66

77
error: lifetime parameters must be declared prior to type parameters
88
--> $DIR/suggest-move-lifetimes.rs:5:13
99
|
1010
LL | struct B<T, 'a, U> {
11-
| ----^^---- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, U>`
11+
| ----^^---- help: reorder the parameters: lifetimes, then types: `<'a, T, U>`
1212

1313
error: lifetime parameters must be declared prior to type parameters
1414
--> $DIR/suggest-move-lifetimes.rs:10:16
1515
|
1616
LL | struct C<T, U, 'a> {
17-
| -------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, U>`
17+
| -------^^- help: reorder the parameters: lifetimes, then types: `<'a, T, U>`
1818

1919
error: lifetime parameters must be declared prior to type parameters
2020
--> $DIR/suggest-move-lifetimes.rs:15:16
2121
|
2222
LL | struct D<T, U, 'a, 'b, V, 'c> {
23-
| -------^^--^^-----^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, 'c, T, U, V>`
23+
| -------^^--^^-----^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, 'c, T, U, V>`
2424

2525
error: aborting due to 4 previous errors
2626

0 commit comments

Comments
 (0)