Skip to content

Commit

Permalink
Check for shadowing issues involving block labels
Browse files Browse the repository at this point in the history
  • Loading branch information
tmiasko committed Sep 15, 2021
1 parent e846f9c commit ffdabc8
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 21 deletions.
6 changes: 5 additions & 1 deletion compiler/rustc_resolve/src/late/lifetimes.rs
Expand Up @@ -1652,7 +1652,11 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) {
}

fn expression_label(ex: &hir::Expr<'_>) -> Option<Ident> {
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) {
Expand Down
6 changes: 4 additions & 2 deletions 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:
Expand All @@ -26,6 +26,8 @@ pub fn foo() {
{ 'lt: loop { break; } }
{ 'lt: while let Some(_) = None::<i32> { 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
}


Expand Down
10 changes: 9 additions & 1 deletion src/test/ui/loops/loops-reject-duplicate-labels-2.stderr
Expand Up @@ -62,5 +62,13 @@ LL | { 'lt: loop { break; } }
LL | { 'lt: while let Some(_) = None::<i32> { 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

11 changes: 8 additions & 3 deletions 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() {
Expand All @@ -24,6 +23,8 @@ fn foo() {
'lt: loop { break; }
'lt: while let Some(_) = None::<i32> { 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
Expand All @@ -33,12 +34,16 @@ 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; } }
}


pub fn main() {
let s = S;
s.m1();
s.m2();
s.m3();
s.m4();
foo();
}
26 changes: 17 additions & 9 deletions src/test/ui/loops/loops-reject-duplicate-labels.stderr
@@ -1,66 +1,74 @@
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
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
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
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
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
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
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::<i32> { break; }
| --- first declared here
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::<i32> { 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

13 changes: 9 additions & 4 deletions 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.
Expand All @@ -23,8 +23,13 @@ fn foo() {
assert_eq!((*b)(&z), z);
break 'a;
}
}

'b: {
let b = Box::new(|x: &()| ()) as Box<dyn for <'b> Fn(&'b ())>;
//~^ WARN lifetime name `'b` shadows a label name that is already in scope
break 'b;
}
}

pub fn main() {
foo();
Expand Down
10 changes: 9 additions & 1 deletion src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr
Expand Up @@ -6,5 +6,13 @@ LL | 'a: loop {
LL | let b = Box::new(|x: &i8| *x) as Box<dyn for <'a> 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<dyn for <'b> Fn(&'b ())>;
| ^^ label `'b` already in scope

warning: 2 warnings emitted

0 comments on commit ffdabc8

Please sign in to comment.