Skip to content

Commit abdcb86

Browse files
committed
Point at every unexpected lifetime and type argument in E0107
1 parent 910ec6d commit abdcb86

File tree

5 files changed

+69
-29
lines changed

5 files changed

+69
-29
lines changed

src/librustc_typeck/astconv.rs

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -338,33 +338,31 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
338338
(required, "")
339339
};
340340

341-
let mut span = span;
342-
let label = if required == permitted && provided > permitted {
343-
let diff = provided - permitted;
344-
if diff == 1 {
345-
// In the case when the user has provided too many arguments,
346-
// we want to point to the first unexpected argument.
347-
let first_superfluous_arg: &GenericArg = &args.args[offset + permitted];
348-
span = first_superfluous_arg.span();
349-
}
350-
format!(
351-
"{}unexpected {} argument{}",
352-
if diff != 1 { format!("{} ", diff) } else { String::new() },
353-
kind,
354-
if diff != 1 { "s" } else { "" },
341+
let (spans, label) = if required == permitted && provided > permitted {
342+
// In the case when the user has provided too many arguments,
343+
// we want to point to the unexpected arguments.
344+
(
345+
args.args[offset+permitted .. offset+provided]
346+
.iter()
347+
.map(|arg| arg.span())
348+
.collect(),
349+
format!(
350+
"unexpected {} argument",
351+
kind,
352+
),
355353
)
356354
} else {
357-
format!(
355+
(vec![span], format!(
358356
"expected {}{} {} argument{}",
359357
quantifier,
360358
bound,
361359
kind,
362360
if bound != 1 { "s" } else { "" },
363-
)
361+
))
364362
};
365363

366-
tcx.sess.struct_span_err_with_code(
367-
span,
364+
let mut err = tcx.sess.struct_span_err_with_code(
365+
spans.clone(),
368366
&format!(
369367
"wrong number of {} arguments: expected {}{}, found {}",
370368
kind,
@@ -373,7 +371,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
373371
provided,
374372
),
375373
DiagnosticId::Error("E0107".into())
376-
).span_label(span, label).emit();
374+
);
375+
for span in spans {
376+
err.span_label(span, label.as_str());
377+
}
378+
err.emit();
377379

378380
provided > required // `suppress_error`
379381
};
@@ -1030,13 +1032,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
10301032
for item_def_id in associated_types {
10311033
let assoc_item = tcx.associated_item(item_def_id);
10321034
let trait_def_id = assoc_item.container.id();
1033-
struct_span_err!(tcx.sess, span, E0191, "the value of the associated type `{}` \
1034-
(from the trait `{}`) must be specified",
1035-
assoc_item.ident,
1036-
tcx.item_path_str(trait_def_id))
1037-
.span_label(span, format!("missing associated type `{}` value",
1038-
assoc_item.ident))
1039-
.emit();
1035+
let mut err = struct_span_err!(
1036+
tcx.sess,
1037+
span,
1038+
E0191,
1039+
"the value of the associated type `{}` (from the trait `{}`) must be specified",
1040+
assoc_item.ident,
1041+
tcx.item_path_str(trait_def_id),
1042+
);
1043+
err.span_label(span, format!("missing associated type `{}` value", assoc_item.ident));
1044+
err.emit();
10401045
}
10411046

10421047
// Erase the `dummy_self` (`TRAIT_OBJECT_DUMMY_SELF`) used above.

src/test/ui/error-codes/E0107-b.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
pub trait T<X, Y> {
2+
type A;
3+
type B;
4+
type C;
5+
}
6+
pub struct Foo { i: Box<T<usize, usize, usize, usize, B=usize>> }
7+
8+
fn main() {}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0107]: wrong number of type arguments: expected 2, found 4
2+
--> $DIR/E0107-b.rs:6:42
3+
|
4+
LL | pub struct Foo { i: Box<T<usize, usize, usize, usize, B=usize>> }
5+
| ^^^^^ ^^^^^ unexpected type argument
6+
| |
7+
| unexpected type argument
8+
9+
error[E0191]: the value of the associated type `A` (from the trait `T`) must be specified
10+
--> $DIR/E0107-b.rs:6:26
11+
|
12+
LL | pub struct Foo { i: Box<T<usize, usize, usize, usize, B=usize>> }
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing associated type `A` value
14+
15+
error[E0191]: the value of the associated type `C` (from the trait `T`) must be specified
16+
--> $DIR/E0107-b.rs:6:26
17+
|
18+
LL | pub struct Foo { i: Box<T<usize, usize, usize, usize, B=usize>> }
19+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing associated type `C` value
20+
21+
error: aborting due to 3 previous errors
22+
23+
Some errors occurred: E0107, E0191.
24+
For more information about an error, try `rustc --explain E0107`.

src/test/ui/error-codes/E0107.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ struct Baz<'a, 'b, 'c> {
2626
//~| unexpected lifetime argument
2727
foo2: Foo<'a, 'b, 'c>,
2828
//~^ ERROR E0107
29-
//~| 2 unexpected lifetime arguments
29+
//~| unexpected lifetime argument
30+
//~| unexpected lifetime argument
3031
}
3132

3233
fn main() {}

src/test/ui/error-codes/E0107.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ LL | bar: Bar<'a>,
1111
| ^^ unexpected lifetime argument
1212

1313
error[E0107]: wrong number of lifetime arguments: expected 1, found 3
14-
--> $DIR/E0107.rs:27:11
14+
--> $DIR/E0107.rs:27:19
1515
|
1616
LL | foo2: Foo<'a, 'b, 'c>,
17-
| ^^^^^^^^^^^^^^^ 2 unexpected lifetime arguments
17+
| ^^ ^^ unexpected lifetime argument
18+
| |
19+
| unexpected lifetime argument
1820

1921
error: aborting due to 3 previous errors
2022

0 commit comments

Comments
 (0)