Stabilized Trait Upcasting does not work with borrows
โ Rust ๐ 2026-01-04 ๐ค surdeus ๐๏ธ 2Hello,
according to the following pages, upcasting has been stabilized with Rust 1.86:
- Announcing Rust 1.86.0 | Rust Blog
- Tracking issue for dyn upcasting coercion ยท Issue #65991 ยท rust-lang/rust ยท GitHub
- Stabilize `feature(trait_upcasting)` by WaffleLapkin ยท Pull Request #134367 ยท rust-lang/rust ยท GitHub
but still minimal code example below does not compile (Stable, Edition 2024, Rust 1.92):
trait Sup {
fn do_sup(&self);
}
trait Sub: Sup {
fn do_sub(&self);
}
impl Sup for () {
fn do_sup(&self) {
println!("Doing sup things!");
}
}
impl Sub for () {
fn do_sub(&self) {
println!("Doing sub things!");
}
}
fn expecting_borrow_sup_box(a: &Box<dyn Sup>) {
a.do_sup();
}
fn expecting_sup(a: &dyn Sup) {
a.do_sup();
}
fn main() {
// Stack allocated trait objects, i.e. borrowed values work
let a: &dyn Sub = &();
expecting_sup(a);
// Coercion requires strange syntax
// FAILS:
// let b: &Box<dyn Sub> = &Box::new(()) as &Box<dyn Sub>;
// WORKS:
let b: &Box<dyn Sub> = &(Box::new(()) as Box<dyn Sub>);
// Upcasting fails for borrowed values (owned values work in (some cases))
//expecting_borrow_sup_box(b);
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:41:30
|
41 | expecting_borrow_sup_box(b);
| ------------------------ ^ expected trait `Sup`, found trait `Sub`
| |
| arguments to this function are incorrect
|
= note: expected reference `&Box<(dyn Sup + 'static)>`
found reference `&Box<dyn Sub>`
note: function defined here
--> src/main.rs:21:4
|
21 | fn expecting_borrow_sup_box(a: &Box<dyn Sup>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^ ----------------
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` (bin "playground") due to 1 previous error
It looks like upcasting works for:
- Raw stack allocated trait objects
- Owned smart pointers
But fails for references to smart pointers.
Is this is expected and why doesn't rust support it for borrowed smart pointers?.
This restricts you to owned values. It seems the coercion operator also has not been updated to catch trait objects inside smart pointers.
5 posts - 3 participants
๐ท๏ธ Rust_feed