From ffdabc8be8c3514d97ff24de21e3e4f2d9441a16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Wed, 15 Sep 2021 00:00:00 +0000 Subject: [PATCH] Check for shadowing issues involving block labels --- compiler/rustc_resolve/src/late/lifetimes.rs | 6 ++++- .../loops/loops-reject-duplicate-labels-2.rs | 6 +++-- .../loops-reject-duplicate-labels-2.stderr | 10 ++++++- .../ui/loops/loops-reject-duplicate-labels.rs | 11 +++++--- .../loops-reject-duplicate-labels.stderr | 26 ++++++++++++------- .../loops-reject-lifetime-shadowing-label.rs | 13 +++++++--- ...ops-reject-lifetime-shadowing-label.stderr | 10 ++++++- 7 files changed, 61 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 4c1d537d55fa3..548c734b86543 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -1652,7 +1652,11 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) { } fn expression_label(ex: &hir::Expr<'_>) -> Option { - if let hir::ExprKind::Loop(_, Some(label), ..) = ex.kind { Some(label.ident) } else { None } + match ex.kind { + hir::ExprKind::Loop(_, Some(label), ..) => Some(label.ident), + hir::ExprKind::Block(_, Some(label)) => Some(label.ident), + _ => None, + } } fn check_if_label_shadows_lifetime(tcx: TyCtxt<'_>, mut scope: ScopeRef<'_>, label: Ident) { diff --git a/src/test/ui/loops/loops-reject-duplicate-labels-2.rs b/src/test/ui/loops/loops-reject-duplicate-labels-2.rs index 3a860f508ff78..68a19a8f6f717 100644 --- a/src/test/ui/loops/loops-reject-duplicate-labels-2.rs +++ b/src/test/ui/loops/loops-reject-duplicate-labels-2.rs @@ -1,7 +1,7 @@ // check-pass +#![feature(label_break_value)] - -// Issue #21633: reject duplicate loop labels in function bodies. +// Issue #21633: reject duplicate loop labels and block labels in function bodies. // // This is testing the generalization (to the whole function body) // discussed here: @@ -26,6 +26,8 @@ pub fn foo() { { 'lt: loop { break; } } { 'lt: while let Some(_) = None:: { break; } } //~^ WARN label name `'lt` shadows a label name that is already in scope + { 'bl: {} } + { 'bl: {} } //~ WARN label name `'bl` shadows a label name that is already in scope } diff --git a/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr b/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr index 6c53d04e10790..2c372fcff7a12 100644 --- a/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr +++ b/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr @@ -62,5 +62,13 @@ LL | { 'lt: loop { break; } } LL | { 'lt: while let Some(_) = None:: { break; } } | ^^^ label `'lt` already in scope -warning: 8 warnings emitted +warning: label name `'bl` shadows a label name that is already in scope + --> $DIR/loops-reject-duplicate-labels-2.rs:30:7 + | +LL | { 'bl: {} } + | --- first declared here +LL | { 'bl: {} } + | ^^^ label `'bl` already in scope + +warning: 9 warnings emitted diff --git a/src/test/ui/loops/loops-reject-duplicate-labels.rs b/src/test/ui/loops/loops-reject-duplicate-labels.rs index d9334ce385718..c34bcf3df1d76 100644 --- a/src/test/ui/loops/loops-reject-duplicate-labels.rs +++ b/src/test/ui/loops/loops-reject-duplicate-labels.rs @@ -1,8 +1,7 @@ // check-pass +#![feature(label_break_value)] - -// Issue #21633: reject duplicate loop labels in function bodies. -// This is testing the exact cases that are in the issue description. +// Issue #21633: reject duplicate loop labels and block labels in function bodies. #[allow(unused_labels)] fn foo() { @@ -24,6 +23,8 @@ fn foo() { 'lt: loop { break; } 'lt: while let Some(_) = None:: { break; } //~^ WARN label name `'lt` shadows a label name that is already in scope + 'bl: {} + 'bl: {} //~ WARN label name `'bl` shadows a label name that is already in scope } // Note however that it is okay for the same label to be reused in @@ -33,6 +34,8 @@ struct S; impl S { fn m1(&self) { 'okay: loop { break 'okay; } } fn m2(&self) { 'okay: loop { break 'okay; } } + fn m3(&self) { 'okay: { break 'okay; } } + fn m4(&self) { 'okay: { break 'okay; } } } @@ -40,5 +43,7 @@ pub fn main() { let s = S; s.m1(); s.m2(); + s.m3(); + s.m4(); foo(); } diff --git a/src/test/ui/loops/loops-reject-duplicate-labels.stderr b/src/test/ui/loops/loops-reject-duplicate-labels.stderr index 5bdf64849f305..3bf3af763ecfc 100644 --- a/src/test/ui/loops/loops-reject-duplicate-labels.stderr +++ b/src/test/ui/loops/loops-reject-duplicate-labels.stderr @@ -1,5 +1,5 @@ warning: label name `'fl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:10:5 + --> $DIR/loops-reject-duplicate-labels.rs:9:5 | LL | 'fl: for _ in 0..10 { break; } | --- first declared here @@ -7,7 +7,7 @@ LL | 'fl: loop { break; } | ^^^ label `'fl` already in scope warning: label name `'lf` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:13:5 + --> $DIR/loops-reject-duplicate-labels.rs:12:5 | LL | 'lf: loop { break; } | --- first declared here @@ -15,7 +15,7 @@ LL | 'lf: for _ in 0..10 { break; } | ^^^ label `'lf` already in scope warning: label name `'wl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:15:5 + --> $DIR/loops-reject-duplicate-labels.rs:14:5 | LL | 'wl: while 2 > 1 { break; } | --- first declared here @@ -23,7 +23,7 @@ LL | 'wl: loop { break; } | ^^^ label `'wl` already in scope warning: label name `'lw` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:17:5 + --> $DIR/loops-reject-duplicate-labels.rs:16:5 | LL | 'lw: loop { break; } | --- first declared here @@ -31,7 +31,7 @@ LL | 'lw: while 2 > 1 { break; } | ^^^ label `'lw` already in scope warning: label name `'fw` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:19:5 + --> $DIR/loops-reject-duplicate-labels.rs:18:5 | LL | 'fw: for _ in 0..10 { break; } | --- first declared here @@ -39,7 +39,7 @@ LL | 'fw: while 2 > 1 { break; } | ^^^ label `'fw` already in scope warning: label name `'wf` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:21:5 + --> $DIR/loops-reject-duplicate-labels.rs:20:5 | LL | 'wf: while 2 > 1 { break; } | --- first declared here @@ -47,7 +47,7 @@ LL | 'wf: for _ in 0..10 { break; } | ^^^ label `'wf` already in scope warning: label name `'tl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:23:5 + --> $DIR/loops-reject-duplicate-labels.rs:22:5 | LL | 'tl: while let Some(_) = None:: { break; } | --- first declared here @@ -55,12 +55,20 @@ LL | 'tl: loop { break; } | ^^^ label `'tl` already in scope warning: label name `'lt` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:25:5 + --> $DIR/loops-reject-duplicate-labels.rs:24:5 | LL | 'lt: loop { break; } | --- first declared here LL | 'lt: while let Some(_) = None:: { break; } | ^^^ label `'lt` already in scope -warning: 8 warnings emitted +warning: label name `'bl` shadows a label name that is already in scope + --> $DIR/loops-reject-duplicate-labels.rs:27:5 + | +LL | 'bl: {} + | --- first declared here +LL | 'bl: {} + | ^^^ label `'bl` already in scope + +warning: 9 warnings emitted diff --git a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs index 3212b78b08cd8..ce2d07eb06a4d 100644 --- a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs +++ b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs @@ -1,10 +1,10 @@ // check-pass - +#![feature(label_break_value)] #![allow(dead_code, unused_variables)] -// Issue #21633: reject duplicate loop labels in function bodies. +// Issue #21633: reject duplicate loop labels and block labels in function bodies. // -// Test rejection of lifetimes in *expressions* that shadow loop labels. +// Test rejection of lifetimes in *expressions* that shadow labels. fn foo() { // Reusing lifetime `'a` in function item is okay. @@ -23,8 +23,13 @@ fn foo() { assert_eq!((*b)(&z), z); break 'a; } -} + 'b: { + let b = Box::new(|x: &()| ()) as Box Fn(&'b ())>; + //~^ WARN lifetime name `'b` shadows a label name that is already in scope + break 'b; + } +} pub fn main() { foo(); diff --git a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr index dcee1a8009053..9702b71600b5e 100644 --- a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr +++ b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr @@ -6,5 +6,13 @@ LL | 'a: loop { LL | let b = Box::new(|x: &i8| *x) as Box Fn(&'a i8) -> i8>; | ^^ label `'a` already in scope -warning: 1 warning emitted +warning: lifetime name `'b` shadows a label name that is already in scope + --> $DIR/loops-reject-lifetime-shadowing-label.rs:28:55 + | +LL | 'b: { + | -- first declared here +LL | let b = Box::new(|x: &()| ()) as Box Fn(&'b ())>; + | ^^ label `'b` already in scope + +warning: 2 warnings emitted