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

`impl Trait` fails to resolve when returning `!` #36375

Open
Cobrand opened this Issue Sep 10, 2016 · 7 comments

Comments

Projects
None yet
7 participants
@Cobrand
Copy link
Contributor

Cobrand commented Sep 10, 2016

I couldn't think of a better title.

This code doesn't compile on nightly :

#![feature(conservative_impl_trait)]
use std::ops::Add ;

fn test() -> impl Add<u32> {
    unimplemented!()
}

fn main() {}
rustc 1.13.0-nightly (378195665 2016-09-08)
error[E0277]: the trait bound `(): std::ops::Add<u32>` is not satisfied

while this does :

#![feature(conservative_impl_trait)]
use std::ops::Add ;

fn test() -> impl Add<u32> {
    if true {
        unimplemented!()
    } else {
        0
    }
}

fn main() {}
@cramertj

This comment has been minimized.

Copy link
Member

cramertj commented Jan 5, 2018

Currently, ! does not implement Add<u32>. That's the underlying issue here. In order to fix this in general, IMO we should generate automatic ! impls of all traits containing only non-static methods.

@varkor

This comment has been minimized.

Copy link
Member

varkor commented Jan 12, 2018

Considering that ! can coerce to any other type, it seems strange that it can't coerce to any impl Trait (even if it doesn't explicitly implement that trait). It would seem like an inconsistency to only implement traits that contain non-static methods. As long as an object exists that implements that trait, ! could trivially coerce to that type, so you could do it by casting beforehand. I think this should "just work" (assuming there aren't any compatibility issues with doing it).

@rkruppe

This comment has been minimized.

Copy link
Member

rkruppe commented Jan 12, 2018

The issue is which type you coerce to. There can be multiple, and the choice can be observed if there are static methods: https://play.rust-lang.org/?gist=f8679a05f75f3db559870ad2389713bb&version=nightly

@varkor

This comment has been minimized.

Copy link
Member

varkor commented Jan 12, 2018

@rkruppe: Ah, I see; that's more awkward. The "non-static implementations only" causes issues too, though, because you'd always be able to get around it with this unintuitive if true { ... } else { valid_value } construction. Tricky.

@rkruppe

This comment has been minimized.

Copy link
Member

rkruppe commented Jan 12, 2018

if true { <diverges> } else { <something of type T> } unambiguously has type T. So there's no ambiguity. It's just a very ugly workaround.

@varkor

This comment has been minimized.

Copy link
Member

varkor commented Jan 12, 2018

Yeah, it's like explicitly casting the ! to any other type (that implements the trait) in the return position — it just feels very ugly, like you say (though casting is possibly somewhat nicer — and in the worst case, we could probably lint this case).

@kennytm

This comment has been minimized.

Copy link
Member

kennytm commented Jan 12, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment