Skip to content

Commit

Permalink
Provide more context on derived obligation error primary label
Browse files Browse the repository at this point in the history
Expand the primary span of E0277 when the immediate unmet bound is not what the user wrote:

```
error[E0277]: the trait bound `i32: Bar` is not satisfied
 --> f100.rs:6:6
  |
6 |     <i32 as Foo>::foo();
  |      ^^^ the trait `Bar` is not implemented for `i32`, which is required by `i32: Foo`
  |
help: this trait has no implementations, consider adding one
 --> f100.rs:2:1
  |
2 | trait Bar {}
  | ^^^^^^^^^
note: required for `i32` to implement `Foo`
 --> f100.rs:3:14
  |
3 | impl<T: Bar> Foo for T {}
  |         ---  ^^^     ^
  |         |
  |         unsatisfied trait bound introduced here
```

Fix #40120.
  • Loading branch information
estebank committed Jan 29, 2024
1 parent 6351247 commit 19728a9
Show file tree
Hide file tree
Showing 196 changed files with 382 additions and 373 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1432,20 +1432,18 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
) -> bool {
let span = obligation.cause.span;

let code = if let ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } =
obligation.cause.code()
{
parent_code
} else if let ObligationCauseCode::ItemObligation(_)
| ObligationCauseCode::ExprItemObligation(..) = obligation.cause.code()
{
obligation.cause.code()
} else if let ExpnKind::Desugaring(DesugaringKind::ForLoop) =
span.ctxt().outer_expn_data().kind
{
obligation.cause.code()
} else {
return false;
let code = match obligation.cause.code() {
ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => parent_code,
c @ ObligationCauseCode::ItemObligation(_)
| c @ ObligationCauseCode::ExprItemObligation(..) => c,
c if matches!(
span.ctxt().outer_expn_data().kind,
ExpnKind::Desugaring(DesugaringKind::ForLoop)
) =>
{
c
}
_ => return false,
};

// List of traits for which it would be nonsensical to suggest borrowing.
Expand Down Expand Up @@ -4978,16 +4976,27 @@ pub(super) fn get_explanation_based_on_obligation<'tcx>(
_ => None,
};

