Specialization results in spurious mismatch type errors

5d0f101
Opened by srrrse at 2024-04-19 14:17:43

An upstream crate presents me with this API:

trait Foo { }

trait Bar {
    fn bar<F: Foo>(&self, f: F);
}

This is a fine API as far as it goes, but my problem is that I only care about one Foo, and I need Bar to be object safe. For my use case, this is the API I want:

struct MyFoo;

impl Foo for MyFoo { }

trait MyBar {
    fn my_bar(&self, f: MyFoo);
}

But I need to bridge T: MyBar to T: Bar. I have this solution, based on specialization, which I believe is correct:

trait BarBridge<F: Foo> {
    fn bridge(&self, f: F) -> F::Assoc;
}

struct Bridge<T: MyBar>(T);

impl<T: MyBar> BarBridge<MyFoo> for Bridge<T> {
    fn bridge(&self, f: MyFoo) -> bool {
        self.0.my_bar(f)
    }
}

impl<T: MyBar, F: Foo> BarBridge<F> for Bridge<T> {
    default fn bridge(&self, _: F) {
        unreachable!()
    }
}

impl<T: MyBar> Bar for Bridge<T> {
    fn bar<F: Foo>(&self, f: F) {
        self.bridge(f)
    }
}

However this appears to greedily attempt to unify F with MyFoo because of the implementation of BarBridge<MyFoo> instead of recognizing the implementation of forall<F: Foo> BarBridge<F>.

cc @nikomatsakis @aturon

  1. Hm, can you give a complete example with error? In particular, I'm not sure where this greedy unification is happening, or where you're seeing the error.

    Aaron Turon at 2017-04-29 01:54:04

  2. Here's all the code from my post in one playpen, which shows the error: https://is.gd/Kem7r0

    The error is:

    error[E0308]: mismatched types
      --> <anon>:37:21
       |
    37 |         self.bridge(f)
       |                     ^ expected struct `MyFoo`, found type parameter
       |
       = note: expected type `MyFoo`
                  found type `F`
    

    I've discovered that this is method dispatch specifically, if I use the canonical name it compiles:

    impl<T: MyBar> Bar for Bridge<T> {
        fn bar<F: Foo>(&self, f: F) {
            <Bridge<T> as BarBridge<F>>::bridge(self, f)
        }
    }
    

    srrrse at 2017-04-29 02:01:41

  3. Heh, yikes. I suspect at this point it probably makes sense to wait until we've got specialization up and running in Chalk, and see the results there.

    Aaron Turon at 2017-04-29 02:09:37