From fbcca2aaf0280190111982e931bc113b21f7ec0d Mon Sep 17 00:00:00 2001 From: Nathan Fenner Date: Sun, 19 Feb 2023 21:27:04 -0800 Subject: [PATCH] Refine error span for trait error into borrowed expression --- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 13 ++++ .../blame-trait-error-spans-on-exprs.rs | 6 ++ .../blame-trait-error-spans-on-exprs.stderr | 60 ++++++++++++++----- .../suggest-deferences/issue-39029.stderr | 4 +- 4 files changed, 67 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 06d6a375697d1..39e0ea98f96e3 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -549,6 +549,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return Err(expr); }; + if let ( + hir::ExprKind::AddrOf(_borrow_kind, _borrow_mutability, borrowed_expr), + ty::Ref(_ty_region, ty_ref_type, _ty_mutability), + ) = (&expr.kind, in_ty.kind()) + { + // We can "drill into" the borrowed expression. + return self.blame_specific_part_of_expr_corresponding_to_generic_param( + param, + borrowed_expr, + (*ty_ref_type).into(), + ); + } + if let (hir::ExprKind::Tup(expr_elements), ty::Tuple(in_ty_elements)) = (&expr.kind, in_ty.kind()) { diff --git a/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.rs b/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.rs index 2b75f43241289..6fea409ed4716 100644 --- a/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.rs +++ b/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.rs @@ -71,6 +71,8 @@ struct DoubleWrapper { impl T1 for DoubleWrapper {} +impl<'a, T: T2> T1 for &'a T {} + fn example(q: Q) { // In each of the following examples, we expect the error span to point at the 'q' variable, // since the missing constraint is `Q: T3`. @@ -126,6 +128,10 @@ fn example(q: Q) { Two { a: Two { a: (), b: Two { a: Two { a: (), b: q }, b: () } }, b: () }, //~^ ERROR the trait bound `Q: T1` is not satisfied [E0277] ); + + // Verifies for reference: + want(&Burrito { spicy: false, filling: q }); + //~^ ERROR the trait bound `Q: T3` is not satisfied [E0277] } fn main() {} diff --git a/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.stderr b/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.stderr index 5f87c670d8acd..6913771f2883e 100644 --- a/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.stderr +++ b/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `Q: T3` is not satisfied - --> $DIR/blame-trait-error-spans-on-exprs.rs:79:60 + --> $DIR/blame-trait-error-spans-on-exprs.rs:81:60 | LL | want(Wrapper { value: Burrito { spicy: false, filling: q } }); | ---- required by a bound introduced by this call ^ the trait `T3` is not implemented for `Q` @@ -29,7 +29,7 @@ LL | fn example(q: Q) { | ++++ error[E0277]: the trait bound `Q: T3` is not satisfied - --> $DIR/blame-trait-error-spans-on-exprs.rs:83:84 + --> $DIR/blame-trait-error-spans-on-exprs.rs:85:84 | LL | want(Wrapper { value: BurritoKinds::SmallBurrito { spicy: true, small_filling: q } }); | ---- required by a bound introduced by this call ^ the trait `T3` is not implemented for `Q` @@ -59,7 +59,7 @@ LL | fn example(q: Q) { | ++++ error[E0277]: the trait bound `Q: T3` is not satisfied - --> $DIR/blame-trait-error-spans-on-exprs.rs:87:39 + --> $DIR/blame-trait-error-spans-on-exprs.rs:89:39 | LL | want(Wrapper { value: Taco(false, q) }); | ---- ^ the trait `T3` is not implemented for `Q` @@ -91,7 +91,7 @@ LL | fn example(q: Q) { | ++++ error[E0277]: the trait bound `Q: T3` is not satisfied - --> $DIR/blame-trait-error-spans-on-exprs.rs:91:27 + --> $DIR/blame-trait-error-spans-on-exprs.rs:93:27 | LL | want(Wrapper { value: TacoKinds::OneTaco(false, q) }); | ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `T3` is not implemented for `Q` @@ -123,7 +123,7 @@ LL | fn example(q: Q) { | ++++ error[E0277]: the trait bound `Q: T3` is not satisfied - --> $DIR/blame-trait-error-spans-on-exprs.rs:95:74 + --> $DIR/blame-trait-error-spans-on-exprs.rs:97:74 | LL | want(Wrapper { value: GenericBurrito { spiciness: NotSpicy, filling: q } }); | ---- required by a bound introduced by this call ^ the trait `T3` is not implemented for `Q` @@ -153,7 +153,7 @@ LL | fn example(q: Q) { | ++++ error[E0277]: the trait bound `Q: T2` is not satisfied - --> $DIR/blame-trait-error-spans-on-exprs.rs:99:14 + --> $DIR/blame-trait-error-spans-on-exprs.rs:101:14 | LL | want((3, q)); | ---- ^ the trait `T2` is not implemented for `Q` @@ -178,7 +178,7 @@ LL | fn example(q: Q) { | ++++ error[E0277]: the trait bound `Q: T3` is not satisfied - --> $DIR/blame-trait-error-spans-on-exprs.rs:103:31 + --> $DIR/blame-trait-error-spans-on-exprs.rs:105:31 | LL | want(Wrapper { value: (3, q) }); | ---- ^ the trait `T3` is not implemented for `Q` @@ -210,7 +210,7 @@ LL | fn example(q: Q) { | ++++ error[E0277]: the trait bound `Q: T3` is not satisfied - --> $DIR/blame-trait-error-spans-on-exprs.rs:107:15 + --> $DIR/blame-trait-error-spans-on-exprs.rs:109:15 | LL | want(((3, q), 5)); | ---- ^ the trait `T3` is not implemented for `Q` @@ -242,7 +242,7 @@ LL | fn example(q: Q) { | ++++ error[E0277]: the trait bound `Q: T1` is not satisfied - --> $DIR/blame-trait-error-spans-on-exprs.rs:110:49 + --> $DIR/blame-trait-error-spans-on-exprs.rs:112:49 | LL | want(DoubleWrapper { item: Wrapper { value: q } }); | ---- ^ the trait `T1` is not implemented for `Q` @@ -267,7 +267,7 @@ LL | fn example(q: Q) { | ++++ error[E0277]: the trait bound `Q: T1` is not satisfied - --> $DIR/blame-trait-error-spans-on-exprs.rs:113:88 + --> $DIR/blame-trait-error-spans-on-exprs.rs:115:88 | LL | want(DoubleWrapper { item: Wrapper { value: DoubleWrapper { item: Wrapper { value: q } } } }); | ---- required by a bound introduced by this call ^ the trait `T1` is not implemented for `Q` @@ -292,7 +292,7 @@ LL | fn example(q: Q) { | ++++ error[E0277]: the trait bound `Q: T3` is not satisfied - --> $DIR/blame-trait-error-spans-on-exprs.rs:117:27 + --> $DIR/blame-trait-error-spans-on-exprs.rs:119:27 | LL | want(Wrapper { value: AliasBurrito { spiciness: q, filling: q } }); | ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `T3` is not implemented for `Q` @@ -324,7 +324,7 @@ LL | fn example(q: Q) { | ++++ error[E0277]: the trait bound `Q: T1` is not satisfied - --> $DIR/blame-trait-error-spans-on-exprs.rs:120:35 + --> $DIR/blame-trait-error-spans-on-exprs.rs:122:35 | LL | want(Two { a: Two { a: (), b: q }, b: () }); | ---- ^ the trait `T1` is not implemented for `Q` @@ -349,7 +349,7 @@ LL | fn example(q: Q) { | ++++ error[E0277]: the trait bound `Q: T1` is not satisfied - --> $DIR/blame-trait-error-spans-on-exprs.rs:126:59 + --> $DIR/blame-trait-error-spans-on-exprs.rs:128:59 | LL | want( | ---- required by a bound introduced by this call @@ -375,6 +375,38 @@ help: consider restricting type parameter `Q` LL | fn example(q: Q) { | ++++ -error: aborting due to 13 previous errors +error[E0277]: the trait bound `Q: T3` is not satisfied + --> $DIR/blame-trait-error-spans-on-exprs.rs:133:44 + | +LL | want(&Burrito { spicy: false, filling: q }); + | ---- ^ the trait `T3` is not implemented for `Q` + | | + | required by a bound introduced by this call + | +note: required for `Burrito` to implement `T2` + --> $DIR/blame-trait-error-spans-on-exprs.rs:22:13 + | +LL | impl T2 for Burrito {} + | -- ^^ ^^^^^^^^^^ + | | + | unsatisfied trait bound introduced here +note: required for `&Burrito` to implement `T1` + --> $DIR/blame-trait-error-spans-on-exprs.rs:74:17 + | +LL | impl<'a, T: T2> T1 for &'a T {} + | -- ^^ ^^^^^ + | | + | unsatisfied trait bound introduced here +note: required by a bound in `want` + --> $DIR/blame-trait-error-spans-on-exprs.rs:53:12 + | +LL | fn want(_x: V) {} + | ^^ required by this bound in `want` +help: consider restricting type parameter `Q` + | +LL | fn example(q: Q) { + | ++++ + +error: aborting due to 14 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/suggest-deferences/issue-39029.stderr b/tests/ui/traits/suggest-deferences/issue-39029.stderr index 49e20c6a76ad9..49105de3d691d 100644 --- a/tests/ui/traits/suggest-deferences/issue-39029.stderr +++ b/tests/ui/traits/suggest-deferences/issue-39029.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `NoToSocketAddrs: ToSocketAddrs` is not satisfied - --> $DIR/issue-39029.rs:16:37 + --> $DIR/issue-39029.rs:16:38 | LL | let _errors = TcpListener::bind(&bad); - | ----------------- ^^^^ the trait `ToSocketAddrs` is not implemented for `NoToSocketAddrs` + | ----------------- ^^^ the trait `ToSocketAddrs` is not implemented for `NoToSocketAddrs` | | | required by a bound introduced by this call |