Skip to content

Commit 096f296

Browse files
committed
Tests for shadowing between lifetimes and loop labels within function bodies.
1 parent 483d210 commit 096f296

4 files changed

+231
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Issue #21633: reject duplicate loop labels in function bodies.
12+
//
13+
// This is testing the generalization (to the whole function body)
14+
// discussed here:
15+
// http://internals.rust-lang.org/t/psa-rejecting-duplicate-loop-labels/1833
16+
17+
fn main() {
18+
{ 'fl: for _ in 0..10 { break; } } //~ NOTE shadowed label `'fl` declared here
19+
{ 'fl: loop { break; } } //~ ERROR label name `'fl` shadows a label name that is already in scope
20+
21+
{ 'lf: loop { break; } } //~ NOTE shadowed label `'lf` declared here
22+
{ 'lf: for _ in 0..10 { break; } } //~ ERROR label name `'lf` shadows a label name that is already in scope
23+
24+
{ 'wl: while 2 > 1 { break; } } //~ NOTE shadowed label `'wl` declared here
25+
{ 'wl: loop { break; } } //~ ERROR label name `'wl` shadows a label name that is already in scope
26+
27+
{ 'lw: loop { break; } } //~ NOTE shadowed label `'lw` declared here
28+
{ 'lw: while 2 > 1 { break; } } //~ ERROR label name `'lw` shadows a label name that is already in scope
29+
30+
{ 'fw: for _ in 0..10 { break; } } //~ NOTE shadowed label `'fw` declared here
31+
{ 'fw: while 2 > 1 { break; } } //~ ERROR label name `'fw` shadows a label name that is already in scope
32+
33+
{ 'wf: while 2 > 1 { break; } } //~ NOTE shadowed label `'wf` declared here
34+
{ 'wf: for _ in 0..10 { break; } } //~ ERROR label name `'wf` shadows a label name that is already in scope
35+
36+
{ 'tl: while let Some(_) = None::<i32> { break; } } //~ NOTE shadowed label `'tl` declared here
37+
{ 'tl: loop { break; } } //~ ERROR label name `'tl` shadows a label name that is already in scope
38+
39+
{ 'lt: loop { break; } } //~ NOTE shadowed label `'lt` declared here
40+
{ 'lt: while let Some(_) = None::<i32> { break; } }
41+
//~^ ERROR label name `'lt` shadows a label name that is already in scope
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Issue #21633: reject duplicate loop labels in function bodies.
12+
// This is testing the exact cases that are in the issue description.
13+
14+
fn main() {
15+
'fl: for _ in 0..10 { break; } //~ NOTE shadowed label `'fl` declared here
16+
'fl: loop { break; } //~ ERROR label name `'fl` shadows a label name that is already in scope
17+
18+
'lf: loop { break; } //~ NOTE shadowed label `'lf` declared here
19+
'lf: for _ in 0..10 { break; } //~ ERROR label name `'lf` shadows a label name that is already in scope
20+
21+
'wl: while 2 > 1 { break; } //~ NOTE shadowed label `'wl` declared here
22+
'wl: loop { break; } //~ ERROR label name `'wl` shadows a label name that is already in scope
23+
24+
'lw: loop { break; } //~ NOTE shadowed label `'lw` declared here
25+
'lw: while 2 > 1 { break; } //~ ERROR label name `'lw` shadows a label name that is already in scope
26+
27+
'fw: for _ in 0..10 { break; } //~ NOTE shadowed label `'fw` declared here
28+
'fw: while 2 > 1 { break; } //~ ERROR label name `'fw` shadows a label name that is already in scope
29+
30+
'wf: while 2 > 1 { break; } //~ NOTE shadowed label `'wf` declared here
31+
'wf: for _ in 0..10 { break; } //~ ERROR label name `'wf` shadows a label name that is already in scope
32+
33+
'tl: while let Some(_) = None::<i32> { break; } //~ NOTE shadowed label `'tl` declared here
34+
'tl: loop { break; } //~ ERROR label name `'tl` shadows a label name that is already in scope
35+
36+
'lt: loop { break; } //~ NOTE shadowed label `'lt` declared here
37+
'lt: while let Some(_) = None::<i32> { break; }
38+
//~^ ERROR label name `'lt` shadows a label name that is already in scope
39+
}
40+
41+
// Note however that it is okay for the same label to be reuse in
42+
// different methods of one impl, as illustrated here.
43+
44+
struct S;
45+
impl S {
46+
fn m1(&self) { 'okay: loop { break 'okay; } }
47+
fn m2(&self) { 'okay: loop { break 'okay; } }
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Issue #21633: reject duplicate loop labels in function bodies.
12+
// This is testing interaction between lifetime-params and labels.
13+
14+
fn main() {
15+
fn foo<'a>() { //~ NOTE shadowed lifetime `'a` declared here
16+
'a: loop { break 'a; } //~ ERROR label name `'a` shadows a lifetime name that is already in scope
17+
}
18+
19+
struct Struct<'b, 'c> { _f: &'b i8, _g: &'c i8 }
20+
enum Enum<'d, 'e> { A(&'d i8), B(&'e i8) }
21+
22+
impl<'d, 'e> Struct<'d, 'e> {
23+
fn meth_okay() {
24+
'a: loop { break 'a; }
25+
'b: loop { break 'b; }
26+
'c: loop { break 'c; }
27+
}
28+
}
29+
30+
impl <'d, 'e> Enum<'d, 'e> {
31+
fn meth_okay() {
32+
'a: loop { break 'a; }
33+
'b: loop { break 'b; }
34+
'c: loop { break 'c; }
35+
}
36+
}
37+
38+
impl<'bad, 'c> Struct<'bad, 'c> { //~ NOTE shadowed lifetime `'bad` declared here
39+
fn meth_bad(&self) {
40+
'bad: loop { break 'bad; }
41+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
42+
}
43+
}
44+
45+
impl<'b, 'bad> Struct<'b, 'bad> { //~ NOTE shadowed lifetime `'bad` declared here
46+
fn meth_bad2(&self) {
47+
'bad: loop { break 'bad; }
48+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
49+
}
50+
}
51+
52+
impl<'b, 'c> Struct<'b, 'c> {
53+
fn meth_bad3<'bad>(x: &'bad i8) { //~ NOTE shadowed lifetime `'bad` declared here
54+
'bad: loop { break 'bad; }
55+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
56+
}
57+
58+
fn meth_bad4<'a,'bad>(x: &'a i8, y: &'bad i8) { //~ NOTE shadowed lifetime `'bad` declared here
59+
'bad: loop { break 'bad; }
60+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
61+
}
62+
}
63+
64+
impl <'bad, 'e> Enum<'bad, 'e> { //~ NOTE shadowed lifetime `'bad` declared here
65+
fn meth_bad(&self) {
66+
'bad: loop { break 'bad; }
67+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
68+
}
69+
}
70+
impl <'d, 'bad> Enum<'d, 'bad> { //~ NOTE shadowed lifetime `'bad` declared here
71+
fn meth_bad2(&self) {
72+
'bad: loop { break 'bad; }
73+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
74+
}
75+
}
76+
impl <'d, 'e> Enum<'d, 'e> {
77+
fn meth_bad3<'bad>(x: &'bad i8) { //~ NOTE shadowed lifetime `'bad` declared here
78+
'bad: loop { break 'bad; }
79+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
80+
}
81+
82+
fn meth_bad4<'a,'bad>(x: &'bad i8) { //~ NOTE shadowed lifetime `'bad` declared here
83+
'bad: loop { break 'bad; }
84+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
85+
}
86+
}
87+
88+
trait HasDefaultMethod1<'bad> { //~ NOTE shadowed lifetime `'bad` declared here
89+
fn meth_okay() {
90+
'c: loop { break 'c; }
91+
}
92+
fn meth_bad(&self) {
93+
'bad: loop { break 'bad; }
94+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
95+
}
96+
}
97+
trait HasDefaultMethod2<'a,'bad> { //~ NOTE shadowed lifetime `'bad` declared here
98+
fn meth_bad(&self) {
99+
'bad: loop { break 'bad; }
100+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
101+
}
102+
}
103+
trait HasDefaultMethod3<'a,'b> {
104+
fn meth_bad<'bad>(&self) { //~ NOTE shadowed lifetime `'bad` declared here
105+
'bad: loop { break 'bad; }
106+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
107+
}
108+
}
109+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Issue #21633: reject duplicate loop labels in function bodies.
12+
//
13+
// Test rejection of lifetimes in *expressions* that shadow loop labels.
14+
15+
fn main() {
16+
// Reusing lifetime `'a` in function item is okay.
17+
fn foo<'a>(x: &'a i8) -> i8 { *x }
18+
19+
// So is reusing `'a` in struct item
20+
struct S1<'a> { x: &'a i8 } impl<'a> S1<'a> { fn m(&self) {} }
21+
// and a method item
22+
struct S2; impl S2 { fn m<'a>(&self) {} }
23+
24+
let z = 3_i8;
25+
26+
'a: loop { //~ NOTE shadowed label `'a` declared here
27+
let b = Box::new(|x: i8| *x) as Box<for <'a> Fn(&'a i8)>;
28+
//~^ ERROR lifetime name `'a` shadows a label name that is already in scope
29+
assert_eq!((*b)(&z), z);
30+
break 'a;
31+
}
32+
}

0 commit comments

Comments
 (0)