-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Closed
Milestone
Description
This code causes a segfault (without optimisations on):
use std::fmt;
fn main() {
let a = std::rc::Rc::new(1);
let x = (1, 2);
match x {
(_, y) |
(y, _) if take(y, a) => (),
_ => ()
}
}
fn take<T:fmt::Debug>(x: usize, t: T) -> bool {
println!("{:?}", t);
x == 1
}
as does this similar code:
use std::fmt;
fn main() {
let a = std::rc::Rc::new(1);
let x = (1, 2);
match x {
(_, y) if take(y, a) => (),
(y, _) if take(y, a) => (),
_ => ()
}
}
fn take<T:fmt::Debug>(x: usize, t: T) -> bool {
println!("{:?}", t);
x == 1
}
This is because the current control flow graph essentially visits each arm in parallel. With multiple patterns, each pattern within the arm is visited, then the guard is visited after all the patterns have been visited, even though this doesn't reflect the real semantics (we visit the pattern, then the guard, then the next pattern, then the guard again).