Skip to content

Commit fbcca2a

Browse files
committed
Refine error span for trait error into borrowed expression
1 parent 7b55296 commit fbcca2a

File tree

4 files changed

+67
-16
lines changed

4 files changed

+67
-16
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs

+13
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
549549
return Err(expr);
550550
};
551551

552+
if let (
553+
hir::ExprKind::AddrOf(_borrow_kind, _borrow_mutability, borrowed_expr),
554+
ty::Ref(_ty_region, ty_ref_type, _ty_mutability),
555+
) = (&expr.kind, in_ty.kind())
556+
{
557+
// We can "drill into" the borrowed expression.
558+
return self.blame_specific_part_of_expr_corresponding_to_generic_param(
559+
param,
560+
borrowed_expr,
561+
(*ty_ref_type).into(),
562+
);
563+
}
564+
552565
if let (hir::ExprKind::Tup(expr_elements), ty::Tuple(in_ty_elements)) =
553566
(&expr.kind, in_ty.kind())
554567
{

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

+6
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ struct DoubleWrapper<T> {
7171

7272
impl<T: T1> T1 for DoubleWrapper<T> {}
7373

74+
impl<'a, T: T2> T1 for &'a T {}
75+
7476
fn example<Q>(q: Q) {
7577
// In each of the following examples, we expect the error span to point at the 'q' variable,
7678
// since the missing constraint is `Q: T3`.
@@ -126,6 +128,10 @@ fn example<Q>(q: Q) {
126128
Two { a: Two { a: (), b: Two { a: Two { a: (), b: q }, b: () } }, b: () },
127129
//~^ ERROR the trait bound `Q: T1` is not satisfied [E0277]
128130
);
131+
132+
// Verifies for reference:
133+
want(&Burrito { spicy: false, filling: q });
134+
//~^ ERROR the trait bound `Q: T3` is not satisfied [E0277]
129135
}
130136

131137
fn main() {}

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

+46-14
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-spans-on-exprs.rs:79:60
2+
--> $DIR/blame-trait-error-spans-on-exprs.rs:81:60
33
|
44
LL | want(Wrapper { value: Burrito { spicy: false, filling: q } });
55
| ---- required by a bound introduced by this call ^ the trait `T3` is not implemented for `Q`
@@ -29,7 +29,7 @@ LL | fn example<Q: T3>(q: Q) {
2929
| ++++
3030

3131
error[E0277]: the trait bound `Q: T3` is not satisfied
32-
--> $DIR/blame-trait-error-spans-on-exprs.rs:83:84
32+
--> $DIR/blame-trait-error-spans-on-exprs.rs:85:84
3333
|
3434
LL | want(Wrapper { value: BurritoKinds::SmallBurrito { spicy: true, small_filling: q } });
3535
| ---- required by a bound introduced by this call ^ the trait `T3` is not implemented for `Q`
@@ -59,7 +59,7 @@ LL | fn example<Q: T3>(q: Q) {
5959
| ++++
6060

6161
error[E0277]: the trait bound `Q: T3` is not satisfied
62-
--> $DIR/blame-trait-error-spans-on-exprs.rs:87:39
62+
--> $DIR/blame-trait-error-spans-on-exprs.rs:89:39
6363
|
6464
LL | want(Wrapper { value: Taco(false, q) });
6565
| ---- ^ the trait `T3` is not implemented for `Q`
@@ -91,7 +91,7 @@ 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:91:27
94+
--> $DIR/blame-trait-error-spans-on-exprs.rs:93:27
9595
|
9696
LL | want(Wrapper { value: TacoKinds::OneTaco(false, q) });
9797
| ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `T3` is not implemented for `Q`
@@ -123,7 +123,7 @@ LL | fn example<Q: T3>(q: Q) {
123123
| ++++
124124

125125
error[E0277]: the trait bound `Q: T3` is not satisfied
126-
--> $DIR/blame-trait-error-spans-on-exprs.rs:95:74
126+
--> $DIR/blame-trait-error-spans-on-exprs.rs:97:74
127127
|
128128
LL | want(Wrapper { value: GenericBurrito { spiciness: NotSpicy, filling: q } });
129129
| ---- required by a bound introduced by this call ^ the trait `T3` is not implemented for `Q`
@@ -153,7 +153,7 @@ LL | fn example<Q: T3>(q: Q) {
153153
| ++++
154154

155155
error[E0277]: the trait bound `Q: T2` is not satisfied
156-
--> $DIR/blame-trait-error-spans-on-exprs.rs:99:14
156+
--> $DIR/blame-trait-error-spans-on-exprs.rs:101:14
157157
|
158158
LL | want((3, q));
159159
| ---- ^ the trait `T2` is not implemented for `Q`
@@ -178,7 +178,7 @@ LL | fn example<Q: T2>(q: Q) {
178178
| ++++
179179

180180
error[E0277]: the trait bound `Q: T3` is not satisfied
181-
--> $DIR/blame-trait-error-spans-on-exprs.rs:103:31
181+
--> $DIR/blame-trait-error-spans-on-exprs.rs:105:31
182182
|
183183
LL | want(Wrapper { value: (3, q) });
184184
| ---- ^ the trait `T3` is not implemented for `Q`
@@ -210,7 +210,7 @@ LL | fn example<Q: T3>(q: Q) {
210210
| ++++
211211

212212
error[E0277]: the trait bound `Q: T3` is not satisfied
213-
--> $DIR/blame-trait-error-spans-on-exprs.rs:107:15
213+
--> $DIR/blame-trait-error-spans-on-exprs.rs:109:15
214214
|
215215
LL | want(((3, q), 5));
216216
| ---- ^ the trait `T3` is not implemented for `Q`
@@ -242,7 +242,7 @@ LL | fn example<Q: T3>(q: Q) {
242242
| ++++
243243

244244
error[E0277]: the trait bound `Q: T1` is not satisfied
245-
--> $DIR/blame-trait-error-spans-on-exprs.rs:110:49
245+
--> $DIR/blame-trait-error-spans-on-exprs.rs:112:49
246246
|
247247
LL | want(DoubleWrapper { item: Wrapper { value: q } });
248248
| ---- ^ the trait `T1` is not implemented for `Q`
@@ -267,7 +267,7 @@ LL | fn example<Q: T1>(q: Q) {
267267
| ++++
268268

269269
error[E0277]: the trait bound `Q: T1` is not satisfied
270-
--> $DIR/blame-trait-error-spans-on-exprs.rs:113:88
270+
--> $DIR/blame-trait-error-spans-on-exprs.rs:115:88
271271
|
272272
LL | want(DoubleWrapper { item: Wrapper { value: DoubleWrapper { item: Wrapper { value: q } } } });
273273
| ---- required by a bound introduced by this call ^ the trait `T1` is not implemented for `Q`
@@ -292,7 +292,7 @@ LL | fn example<Q: T1>(q: Q) {
292292
| ++++
293293

294294
error[E0277]: the trait bound `Q: T3` is not satisfied
295-
--> $DIR/blame-trait-error-spans-on-exprs.rs:117:27
295+
--> $DIR/blame-trait-error-spans-on-exprs.rs:119:27
296296
|
297297
LL | want(Wrapper { value: AliasBurrito { spiciness: q, filling: q } });
298298
| ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `T3` is not implemented for `Q`
@@ -324,7 +324,7 @@ LL | fn example<Q: T3>(q: Q) {
324324
| ++++
325325

326326
error[E0277]: the trait bound `Q: T1` is not satisfied
327-
--> $DIR/blame-trait-error-spans-on-exprs.rs:120:35
327+
--> $DIR/blame-trait-error-spans-on-exprs.rs:122:35
328328
|
329329
LL | want(Two { a: Two { a: (), b: q }, b: () });
330330
| ---- ^ the trait `T1` is not implemented for `Q`
@@ -349,7 +349,7 @@ LL | fn example<Q: T1>(q: Q) {
349349
| ++++
350350

351351
error[E0277]: the trait bound `Q: T1` is not satisfied
352-
--> $DIR/blame-trait-error-spans-on-exprs.rs:126:59
352+
--> $DIR/blame-trait-error-spans-on-exprs.rs:128:59
353353
|
354354
LL | want(
355355
| ---- required by a bound introduced by this call
@@ -375,6 +375,38 @@ help: consider restricting type parameter `Q`
375375
LL | fn example<Q: T1>(q: Q) {
376376
| ++++
377377

378-
error: aborting due to 13 previous errors
378+
error[E0277]: the trait bound `Q: T3` is not satisfied
379+
--> $DIR/blame-trait-error-spans-on-exprs.rs:133:44
380+
|
381+
LL | want(&Burrito { spicy: false, filling: q });
382+
| ---- ^ the trait `T3` is not implemented for `Q`
383+
| |
384+
| required by a bound introduced by this call
385+
|
386+
note: required for `Burrito<Q>` to implement `T2`
387+
--> $DIR/blame-trait-error-spans-on-exprs.rs:22:13
388+
|
389+
LL | impl<A: T3> T2 for Burrito<A> {}
390+
| -- ^^ ^^^^^^^^^^
391+
| |
392+
| unsatisfied trait bound introduced here
393+
note: required for `&Burrito<Q>` to implement `T1`
394+
--> $DIR/blame-trait-error-spans-on-exprs.rs:74:17
395+
|
396+
LL | impl<'a, T: T2> T1 for &'a T {}
397+
| -- ^^ ^^^^^
398+
| |
399+
| unsatisfied trait bound introduced here
400+
note: required by a bound in `want`
401+
--> $DIR/blame-trait-error-spans-on-exprs.rs:53:12
402+
|
403+
LL | fn want<V: T1>(_x: V) {}
404+
| ^^ required by this bound in `want`
405+
help: consider restricting type parameter `Q`
406+
|
407+
LL | fn example<Q: T3>(q: Q) {
408+
| ++++
409+
410+
error: aborting due to 14 previous errors
379411

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

tests/ui/traits/suggest-deferences/issue-39029.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `NoToSocketAddrs: ToSocketAddrs` is not satisfied
2-
--> $DIR/issue-39029.rs:16:37
2+
--> $DIR/issue-39029.rs:16:38
33
|
44
LL | let _errors = TcpListener::bind(&bad);
5-
| ----------------- ^^^^ the trait `ToSocketAddrs` is not implemented for `NoToSocketAddrs`
5+
| ----------------- ^^^ the trait `ToSocketAddrs` is not implemented for `NoToSocketAddrs`
66
| |
77
| required by a bound introduced by this call
88
|

0 commit comments

Comments
 (0)