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

incompatible type for trait E0053 with specialization #32519

Closed
amarant opened this issue Mar 26, 2016 · 4 comments
Closed

incompatible type for trait E0053 with specialization #32519

amarant opened this issue Mar 26, 2016 · 4 comments
Labels
A-typesystem Area: The type system

Comments

@amarant
Copy link

amarant commented Mar 26, 2016

Hi,
When compiling this it results in :

error: method `mul` has an incompatible type for trait:expected associated type, found struct `Mat2f32` [[E0053](https://doc.rust-lang.org/error-index.html#E0053)]

I expected that to compile, because Mat2f32 is the associated type.
Instead it seems the new feature specialization interacts strangely with default or associated type.

Error:

 <anon>:54:5: 61:6 error: method `mul` has an incompatible type for trait:
  expected associated type,
     found struct `Mat2f32` [E0053]
 <anon>:54     default fn mul(self, rhs: T) -> Mat2f32 {
 <anon>:55         Mat2f32 {
 <anon>:56             e00: self.e00_rhs.e00() + self.e01_rhs.e10(),
 <anon>:57             e01: self.e00_rhs.e10() + self.e01_rhs.e11(),
 <anon>:58             e10: self.e10_rhs.e00() + self.e11_rhs.e10(),
 <anon>:59             e11: self.e10_rhs.e10() + self.e11_rhs.e11(),
           ...

Here is the code if play goes down:

#![feature(specialization)]

use std::ops::Mul;

struct Mat2f32 {
    e00: f32,
    e01: f32,
    e10: f32,
    e11: f32,
}

struct IdMatf32;

trait Mat2 : Sized {
    fn e00(&self) -> f32;
    fn e01(&self) -> f32;
    fn e10(&self) -> f32;
    fn e11(&self) -> f32;
}

impl Mat2 for Mat2f32 {
    fn e00(&self) -> f32 {
        self.e00
    }
    fn e01(&self) -> f32 {
        self.e01
    }
    fn e10(&self) -> f32 {
        self.e10
    }
    fn e11(&self) -> f32 {
        self.e11
    }
}


impl Mat2 for IdMatf32 {
    fn e00(&self) -> f32 {
        1f32
    }
    fn e01(&self) -> f32 {
        0f32
    }
    fn e10(&self) -> f32 {
        0f32
    }
    fn e11(&self) -> f32 {
        1f32
    }
}

impl<T: Mat2> Mul<T> for Mat2f32 {
    default type Output = Mat2f32;
    default fn mul(self, rhs: T) -> Mat2f32 {
        Mat2f32 {
            e00: self.e00*rhs.e00() + self.e01*rhs.e10(),
            e01: self.e00*rhs.e10() + self.e01*rhs.e11(),
            e10: self.e10*rhs.e00() + self.e11*rhs.e10(),
            e11: self.e10*rhs.e10() + self.e11*rhs.e11(),
        }
    }
}

impl Mul<IdMatf32> for Mat2f32 {
    type Output = Mat2f32;
    fn mul(self, _: IdMatf32) -> Mat2f32 {
        self
    }
}

fn main() {}
@steveklabnik steveklabnik added the A-typesystem Area: The type system label Mar 28, 2016
@amarant
Copy link
Author

amarant commented Mar 29, 2016

After reading this commit : Implement default associated type inheritance, this one : Add tests for specialization on associated types and the comments about associated type in the issue #30652 , it seems it is expected behavior, we "avoid projecting associated types", I feel the resulting error is a bit unclear and I don't know if it is even possible to have a "default type" that will pass.
Maybe I should close the issue ?

@shepmaster
Copy link
Member

Smaller example:

#![feature(specialization)]

trait Convert {
    type Target;
    fn convert(self) -> Self::Target;
}

impl<T> Convert for T {
    default type Target = T;
    default fn convert(self) -> Self::Target { self }
}

fn main() {}

Removing the defaults from the impl allows the code to compile. I have no idea on the validity of this as a bug or not, but I was surprised by it.

@Mark-Simulacrum
Copy link
Member

That seems valid, since I presume that type Target can be specialized separately from the function, though I haven't followed specialization closely. cc @aturon Is that correct?

@aturon
Copy link
Member

aturon commented May 16, 2017

This is currently intended behavior. In general, it would be unsound to allow convert to assume that Target is T if you can individually specialize to a different associated type later. (There are some alternative designs, but that can be discussed on the tracking issue).

I agree that the error is not great, and would be happy to see an issue for improving the error specifically.

@aturon aturon closed this as completed May 16, 2017
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

5 participants