Repository navigation
can the ? operator use into rather than from? #38751
Description
Activity
Nominating for discussion. I feel like this might cause inference failures.
Conclusion from @rust-lang/lang meeting: we should try it and see!
- addedC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.
on Jul 26, 2017 This issue should probably get an update with the current state.
IIRC, there were some ugly inference issues when we last tried this, but I'm unable to find the discussion that tried.
- added a commit that references this issue
on May 17, 2019 I tried this in #60796, and indeed type inference was a problem. Maybe the compiler can learn some tricks to make that work better, but for now this change doesn't seem feasible.
Reacted by scottmcmThe need for
Intorather thanFromhas come up for me in a real-world codebase. Here's a simplified motivating example:struct E; trait Fallible { type Error: Into<E>; fn e(&self) -> Result<(), Self::Error>; } fn test(f: &impl Fallible) -> Result<(), E> { Ok(f.e()?) }What the trait is trying to express is simple - any
Errortype that can be thrown needs to be convertible toEbecause of the way this trait is going to be used. Presently, this doesn't compile:error[E0277]: `?` couldn't convert the error to `E` --> src/lib.rs:9:13 | 9 | Ok(f.e()?) | ^ the trait `std::convert::From<<impl Fallible as Fallible>::Error>` is not implemented for `E` | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait = note: required by `std::convert::From::from`But, there's no straightforward way to fix this since there is no way to express the "reverse bound"
type Error: (E : From<Self::Error>). The only option is to decorate all of the call sites with something verbose like the following, which is taken from the actual code:where ReadError : From<<<K as Readable>::ReaderArray as ReaderArray>::Error>, ReadError : From<<<V as Readable>::ReaderArray as ReaderArray>::Error> {Link to project: Tree-Buf
Reacted by zohnannorFWIW, you can put
where E: From<Self::Error>on the trait, or even directly on the type declaration with#![feature(generic_associated_types)], but I think call sites still have trouble with #20671.There is also a hard-coded limit in the trait system. If you have to solve a goal like
?X: Into<ReturnType>, we will fail to resolve, but if you have to solve a goal likeReturnType: From<?X>, we will potentially succeed and infer a value for?X.Edit: Here,
?Xrefers to some unknown inference variable. The hard-coded limit in today's trait system is that theSelftype must be at least partly inferred for us to explore that option.So I could see that changing
?to useIntocould cause inference failures where none existed before.I'm inclined to close this issue, myself.
I am also inclined to close this -- it seems clear that we cannot change this now anyway.
@nikomatsakis would proper chalk integration for the trait solver be able to relax this limitation? (Could the relaxation be targeted exclusively to
??)It would be nice if we could "fix"
?to useIntoin an edition after rustc's trait solver is exclusively chalk (as far in the future as that is).Reacted by Mindaugas VinkelisReacted by Jon Gjengset and Anton BarkovskyReacted by Jon Gjengset and Eduard-Mihai Burtescu
Since implementing
Fromimplies an implementation forInto, but not vice versa, this seems like it should admit strictly more programs. Not entirely convinced this would be backwards compatible though.