#Multiple overlapping `From` implementations are allowed?!

4 messages · Page 1 of 1 (latest)

vapid tusk
#

I have been working on a library and have had the following code snippet:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=60c0f0196a14fd6a8b53e6d04065b46b

pub struct Never(());

pub struct Attributes<I, W> {
    pub(crate) id: I,
    pub(crate) weight: W,
}

impl<I, W> From<(I, W)> for Attributes<I, W>
{
    fn from(value: (I, W)) -> Self {
        Self {
            id: value.0,
            weight: value.1,
        }
    }
}

impl<W> From<(W,)> for Attributes<Never, W> {
    fn from((weight,): (W,)) -> Self {
        Self {
            id: Never(()),
            weight,
        }
    }
}

impl<W> From<W> for Attributes<Never, W> {
    fn from(weight: W) -> Self {
        Self {
            id: Never(()),
            weight,
        }
    }
}

You might immediately see it, but even though I provide a blanket implementation (via From<W> for Attributes<Never, W>) I am able to implement (and subsequently compile) with a more specialised implementation of From<(W, )> for Attributes<Never, W>, but this should violate the coherence rules. Take for example (u8, ), both the second and third From implementation would match both implementation, therefor violating the rule, and last time I checked tuples are no fundamental types either.

So I am baffled - why does this compile? What am I overlooking?

#

Multiple overlapping From implementations are allowed?!

orchid hamlet
#

the compiler knows that W and (W,) can't be the same type for the same W