Auto merge of #34139 - steveklabnik:rollup, r=steveklabnik
Rollup of 13 pull requests - Successful merges: #33645, #33897, #33945, #34007, #34060, #34070, #34094, #34098, #34099, #34104, #34124, #34125, #34138 - Failed merges:
This commit is contained in:
commit
39a523ba13
@ -108,7 +108,8 @@ root.
|
||||
There are large number of options accepted by this script to alter the
|
||||
configuration used later in the build process. Some options to note:
|
||||
|
||||
- `--enable-debug` - Build a debug version of the compiler (disables optimizations)
|
||||
- `--enable-debug` - Build a debug version of the compiler (disables optimizations,
|
||||
which speeds up compilation of stage1 rustc)
|
||||
- `--enable-optimize` - Enable optimizations (can be used with `--enable-debug`
|
||||
to make a debug build with optimizations)
|
||||
- `--disable-valgrind-rpass` - Don't run tests with valgrind
|
||||
@ -128,6 +129,12 @@ Some common make targets are:
|
||||
cases we don't need to build the stage2 compiler, so we can save time by not
|
||||
building it. The stage1 compiler is a fully functioning compiler and
|
||||
(probably) will be enough to determine if your change works as expected.
|
||||
- `make $host/stage1/bin/rustc` - Where $host is a target triple like x86_64-unknown-linux-gnu.
|
||||
This will build just rustc, without libstd. This is the fastest way to recompile after
|
||||
you changed only rustc source code. Note however that the resulting rustc binary
|
||||
won't have a stdlib to link against by default. You can build libstd once with
|
||||
`make rustc-stage1`, rustc will pick it up afterwards. libstd is only guaranteed to
|
||||
work if recompiled, so if there are any issues recompile it.
|
||||
- `make check` - build the full compiler & run all tests (takes a while). This
|
||||
is what gets run by the continuous integration system against your pull
|
||||
request. You should run this before submitting to make sure your tests pass
|
||||
|
11
Makefile.in
11
Makefile.in
@ -62,6 +62,8 @@
|
||||
# * tidy - Basic style check, show highest rustc error code and
|
||||
# the status of language and lib features
|
||||
# * rustc-stage$(stage) - Only build up to a specific stage
|
||||
# * $host/stage1/bin/rustc - Only build stage1 rustc, not libstd. For further
|
||||
# information see "Rust recipes for build system success" below.
|
||||
#
|
||||
# Then mix in some of these environment variables to harness the
|
||||
# ultimate power of The Rust Build System.
|
||||
@ -93,6 +95,15 @@
|
||||
# // Modifying libstd? Use this command to run unit tests just on your change
|
||||
# make check-stage1-std NO_REBUILD=1 NO_BENCH=1
|
||||
#
|
||||
# // Modifying just rustc?
|
||||
# // Compile rustc+libstd once
|
||||
# make rustc-stage1
|
||||
# // From now on use this command to rebuild just rustc and reuse the previously built libstd
|
||||
# // $host is a target triple, eg. x86_64-unknown-linux-gnu
|
||||
# // The resulting binary is located at $host/stage1/bin/rustc.
|
||||
# // If there are any issues with libstd recompile it with the command above.
|
||||
# make $host/stage1/bin/rustc
|
||||
#
|
||||
# // Added a run-pass test? Use this to test running your test
|
||||
# make check-stage1-rpass TESTNAME=my-shiny-new-test
|
||||
#
|
||||
|
4
configure
vendored
4
configure
vendored
@ -988,11 +988,11 @@ then
|
||||
LLVM_VERSION=$($LLVM_CONFIG --version)
|
||||
|
||||
case $LLVM_VERSION in
|
||||
(3.[6-8]*)
|
||||
(3.[7-8]*)
|
||||
msg "found ok version of LLVM: $LLVM_VERSION"
|
||||
;;
|
||||
(*)
|
||||
err "bad LLVM version: $LLVM_VERSION, need >=3.6"
|
||||
err "bad LLVM version: $LLVM_VERSION, need >=3.7"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
@ -249,7 +249,7 @@ stack backtrace:
|
||||
If you need to override an already set `RUST_BACKTRACE`,
|
||||
in cases when you cannot just unset the variable,
|
||||
then set it to `0` to avoid getting a backtrace.
|
||||
Any other value(even no value at all) turns on backtrace.
|
||||
Any other value (even no value at all) turns on backtrace.
|
||||
|
||||
```text
|
||||
$ export RUST_BACKTRACE=1
|
||||
|
@ -380,8 +380,9 @@ the `tests` directory.
|
||||
|
||||
# The `tests` directory
|
||||
|
||||
To write an integration test, let's make a `tests` directory, and
|
||||
put a `tests/lib.rs` file inside, with this as its contents:
|
||||
Each file in `tests/*.rs` directory is treated as individual crate.
|
||||
So, to write an integration test, let's make a `tests` directory, and
|
||||
put a `tests/integration_test.rs` file inside, with this as its contents:
|
||||
|
||||
```rust,ignore
|
||||
extern crate adder;
|
||||
@ -394,8 +395,8 @@ fn it_works() {
|
||||
```
|
||||
|
||||
This looks similar to our previous tests, but slightly different. We now have
|
||||
an `extern crate adder` at the top. This is because the tests in the `tests`
|
||||
directory are an entirely separate crate, and so we need to import our library.
|
||||
an `extern crate adder` at the top. This is because each test in the `tests`
|
||||
directory is an entirely separate crate, and so we need to import our library.
|
||||
This is also why `tests` is a suitable place to write integration-style tests:
|
||||
they use the library like any other consumer of it would.
|
||||
|
||||
@ -428,6 +429,11 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
|
||||
Now we have three sections: our previous test is also run, as well as our new
|
||||
one.
|
||||
|
||||
Cargo will ignore files in subdirectories of the `tests/` directory.
|
||||
Therefore shared modules in integrations tests are possible.
|
||||
For example `tests/common/mod.rs` is not seperatly compiled by cargo but can
|
||||
be imported in every test with `mod common;`
|
||||
|
||||
That's all there is to the `tests` directory. The `tests` module isn't needed
|
||||
here, since the whole thing is focused on tests.
|
||||
|
||||
|
@ -37,8 +37,8 @@ of our minds as we go forward.
|
||||
Rust is a statically typed language, which means that we specify our types up
|
||||
front, and they’re checked at compile time. So why does our first example
|
||||
compile? Well, Rust has this thing called ‘type inference’. If it can figure
|
||||
out what the type of something is, Rust doesn’t require you to actually type it
|
||||
out.
|
||||
out what the type of something is, Rust doesn’t require you to explicitly type
|
||||
it out.
|
||||
|
||||
We can add the type if we want to, though. Types come after a colon (`:`):
|
||||
|
||||
@ -159,8 +159,9 @@ error: aborting due to previous error
|
||||
Could not compile `hello_world`.
|
||||
```
|
||||
|
||||
Rust will not let us use a value that has not been initialized. Next, let’s
|
||||
talk about this stuff we've added to `println!`.
|
||||
Rust will not let us use a value that has not been initialized.
|
||||
|
||||
Let take a minute to talk about this stuff we've added to `println!`.
|
||||
|
||||
If you include two curly braces (`{}`, some call them moustaches...) in your
|
||||
string to print, Rust will interpret this as a request to interpolate some sort
|
||||
@ -222,8 +223,8 @@ To learn more, run the command again with --verbose.
|
||||
```
|
||||
|
||||
Additionally, variable bindings can be shadowed. This means that a later
|
||||
variable binding with the same name as another binding, that's currently in
|
||||
scope, will override the previous binding.
|
||||
variable binding with the same name as another binding that is currently in
|
||||
scope will override the previous binding.
|
||||
|
||||
```rust
|
||||
let x: i32 = 8;
|
||||
@ -240,7 +241,10 @@ println!("{}", x); // Prints "42"
|
||||
Shadowing and mutable bindings may appear as two sides of the same coin, but
|
||||
they are two distinct concepts that can't always be used interchangeably. For
|
||||
one, shadowing enables us to rebind a name to a value of a different type. It
|
||||
is also possible to change the mutability of a binding.
|
||||
is also possible to change the mutability of a binding. Note that shadowing a
|
||||
name does not alter or destroy the value it was bound to, and the value will
|
||||
continue to exist until it goes out of scope, even if it is no longer accessible
|
||||
by any means.
|
||||
|
||||
```rust
|
||||
let mut x: i32 = 1;
|
||||
|
@ -1983,6 +1983,7 @@ macro scope.
|
||||
|
||||
### Miscellaneous attributes
|
||||
|
||||
- `deprecated` - mark the item as deprecated; the full attribute is `#[deprecated(since = "crate version", note = "...")`, where both arguments are optional.
|
||||
- `export_name` - on statics and functions, this determines the name of the
|
||||
exported symbol.
|
||||
- `link_section` - on statics and functions, this specifies the section of the
|
||||
@ -2426,8 +2427,6 @@ The currently implemented features of the reference compiler are:
|
||||
* - `stmt_expr_attributes` - Allows attributes on expressions and
|
||||
non-item statements.
|
||||
|
||||
* - `deprecated` - Allows using the `#[deprecated]` attribute.
|
||||
|
||||
* - `type_ascription` - Allows type ascription expressions `expr: Type`.
|
||||
|
||||
* - `abi_vectorcall` - Allows the usage of the vectorcall calling convention
|
||||
|
@ -229,7 +229,7 @@ a > code {
|
||||
pre.rust .kw { color: #8959A8; }
|
||||
pre.rust .kw-2, pre.rust .prelude-ty { color: #4271AE; }
|
||||
pre.rust .number, pre.rust .string { color: #718C00; }
|
||||
pre.rust .self, pre.rust .boolval, pre.rust .prelude-val,
|
||||
pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val,
|
||||
pre.rust .attribute, pre.rust .attribute .ident { color: #C82829; }
|
||||
pre.rust .comment { color: #8E908C; }
|
||||
pre.rust .doccomment { color: #4D4D4C; }
|
||||
|
@ -271,7 +271,7 @@ impl<T> Rc<T> {
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Rc<T> {
|
||||
/// Downgrades the `Rc<T>` to a `Weak<T>` reference.
|
||||
/// Creates a new `Weak<T>` reference from this value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -1404,8 +1404,8 @@ impl str {
|
||||
/// Returns a string slice with all prefixes and suffixes that match a
|
||||
/// pattern repeatedly removed.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines
|
||||
/// if a character matches.
|
||||
/// The pattern can be a [`char`] or a closure that determines if a
|
||||
/// character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
|
@ -24,36 +24,35 @@
|
||||
use dwarf::DwarfReader;
|
||||
use core::mem;
|
||||
|
||||
pub const DW_EH_PE_omit : u8 = 0xFF;
|
||||
pub const DW_EH_PE_absptr : u8 = 0x00;
|
||||
pub const DW_EH_PE_omit: u8 = 0xFF;
|
||||
pub const DW_EH_PE_absptr: u8 = 0x00;
|
||||
|
||||
pub const DW_EH_PE_uleb128 : u8 = 0x01;
|
||||
pub const DW_EH_PE_udata2 : u8 = 0x02;
|
||||
pub const DW_EH_PE_udata4 : u8 = 0x03;
|
||||
pub const DW_EH_PE_udata8 : u8 = 0x04;
|
||||
pub const DW_EH_PE_sleb128 : u8 = 0x09;
|
||||
pub const DW_EH_PE_sdata2 : u8 = 0x0A;
|
||||
pub const DW_EH_PE_sdata4 : u8 = 0x0B;
|
||||
pub const DW_EH_PE_sdata8 : u8 = 0x0C;
|
||||
pub const DW_EH_PE_uleb128: u8 = 0x01;
|
||||
pub const DW_EH_PE_udata2: u8 = 0x02;
|
||||
pub const DW_EH_PE_udata4: u8 = 0x03;
|
||||
pub const DW_EH_PE_udata8: u8 = 0x04;
|
||||
pub const DW_EH_PE_sleb128: u8 = 0x09;
|
||||
pub const DW_EH_PE_sdata2: u8 = 0x0A;
|
||||
pub const DW_EH_PE_sdata4: u8 = 0x0B;
|
||||
pub const DW_EH_PE_sdata8: u8 = 0x0C;
|
||||
|
||||
pub const DW_EH_PE_pcrel : u8 = 0x10;
|
||||
pub const DW_EH_PE_textrel : u8 = 0x20;
|
||||
pub const DW_EH_PE_datarel : u8 = 0x30;
|
||||
pub const DW_EH_PE_funcrel : u8 = 0x40;
|
||||
pub const DW_EH_PE_aligned : u8 = 0x50;
|
||||
pub const DW_EH_PE_pcrel: u8 = 0x10;
|
||||
pub const DW_EH_PE_textrel: u8 = 0x20;
|
||||
pub const DW_EH_PE_datarel: u8 = 0x30;
|
||||
pub const DW_EH_PE_funcrel: u8 = 0x40;
|
||||
pub const DW_EH_PE_aligned: u8 = 0x50;
|
||||
|
||||
pub const DW_EH_PE_indirect : u8 = 0x80;
|
||||
pub const DW_EH_PE_indirect: u8 = 0x80;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct EHContext {
|
||||
pub ip: usize, // Current instruction pointer
|
||||
pub ip: usize, // Current instruction pointer
|
||||
pub func_start: usize, // Address of the current function
|
||||
pub text_start: usize, // Address of the code section
|
||||
pub data_start: usize, // Address of the data section
|
||||
}
|
||||
|
||||
pub unsafe fn find_landing_pad(lsda: *const u8, context: &EHContext)
|
||||
-> Option<usize> {
|
||||
pub unsafe fn find_landing_pad(lsda: *const u8, context: &EHContext) -> Option<usize> {
|
||||
if lsda.is_null() {
|
||||
return None;
|
||||
}
|
||||
@ -80,7 +79,7 @@ pub unsafe fn find_landing_pad(lsda: *const u8, context: &EHContext)
|
||||
let action_table = reader.ptr.offset(call_site_table_length as isize);
|
||||
// Return addresses point 1 byte past the call instruction, which could
|
||||
// be in the next IP range.
|
||||
let ip = context.ip-1;
|
||||
let ip = context.ip - 1;
|
||||
|
||||
while reader.ptr < action_table {
|
||||
let cs_start = read_encoded_pointer(&mut reader, context, call_site_encoding);
|
||||
@ -90,7 +89,7 @@ pub unsafe fn find_landing_pad(lsda: *const u8, context: &EHContext)
|
||||
// Callsite table is sorted by cs_start, so if we've passed the ip, we
|
||||
// may stop searching.
|
||||
if ip < func_start + cs_start {
|
||||
break
|
||||
break;
|
||||
}
|
||||
if ip < func_start + cs_start + cs_len {
|
||||
if cs_lpad != 0 {
|
||||
@ -114,13 +113,13 @@ fn round_up(unrounded: usize, align: usize) -> usize {
|
||||
|
||||
unsafe fn read_encoded_pointer(reader: &mut DwarfReader,
|
||||
context: &EHContext,
|
||||
encoding: u8) -> usize {
|
||||
encoding: u8)
|
||||
-> usize {
|
||||
assert!(encoding != DW_EH_PE_omit);
|
||||
|
||||
// DW_EH_PE_aligned implies it's an absolute pointer value
|
||||
if encoding == DW_EH_PE_aligned {
|
||||
reader.ptr = round_up(reader.ptr as usize,
|
||||
mem::size_of::<usize>()) as *const u8;
|
||||
reader.ptr = round_up(reader.ptr as usize, mem::size_of::<usize>()) as *const u8;
|
||||
return reader.read::<usize>();
|
||||
}
|
||||
|
||||
@ -134,20 +133,26 @@ unsafe fn read_encoded_pointer(reader: &mut DwarfReader,
|
||||
DW_EH_PE_sdata2 => reader.read::<i16>() as usize,
|
||||
DW_EH_PE_sdata4 => reader.read::<i32>() as usize,
|
||||
DW_EH_PE_sdata8 => reader.read::<i64>() as usize,
|
||||
_ => panic!()
|
||||
_ => panic!(),
|
||||
};
|
||||
|
||||
result += match encoding & 0x70 {
|
||||
DW_EH_PE_absptr => 0,
|
||||
// relative to address of the encoded value, despite the name
|
||||
DW_EH_PE_pcrel => reader.ptr as usize,
|
||||
DW_EH_PE_textrel => { assert!(context.text_start != 0);
|
||||
context.text_start },
|
||||
DW_EH_PE_datarel => { assert!(context.data_start != 0);
|
||||
context.data_start },
|
||||
DW_EH_PE_funcrel => { assert!(context.func_start != 0);
|
||||
context.func_start },
|
||||
_ => panic!()
|
||||
DW_EH_PE_textrel => {
|
||||
assert!(context.text_start != 0);
|
||||
context.text_start
|
||||
}
|
||||
DW_EH_PE_datarel => {
|
||||
assert!(context.data_start != 0);
|
||||
context.data_start
|
||||
}
|
||||
DW_EH_PE_funcrel => {
|
||||
assert!(context.func_start != 0);
|
||||
context.func_start
|
||||
}
|
||||
_ => panic!(),
|
||||
};
|
||||
|
||||
if encoding & DW_EH_PE_indirect != 0 {
|
||||
|
@ -21,25 +21,22 @@ pub mod eh;
|
||||
use core::mem;
|
||||
|
||||
pub struct DwarfReader {
|
||||
pub ptr : *const u8
|
||||
pub ptr: *const u8,
|
||||
}
|
||||
|
||||
#[repr(C,packed)]
|
||||
struct Unaligned<T>(T);
|
||||
|
||||
impl DwarfReader {
|
||||
|
||||
pub fn new(ptr : *const u8) -> DwarfReader {
|
||||
DwarfReader {
|
||||
ptr : ptr
|
||||
}
|
||||
pub fn new(ptr: *const u8) -> DwarfReader {
|
||||
DwarfReader { ptr: ptr }
|
||||
}
|
||||
|
||||
// DWARF streams are packed, so e.g. a u32 would not necessarily be aligned
|
||||
// on a 4-byte boundary. This may cause problems on platforms with strict
|
||||
// alignment requirements. By wrapping data in a "packed" struct, we are
|
||||
// telling the backend to generate "misalignment-safe" code.
|
||||
pub unsafe fn read<T:Copy>(&mut self) -> T {
|
||||
pub unsafe fn read<T: Copy>(&mut self) -> T {
|
||||
let Unaligned(result) = *(self.ptr as *const Unaligned<T>);
|
||||
self.ptr = self.ptr.offset(mem::size_of::<T>() as isize);
|
||||
result
|
||||
@ -48,9 +45,9 @@ impl DwarfReader {
|
||||
// ULEB128 and SLEB128 encodings are defined in Section 7.6 - "Variable
|
||||
// Length Data".
|
||||
pub unsafe fn read_uleb128(&mut self) -> u64 {
|
||||
let mut shift : usize = 0;
|
||||
let mut result : u64 = 0;
|
||||
let mut byte : u8;
|
||||
let mut shift: usize = 0;
|
||||
let mut result: u64 = 0;
|
||||
let mut byte: u8;
|
||||
loop {
|
||||
byte = self.read::<u8>();
|
||||
result |= ((byte & 0x7F) as u64) << shift;
|
||||
@ -63,9 +60,9 @@ impl DwarfReader {
|
||||
}
|
||||
|
||||
pub unsafe fn read_sleb128(&mut self) -> i64 {
|
||||
let mut shift : usize = 0;
|
||||
let mut result : u64 = 0;
|
||||
let mut byte : u8;
|
||||
let mut shift: usize = 0;
|
||||
let mut result: u64 = 0;
|
||||
let mut byte: u8;
|
||||
loop {
|
||||
byte = self.read::<u8>();
|
||||
result |= ((byte & 0x7F) as u64) << shift;
|
||||
@ -84,12 +81,7 @@ impl DwarfReader {
|
||||
|
||||
#[test]
|
||||
fn dwarf_reader() {
|
||||
let encoded: &[u8] = &[1,
|
||||
2, 3,
|
||||
4, 5, 6, 7,
|
||||
0xE5, 0x8E, 0x26,
|
||||
0x9B, 0xF1, 0x59,
|
||||
0xFF, 0xFF];
|
||||
let encoded: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 0xE5, 0x8E, 0x26, 0x9B, 0xF1, 0x59, 0xFF, 0xFF];
|
||||
|
||||
let mut reader = DwarfReader::new(encoded.as_ptr());
|
||||
|
||||
|
@ -79,8 +79,8 @@ pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
|
||||
let exception_param = Box::into_raw(exception) as *mut uw::_Unwind_Exception;
|
||||
return uw::_Unwind_RaiseException(exception_param) as u32;
|
||||
|
||||
extern fn exception_cleanup(_unwind_code: uw::_Unwind_Reason_Code,
|
||||
exception: *mut uw::_Unwind_Exception) {
|
||||
extern "C" fn exception_cleanup(_unwind_code: uw::_Unwind_Reason_Code,
|
||||
exception: *mut uw::_Unwind_Exception) {
|
||||
unsafe {
|
||||
let _: Box<Exception> = Box::from_raw(exception as *mut Exception);
|
||||
}
|
||||
@ -130,50 +130,41 @@ pub mod eabi {
|
||||
use unwind as uw;
|
||||
use libc::c_int;
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
fn __gcc_personality_v0(version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *mut uw::_Unwind_Exception,
|
||||
context: *mut uw::_Unwind_Context)
|
||||
-> uw::_Unwind_Reason_Code;
|
||||
-> uw::_Unwind_Reason_Code;
|
||||
}
|
||||
|
||||
#[lang = "eh_personality"]
|
||||
#[no_mangle]
|
||||
extern fn rust_eh_personality(
|
||||
version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *mut uw::_Unwind_Exception,
|
||||
context: *mut uw::_Unwind_Context
|
||||
) -> uw::_Unwind_Reason_Code
|
||||
{
|
||||
unsafe {
|
||||
__gcc_personality_v0(version, actions, exception_class, ue_header,
|
||||
context)
|
||||
}
|
||||
extern "C" fn rust_eh_personality(version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *mut uw::_Unwind_Exception,
|
||||
context: *mut uw::_Unwind_Context)
|
||||
-> uw::_Unwind_Reason_Code {
|
||||
unsafe { __gcc_personality_v0(version, actions, exception_class, ue_header, context) }
|
||||
}
|
||||
|
||||
#[lang = "eh_personality_catch"]
|
||||
#[no_mangle]
|
||||
pub extern fn rust_eh_personality_catch(
|
||||
version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *mut uw::_Unwind_Exception,
|
||||
context: *mut uw::_Unwind_Context
|
||||
) -> uw::_Unwind_Reason_Code
|
||||
{
|
||||
pub extern "C" fn rust_eh_personality_catch(version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *mut uw::_Unwind_Exception,
|
||||
context: *mut uw::_Unwind_Context)
|
||||
-> uw::_Unwind_Reason_Code {
|
||||
|
||||
if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
|
||||
if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 {
|
||||
// search phase
|
||||
uw::_URC_HANDLER_FOUND // catch!
|
||||
}
|
||||
else { // cleanup phase
|
||||
unsafe {
|
||||
__gcc_personality_v0(version, actions, exception_class, ue_header,
|
||||
context)
|
||||
}
|
||||
} else {
|
||||
// cleanup phase
|
||||
unsafe { __gcc_personality_v0(version, actions, exception_class, ue_header, context) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -186,49 +177,40 @@ pub mod eabi {
|
||||
use unwind as uw;
|
||||
use libc::c_int;
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
fn __gcc_personality_sj0(version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *mut uw::_Unwind_Exception,
|
||||
context: *mut uw::_Unwind_Context)
|
||||
-> uw::_Unwind_Reason_Code;
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *mut uw::_Unwind_Exception,
|
||||
context: *mut uw::_Unwind_Context)
|
||||
-> uw::_Unwind_Reason_Code;
|
||||
}
|
||||
|
||||
#[lang = "eh_personality"]
|
||||
#[no_mangle]
|
||||
pub extern fn rust_eh_personality(
|
||||
version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *mut uw::_Unwind_Exception,
|
||||
context: *mut uw::_Unwind_Context
|
||||
) -> uw::_Unwind_Reason_Code
|
||||
{
|
||||
unsafe {
|
||||
__gcc_personality_sj0(version, actions, exception_class, ue_header,
|
||||
context)
|
||||
}
|
||||
pub extern "C" fn rust_eh_personality(version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *mut uw::_Unwind_Exception,
|
||||
context: *mut uw::_Unwind_Context)
|
||||
-> uw::_Unwind_Reason_Code {
|
||||
unsafe { __gcc_personality_sj0(version, actions, exception_class, ue_header, context) }
|
||||
}
|
||||
|
||||
#[lang = "eh_personality_catch"]
|
||||
#[no_mangle]
|
||||
pub extern fn rust_eh_personality_catch(
|
||||
version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *mut uw::_Unwind_Exception,
|
||||
context: *mut uw::_Unwind_Context
|
||||
) -> uw::_Unwind_Reason_Code
|
||||
{
|
||||
if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
|
||||
pub extern "C" fn rust_eh_personality_catch(version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *mut uw::_Unwind_Exception,
|
||||
context: *mut uw::_Unwind_Context)
|
||||
-> uw::_Unwind_Reason_Code {
|
||||
if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 {
|
||||
// search phase
|
||||
uw::_URC_HANDLER_FOUND // catch!
|
||||
}
|
||||
else { // cleanup phase
|
||||
unsafe {
|
||||
__gcc_personality_sj0(version, actions, exception_class, ue_header,
|
||||
context)
|
||||
}
|
||||
} else {
|
||||
// cleanup phase
|
||||
unsafe { __gcc_personality_sj0(version, actions, exception_class, ue_header, context) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -241,47 +223,40 @@ pub mod eabi {
|
||||
use unwind as uw;
|
||||
use libc::c_int;
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
fn __gcc_personality_v0(state: uw::_Unwind_State,
|
||||
ue_header: *mut uw::_Unwind_Exception,
|
||||
context: *mut uw::_Unwind_Context)
|
||||
-> uw::_Unwind_Reason_Code;
|
||||
-> uw::_Unwind_Reason_Code;
|
||||
}
|
||||
|
||||
#[lang = "eh_personality"]
|
||||
#[no_mangle]
|
||||
extern fn rust_eh_personality(
|
||||
state: uw::_Unwind_State,
|
||||
ue_header: *mut uw::_Unwind_Exception,
|
||||
context: *mut uw::_Unwind_Context
|
||||
) -> uw::_Unwind_Reason_Code
|
||||
{
|
||||
unsafe {
|
||||
__gcc_personality_v0(state, ue_header, context)
|
||||
}
|
||||
extern "C" fn rust_eh_personality(state: uw::_Unwind_State,
|
||||
ue_header: *mut uw::_Unwind_Exception,
|
||||
context: *mut uw::_Unwind_Context)
|
||||
-> uw::_Unwind_Reason_Code {
|
||||
unsafe { __gcc_personality_v0(state, ue_header, context) }
|
||||
}
|
||||
|
||||
#[lang = "eh_personality_catch"]
|
||||
#[no_mangle]
|
||||
pub extern fn rust_eh_personality_catch(
|
||||
state: uw::_Unwind_State,
|
||||
ue_header: *mut uw::_Unwind_Exception,
|
||||
context: *mut uw::_Unwind_Context
|
||||
) -> uw::_Unwind_Reason_Code
|
||||
{
|
||||
pub extern "C" fn rust_eh_personality_catch(state: uw::_Unwind_State,
|
||||
ue_header: *mut uw::_Unwind_Exception,
|
||||
context: *mut uw::_Unwind_Context)
|
||||
-> uw::_Unwind_Reason_Code {
|
||||
// Backtraces on ARM will call the personality routine with
|
||||
// state == _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND. In those cases
|
||||
// we want to continue unwinding the stack, otherwise all our backtraces
|
||||
// would end at __rust_try.
|
||||
if (state as c_int & uw::_US_ACTION_MASK as c_int)
|
||||
== uw::_US_VIRTUAL_UNWIND_FRAME as c_int
|
||||
&& (state as c_int & uw::_US_FORCE_UNWIND as c_int) == 0 { // search phase
|
||||
if (state as c_int & uw::_US_ACTION_MASK as c_int) ==
|
||||
uw::_US_VIRTUAL_UNWIND_FRAME as c_int &&
|
||||
(state as c_int & uw::_US_FORCE_UNWIND as c_int) == 0 {
|
||||
// search phase
|
||||
uw::_URC_HANDLER_FOUND // catch!
|
||||
}
|
||||
else { // cleanup phase
|
||||
unsafe {
|
||||
__gcc_personality_v0(state, ue_header, context)
|
||||
}
|
||||
} else {
|
||||
// cleanup phase
|
||||
unsafe { __gcc_personality_v0(state, ue_header, context) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -290,7 +265,7 @@ pub mod eabi {
|
||||
#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))]
|
||||
#[lang = "eh_unwind_resume"]
|
||||
#[unwind]
|
||||
unsafe extern fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! {
|
||||
unsafe extern "C" fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! {
|
||||
uw::_Unwind_Resume(panic_ctx as *mut uw::_Unwind_Exception);
|
||||
}
|
||||
|
||||
@ -314,22 +289,21 @@ unsafe extern fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! {
|
||||
pub mod eh_frame_registry {
|
||||
#[link(name = "gcc_eh")]
|
||||
#[cfg(not(cargobuild))]
|
||||
extern {}
|
||||
extern "C" {}
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
fn __register_frame_info(eh_frame_begin: *const u8, object: *mut u8);
|
||||
fn __deregister_frame_info(eh_frame_begin: *const u8, object: *mut u8);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn rust_eh_register_frames(eh_frame_begin: *const u8,
|
||||
object: *mut u8) {
|
||||
pub unsafe extern "C" fn rust_eh_register_frames(eh_frame_begin: *const u8, object: *mut u8) {
|
||||
__register_frame_info(eh_frame_begin, object);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn rust_eh_unregister_frames(eh_frame_begin: *const u8,
|
||||
object: *mut u8) {
|
||||
pub unsafe extern "C" fn rust_eh_unregister_frames(eh_frame_begin: *const u8,
|
||||
object: *mut u8) {
|
||||
__deregister_frame_info(eh_frame_begin, object);
|
||||
}
|
||||
}
|
||||
|
@ -82,11 +82,11 @@ mod windows;
|
||||
// hairy and tightly coupled, for more information see the compiler's
|
||||
// implementation of this.
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8),
|
||||
data: *mut u8,
|
||||
data_ptr: *mut usize,
|
||||
vtable_ptr: *mut usize)
|
||||
-> u32 {
|
||||
pub unsafe extern "C" fn __rust_maybe_catch_panic(f: fn(*mut u8),
|
||||
data: *mut u8,
|
||||
data_ptr: *mut usize,
|
||||
vtable_ptr: *mut usize)
|
||||
-> u32 {
|
||||
let mut payload = imp::payload();
|
||||
if intrinsics::try(f, data, &mut payload as *mut _ as *mut _) == 0 {
|
||||
0
|
||||
@ -101,7 +101,7 @@ pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8),
|
||||
// Entry point for raising an exception, just delegates to the platform-specific
|
||||
// implementation.
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn __rust_start_panic(data: usize, vtable: usize) -> u32 {
|
||||
pub unsafe extern "C" fn __rust_start_panic(data: usize, vtable: usize) -> u32 {
|
||||
imp::panic(mem::transmute(raw::TraitObject {
|
||||
data: data as *mut (),
|
||||
vtable: vtable as *mut (),
|
||||
|
@ -128,7 +128,7 @@ mod imp {
|
||||
pub const NAME1: [u8; 7] = [b'.', b'P', b'E', b'A', b'_', b'K', 0];
|
||||
pub const NAME2: [u8; 7] = [b'.', b'P', b'E', b'A', b'X', 0, 0];
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
pub static __ImageBase: u8;
|
||||
}
|
||||
|
||||
@ -186,10 +186,7 @@ static mut THROW_INFO: _ThrowInfo = _ThrowInfo {
|
||||
|
||||
static mut CATCHABLE_TYPE_ARRAY: _CatchableTypeArray = _CatchableTypeArray {
|
||||
nCatchableTypes: 2,
|
||||
arrayOfCatchableTypes: [
|
||||
ptr!(0),
|
||||
ptr!(0),
|
||||
],
|
||||
arrayOfCatchableTypes: [ptr!(0), ptr!(0)],
|
||||
};
|
||||
|
||||
static mut CATCHABLE_TYPE1: _CatchableType = _CatchableType {
|
||||
@ -216,7 +213,7 @@ static mut CATCHABLE_TYPE2: _CatchableType = _CatchableType {
|
||||
copy_function: ptr!(0),
|
||||
};
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
// The leading `\x01` byte here is actually a magical signal to LLVM to
|
||||
// *not* apply any other mangling like prefixing with a `_` character.
|
||||
//
|
||||
|
@ -32,11 +32,11 @@ use windows as c;
|
||||
const ETYPE: c::DWORD = 0b1110_u32 << 28;
|
||||
const MAGIC: c::DWORD = 0x525354; // "RST"
|
||||
|
||||
const RUST_PANIC: c::DWORD = ETYPE | (1 << 24) | MAGIC;
|
||||
const RUST_PANIC: c::DWORD = ETYPE | (1 << 24) | MAGIC;
|
||||
|
||||
#[repr(C)]
|
||||
struct PanicData {
|
||||
data: Box<Any + Send>
|
||||
data: Box<Any + Send>,
|
||||
}
|
||||
|
||||
pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
|
||||
@ -82,30 +82,29 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send> {
|
||||
|
||||
#[lang = "eh_personality_catch"]
|
||||
#[cfg(not(test))]
|
||||
unsafe extern fn rust_eh_personality_catch(
|
||||
exceptionRecord: *mut c::EXCEPTION_RECORD,
|
||||
establisherFrame: c::LPVOID,
|
||||
contextRecord: *mut c::CONTEXT,
|
||||
dispatcherContext: *mut c::DISPATCHER_CONTEXT
|
||||
) -> c::EXCEPTION_DISPOSITION
|
||||
{
|
||||
rust_eh_personality(exceptionRecord, establisherFrame,
|
||||
contextRecord, dispatcherContext)
|
||||
unsafe extern "C" fn rust_eh_personality_catch(exceptionRecord: *mut c::EXCEPTION_RECORD,
|
||||
establisherFrame: c::LPVOID,
|
||||
contextRecord: *mut c::CONTEXT,
|
||||
dispatcherContext: *mut c::DISPATCHER_CONTEXT)
|
||||
-> c::EXCEPTION_DISPOSITION {
|
||||
rust_eh_personality(exceptionRecord,
|
||||
establisherFrame,
|
||||
contextRecord,
|
||||
dispatcherContext)
|
||||
}
|
||||
|
||||
#[lang = "eh_personality"]
|
||||
#[cfg(not(test))]
|
||||
unsafe extern fn rust_eh_personality(
|
||||
exceptionRecord: *mut c::EXCEPTION_RECORD,
|
||||
establisherFrame: c::LPVOID,
|
||||
contextRecord: *mut c::CONTEXT,
|
||||
dispatcherContext: *mut c::DISPATCHER_CONTEXT
|
||||
) -> c::EXCEPTION_DISPOSITION
|
||||
{
|
||||
unsafe extern "C" fn rust_eh_personality(exceptionRecord: *mut c::EXCEPTION_RECORD,
|
||||
establisherFrame: c::LPVOID,
|
||||
contextRecord: *mut c::CONTEXT,
|
||||
dispatcherContext: *mut c::DISPATCHER_CONTEXT)
|
||||
-> c::EXCEPTION_DISPOSITION {
|
||||
let er = &*exceptionRecord;
|
||||
let dc = &*dispatcherContext;
|
||||
|
||||
if er.ExceptionFlags & c::EXCEPTION_UNWIND == 0 { // we are in the dispatch phase
|
||||
if er.ExceptionFlags & c::EXCEPTION_UNWIND == 0 {
|
||||
// we are in the dispatch phase
|
||||
if er.ExceptionCode == RUST_PANIC {
|
||||
if let Some(lpad) = find_landing_pad(dc) {
|
||||
c::RtlUnwindEx(establisherFrame,
|
||||
@ -122,7 +121,7 @@ unsafe extern fn rust_eh_personality(
|
||||
|
||||
#[lang = "eh_unwind_resume"]
|
||||
#[unwind]
|
||||
unsafe extern fn rust_eh_unwind_resume(panic_ctx: c::LPVOID) -> ! {
|
||||
unsafe extern "C" fn rust_eh_unwind_resume(panic_ctx: c::LPVOID) -> ! {
|
||||
let params = [panic_ctx as c::ULONG_PTR];
|
||||
c::RaiseException(RUST_PANIC,
|
||||
c::EXCEPTION_NONCONTINUABLE,
|
||||
@ -136,7 +135,7 @@ unsafe fn find_landing_pad(dc: &c::DISPATCHER_CONTEXT) -> Option<usize> {
|
||||
ip: dc.ControlPc as usize,
|
||||
func_start: dc.ImageBase as usize + (*dc.FunctionEntry).BeginAddress as usize,
|
||||
text_start: dc.ImageBase as usize,
|
||||
data_start: 0
|
||||
data_start: 0,
|
||||
};
|
||||
eh::find_landing_pad(dc.HandlerData, &eh_ctx)
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
#![allow(dead_code)]
|
||||
#![cfg(windows)]
|
||||
|
||||
use libc::{c_void, c_ulong, c_long, c_ulonglong};
|
||||
use libc::{c_long, c_ulong, c_ulonglong, c_void};
|
||||
|
||||
pub type DWORD = c_ulong;
|
||||
pub type LONG = c_long;
|
||||
@ -25,8 +25,7 @@ pub const EXCEPTION_UNWINDING: DWORD = 0x2; // Unwind is in progress
|
||||
pub const EXCEPTION_EXIT_UNWIND: DWORD = 0x4; // Exit unwind is in progress
|
||||
pub const EXCEPTION_TARGET_UNWIND: DWORD = 0x20; // Target unwind in progress
|
||||
pub const EXCEPTION_COLLIDED_UNWIND: DWORD = 0x40; // Collided exception handler call
|
||||
pub const EXCEPTION_UNWIND: DWORD = EXCEPTION_UNWINDING |
|
||||
EXCEPTION_EXIT_UNWIND |
|
||||
pub const EXCEPTION_UNWIND: DWORD = EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND |
|
||||
EXCEPTION_TARGET_UNWIND |
|
||||
EXCEPTION_COLLIDED_UNWIND;
|
||||
|
||||
@ -37,7 +36,7 @@ pub struct EXCEPTION_RECORD {
|
||||
pub ExceptionRecord: *mut EXCEPTION_RECORD,
|
||||
pub ExceptionAddress: LPVOID,
|
||||
pub NumberParameters: DWORD,
|
||||
pub ExceptionInformation: [LPVOID; EXCEPTION_MAXIMUM_PARAMETERS]
|
||||
pub ExceptionInformation: [LPVOID; EXCEPTION_MAXIMUM_PARAMETERS],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
@ -75,7 +74,7 @@ pub enum EXCEPTION_DISPOSITION {
|
||||
ExceptionContinueExecution,
|
||||
ExceptionContinueSearch,
|
||||
ExceptionNestedException,
|
||||
ExceptionCollidedUnwind
|
||||
ExceptionCollidedUnwind,
|
||||
}
|
||||
pub use self::EXCEPTION_DISPOSITION::*;
|
||||
|
||||
@ -93,6 +92,5 @@ extern "system" {
|
||||
OriginalContext: *const CONTEXT,
|
||||
HistoryTable: *const UNWIND_HISTORY_TABLE);
|
||||
#[unwind]
|
||||
pub fn _CxxThrowException(pExceptionObject: *mut c_void,
|
||||
pThrowInfo: *mut u8);
|
||||
pub fn _CxxThrowException(pExceptionObject: *mut c_void, pThrowInfo: *mut u8);
|
||||
}
|
||||
|
@ -112,7 +112,6 @@ pub struct Options {
|
||||
// with additional crate configurations during the compile process
|
||||
pub crate_types: Vec<CrateType>,
|
||||
|
||||
pub gc: bool,
|
||||
pub optimize: OptLevel,
|
||||
pub debug_assertions: bool,
|
||||
pub debuginfo: DebugInfoLevel,
|
||||
@ -242,7 +241,6 @@ pub fn host_triple() -> &'static str {
|
||||
pub fn basic_options() -> Options {
|
||||
Options {
|
||||
crate_types: Vec::new(),
|
||||
gc: false,
|
||||
optimize: OptLevel::No,
|
||||
debuginfo: NoDebugInfo,
|
||||
lint_opts: Vec::new(),
|
||||
@ -632,14 +630,10 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
|
||||
"omit landing pads for unwinding"),
|
||||
debug_llvm: bool = (false, parse_bool,
|
||||
"enable debug output from LLVM"),
|
||||
count_type_sizes: bool = (false, parse_bool,
|
||||
"count the sizes of aggregate types"),
|
||||
meta_stats: bool = (false, parse_bool,
|
||||
"gather metadata statistics"),
|
||||
print_link_args: bool = (false, parse_bool,
|
||||
"print the arguments passed to the linker"),
|
||||
gc: bool = (false, parse_bool,
|
||||
"garbage collect shared data (experimental)"),
|
||||
print_llvm_passes: bool = (false, parse_bool,
|
||||
"prints the llvm optimization passes being run"),
|
||||
ast_json: bool = (false, parse_bool,
|
||||
@ -1189,7 +1183,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
||||
}
|
||||
};
|
||||
let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
|
||||
let gc = debugging_opts.gc;
|
||||
let debuginfo = if matches.opt_present("g") {
|
||||
if cg.debuginfo.is_some() {
|
||||
early_error(error_format, "-g and -C debuginfo both provided");
|
||||
@ -1272,7 +1265,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
||||
|
||||
Options {
|
||||
crate_types: crate_types,
|
||||
gc: gc,
|
||||
optimize: opt_level,
|
||||
debuginfo: debuginfo,
|
||||
lint_opts: lint_opts,
|
||||
|
@ -284,9 +284,6 @@ impl Session {
|
||||
pub fn count_llvm_insns(&self) -> bool {
|
||||
self.opts.debugging_opts.count_llvm_insns
|
||||
}
|
||||
pub fn count_type_sizes(&self) -> bool {
|
||||
self.opts.debugging_opts.count_type_sizes
|
||||
}
|
||||
pub fn time_llvm_passes(&self) -> bool {
|
||||
self.opts.debugging_opts.time_llvm_passes
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ impl Class {
|
||||
Class::MacroNonTerminal => "macro-nonterminal",
|
||||
Class::String => "string",
|
||||
Class::Number => "number",
|
||||
Class::Bool => "boolvalue",
|
||||
Class::Bool => "bool-val",
|
||||
Class::Ident => "ident",
|
||||
Class::Lifetime => "lifetime",
|
||||
Class::PreludeTy => "prelude-ty",
|
||||
|
@ -554,7 +554,7 @@ td.summary-column {
|
||||
pre.rust .kw { color: #8959A8; }
|
||||
pre.rust .kw-2, pre.rust .prelude-ty { color: #4271AE; }
|
||||
pre.rust .number, pre.rust .string { color: #718C00; }
|
||||
pre.rust .self, pre.rust .boolval, pre.rust .prelude-val,
|
||||
pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val,
|
||||
pre.rust .attribute, pre.rust .attribute .ident { color: #C82829; }
|
||||
pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; }
|
||||
pre.rust .lifetime { color: #B76514; }
|
||||
|
@ -14,6 +14,10 @@
|
||||
#![allow(unknown_features)]
|
||||
#![feature(box_syntax)]
|
||||
|
||||
fn f(_a: isize, _b: isize, _c: Box<isize>) { panic!("moop"); }
|
||||
fn f(_a: isize, _b: isize, _c: Box<isize>) {
|
||||
panic!("moop");
|
||||
}
|
||||
|
||||
fn main() { f(1, panic!("meep"), box 42); }
|
||||
fn main() {
|
||||
f(1, panic!("meep"), box 42);
|
||||
}
|
||||
|
@ -11,5 +11,5 @@
|
||||
// error-pattern:assertion failed: `(left == right)` (left: `14`, right: `15`)
|
||||
|
||||
fn main() {
|
||||
assert_eq!(14,15);
|
||||
assert_eq!(14, 15);
|
||||
}
|
||||
|
@ -9,7 +9,9 @@
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:quux
|
||||
fn foo() -> ! { panic!("quux"); }
|
||||
fn foo() -> ! {
|
||||
panic!("quux");
|
||||
}
|
||||
fn main() {
|
||||
foo() == foo(); // these types wind up being defaulted to ()
|
||||
}
|
||||
|
@ -9,5 +9,10 @@
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:quux
|
||||
fn my_err(s: String) -> ! { println!("{}", s); panic!("quux"); }
|
||||
fn main() { 3_usize == my_err("bye".to_string()); }
|
||||
fn my_err(s: String) -> ! {
|
||||
println!("{}", s);
|
||||
panic!("quux");
|
||||
}
|
||||
fn main() {
|
||||
3_usize == my_err("bye".to_string());
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ fn main() {
|
||||
// address of the 0th cell in the array (even though the index is
|
||||
// huge).
|
||||
|
||||
let x = vec!(1_usize,2_usize,3_usize);
|
||||
let x = vec![1_usize, 2_usize, 3_usize];
|
||||
|
||||
let base = x.as_ptr() as usize;
|
||||
let idx = base / mem::size_of::<usize>();
|
||||
@ -28,7 +28,7 @@ fn main() {
|
||||
println!("ov1 idx = 0x{:x}", idx);
|
||||
println!("ov1 sizeof::<usize>() = 0x{:x}", mem::size_of::<usize>());
|
||||
println!("ov1 idx * sizeof::<usize>() = 0x{:x}",
|
||||
idx * mem::size_of::<usize>());
|
||||
idx * mem::size_of::<usize>());
|
||||
|
||||
// This should panic.
|
||||
println!("ov1 0x{:x}", x[idx]);
|
||||
|
@ -12,7 +12,9 @@
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
fn test00_start(ch: chan_t<isize>, message: isize) { send(ch, message); }
|
||||
fn test00_start(ch: chan_t<isize>, message: isize) {
|
||||
send(ch, message);
|
||||
}
|
||||
|
||||
type task_id = isize;
|
||||
type port_id = isize;
|
||||
@ -23,6 +25,10 @@ struct chan_t<T> {
|
||||
marker: PhantomData<*mut T>,
|
||||
}
|
||||
|
||||
fn send<T:Send>(_ch: chan_t<T>, _data: T) { panic!(); }
|
||||
fn send<T: Send>(_ch: chan_t<T>, _data: T) {
|
||||
panic!();
|
||||
}
|
||||
|
||||
fn main() { panic!("quux"); }
|
||||
fn main() {
|
||||
panic!("quux");
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#![allow(unreachable_code)]
|
||||
|
||||
//error-pattern:One
|
||||
// error-pattern:One
|
||||
fn main() {
|
||||
panic!("One");
|
||||
panic!("Two");
|
||||
|
@ -14,6 +14,8 @@
|
||||
// error-pattern:wooooo
|
||||
fn main() {
|
||||
let mut a = 1;
|
||||
if 1 == 1 { a = 2; }
|
||||
if 1 == 1 {
|
||||
a = 2;
|
||||
}
|
||||
panic!(format!("woooo{}", "o"));
|
||||
}
|
||||
|
@ -12,4 +12,6 @@
|
||||
|
||||
|
||||
// error-pattern:explicit
|
||||
fn main() { panic!(); }
|
||||
fn main() {
|
||||
panic!();
|
||||
}
|
||||
|
@ -10,6 +10,10 @@
|
||||
|
||||
// error-pattern:explicit panic
|
||||
|
||||
fn f() -> ! { panic!() }
|
||||
fn f() -> ! {
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn main() { f(); }
|
||||
fn main() {
|
||||
f();
|
||||
}
|
||||
|
@ -10,8 +10,19 @@
|
||||
|
||||
// error-pattern:explicit panic
|
||||
|
||||
fn f() -> ! { panic!() }
|
||||
fn f() -> ! {
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn g() -> isize { let x = if true { f() } else { 10 }; return x; }
|
||||
fn g() -> isize {
|
||||
let x = if true {
|
||||
f()
|
||||
} else {
|
||||
10
|
||||
};
|
||||
return x;
|
||||
}
|
||||
|
||||
fn main() { g(); }
|
||||
fn main() {
|
||||
g();
|
||||
}
|
||||
|
@ -10,4 +10,12 @@
|
||||
|
||||
// error-pattern:explicit panic
|
||||
|
||||
fn main() { let _x = if false { 0 } else if true { panic!() } else { 10 }; }
|
||||
fn main() {
|
||||
let _x = if false {
|
||||
0
|
||||
} else if true {
|
||||
panic!()
|
||||
} else {
|
||||
10
|
||||
};
|
||||
}
|
||||
|
@ -10,8 +10,18 @@
|
||||
|
||||
// error-pattern:explicit panic
|
||||
|
||||
fn f() -> ! { panic!() }
|
||||
fn f() -> ! {
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn g() -> isize { let x = match true { true => { f() } false => { 10 } }; return x; }
|
||||
fn g() -> isize {
|
||||
let x = match true {
|
||||
true => f(),
|
||||
false => 10,
|
||||
};
|
||||
return x;
|
||||
}
|
||||
|
||||
fn main() { g(); }
|
||||
fn main() {
|
||||
g();
|
||||
}
|
||||
|
@ -10,4 +10,9 @@
|
||||
|
||||
// error-pattern:explicit panic
|
||||
|
||||
fn main() { let _x = match true { false => { 0 } true => { panic!() } }; }
|
||||
fn main() {
|
||||
let _x = match true {
|
||||
false => 0,
|
||||
true => panic!(),
|
||||
};
|
||||
}
|
||||
|
@ -10,4 +10,8 @@
|
||||
|
||||
// error-pattern:moop
|
||||
|
||||
fn main() { for _ in 0_usize..10_usize { panic!("moop"); } }
|
||||
fn main() {
|
||||
for _ in 0_usize..10_usize {
|
||||
panic!("moop");
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,11 @@
|
||||
fn even(x: usize) -> bool {
|
||||
if x < 2 {
|
||||
return false;
|
||||
} else if x == 2 { return true; } else { return even(x - 2); }
|
||||
} else if x == 2 {
|
||||
return true;
|
||||
} else {
|
||||
return even(x - 2);
|
||||
}
|
||||
}
|
||||
|
||||
fn foo(x: usize) {
|
||||
@ -23,4 +27,6 @@ fn foo(x: usize) {
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { foo(3); }
|
||||
fn main() {
|
||||
foo(3);
|
||||
}
|
||||
|
@ -9,5 +9,11 @@
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:quux
|
||||
fn my_err(s: String) -> ! { println!("{}", s); panic!("quux"); }
|
||||
fn main() { if my_err("bye".to_string()) { } }
|
||||
fn my_err(s: String) -> ! {
|
||||
println!("{}", s);
|
||||
panic!("quux");
|
||||
}
|
||||
fn main() {
|
||||
if my_err("bye".to_string()) {
|
||||
}
|
||||
}
|
||||
|
@ -11,5 +11,6 @@
|
||||
// error-pattern:explicit panic
|
||||
|
||||
pub fn main() {
|
||||
panic!(); println!("{}", 1);
|
||||
panic!();
|
||||
println!("{}", 1);
|
||||
}
|
||||
|
@ -20,4 +20,4 @@ fn main() {
|
||||
let pointer = other;
|
||||
pointer();
|
||||
}
|
||||
extern fn other() {}
|
||||
extern "C" fn other() {}
|
||||
|
@ -19,16 +19,13 @@ pub trait Parser {
|
||||
|
||||
impl Parser for () {
|
||||
type Input = ();
|
||||
fn parse(&mut self, input: ()) {
|
||||
|
||||
}
|
||||
fn parse(&mut self, input: ()) {}
|
||||
}
|
||||
|
||||
pub fn many() -> Box<Parser<Input=<() as Parser>::Input> + 'static> {
|
||||
pub fn many() -> Box<Parser<Input = <() as Parser>::Input> + 'static> {
|
||||
panic!("Hello, world!")
|
||||
}
|
||||
|
||||
fn main() {
|
||||
many()
|
||||
.parse(());
|
||||
many().parse(());
|
||||
}
|
||||
|
@ -12,10 +12,14 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
enum e<T> { ee(Arc<T>) }
|
||||
enum e<T> {
|
||||
ee(Arc<T>),
|
||||
}
|
||||
|
||||
fn foo() -> e<isize> {panic!();}
|
||||
fn foo() -> e<isize> {
|
||||
panic!();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _f = foo();
|
||||
let _f = foo();
|
||||
}
|
||||
|
@ -17,9 +17,14 @@ struct Parser<'i: 't, 't>(&'i u8, &'t u8);
|
||||
|
||||
impl<'i, 't> Parser<'i, 't> {
|
||||
fn parse_nested_block<F, T>(&mut self, parse: F) -> Result<T, ()>
|
||||
where for<'tt> F: FnOnce(&mut Parser<'i, 'tt>) -> T { panic!() }
|
||||
where for<'tt> F: FnOnce(&mut Parser<'i, 'tt>) -> T
|
||||
{
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn expect_exhausted(&mut self) -> Result<(), ()> { Ok(()) }
|
||||
fn expect_exhausted(&mut self) -> Result<(), ()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -16,7 +16,7 @@
|
||||
// error-pattern:so long
|
||||
fn main() {
|
||||
let mut x = Vec::new();
|
||||
let y = vec!(3);
|
||||
let y = vec![3];
|
||||
panic!("so long");
|
||||
x.extend(y.into_iter());
|
||||
}
|
||||
|
@ -11,4 +11,6 @@
|
||||
// error-pattern:explicit panic
|
||||
|
||||
fn foo<T>(t: T) {}
|
||||
fn main() { foo(panic!()) }
|
||||
fn main() {
|
||||
foo(panic!())
|
||||
}
|
||||
|
@ -12,9 +12,12 @@
|
||||
|
||||
#![allow(unused_variables)]
|
||||
|
||||
struct Point { x: isize, y: isize }
|
||||
struct Point {
|
||||
x: isize,
|
||||
y: isize,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let origin = Point {x: 0, y: 0};
|
||||
let f: Point = Point {x: (panic!("beep boop")),.. origin};
|
||||
let origin = Point { x: 0, y: 0 };
|
||||
let f: Point = Point { x: (panic!("beep boop")), ..origin };
|
||||
}
|
||||
|
@ -13,10 +13,12 @@
|
||||
#![allow(unreachable_code)]
|
||||
#![allow(unused_variables)]
|
||||
|
||||
fn foo(s: String) { }
|
||||
fn foo(s: String) {}
|
||||
|
||||
fn main() {
|
||||
let i =
|
||||
match Some::<isize>(3) { None::<isize> => { panic!() } Some::<isize>(_) => { panic!() } };
|
||||
let i = match Some::<isize>(3) {
|
||||
None::<isize> => panic!(),
|
||||
Some::<isize>(_) => panic!(),
|
||||
};
|
||||
foo(i);
|
||||
}
|
||||
|
@ -9,6 +9,15 @@
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:quux
|
||||
fn f() -> ! { panic!("quux") }
|
||||
fn g() -> isize { match f() { true => { 1 } false => { 0 } } }
|
||||
fn main() { g(); }
|
||||
fn f() -> ! {
|
||||
panic!("quux")
|
||||
}
|
||||
fn g() -> isize {
|
||||
match f() {
|
||||
true => 1,
|
||||
false => 0,
|
||||
}
|
||||
}
|
||||
fn main() {
|
||||
g();
|
||||
}
|
||||
|
@ -11,10 +11,18 @@
|
||||
// error-pattern:squirrelcupcake
|
||||
fn cmp() -> isize {
|
||||
match (Some('a'), None::<char>) {
|
||||
(Some(_), _) => { panic!("squirrelcupcake"); }
|
||||
(_, Some(_)) => { panic!(); }
|
||||
_ => { panic!("wat"); }
|
||||
(Some(_), _) => {
|
||||
panic!("squirrelcupcake");
|
||||
}
|
||||
(_, Some(_)) => {
|
||||
panic!();
|
||||
}
|
||||
_ => {
|
||||
panic!("wat");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { println!("{}", cmp()); }
|
||||
fn main() {
|
||||
println!("{}", cmp());
|
||||
}
|
||||
|
@ -16,7 +16,15 @@
|
||||
//[foo] error-pattern:bar
|
||||
//[bar] error-pattern:foo
|
||||
|
||||
#[cfg(foo)] fn die() {panic!("foo");}
|
||||
#[cfg(bar)] fn die() {panic!("bar");}
|
||||
#[cfg(foo)]
|
||||
fn die() {
|
||||
panic!("foo");
|
||||
}
|
||||
#[cfg(bar)]
|
||||
fn die() {
|
||||
panic!("bar");
|
||||
}
|
||||
|
||||
fn main() { die(); }
|
||||
fn main() {
|
||||
die();
|
||||
}
|
||||
|
@ -15,7 +15,15 @@
|
||||
//[foo] error-pattern:foo
|
||||
//[bar] error-pattern:bar
|
||||
|
||||
#[cfg(foo)] fn die() {panic!("foo");}
|
||||
#[cfg(bar)] fn die() {panic!("bar");}
|
||||
#[cfg(foo)]
|
||||
fn die() {
|
||||
panic!("foo");
|
||||
}
|
||||
#[cfg(bar)]
|
||||
fn die() {
|
||||
panic!("bar");
|
||||
}
|
||||
|
||||
fn main() { die(); }
|
||||
fn main() {
|
||||
die();
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ impl<'a> Drop for Droppable<'a> {
|
||||
}
|
||||
|
||||
#[rustc_mir]
|
||||
fn mir(){
|
||||
fn mir() {
|
||||
let (mut xv, mut yv) = (false, false);
|
||||
let x = Droppable(&mut xv, 1);
|
||||
let y = Droppable(&mut yv, 2);
|
||||
|
@ -26,7 +26,7 @@ impl<'a> Drop for Droppable<'a> {
|
||||
}
|
||||
|
||||
#[rustc_mir]
|
||||
fn mir<'a>(d: Droppable<'a>){
|
||||
fn mir<'a>(d: Droppable<'a>) {
|
||||
loop {
|
||||
let x = d;
|
||||
break;
|
||||
|
@ -33,7 +33,7 @@ fn may_panic<'a>() -> Droppable<'a> {
|
||||
}
|
||||
|
||||
#[rustc_mir]
|
||||
fn mir<'a>(d: Droppable<'a>){
|
||||
fn mir<'a>(d: Droppable<'a>) {
|
||||
let (mut a, mut b) = (false, false);
|
||||
let y = Droppable(&mut a, 2);
|
||||
let x = [Droppable(&mut b, 1), y, d, may_panic()];
|
||||
|
@ -9,6 +9,10 @@
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:woe
|
||||
fn f(a: isize) { println!("{}", a); }
|
||||
fn f(a: isize) {
|
||||
println!("{}", a);
|
||||
}
|
||||
|
||||
fn main() { f(panic!("woe")); }
|
||||
fn main() {
|
||||
f(panic!("woe"));
|
||||
}
|
||||
|
@ -14,5 +14,5 @@
|
||||
#![feature(box_syntax)]
|
||||
|
||||
fn main() {
|
||||
panic!(box 413 as Box<::std::any::Any+Send>);
|
||||
panic!(box 413 as Box<::std::any::Any + Send>);
|
||||
}
|
||||
|
@ -9,4 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:moop
|
||||
fn main() { panic!("moop"); }
|
||||
fn main() {
|
||||
panic!("moop");
|
||||
}
|
||||
|
@ -13,11 +13,15 @@
|
||||
// error-pattern:oops
|
||||
|
||||
fn bigpanic() {
|
||||
while (panic!("oops")) { if (panic!()) {
|
||||
match (panic!()) { () => {
|
||||
while (panic!("oops")) {
|
||||
if (panic!()) {
|
||||
match (panic!()) {
|
||||
() => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}};
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { bigpanic(); }
|
||||
fn main() {
|
||||
bigpanic();
|
||||
}
|
||||
|
@ -13,8 +13,9 @@
|
||||
use std::thread;
|
||||
|
||||
fn main() {
|
||||
let r: Result<(),_> = thread::spawn(move|| {
|
||||
panic!("test");
|
||||
}).join();
|
||||
let r: Result<(), _> = thread::spawn(move || {
|
||||
panic!("test");
|
||||
})
|
||||
.join();
|
||||
assert!(r.is_ok());
|
||||
}
|
||||
|
@ -13,9 +13,14 @@
|
||||
use std::thread::Builder;
|
||||
|
||||
fn main() {
|
||||
let r: () = Builder::new().name("owned name".to_string()).spawn(move|| {
|
||||
panic!("test");
|
||||
()
|
||||
}).unwrap().join().unwrap();
|
||||
let r: () = Builder::new()
|
||||
.name("owned name".to_string())
|
||||
.spawn(move || {
|
||||
panic!("test");
|
||||
()
|
||||
})
|
||||
.unwrap()
|
||||
.join()
|
||||
.unwrap();
|
||||
panic!();
|
||||
}
|
||||
|
@ -9,4 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:1 == 2
|
||||
fn main() { assert!(1 == 2); }
|
||||
fn main() {
|
||||
assert!(1 == 2);
|
||||
}
|
||||
|
@ -13,5 +13,5 @@
|
||||
use std::result::Result::Err;
|
||||
|
||||
fn main() {
|
||||
println!("{}", Err::<isize,String>("kitty".to_string()).unwrap());
|
||||
println!("{}", Err::<isize, String>("kitty".to_string()).unwrap());
|
||||
}
|
||||
|
@ -15,9 +15,11 @@
|
||||
#![allow(unreachable_code)]
|
||||
#![allow(unused_variables)]
|
||||
|
||||
struct T { t: String }
|
||||
struct T {
|
||||
t: String,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let pth = panic!("bye");
|
||||
let _rs: T = T {t: pth};
|
||||
let _rs: T = T { t: pth };
|
||||
}
|
||||
|
@ -14,8 +14,10 @@
|
||||
// ignore-pretty: does not work well with `--test`
|
||||
|
||||
mod m {
|
||||
pub fn exported() { }
|
||||
pub fn exported() {}
|
||||
|
||||
#[test]
|
||||
fn unexported() { panic!("runned an unexported test"); }
|
||||
fn unexported() {
|
||||
panic!("runned an unexported test");
|
||||
}
|
||||
}
|
||||
|
@ -9,4 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:not yet implemented
|
||||
fn main() { unimplemented!() }
|
||||
fn main() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
@ -10,4 +10,6 @@
|
||||
|
||||
// error-pattern: panic
|
||||
|
||||
fn main() { Box::new(panic!()); }
|
||||
fn main() {
|
||||
Box::new(panic!());
|
||||
}
|
||||
|
@ -9,4 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:internal error: entered unreachable code
|
||||
fn main() { unreachable!() }
|
||||
fn main() {
|
||||
unreachable!()
|
||||
}
|
||||
|
@ -9,4 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:internal error: entered unreachable code: uhoh
|
||||
fn main() { unreachable!("uhoh") }
|
||||
fn main() {
|
||||
unreachable!("uhoh")
|
||||
}
|
||||
|
@ -9,4 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:internal error: entered unreachable code
|
||||
fn main() { unreachable!() }
|
||||
fn main() {
|
||||
unreachable!()
|
||||
}
|
||||
|
@ -10,13 +10,15 @@
|
||||
|
||||
// error-pattern:fail
|
||||
|
||||
fn a() { }
|
||||
fn a() {}
|
||||
|
||||
fn b() { panic!(); }
|
||||
fn b() {
|
||||
panic!();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _x = vec!(0);
|
||||
let _x = vec![0];
|
||||
a();
|
||||
let _y = vec!(0);
|
||||
let _y = vec![0];
|
||||
b();
|
||||
}
|
||||
|
@ -15,10 +15,10 @@ fn build() -> Vec<isize> {
|
||||
panic!();
|
||||
}
|
||||
|
||||
struct Blk { node: Vec<isize> }
|
||||
struct Blk {
|
||||
node: Vec<isize>,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _blk = Blk {
|
||||
node: build()
|
||||
};
|
||||
let _blk = Blk { node: build() };
|
||||
}
|
||||
|
@ -12,18 +12,21 @@
|
||||
|
||||
|
||||
fn build1() -> Vec<isize> {
|
||||
vec!(0,0,0,0,0,0,0)
|
||||
vec![0, 0, 0, 0, 0, 0, 0]
|
||||
}
|
||||
|
||||
fn build2() -> Vec<isize> {
|
||||
panic!();
|
||||
}
|
||||
|
||||
struct Blk { node: Vec<isize> , span: Vec<isize> }
|
||||
struct Blk {
|
||||
node: Vec<isize>,
|
||||
span: Vec<isize>,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _blk = Blk {
|
||||
node: build1(),
|
||||
span: build2()
|
||||
span: build2(),
|
||||
};
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
|
||||
fn main() {
|
||||
let v: Vec<isize> = vec!(10);
|
||||
let v: Vec<isize> = vec![10];
|
||||
let x: usize = 0;
|
||||
assert_eq!(v[x], 10);
|
||||
// Bounds-check panic.
|
||||
|
@ -11,4 +11,11 @@
|
||||
#![allow(while_true)]
|
||||
|
||||
// error-pattern:quux
|
||||
fn main() { let _x: isize = { while true { panic!("quux"); } ; 8 } ; }
|
||||
fn main() {
|
||||
let _x: isize = {
|
||||
while true {
|
||||
panic!("quux");
|
||||
}
|
||||
8
|
||||
};
|
||||
}
|
||||
|
@ -12,5 +12,10 @@
|
||||
|
||||
// error-pattern:giraffe
|
||||
fn main() {
|
||||
panic!({ while true { panic!("giraffe") }; "clandestine" });
|
||||
panic!({
|
||||
while true {
|
||||
panic!("giraffe")
|
||||
}
|
||||
"clandestine"
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user