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't Unify Super Generic Code #31580

Open
Gankra opened this issue Feb 11, 2016 · 6 comments
Open

Can't Unify Super Generic Code #31580

Gankra opened this issue Feb 11, 2016 · 6 comments
Labels
A-associated-items Area: Associated items (types, constants & functions) A-type-system Area: Type system C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Gankra
Copy link
Contributor

Gankra commented Feb 11, 2016

I was trying to verify that the associated-items-based HKT described in the associated items RFC still worked. As best I know, I updated everything to work with today's stable Rust (1.7), but it fails out in unifying in the actual implementation of Mappable for Vec<T> (see the FIXME).

// The kind * -> *
trait TypeToType<Input> {
    type Output;
}

struct Vec_;

impl<T> TypeToType<T> for Vec_ {
    type Output = Vec<T>;
}

trait Mappable 
    where Self: Sized,
{
    type E;
    type HKT: TypeToType<Self::E, Output=Self>;

    fn map<F, O>(self, f: F) -> <Self::HKT as TypeToType<O>>::Output
        where F: FnMut(Self::E) -> O,
              Self::HKT: TypeToType<O>;
}

impl<T> Mappable for Vec<T> {
    type E = T;
    type HKT = Vec_;

    // FIXME: I won't unify `Vec_::Output = Vec<O>`!
    fn map<F, O>(self, mut f: F) -> <Self::HKT as TypeToType<O>>::Output
        where F: FnMut(Self::E) -> O,
              Self::HKT: TypeToType<O>
    {
        let r: Vec<O> = self.into_iter().map(&mut f).collect();
        r
    }

}


fn main() {
    let nums: Vec<u32> = vec![1, 2, 3, 4, 5, 6];
    let bools: Vec<bool> = nums.map(|x| x < 3);
}
@aturon
Copy link
Member

aturon commented Feb 11, 2016

cc @nikomatsakis

@jonas-schievink
Copy link
Contributor

cc #30472 and #28994 (dupe?)

@aturon
Copy link
Member

aturon commented Feb 11, 2016

@jonas-schievink Yes, I think you're right -- the projection works if you define a helper like:

fn project<O>(v: Vec<O>) -> <Vec_ as TypeToType<O>>::Output {
    v
}

@aturon aturon closed this as completed Feb 11, 2016
@aturon
Copy link
Member

aturon commented Feb 11, 2016

Actually, I was a bit too hasty: HRTBs are not clearly at fault here, since there's no lifetime involved in the FnMut where clause. I suspect it's related, but not identical to the other bugs.

@aturon aturon reopened this Feb 11, 2016
@Gankra
Copy link
Contributor Author

Gankra commented Feb 11, 2016

The full fix, to be clear:

fn project_vec<O>(v: Vec<O>) -> <Vec_ as TypeToType<O>>::Output {
    v
}

impl<T> Mappable for Vec<T> {
    type E = T;
    type HKT = Vec_;

    fn map<F, O>(self, mut f: F) -> <Self::HKT as TypeToType<O>>::Output
        where F: FnMut(Self::E) -> O,
              Self::HKT: TypeToType<O>
    {
        let r: Vec<O> = self.into_iter().map(&mut f).collect();
        project_vec::<O>(r)
    }

}

But this shouldn't be necessary.

@bstrie
Copy link
Contributor

bstrie commented Feb 21, 2020

Triage: the given code still fails to compile as of Rust 1.41. Error message:

error[E0308]: mismatched types
  --> src/main.rs:33:9
   |
28 |     fn map<F, O>(self, mut f: F) -> <Self::HKT as TypeToType<O>>::Output
   |                                     ------------------------------------ expected `<Vec_ as TypeToType<O>>::Output` because of return type
...
33 |         r
   |         ^ expected associated type, found struct `std::vec::Vec`
   |
   = note: expected associated type `<Vec_ as TypeToType<O>>::Output`
                       found struct `std::vec::Vec<O>`
   = note: consider constraining the associated type `<Vec_ as TypeToType<O>>::Output` to `std::vec::Vec<O>` or calling a method that returns `<Vec_ as TypeToType<O>>::Output`
   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

@jonas-schievink jonas-schievink added A-associated-items Area: Associated items (types, constants & functions) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items Area: Associated items (types, constants & functions) A-type-system Area: Type system C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants