Skip to content

where clause with generic is suggested at the impl block before the generic is introduced #144734

@m4rch3n1ng

Description

@m4rch3n1ng

Code

struct Application;

trait Trait {
	type Error: std::error::Error;

	fn run(&self) -> Result<(), Self::Error>;
}

#[derive(Debug)]
enum ApplicationError {
	Quit,
}

impl Application {
	fn thing<T: Trait>(&self, t: T) -> Result<(), ApplicationError> {
		t.run()?;
		Ok(())
	}
}

fn main() {}

Current output

error[E0277]: `?` couldn't convert the error to `ApplicationError`
  --> src/main.rs:16:10
   |
16 |         t.run()?;
   |           -----^ the trait `std::convert::From<<T as Trait>::Error>` is not implemented for `ApplicationError`
   |           |
   |           this can't be annotated with `?` because it has type `Result<_, <T as Trait>::Error>`
   |
note: `ApplicationError` needs to implement `From<<T as Trait>::Error>`
  --> src/main.rs:10:1
   |
10 | enum ApplicationError {
   | ^^^^^^^^^^^^^^^^^^^^^
   = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
   |
14 | impl Application where ApplicationError: std::convert::From<<T as Trait>::Error> {
   |                  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

For more information about this error, try `rustc --explain E0277`.
error: could not compile `stuff` (bin "stuff") due to 1 previous error

Desired output

error[E0277]: `?` couldn't convert the error to `ApplicationError`
  --> src/main.rs:16:10
   |
16 |         t.run()?;
   |           -----^ the trait `std::convert::From<<T as Trait>::Error>` is not implemented for `ApplicationError`
   |           |
   |           this can't be annotated with `?` because it has type `Result<_, <T as Trait>::Error>`
   |
note: `ApplicationError` needs to implement `From<<T as Trait>::Error>`
  --> src/main.rs:10:1
   |
10 | enum ApplicationError {
   | ^^^^^^^^^^^^^^^^^^^^^
   = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
   |
15 |    fn thing<T: Trait>(&self, t: T) -> Result<(), ApplicationError>
16 +    where ApplicationError: std::convert::From<<T as Trait>::Error> {

For more information about this error, try `rustc --explain E0277`.
error: could not compile `stuff` (bin "stuff") due to 1 previous error

Rationale and extra context

the where clause that is suggested is suggested to be added to the impl block itself, where the type parameter T is not yet available, as T is only introduced for the thing fn.

if i apply the current suggestion i get this error:

error[E0412]: cannot find type `T` in this scope
  --> src/main.rs:16:40
   |
16 |     ApplicationError: std::convert::From<<T as Trait>::Error>,
   |                                           ^ not found in this scope
   |
help: you might be missing a type parameter
   |
14 | impl<T> Application
   |     +++

For more information about this error, try `rustc --explain E0412`.
error: could not compile `stuff` (bin "stuff") due to 1 previous error

Rust Version

rustc 1.90.0-nightly (3048886e5 2025-07-30)
binary: rustc
commit-hash: 3048886e59c94470e726ecaaf2add7242510ac11
commit-date: 2025-07-30
host: x86_64-unknown-linux-gnu
release: 1.90.0-nightly
LLVM version: 20.1.8

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions