I've got a trait with an associated type that I've got a default blanket impl for along with a specialized impl; the two impls have a different value for the associated type.
When I use the associated type in a trait bound on a function, typechecking fails as expected when the actual associated type doesn't match what the bound is asking for (the error message shows the expected type and the actual type). However, when I give the function a type that does have the expected type for the trait's associated type, it fails to typecheck with an error message that doesn't show what the associated type actually is ("expected struct Yes
; found associated type <SomeFoo as FooFilter>::IsNotClonable
").
I have a minimized example here: Rust Playground
#![feature(specialization)]
#![allow(incomplete_features)]
// Minimized:
struct Yes; struct No;
trait Foo { }
struct SomeFoo; impl Foo for SomeFoo { }
#[derive(Clone)] struct ClonableFoo; impl Foo for ClonableFoo { }
trait FooFilter { type IsNotClonable; }
impl<T: Foo> FooFilter for T { default type IsNotClonable = Yes; }
impl<T: Foo + Clone> FooFilter for T { type IsNotClonable = No; }
fn unclonable_foos_only<F: FooFilter<IsNotClonable = Yes>>(_foo: F) { }
fn main() {
// Correctly doesn't typecheck:
// ```
// | unclonable_foos_only(ClonableFoo);
// | ^^^^^^^^^^^^^^^^^^^^ expected struct `Yes`, found struct `No`
// ```
unclonable_foos_only(ClonableFoo);
// Also doesn't typecheck:
// ```
// | unclonable_foos_only(SomeFoo);
// | ^^^^^^^^^^^^^^^^^^^^ expected struct `Yes`, found associated type
// |
// = note: expected struct `Yes`
// found associated type `<SomeFoo as FooFilter>::IsNotClonable`
// ```
unclonable_foos_only(SomeFoo);
}
Is this the expected behavior?