Skip to content

Commit 33d793c

Browse files
committed
Point at all constraints before args
1 parent b9d5ee5 commit 33d793c

File tree

3 files changed

+86
-54
lines changed

3 files changed

+86
-54
lines changed

src/librustc_ast_passes/ast_validation.rs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
1414
use rustc_ast::walk_list;
1515
use rustc_ast_pretty::pprust;
1616
use rustc_data_structures::fx::FxHashMap;
17-
use rustc_errors::{error_code, struct_span_err, Applicability};
17+
use rustc_errors::{error_code, pluralize, struct_span_err, Applicability};
1818
use rustc_parse::validate_attr;
1919
use rustc_session::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY;
2020
use rustc_session::lint::LintBuffer;
@@ -647,24 +647,38 @@ impl<'a> AstValidator<'a> {
647647
return;
648648
}
649649
// Find all generic argument coming after the first constraint...
650-
let mut misplaced_args = Vec::new();
651-
let mut first = None;
652-
for arg in &data.args {
653-
match (arg, first) {
654-
(AngleBracketedArg::Arg(a), Some(_)) => misplaced_args.push(a.span()),
655-
(AngleBracketedArg::Constraint(c), None) => first = Some(c.span),
656-
(AngleBracketedArg::Arg(_), None) | (AngleBracketedArg::Constraint(_), Some(_)) => {
657-
}
658-
}
659-
}
650+
let constraint_spans = data
651+
.args
652+
.iter()
653+
.filter_map(|arg| match arg {
654+
AngleBracketedArg::Constraint(c) => Some(c.span),
655+
_ => None,
656+
})
657+
.collect::<Vec<_>>();
658+
let arg_spans = data
659+
.args
660+
.iter()
661+
.filter_map(|arg| match arg {
662+
AngleBracketedArg::Arg(a) => Some(a.span()),
663+
_ => None,
664+
})
665+
.collect::<Vec<_>>();
666+
let constraint_len = constraint_spans.len();
660667
// ...and then error:
661668
self.err_handler()
662669
.struct_span_err(
663-
misplaced_args.clone(),
670+
arg_spans.clone(),
664671
"generic arguments must come before the first constraint",
665672
)
666-
.span_label(first.unwrap(), "the first constraint is provided here")
667-
.span_labels(misplaced_args, "generic argument")
673+
.span_labels(
674+
constraint_spans,
675+
&format!(
676+
"the constraint{} {} provided here",
677+
pluralize!(constraint_len),
678+
if constraint_len == 1 { "is" } else { "are" }
679+
),
680+
)
681+
.span_labels(arg_spans, "generic argument")
668682
.emit();
669683
}
670684
}

src/test/ui/parser/issue-32214.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error: generic arguments must come before the first constraint
44
LL | pub fn test<W, I: Trait<Item=(), W> >() {}
55
| ------- ^ generic argument
66
| |
7-
| the first constraint is provided here
7+
| the constraint is provided here
88

99
error: aborting due to previous error
1010

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

