Skip to content

Bug in type inference #36418

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

Closed
golddranks opened this issue Sep 12, 2016 · 6 comments
Closed

Bug in type inference #36418

golddranks opened this issue Sep 12, 2016 · 6 comments
Labels
A-inference Area: Type inference

Comments

@golddranks
Copy link
Contributor

golddranks commented Sep 12, 2016

I've got code like this: (this is using the diesel crate for DB stuff)


fn get_user_pass_by_email(conn : &PgConnection, user_email : &str) -> std::result::Result<(User, Password), diesel::result::Error> {
    use schema::users;
    use schema::passwords;

    let user = users::table.filter(users::email.eq(user_email)).first(&*conn)?;
    let password = passwords::table.filter(passwords::id.eq(user.id)).first(&*conn)?;
    Ok((user, password))
}

This code won't compile:

error: the type of this value must be known in this context
  --> src/lib.rs:94:61
   |
94 |     let password = passwords::table.filter(passwords::id.eq(user.id)).first(&*conn)?;
   |                                                             ^^^^^^^

It compiles fine, if we add User as a type annotation:
let user : User = users::table.filter( ...
The type inference inside diesel is very complex indeed, but in this case the type inference should be very straightforward: our function returns Result<(User, Password), diesel::result::Error>, and through the line Ok((user, password)), the type of variable user should be directly inferable.

So I think this is a bug. If somebody who knows more about the type inference, can confirm that this should work, I can try to make a self-contained test-case for further debugging.

@golddranks
Copy link
Contributor Author

I was told later that Rust tries to infer the variable from the first usage, so even if user is being later used in a way that would allow inference from the function signature, it doesn't help. So it's more like a missing feature (in the sense that intra-function inference isn't against any design principle of Rust, and is considered a desirable feature), not a bug?

@Mark-Simulacrum Mark-Simulacrum added the A-inference Area: Type inference label May 13, 2017
@Mark-Simulacrum
Copy link
Member

Yeah, I'm going to close this -- type inference just doesn't work this way, and it's a large and unlikely thing to change.

@golddranks
Copy link
Contributor Author

@Mark-Simulacrum is the expected behavior documented anywhere? Unlike, say C# and C++, Rust does allow unifying "backwards", but as this issue shows, this has limits even inside a function. (I guess that my mental model was wrong in the sense that I thought it would try to unify "all the way" within a function body.) Should we expect this always be the case? Or will integrating chalk, for example, change it?

@Mark-Simulacrum
Copy link
Member

AIUI, inference isn't really guaranteed to work in a given way -- that is, we don't really have a documented set of things that it should do. We try to avoid backwards incompatible changes, and enhance it if deemed a good idea, but not more than that. Chalk may help in some cases, I'm not sure. I'd be fine with reopening this if you want, I don't feel strongly about it -- I just don't really think tracking it will change anything.

@golddranks
Copy link
Contributor Author

I do feel that a case where a local variable is returned from the function should be "clearly inferrable" as an ideal, but I don't feel strongly about closing or reopening this particular issue, if it isn't going to affect anything, so it's fine.

@Mark-Simulacrum
Copy link
Member

Yes, inference is currently often suboptimal. There's issues all over about improving it; I hope that once chalk is figured out we might be able to make some improvements in the area.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-inference Area: Type inference
Projects
None yet
Development

No branches or pull requests

2 participants