// 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 range bound must be less than upper todo!() } } } } }