Point at all constraints before args
This commit is contained in:
parent
b9d5ee5676
commit
33d793c326
3 changed files with 86 additions and 54 deletions
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue