diff options
Diffstat (limited to '')
-rw-r--r-- | src/test/ui/for-loop-while/label_break_value.rs | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/src/test/ui/for-loop-while/label_break_value.rs b/src/test/ui/for-loop-while/label_break_value.rs new file mode 100644 index 000000000..ca9d71a7a --- /dev/null +++ b/src/test/ui/for-loop-while/label_break_value.rs @@ -0,0 +1,167 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_assignments)] +#![feature(label_break_value)] + +// Test control flow to follow label_break_value semantics +fn label_break(a: bool, b: bool) -> u32 { + let mut v = 0; + 'b: { + v = 1; + if a { + break 'b; + } + v = 2; + if b { + break 'b; + } + v = 3; + } + return v; +} + +// Test that values can be returned +fn break_value(a: bool, b: bool) -> u32 { + let result = 'block: { + if a { break 'block 1; } + if b { break 'block 2; } + 3 + }; + result +} + +// Test nesting of labeled blocks +// here we only check that it compiles +fn label_break_nested() { + 'b: { + println!("hi"); + if false { + break 'b; + } + 'c: { + if false { + break 'b; + } + break 'c; + } + println!("hello"); + if true { + break 'b; + } + } +} + +// Tests for mixing labeled blocks with loop constructs +// This function should be the identity function +fn label_break_mixed(v: u32) -> u32 { + let mut r = 0; + 'b: { + // Unlabeled break still works + // (only crossing boundaries is an error) + loop { + break; + } + if v == 0 { + break 'b; + } + // Labeled breaking an inner loop still works + 'c: loop { + if r == 1 { + break 'c; + } + r += 1; + } + assert_eq!(r, 1); + if v == 1 { + break 'b; + } + // Labeled breaking an outer loop still works + 'd: loop { + { + if v == r { + break 'b; + } + if r == 5 { + break 'd; + } + r += 1; + } + } + assert_eq!(r, 5); + assert!(v > r); + // Here we test return from inside a labeled block + return v; + } + r +} + +fn label_break_match(c: u8, xe: u8, ye: i8) { + let mut x = 0; + let y = 'a: { + match c { + 0 => break 'a 0, + v if { if v % 2 == 0 { break 'a 1; }; v % 3 == 0 } => { x += 1; }, + v if { 'b: { break 'b v == 5; } } => { x = 41; }, + _ => 'b: { + break 'b (); + }, + } + x += 1; + -1 + }; + + assert_eq!(x, xe); + assert_eq!(y, ye); +} + +#[allow(unused_labels)] +fn label_break_macro() { + macro_rules! mac1 { + ($target:lifetime, $val:expr) => { + break $target $val; + }; + } + let x: u8 = 'a: { + 'b: { + mac1!('b, 1); + }; + 0 + }; + assert_eq!(x, 0); + let x: u8 = 'a: { + 'b: { + if true { + mac1!('a, 1); + } + }; + 0 + }; + assert_eq!(x, 1); +} + +pub fn main() { + assert_eq!(label_break(true, false), 1); + assert_eq!(label_break(false, true), 2); + assert_eq!(label_break(false, false), 3); + + assert_eq!(break_value(true, false), 1); + assert_eq!(break_value(false, true), 2); + assert_eq!(break_value(false, false), 3); + + assert_eq!(label_break_mixed(0), 0); + assert_eq!(label_break_mixed(1), 1); + assert_eq!(label_break_mixed(2), 2); + assert_eq!(label_break_mixed(3), 3); + assert_eq!(label_break_mixed(4), 4); + assert_eq!(label_break_mixed(5), 5); + assert_eq!(label_break_mixed(6), 6); + + label_break_match(0, 0, 0); + label_break_match(1, 1, -1); + label_break_match(2, 0, 1); + label_break_match(3, 2, -1); + label_break_match(5, 42, -1); + label_break_match(7, 1, -1); + + label_break_macro(); +} |