Skip to content

Commit 2566b41

Browse files
committed
Point error span at Some constructor argument when trait resolution fails
1 parent 7281249 commit 2566b41

File tree

4 files changed

+103
-9
lines changed

4 files changed

+103
-9
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -714,12 +714,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
714714
self.tcx.parent(expr_ctor_def_id)
715715
}
716716
hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, hir::def::CtorKind::Fn) => {
717-
// If this is a variant, its parent is the type definition.
718-
if in_ty_adt.did() != self.tcx.parent(expr_ctor_def_id) {
719-
// FIXME: Deal with type aliases?
717+
if in_ty_adt.did() == self.tcx.parent(expr_ctor_def_id) {
718+
// The constructor definition refers to the variant:
719+
// For example, for a local type `MyEnum::MyVariant` triggers this case.
720+
expr_ctor_def_id
721+
} else if in_ty_adt.did() == self.tcx.parent(self.tcx.parent(expr_ctor_def_id))
722+
{
723+
// The constructor definition refers to the "constructor" of the variant:
724+
// For example, `Some(5)` triggers this case.
725+
self.tcx.parent(expr_ctor_def_id)
726+
} else {
720727
return Err(expr);
721728
}
722-
expr_ctor_def_id
723729
}
724730
_ => {
725731
return Err(expr);

tests/ui/errors/trait-bound-error-spans/blame-trait-error.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,24 @@ struct Burrito<F> {
1818
filling: F,
1919
}
2020

21+
impl<It: Iterator> T1 for Option<It> {}
22+
23+
impl<'a, A: T1> T1 for &'a A {}
24+
2125
fn want<V: T1>(_x: V) {}
2226

2327
fn example<Q>(q: Q) {
2428
want(Wrapper { value: Burrito { filling: q } });
2529
//~^ ERROR the trait bound `Q: T3` is not satisfied [E0277]
30+
31+
want(Some(()));
32+
//~^ ERROR `()` is not an iterator [E0277]
33+
34+
want(Some(q));
35+
//~^ ERROR `Q` is not an iterator [E0277]
36+
37+
want(&Some(q));
38+
//~^ ERROR `Q` is not an iterator [E0277]
2639
}
2740

2841
fn main() {}

tests/ui/errors/trait-bound-error-spans/blame-trait-error.stderr

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0277]: the trait bound `Q: T3` is not satisfied
2-
--> $DIR/blame-trait-error.rs:24:46
2+
--> $DIR/blame-trait-error.rs:28:46
33
|
44
LL | want(Wrapper { value: Burrito { filling: q } });
55
| ---- ^ the trait `T3` is not implemented for `Q`
@@ -21,7 +21,7 @@ LL | impl<B: T2> T1 for Wrapper<B> {}
2121
| |
2222
| unsatisfied trait bound introduced here
2323
note: required by a bound in `want`
24-
--> $DIR/blame-trait-error.rs:21:12
24+
--> $DIR/blame-trait-error.rs:25:12
2525
|
2626
LL | fn want<V: T1>(_x: V) {}
2727
| ^^ required by this bound in `want`
@@ -30,6 +30,81 @@ help: consider restricting type parameter `Q`
3030
LL | fn example<Q: T3>(q: Q) {
3131
| ++++
3232

33-
error: aborting due to previous error
33+
error[E0277]: `()` is not an iterator
34+
--> $DIR/blame-trait-error.rs:31:15
35+
|
36+
LL | want(Some(()));
37+
| ---- ^^ `()` is not an iterator
38+
| |
39+
| required by a bound introduced by this call
40+
|
41+
= help: the trait `Iterator` is not implemented for `()`
42+
= help: the trait `T1` is implemented for `Option<It>`
43+
note: required for `Option<()>` to implement `T1`
44+
--> $DIR/blame-trait-error.rs:21:20
45+
|
46+
LL | impl<It: Iterator> T1 for Option<It> {}
47+
| -------- ^^ ^^^^^^^^^^
48+
| |
49+
| unsatisfied trait bound introduced here
50+
note: required by a bound in `want`
51+
--> $DIR/blame-trait-error.rs:25:12
52+
|
53+
LL | fn want<V: T1>(_x: V) {}
54+
| ^^ required by this bound in `want`
55+
56+
error[E0277]: `Q` is not an iterator
57+
--> $DIR/blame-trait-error.rs:34:15
58+
|
59+
LL | want(Some(q));
60+
| ---- ^ `Q` is not an iterator
61+
| |
62+
| required by a bound introduced by this call
63+
|
64+
note: required for `Option<Q>` to implement `T1`
65+
--> $DIR/blame-trait-error.rs:21:20
66+
|
67+
LL | impl<It: Iterator> T1 for Option<It> {}
68+
| -------- ^^ ^^^^^^^^^^
69+
| |
70+
| unsatisfied trait bound introduced here
71+
note: required by a bound in `want`
72+
--> $DIR/blame-trait-error.rs:25:12
73+
|
74+
LL | fn want<V: T1>(_x: V) {}
75+
| ^^ required by this bound in `want`
76+
help: consider restricting type parameter `Q`
77+
|
78+
LL | fn example<Q: std::iter::Iterator>(q: Q) {
79+
| +++++++++++++++++++++
80+
81+
error[E0277]: `Q` is not an iterator
82+
--> $DIR/blame-trait-error.rs:37:16
83+
|
84+
LL | want(&Some(q));
85+
| ---- ^ `Q` is not an iterator
86+
| |
87+
| required by a bound introduced by this call
88+
|
89+
note: required for `Option<Q>` to implement `T1`
90+
--> $DIR/blame-trait-error.rs:21:20
91+
|
92+
LL | impl<It: Iterator> T1 for Option<It> {}
93+
| -------- ^^ ^^^^^^^^^^
94+
| |
95+
| unsatisfied trait bound introduced here
96+
= note: 1 redundant requirement hidden
97+
= note: required for `&Option<Q>` to implement `T1`
98+
note: required by a bound in `want`
99+
--> $DIR/blame-trait-error.rs:25:12
100+
|
101+
LL | fn want<V: T1>(_x: V) {}
102+
| ^^ required by this bound in `want`
103+
help: consider restricting type parameter `Q`
104+
|
105+
LL | fn example<Q: std::iter::Iterator>(q: Q) {
106+
| +++++++++++++++++++++
107+
108+
error: aborting due to 4 previous errors
34109

35110
For more information about this error, try `rustc --explain E0277`.

tests/ui/errors/traits/blame-trait-error-spans-on-exprs.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,10 @@ LL | fn example<Q: T3>(q: Q) {
9191
| ++++
9292

9393
error[E0277]: the trait bound `Q: T3` is not satisfied
94-
--> $DIR/blame-trait-error-spans-on-exprs.rs:93:27
94+
--> $DIR/blame-trait-error-spans-on-exprs.rs:93:53
9595
|
9696
LL | want(Wrapper { value: TacoKinds::OneTaco(false, q) });
97-
| ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `T3` is not implemented for `Q`
97+
| ---- ^ the trait `T3` is not implemented for `Q`
9898
| |
9999
| required by a bound introduced by this call
100100
|

0 commit comments

Comments
 (0)