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

Type inference works with method calls, but not with UFCS #21245

Closed
japaric opened this issue Jan 16, 2015 · 0 comments
Closed

Type inference works with method calls, but not with UFCS #21245

japaric opened this issue Jan 16, 2015 · 0 comments
Labels
A-typesystem Area: The type system

Comments

@japaric
Copy link
Member

japaric commented Jan 16, 2015

STR

use std::u8;

trait IntoIterator {
    type Iter: Iterator;

    fn into_iter(self) -> Self::Iter;
}

impl<I> IntoIterator for I where I: Iterator {
    type Iter = I;

    fn into_iter(self) -> I {
        self
    }
}

fn old_for_loop(byte: u8) -> u8 {
    let mut result = 0;
    for i in range(0, u8::BITS) {
        result |= ((byte >> i) & 1) << (u8::BITS - 1 - i);
    }
    result
}

fn desugared_for_loop_bad(byte: u8) -> u8 {
    let mut result = 0;
    match IntoIterator::into_iter(range(0, u8::BITS)) {
        mut iter => {
            loop {
                match ::std::iter::Iterator::next(&mut iter) {
                    ::std::option::Option::Some(i) => {
                        result |= ((byte >> i) & 1) << (u8::BITS - 1 - i);
                        //~^ error: right-hand-side of a shift operation must have integral type, not `_`
                    },
                    ::std::option::Option::None => break
                }
            }
        }
    }
    result
}

fn desugared_for_loop_good(byte: u8) -> u8 {
    let mut result = 0;
    match range(0, u8::BITS).into_iter() {  // NB method call instead of UFCS
        mut iter => {
            loop {
                match ::std::iter::Iterator::next(&mut iter) {
                    ::std::option::Option::Some(i) => {
                        result |= ((byte >> i) & 1) << (u8::BITS - 1 - i);
                    },
                    ::std::option::Option::None => break
                }
            }
        }
    }
    result
}

fn main() {}
use std::ptr;

trait IntoIterator {
    type Iter: Iterator;

    fn into_iter(self) -> Self::Iter;
}

impl<I> IntoIterator for I where I: Iterator {
    type Iter = I;

    fn into_iter(self) -> I {
        self
    }
}

fn old_for_loop<T>(v: Vec<T>) {
    for x in v.iter() {
        unsafe { ptr::read(x); }
    }
}

fn desugared_for_loop_bad<T>(v: Vec<T>) {
    match IntoIterator::into_iter(v.iter()) {
        mut iter => {
            loop {
                match ::std::iter::Iterator::next(&mut iter) {
                    ::std::option::Option::Some(x) => {
                        unsafe { ptr::read(x); }
//~^ error: type mismatch resolving `<core::slice::Iter<'_, T> as core::iter::Iterator>::Item == *const _`: expected &-ptr, found *-ptr
                    },
                    ::std::option::Option::None => break
                }
            }
        }
    }
}

fn desugared_for_loop_good<T>(v: Vec<T>) {
    match v.iter().into_iter() {  // NB method call instead of UFCS
        mut iter => {
            loop {
                match ::std::iter::Iterator::next(&mut iter) {
                    ::std::option::Option::Some(x) => {
                        unsafe { ptr::read(x); }
                    },
                    ::std::option::Option::None => break
                }
            }
        }
    }
}

fn main() {}

Type inference works fine with method calls (into_iter()), but fails with UFCS (IntoIterator::into_iter()).

Version

rustc 1.0.0-nightly (8903c21d6 2015-01-15 22:42:58 +0000)

This is blocking migration to the new for loops (#20790).

cc @nikomatsakis

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

No branches or pull requests

2 participants