Rollup merge of #59572 - davidtwco:issue-59508, r=varkor
Include bounds in generic re-ordering diagnostic Fixes #59508. r? @estebank cc @varkor
This commit is contained in:
commit
61222b5731
@ -352,8 +352,16 @@ enum GenericPosition {
|
||||
}
|
||||
|
||||
fn validate_generics_order<'a>(
|
||||
sess: &Session,
|
||||
handler: &errors::Handler,
|
||||
generics: impl Iterator<Item = (ParamKindOrd, Span, Option<String>)>,
|
||||
generics: impl Iterator<
|
||||
Item = (
|
||||
ParamKindOrd,
|
||||
Option<&'a [GenericBound]>,
|
||||
Span,
|
||||
Option<String>
|
||||
),
|
||||
>,
|
||||
pos: GenericPosition,
|
||||
span: Span,
|
||||
) {
|
||||
@ -361,9 +369,9 @@ fn validate_generics_order<'a>(
|
||||
let mut out_of_order = FxHashMap::default();
|
||||
let mut param_idents = vec![];
|
||||
|
||||
for (kind, span, ident) in generics {
|
||||
for (kind, bounds, span, ident) in generics {
|
||||
if let Some(ident) = ident {
|
||||
param_idents.push((kind, param_idents.len(), ident));
|
||||
param_idents.push((kind, bounds, param_idents.len(), ident));
|
||||
}
|
||||
let max_param = &mut max_param;
|
||||
match max_param {
|
||||
@ -377,13 +385,19 @@ fn validate_generics_order<'a>(
|
||||
|
||||
let mut ordered_params = "<".to_string();
|
||||
if !out_of_order.is_empty() {
|
||||
param_idents.sort_by_key(|&(po, i, _)| (po, i));
|
||||
param_idents.sort_by_key(|&(po, _, i, _)| (po, i));
|
||||
let mut first = true;
|
||||
for (_, _, ident) in param_idents {
|
||||
for (_, bounds, _, ident) in param_idents {
|
||||
if !first {
|
||||
ordered_params += ", ";
|
||||
}
|
||||
ordered_params += &ident;
|
||||
if let Some(bounds) = bounds {
|
||||
if !bounds.is_empty() {
|
||||
ordered_params += ": ";
|
||||
ordered_params += &pprust::bounds_to_string(&bounds);
|
||||
}
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
@ -405,7 +419,11 @@ fn validate_generics_order<'a>(
|
||||
if let GenericPosition::Param = pos {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
&format!("reorder the {}s: lifetimes, then types, then consts", pos_str),
|
||||
&format!(
|
||||
"reorder the {}s: lifetimes, then types{}",
|
||||
pos_str,
|
||||
if sess.features_untracked().const_generics { ", then consts" } else { "" },
|
||||
),
|
||||
ordered_params.clone(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
@ -687,13 +705,19 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
match *generic_args {
|
||||
GenericArgs::AngleBracketed(ref data) => {
|
||||
walk_list!(self, visit_generic_arg, &data.args);
|
||||
validate_generics_order(self.err_handler(), data.args.iter().map(|arg| {
|
||||
(match arg {
|
||||
GenericArg::Lifetime(..) => ParamKindOrd::Lifetime,
|
||||
GenericArg::Type(..) => ParamKindOrd::Type,
|
||||
GenericArg::Const(..) => ParamKindOrd::Const,
|
||||
}, arg.span(), None)
|
||||
}), GenericPosition::Arg, generic_args.span());
|
||||
validate_generics_order(
|
||||
self.session,
|
||||
self.err_handler(),
|
||||
data.args.iter().map(|arg| {
|
||||
(match arg {
|
||||
GenericArg::Lifetime(..) => ParamKindOrd::Lifetime,
|
||||
GenericArg::Type(..) => ParamKindOrd::Type,
|
||||
GenericArg::Const(..) => ParamKindOrd::Const,
|
||||
}, None, arg.span(), None)
|
||||
}),
|
||||
GenericPosition::Arg,
|
||||
generic_args.span(),
|
||||
);
|
||||
|
||||
// Type bindings such as `Item=impl Debug` in `Iterator<Item=Debug>`
|
||||
// are allowed to contain nested `impl Trait`.
|
||||
@ -726,18 +750,24 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
validate_generics_order(self.err_handler(), generics.params.iter().map(|param| {
|
||||
let span = param.ident.span;
|
||||
let ident = Some(param.ident.to_string());
|
||||
match ¶m.kind {
|
||||
GenericParamKind::Lifetime { .. } => (ParamKindOrd::Lifetime, span, ident),
|
||||
GenericParamKind::Type { .. } => (ParamKindOrd::Type, span, ident),
|
||||
GenericParamKind::Const { ref ty } => {
|
||||
let ty = pprust::ty_to_string(ty);
|
||||
(ParamKindOrd::Const, span, Some(format!("const {}: {}", param.ident, ty)))
|
||||
}
|
||||
}
|
||||
}), GenericPosition::Param, generics.span);
|
||||
validate_generics_order(
|
||||
self.session,
|
||||
self.err_handler(),
|
||||
generics.params.iter().map(|param| {
|
||||
let ident = Some(param.ident.to_string());
|
||||
let (kind, ident) = match ¶m.kind {
|
||||
GenericParamKind::Lifetime { .. } => (ParamKindOrd::Lifetime, ident),
|
||||
GenericParamKind::Type { .. } => (ParamKindOrd::Type, ident),
|
||||
GenericParamKind::Const { ref ty } => {
|
||||
let ty = pprust::ty_to_string(ty);
|
||||
(ParamKindOrd::Const, Some(format!("const {}: {}", param.ident, ty)))
|
||||
}
|
||||
};
|
||||
(kind, Some(&*param.bounds), param.ident.span, ident)
|
||||
}),
|
||||
GenericPosition::Param,
|
||||
generics.span,
|
||||
);
|
||||
|
||||
for predicate in &generics.where_clause.predicates {
|
||||
if let WherePredicate::EqPredicate(ref predicate) = *predicate {
|
||||
|
18
src/test/ui/issue-59508-1.rs
Normal file
18
src/test/ui/issue-59508-1.rs
Normal file
@ -0,0 +1,18 @@
|
||||
#![allow(dead_code)]
|
||||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
|
||||
// This test checks that generic parameter re-ordering diagnostic suggestions mention that
|
||||
// consts come after types and lifetimes when the `const_generics` feature is enabled.
|
||||
// We cannot run rustfix on this test because of the above const generics warning.
|
||||
|
||||
struct A;
|
||||
|
||||
impl A {
|
||||
pub fn do_things<T, 'a, 'b: 'a>() {
|
||||
//~^ ERROR lifetime parameters must be declared prior to type parameters
|
||||
println!("panic");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
14
src/test/ui/issue-59508-1.stderr
Normal file
14
src/test/ui/issue-59508-1.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
--> $DIR/issue-59508-1.rs:2:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: lifetime parameters must be declared prior to type parameters
|
||||
--> $DIR/issue-59508-1.rs:12:25
|
||||
|
|
||||
LL | pub fn do_things<T, 'a, 'b: 'a>() {
|
||||
| ----^^--^^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b: 'a, T>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
16
src/test/ui/issue-59508.fixed
Normal file
16
src/test/ui/issue-59508.fixed
Normal file
@ -0,0 +1,16 @@
|
||||
// run-rustfix
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
// This test checks that generic parameter re-ordering diagnostic suggestions contain bounds.
|
||||
|
||||
struct A;
|
||||
|
||||
impl A {
|
||||
pub fn do_things<'a, 'b: 'a, T>() {
|
||||
//~^ ERROR lifetime parameters must be declared prior to type parameters
|
||||
println!("panic");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
16
src/test/ui/issue-59508.rs
Normal file
16
src/test/ui/issue-59508.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// run-rustfix
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
// This test checks that generic parameter re-ordering diagnostic suggestions contain bounds.
|
||||
|
||||
struct A;
|
||||
|
||||
impl A {
|
||||
pub fn do_things<T, 'a, 'b: 'a>() {
|
||||
//~^ ERROR lifetime parameters must be declared prior to type parameters
|
||||
println!("panic");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
8
src/test/ui/issue-59508.stderr
Normal file
8
src/test/ui/issue-59508.stderr
Normal file
@ -0,0 +1,8 @@
|
||||
error: lifetime parameters must be declared prior to type parameters
|
||||
--> $DIR/issue-59508.rs:10:25
|
||||
|
|
||||
LL | pub fn do_things<T, 'a, 'b: 'a>() {
|
||||
| ----^^--^^----- help: reorder the parameters: lifetimes, then types: `<'a, 'b: 'a, T>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -2,25 +2,25 @@ error: lifetime parameters must be declared prior to type parameters
|
||||
--> $DIR/lifetime-before-type-params.rs:2:13
|
||||
|
|
||||
LL | fn first<T, 'a, 'b>() {}
|
||||
| ----^^--^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
|
||||
| ----^^--^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
|
||||
|
||||
error: lifetime parameters must be declared prior to type parameters
|
||||
--> $DIR/lifetime-before-type-params.rs:4:18
|
||||
|
|
||||
LL | fn second<'a, T, 'b>() {}
|
||||
| --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
|
||||
| --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
|
||||
|
||||
error: lifetime parameters must be declared prior to type parameters
|
||||
--> $DIR/lifetime-before-type-params.rs:6:16
|
||||
|
|
||||
LL | fn third<T, U, 'a>() {}
|
||||
| -------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, U>`
|
||||
| -------^^- help: reorder the parameters: lifetimes, then types: `<'a, T, U>`
|
||||
|
||||
error: lifetime parameters must be declared prior to type parameters
|
||||
--> $DIR/lifetime-before-type-params.rs:8:18
|
||||
|
|
||||
LL | fn fourth<'a, T, 'b, U, 'c, V>() {}
|
||||
| --------^^-----^^---- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, 'c, T, U, V>`
|
||||
| --------^^-----^^---- help: reorder the parameters: lifetimes, then types: `<'a, 'b, 'c, T, U, V>`
|
||||
|
||||
error[E0601]: `main` function not found in crate `lifetime_before_type_params`
|
||||
|
|
||||
|
@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to type parameters
|
||||
--> $DIR/issue-14303-enum.rs:1:15
|
||||
|
|
||||
LL | enum X<'a, T, 'b> {
|
||||
| --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
|
||||
| --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to type parameters
|
||||
--> $DIR/issue-14303-fn-def.rs:1:15
|
||||
|
|
||||
LL | fn foo<'a, T, 'b>(x: &'a T) {}
|
||||
| --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
|
||||
| --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to type parameters
|
||||
--> $DIR/issue-14303-impl.rs:3:13
|
||||
|
|
||||
LL | impl<'a, T, 'b> X<T> {}
|
||||
| --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
|
||||
| --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to type parameters
|
||||
--> $DIR/issue-14303-struct.rs:1:17
|
||||
|
|
||||
LL | struct X<'a, T, 'b> {
|
||||
| --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
|
||||
| --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to type parameters
|
||||
--> $DIR/issue-14303-trait.rs:1:18
|
||||
|
|
||||
LL | trait Foo<'a, T, 'b> {}
|
||||
| --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
|
||||
| --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,25 +2,25 @@ error: lifetime parameters must be declared prior to type parameters
|
||||
--> $DIR/suggest-move-lifetimes.rs:1:13
|
||||
|
|
||||
LL | struct A<T, 'a> {
|
||||
| ----^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T>`
|
||||
| ----^^- help: reorder the parameters: lifetimes, then types: `<'a, T>`
|
||||
|
||||
error: lifetime parameters must be declared prior to type parameters
|
||||
--> $DIR/suggest-move-lifetimes.rs:5:13
|
||||
|
|
||||
LL | struct B<T, 'a, U> {
|
||||
| ----^^---- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, U>`
|
||||
| ----^^---- help: reorder the parameters: lifetimes, then types: `<'a, T, U>`
|
||||
|
||||
error: lifetime parameters must be declared prior to type parameters
|
||||
--> $DIR/suggest-move-lifetimes.rs:10:16
|
||||
|
|
||||
LL | struct C<T, U, 'a> {
|
||||
| -------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, U>`
|
||||
| -------^^- help: reorder the parameters: lifetimes, then types: `<'a, T, U>`
|
||||
|
||||
error: lifetime parameters must be declared prior to type parameters
|
||||
--> $DIR/suggest-move-lifetimes.rs:15:16
|
||||
|
|
||||
LL | struct D<T, U, 'a, 'b, V, 'c> {
|
||||
| -------^^--^^-----^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, 'c, T, U, V>`
|
||||
| -------^^--^^-----^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, 'c, T, U, V>`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user