Skip to content

Commit aafed03

Browse files
committed
Tests for shadowing between lifetimes and loop labels within function bodies.
1 parent fb6aae6 commit aafed03

6 files changed

+275
-3
lines changed

src/test/compile-fail/loop-labeled-break-value.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ fn main() {
1616
let _: i32 = 'inner: loop { break 'inner }; //~ ERROR mismatched types
1717
}
1818
loop {
19-
let _: i32 = 'inner: loop { loop { break 'inner } }; //~ ERROR mismatched types
19+
let _: i32 = 'inner2: loop { loop { break 'inner2 } }; //~ ERROR mismatched types
2020
}
2121
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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+
#![feature(rustc_attrs)]
12+
13+
// ignore-tidy-linelength
14+
15+
// Issue #21633: reject duplicate loop labels in function bodies.
16+
//
17+
// This is testing the generalization (to the whole function body)
18+
// discussed here:
19+
// http://internals.rust-lang.org/t/psa-rejecting-duplicate-loop-labels/1833
20+
21+
pub fn foo() {
22+
{ 'fl: for _ in 0..10 { break; } } //~ NOTE shadowed label `'fl` declared here
23+
{ 'fl: loop { break; } } //~ WARN label name `'fl` shadows a label name that is already in scope
24+
25+
{ 'lf: loop { break; } } //~ NOTE shadowed label `'lf` declared here
26+
{ 'lf: for _ in 0..10 { break; } } //~ WARN label name `'lf` shadows a label name that is already in scope
27+
28+
{ 'wl: while 2 > 1 { break; } } //~ NOTE shadowed label `'wl` declared here
29+
{ 'wl: loop { break; } } //~ WARN label name `'wl` shadows a label name that is already in scope
30+
31+
{ 'lw: loop { break; } } //~ NOTE shadowed label `'lw` declared here
32+
{ 'lw: while 2 > 1 { break; } } //~ WARN label name `'lw` shadows a label name that is already in scope
33+
34+
{ 'fw: for _ in 0..10 { break; } } //~ NOTE shadowed label `'fw` declared here
35+
{ 'fw: while 2 > 1 { break; } } //~ WARN label name `'fw` shadows a label name that is already in scope
36+
37+
{ 'wf: while 2 > 1 { break; } } //~ NOTE shadowed label `'wf` declared here
38+
{ 'wf: for _ in 0..10 { break; } } //~ WARN label name `'wf` shadows a label name that is already in scope
39+
40+
{ 'tl: while let Some(_) = None::<i32> { break; } } //~ NOTE shadowed label `'tl` declared here
41+
{ 'tl: loop { break; } } //~ WARN label name `'tl` shadows a label name that is already in scope
42+
43+
{ 'lt: loop { break; } } //~ NOTE shadowed label `'lt` declared here
44+
{ 'lt: while let Some(_) = None::<i32> { break; } }
45+
//~^ WARN label name `'lt` shadows a label name that is already in scope
46+
}
47+
48+
#[rustc_error]
49+
pub fn main() { //~ ERROR compilation successful
50+
foo();
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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+
#![feature(rustc_attrs)]
12+
13+
// ignore-tidy-linelength
14+
15+
// Issue #21633: reject duplicate loop labels in function bodies.
16+
// This is testing the exact cases that are in the issue description.
17+
18+
fn foo() {
19+
'fl: for _ in 0..10 { break; } //~ NOTE shadowed label `'fl` declared here
20+
'fl: loop { break; } //~ WARN label name `'fl` shadows a label name that is already in scope
21+
22+
'lf: loop { break; } //~ NOTE shadowed label `'lf` declared here
23+
'lf: for _ in 0..10 { break; } //~ WARN label name `'lf` shadows a label name that is already in scope
24+
25+
'wl: while 2 > 1 { break; } //~ NOTE shadowed label `'wl` declared here
26+
'wl: loop { break; } //~ WARN label name `'wl` shadows a label name that is already in scope
27+
28+
'lw: loop { break; } //~ NOTE shadowed label `'lw` declared here
29+
'lw: while 2 > 1 { break; } //~ WARN label name `'lw` shadows a label name that is already in scope
30+
31+
'fw: for _ in 0..10 { break; } //~ NOTE shadowed label `'fw` declared here
32+
'fw: while 2 > 1 { break; } //~ WARN label name `'fw` shadows a label name that is already in scope
33+
34+
'wf: while 2 > 1 { break; } //~ NOTE shadowed label `'wf` declared here
35+
'wf: for _ in 0..10 { break; } //~ WARN label name `'wf` shadows a label name that is already in scope
36+
37+
'tl: while let Some(_) = None::<i32> { break; } //~ NOTE shadowed label `'tl` declared here
38+
'tl: loop { break; } //~ WARN label name `'tl` shadows a label name that is already in scope
39+
40+
'lt: loop { break; } //~ NOTE shadowed label `'lt` declared here
41+
'lt: while let Some(_) = None::<i32> { break; }
42+
//~^ WARN label name `'lt` shadows a label name that is already in scope
43+
}
44+
45+
// Note however that it is okay for the same label to be reused in
46+
// different methods of one impl, as illustrated here.
47+
48+
struct S;
49+
impl S {
50+
fn m1(&self) { 'okay: loop { break 'okay; } }
51+
fn m2(&self) { 'okay: loop { break 'okay; } }
52+
}
53+
54+
#[rustc_error]
55+
pub fn main() { //~ ERROR compilation successful
56+
let s = S;
57+
s.m1();
58+
s.m2();
59+
foo();
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
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+
#![feature(rustc_attrs)]
15+
16+
#![allow(dead_code, unused_variables)]
17+
18+
fn foo() {
19+
fn foo<'a>() { //~ NOTE shadowed lifetime `'a` declared here
20+
'a: loop { break 'a; }
21+
//~^ WARN label name `'a` shadows a lifetime name that is already in scope
22+
}
23+
24+
struct Struct<'b, 'c> { _f: &'b i8, _g: &'c i8 }
25+
enum Enum<'d, 'e> { A(&'d i8), B(&'e i8) }
26+
27+
impl<'d, 'e> Struct<'d, 'e> {
28+
fn meth_okay() {
29+
'a: loop { break 'a; }
30+
'b: loop { break 'b; }
31+
'c: loop { break 'c; }
32+
}
33+
}
34+
35+
impl <'d, 'e> Enum<'d, 'e> {
36+
fn meth_okay() {
37+
'a: loop { break 'a; }
38+
'b: loop { break 'b; }
39+
'c: loop { break 'c; }
40+
}
41+
}
42+
43+
impl<'bad, 'c> Struct<'bad, 'c> { //~ NOTE shadowed lifetime `'bad` declared here
44+
fn meth_bad(&self) {
45+
'bad: loop { break 'bad; }
46+
//~^ WARN label name `'bad` shadows a lifetime name that is already in scope
47+
}
48+
}
49+
50+
impl<'b, 'bad> Struct<'b, 'bad> { //~ NOTE shadowed lifetime `'bad` declared here
51+
fn meth_bad2(&self) {
52+
'bad: loop { break 'bad; }
53+
//~^ WARN label name `'bad` shadows a lifetime name that is already in scope
54+
}
55+
}
56+
57+
impl<'b, 'c> Struct<'b, 'c> {
58+
fn meth_bad3<'bad>(x: &'bad i8) { //~ NOTE shadowed lifetime `'bad` declared here
59+
'bad: loop { break 'bad; }
60+
//~^ WARN label name `'bad` shadows a lifetime name that is already in scope
61+
}
62+
63+
fn meth_bad4<'a,'bad>(x: &'a i8, y: &'bad i8) {
64+
//~^ NOTE shadowed lifetime `'bad` declared here
65+
'bad: loop { break 'bad; }
66+
//~^ WARN label name `'bad` shadows a lifetime name that is already in scope
67+
}
68+
}
69+
70+
impl <'bad, 'e> Enum<'bad, 'e> { //~ NOTE shadowed lifetime `'bad` declared here
71+
fn meth_bad(&self) {
72+
'bad: loop { break 'bad; }
73+
//~^ WARN label name `'bad` shadows a lifetime name that is already in scope
74+
}
75+
}
76+
impl <'d, 'bad> Enum<'d, 'bad> { //~ NOTE shadowed lifetime `'bad` declared here
77+
fn meth_bad2(&self) {
78+
'bad: loop { break 'bad; }
79+
//~^ WARN label name `'bad` shadows a lifetime name that is already in scope
80+
}
81+
}
82+
impl <'d, 'e> Enum<'d, 'e> {
83+
fn meth_bad3<'bad>(x: &'bad i8) { //~ NOTE shadowed lifetime `'bad` declared here
84+
'bad: loop { break 'bad; }
85+
//~^ WARN label name `'bad` shadows a lifetime name that is already in scope
86+
}
87+
88+
fn meth_bad4<'a,'bad>(x: &'bad i8) { //~ NOTE shadowed lifetime `'bad` declared here
89+
'bad: loop { break 'bad; }
90+
//~^ WARN label name `'bad` shadows a lifetime name that is already in scope
91+
}
92+
}
93+
94+
trait HasDefaultMethod1<'bad> { //~ NOTE shadowed lifetime `'bad` declared here
95+
fn meth_okay() {
96+
'c: loop { break 'c; }
97+
}
98+
fn meth_bad(&self) {
99+
'bad: loop { break 'bad; }
100+
//~^ WARN label name `'bad` shadows a lifetime name that is already in scope
101+
}
102+
}
103+
trait HasDefaultMethod2<'a,'bad> { //~ NOTE shadowed lifetime `'bad` declared here
104+
fn meth_bad(&self) {
105+
'bad: loop { break 'bad; }
106+
//~^ WARN label name `'bad` shadows a lifetime name that is already in scope
107+
}
108+
}
109+
trait HasDefaultMethod3<'a,'b> {
110+
fn meth_bad<'bad>(&self) { //~ NOTE shadowed lifetime `'bad` declared here
111+
'bad: loop { break 'bad; }
112+
//~^ WARN label name `'bad` shadows a lifetime name that is already in scope
113+
}
114+
}
115+
}
116+
117+
#[rustc_error]
118+
pub fn main() { //~ ERROR compilation successful
119+
foo();
120+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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+
#![feature(rustc_attrs)]
12+
13+
#![allow(dead_code, unused_variables)]
14+
15+
// Issue #21633: reject duplicate loop labels in function bodies.
16+
//
17+
// Test rejection of lifetimes in *expressions* that shadow loop labels.
18+
19+
fn foo() {
20+
// Reusing lifetime `'a` in function item is okay.
21+
fn foo<'a>(x: &'a i8) -> i8 { *x }
22+
23+
// So is reusing `'a` in struct item
24+
struct S1<'a> { x: &'a i8 } impl<'a> S1<'a> { fn m(&self) {} }
25+
// and a method item
26+
struct S2; impl S2 { fn m<'a>(&self) {} }
27+
28+
let z = 3_i8;
29+
30+
'a: loop { //~ NOTE shadowed label `'a` declared here
31+
let b = Box::new(|x: &i8| *x) as Box<for <'a> Fn(&'a i8) -> i8>;
32+
//~^ WARN lifetime name `'a` shadows a label name that is already in scope
33+
assert_eq!((*b)(&z), z);
34+
break 'a;
35+
}
36+
}
37+
38+
#[rustc_error]
39+
pub fn main() { //~ ERROR compilation successful
40+
foo();
41+
}

src/test/compile-fail/shadowed-lifetime.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ struct Foo<'a>(&'a isize);
1515
impl<'a> Foo<'a> {
1616
//~^ NOTE shadowed lifetime `'a` declared here
1717
fn shadow_in_method<'a>(&'a self) -> &'a isize {
18-
//~^ ERROR lifetime name `'a` shadows another lifetime name that is already in scope
18+
//~^ ERROR lifetime name `'a` shadows a lifetime name that is already in scope
1919
self.0
2020
}
2121

2222
fn shadow_in_type<'b>(&'b self) -> &'b isize {
2323
//~^ NOTE shadowed lifetime `'b` declared here
2424
let x: for<'b> fn(&'b isize) = panic!();
25-
//~^ ERROR lifetime name `'b` shadows another lifetime name that is already in scope
25+
//~^ ERROR lifetime name `'b` shadows a lifetime name that is already in scope
2626
self.0
2727
}
2828

0 commit comments

Comments
 (0)