Point at all constraints before args

This commit is contained in:
Esteban Küber 2020-03-28 13:48:04 -07:00
parent b9d5ee5676
commit 33d793c326
3 changed files with 86 additions and 54 deletions

View file

@ -14,7 +14,7 @@ use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
use rustc_ast::walk_list;
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{error_code, struct_span_err, Applicability};
use rustc_errors::{error_code, pluralize, struct_span_err, Applicability};
use rustc_parse::validate_attr;
use rustc_session::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY;
use rustc_session::lint::LintBuffer;
@ -647,24 +647,38 @@ impl<'a> AstValidator<'a> {
return;
}
// Find all generic argument coming after the first constraint...
let mut misplaced_args = Vec::new();
let mut first = None;
for arg in &data.args {
match (arg, first) {
(AngleBracketedArg::Arg(a), Some(_)) => misplaced_args.push(a.span()),
(AngleBracketedArg::Constraint(c), None) => first = Some(c.span),
(AngleBracketedArg::Arg(_), None) | (AngleBracketedArg::Constraint(_), Some(_)) => {
}
}
}
let constraint_spans = data
.args
.iter()
.filter_map(|arg| match arg {
AngleBracketedArg::Constraint(c) => Some(c.span),
_ => None,
})
.collect::<Vec<_>>();
let arg_spans = data
.args
.iter()
.filter_map(|arg| match arg {
AngleBracketedArg::Arg(a) => Some(a.span()),
_ => None,
})
.collect::<Vec<_>>();
let constraint_len = constraint_spans.len();
// ...and then error:
self.err_handler()
.struct_span_err(
misplaced_args.clone(),
arg_spans.clone(),
"generic arguments must come before the first constraint",
)
.span_label(first.unwrap(), "the first constraint is provided here")
.span_labels(misplaced_args, "generic argument")
.span_labels(
constraint_spans,
&format!(
"the constraint{} {} provided here",
pluralize!(constraint_len),
if constraint_len == 1 { "is" } else { "are" }
),
)
.span_labels(arg_spans, "generic argument")
.emit();
}
}

View file

@ -4,7 +4,7 @@ error: generic arguments must come before the first constraint
LL | pub fn test<W, I: Trait<Item=(), W> >() {}
| ------- ^ generic argument
| |
| the first constraint is provided here
| the constraint is provided here
error: aborting due to previous error

View file

@ -4,7 +4,7 @@ error: generic arguments must come before the first constraint
LL | struct A<T, M: One<A=(), T>> {
| ---- ^ generic argument
| |
| the first constraint is provided here
| the constraint is provided here
error: generic arguments must come before the first constraint
--> $DIR/suggest-move-types.rs:33:43
@ -13,70 +13,88 @@ LL | struct Al<'a, T, M: OneWithLifetime<A=(), T, 'a>> {
| ---- ^ ^^ generic argument
| | |
| | generic argument
| the first constraint is provided here
| the constraint is provided here
error: generic arguments must come before the first constraint
--> $DIR/suggest-move-types.rs:40:46
|
LL | struct B<T, U, V, M: Three<A=(), B=(), C=(), T, U, V>> {
| ---- ^ ^ ^ generic argument
| | | |
| | | generic argument
| | generic argument
| the first constraint is provided here
| ---- ---- ---- ^ ^ ^ generic argument
| | | | | |
| | | | | generic argument
| | | | generic argument
| | | the constraints are provided here
| | the constraints are provided here
| the constraints are provided here
error: generic arguments must come before the first constraint
--> $DIR/suggest-move-types.rs:48:71
|
LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), C=(), T, U, V, 'a, 'b, 'c>> {
| ---- ^ ^ ^ ^^ ^^ ^^ generic argument
| | | | | | |
| | | | | | generic argument
| | | | | generic argument
| | | | generic argument
| | | generic argument
| | generic argument
| the first constraint is provided here
| ---- ---- ---- ^ ^ ^ ^^ ^^ ^^ generic argument
| | | | | | | | |
| | | | | | | | generic argument
| | | | | | | generic argument
| | | | | | generic argument
| | | | | generic argument
| | | | generic argument
| | | the constraints are provided here
| | the constraints are provided here
| the constraints are provided here
error: generic arguments must come before the first constraint
--> $DIR/suggest-move-types.rs:57:49
--> $DIR/suggest-move-types.rs:57:28
|
LL | struct C<T, U, V, M: Three<T, A=(), B=(), C=(), U, V>> {
| ---- ^ ^ generic argument
| | |
| | generic argument
| the first constraint is provided here
| ^ ---- ---- ---- ^ ^ generic argument
| | | | | |
| | | | | generic argument
| | | | the constraints are provided here
| | | the constraints are provided here
| | the constraints are provided here
| generic argument
error: generic arguments must come before the first constraint
--> $DIR/suggest-move-types.rs:65:78
--> $DIR/suggest-move-types.rs:65:53
|
LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), C=(), U, 'b, V, 'c>> {
| ---- ^ ^^ ^ ^^ generic argument
| | | | |
| | | | generic argument
| | | generic argument
| | generic argument
| the first constraint is provided here
| ^ ^^ ---- ---- ---- ^ ^^ ^ ^^ generic argument
| | | | | | | | |
| | | | | | | | generic argument
| | | | | | | generic argument
| | | | | | generic argument
| | | | | the constraints are provided here
| | | | the constraints are provided here
| | | the constraints are provided here
| | generic argument
| generic argument
error: generic arguments must come before the first constraint
--> $DIR/suggest-move-types.rs:74:43
--> $DIR/suggest-move-types.rs:74:28
|
LL | struct D<T, U, V, M: Three<T, A=(), B=(), U, C=(), V>> {
| ---- ^ ^ generic argument
| | |
| | generic argument
| the first constraint is provided here
| ^ ---- ---- ^ ---- ^ generic argument
| | | | | |
| | | | | the constraints are provided here
| | | | generic argument
| | | the constraints are provided here
| | the constraints are provided here
| generic argument
error: generic arguments must come before the first constraint
--> $DIR/suggest-move-types.rs:82:72
--> $DIR/suggest-move-types.rs:82:53
|
LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), U, 'b, C=(), V, 'c>> {
| ---- ^ ^^ ^ ^^ generic argument
| | | | |
| | | | generic argument
| | | generic argument
| | generic argument
| the first constraint is provided here
| ^ ^^ ---- ---- ^ ^^ ---- ^ ^^ generic argument
| | | | | | | | |
| | | | | | | | generic argument
| | | | | | | the constraints are provided here
| | | | | | generic argument
| | | | | generic argument
| | | | the constraints are provided here
| | | the constraints are provided here
| | generic argument
| generic argument
error[E0747]: type provided when a lifetime was expected
--> $DIR/suggest-move-types.rs:33:43