8

I'm trying to access an attribute of a boxed struct inside an enum but I can't figure out how to pattern-match with std::boxed::Box

enum ArithExp {
    Sum {
        lhs: Box<ArithExp>,
        rhs: Box<ArithExp>,
    },
    Mul {
        lhs: Box<ArithExp>,
        rhs: Box<ArithExp>,
    },
    Num {
        value: f64,
    },
}

fn num(value: f64) -> std::boxed::Box<ArithExp> {
    Box::new(ArithExp::Num { value })
}

let mut number = num(1.0);
match number {
    ArithExp::Num { value } => println!("VALUE = {}", value),
}

I get the following error:

error[E0308]: mismatched types
  --> src/main.rs:22:9
   |
22 |         ArithExp::Num { value } => println!("VALUE = {}", value),
   |         ^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `main::ArithExp`
   |
   = note: expected type `std::boxed::Box<main::ArithExp>`
              found type `main::ArithExp`

What is the correct way of accessing the attribute?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • 1
    @ljedrz I think this is a bit different. The linked question is specifically about pattern matching the box itself. This is more about matching the contents of the box. – Peter Hall Sep 19 '18 at 10:37

1 Answers1

14

You need to dereference the boxed value so that you can access what's inside the box:

match *number {
    ArithExp::Num { value } => println!("VALUE = {}", value),
    _ => (),
}

playground

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Jmb
  • 18,893
  • 2
  • 28
  • 55
  • 1
    I'm running into a similar issue (also for an expression tree `struct`) but when I deference the box valued I get a different compiler error because the variable I'm pattern matching against is behind a shared reference. For example, I'm having to `match **expr { ... }` (one dereference for the reference, and the other for unboxing the value). The compiler suggests that I need to implement the `Copy` trait - is this the only way around this type of issue? – yanniskatsaros Dec 23 '22 at 23:25