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 the ? operator use into rather than from? #38751

Closed
nrc opened this issue Jan 1, 2017 · 9 comments
Closed

can the ? operator use into rather than from? #38751

nrc opened this issue Jan 1, 2017 · 9 comments
Labels
C-enhancement Category: An issue proposing an enhancement or a PR with one. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@nrc
Copy link
Member

nrc commented Jan 1, 2017

Since implementing From implies an implementation for Into, but not vice versa, this seems like it should admit strictly more programs. Not entirely convinced this would be backwards compatible though.

@nrc nrc added the T-lang Relevant to the language team, which will review and decide on the PR/issue. label Jan 1, 2017
@Mark-Simulacrum
Copy link
Member

Nominating for discussion. I feel like this might cause inference failures.

@nikomatsakis
Copy link
Contributor

Conclusion from @rust-lang/lang meeting: we should try it and see!

@Mark-Simulacrum Mark-Simulacrum added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jul 26, 2017
@CAD97
Copy link
Contributor

CAD97 commented Apr 19, 2019

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.

bors added a commit that referenced this issue May 17, 2019
[WIP] Use `Into::into` in operator `?`

#38751 proposes using `into` for `?`, and while commenters suggested problems with inference, I couldn't find any evidence where this was actually attempted -- so here we go!
@cuviper
Copy link
Member

cuviper commented Jul 22, 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.

@That3Percent
Copy link

The need for Into rather than From has 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 Error type that can be thrown needs to be convertible to E because 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

@cuviper
Copy link
Member

cuviper commented Apr 17, 2020

FWIW, 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.

@nikomatsakis
Copy link
Contributor

nikomatsakis commented Apr 20, 2020

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 like ReturnType: From<?X>, we will potentially succeed and infer a value for ?X.

Edit: Here, ?X refers to some unknown inference variable. The hard-coded limit in today's trait system is that the Self type must be at least partly inferred for us to explore that option.

So I could see that changing ? to use Into could cause inference failures where none existed before.

I'm inclined to close this issue, myself.

@Mark-Simulacrum
Copy link
Member

I am also inclined to close this -- it seems clear that we cannot change this now anyway.

@CAD97
Copy link
Contributor

CAD97 commented Apr 25, 2020

@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 use Into in an edition after rustc's trait solver is exclusively chalk (as far in the future as that is).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-enhancement Category: An issue proposing an enhancement or a PR with one. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants