Skip to content

Commit ffdabc8

Browse files
committed
Check for shadowing issues involving block labels
1 parent e846f9c commit ffdabc8

7 files changed

+61
-21
lines changed

compiler/rustc_resolve/src/late/lifetimes.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1652,7 +1652,11 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) {
16521652
}
16531653

16541654
fn expression_label(ex: &hir::Expr<'_>) -> Option<Ident> {
1655-
if let hir::ExprKind::Loop(_, Some(label), ..) = ex.kind { Some(label.ident) } else { None }
1655+
match ex.kind {
1656+
hir::ExprKind::Loop(_, Some(label), ..) => Some(label.ident),
1657+
hir::ExprKind::Block(_, Some(label)) => Some(label.ident),
1658+
_ => None,
1659+
}
16561660
}
16571661

16581662
fn check_if_label_shadows_lifetime(tcx: TyCtxt<'_>, mut scope: ScopeRef<'_>, label: Ident) {

src/test/ui/loops/loops-reject-duplicate-labels-2.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// check-pass
2+
#![feature(label_break_value)]
23

3-
4-
// Issue #21633: reject duplicate loop labels in function bodies.
4+
// Issue #21633: reject duplicate loop labels and block labels in function bodies.
55
//
66
// This is testing the generalization (to the whole function body)
77
// discussed here:
@@ -26,6 +26,8 @@ pub fn foo() {
2626
{ 'lt: loop { break; } }
2727
{ 'lt: while let Some(_) = None::<i32> { break; } }
2828
//~^ WARN label name `'lt` shadows a label name that is already in scope
29+
{ 'bl: {} }
30+
{ 'bl: {} } //~ WARN label name `'bl` shadows a label name that is already in scope
2931
}
3032

3133

src/test/ui/loops/loops-reject-duplicate-labels-2.stderr

+9-1
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,13 @@ LL | { 'lt: loop { break; } }
6262
LL | { 'lt: while let Some(_) = None::<i32> { break; } }
6363
| ^^^ label `'lt` already in scope
6464

65-
warning: 8 warnings emitted
65+
warning: label name `'bl` shadows a label name that is already in scope
66+
--> $DIR/loops-reject-duplicate-labels-2.rs:30:7
67+
|
68+
LL | { 'bl: {} }
69+
| --- first declared here
70+
LL | { 'bl: {} }
71+
| ^^^ label `'bl` already in scope
72+
73+
warning: 9 warnings emitted
6674

src/test/ui/loops/loops-reject-duplicate-labels.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
// check-pass
2+
#![feature(label_break_value)]
23

3-
4-
// Issue #21633: reject duplicate loop labels in function bodies.
5-
// This is testing the exact cases that are in the issue description.
4+
// Issue #21633: reject duplicate loop labels and block labels in function bodies.
65

76
#[allow(unused_labels)]
87
fn foo() {
@@ -24,6 +23,8 @@ fn foo() {
2423
'lt: loop { break; }
2524
'lt: while let Some(_) = None::<i32> { break; }
2625
//~^ WARN label name `'lt` shadows a label name that is already in scope
26+
'bl: {}
27+
'bl: {} //~ WARN label name `'bl` shadows a label name that is already in scope
2728
}
2829

2930
// Note however that it is okay for the same label to be reused in
@@ -33,12 +34,16 @@ struct S;
3334
impl S {
3435
fn m1(&self) { 'okay: loop { break 'okay; } }
3536
fn m2(&self) { 'okay: loop { break 'okay; } }
37+
fn m3(&self) { 'okay: { break 'okay; } }
38+
fn m4(&self) { 'okay: { break 'okay; } }
3639
}
3740

3841

3942
pub fn main() {
4043
let s = S;
4144
s.m1();
4245
s.m2();
46+
s.m3();
47+
s.m4();
4348
foo();
4449
}
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,74 @@
11
warning: label name `'fl` shadows a label name that is already in scope
2-
--> $DIR/loops-reject-duplicate-labels.rs:10:5
2+
--> $DIR/loops-reject-duplicate-labels.rs:9:5
33
|
44
LL | 'fl: for _ in 0..10 { break; }
55
| --- first declared here
66
LL | 'fl: loop { break; }
77
| ^^^ label `'fl` already in scope
88

99
warning: label name `'lf` shadows a label name that is already in scope
10-
--> $DIR/loops-reject-duplicate-labels.rs:13:5
10+
--> $DIR/loops-reject-duplicate-labels.rs:12:5
1111
|
1212
LL | 'lf: loop { break; }
1313
| --- first declared here
1414
LL | 'lf: for _ in 0..10 { break; }
1515
| ^^^ label `'lf` already in scope
1616

1717
warning: label name `'wl` shadows a label name that is already in scope
18-
--> $DIR/loops-reject-duplicate-labels.rs:15:5
18+
--> $DIR/loops-reject-duplicate-labels.rs:14:5
1919
|
2020
LL | 'wl: while 2 > 1 { break; }
2121
| --- first declared here
2222
LL | 'wl: loop { break; }
2323
| ^^^ label `'wl` already in scope
2424

2525
warning: label name `'lw` shadows a label name that is already in scope
26-
--> $DIR/loops-reject-duplicate-labels.rs:17:5
26+
--> $DIR/loops-reject-duplicate-labels.rs:16:5
2727
|
2828
LL | 'lw: loop { break; }
2929
| --- first declared here
3030
LL | 'lw: while 2 > 1 { break; }
3131
| ^^^ label `'lw` already in scope
3232

3333
warning: label name `'fw` shadows a label name that is already in scope
34-
--> $DIR/loops-reject-duplicate-labels.rs:19:5
34+
--> $DIR/loops-reject-duplicate-labels.rs:18:5
3535
|
3636
LL | 'fw: for _ in 0..10 { break; }
3737
| --- first declared here
3838
LL | 'fw: while 2 > 1 { break; }
3939
| ^^^ label `'fw` already in scope
4040

4141
warning: label name `'wf` shadows a label name that is already in scope
42-
--> $DIR/loops-reject-duplicate-labels.rs:21:5
42+
--> $DIR/loops-reject-duplicate-labels.rs:20:5
4343
|
4444
LL | 'wf: while 2 > 1 { break; }
4545
| --- first declared here
4646
LL | 'wf: for _ in 0..10 { break; }
4747
| ^^^ label `'wf` already in scope
4848

4949
warning: label name `'tl` shadows a label name that is already in scope
50-
--> $DIR/loops-reject-duplicate-labels.rs:23:5
50+
--> $DIR/loops-reject-duplicate-labels.rs:22:5
5151
|
5252
LL | 'tl: while let Some(_) = None::<i32> { break; }
5353
| --- first declared here
5454
LL | 'tl: loop { break; }
5555
| ^^^ label `'tl` already in scope
5656

5757
warning: label name `'lt` shadows a label name that is already in scope
58-
--> $DIR/loops-reject-duplicate-labels.rs:25:5
58+
--> $DIR/loops-reject-duplicate-labels.rs:24:5
5959
|
6060
LL | 'lt: loop { break; }
6161
| --- first declared here
6262
LL | 'lt: while let Some(_) = None::<i32> { break; }
6363
| ^^^ label `'lt` already in scope
6464

65-
warning: 8 warnings emitted
65+
warning: label name `'bl` shadows a label name that is already in scope
66+
--> $DIR/loops-reject-duplicate-labels.rs:27:5
67+
|
68+
LL | 'bl: {}
69+
| --- first declared here
70+
LL | 'bl: {}
71+
| ^^^ label `'bl` already in scope
72+
73+
warning: 9 warnings emitted
6674

src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// check-pass
2-
2+
#![feature(label_break_value)]
33
#![allow(dead_code, unused_variables)]
44

5-
// Issue #21633: reject duplicate loop labels in function bodies.
5+
// Issue #21633: reject duplicate loop labels and block labels in function bodies.
66
//
7-
// Test rejection of lifetimes in *expressions* that shadow loop labels.
7+
// Test rejection of lifetimes in *expressions* that shadow labels.
88

99
fn foo() {
1010
// Reusing lifetime `'a` in function item is okay.
@@ -23,8 +23,13 @@ fn foo() {
2323
assert_eq!((*b)(&z), z);
2424
break 'a;
2525
}
26-
}
2726

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

2934
pub fn main() {
3035
foo();

src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr

+9-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,13 @@ LL | 'a: loop {
66
LL | let b = Box::new(|x: &i8| *x) as Box<dyn for <'a> Fn(&'a i8) -> i8>;
77
| ^^ label `'a` already in scope
88

9-
warning: 1 warning emitted
9+
warning: lifetime name `'b` shadows a label name that is already in scope
10+
--> $DIR/loops-reject-lifetime-shadowing-label.rs:28:55
11+
|
12+
LL | 'b: {
13+
| -- first declared here
14+
LL | let b = Box::new(|x: &()| ()) as Box<dyn for <'b> Fn(&'b ())>;
15+
| ^^ label `'b` already in scope
16+
17+
warning: 2 warnings emitted
1018

0 commit comments

Comments
 (0)