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: { //~ WARNING `'b` shadows a label
+ 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: { //~ WARNING `'a` shadows a label
+ 'b: { //~ WARNING `'b` shadows a label
+ 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_mixed(5), 5);
assert_eq!(label_break_mixed(6), 6);
- // FIXME: ensure that labeled blocks work if produced by macros and in match arms
+ 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();
}
--- /dev/null
+warning: label name `'b` shadows a label name that is already in scope
+ --> $DIR/label_break_value.rs:105:18
+ |
+LL | v if { 'b: { break 'b v == 5; } } => { x = 41; },
+ | -- first declared here
+LL | _ => 'b: {
+ | ^^ label `'b` already in scope
+
+warning: label name `'a` shadows a label name that is already in scope
+ --> $DIR/label_break_value.rs:131:17
+ |
+LL | let x: u8 = 'a: {
+ | -- first declared here
+...
+LL | let x: u8 = 'a: {
+ | ^^ label `'a` already in scope
+
+warning: label name `'b` shadows a label name that is already in scope
+ --> $DIR/label_break_value.rs:132:9
+ |
+LL | 'b: {
+ | -- first declared here
+...
+LL | 'b: {
+ | ^^ label `'b` already in scope
+
+warning: 3 warnings emitted
+
--- /dev/null
+#![crate_type = "lib"]
+#![feature(label_break_value)]
+
+fn lbv_macro_test_hygiene_respected() {
+ macro_rules! mac2 {
+ ($val:expr) => {
+ break 'a $val; //~ ERROR undeclared label `'a` [E0426]
+ };
+ }
+ let x: u8 = 'a: {
+ 'b: {
+ if true {
+ mac2!(2);
+ }
+ };
+ 0
+ };
+ assert_eq!(x, 2);
+
+ macro_rules! mac3 {
+ ($val:expr) => {
+ 'a: {
+ //~^ WARNING `'a` shadows a label
+ //~| WARNING `'a` shadows a label
+ //~| WARNING `'a` shadows a label
+ $val
+ }
+ };
+ }
+ let x: u8 = mac3!('b: { //~ WARNING `'b` shadows a label
+ if true {
+ break 'a 3; //~ ERROR undeclared label `'a` [E0426]
+ }
+ 0
+ });
+ assert_eq!(x, 3);
+ let x: u8 = mac3!(break 'a 4); //~ ERROR undeclared label `'a` [E0426]
+ assert_eq!(x, 4);
+}
--- /dev/null
+error[E0426]: use of undeclared label `'a`
+ --> $DIR/label_break_value_invalid.rs:7:19
+ |
+LL | break 'a $val;
+ | ^^ undeclared label `'a`
+...
+LL | mac2!(2);
+ | -------- in this macro invocation
+ |
+ = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0426]: use of undeclared label `'a`
+ --> $DIR/label_break_value_invalid.rs:32:19
+ |
+LL | let x: u8 = mac3!('b: {
+ | -- a label with a similar name is reachable
+LL | if true {
+LL | break 'a 3;
+ | ^^
+ | |
+ | undeclared label `'a`
+ | help: try using similarly named label: `'b`
+
+error[E0426]: use of undeclared label `'a`
+ --> $DIR/label_break_value_invalid.rs:37:29
+ |
+LL | let x: u8 = mac3!(break 'a 4);
+ | ^^ undeclared label `'a`
+
+warning: label name `'a` shadows a label name that is already in scope
+ --> $DIR/label_break_value_invalid.rs:22:13
+ |
+LL | let x: u8 = 'a: {
+ | -- first declared here
+...
+LL | 'a: {
+ | ^^ label `'a` already in scope
+...
+LL | let x: u8 = mac3!('b: {
+ | _________________-
+LL | | if true {
+LL | | break 'a 3;
+LL | | }
+LL | | 0
+LL | | });
+ | |______- in this macro invocation
+ |
+ = note: this warning originates in the macro `mac3` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: label name `'b` shadows a label name that is already in scope
+ --> $DIR/label_break_value_invalid.rs:30:23
+ |
+LL | 'b: {
+ | -- first declared here
+...
+LL | let x: u8 = mac3!('b: {
+ | ^^ label `'b` already in scope
+
+warning: label name `'a` shadows a label name that is already in scope
+ --> $DIR/label_break_value_invalid.rs:22:13
+ |
+LL | let x: u8 = 'a: {
+ | -- first declared here
+...
+LL | 'a: {
+ | ^^ label `'a` already in scope
+...
+LL | let x: u8 = mac3!(break 'a 4);
+ | ----------------- in this macro invocation
+ |
+ = note: this warning originates in the macro `mac3` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: label name `'a` shadows a label name that is already in scope
+ --> $DIR/label_break_value_invalid.rs:22:13
+ |
+LL | 'a: {
+ | ^^
+ | |
+ | first declared here
+ | label `'a` already in scope
+...
+LL | let x: u8 = mac3!(break 'a 4);
+ | ----------------- in this macro invocation
+ |
+ = note: this warning originates in the macro `mac3` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors; 4 warnings emitted
+
+For more information about this error, try `rustc --explain E0426`.