Move /src/test to /tests
This commit is contained in:
parent
ca855e6e42
commit
cf2dff2b1e
27592 changed files with 0 additions and 0 deletions
10
tests/ui/for-loop-while/auto-loop.rs
Normal file
10
tests/ui/for-loop-while/auto-loop.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
// run-pass
|
||||
|
||||
pub fn main() {
|
||||
let mut sum = 0;
|
||||
let xs = vec![1, 2, 3, 4, 5];
|
||||
for x in &xs {
|
||||
sum += *x;
|
||||
}
|
||||
assert_eq!(sum, 15);
|
||||
}
|
35
tests/ui/for-loop-while/break-outside-loop.rs
Normal file
35
tests/ui/for-loop-while/break-outside-loop.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
struct Foo {
|
||||
t: String
|
||||
}
|
||||
|
||||
fn cond() -> bool { true }
|
||||
|
||||
fn foo<F>(_: F) where F: FnOnce() {}
|
||||
|
||||
fn main() {
|
||||
let pth = break; //~ ERROR: `break` outside of a loop
|
||||
if cond() { continue } //~ ERROR: `continue` outside of a loop
|
||||
|
||||
while cond() {
|
||||
if cond() { break }
|
||||
if cond() { continue }
|
||||
foo(|| {
|
||||
if cond() { break } //~ ERROR: `break` inside of a closure
|
||||
if cond() { continue } //~ ERROR: `continue` inside of a closure
|
||||
})
|
||||
}
|
||||
|
||||
let rs: Foo = Foo{t: pth};
|
||||
|
||||
let unconstrained = break; //~ ERROR: `break` outside of a loop
|
||||
|
||||
// This used to ICE because `target_id` passed to `check_expr_break` would be the closure and
|
||||
// not the `loop`, which failed in the call to `find_breakable`. (#65383)
|
||||
'lab: loop {
|
||||
|| {
|
||||
break 'lab;
|
||||
//~^ ERROR use of unreachable label `'lab`
|
||||
//~| ERROR `break` inside of a closure
|
||||
};
|
||||
}
|
||||
}
|
58
tests/ui/for-loop-while/break-outside-loop.stderr
Normal file
58
tests/ui/for-loop-while/break-outside-loop.stderr
Normal file
|
@ -0,0 +1,58 @@
|
|||
error[E0767]: use of unreachable label `'lab`
|
||||
--> $DIR/break-outside-loop.rs:30:19
|
||||
|
|
||||
LL | 'lab: loop {
|
||||
| ---- unreachable label defined here
|
||||
LL | || {
|
||||
LL | break 'lab;
|
||||
| ^^^^ unreachable label `'lab`
|
||||
|
|
||||
= note: labels are unreachable through functions, closures, async blocks and modules
|
||||
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/break-outside-loop.rs:10:15
|
||||
|
|
||||
LL | let pth = break;
|
||||
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
||||
error[E0268]: `continue` outside of a loop
|
||||
--> $DIR/break-outside-loop.rs:11:17
|
||||
|
|
||||
LL | if cond() { continue }
|
||||
| ^^^^^^^^ cannot `continue` outside of a loop
|
||||
|
||||
error[E0267]: `break` inside of a closure
|
||||
--> $DIR/break-outside-loop.rs:17:25
|
||||
|
|
||||
LL | foo(|| {
|
||||
| -- enclosing closure
|
||||
LL | if cond() { break }
|
||||
| ^^^^^ cannot `break` inside of a closure
|
||||
|
||||
error[E0267]: `continue` inside of a closure
|
||||
--> $DIR/break-outside-loop.rs:18:25
|
||||
|
|
||||
LL | foo(|| {
|
||||
| -- enclosing closure
|
||||
LL | if cond() { break }
|
||||
LL | if cond() { continue }
|
||||
| ^^^^^^^^ cannot `continue` inside of a closure
|
||||
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/break-outside-loop.rs:24:25
|
||||
|
|
||||
LL | let unconstrained = break;
|
||||
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
||||
error[E0267]: `break` inside of a closure
|
||||
--> $DIR/break-outside-loop.rs:30:13
|
||||
|
|
||||
LL | || {
|
||||
| -- enclosing closure
|
||||
LL | break 'lab;
|
||||
| ^^^^^^^^^^ cannot `break` inside of a closure
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0267, E0268, E0767.
|
||||
For more information about an error, try `rustc --explain E0267`.
|
7
tests/ui/for-loop-while/break-value.rs
Normal file
7
tests/ui/for-loop-while/break-value.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
// run-pass
|
||||
#![allow(unreachable_code)]
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
fn int_id(x: isize) -> isize { return x; }
|
||||
|
||||
pub fn main() { loop { int_id(break); } }
|
29
tests/ui/for-loop-while/break-while-condition.rs
Normal file
29
tests/ui/for-loop-while/break-while-condition.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
#![feature(never_type)]
|
||||
|
||||
fn main() {
|
||||
// The `if false` expressions are simply to
|
||||
// make sure we don't avoid checking everything
|
||||
// simply because a few expressions are unreachable.
|
||||
|
||||
if false {
|
||||
let _: ! = { //~ ERROR mismatched types
|
||||
'a: while break 'a {};
|
||||
};
|
||||
}
|
||||
|
||||
if false {
|
||||
let _: ! = {
|
||||
while false { //~ ERROR mismatched types
|
||||
break
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if false {
|
||||
let _: ! = {
|
||||
while false { //~ ERROR mismatched types
|
||||
return
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
45
tests/ui/for-loop-while/break-while-condition.stderr
Normal file
45
tests/ui/for-loop-while/break-while-condition.stderr
Normal file
|
@ -0,0 +1,45 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/break-while-condition.rs:9:20
|
||||
|
|
||||
LL | let _: ! = {
|
||||
| ____________________^
|
||||
LL | | 'a: while break 'a {};
|
||||
LL | | };
|
||||
| |_________^ expected `!`, found `()`
|
||||
|
|
||||
= note: expected type `!`
|
||||
found unit type `()`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/break-while-condition.rs:16:13
|
||||
|
|
||||
LL | / while false {
|
||||
LL | | break
|
||||
LL | | }
|
||||
| |_____________^ expected `!`, found `()`
|
||||
|
|
||||
= note: expected type `!`
|
||||
found unit type `()`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/break-while-condition.rs:24:13
|
||||
|
|
||||
LL | / while false {
|
||||
LL | | return
|
||||
LL | | }
|
||||
| |_____________^ expected `!`, found `()`
|
||||
|
|
||||
= note: expected type `!`
|
||||
found unit type `()`
|
||||
note: the function expects a value to always be returned, but loops might run zero times
|
||||
--> $DIR/break-while-condition.rs:24:13
|
||||
|
|
||||
LL | while false {
|
||||
| ^^^^^^^^^^^ this might have zero elements to iterate on
|
||||
LL | return
|
||||
| ------ if the loop doesn't execute, this value would never get returned
|
||||
= help: return a value for the case when the loop has zero elements to iterate on, or consider changing the return type to account for that possibility
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
25
tests/ui/for-loop-while/break.rs
Normal file
25
tests/ui/for-loop-while/break.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
// run-pass
|
||||
|
||||
pub fn main() {
|
||||
let mut i = 0;
|
||||
while i < 20 { i += 1; if i == 10 { break; } }
|
||||
assert_eq!(i, 10);
|
||||
loop { i += 1; if i == 20 { break; } }
|
||||
assert_eq!(i, 20);
|
||||
let xs = [1, 2, 3, 4, 5, 6];
|
||||
for x in &xs {
|
||||
if *x == 3 { break; } assert!((*x <= 3));
|
||||
}
|
||||
i = 0;
|
||||
while i < 10 { i += 1; if i % 2 == 0 { continue; } assert!((i % 2 != 0)); }
|
||||
i = 0;
|
||||
loop {
|
||||
i += 1; if i % 2 == 0 { continue; } assert!((i % 2 != 0));
|
||||
if i >= 10 { break; }
|
||||
}
|
||||
let ys = vec![1, 2, 3, 4, 5, 6];
|
||||
for x in &ys {
|
||||
if *x % 2 == 0 { continue; }
|
||||
assert!((*x % 2 != 0));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
// run-pass
|
||||
// This test verifies that temporaries created for `while`'s and `if`
|
||||
// conditions are dropped after the condition is evaluated.
|
||||
|
||||
struct Temporary;
|
||||
|
||||
static mut DROPPED: isize = 0;
|
||||
|
||||
impl Drop for Temporary {
|
||||
fn drop(&mut self) {
|
||||
unsafe { DROPPED += 1; }
|
||||
}
|
||||
}
|
||||
|
||||
impl Temporary {
|
||||
fn do_stuff(&self) -> bool {true}
|
||||
}
|
||||
|
||||
fn borrow() -> Box<Temporary> { Box::new(Temporary) }
|
||||
|
||||
|
||||
pub fn main() {
|
||||
let mut i = 0;
|
||||
|
||||
// This loop's condition
|
||||
// should call `Temporary`'s
|
||||
// `drop` 6 times.
|
||||
while borrow().do_stuff() {
|
||||
i += 1;
|
||||
unsafe { assert_eq!(DROPPED, i) }
|
||||
if i > 5 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// This if condition should
|
||||
// call it 1 time
|
||||
if borrow().do_stuff() {
|
||||
unsafe { assert_eq!(DROPPED, i + 1) }
|
||||
}
|
||||
}
|
9
tests/ui/for-loop-while/for-destruct.rs
Normal file
9
tests/ui/for-loop-while/for-destruct.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
// run-pass
|
||||
|
||||
struct Pair { x: isize, y: isize }
|
||||
|
||||
pub fn main() {
|
||||
for elt in &(vec![Pair {x: 10, y: 20}, Pair {x: 30, y: 0}]) {
|
||||
assert_eq!(elt.x + elt.y, 30);
|
||||
}
|
||||
}
|
16
tests/ui/for-loop-while/for-loop-goofiness.rs
Normal file
16
tests/ui/for-loop-while/for-loop-goofiness.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
|
||||
enum BogusOption<T> {
|
||||
None,
|
||||
Some(T),
|
||||
}
|
||||
|
||||
type Iterator = isize;
|
||||
|
||||
pub fn main() {
|
||||
let x = [ 3, 3, 3 ];
|
||||
for i in &x {
|
||||
assert_eq!(*i, 3);
|
||||
}
|
||||
}
|
13
tests/ui/for-loop-while/for-loop-has-unit-body.rs
Normal file
13
tests/ui/for-loop-while/for-loop-has-unit-body.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
// run-pass
|
||||
fn main() {
|
||||
// Check that the tail statement in the body unifies with something
|
||||
for _ in 0..3 {
|
||||
// `()` is fine to zero-initialize as it is zero sized and inhabited.
|
||||
unsafe { std::mem::zeroed() }
|
||||
}
|
||||
|
||||
// Check that the tail statement in the body can be unit
|
||||
for _ in 0..3 {
|
||||
()
|
||||
}
|
||||
}
|
19
tests/ui/for-loop-while/for-loop-into-iterator.rs
Normal file
19
tests/ui/for-loop-while/for-loop-into-iterator.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
// run-pass
|
||||
// Test that for loops can do what RFC #235 claims
|
||||
|
||||
|
||||
fn main() {
|
||||
let mut v = vec![1];
|
||||
|
||||
for x in &v {
|
||||
assert_eq!(x, &1);
|
||||
}
|
||||
|
||||
for x in &mut v {
|
||||
assert_eq!(x, &mut 1);
|
||||
}
|
||||
|
||||
for x in v {
|
||||
assert_eq!(x, 1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
// run-pass
|
||||
// Test when destructors run in a for loop. The intention is
|
||||
// that the value for each iteration is dropped *after* the loop
|
||||
// body has executed. This is true even when the value is assigned
|
||||
// to a `_` pattern (and hence ignored).
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
struct Flag<'a>(&'a Cell<bool>);
|
||||
|
||||
impl<'a> Drop for Flag<'a> {
|
||||
fn drop(&mut self) {
|
||||
self.0.set(false)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let alive2 = Cell::new(true);
|
||||
for _i in std::iter::once(Flag(&alive2)) {
|
||||
// The Flag value should be alive in the for loop body
|
||||
assert_eq!(alive2.get(), true);
|
||||
}
|
||||
// The Flag value should be dead outside of the loop
|
||||
assert_eq!(alive2.get(), false);
|
||||
|
||||
let alive = Cell::new(true);
|
||||
for _ in std::iter::once(Flag(&alive)) {
|
||||
// The Flag value should be alive in the for loop body even if it wasn't
|
||||
// bound by the for loop
|
||||
assert_eq!(alive.get(), true);
|
||||
}
|
||||
// The Flag value should be dead outside of the loop
|
||||
assert_eq!(alive.get(), false);
|
||||
}
|
11
tests/ui/for-loop-while/for-loop-macro.rs
Normal file
11
tests/ui/for-loop-while/for-loop-macro.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// run-pass
|
||||
macro_rules! var {
|
||||
( $name:ident ) => ( $name );
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let x = [ 3, 3, 3 ];
|
||||
for var!(i) in &x {
|
||||
assert_eq!(*i, 3);
|
||||
}
|
||||
}
|
6
tests/ui/for-loop-while/for-loop-mut-ref-element.rs
Normal file
6
tests/ui/for-loop-while/for-loop-mut-ref-element.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
// run-pass
|
||||
// Tests that for loops can bind elements as mutable references
|
||||
|
||||
fn main() {
|
||||
for ref mut _a in std::iter::once(true) {}
|
||||
}
|
14
tests/ui/for-loop-while/for-loop-no-std.rs
Normal file
14
tests/ui/for-loop-while/for-loop-no-std.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
// run-pass
|
||||
#![allow(unused_imports)]
|
||||
#![feature(lang_items, start)]
|
||||
#![no_std]
|
||||
|
||||
extern crate std as other;
|
||||
|
||||
#[macro_use] extern crate alloc;
|
||||
|
||||
#[start]
|
||||
fn start(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
for _ in [1,2,3].iter() { }
|
||||
0
|
||||
}
|
4
tests/ui/for-loop-while/for-loop-panic.rs
Normal file
4
tests/ui/for-loop-while/for-loop-panic.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
// run-pass
|
||||
|
||||
|
||||
pub fn main() { let x: Vec<isize> = Vec::new(); for _ in &x { panic!("moop"); } }
|
|
@ -0,0 +1,11 @@
|
|||
// run-pass
|
||||
// Test that the type of `sum` falls back to `i32` here,
|
||||
// and that the for loop desugaring doesn't interfere with
|
||||
// that.
|
||||
|
||||
fn main() {
|
||||
let mut sum = 0;
|
||||
for i in Vec::new() {
|
||||
sum += &i;
|
||||
}
|
||||
}
|
13
tests/ui/for-loop-while/foreach-external-iterators-break.rs
Normal file
13
tests/ui/for-loop-while/foreach-external-iterators-break.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
// run-pass
|
||||
|
||||
pub fn main() {
|
||||
let x = [1; 100];
|
||||
let mut y = 0;
|
||||
for i in &x[..] {
|
||||
if y > 10 {
|
||||
break;
|
||||
}
|
||||
y += *i;
|
||||
}
|
||||
assert_eq!(y, 11);
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
// run-pass
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
// This is a fancy one: it uses an external iterator established
|
||||
// outside the loop, breaks, then _picks back up_ and continues
|
||||
// iterating with it.
|
||||
|
||||
pub fn main() {
|
||||
let mut h = HashMap::new();
|
||||
let kvs = [(1, 10), (2, 20), (3, 30)];
|
||||
for &(k,v) in &kvs {
|
||||
h.insert(k,v);
|
||||
}
|
||||
let mut x = 0;
|
||||
let mut y = 0;
|
||||
|
||||
let mut i = h.iter();
|
||||
|
||||
for (&k,&v) in i.by_ref() {
|
||||
x += k;
|
||||
y += v;
|
||||
break;
|
||||
}
|
||||
|
||||
for (&k,&v) in i {
|
||||
x += k;
|
||||
y += v;
|
||||
}
|
||||
|
||||
assert_eq!(x, 6);
|
||||
assert_eq!(y, 60);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// run-pass
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub fn main() {
|
||||
let mut h = HashMap::new();
|
||||
let kvs = [(1, 10), (2, 20), (3, 30)];
|
||||
for &(k,v) in &kvs {
|
||||
h.insert(k,v);
|
||||
}
|
||||
let mut x = 0;
|
||||
let mut y = 0;
|
||||
for (&k,&v) in &h {
|
||||
x += k;
|
||||
y += v;
|
||||
}
|
||||
assert_eq!(x, 6);
|
||||
assert_eq!(y, 60);
|
||||
}
|
13
tests/ui/for-loop-while/foreach-external-iterators-loop.rs
Normal file
13
tests/ui/for-loop-while/foreach-external-iterators-loop.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
// run-pass
|
||||
|
||||
pub fn main() {
|
||||
let x = [1; 100];
|
||||
let mut y = 0;
|
||||
for (n,i) in x.iter().enumerate() {
|
||||
if n < 10 {
|
||||
continue;
|
||||
}
|
||||
y += *i;
|
||||
}
|
||||
assert_eq!(y, 90);
|
||||
}
|
15
tests/ui/for-loop-while/foreach-external-iterators-nested.rs
Normal file
15
tests/ui/for-loop-while/foreach-external-iterators-nested.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
// run-pass
|
||||
|
||||
pub fn main() {
|
||||
let x = [1; 100];
|
||||
let y = [2; 100];
|
||||
let mut p = 0;
|
||||
let mut q = 0;
|
||||
for i in &x[..] {
|
||||
for j in &y[..] {
|
||||
p += *j;
|
||||
}
|
||||
q += *i + p;
|
||||
}
|
||||
assert_eq!(q, 1010100);
|
||||
}
|
10
tests/ui/for-loop-while/foreach-external-iterators.rs
Normal file
10
tests/ui/for-loop-while/foreach-external-iterators.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
// run-pass
|
||||
|
||||
pub fn main() {
|
||||
let x = [1; 100];
|
||||
let mut y = 0;
|
||||
for i in &x[..] {
|
||||
y += *i
|
||||
}
|
||||
assert_eq!(y, 100);
|
||||
}
|
16
tests/ui/for-loop-while/foreach-nested.rs
Normal file
16
tests/ui/for-loop-while/foreach-nested.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
// run-pass
|
||||
|
||||
|
||||
fn two<F>(mut it: F) where F: FnMut(isize) { it(0); it(1); }
|
||||
|
||||
pub fn main() {
|
||||
let mut a: Vec<isize> = vec![-1, -1, -1, -1];
|
||||
let mut p: isize = 0;
|
||||
two(|i| {
|
||||
two(|j| { a[p as usize] = 10 * i + j; p += 1; })
|
||||
});
|
||||
assert_eq!(a[0], 0);
|
||||
assert_eq!(a[1], 1);
|
||||
assert_eq!(a[2], 10);
|
||||
assert_eq!(a[3], 11);
|
||||
}
|
22
tests/ui/for-loop-while/foreach-put-structured.rs
Normal file
22
tests/ui/for-loop-while/foreach-put-structured.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
// run-pass
|
||||
|
||||
|
||||
fn pairs<F>(mut it: F) where F: FnMut((isize, isize)) {
|
||||
let mut i: isize = 0;
|
||||
let mut j: isize = 0;
|
||||
while i < 10 { it((i, j)); i += 1; j += i; }
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let mut i: isize = 10;
|
||||
let mut j: isize = 0;
|
||||
pairs(|p| {
|
||||
let (_0, _1) = p;
|
||||
println!("{}", _0);
|
||||
println!("{}", _1);
|
||||
assert_eq!(_0 + 10, i);
|
||||
i += 1;
|
||||
j = _1;
|
||||
});
|
||||
assert_eq!(j, 45);
|
||||
}
|
16
tests/ui/for-loop-while/foreach-simple-outer-slot.rs
Normal file
16
tests/ui/for-loop-while/foreach-simple-outer-slot.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
// run-pass
|
||||
|
||||
|
||||
|
||||
pub fn main() {
|
||||
let mut sum: isize = 0;
|
||||
first_ten(|i| { println!("main"); println!("{}", i); sum = sum + i; });
|
||||
println!("sum");
|
||||
println!("{}", sum);
|
||||
assert_eq!(sum, 45);
|
||||
}
|
||||
|
||||
fn first_ten<F>(mut it: F) where F: FnMut(isize) {
|
||||
let mut i: isize = 0;
|
||||
while i < 10 { println!("first_ten"); it(i); i = i + 1; }
|
||||
}
|
24
tests/ui/for-loop-while/issue-2216.rs
Normal file
24
tests/ui/for-loop-while/issue-2216.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
// run-pass
|
||||
#![allow(unreachable_code)]
|
||||
pub fn main() {
|
||||
let mut x = 0;
|
||||
|
||||
'foo: loop {
|
||||
'bar: loop {
|
||||
loop {
|
||||
if 1 == 2 {
|
||||
break 'foo;
|
||||
}
|
||||
else {
|
||||
break 'bar;
|
||||
}
|
||||
}
|
||||
continue 'foo;
|
||||
}
|
||||
x = 42;
|
||||
break;
|
||||
}
|
||||
|
||||
println!("{}", x);
|
||||
assert_eq!(x, 42);
|
||||
}
|
8
tests/ui/for-loop-while/issue-51345.rs
Normal file
8
tests/ui/for-loop-while/issue-51345.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
// run-pass
|
||||
#![allow(unreachable_code)]
|
||||
|
||||
fn main() {
|
||||
let mut v = Vec::new();
|
||||
|
||||
loop { v.push(break) }
|
||||
}
|
31
tests/ui/for-loop-while/issue-69841.rs
Normal file
31
tests/ui/for-loop-while/issue-69841.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
// This is a regression test for issue rust-lang/rust#69841, which exposed an
|
||||
// LLVM bug which needed a fix to be backported.
|
||||
|
||||
// run-pass
|
||||
// no-system-llvm
|
||||
|
||||
fn main() {
|
||||
let buffer = [49u8, 10];
|
||||
let mut a : u64 = 0;
|
||||
'read: loop {
|
||||
for c in &buffer {
|
||||
match c {
|
||||
48..=57 => {
|
||||
a*= 10;
|
||||
a+= *c as u64 - 48;
|
||||
}
|
||||
10 => {
|
||||
break 'read;
|
||||
}
|
||||
_ => {
|
||||
unsafe { std::hint::unreachable_unchecked() };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if a == 1 {
|
||||
println!("What did you expect?");
|
||||
} else {
|
||||
panic!("this should be unreachable.");
|
||||
}
|
||||
}
|
166
tests/ui/for-loop-while/label_break_value.rs
Normal file
166
tests/ui/for-loop-while/label_break_value.rs
Normal file
|
@ -0,0 +1,166 @@
|
|||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_assignments)]
|
||||
|
||||
// Test control flow to follow label_break_value semantics
|
||||
fn label_break(a: bool, b: bool) -> u32 {
|
||||
let mut v = 0;
|
||||
'b: {
|
||||
v = 1;
|
||||
if a {
|
||||
break 'b;
|
||||
}
|
||||
v = 2;
|
||||
if b {
|
||||
break 'b;
|
||||
}
|
||||
v = 3;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
// Test that values can be returned
|
||||
fn break_value(a: bool, b: bool) -> u32 {
|
||||
let result = 'block: {
|
||||
if a { break 'block 1; }
|
||||
if b { break 'block 2; }
|
||||
3
|
||||
};
|
||||
result
|
||||
}
|
||||
|
||||
// Test nesting of labeled blocks
|
||||
// here we only check that it compiles
|
||||
fn label_break_nested() {
|
||||
'b: {
|
||||
println!("hi");
|
||||
if false {
|
||||
break 'b;
|
||||
}
|
||||
'c: {
|
||||
if false {
|
||||
break 'b;
|
||||
}
|
||||
break 'c;
|
||||
}
|
||||
println!("hello");
|
||||
if true {
|
||||
break 'b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests for mixing labeled blocks with loop constructs
|
||||
// This function should be the identity function
|
||||
fn label_break_mixed(v: u32) -> u32 {
|
||||
let mut r = 0;
|
||||
'b: {
|
||||
// Unlabeled break still works
|
||||
// (only crossing boundaries is an error)
|
||||
loop {
|
||||
break;
|
||||
}
|
||||
if v == 0 {
|
||||
break 'b;
|
||||
}
|
||||
// Labeled breaking an inner loop still works
|
||||
'c: loop {
|
||||
if r == 1 {
|
||||
break 'c;
|
||||
}
|
||||
r += 1;
|
||||
}
|
||||
assert_eq!(r, 1);
|
||||
if v == 1 {
|
||||
break 'b;
|
||||
}
|
||||
// Labeled breaking an outer loop still works
|
||||
'd: loop {
|
||||
{
|
||||
if v == r {
|
||||
break 'b;
|
||||
}
|
||||
if r == 5 {
|
||||
break 'd;
|
||||
}
|
||||
r += 1;
|
||||
}
|
||||
}
|
||||
assert_eq!(r, 5);
|
||||
assert!(v > r);
|
||||
// Here we test return from inside a labeled block
|
||||
return v;
|
||||
}
|
||||
r
|
||||
}
|
||||
|
||||
fn label_break_match(c: u8, xe: u8, ye: i8) {
|
||||
let mut x = 0;
|
||||
let y = 'a: {
|
||||
match c {
|
||||
0 => break 'a 0,
|
||||
v if { if v % 2 == 0 { break 'a 1; }; v % 3 == 0 } => { x += 1; },
|
||||
v if { 'b: { break 'b v == 5; } } => { x = 41; },
|
||||
_ => 'b: {
|
||||
break 'b ();
|
||||
},
|
||||
}
|
||||
x += 1;
|
||||
-1
|
||||
};
|
||||
|
||||
assert_eq!(x, xe);
|
||||
assert_eq!(y, ye);
|
||||
}
|
||||
|
||||
#[allow(unused_labels)]
|
||||
fn label_break_macro() {
|
||||
macro_rules! mac1 {
|
||||
($target:lifetime, $val:expr) => {
|
||||
break $target $val;
|
||||
};
|
||||
}
|
||||
let x: u8 = 'a: {
|
||||
'b: {
|
||||
mac1!('b, 1);
|
||||
};
|
||||
0
|
||||
};
|
||||
assert_eq!(x, 0);
|
||||
let x: u8 = 'a: {
|
||||
'b: {
|
||||
if true {
|
||||
mac1!('a, 1);
|
||||
}
|
||||
};
|
||||
0
|
||||
};
|
||||
assert_eq!(x, 1);
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
assert_eq!(label_break(true, false), 1);
|
||||
assert_eq!(label_break(false, true), 2);
|
||||
assert_eq!(label_break(false, false), 3);
|
||||
|
||||
assert_eq!(break_value(true, false), 1);
|
||||
assert_eq!(break_value(false, true), 2);
|
||||
assert_eq!(break_value(false, false), 3);
|
||||
|
||||
assert_eq!(label_break_mixed(0), 0);
|
||||
assert_eq!(label_break_mixed(1), 1);
|
||||
assert_eq!(label_break_mixed(2), 2);
|
||||
assert_eq!(label_break_mixed(3), 3);
|
||||
assert_eq!(label_break_mixed(4), 4);
|
||||
assert_eq!(label_break_mixed(5), 5);
|
||||
assert_eq!(label_break_mixed(6), 6);
|
||||
|
||||
label_break_match(0, 0, 0);
|
||||
label_break_match(1, 1, -1);
|
||||
label_break_match(2, 0, 1);
|
||||
label_break_match(3, 2, -1);
|
||||
label_break_match(5, 42, -1);
|
||||
label_break_match(7, 1, -1);
|
||||
|
||||
label_break_macro();
|
||||
}
|
35
tests/ui/for-loop-while/label_break_value_invalid.rs
Normal file
35
tests/ui/for-loop-while/label_break_value_invalid.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
#![crate_type = "lib"]
|
||||
|
||||
fn lbv_macro_test_hygiene_respected() {
|
||||
macro_rules! mac2 {
|
||||
($val:expr) => {
|
||||
break 'a $val; //~ ERROR undeclared label `'a` [E0426]
|
||||
};
|
||||
}
|
||||
let x: u8 = 'a: {
|
||||
'b: {
|
||||
if true {
|
||||
mac2!(2);
|
||||
}
|
||||
};
|
||||
0
|
||||
};
|
||||
assert_eq!(x, 2);
|
||||
|
||||
macro_rules! mac3 {
|
||||
($val:expr) => {
|
||||
'a: {
|
||||
$val
|
||||
}
|
||||
};
|
||||
}
|
||||
let x: u8 = mac3!('b: {
|
||||
if true {
|
||||
break 'a 3; //~ ERROR undeclared label `'a` [E0426]
|
||||
}
|
||||
0
|
||||
});
|
||||
assert_eq!(x, 3);
|
||||
let x: u8 = mac3!(break 'a 4); //~ ERROR undeclared label `'a` [E0426]
|
||||
assert_eq!(x, 4);
|
||||
}
|
32
tests/ui/for-loop-while/label_break_value_invalid.stderr
Normal file
32
tests/ui/for-loop-while/label_break_value_invalid.stderr
Normal file
|
@ -0,0 +1,32 @@
|
|||
error[E0426]: use of undeclared label `'a`
|
||||
--> $DIR/label_break_value_invalid.rs:6:19
|
||||
|
|
||||
LL | break 'a $val;
|
||||
| ^^ undeclared label `'a`
|
||||
...
|
||||
LL | mac2!(2);
|
||||
| -------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0426]: use of undeclared label `'a`
|
||||
--> $DIR/label_break_value_invalid.rs:28:19
|
||||
|
|
||||
LL | let x: u8 = mac3!('b: {
|
||||
| -- a label with a similar name is reachable
|
||||
LL | if true {
|
||||
LL | break 'a 3;
|
||||
| ^^
|
||||
| |
|
||||
| undeclared label `'a`
|
||||
| help: try using similarly named label: `'b`
|
||||
|
||||
error[E0426]: use of undeclared label `'a`
|
||||
--> $DIR/label_break_value_invalid.rs:33:29
|
||||
|
|
||||
LL | let x: u8 = mac3!(break 'a 4);
|
||||
| ^^ undeclared label `'a`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0426`.
|
22
tests/ui/for-loop-while/labeled-break.rs
Normal file
22
tests/ui/for-loop-while/labeled-break.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
// run-pass
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
pub fn main() {
|
||||
'foo: loop {
|
||||
loop {
|
||||
break 'foo;
|
||||
}
|
||||
}
|
||||
|
||||
'bar: for _ in 0..100 {
|
||||
loop {
|
||||
break 'bar;
|
||||
}
|
||||
}
|
||||
|
||||
'foobar: while 1 + 1 == 2 {
|
||||
loop {
|
||||
break 'foobar;
|
||||
}
|
||||
}
|
||||
}
|
23
tests/ui/for-loop-while/linear-for-loop.rs
Normal file
23
tests/ui/for-loop-while/linear-for-loop.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
// run-pass
|
||||
pub fn main() {
|
||||
let x = vec![1, 2, 3];
|
||||
let mut y = 0;
|
||||
for i in &x { println!("{}", *i); y += *i; }
|
||||
println!("{}", y);
|
||||
assert_eq!(y, 6);
|
||||
let s = "hello there".to_string();
|
||||
let mut i: isize = 0;
|
||||
for c in s.bytes() {
|
||||
if i == 0 { assert_eq!(c, 'h' as u8); }
|
||||
if i == 1 { assert_eq!(c, 'e' as u8); }
|
||||
if i == 2 { assert_eq!(c, 'l' as u8); }
|
||||
if i == 3 { assert_eq!(c, 'l' as u8); }
|
||||
if i == 4 { assert_eq!(c, 'o' as u8); }
|
||||
// ...
|
||||
|
||||
i += 1;
|
||||
println!("{}", i);
|
||||
println!("{}", c);
|
||||
}
|
||||
assert_eq!(i, 11);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_assignments)]
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
#![allow(unreachable_code)]
|
||||
#![allow(unused_variables)]
|
||||
|
||||
fn test(_cond: bool) {
|
||||
let v: isize;
|
||||
v = 1;
|
||||
loop { } // loop never terminates, so no error is reported
|
||||
v = 2;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
// note: don't call test()... :)
|
||||
}
|
13
tests/ui/for-loop-while/liveness-loop-break.rs
Normal file
13
tests/ui/for-loop-while/liveness-loop-break.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
// run-pass
|
||||
fn test() {
|
||||
let v;
|
||||
loop {
|
||||
v = 3;
|
||||
break;
|
||||
}
|
||||
println!("{}", v);
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
test();
|
||||
}
|
20
tests/ui/for-loop-while/liveness-move-in-loop.rs
Normal file
20
tests/ui/for-loop-while/liveness-move-in-loop.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
fn take(x: isize) -> isize {x}
|
||||
|
||||
fn the_loop() {
|
||||
let mut list = Vec::new();
|
||||
loop {
|
||||
let x = 5;
|
||||
if x > 3 {
|
||||
list.push(take(x));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {}
|
12
tests/ui/for-loop-while/long-while.rs
Normal file
12
tests/ui/for-loop-while/long-while.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
// run-pass
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
#![allow(unused_variables)]
|
||||
|
||||
pub fn main() {
|
||||
let mut i: isize = 0;
|
||||
while i < 1000000 {
|
||||
i += 1;
|
||||
let x = 3;
|
||||
}
|
||||
}
|
9
tests/ui/for-loop-while/loop-break-cont-1.rs
Normal file
9
tests/ui/for-loop-while/loop-break-cont-1.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
// run-pass
|
||||
|
||||
pub fn main() {
|
||||
let _i = 0_usize;
|
||||
loop {
|
||||
break;
|
||||
}
|
||||
assert!(true);
|
||||
}
|
39
tests/ui/for-loop-while/loop-break-cont.rs
Normal file
39
tests/ui/for-loop-while/loop-break-cont.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
// run-pass
|
||||
pub fn main() {
|
||||
let mut i = 0_usize;
|
||||
loop {
|
||||
println!("a");
|
||||
i += 1_usize;
|
||||
if i == 10_usize {
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert_eq!(i, 10_usize);
|
||||
let mut is_even = false;
|
||||
loop {
|
||||
if i == 21_usize {
|
||||
break;
|
||||
}
|
||||
println!("b");
|
||||
is_even = false;
|
||||
i += 1_usize;
|
||||
if i % 2_usize != 0_usize {
|
||||
continue;
|
||||
}
|
||||
is_even = true;
|
||||
}
|
||||
assert!(!is_even);
|
||||
loop {
|
||||
println!("c");
|
||||
if i == 22_usize {
|
||||
break;
|
||||
}
|
||||
is_even = false;
|
||||
i += 1_usize;
|
||||
if i % 2_usize != 0_usize {
|
||||
continue;
|
||||
}
|
||||
is_even = true;
|
||||
}
|
||||
assert!(is_even);
|
||||
}
|
139
tests/ui/for-loop-while/loop-break-value.rs
Normal file
139
tests/ui/for-loop-while/loop-break-value.rs
Normal file
|
@ -0,0 +1,139 @@
|
|||
// run-pass
|
||||
|
||||
#![allow(unreachable_code)]
|
||||
#![feature(never_type)]
|
||||
|
||||
#[allow(unused)]
|
||||
fn never_returns() {
|
||||
loop {
|
||||
break loop {};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let value = 'outer: loop {
|
||||
if 1 == 1 {
|
||||
break 13;
|
||||
} else {
|
||||
let _never: ! = loop {
|
||||
break loop {
|
||||
break 'outer panic!();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
assert_eq!(value, 13);
|
||||
|
||||
let x = [1, 3u32, 5];
|
||||
let y = [17];
|
||||
let z = [];
|
||||
let coerced: &[_] = loop {
|
||||
match 2 {
|
||||
1 => break &x,
|
||||
2 => break &y,
|
||||
3 => break &z,
|
||||
_ => (),
|
||||
}
|
||||
};
|
||||
assert_eq!(coerced, &[17u32]);
|
||||
|
||||
let trait_unified = loop {
|
||||
break if true {
|
||||
break Default::default()
|
||||
} else {
|
||||
break [13, 14]
|
||||
};
|
||||
};
|
||||
assert_eq!(trait_unified, [0, 0]);
|
||||
|
||||
let trait_unified_2 = loop {
|
||||
if false {
|
||||
break [String::from("Hello")]
|
||||
} else {
|
||||
break Default::default()
|
||||
};
|
||||
};
|
||||
assert_eq!(trait_unified_2, [""]);
|
||||
|
||||
let trait_unified_3 = loop {
|
||||
break if false {
|
||||
break [String::from("Hello")]
|
||||
} else {
|
||||
["Yes".into()]
|
||||
};
|
||||
};
|
||||
assert_eq!(trait_unified_3, ["Yes"]);
|
||||
|
||||
let regular_break = loop {
|
||||
if true {
|
||||
break;
|
||||
} else {
|
||||
break break Default::default();
|
||||
}
|
||||
};
|
||||
assert_eq!(regular_break, ());
|
||||
|
||||
let regular_break_2 = loop {
|
||||
if true {
|
||||
break Default::default();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
};
|
||||
assert_eq!(regular_break_2, ());
|
||||
|
||||
let regular_break_3 = loop {
|
||||
break if true {
|
||||
Default::default()
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
};
|
||||
assert_eq!(regular_break_3, ());
|
||||
|
||||
let regular_break_4 = loop {
|
||||
break ();
|
||||
break;
|
||||
};
|
||||
assert_eq!(regular_break_4, ());
|
||||
|
||||
let regular_break_5 = loop {
|
||||
break;
|
||||
break ();
|
||||
};
|
||||
assert_eq!(regular_break_5, ());
|
||||
|
||||
let nested_break_value = 'outer2: loop {
|
||||
let _a: u32 = 'inner: loop {
|
||||
if true {
|
||||
break 'outer2 "hello";
|
||||
} else {
|
||||
break 'inner 17;
|
||||
}
|
||||
};
|
||||
panic!();
|
||||
};
|
||||
assert_eq!(nested_break_value, "hello");
|
||||
|
||||
let break_from_while_cond = loop {
|
||||
'inner_loop: while break 'inner_loop {
|
||||
panic!();
|
||||
}
|
||||
break 123;
|
||||
};
|
||||
assert_eq!(break_from_while_cond, 123);
|
||||
|
||||
let break_from_while_to_outer = 'outer_loop: loop {
|
||||
while break 'outer_loop 567 {
|
||||
panic!("from_inner");
|
||||
}
|
||||
panic!("from outer");
|
||||
};
|
||||
assert_eq!(break_from_while_to_outer, 567);
|
||||
|
||||
let rust = true;
|
||||
let value = loop {
|
||||
break rust;
|
||||
};
|
||||
assert!(value);
|
||||
}
|
14
tests/ui/for-loop-while/loop-diverges.rs
Normal file
14
tests/ui/for-loop-while/loop-diverges.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
// run-pass
|
||||
#![allow(unused_parens)]
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
/* Make sure a loop{} can be the tailexpr in the body
|
||||
of a diverging function */
|
||||
|
||||
fn forever() -> ! {
|
||||
loop{}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
if (1 == 2) { forever(); }
|
||||
}
|
12
tests/ui/for-loop-while/loop-label-shadowing.rs
Normal file
12
tests/ui/for-loop-while/loop-label-shadowing.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
// run-pass
|
||||
// Issue #12512.
|
||||
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
fn main() {
|
||||
let mut foo = Vec::new();
|
||||
#[allow(unused_labels)]
|
||||
'foo: for i in &[1, 2, 3] {
|
||||
foo.push(*i);
|
||||
}
|
||||
}
|
11
tests/ui/for-loop-while/loop-labeled-break-value.rs
Normal file
11
tests/ui/for-loop-while/loop-labeled-break-value.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// run-pass
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
fn main() {
|
||||
'outer: loop {
|
||||
let _: i32 = loop { break 'outer };
|
||||
}
|
||||
'outer2: loop {
|
||||
let _: i32 = loop { loop { break 'outer2 } };
|
||||
}
|
||||
}
|
34
tests/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs
Normal file
34
tests/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
// run-pass
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
struct S;
|
||||
// Ensure S is moved, not copied, on assignment.
|
||||
impl Drop for S { fn drop(&mut self) { } }
|
||||
|
||||
// user-defined function "returning" bottom (i.e., no return at all).
|
||||
fn my_panic() -> ! { loop {} }
|
||||
|
||||
pub fn step(f: bool) {
|
||||
let mut g = S;
|
||||
let mut i = 0;
|
||||
loop
|
||||
{
|
||||
if i > 10 { break; } else { i += 1; }
|
||||
|
||||
let _g = g;
|
||||
|
||||
if f {
|
||||
// re-initialize g, but only before restarting loop.
|
||||
g = S;
|
||||
continue;
|
||||
}
|
||||
|
||||
my_panic();
|
||||
|
||||
// we never get here, so we do not need to re-initialize g.
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
step(true);
|
||||
}
|
8
tests/ui/for-loop-while/loop-scope.rs
Normal file
8
tests/ui/for-loop-while/loop-scope.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
// run-pass
|
||||
|
||||
pub fn main() {
|
||||
let x = vec![10, 20, 30];
|
||||
let mut sum = 0;
|
||||
for x in &x { sum += *x; }
|
||||
assert_eq!(sum, 60);
|
||||
}
|
11
tests/ui/for-loop-while/while-cont.rs
Normal file
11
tests/ui/for-loop-while/while-cont.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// run-pass
|
||||
// Issue #825: Should recheck the loop condition after continuing
|
||||
pub fn main() {
|
||||
let mut i = 1;
|
||||
while i > 0 {
|
||||
assert!((i > 0));
|
||||
println!("{}", i);
|
||||
i -= 1;
|
||||
continue;
|
||||
}
|
||||
}
|
6
tests/ui/for-loop-while/while-flow-graph.rs
Normal file
6
tests/ui/for-loop-while/while-flow-graph.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
// run-pass
|
||||
|
||||
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
pub fn main() { let x: isize = 10; while x == 10 && x == 11 { let _y = 0xf00_usize; } }
|
15
tests/ui/for-loop-while/while-label.rs
Normal file
15
tests/ui/for-loop-while/while-label.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
// run-pass
|
||||
#![allow(unreachable_code)]
|
||||
|
||||
|
||||
pub fn main() {
|
||||
let mut i = 100;
|
||||
'w: while 1 + 1 == 2 {
|
||||
i -= 1;
|
||||
if i == 95 {
|
||||
break 'w;
|
||||
panic!("Should have broken out of loop");
|
||||
}
|
||||
}
|
||||
assert_eq!(i, 95);
|
||||
}
|
31
tests/ui/for-loop-while/while-let-2.rs
Normal file
31
tests/ui/for-loop-while/while-let-2.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
// run-pass
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn macros() {
|
||||
macro_rules! foo{
|
||||
($p:pat, $e:expr, $b:block) => {{
|
||||
while let $p = $e $b
|
||||
//~^ WARN irrefutable `while let`
|
||||
//~| WARN irrefutable `while let`
|
||||
}}
|
||||
}
|
||||
macro_rules! bar{
|
||||
($p:pat, $e:expr, $b:block) => {{
|
||||
foo!($p, $e, $b)
|
||||
}}
|
||||
}
|
||||
|
||||
foo!(_a, 1, {
|
||||
println!("irrefutable pattern");
|
||||
});
|
||||
bar!(_a, 1, {
|
||||
println!("irrefutable pattern");
|
||||
});
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
while let _a = 1 { //~ WARN irrefutable `while let`
|
||||
println!("irrefutable pattern");
|
||||
break;
|
||||
}
|
||||
}
|
42
tests/ui/for-loop-while/while-let-2.stderr
Normal file
42
tests/ui/for-loop-while/while-let-2.stderr
Normal file
|
@ -0,0 +1,42 @@
|
|||
warning: irrefutable `while let` pattern
|
||||
--> $DIR/while-let-2.rs:7:19
|
||||
|
|
||||
LL | while let $p = $e $b
|
||||
| ^^^
|
||||
...
|
||||
LL | / foo!(_a, 1, {
|
||||
LL | | println!("irrefutable pattern");
|
||||
LL | | });
|
||||
| |______- in this macro invocation
|
||||
|
|
||||
= note: this pattern will always match, so the loop will never exit
|
||||
= help: consider instead using a `loop { ... }` with a `let` inside it
|
||||
= note: `#[warn(irrefutable_let_patterns)]` on by default
|
||||
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
warning: irrefutable `while let` pattern
|
||||
--> $DIR/while-let-2.rs:7:19
|
||||
|
|
||||
LL | while let $p = $e $b
|
||||
| ^^^
|
||||
...
|
||||
LL | / bar!(_a, 1, {
|
||||
LL | | println!("irrefutable pattern");
|
||||
LL | | });
|
||||
| |______- in this macro invocation
|
||||
|
|
||||
= note: this pattern will always match, so the loop will never exit
|
||||
= help: consider instead using a `loop { ... }` with a `let` inside it
|
||||
= note: this warning originates in the macro `foo` which comes from the expansion of the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
warning: irrefutable `while let` pattern
|
||||
--> $DIR/while-let-2.rs:27:11
|
||||
|
|
||||
LL | while let _a = 1 {
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: this pattern will always match, so the loop will never exit
|
||||
= help: consider instead using a `loop { ... }` with a `let` inside it
|
||||
|
||||
warning: 3 warnings emitted
|
||||
|
46
tests/ui/for-loop-while/while-let.rs
Normal file
46
tests/ui/for-loop-while/while-let.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
// run-pass
|
||||
|
||||
use std::collections::BinaryHeap;
|
||||
|
||||
fn make_pq() -> BinaryHeap<isize> {
|
||||
BinaryHeap::from(vec![1,2,3])
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let mut pq = make_pq();
|
||||
let mut sum = 0;
|
||||
while let Some(x) = pq.pop() {
|
||||
sum += x;
|
||||
}
|
||||
assert_eq!(sum, 6);
|
||||
|
||||
pq = make_pq();
|
||||
sum = 0;
|
||||
'a: while let Some(x) = pq.pop() {
|
||||
sum += x;
|
||||
if x == 2 {
|
||||
break 'a;
|
||||
}
|
||||
}
|
||||
assert_eq!(sum, 5);
|
||||
|
||||
pq = make_pq();
|
||||
sum = 0;
|
||||
'a2: while let Some(x) = pq.pop() {
|
||||
if x == 3 {
|
||||
continue 'a2;
|
||||
}
|
||||
sum += x;
|
||||
}
|
||||
assert_eq!(sum, 3);
|
||||
|
||||
let mut pq1 = make_pq();
|
||||
sum = 0;
|
||||
while let Some(x) = pq1.pop() {
|
||||
let mut pq2 = make_pq();
|
||||
while let Some(y) = pq2.pop() {
|
||||
sum += x * y;
|
||||
}
|
||||
}
|
||||
assert_eq!(sum, 6 + 12 + 18);
|
||||
}
|
15
tests/ui/for-loop-while/while-loop-constraints-2.rs
Normal file
15
tests/ui/for-loop-while/while-loop-constraints-2.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
// run-pass
|
||||
#![allow(unused_assignments)]
|
||||
#![allow(unused_variables)]
|
||||
|
||||
pub fn main() {
|
||||
let mut y: isize = 42;
|
||||
let mut z: isize = 42;
|
||||
let mut x: isize;
|
||||
while z < 50 {
|
||||
z += 1;
|
||||
while false { x = y; y = z; }
|
||||
println!("{}", y);
|
||||
}
|
||||
assert!((y == 42 && z == 50));
|
||||
}
|
24
tests/ui/for-loop-while/while-prelude-drop.rs
Normal file
24
tests/ui/for-loop-while/while-prelude-drop.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
// run-pass
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use std::string::String;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum t { a, b(String), }
|
||||
|
||||
fn make(i: isize) -> t {
|
||||
if i > 10 { return t::a; }
|
||||
let mut s = String::from("hello");
|
||||
// Ensure s is non-const.
|
||||
|
||||
s.push_str("there");
|
||||
return t::b(s);
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let mut i = 0;
|
||||
|
||||
|
||||
// The auto slot for the result of make(i) should not leak.
|
||||
while make(i) != t::a { i += 1; }
|
||||
}
|
17
tests/ui/for-loop-while/while-with-break.rs
Normal file
17
tests/ui/for-loop-while/while-with-break.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
// run-pass
|
||||
|
||||
pub fn main() {
|
||||
let mut i: isize = 90;
|
||||
while i < 100 {
|
||||
println!("{}", i);
|
||||
i = i + 1;
|
||||
if i == 95 {
|
||||
let _v: Vec<isize> =
|
||||
vec![1, 2, 3, 4, 5]; // we check that it is freed by break
|
||||
|
||||
println!("breaking");
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert_eq!(i, 95);
|
||||
}
|
13
tests/ui/for-loop-while/while.rs
Normal file
13
tests/ui/for-loop-while/while.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
// run-pass
|
||||
|
||||
|
||||
pub fn main() {
|
||||
let mut x: isize = 10;
|
||||
let mut y: isize = 0;
|
||||
while y < x { println!("{}", y); println!("hello"); y = y + 1; }
|
||||
while x > 0 {
|
||||
println!("goodbye");
|
||||
x = x - 1;
|
||||
println!("{}", x);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue