#Why is `.` not allowed in match statements?

38 messages · Page 1 of 1 (latest)

radiant zenith
#

this works, but gives a weird warning message (tested on rust playground):

fn main() {
  let test = Main {
    test: 0
  };
  let testdefault = Test::default().input;
  match test {
    Main {
      test: testdefault
    } => print!("success"),
    _ => print!("failure")
  }
}

#[derive(Default)]
struct Test {
  input: u32
}

struct Main {
  test: u32
}

output:

warning: unreachable pattern
  --> src/main.rs:10:5
   |
7  | /     Main {
8  | |       test: testdefault
9  | |     } => print!("success"),
   | |_____- matches any value
10 |       _ => print!("failure")
   |       ^ unreachable pattern
   |
   = note: `#[warn(unreachable_patterns)]` on by default

warning: unused variable: `testdefault`
 --> src/main.rs:5:7
  |
5 |   let testdefault = Test::default().input;
  |       ^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_testdefault`
  |
  = note: `#[warn(unused_variables)]` on by default

warning: unused variable: `testdefault`
 --> src/main.rs:8:13
  |
8 |       test: testdefault
  |             ^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_testdefault`

output: success

however, this does not work at all:

fn main() {
  let test = Main {
    test: 0
  };
- let testdefault = Test::default();
  match test {
    Main {
+     test: testdefault.input
    } => print!("success"),
    _ => print!("failure")
  }
}

#[derive(Default)]
struct Test {
  input: u32
}

struct Main {
  test: u32
}

giving the error:

error: expected `,`
 --> src/main.rs:8:24
  |
7 |     Main {
  |     ---- while parsing the fields for this pattern
8 |       test: testdefault.input
  |                        ^

firstly, why are struct fields not accessible in match statements, and secondly, why does the working example have a warning of an unused variable despite the variable clearly being used?

idle bane
#

firstly, why are struct fields not accessible in match statements
they're not accessible on the pattern side. all you're doing there in a struct destructuring is adding a new pattern there, not a value.

#

which, coincidentally, is answering your second question.

an unused variable despite the variable clearly being used?
test: testdefault doesn't refer to the variable - it's a new binding of the name testdefault that's only valid for the scope of match arm.

desert maple
#

patterns are never (at least currently) dynamic. They are whatever you write in the source, values and all

idle bane
#

?play

#[derive(Default)]
struct Test {
  input: u32
}

struct Main {
  test: u32
}

fn main() {
    let test = Main {
        test: 2,
    };
    let testdefault = Test::default().input;
    println!("testdefault is {testdefault} here");
    match test {
        Main { test: testdefault } => println!("but not here - it's {testdefault}"),
        _ => println!("not a match"),
    }
}
frozen craneBOT
#
     Running `target/debug/playground`

testdefault is 0 here
but not here - it's 2
idle bane
#

testdefault is being bound to the value of the test field of the Main struct

#

does that make any sense?

radiant zenith
#

so match statements change the thing it is matching against if it is a variable?

desert maple
humble musk
#

you'd want match guards here

#

?play

#[derive(Default)]
struct Test {
  input: u32
}

struct Main {
  test: u32
}

fn main() {
  let test = Main {
    test: 0
  };
  let testdefault = Test::default().input;
  match test {
    _ if test.test == testdefault => print!("success"),
    _ => print!("failure")
  }
}
frozen craneBOT
#
     Running `target/debug/playground`

success```
humble musk
#

by that point you just wanna write an if else expression instead

radiant zenith
#

this is the actual use case. i am following the Learn WGPU tutorial, and I wanted to use scancodes.

use winit::{event_loop::EventLoop, window::WindowBuilder, event::{Event, WindowEvent, KeyboardInput, ElementState}};

pub fn run() {
    env_logger::init();
    let event_loop = EventLoop::new();
    let window = WindowBuilder::new().build(&event_loop).unwrap();
    
    event_loop.run(move |event, _, control_flow| match event {
    Event::WindowEvent { window_id, ref event } if window_id == window.id() => match event {
    WindowEvent::CloseRequested | WindowEvent::KeyboardInput { input: KeyboardInput {
        state: ElementState::Pressed,
+       scancode: ScanCode::default().Escape
    } }
}
})
}

struct ScanCode {
   Escape: u32
}

impl Default for ScanCode {
    fn default() -> Self {
        ScanCode { Escape: 1 }
    }
}
#

at this point, should i just follow the suggestion from @humble musk and use if else statements instead?

humble musk
#

ScanCode::default().Escape is kinda weird tbh

radiant zenith
#

haha yeah it is, but the problem is that even if i created a variable let scancodes = ScanCode::default(); at the top of the function to make it more readable or something it still wouldn't help with my use case at all

desert maple
radiant zenith
desert maple
#

oh

radiant zenith
#

because winit does not have scancodes so i tried to make my own

desert maple
humble musk
#

not experienced with wgpu, but isn't scan codes usually represented by enums?

desert maple
desert maple
#

scan codes are from the device directly

#

they can be anything

desert maple
# radiant zenith this is the actual use case. i am following the Learn WGPU tutorial, and I wante...
pub fn run() {
    env_logger::init();
    let event_loop = EventLoop::new();
    let window = WindowBuilder::new().build(&event_loop).unwrap();
    
    event_loop.run(move |event, _, control_flow| match event {
    Event::WindowEvent { window_id, ref event } if window_id == window.id() => match event {
    WindowEvent::CloseRequested | WindowEvent::KeyboardInput { input: KeyboardInput {
        state: ElementState::Pressed,
        virtual_keycode: Some(VirtualKeyCode::Escape),
        ..
    } }
}
})
}
radiant zenith
desert maple
#

the scan code would be the physical key for the specific keyboard

radiant zenith
desert maple
#

thats why they are virtual

#

they can float around the keyboard

radiant zenith
#

ah yes but that is what I don't want, I am trying to create a renderer with a movable camera so it will be better to map directions to the physical keys WASD instead of virtual keys since that changes whenever i switch keyboard layouts.

desert maple