let pred = obligation.predicate;
let (_, base) = obligation.cause.code().peel_derives_with_predicate();
let post = if let ty::PredicateKind::Clause(clause) = pred.kind().skip_binder()
&& let ty::ClauseKind::Trait(pred) = clause
&& let Some(base) = base
&& base.skip_binder() != pred
{
format!(", which is required by `{base}`")
} else {
String::new()
};
match ty_desc {
Some(desc) => format!(
"{}the trait `{}` is not implemented for {} `{}`",
"{}the trait `{}` is not implemented for {} `{}`{post}",
pre_message,
trait_predicate.print_modifiers_and_trait_path(),
desc,
tcx.short_ty_string(trait_ref.skip_binder().self_ty(), &mut None),
),
None => format!(
"{}the trait `{}` is not implemented for `{}`",
"{}the trait `{}` is not implemented for `{}`{post}",
pre_message,
trait_predicate.print_modifiers_and_trait_path(),
tcx.short_ty_string(trait_ref.skip_binder().self_ty(), &mut None),
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/associated-consts/issue-58022.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation
LL | fn new(slice: &[u8; Self::SIZE]) -> Self {
| ^^^^ doesn't have a size known at compile-time
|
= help: within `Bar<[u8]>`, the trait `Sized` is not implemented for `[u8]`
= help: within `Bar<[u8]>`, the trait `Sized` is not implemented for `[u8]`, which is required by `Bar<[u8]>: Sized`
note: required because it appears within the type `Bar<[u8]>`
--> $DIR/issue-58022.rs:8:12
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ error: future cannot be sent between threads safely
LL | is_send(foo::<T>());
| ^^^^^^^^^^ future returned by `foo` is not `Send`
|
= help: within `impl Future<Output = Result<(), ()>>`, the trait `Send` is not implemented for `impl Future<Output = Result<(), ()>> { <T as Foo>::method() }`
= help: within `impl Future<Output = Result<(), ()>>`, the trait `Send` is not implemented for `impl Future<Output = Result<(), ()>> { <T as Foo>::method() }`, which is required by `impl Future<Output = Result<(), ()>>: Send`
note: future is not `Send` as it awaits another future which is not `Send`
--> $DIR/basic.rs:13:5
|
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/associated-types/defaults-suitability.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ error[E0277]: the trait bound `T: Clone` is not satisfied
--> $DIR/defaults-suitability.rs:28:23
|
LL | type Bar: Clone = Vec<T>;
| ^^^^^^ the trait `Clone` is not implemented for `T`
| ^^^^^^ the trait `Clone` is not implemented for `T`, which is required by `Vec<T>: Clone`
|
= note: required for `Vec<T>` to implement `Clone`
note: required by a bound in `Foo::Bar`
Expand Down Expand Up @@ -88,7 +88,7 @@ error[E0277]: the trait bound `<Self as Foo2<T>>::Baz: Clone` is not satisfied
--> $DIR/defaults-suitability.rs:65:23
|
LL | type Bar: Clone = Vec<Self::Baz>;
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo2<T>>::Baz`
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo2<T>>::Baz`, which is required by `Vec<<Self as Foo2<T>>::Baz>: Clone`
|
= note: required for `Vec<<Self as Foo2<T>>::Baz>` to implement `Clone`
note: required by a bound in `Foo2::Bar`
Expand All @@ -105,7 +105,7 @@ error[E0277]: the trait bound `<Self as Foo25<T>>::Baz: Clone` is not satisfied
--> $DIR/defaults-suitability.rs:74:23
|
LL | type Bar: Clone = Vec<Self::Baz>;
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo25<T>>::Baz`
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo25<T>>::Baz`, which is required by `Vec<<Self as Foo25<T>>::Baz>: Clone`
|
= note: required for `Vec<<Self as Foo25<T>>::Baz>` to implement `Clone`
note: required by a bound in `Foo25::Bar`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0277]: the trait bound `str: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-1.rs:12:14
|
LL | type U = str;
| ^^^ the trait `Clone` is not implemented for `str`
| ^^^ the trait `Clone` is not implemented for `str`, which is required by `for<'b> <i32 as X<'b>>::U: Clone`
|
= help: the trait `Clone` is implemented for `String`
note: required by a bound in `X`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0277]: the trait bound `str: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-1.rs:14:14
|
LL | type V = str;
| ^^^ the trait `Clone` is not implemented for `str`
| ^^^ the trait `Clone` is not implemented for `str`, which is required by `for<'b> <u8 as Y<'b, u8>>::V: Clone`
|
= help: the trait `Clone` is implemented for `String`
note: required by a bound in `Y`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ error[E0277]: the trait bound `str: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-2.rs:15:14
|
LL | type W = str;
| ^^^ the trait `Clone` is not implemented for `str`
| ^^^ the trait `Clone` is not implemented for `str`, which is required by `for<'b> <u16 as Z<'b, u16>>::W: Clone`
|
= help: the trait `Clone` is implemented for `String`
note: required by a bound in `Z`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0277]: the trait bound `str: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-3.rs:13:14
|
LL | type U = str;
| ^^^ the trait `Clone` is not implemented for `str`
| ^^^ the trait `Clone` is not implemented for `str`, which is required by `for<'b> <(T,) as X<'b, (T,)>>::U: Clone`
|
= help: the trait `Clone` is implemented for `String`
note: required by a bound in `X`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0277]: the trait bound `str: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-4.rs:13:14
|
LL | type U = str;
| ^^^ the trait `Clone` is not implemented for `str`
| ^^^ the trait `Clone` is not implemented for `str`, which is required by `for<'b> <(T,) as X<'b, T>>::U: Clone`
|
= help: the trait `Clone` is implemented for `String`
note: required by a bound in `X`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0277]: the trait bound `str: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-5.rs:26:14
|
LL | type U = str;
| ^^^ the trait `Clone` is not implemented for `str`
| ^^^ the trait `Clone` is not implemented for `str`, which is required by `for<'b> <<Vec<T> as Cycle>::Next as X<'b, <Vec<T> as Cycle>::Next>>::U: Clone`
|
= help: the trait `Clone` is implemented for `String`
note: required by a bound in `X`
Expand All @@ -18,7 +18,7 @@ error[E0277]: the trait bound `str: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-5.rs:31:14
|
LL | type U = str;
| ^^^ the trait `Clone` is not implemented for `str`
| ^^^ the trait `Clone` is not implemented for `str`, which is required by `for<'b> <<Box<T> as Cycle>::Next as X<'b, <Box<T> as Cycle>::Next>>::U: Clone`
|
= help: the trait `Clone` is implemented for `String`
note: required by a bound in `X`
Expand Down
32 changes: 16 additions & 16 deletions tests/ui/associated-types/issue-38821.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
--> $DIR/issue-38821.rs:23:17
|
LL | #[derive(Debug, Copy, Clone)]
| ^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
| ^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
Expand All @@ -21,7 +21,7 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
--> $DIR/issue-38821.rs:38:1
|
LL | pub enum ColumnInsertValue<Col, Expr> where
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
Expand All @@ -45,7 +45,7 @@ LL | | Col: Column,
... |
LL | | Default(Col),
LL | | }
| |_^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
| |_^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
Expand All @@ -63,7 +63,7 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
--> $DIR/issue-38821.rs:23:10
|
LL | #[derive(Debug, Copy, Clone)]
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
Expand All @@ -82,7 +82,7 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
--> $DIR/issue-38821.rs:23:10
|
LL | #[derive(Debug, Copy, Clone)]
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
Expand All @@ -102,7 +102,7 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
--> $DIR/issue-38821.rs:23:10
|
LL | #[derive(Debug, Copy, Clone)]
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
Expand All @@ -117,7 +117,7 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
--> $DIR/issue-38821.rs:23:10
|
LL | #[derive(Debug, Copy, Clone)]
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
Expand All @@ -133,7 +133,7 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
--> $DIR/issue-38821.rs:23:17
|
LL | #[derive(Debug, Copy, Clone)]
| ^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
| ^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
Expand All @@ -153,7 +153,7 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
--> $DIR/issue-38821.rs:23:23
|
LL | #[derive(Debug, Copy, Clone)]
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
Expand All @@ -172,7 +172,7 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
--> $DIR/issue-38821.rs:23:23
|
LL | #[derive(Debug, Copy, Clone)]
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
Expand All @@ -192,7 +192,7 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
--> $DIR/issue-38821.rs:23:23
|
LL | #[derive(Debug, Copy, Clone)]
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
Expand All @@ -207,7 +207,7 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
--> $DIR/issue-38821.rs:23:23
|
LL | #[derive(Debug, Copy, Clone)]
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
Expand All @@ -223,7 +223,7 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
--> $DIR/issue-38821.rs:23:10
|
LL | #[derive(Debug, Copy, Clone)]
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
Expand All @@ -239,7 +239,7 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
--> $DIR/issue-38821.rs:23:10
|
LL | #[derive(Debug, Copy, Clone)]
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
Expand All @@ -255,7 +255,7 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
--> $DIR/issue-38821.rs:23:23
|
LL | #[derive(Debug, Copy, Clone)]
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
Expand All @@ -271,7 +271,7 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
--> $DIR/issue-38821.rs:23:23
|
LL | #[derive(Debug, Copy, Clone)]
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0277]: the trait bound `T: Copy` is not satisfied
--> $DIR/issue-43784-associated-type.rs:14:18
|
LL | type Assoc = T;
| ^ the trait `Copy` is not implemented for `T`
| ^ the trait `Copy` is not implemented for `T`, which is required by `<T as Complete>::Assoc: Partial<T>`
|
note: required for `<T as Complete>::Assoc` to implement `Partial<T>`
--> $DIR/issue-43784-associated-type.rs:1:11
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/associated-types/issue-65774-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ error[E0277]: the trait bound `T: MyDisplay` is not satisfied
--> $DIR/issue-65774-1.rs:44:76
|
LL | let closure = |config: &mut <S as MPU>::MpuConfig| writer.my_write(&config);
| ^^^^^^^ the trait `MyDisplay` is not implemented for `T`
| ^^^^^^^ the trait `MyDisplay` is not implemented for `T`, which is required by `&mut T: MyDisplay`
|
= help: the trait `MyDisplay` is implemented for `&'a mut T`
note: required for `&mut T` to implement `MyDisplay`
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/associated-types/substs-ppaux.normal.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
LL | <str as Foo<u8>>::bar;
| ^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
= help: the trait `Sized` is not implemented for `str`, which is required by `str: Foo<'_, '_, u8>`
note: required for `str` to implement `Foo<'_, '_, u8>`
--> $DIR/substs-ppaux.rs:11:17
|
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/associated-types/substs-ppaux.verbose.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
LL | <str as Foo<u8>>::bar;
| ^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
= help: the trait `Sized` is not implemented for `str`, which is required by `str: Foo<'?0, '?1, u8>`
note: required for `str` to implement `Foo<'?0, '?1, u8>`
--> $DIR/substs-ppaux.rs:11:17
|
Expand Down
Loading

0 comments on commit 19728a9

Please sign in to comment.