Description
I tried this code:
#![feature(trait_upcasting)]
trait A: B {
type Assoc;
}
trait B {}
fn upcast(a: &dyn A<Assoc = i32>) -> &dyn B { a }
fn main() {}
I expected to see it compile.
Instead, this happened:
error[E0308]: mismatched types
--> src/main.rs:9:47
|
9 | fn upcast(a: &dyn A<Assoc = i32>) -> &dyn B { a }
| ------ ^ expected trait `B`, found trait `A<Assoc = i32>`
| |
| expected `&dyn B` because of return type
|
= note: expected reference `&dyn B`
found reference `&dyn A<Assoc = i32>`
The algorithm we use to do trait upcasting is incorrect, since it simply copies the existential associated types over:
rust/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
Lines 933 to 937 in fd56162
So if we upcast to a trait with fewer associated types (like B
), then the subtyping we do here is wrong:
rust/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
Lines 949 to 953 in fd56162
Since we require the list of existential trait bounds to be structurally compatible:
rust/compiler/rustc_middle/src/ty/relate.rs
Lines 689 to 698 in fd56162