Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

? can not use assiciated type constraints usable by .into() #55984

Open
chrysn opened this issue Nov 15, 2018 · 1 comment
Open

? can not use assiciated type constraints usable by .into() #55984

chrysn opened this issue Nov 15, 2018 · 1 comment
Labels
A-trait-system Area: Trait system T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@chrysn
Copy link
Contributor

chrysn commented Nov 15, 2018

When an error type is guaranteed to come From<> a result error type by means of a trait constraint in a generic function with a constant result type, the idiom some_result.map_err(|e| e.into()) works, but the should-be equivalent Ok(some_result?) does not and produces:

the trait `std::convert::From<<W as Worker>::Error>` is not implemented for `GenericError`

That can be alleviated by explicitly demanding that From<<W as Worker>::Error> of the generic function's error type, but my expectation would be that this is implied by the type constraint -- especially since the .map_err version that should be equivalent to the ? one does "get it".

Full example:

#[derive(Debug)]
struct GenericError();

// impl Into<GenericError> for i32 {
//     fn into(self) -> GenericError {
//         GenericError()
//     }
// }

impl From<i32> for GenericError {
    fn from(_: i32) -> Self {
        GenericError()
    }
}

trait Worker {
    type Error: Into<GenericError>;

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

struct IntegerWorker();

impl Worker for IntegerWorker {
    type Error = i32;

    fn do_something(&self) -> Result<(), Self::Error> {
        Err(42)
    }
}

fn process<W>(w: W) -> Result<(), GenericError> where
    W: Worker,
    // GenericError: From<<W as Worker>::Error>
{
    let some_result = w.do_something();
    // // This works:
    // some_result.map_err(|e| e.into())
    // This doesn't
    Ok(some_result?)
}

fn main() {
    let w = IntegerWorker();
    println!("Result: {:?}", process(w));
}

This fails to build with the above error message, while the commented-out version with .map_err(|e| e.into()) builds fine. Adding the GenericError: From<...> "where" clause solves the build error, but is unergonomic (it'd clutter all functions working on that type).

In case it is relevant: If Into<> is implemented instead of the equivalent From<> (top comment block), then the problem still exists, but adding the additional constraint does not solve it any more but produces a different error message.

Meta

Previous research on web and issue tracker search turned out dry, and disucssion on IRC just helped rule out some possible oversights. The behavior is the same with 1.29.0, 1.30.0 and current nightly; full example version:

rustc 1.30.1 (1433507eb 2018-11-07)                                                                                                                            
binary: rustc                                                                                                                                                  
commit-hash: 1433507eba7d1a114e4c6f27ae0e1a74f60f20de                                                                                                          
commit-date: 2018-11-07                                                                                                                                        
host: x86_64-unknown-linux-gnu                                                                                                                                 
release: 1.30.1                                                                                                                                                
LLVM version: 8.0
@jonas-schievink jonas-schievink added A-trait-system Area: Trait system T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 27, 2019
@waynr
Copy link
Contributor

waynr commented Oct 18, 2023

I recently ran into this myself and wanted to chime in with what I've found so far while asking around how this might be fixed:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-trait-system Area: Trait system T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants