Skip to content

Improve E0277 diagnostics for conditionally implemented traits#158494

Open
raushan728 wants to merge 2 commits into
rust-lang:mainfrom
raushan728:issues/158423
Open

Improve E0277 diagnostics for conditionally implemented traits#158494
raushan728 wants to merge 2 commits into
rust-lang:mainfrom
raushan728:issues/158423

Conversation

@raushan728

@raushan728 raushan728 commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Fixes #158423.

The diagnostic previously reported that a trait was "implemented" even when the matching impl failed because its own where-clause requirements were not satisfied, which was misleading.

This change:

  • updates the diagnostic to say "conditionally implemented" when the matching impl fails due to unsatisfied bounds
  • highlights the specific unsatisfied trait bound within the impl using ObligationCtxt::new_with_diagnostics
  • preserves the existing diagnostic flow while making it clearer why the impl was rejected

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Jun 27, 2026
@rustbot

rustbot commented Jun 27, 2026

Copy link
Copy Markdown
Collaborator

r? @mu001999

rustbot has assigned @mu001999.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 73 candidates
  • Random selection from 18 candidates

@rust-log-analyzer

This comment has been minimized.

@rustbot

rustbot commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@mu001999 mu001999 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you try to add the label on unsatisfied bounds, as desired in the issue? I think we can achieve this with ObligationCtxt::new_with_diagnostics.

And for the logic here, perhaps you could check the implementation of impl_may_apply. Maybe the logic could even be shared between them.

@rustbot author

View changes since this review

@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 28, 2026
@rustbot

rustbot commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@rustbot rustbot added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jun 28, 2026
@raushan728

Copy link
Copy Markdown
Contributor Author

Could you try to add the label on unsatisfied bounds, as desired in the issue? I think we can achieve this with ObligationCtxt::new_with_diagnostics.

And for the logic here, perhaps you could check the implementation of impl_may_apply. Maybe the logic could even be shared between them.

@rustbot author

View changes since this review

Thanks! I updated this to use ObligationCtxt::new_with_diagnostics, so the diagnostic now highlights the unsatisfied trait bound. I also looked into impl_may_apply, but kept the logic local since it serves a different purpose.

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 29, 2026
@raushan728 raushan728 requested a review from mu001999 June 29, 2026 11:58
@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
diff of stderr:

84   --> $DIR/copy-bounds-impl-type-params.rs:14:1
85    |
86 LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
-    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+    | ^^^^^^^^^^^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+    |                |
+    |                unsatisfied trait bound
88 note: required for `S<String>` to implement `Gettable<String>`
89   --> $DIR/copy-bounds-impl-type-params.rs:14:32
90    |

104   --> $DIR/copy-bounds-impl-type-params.rs:14:1
105    |
106 LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
-    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+    | ^^^^^^^^^^^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+    |                |
+    |                unsatisfied trait bound
108 note: required for `S<Foo>` to implement `Gettable<Foo>`
109   --> $DIR/copy-bounds-impl-type-params.rs:14:32
110    |


The actual stderr differed from the expected stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args traits/copy-bounds-impl-type-params.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/traits/copy-bounds-impl-type-params.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/traits/copy-bounds-impl-type-params" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers"
stdout: none
--- stderr -------------------------------
error[E0277]: `T` cannot be sent between threads safely
##[error]  --> /checkout/tests/ui/traits/copy-bounds-impl-type-params.rs:18:13
   |
LL |     let a = &t as &dyn Gettable<T>;
   |             ^^ `T` cannot be sent between threads safely
   |
note: required for `S<T>` to implement `Gettable<T>`
  --> /checkout/tests/ui/traits/copy-bounds-impl-type-params.rs:14:32
   |
LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
   |         ----                   ^^^^^^^^^^^     ^^^^
   |         |
   |         unsatisfied trait bound introduced here
   = note: required for the cast from `&S<T>` to `&dyn Gettable<T>`
help: consider restricting type parameter `T` with trait `Send`
   |
LL | fn f<T: std::marker::Send>(val: T) {
   |       +++++++++++++++++++

error[E0277]: the trait bound `T: Copy` is not satisfied
##[error]  --> /checkout/tests/ui/traits/copy-bounds-impl-type-params.rs:18:13
   |
LL |     let a = &t as &dyn Gettable<T>;
   |             ^^ the trait `Copy` is not implemented for `T`
   |
note: required for `S<T>` to implement `Gettable<T>`
  --> /checkout/tests/ui/traits/copy-bounds-impl-type-params.rs:14:32
   |
LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
   |                ----            ^^^^^^^^^^^     ^^^^
   |                |
   |                unsatisfied trait bound introduced here
   = note: required for the cast from `&S<T>` to `&dyn Gettable<T>`
help: consider restricting type parameter `T` with trait `Copy`
   |
LL | fn f<T: std::marker::Copy>(val: T) {
   |       +++++++++++++++++++

error[E0277]: `T` cannot be sent between threads safely
##[error]  --> /checkout/tests/ui/traits/copy-bounds-impl-type-params.rs:25:31
   |
LL |     let a: &dyn Gettable<T> = &t;
   |                               ^^ `T` cannot be sent between threads safely
   |
note: required for `S<T>` to implement `Gettable<T>`
  --> /checkout/tests/ui/traits/copy-bounds-impl-type-params.rs:14:32
   |
LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
   |         ----                   ^^^^^^^^^^^     ^^^^
   |         |
   |         unsatisfied trait bound introduced here
   = note: required for the cast from `&S<T>` to `&dyn Gettable<T>`
help: consider restricting type parameter `T` with trait `Send`
   |
LL | fn g<T: std::marker::Send>(val: T) {
   |       +++++++++++++++++++

error[E0277]: the trait bound `T: Copy` is not satisfied
##[error]  --> /checkout/tests/ui/traits/copy-bounds-impl-type-params.rs:25:31
   |
LL |     let a: &dyn Gettable<T> = &t;
   |                               ^^ the trait `Copy` is not implemented for `T`
   |
note: required for `S<T>` to implement `Gettable<T>`
  --> /checkout/tests/ui/traits/copy-bounds-impl-type-params.rs:14:32
   |
LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
   |                ----            ^^^^^^^^^^^     ^^^^
   |                |
   |                unsatisfied trait bound introduced here
   = note: required for the cast from `&S<T>` to `&dyn Gettable<T>`
help: consider restricting type parameter `T` with trait `Copy`
   |
LL | fn g<T: std::marker::Copy>(val: T) {
   |       +++++++++++++++++++

error[E0277]: the trait bound `String: Copy` is not satisfied
##[error]  --> /checkout/tests/ui/traits/copy-bounds-impl-type-params.rs:38:13
   |
LL |     let a = t as Box<dyn Gettable<String>>;
   |             ^ the trait `Copy` is not implemented for `String`
   |
help: the trait `Gettable<T>` is conditionally implemented for `S<T>`
  --> /checkout/tests/ui/traits/copy-bounds-impl-type-params.rs:14:1
   |
LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
   | ^^^^^^^^^^^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |                |
   |                unsatisfied trait bound
note: required for `S<String>` to implement `Gettable<String>`
  --> /checkout/tests/ui/traits/copy-bounds-impl-type-params.rs:14:32
   |
LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
   |                ----            ^^^^^^^^^^^     ^^^^
   |                |
   |                unsatisfied trait bound introduced here
   = note: required for the cast from `Box<S<String>>` to `Box<dyn Gettable<String>>`

error[E0277]: the trait bound `Foo: Copy` is not satisfied
##[error]  --> /checkout/tests/ui/traits/copy-bounds-impl-type-params.rs:46:37
   |
LL |     let a: Box<dyn Gettable<Foo>> = t;
   |                                     ^ the trait `Copy` is not implemented for `Foo`
   |
help: the trait `Gettable<T>` is conditionally implemented for `S<T>`
  --> /checkout/tests/ui/traits/copy-bounds-impl-type-params.rs:14:1
   |
LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
   | ^^^^^^^^^^^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |                |
   |                unsatisfied trait bound
note: required for `S<Foo>` to implement `Gettable<Foo>`
  --> /checkout/tests/ui/traits/copy-bounds-impl-type-params.rs:14:32
   |
LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
   |                ----            ^^^^^^^^^^^     ^^^^
   |                |
   |                unsatisfied trait bound introduced here
   = note: required for the cast from `Box<S<Foo>>` to `Box<dyn Gettable<Foo>>`
help: consider annotating `Foo` with `#[derive(Copy)]`
   |
LL +     #[derive(Copy)]
LL |     struct Foo; // does not impl Copy
   |

error: lifetime may not live long enough
##[error]  --> /checkout/tests/ui/traits/copy-bounds-impl-type-params.rs:32:13
   |
LL | fn foo<'a>() {
   |        -- lifetime `'a` defined here
LL |     let t: S<&'a isize> = S(marker::PhantomData);
LL |     let a = &t as &dyn Gettable<&'a isize>;
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'a` must outlive `'static`

error: aborting due to 7 previous errors

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

---- [ui] tests/ui/traits/copy-bounds-impl-type-params.rs stdout end ----
---- [ui] tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs#with stdout ----
Saved the actual stderr to `/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with/incompleteness-unstable-result.with.stderr`
diff of stderr:

16 LL | | where
17 LL | |     T: IncompleteGuidance<U, V>,
18 LL | |     A<T>: Trait<U, D, V>,
+    | |           -------------- unsatisfied trait bound
19 LL | |     B<T>: Trait<U, V, D>,
20 LL | |     (): ToU8<D>,
21    | |________________^


The actual stderr differed from the expected stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs`

error in revision `with`: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--cfg" "with" "--check-cfg" "cfg(test,FALSE,with,without)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers" "-Znext-solver"
stdout: none
--- stderr -------------------------------
error[E0277]: the trait bound `A<X>: Trait<_, _, _>` is not satisfied
##[error]  --> /checkout/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs:66:19
   |
LL |     impls_trait::<A<X>, _, _, _>();
   |                   ^^^^ unsatisfied trait bound
   |
help: the trait `Trait<_, _, _>` is not implemented for `A<X>`
  --> /checkout/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs:22:1
   |
LL | struct A<T>(*const T);
   | ^^^^^^^^^^^
help: the trait `Trait<U, V, D>` is conditionally implemented for `A<T>`
  --> /checkout/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs:34:1
   |
LL | / impl<T, U, V, D> Trait<U, V, D> for A<T>
LL | | where
LL | |     T: IncompleteGuidance<U, V>,
LL | |     A<T>: Trait<U, D, V>,
   | |           -------------- unsatisfied trait bound
LL | |     B<T>: Trait<U, V, D>,
LL | |     (): ToU8<D>,
   | |________________^
note: required for `A<X>` to implement `Trait<_, _, _>`
  --> /checkout/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs:34:18
   |
LL | impl<T, U, V, D> Trait<U, V, D> for A<T>
   |                  ^^^^^^^^^^^^^^     ^^^^
...
LL |     A<T>: Trait<U, D, V>,
   |           -------------- unsatisfied trait bound introduced here
   = note: 8 redundant requirements hidden
   = note: required for `A<X>` to implement `Trait<_, _, _>`
note: required by a bound in `impls_trait`
  --> /checkout/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs:53:19
   |
LL | fn impls_trait<T: Trait<U, V, D>, U, V, D>() {}
   |                   ^^^^^^^^^^^^^^ required by this bound in `impls_trait`

error: aborting due to 1 previous error

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

---- [ui] tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs#with stdout end ----
---- [ui] tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs#without stdout ----
Saved the actual stderr to `/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without/incompleteness-unstable-result.without.stderr`
diff of stderr:

16 LL | | where
17 LL | |     T: IncompleteGuidance<U, V>,
18 LL | |     A<T>: Trait<U, D, V>,
+    | |           -------------- unsatisfied trait bound
19 LL | |     B<T>: Trait<U, V, D>,
20 LL | |     (): ToU8<D>,
21    | |________________^


The actual stderr differed from the expected stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs`

error in revision `without`: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--cfg" "without" "--check-cfg" "cfg(test,FALSE,with,without)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers" "-Znext-solver"
stdout: none
--- stderr -------------------------------
error[E0277]: the trait bound `A<X>: Trait<_, _, _>` is not satisfied
##[error]  --> /checkout/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs:66:19
   |
LL |     impls_trait::<A<X>, _, _, _>();
   |                   ^^^^ unsatisfied trait bound
   |
help: the trait `Trait<_, _, _>` is not implemented for `A<X>`
  --> /checkout/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs:22:1
   |
LL | struct A<T>(*const T);
   | ^^^^^^^^^^^
help: the trait `Trait<U, V, D>` is conditionally implemented for `A<T>`
  --> /checkout/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs:34:1
   |
LL | / impl<T, U, V, D> Trait<U, V, D> for A<T>
LL | | where
LL | |     T: IncompleteGuidance<U, V>,
LL | |     A<T>: Trait<U, D, V>,
   | |           -------------- unsatisfied trait bound
LL | |     B<T>: Trait<U, V, D>,
LL | |     (): ToU8<D>,
   | |________________^
note: required for `A<X>` to implement `Trait<_, _, _>`
  --> /checkout/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs:34:18
   |
LL | impl<T, U, V, D> Trait<U, V, D> for A<T>
   |                  ^^^^^^^^^^^^^^     ^^^^
...
LL |     A<T>: Trait<U, D, V>,
   |           -------------- unsatisfied trait bound introduced here
   = note: 8 redundant requirements hidden
   = note: required for `A<X>` to implement `Trait<_, _, _>`
note: required by a bound in `impls_trait`
  --> /checkout/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs:53:19
   |
LL | fn impls_trait<T: Trait<U, V, D>, U, V, D>() {}
   |                   ^^^^^^^^^^^^^^ required by this bound in `impls_trait`

error: aborting due to 1 previous error

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

@mu001999 mu001999 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.tcx,
ObligationCause::dummy_with_span(span),
param_env,
clause.skip_norm_wip(),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
clause.skip_norm_wip(),
clause.skip_normalization(),

let mut multi_span = MultiSpan::from_span(self.tcx.def_span(def_id));
for error in failing_obligations {
multi_span
.push_span_label(error.obligation.cause.span, "unsatisfied trait bound");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.push_span_label(error.obligation.cause.span, "unsatisfied trait bound");
.push_span_label(error.root_obligation.cause.span, "unsatisfied trait bound");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And I think we can print root_obligation.predicate here, because this span will only point to the bound self.

Comment on lines 45 to 55
LL | impl<It: Iterator> T1 for Option<It> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^--------^^^^^^^^^^^^^^^^^^^
| |
| unsatisfied trait bound
note: required for `Option<()>` to implement `T1`
--> $DIR/blame-trait-error.rs:21:20
|
LL | impl<It: Iterator> T1 for Option<It> {}
| -------- ^^ ^^^^^^^^^^
| |
| unsatisfied trait bound introduced here

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two seems to be duplicated, but I think it's okay because they are from different ways and this would be helpful like in https://github.com/raushan728/rust/blob/9f2d7b14cdbc0b4a1efa4dbaa867b57189b9bbc4/tests/ui/traits/error_reporting/conditionally-implemented-trait-158423.stderr

{
return false;
}
let mut failing_obligations = Vec::new();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I'd like to move the declaration of multi_span here and move failing_obligations into the arm of the bellow match.

Then we just need to modify the multi_span in the arm, and don't need to make failing_obligations mutable. We can write

let failing_obligations = if .. { self.probe(..) } else { vec![] };

for error in &failing_obligations { ... }

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Misleading "trait bound not satisfied" with non-generic where clauses

4 participants