Stabilized Trait Upcasting does not work with borrows

โš“ Rust    ๐Ÿ“… 2026-01-04    ๐Ÿ‘ค surdeus    ๐Ÿ‘๏ธ 2      

surdeus

Hello,
according to the following pages, upcasting has been stabilized with Rust 1.86:

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);
}

(Playground)

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

Read full topic

๐Ÿท๏ธ Rust_feed