Lines changed: 57 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error: generic arguments must come before the first constraint
44
LL | struct A<T, M: One<A=(), T>> {
55
| ---- ^ generic argument
66
| |
7-
| the first constraint is provided here
7+
| the constraint is provided here
88

99
error: generic arguments must come before the first constraint
1010
--> $DIR/suggest-move-types.rs:33:43
@@ -13,70 +13,88 @@ LL | struct Al<'a, T, M: OneWithLifetime<A=(), T, 'a>> {
1313
| ---- ^ ^^ generic argument
1414
| | |
1515
| | generic argument
16-
| the first constraint is provided here
16+
| the constraint is provided here
1717

1818
error: generic arguments must come before the first constraint
1919
--> $DIR/suggest-move-types.rs:40:46
2020
|
2121
LL | struct B<T, U, V, M: Three<A=(), B=(), C=(), T, U, V>> {
22-
| ---- ^ ^ ^ generic argument
23-
| | | |
24-
| | | generic argument
25-
| | generic argument
26-
| the first constraint is provided here
22+
| ---- ---- ---- ^ ^ ^ generic argument
23+
| | | | | |
24+
| | | | | generic argument
25+
| | | | generic argument
26+
| | | the constraints are provided here
27+
| | the constraints are provided here
28+
| the constraints are provided here
2729

2830
error: generic arguments must come before the first constraint
2931
--> $DIR/suggest-move-types.rs:48:71
3032
|
3133
LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), C=(), T, U, V, 'a, 'b, 'c>> {
32-
| ---- ^ ^ ^ ^^ ^^ ^^ generic argument
33-
| | | | | | |
34-
| | | | | | generic argument
35-
| | | | | generic argument
36-
| | | | generic argument
37-
| | | generic argument
38-
| | generic argument
39-
| the first constraint is provided here
34+
| ---- ---- ---- ^ ^ ^ ^^ ^^ ^^ generic argument
35+
| | | | | | | | |
36+
| | | | | | | | generic argument
37+
| | | | | | | generic argument
38+
| | | | | | generic argument
39+
| | | | | generic argument
40+
| | | | generic argument
41+
| | | the constraints are provided here
42+
| | the constraints are provided here
43+
| the constraints are provided here
4044

4145
error: generic arguments must come before the first constraint
42-
--> $DIR/suggest-move-types.rs:57:49
46+
--> $DIR/suggest-move-types.rs:57:28
4347
|
4448
LL | struct C<T, U, V, M: Three<T, A=(), B=(), C=(), U, V>> {
45-
| ---- ^ ^ generic argument
46-
| | |
47-
| | generic argument
48-
| the first constraint is provided here
49+
| ^ ---- ---- ---- ^ ^ generic argument
50+
| | | | | |
51+
| | | | | generic argument
52+
| | | | the constraints are provided here
53+
| | | the constraints are provided here
54+
| | the constraints are provided here
55+
| generic argument
4956

5057
error: generic arguments must come before the first constraint
51-
--> $DIR/suggest-move-types.rs:65:78
58+
--> $DIR/suggest-move-types.rs:65:53
5259
|
5360
LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), C=(), U, 'b, V, 'c>> {
54-
| ---- ^ ^^ ^ ^^ generic argument
55-
| | | | |
56-
| | | | generic argument
57-
| | | generic argument
58-
| | generic argument
59-
| the first constraint is provided here
61+
| ^ ^^ ---- ---- ---- ^ ^^ ^ ^^ generic argument
62+
| | | | | | | | |
63+
| | | | | | | | generic argument
64+
| | | | | | | generic argument
65+
| | | | | | generic argument
66+
| | | | | the constraints are provided here
67+
| | | | the constraints are provided here
68+
| | | the constraints are provided here
69+
| | generic argument
70+
| generic argument
6071

6172
error: generic arguments must come before the first constraint
62-
--> $DIR/suggest-move-types.rs:74:43
73+
--> $DIR/suggest-move-types.rs:74:28
6374
|
6475
LL | struct D<T, U, V, M: Three<T, A=(), B=(), U, C=(), V>> {
65-
| ---- ^ ^ generic argument
66-
| | |
67-
| | generic argument
68-
| the first constraint is provided here
76+
| ^ ---- ---- ^ ---- ^ generic argument
77+
| | | | | |
78+
| | | | | the constraints are provided here
79+
| | | | generic argument
80+
| | | the constraints are provided here
81+
| | the constraints are provided here
82+
| generic argument
6983

7084
error: generic arguments must come before the first constraint
71-
--> $DIR/suggest-move-types.rs:82:72
85+
--> $DIR/suggest-move-types.rs:82:53
7286
|
7387
LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), U, 'b, C=(), V, 'c>> {
74-
| ---- ^ ^^ ^ ^^ generic argument
75-
| | | | |
76-
| | | | generic argument
77-
| | | generic argument
78-
| | generic argument
79-
| the first constraint is provided here
88+
| ^ ^^ ---- ---- ^ ^^ ---- ^ ^^ generic argument
89+
| | | | | | | | |
90+
| | | | | | | | generic argument
91+
| | | | | | | the constraints are provided here
92+
| | | | | | generic argument
93+
| | | | | generic argument
94+
| | | | the constraints are provided here
95+
| | | the constraints are provided here
96+
| | generic argument
97+
| generic argument
8098

8199
error[E0747]: type provided when a lifetime was expected
82100
--> $DIR/suggest-move-types.rs:33:43

0 commit comments

Comments
 (0)