| // Test that the correct error is emitted when `#[loop_match]` is applied to | |
| // syntax it does not support. | |
| #![allow(incomplete_features)] | |
| #![feature(loop_match)] | |
| #![crate_type = "lib"] | |
| enum State { | |
| A, | |
| B, | |
| C, | |
| } | |
| fn invalid_update() { | |
| let mut fake = State::A; | |
| let state = State::A; | |
| #[loop_match] | |
| loop { | |
| fake = 'blk: { | |
| //~^ ERROR invalid update of the `#[loop_match]` state | |
| match state { | |
| _ => State::B, | |
| } | |
| } | |
| } | |
| } | |
| fn invalid_scrutinee() { | |
| let mut state = State::A; | |
| #[loop_match] | |
| loop { | |
| state = 'blk: { | |
| match State::A { | |
| //~^ ERROR invalid match on `#[loop_match]` state | |
| _ => State::B, | |
| } | |
| } | |
| } | |
| } | |
| fn bad_statements_1() { | |
| let mut state = State::A; | |
| #[loop_match] | |
| loop { | |
| 1; | |
| //~^ ERROR statements are not allowed in this position within a `#[loop_match]` | |
| state = 'blk: { | |
| match State::A { | |
| _ => State::B, | |
| } | |
| } | |
| } | |
| } | |
| fn bad_statements_2() { | |
| let mut state = State::A; | |
| #[loop_match] | |
| loop { | |
| state = 'blk: { | |
| 1; | |
| //~^ ERROR statements are not allowed in this position within a `#[loop_match]` | |
| match State::A { | |
| _ => State::B, | |
| } | |
| } | |
| } | |
| } | |
| fn bad_rhs_1() { | |
| let mut state = State::A; | |
| #[loop_match] | |
| loop { | |
| state = State::B | |
| //~^ ERROR this expression must be a single `match` wrapped in a labeled block | |
| } | |
| } | |
| fn bad_rhs_2() { | |
| let mut state = State::A; | |
| #[loop_match] | |
| loop { | |
| state = 'blk: { | |
| State::B | |
| //~^ ERROR this expression must be a single `match` wrapped in a labeled block | |
| } | |
| } | |
| } | |
| fn bad_rhs_3() { | |
| let mut state = (); | |
| #[loop_match] | |
| loop { | |
| state = 'blk: { | |
| //~^ ERROR this expression must be a single `match` wrapped in a labeled block | |
| } | |
| } | |
| } | |
| fn missing_assignment() { | |
| #[loop_match] | |
| loop { | |
| () //~ ERROR expected a single assignment expression | |
| } | |
| } | |
| fn empty_loop_body() { | |
| #[loop_match] | |
| loop { | |
| //~^ ERROR expected a single assignment expression | |
| } | |
| } | |
| fn break_without_value() { | |
| let mut state = State::A; | |
| #[loop_match] | |
| 'a: loop { | |
| state = 'blk: { | |
| match state { | |
| State::A => { | |
| #[const_continue] | |
| break 'blk; | |
| //~^ ERROR mismatched types | |
| } | |
| _ => break 'a, | |
| } | |
| } | |
| } | |
| } | |
| fn break_without_value_unit() { | |
| let mut state = (); | |
| #[loop_match] | |
| 'a: loop { | |
| state = 'blk: { | |
| match state { | |
| () => { | |
| #[const_continue] | |
| break 'blk; | |
| //~^ ERROR a `#[const_continue]` must break to a label with a value | |
| } | |
| } | |
| } | |
| } | |
| } | |
| fn break_without_label() { | |
| let mut state = State::A; | |
| let _ = { | |
| #[loop_match] | |
| loop { | |
| state = 'blk: { | |
| match state { | |
| _ => { | |
| #[const_continue] | |
| break State::A; | |
| //~^ ERROR unlabeled `break` inside of a labeled block | |
| //~| ERROR a `#[const_continue]` must break to a label with a value | |
| } | |
| } | |
| } | |
| } | |
| }; | |
| } | |
| fn arm_has_guard(cond: bool) { | |
| let mut state = State::A; | |
| #[loop_match] | |
| 'a: loop { | |
| state = 'blk: { | |
| match state { | |
| State::A => { | |
| #[const_continue] | |
| break 'blk State::B; | |
| } | |
| State::B if cond => break 'a, | |
| //~^ ERROR match arms that are part of a `#[loop_match]` cannot have guards | |
| _ => break 'a, | |
| } | |
| } | |
| } | |
| } | |
| fn non_exhaustive() { | |
| let mut state = State::A; | |
| #[loop_match] | |
| loop { | |
| state = 'blk: { | |
| match state { | |
| //~^ ERROR non-exhaustive patterns: `State::B` and `State::C` not covered | |
| State::A => State::B, | |
| } | |
| } | |
| } | |
| } | |
| fn invalid_range_pattern(state: f32) { | |
| #[loop_match] | |
| loop { | |
| state = 'blk: { | |
| match state { | |
| 1.0 => { | |
| #[const_continue] | |
| break 'blk 2.5; | |
| } | |
| 4.0..3.0 => { | |
| //~^ ERROR lower bound for range pattern must be less than upper bound | |
| todo!() | |
| } | |
| } | |
| } | |
| } | |
| } |