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

Modeling coercions #104

Open
leodasvacas opened this Issue Mar 27, 2018 · 0 comments

Comments

Projects
None yet
1 participant
@leodasvacas
Copy link
Contributor

leodasvacas commented Mar 27, 2018

A description of what coercions do can be found in the reference and the nomicon.

In many places Rust only requires that one type coerces to another, but there is no way to explain that to the inference engine which only understands type equality. So if there are multiple types being coerced to a single target type the current rustc implementation will sometimes greedily unify the first type it sees.

First a trivial example, in let mut a = &&0; a = &0; the type of a should be inferred to &i32 not &&i32. It's the same with generic functions:

fn foo<T>(_: T, _: T) {}

fn main() {
    let x: u8 = 0;
    foo(&&x, &x); // Fails, `T = &&u8`.
    foo(&x, &&x); // Works, `T = &u8`.
}

And closures, here with &mut to & coercions:

fn main() {
    let mut a = 0;
    let b = 0;
    let c = |x| {};
    // Fails because c is inferred to Fn(&mut i32),
    // but works if lines below swapped and c is inferred to Fn(&i32).
    c(&mut a);
    c(&b);
}

For some cases rustc already improves on this with special treatment for coercing many expressions to a single target type (see CoerceMany in coercion.rs for details), so for example both if true { &0 } else { &&0 } and if true { &&0 } else { &0 } will work with resulting type &i32.

If we can model a "T coerces to U" relationshig in chalk it would be a major step towards improving the situation and integrating coercions within the inference engine. Before diving into formulations for Chalk, I'll try to put together a description of how the current rustc code handles this in coercion.rs.

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