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

Cross-crate coherence failures can produce unhelpful spans #23563

Closed
aturon opened this issue Mar 20, 2015 · 3 comments
Closed

Cross-crate coherence failures can produce unhelpful spans #23563

aturon opened this issue Mar 20, 2015 · 3 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-typesystem Area: The type system C-enhancement Category: An issue proposing an enhancement or a PR with one.

Comments

@aturon
Copy link
Member

aturon commented Mar 20, 2015

Consider the following example.

Crate A

pub trait To<T> {
    fn convert_to(&self) -> T;
}

pub trait Into<T>: Sized {
    fn convert_into(self) -> T;
}

pub trait From<T> {
    fn from(T) -> Self;
}

impl<'a, T: ?Sized, U> Into<U> for &'a T where T: To<U> {
    fn convert_into(self) -> U {
        self.convert_to()
    }
}

impl<T, U> From<T> for U where T: Into<U> {
    fn from(t: T) -> U {
        t.convert_into()
    }
}

Crate B

struct LocalType<T>(Option<T>);

impl<'a, T> From<&'a [T]> for LocalType<T> {
    fn from(_: &'a [T]) -> LocalType<T> { LocalType(None) }
}

impl<T> Into<LocalType<T>> for LocalType<T> {
    fn convert_into(self) -> LocalType<T> {
        self
    }
}

impl To<LocalType<u8>> for [u8] {
    fn convert_to(&self) -> LocalType<u8> {
        LocalType(None)
    }
}

You get an error like:

conv-downstream.rs:6:1: 8:2 error: conflicting implementations for trait `conv_crate::From` [E0119]
conv-downstream.rs:6 impl<'a, T> From<&'a [T]> for LocalType<T> {
conv-downstream.rs:7     fn from(_: &'a [T]) -> LocalType<T> { LocalType(None) }
conv-downstream.rs:8 }
conv-downstream.rs:6:1: 8:2 note: conflicting implementation in crate `conv_crate`
conv-downstream.rs:6 impl<'a, T> From<&'a [T]> for LocalType<T> {
conv-downstream.rs:7     fn from(_: &'a [T]) -> LocalType<T> { LocalType(None) }
conv-downstream.rs:8 }

where the conflicting impls are identical ones, both drawn from the downstream crate.

@aturon aturon added A-typesystem Area: The type system A-diagnostics Area: Messages for errors, warnings, and lints labels Mar 20, 2015
@aturon
Copy link
Member Author

aturon commented Mar 20, 2015

cc @nikomatsakis

@nikomatsakis
Copy link
Contributor

thanks for filing, been meaning to clean this up -- it's not just the spans, i'd like it to tell you more. For example, I would like it to print out something like "there are two impls applicable to the type Foo, and the following conditions are all satisfiable"

@steveklabnik
Copy link
Member

steveklabnik commented Nov 15, 2016

Triage: here's a way to reproduce this:

In a.rs:

pub trait LolTo<T> {
    fn convert_to(&self) -> T;
}

pub trait LolInto<T>: Sized {
    fn convert_into(self) -> T;
}

pub trait LolFrom<T> {
    fn from(T) -> Self;
}

impl<'a, T: ?Sized, U> LolInto<U> for &'a T where T: LolTo<U> {
    fn convert_into(self) -> U {
        self.convert_to()
    }
}

impl<T, U> LolFrom<T> for U where T: LolInto<U> {
    fn from(t: T) -> U {
        t.convert_into()
    }
}

In b.rs:

extern crate a;

use a::LolFrom;
use a::LolInto;
use a::LolTo;

struct LocalType<T>(Option<T>);

impl<'a, T> LolFrom<&'a [T]> for LocalType<T> {
    fn from(_: &'a [T]) -> LocalType<T> { LocalType(None) }
}

impl<T> LolInto<LocalType<T>> for LocalType<T> {
    fn convert_into(self) -> LocalType<T> {
        self
    }
}

impl LolTo<LocalType<u8>> for [u8] {
    fn convert_to(&self) -> LocalType<u8> {
        LocalType(None)
    }
}

then:

$ rustc a.rs --crate-type=lib
$ rustc b.rs --crate-type=lib --extern a=liba.rlib
error[E0119]: conflicting implementations of trait `a::LolFrom<&[_]>` for type `LocalType<_>`:
  --> b.rs:9:1
   |
9  | impl<'a, T> LolFrom<&'a [T]> for LocalType<T> {
   | ^
   |
   = note: conflicting implementation in crate `a`

error: aborting due to previous error

(this is with 1.13.0)

@Mark-Simulacrum Mark-Simulacrum added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jul 22, 2017
bors added a commit that referenced this issue Oct 25, 2017
…sakis

Improve diagnostic of E0119 with extern crate, try to print the conflicting impl.

Closes #27403.
Closes #23563.

Should improve #23980.

The diagnostic now looks like:

```
error[E0119]: conflicting implementations of trait `std::convert::Into<_>` for type `GenX<_>`:
  --> $DIR/issue-27403.rs:15:1
   |
15 | / impl<S> Into<S> for GenX<S> {
16 | |     fn into(self) -> S {
17 | |         self.inner
18 | |     }
19 | | }
   | |_^
   |
   = note: conflicting implementation in crate `core`:
           - impl<T, U> std::convert::Into<U> for T
             where U: std::convert::From<T>;

error: aborting due to previous error
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-typesystem Area: The type system C-enhancement Category: An issue proposing an enhancement or a PR with one.
Projects
None yet
Development

No branches or pull requests

4 participants