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

Adding a normal where-clause bound causes inferencer to equate wrong types #30767

Closed
soltanmm opened this issue Jan 7, 2016 · 2 comments
Closed

Comments

@soltanmm
Copy link

soltanmm commented Jan 7, 2016

On stable/beta/nightly:

pub struct O<X>(X);
pub trait M {
    type X;
    fn get(&self) -> O<Self::X>;  // <-- Make this return just Self::X, and inference proceeds just fine
}
impl M for () {
    type X = (usize, usize);
    fn get(&self) -> O<Self::X> { O((0, 0)) }
}

fn TEST_FN<T>()
    where (T,T): Sized  // <-- Remove this line, and inference proceeds just fine
{
    match M::get(&()) {  // <-- Make this ().get(), and inference proceeds just fine
        O((a, b)) => {
            let i: usize = a;  // ERROR
        }
    }
}
fn main() {}

play-pen

Error:

<anon>:16:28: 16:29 error: mismatched types:
 expected `usize`,
    found `T`
(expected usize,
    found type parameter) [E0308]
<anon>:16             let i: usize = a;  // ERROR
                                     ^
<anon>:16:28: 16:29 help: see the detailed explanation for E0308
<anon>:14:11: 14:17 error: type mismatch resolving `<() as M>::X == (T, T)`:
 expected usize,
    found type parameter [E0271]
<anon>:14     match M::get(&()) {  // <-- Make this ().get(), and inference proceeds just fine
                    ^~~~~~
<anon>:14:11: 14:17 help: see the detailed explanation for E0271
error: aborting due to 2 previous errors
playpen: application terminated with error code 101

From what I gather of debug output of similar code (take this with a grain of salt!), the bound (T, T): Sized is unified with the _ equal to ()::X via ()::X: Sized in match_poly_trait_ref. Then everything falls apart.

This is why simply elaborating all predicates in normalize_param_env_or_error in librustc/middle/traits/mod.rs breaks compilation of libserialize and everything under the sun that includes a bound of the form FnOnce(A, B) -> C and a for loop over an Enumerate iterator, because the bound (A, B): Sized ends up elaborated and unified with a type variable constrained to Enumerate::Item. Otherwise harmless bounds are unified in questionable ways.

cc @jroesch @nikomatsakis @arielb1 (I think?)

@arielb1
Copy link
Contributor

arielb1 commented Jan 8, 2016

Known issue. Type inference guessing - one of my enemies.

@Mark-Simulacrum
Copy link
Member

The code in the original issue compiles without errors, so this is presumably fixed. Closing, please reopen with a code sample if that's not the case, or if the original code sample should error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants