1
Fork 0

Move /src/test to /tests

This commit is contained in:
Albert Larsan 2023-01-05 09:13:28 +01:00
parent ca855e6e42
commit cf2dff2b1e
No known key found for this signature in database
GPG key ID: 92709B88BB8F13EA
27592 changed files with 0 additions and 0 deletions

View 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);
}

View 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
};
}
}

View 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`.

View 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); } }

View 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
}
};
}
}

View 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`.

View 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));
}
}

View file

@ -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) }
}
}

View 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);
}
}

View 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);
}
}

View 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 {
()
}
}

View 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);
}
}

View file

@ -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);
}

View 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);
}
}

View 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) {}
}

View 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
}

View file

@ -0,0 +1,4 @@
// run-pass
pub fn main() { let x: Vec<isize> = Vec::new(); for _ in &x { panic!("moop"); } }

View file

@ -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;
}
}

View 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);
}

View file

@ -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);
}

View file

@ -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);
}

View 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);
}

View 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);
}

View 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);
}

View 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);
}

View 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);
}

View 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; }
}

View 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);
}

View file

@ -0,0 +1,8 @@
// run-pass
#![allow(unreachable_code)]
fn main() {
let mut v = Vec::new();
loop { v.push(break) }
}

View 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.");
}
}

View 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();
}

View 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);
}

View 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`.

View 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;
}
}
}

View 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);
}

View file

@ -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()... :)
}

View file

@ -0,0 +1,13 @@
// run-pass
fn test() {
let v;
loop {
v = 3;
break;
}
println!("{}", v);
}
pub fn main() {
test();
}

View 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() {}

View 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;
}
}

View file

@ -0,0 +1,9 @@
// run-pass
pub fn main() {
let _i = 0_usize;
loop {
break;
}
assert!(true);
}

View 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);
}

View 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);
}

View 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(); }
}

View 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);
}
}

View 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 } };
}
}

View 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);
}

View 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);
}

View 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;
}
}

View 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; } }

View 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);
}

View 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;
}
}

View 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

View 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);
}

View 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));
}

View 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; }
}

View 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);
}

View 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);
}
}