Rust: Misleading E0210: "only traits defined in the current crate can be implemented for a type parameter"

Created on 23 Nov 2017  路  3Comments  路  Source: rust-lang/rust

$ rustc --version
rustc 1.23.0-nightly (45594d5de 2017-11-22)
[package]
name = "type-param"
version = "0.1.0"
authors = ["Michael Lamparski <[email protected]>"]

[dependencies]
# apologies for the heavy dependency; this can probably be minimized
# but when I tried to do this I got the (slightly more accurate) E0117 instead
nalgebra = "0.13"
extern crate nalgebra;
use nalgebra::{Scalar, Dim, U3, MatrixMN};

struct Rows3<X, R>(MatrixMN<X, R, U3>);

// error[E0210]: type parameter `X` must be used as the type parameter for some local type
// (e.g. `MyStruct<T>`); only traits defined in the current crate can be implemented for
// a type parameter
impl<X: Scalar, R: Dim> From<Rows3<X, R>> for MatrixMN<X, R, U3> {
    fn from(rows: Rows3<X, R>) -> Self
    { rows.0 }
}

fn main() { }

The wording of the error seems to suggest that I have written impl<...> From<...> for X, which I clearly have not. (Also, on the surface, I have used X as the type parameter for a local type; just perhaps not in the way that the error message had intended)

A-diagnostics C-enhancement D-confusing T-compiler

Most helpful comment

Here is what I believe to be a reduced test case producing the error without dependency. The specificity here is the use of an associated type as a type parameter for Vec. This is similar to the scenario described by @ExpHP because MatrixMN is actually a type aliasing a struct taking an associated type as a type parameter, e.g., just like the Vec here:

use std::ops::Index;

struct Foo;
struct Bar {}

trait Test {
    type Assoc;
}

impl Test for Bar {
    type Assoc = usize;
}

impl From<Foo> for Vec<<Bar as Test>::Assoc> {
    fn from(data: Foo) -> Self {
        Vec::new()
    }
}

All 3 comments

I'm also getting this error. How do you resolve if?

Here is what I believe to be a reduced test case producing the error without dependency. The specificity here is the use of an associated type as a type parameter for Vec. This is similar to the scenario described by @ExpHP because MatrixMN is actually a type aliasing a struct taking an associated type as a type parameter, e.g., just like the Vec here:

use std::ops::Index;

struct Foo;
struct Bar {}

trait Test {
    type Assoc;
}

impl Test for Bar {
    type Assoc = usize;
}

impl From<Foo> for Vec<<Bar as Test>::Assoc> {
    fn from(data: Foo) -> Self {
        Vec::new()
    }
}

Here's an even smaller test case that also produces E0210.

struct HasVec<T>(Vec<T>);

impl <T> From<HasVec<T>> for Vec<T> {
    fn from(HasVec(vec): HasVec<T>) -> Self {
        vec
    }
}

Playground Link

Was this page helpful?
0 / 5 - 0 ratings