Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Note that the test for #30822 is folded into the test for #30530 (but the file name mentions only 30530).
- Loading branch information
Showing
4 changed files
with
213 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// Regression test for Issue #29092. | ||
// | ||
// (Possibly redundant with regression test run-pass/issue-30530.rs) | ||
|
||
use self::Term::*; | ||
|
||
#[derive(Clone)] | ||
pub enum Term { | ||
Dummy, | ||
A(Box<Term>), | ||
B(Box<Term>), | ||
} | ||
|
||
// a small-step evaluator | ||
pub fn small_eval(v: Term) -> Term { | ||
match v { | ||
A(t) => *t.clone(), | ||
B(t) => *t.clone(), | ||
_ => Dummy, | ||
} | ||
} | ||
|
||
fn main() { | ||
small_eval(Dummy); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// More thorough regression test for Issues #30018 and #30822. This | ||
// attempts to explore different ways that array element construction | ||
// (for both scratch arrays and non-scratch ones) interacts with | ||
// breaks in the control-flow, in terms of the order of evaluation of | ||
// the destructors (which may change; see RFC Issue 744) and the | ||
// number of times that the destructor evaluates for each value (which | ||
// should never exceed 1; this latter case is what #30822 is about). | ||
|
||
use std::cell::RefCell; | ||
|
||
struct D<'a>(&'a RefCell<Vec<i32>>, i32); | ||
|
||
impl<'a> Drop for D<'a> { | ||
fn drop(&mut self) { | ||
println!("Dropping D({})", self.1); | ||
(self.0).borrow_mut().push(self.1); | ||
} | ||
} | ||
|
||
fn main() { | ||
println!("Start"); | ||
break_during_elem(); | ||
break_after_whole(); | ||
println!("Finis"); | ||
} | ||
|
||
fn break_during_elem() { | ||
let log = &RefCell::new(Vec::new()); | ||
|
||
// CASE 1: Fixed-size array itself is stored in _r slot. | ||
loop { | ||
let _r = [D(log, 10), | ||
D(log, 11), | ||
{ D(log, 12); break; }, | ||
D(log, 13)]; | ||
} | ||
assert_eq!(&log.borrow()[..], &[12, 11, 10]); | ||
log.borrow_mut().clear(); | ||
|
||
// CASE 2: Slice (borrow of array) is stored in _r slot. | ||
// This is the case that is actually being reported in #30018. | ||
loop { | ||
let _r = &[D(log, 20), | ||
D(log, 21), | ||
{ D(log, 22); break; }, | ||
D(log, 23)]; | ||
} | ||
assert_eq!(&log.borrow()[..], &[22, 21, 20]); | ||
log.borrow_mut().clear(); | ||
|
||
// CASE 3: (Borrow of) slice-index of array is stored in _r slot. | ||
loop { | ||
let _r = &[D(log, 30), | ||
D(log, 31), | ||
{ D(log, 32); break; }, | ||
D(log, 33)][..]; | ||
} | ||
assert_eq!(&log.borrow()[..], &[32, 31, 30]); | ||
log.borrow_mut().clear(); | ||
} | ||
|
||
// The purpose of these functions is to test what happens when we | ||
// panic after an array has been constructed in its entirety. | ||
// | ||
// It is meant to act as proof that we still need to continue | ||
// scheduling the destruction of an array even after we've scheduling | ||
// drop for its elements during construction; the latter is tested by | ||
// `fn break_during_elem()`. | ||
fn break_after_whole() { | ||
let log = &RefCell::new(Vec::new()); | ||
|
||
// CASE 1: Fixed-size array itself is stored in _r slot. | ||
loop { | ||
let _r = [D(log, 10), | ||
D(log, 11), | ||
D(log, 12)]; | ||
break; | ||
} | ||
assert_eq!(&log.borrow()[..], &[10, 11, 12]); | ||
log.borrow_mut().clear(); | ||
|
||
// CASE 2: Slice (borrow of array) is stored in _r slot. | ||
loop { | ||
let _r = &[D(log, 20), | ||
D(log, 21), | ||
D(log, 22)]; | ||
break; | ||
} | ||
assert_eq!(&log.borrow()[..], &[20, 21, 22]); | ||
log.borrow_mut().clear(); | ||
|
||
// CASE 3: (Borrow of) slice-index of array is stored in _r slot. | ||
loop { | ||
let _r = &[D(log, 30), | ||
D(log, 31), | ||
D(log, 32)][..]; | ||
break; | ||
} | ||
assert_eq!(&log.borrow()[..], &[30, 31, 32]); | ||
log.borrow_mut().clear(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// Regression test for Issue #30018. This is very similar to the | ||
// original reported test, except that the panic is wrapped in a | ||
// spawned thread to isolate the expected error result from the | ||
// SIGTRAP injected by the drop-flag consistency checking. | ||
|
||
struct Foo; | ||
|
||
impl Drop for Foo { | ||
fn drop(&mut self) {} | ||
} | ||
|
||
fn foo() -> Foo { | ||
panic!(); | ||
} | ||
|
||
fn main() { | ||
use std::thread; | ||
let handle = thread::spawn(|| { | ||
let _ = &[foo()]; | ||
}); | ||
let _ = handle.join(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// Regression test for Issue #30530: alloca's created for storing | ||
// intermediate scratch values during brace-less match arms need to be | ||
// initialized with their drop-flag set to "dropped" (or else we end | ||
// up running the destructors on garbage data at the end of the | ||
// function). | ||
|
||
pub enum Handler { | ||
Default, | ||
#[allow(dead_code)] | ||
Custom(*mut Box<Fn()>), | ||
} | ||
|
||
fn main() { | ||
take(Handler::Default, Box::new(main)); | ||
} | ||
|
||
#[inline(never)] | ||
pub fn take(h: Handler, f: Box<Fn()>) -> Box<Fn()> { | ||
unsafe { | ||
match h { | ||
Handler::Custom(ptr) => *Box::from_raw(ptr), | ||
Handler::Default => f, | ||
} | ||
} | ||
} |