Pre-pre-RFC: match ergonomics for container types — restricted method calls in patterns

I tried "translating" some sufficiently complex example:

    struct S;
    // used to better distinguish the use of `Option` in the translation
    enum Maybe<T> {
        Just(T),
        #[allow(dead_code)]
        Nothing,
    }
    use Maybe::*;
    impl S {
        fn test1(&self) -> bool {
            false
        }
        fn test2(&self) -> bool {
            true
        }
        fn consume(self) -> i32 {
            1337
        }
    }
    let x = Box::new(Just(Box::new(S)));
    fn qux(_: &Box<S>) -> bool {
        false
    }
    fn bar(_: &Box<Maybe<Box<S>>>) -> bool {
        false
    }
    fn consume_box(_: Box<S>) -> i32 {
        -1000000
    }
    
    /*
    let _r = match x {
        b if bar(&b) => {drop(b); 42}
        deref Nothing => 123,
        deref Just(s) if qux(&s) => consume_box(s),
        b if bar(&b) => {drop(b); 420}
        deref Just(deref S) if false => 0,
        deref Just(deref s) if s.test1() => s.consume(),
        b if bar(&b) => {drop(b); 4200}
        deref Just(deref s) if s.test2() => s.consume(),
        _ => 0,
    }
    */
    // translation in playground linked below

(See the actual translation here.)

using a DerefMove trait. Bad Deref implementations like the ones @CAD97 described can/will lead to panics in this translation. Also note how it is possible to avoid duplicating any calls to deref.

I’m ignoring things like drop order here, so the translation might be not exactly what one would ultimately want here; also an actual compiler can probably use some thing like goto to avoid code duplication, so the trick using Option like I did may be not necessary.

1 Like