Skip to content

Commit e6880ab

Browse files
committed
Tests for shadowing between lifetimes and loop labels within function bodies.
1 parent 462f45c commit e6880ab

4 files changed

+237
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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+
// ignore-tidy-linelength
12+
13+
// Issue #21633: reject duplicate loop labels in function bodies.
14+
//
15+
// This is testing the generalization (to the whole function body)
16+
// discussed here:
17+
// http://internals.rust-lang.org/t/psa-rejecting-duplicate-loop-labels/1833
18+
19+
fn main() {
20+
{ 'fl: for _ in 0..10 { break; } } //~ NOTE shadowed label `'fl` declared here
21+
{ 'fl: loop { break; } } //~ ERROR label name `'fl` shadows a label name that is already in scope
22+
23+
{ 'lf: loop { break; } } //~ NOTE shadowed label `'lf` declared here
24+
{ 'lf: for _ in 0..10 { break; } } //~ ERROR label name `'lf` shadows a label name that is already in scope
25+
26+
{ 'wl: while 2 > 1 { break; } } //~ NOTE shadowed label `'wl` declared here
27+
{ 'wl: loop { break; } } //~ ERROR label name `'wl` shadows a label name that is already in scope
28+
29+
{ 'lw: loop { break; } } //~ NOTE shadowed label `'lw` declared here
30+
{ 'lw: while 2 > 1 { break; } } //~ ERROR label name `'lw` shadows a label name that is already in scope
31+
32+
{ 'fw: for _ in 0..10 { break; } } //~ NOTE shadowed label `'fw` declared here
33+
{ 'fw: while 2 > 1 { break; } } //~ ERROR label name `'fw` shadows a label name that is already in scope
34+
35+
{ 'wf: while 2 > 1 { break; } } //~ NOTE shadowed label `'wf` declared here
36+
{ 'wf: for _ in 0..10 { break; } } //~ ERROR label name `'wf` shadows a label name that is already in scope
37+
38+
{ 'tl: while let Some(_) = None::<i32> { break; } } //~ NOTE shadowed label `'tl` declared here
39+
{ 'tl: loop { break; } } //~ ERROR label name `'tl` shadows a label name that is already in scope
40+
41+
{ 'lt: loop { break; } } //~ NOTE shadowed label `'lt` declared here
42+
{ 'lt: while let Some(_) = None::<i32> { break; } }
43+
//~^ ERROR label name `'lt` shadows a label name that is already in scope
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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+
// ignore-tidy-linelength
12+
13+
// Issue #21633: reject duplicate loop labels in function bodies.
14+
// This is testing the exact cases that are in the issue description.
15+
16+
fn main() {
17+
'fl: for _ in 0..10 { break; } //~ NOTE shadowed label `'fl` declared here
18+
'fl: loop { break; } //~ ERROR label name `'fl` shadows a label name that is already in scope
19+
20+
'lf: loop { break; } //~ NOTE shadowed label `'lf` declared here
21+
'lf: for _ in 0..10 { break; } //~ ERROR label name `'lf` shadows a label name that is already in scope
22+
23+
'wl: while 2 > 1 { break; } //~ NOTE shadowed label `'wl` declared here
24+
'wl: loop { break; } //~ ERROR label name `'wl` shadows a label name that is already in scope
25+
26+
'lw: loop { break; } //~ NOTE shadowed label `'lw` declared here
27+
'lw: while 2 > 1 { break; } //~ ERROR label name `'lw` shadows a label name that is already in scope
28+
29+
'fw: for _ in 0..10 { break; } //~ NOTE shadowed label `'fw` declared here
30+
'fw: while 2 > 1 { break; } //~ ERROR label name `'fw` shadows a label name that is already in scope
31+
32+
'wf: while 2 > 1 { break; } //~ NOTE shadowed label `'wf` declared here
33+
'wf: for _ in 0..10 { break; } //~ ERROR label name `'wf` shadows a label name that is already in scope
34+
35+
'tl: while let Some(_) = None::<i32> { break; } //~ NOTE shadowed label `'tl` declared here
36+
'tl: loop { break; } //~ ERROR label name `'tl` shadows a label name that is already in scope
37+
38+
'lt: loop { break; } //~ NOTE shadowed label `'lt` declared here
39+
'lt: while let Some(_) = None::<i32> { break; }
40+
//~^ ERROR label name `'lt` shadows a label name that is already in scope
41+
}
42+
43+
// Note however that it is okay for the same label to be reuse in
44+
// different methods of one impl, as illustrated here.
45+
46+
struct S;
47+
impl S {
48+
fn m1(&self) { 'okay: loop { break 'okay; } }
49+
fn m2(&self) { 'okay: loop { break 'okay; } }
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
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; }
17+
//~^ ERROR label name `'a` shadows a lifetime name that is already in scope
18+
}
19+
20+
struct Struct<'b, 'c> { _f: &'b i8, _g: &'c i8 }
21+
enum Enum<'d, 'e> { A(&'d i8), B(&'e i8) }
22+
23+
impl<'d, 'e> Struct<'d, 'e> {
24+
fn meth_okay() {
25+
'a: loop { break 'a; }
26+
'b: loop { break 'b; }
27+
'c: loop { break 'c; }
28+
}
29+
}
30+
31+
impl <'d, 'e> Enum<'d, 'e> {
32+
fn meth_okay() {
33+
'a: loop { break 'a; }
34+
'b: loop { break 'b; }
35+
'c: loop { break 'c; }
36+
}
37+
}
38+
39+
impl<'bad, 'c> Struct<'bad, 'c> { //~ NOTE shadowed lifetime `'bad` declared here
40+
fn meth_bad(&self) {
41+
'bad: loop { break 'bad; }
42+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
43+
}
44+
}
45+
46+
impl<'b, 'bad> Struct<'b, 'bad> { //~ NOTE shadowed lifetime `'bad` declared here
47+
fn meth_bad2(&self) {
48+
'bad: loop { break 'bad; }
49+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
50+
}
51+
}
52+
53+
impl<'b, 'c> Struct<'b, 'c> {
54+
fn meth_bad3<'bad>(x: &'bad i8) { //~ NOTE shadowed lifetime `'bad` declared here
55+
'bad: loop { break 'bad; }
56+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
57+
}
58+
59+
fn meth_bad4<'a,'bad>(x: &'a i8, y: &'bad i8) {
60+
//~^ NOTE shadowed lifetime `'bad` declared here
61+
'bad: loop { break 'bad; }
62+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
63+
}
64+
}
65+
66+
impl <'bad, 'e> Enum<'bad, 'e> { //~ NOTE shadowed lifetime `'bad` declared here
67+
fn meth_bad(&self) {
68+
'bad: loop { break 'bad; }
69+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
70+
}
71+
}
72+
impl <'d, 'bad> Enum<'d, 'bad> { //~ NOTE shadowed lifetime `'bad` declared here
73+
fn meth_bad2(&self) {
74+
'bad: loop { break 'bad; }
75+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
76+
}
77+
}
78+
impl <'d, 'e> Enum<'d, 'e> {
79+
fn meth_bad3<'bad>(x: &'bad i8) { //~ NOTE shadowed lifetime `'bad` declared here
80+
'bad: loop { break 'bad; }
81+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
82+
}
83+
84+
fn meth_bad4<'a,'bad>(x: &'bad i8) { //~ NOTE shadowed lifetime `'bad` declared here
85+
'bad: loop { break 'bad; }
86+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
87+
}
88+
}
89+
90+
trait HasDefaultMethod1<'bad> { //~ NOTE shadowed lifetime `'bad` declared here
91+
fn meth_okay() {
92+
'c: loop { break 'c; }
93+
}
94+
fn meth_bad(&self) {
95+
'bad: loop { break 'bad; }
96+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
97+
}
98+
}
99+
trait HasDefaultMethod2<'a,'bad> { //~ NOTE shadowed lifetime `'bad` declared here
100+
fn meth_bad(&self) {
101+
'bad: loop { break 'bad; }
102+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
103+
}
104+
}
105+
trait HasDefaultMethod3<'a,'b> {
106+
fn meth_bad<'bad>(&self) { //~ NOTE shadowed lifetime `'bad` declared here
107+
'bad: loop { break 'bad; }
108+
//~^ ERROR label name `'bad` shadows a lifetime name that is already in scope
109+
}
110+
}
111+
}
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)