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
75 changed files with 480 additions and 328 deletions
|
@ -108,7 +108,8 @@ root.
|
||||||
There are large number of options accepted by this script to alter the
|
There are large number of options accepted by this script to alter the
|
||||||
configuration used later in the build process. Some options to note:
|
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`
|
- `--enable-optimize` - Enable optimizations (can be used with `--enable-debug`
|
||||||
to make a debug build with optimizations)
|
to make a debug build with optimizations)
|
||||||
- `--disable-valgrind-rpass` - Don't run tests with valgrind
|
- `--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
|
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
|
building it. The stage1 compiler is a fully functioning compiler and
|
||||||
(probably) will be enough to determine if your change works as expected.
|
(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
|
- `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
|
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
|
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
|
# * tidy - Basic style check, show highest rustc error code and
|
||||||
# the status of language and lib features
|
# the status of language and lib features
|
||||||
# * rustc-stage$(stage) - Only build up to a specific stage
|
# * 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
|
# Then mix in some of these environment variables to harness the
|
||||||
# ultimate power of The Rust Build System.
|
# ultimate power of The Rust Build System.
|
||||||
|
@ -93,6 +95,15 @@
|
||||||
# // Modifying libstd? Use this command to run unit tests just on your change
|
# // Modifying libstd? Use this command to run unit tests just on your change
|
||||||
# make check-stage1-std NO_REBUILD=1 NO_BENCH=1
|
# 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
|
# // Added a run-pass test? Use this to test running your test
|
||||||
# make check-stage1-rpass TESTNAME=my-shiny-new-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)
|
LLVM_VERSION=$($LLVM_CONFIG --version)
|
||||||
|
|
||||||
case $LLVM_VERSION in
|
case $LLVM_VERSION in
|
||||||
(3.[6-8]*)
|
(3.[7-8]*)
|
||||||
msg "found ok version of LLVM: $LLVM_VERSION"
|
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
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -249,7 +249,7 @@ stack backtrace:
|
||||||
If you need to override an already set `RUST_BACKTRACE`,
|
If you need to override an already set `RUST_BACKTRACE`,
|
||||||
in cases when you cannot just unset the variable,
|
in cases when you cannot just unset the variable,
|
||||||
then set it to `0` to avoid getting a backtrace.
|
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
|
```text
|
||||||
$ export RUST_BACKTRACE=1
|
$ export RUST_BACKTRACE=1
|
||||||
|
|
|
@ -380,8 +380,9 @@ the `tests` directory.
|
||||||
|
|
||||||
# The `tests` directory
|
# The `tests` directory
|
||||||
|
|
||||||
To write an integration test, let's make a `tests` directory, and
|
Each file in `tests/*.rs` directory is treated as individual crate.
|
||||||
put a `tests/lib.rs` file inside, with this as its contents:
|
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
|
```rust,ignore
|
||||||
extern crate adder;
|
extern crate adder;
|
||||||
|
@ -394,8 +395,8 @@ fn it_works() {
|
||||||
```
|
```
|
||||||
|
|
||||||
This looks similar to our previous tests, but slightly different. We now have
|
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`
|
an `extern crate adder` at the top. This is because each test in the `tests`
|
||||||
directory are an entirely separate crate, and so we need to import our library.
|
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:
|
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.
|
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
|
Now we have three sections: our previous test is also run, as well as our new
|
||||||
one.
|
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
|
That's all there is to the `tests` directory. The `tests` module isn't needed
|
||||||
here, since the whole thing is focused on tests.
|
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
|
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
|
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
|
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 what the type of something is, Rust doesn’t require you to explicitly type
|
||||||
out.
|
it out.
|
||||||
|
|
||||||
We can add the type if we want to, though. Types come after a colon (`:`):
|
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`.
|
Could not compile `hello_world`.
|
||||||
```
|
```
|
||||||
|
|
||||||
Rust will not let us use a value that has not been initialized. Next, let’s
|
Rust will not let us use a value that has not been initialized.
|
||||||
talk about this stuff we've added to `println!`.
|
|
||||||
|
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
|
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
|
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
|
Additionally, variable bindings can be shadowed. This means that a later
|
||||||
variable binding with the same name as another binding, that's currently in
|
variable binding with the same name as another binding that is currently in
|
||||||
scope, will override the previous binding.
|
scope will override the previous binding.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
let x: i32 = 8;
|
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
|
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
|
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
|
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
|
```rust
|
||||||
let mut x: i32 = 1;
|
let mut x: i32 = 1;
|
||||||
|
|
|
@ -1983,6 +1983,7 @@ macro scope.
|
||||||
|
|
||||||
### Miscellaneous attributes
|
### 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
|
- `export_name` - on statics and functions, this determines the name of the
|
||||||
exported symbol.
|
exported symbol.
|
||||||
- `link_section` - on statics and functions, this specifies the section of the
|
- `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
|
* - `stmt_expr_attributes` - Allows attributes on expressions and
|
||||||
non-item statements.
|
non-item statements.
|
||||||
|
|
||||||
* - `deprecated` - Allows using the `#[deprecated]` attribute.
|
|
||||||
|
|
||||||
* - `type_ascription` - Allows type ascription expressions `expr: Type`.
|
* - `type_ascription` - Allows type ascription expressions `expr: Type`.
|
||||||
|
|
||||||
* - `abi_vectorcall` - Allows the usage of the vectorcall calling convention
|
* - `abi_vectorcall` - Allows the usage of the vectorcall calling convention
|
||||||
|
|
|
@ -229,7 +229,7 @@ a > code {
|
||||||
pre.rust .kw { color: #8959A8; }
|
pre.rust .kw { color: #8959A8; }
|
||||||
pre.rust .kw-2, pre.rust .prelude-ty { color: #4271AE; }
|
pre.rust .kw-2, pre.rust .prelude-ty { color: #4271AE; }
|
||||||
pre.rust .number, pre.rust .string { color: #718C00; }
|
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 .attribute, pre.rust .attribute .ident { color: #C82829; }
|
||||||
pre.rust .comment { color: #8E908C; }
|
pre.rust .comment { color: #8E908C; }
|
||||||
pre.rust .doccomment { color: #4D4D4C; }
|
pre.rust .doccomment { color: #4D4D4C; }
|
||||||
|
|
|
@ -271,7 +271,7 @@ impl<T> Rc<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized> 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
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
|
|
@ -1404,8 +1404,8 @@ impl str {
|
||||||
/// Returns a string slice with all prefixes and suffixes that match a
|
/// Returns a string slice with all prefixes and suffixes that match a
|
||||||
/// pattern repeatedly removed.
|
/// pattern repeatedly removed.
|
||||||
///
|
///
|
||||||
/// The pattern can be a `&str`, [`char`], or a closure that determines
|
/// The pattern can be a [`char`] or a closure that determines if a
|
||||||
/// if a character matches.
|
/// character matches.
|
||||||
///
|
///
|
||||||
/// [`char`]: primitive.char.html
|
/// [`char`]: primitive.char.html
|
||||||
///
|
///
|
||||||
|
|
|
@ -24,36 +24,35 @@
|
||||||
use dwarf::DwarfReader;
|
use dwarf::DwarfReader;
|
||||||
use core::mem;
|
use core::mem;
|
||||||
|
|
||||||
pub const DW_EH_PE_omit : u8 = 0xFF;
|
pub const DW_EH_PE_omit: u8 = 0xFF;
|
||||||
pub const DW_EH_PE_absptr : u8 = 0x00;
|
pub const DW_EH_PE_absptr: u8 = 0x00;
|
||||||
|
|
||||||
pub const DW_EH_PE_uleb128 : u8 = 0x01;
|
pub const DW_EH_PE_uleb128: u8 = 0x01;
|
||||||
pub const DW_EH_PE_udata2 : u8 = 0x02;
|
pub const DW_EH_PE_udata2: u8 = 0x02;
|
||||||
pub const DW_EH_PE_udata4 : u8 = 0x03;
|
pub const DW_EH_PE_udata4: u8 = 0x03;
|
||||||
pub const DW_EH_PE_udata8 : u8 = 0x04;
|
pub const DW_EH_PE_udata8: u8 = 0x04;
|
||||||
pub const DW_EH_PE_sleb128 : u8 = 0x09;
|
pub const DW_EH_PE_sleb128: u8 = 0x09;
|
||||||
pub const DW_EH_PE_sdata2 : u8 = 0x0A;
|
pub const DW_EH_PE_sdata2: u8 = 0x0A;
|
||||||
pub const DW_EH_PE_sdata4 : u8 = 0x0B;
|
pub const DW_EH_PE_sdata4: u8 = 0x0B;
|
||||||
pub const DW_EH_PE_sdata8 : u8 = 0x0C;
|
pub const DW_EH_PE_sdata8: u8 = 0x0C;
|
||||||
|
|
||||||
pub const DW_EH_PE_pcrel : u8 = 0x10;
|
pub const DW_EH_PE_pcrel: u8 = 0x10;
|
||||||
pub const DW_EH_PE_textrel : u8 = 0x20;
|
pub const DW_EH_PE_textrel: u8 = 0x20;
|
||||||
pub const DW_EH_PE_datarel : u8 = 0x30;
|
pub const DW_EH_PE_datarel: u8 = 0x30;
|
||||||
pub const DW_EH_PE_funcrel : u8 = 0x40;
|
pub const DW_EH_PE_funcrel: u8 = 0x40;
|
||||||
pub const DW_EH_PE_aligned : u8 = 0x50;
|
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)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct EHContext {
|
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 func_start: usize, // Address of the current function
|
||||||
pub text_start: usize, // Address of the code section
|
pub text_start: usize, // Address of the code section
|
||||||
pub data_start: usize, // Address of the data section
|
pub data_start: usize, // Address of the data section
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn find_landing_pad(lsda: *const u8, context: &EHContext)
|
pub unsafe fn find_landing_pad(lsda: *const u8, context: &EHContext) -> Option<usize> {
|
||||||
-> Option<usize> {
|
|
||||||
if lsda.is_null() {
|
if lsda.is_null() {
|
||||||
return None;
|
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);
|
let action_table = reader.ptr.offset(call_site_table_length as isize);
|
||||||
// Return addresses point 1 byte past the call instruction, which could
|
// Return addresses point 1 byte past the call instruction, which could
|
||||||
// be in the next IP range.
|
// be in the next IP range.
|
||||||
let ip = context.ip-1;
|
let ip = context.ip - 1;
|
||||||
|
|
||||||
while reader.ptr < action_table {
|
while reader.ptr < action_table {
|
||||||
let cs_start = read_encoded_pointer(&mut reader, context, call_site_encoding);
|
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
|
// Callsite table is sorted by cs_start, so if we've passed the ip, we
|
||||||
// may stop searching.
|
// may stop searching.
|
||||||
if ip < func_start + cs_start {
|
if ip < func_start + cs_start {
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
if ip < func_start + cs_start + cs_len {
|
if ip < func_start + cs_start + cs_len {
|
||||||
if cs_lpad != 0 {
|
if cs_lpad != 0 {
|
||||||
|
@ -114,13 +113,13 @@ fn round_up(unrounded: usize, align: usize) -> usize {
|
||||||
|
|
||||||
unsafe fn read_encoded_pointer(reader: &mut DwarfReader,
|
unsafe fn read_encoded_pointer(reader: &mut DwarfReader,
|
||||||
context: &EHContext,
|
context: &EHContext,
|
||||||
encoding: u8) -> usize {
|
encoding: u8)
|
||||||
|
-> usize {
|
||||||
assert!(encoding != DW_EH_PE_omit);
|
assert!(encoding != DW_EH_PE_omit);
|
||||||
|
|
||||||
// DW_EH_PE_aligned implies it's an absolute pointer value
|
// DW_EH_PE_aligned implies it's an absolute pointer value
|
||||||
if encoding == DW_EH_PE_aligned {
|
if encoding == DW_EH_PE_aligned {
|
||||||
reader.ptr = round_up(reader.ptr as usize,
|
reader.ptr = round_up(reader.ptr as usize, mem::size_of::<usize>()) as *const u8;
|
||||||
mem::size_of::<usize>()) as *const u8;
|
|
||||||
return reader.read::<usize>();
|
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_sdata2 => reader.read::<i16>() as usize,
|
||||||
DW_EH_PE_sdata4 => reader.read::<i32>() as usize,
|
DW_EH_PE_sdata4 => reader.read::<i32>() as usize,
|
||||||
DW_EH_PE_sdata8 => reader.read::<i64>() as usize,
|
DW_EH_PE_sdata8 => reader.read::<i64>() as usize,
|
||||||
_ => panic!()
|
_ => panic!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
result += match encoding & 0x70 {
|
result += match encoding & 0x70 {
|
||||||
DW_EH_PE_absptr => 0,
|
DW_EH_PE_absptr => 0,
|
||||||
// relative to address of the encoded value, despite the name
|
// relative to address of the encoded value, despite the name
|
||||||
DW_EH_PE_pcrel => reader.ptr as usize,
|
DW_EH_PE_pcrel => reader.ptr as usize,
|
||||||
DW_EH_PE_textrel => { assert!(context.text_start != 0);
|
DW_EH_PE_textrel => {
|
||||||
context.text_start },
|
assert!(context.text_start != 0);
|
||||||
DW_EH_PE_datarel => { assert!(context.data_start != 0);
|
context.text_start
|
||||||
context.data_start },
|
}
|
||||||
DW_EH_PE_funcrel => { assert!(context.func_start != 0);
|
DW_EH_PE_datarel => {
|
||||||
context.func_start },
|
assert!(context.data_start != 0);
|
||||||
_ => panic!()
|
context.data_start
|
||||||
|
}
|
||||||
|
DW_EH_PE_funcrel => {
|
||||||
|
assert!(context.func_start != 0);
|
||||||
|
context.func_start
|
||||||
|
}
|
||||||
|
_ => panic!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if encoding & DW_EH_PE_indirect != 0 {
|
if encoding & DW_EH_PE_indirect != 0 {
|
||||||
|
|
|
@ -21,25 +21,22 @@ pub mod eh;
|
||||||
use core::mem;
|
use core::mem;
|
||||||
|
|
||||||
pub struct DwarfReader {
|
pub struct DwarfReader {
|
||||||
pub ptr : *const u8
|
pub ptr: *const u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C,packed)]
|
#[repr(C,packed)]
|
||||||
struct Unaligned<T>(T);
|
struct Unaligned<T>(T);
|
||||||
|
|
||||||
impl DwarfReader {
|
impl DwarfReader {
|
||||||
|
pub fn new(ptr: *const u8) -> DwarfReader {
|
||||||
pub fn new(ptr : *const u8) -> DwarfReader {
|
DwarfReader { ptr: ptr }
|
||||||
DwarfReader {
|
|
||||||
ptr : ptr
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DWARF streams are packed, so e.g. a u32 would not necessarily be aligned
|
// 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
|
// on a 4-byte boundary. This may cause problems on platforms with strict
|
||||||
// alignment requirements. By wrapping data in a "packed" struct, we are
|
// alignment requirements. By wrapping data in a "packed" struct, we are
|
||||||
// telling the backend to generate "misalignment-safe" code.
|
// 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>);
|
let Unaligned(result) = *(self.ptr as *const Unaligned<T>);
|
||||||
self.ptr = self.ptr.offset(mem::size_of::<T>() as isize);
|
self.ptr = self.ptr.offset(mem::size_of::<T>() as isize);
|
||||||
result
|
result
|
||||||
|
@ -48,9 +45,9 @@ impl DwarfReader {
|
||||||
// ULEB128 and SLEB128 encodings are defined in Section 7.6 - "Variable
|
// ULEB128 and SLEB128 encodings are defined in Section 7.6 - "Variable
|
||||||
// Length Data".
|
// Length Data".
|
||||||
pub unsafe fn read_uleb128(&mut self) -> u64 {
|
pub unsafe fn read_uleb128(&mut self) -> u64 {
|
||||||
let mut shift : usize = 0;
|
let mut shift: usize = 0;
|
||||||
let mut result : u64 = 0;
|
let mut result: u64 = 0;
|
||||||
let mut byte : u8;
|
let mut byte: u8;
|
||||||
loop {
|
loop {
|
||||||
byte = self.read::<u8>();
|
byte = self.read::<u8>();
|
||||||
result |= ((byte & 0x7F) as u64) << shift;
|
result |= ((byte & 0x7F) as u64) << shift;
|
||||||
|
@ -63,9 +60,9 @@ impl DwarfReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn read_sleb128(&mut self) -> i64 {
|
pub unsafe fn read_sleb128(&mut self) -> i64 {
|
||||||
let mut shift : usize = 0;
|
let mut shift: usize = 0;
|
||||||
let mut result : u64 = 0;
|
let mut result: u64 = 0;
|
||||||
let mut byte : u8;
|
let mut byte: u8;
|
||||||
loop {
|
loop {
|
||||||
byte = self.read::<u8>();
|
byte = self.read::<u8>();
|
||||||
result |= ((byte & 0x7F) as u64) << shift;
|
result |= ((byte & 0x7F) as u64) << shift;
|
||||||
|
@ -84,12 +81,7 @@ impl DwarfReader {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn dwarf_reader() {
|
fn dwarf_reader() {
|
||||||
let encoded: &[u8] = &[1,
|
let encoded: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 0xE5, 0x8E, 0x26, 0x9B, 0xF1, 0x59, 0xFF, 0xFF];
|
||||||
2, 3,
|
|
||||||
4, 5, 6, 7,
|
|
||||||
0xE5, 0x8E, 0x26,
|
|
||||||
0x9B, 0xF1, 0x59,
|
|
||||||
0xFF, 0xFF];
|
|
||||||
|
|
||||||
let mut reader = DwarfReader::new(encoded.as_ptr());
|
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;
|
let exception_param = Box::into_raw(exception) as *mut uw::_Unwind_Exception;
|
||||||
return uw::_Unwind_RaiseException(exception_param) as u32;
|
return uw::_Unwind_RaiseException(exception_param) as u32;
|
||||||
|
|
||||||
extern fn exception_cleanup(_unwind_code: uw::_Unwind_Reason_Code,
|
extern "C" fn exception_cleanup(_unwind_code: uw::_Unwind_Reason_Code,
|
||||||
exception: *mut uw::_Unwind_Exception) {
|
exception: *mut uw::_Unwind_Exception) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let _: Box<Exception> = Box::from_raw(exception as *mut Exception);
|
let _: Box<Exception> = Box::from_raw(exception as *mut Exception);
|
||||||
}
|
}
|
||||||
|
@ -130,50 +130,41 @@ pub mod eabi {
|
||||||
use unwind as uw;
|
use unwind as uw;
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
fn __gcc_personality_v0(version: c_int,
|
fn __gcc_personality_v0(version: c_int,
|
||||||
actions: uw::_Unwind_Action,
|
actions: uw::_Unwind_Action,
|
||||||
exception_class: uw::_Unwind_Exception_Class,
|
exception_class: uw::_Unwind_Exception_Class,
|
||||||
ue_header: *mut uw::_Unwind_Exception,
|
ue_header: *mut uw::_Unwind_Exception,
|
||||||
context: *mut uw::_Unwind_Context)
|
context: *mut uw::_Unwind_Context)
|
||||||
-> uw::_Unwind_Reason_Code;
|
-> uw::_Unwind_Reason_Code;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "eh_personality"]
|
#[lang = "eh_personality"]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern fn rust_eh_personality(
|
extern "C" fn rust_eh_personality(version: c_int,
|
||||||
version: c_int,
|
actions: uw::_Unwind_Action,
|
||||||
actions: uw::_Unwind_Action,
|
exception_class: uw::_Unwind_Exception_Class,
|
||||||
exception_class: uw::_Unwind_Exception_Class,
|
ue_header: *mut uw::_Unwind_Exception,
|
||||||
ue_header: *mut uw::_Unwind_Exception,
|
context: *mut uw::_Unwind_Context)
|
||||||
context: *mut uw::_Unwind_Context
|
-> uw::_Unwind_Reason_Code {
|
||||||
) -> uw::_Unwind_Reason_Code
|
unsafe { __gcc_personality_v0(version, actions, exception_class, ue_header, context) }
|
||||||
{
|
|
||||||
unsafe {
|
|
||||||
__gcc_personality_v0(version, actions, exception_class, ue_header,
|
|
||||||
context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "eh_personality_catch"]
|
#[lang = "eh_personality_catch"]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn rust_eh_personality_catch(
|
pub extern "C" fn rust_eh_personality_catch(version: c_int,
|
||||||
version: c_int,
|
actions: uw::_Unwind_Action,
|
||||||
actions: uw::_Unwind_Action,
|
exception_class: uw::_Unwind_Exception_Class,
|
||||||
exception_class: uw::_Unwind_Exception_Class,
|
ue_header: *mut uw::_Unwind_Exception,
|
||||||
ue_header: *mut uw::_Unwind_Exception,
|
context: *mut uw::_Unwind_Context)
|
||||||
context: *mut uw::_Unwind_Context
|
-> uw::_Unwind_Reason_Code {
|
||||||
) -> 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!
|
uw::_URC_HANDLER_FOUND // catch!
|
||||||
}
|
} else {
|
||||||
else { // cleanup phase
|
// cleanup phase
|
||||||
unsafe {
|
unsafe { __gcc_personality_v0(version, actions, exception_class, ue_header, context) }
|
||||||
__gcc_personality_v0(version, actions, exception_class, ue_header,
|
|
||||||
context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,49 +177,40 @@ pub mod eabi {
|
||||||
use unwind as uw;
|
use unwind as uw;
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
fn __gcc_personality_sj0(version: c_int,
|
fn __gcc_personality_sj0(version: c_int,
|
||||||
actions: uw::_Unwind_Action,
|
actions: uw::_Unwind_Action,
|
||||||
exception_class: uw::_Unwind_Exception_Class,
|
exception_class: uw::_Unwind_Exception_Class,
|
||||||
ue_header: *mut uw::_Unwind_Exception,
|
ue_header: *mut uw::_Unwind_Exception,
|
||||||
context: *mut uw::_Unwind_Context)
|
context: *mut uw::_Unwind_Context)
|
||||||
-> uw::_Unwind_Reason_Code;
|
-> uw::_Unwind_Reason_Code;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "eh_personality"]
|
#[lang = "eh_personality"]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn rust_eh_personality(
|
pub extern "C" fn rust_eh_personality(version: c_int,
|
||||||
version: c_int,
|
actions: uw::_Unwind_Action,
|
||||||
actions: uw::_Unwind_Action,
|
exception_class: uw::_Unwind_Exception_Class,
|
||||||
exception_class: uw::_Unwind_Exception_Class,
|
ue_header: *mut uw::_Unwind_Exception,
|
||||||
ue_header: *mut uw::_Unwind_Exception,
|
context: *mut uw::_Unwind_Context)
|
||||||
context: *mut uw::_Unwind_Context
|
-> uw::_Unwind_Reason_Code {
|
||||||
) -> uw::_Unwind_Reason_Code
|
unsafe { __gcc_personality_sj0(version, actions, exception_class, ue_header, context) }
|
||||||
{
|
|
||||||
unsafe {
|
|
||||||
__gcc_personality_sj0(version, actions, exception_class, ue_header,
|
|
||||||
context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "eh_personality_catch"]
|
#[lang = "eh_personality_catch"]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn rust_eh_personality_catch(
|
pub extern "C" fn rust_eh_personality_catch(version: c_int,
|
||||||
version: c_int,
|
actions: uw::_Unwind_Action,
|
||||||
actions: uw::_Unwind_Action,
|
exception_class: uw::_Unwind_Exception_Class,
|
||||||
exception_class: uw::_Unwind_Exception_Class,
|
ue_header: *mut uw::_Unwind_Exception,
|
||||||
ue_header: *mut uw::_Unwind_Exception,
|
context: *mut uw::_Unwind_Context)
|
||||||
context: *mut uw::_Unwind_Context
|
-> uw::_Unwind_Reason_Code {
|
||||||
) -> 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!
|
uw::_URC_HANDLER_FOUND // catch!
|
||||||
}
|
} else {
|
||||||
else { // cleanup phase
|
// cleanup phase
|
||||||
unsafe {
|
unsafe { __gcc_personality_sj0(version, actions, exception_class, ue_header, context) }
|
||||||
__gcc_personality_sj0(version, actions, exception_class, ue_header,
|
|
||||||
context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,47 +223,40 @@ pub mod eabi {
|
||||||
use unwind as uw;
|
use unwind as uw;
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
fn __gcc_personality_v0(state: uw::_Unwind_State,
|
fn __gcc_personality_v0(state: uw::_Unwind_State,
|
||||||
ue_header: *mut uw::_Unwind_Exception,
|
ue_header: *mut uw::_Unwind_Exception,
|
||||||
context: *mut uw::_Unwind_Context)
|
context: *mut uw::_Unwind_Context)
|
||||||
-> uw::_Unwind_Reason_Code;
|
-> uw::_Unwind_Reason_Code;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "eh_personality"]
|
#[lang = "eh_personality"]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern fn rust_eh_personality(
|
extern "C" fn rust_eh_personality(state: uw::_Unwind_State,
|
||||||
state: uw::_Unwind_State,
|
ue_header: *mut uw::_Unwind_Exception,
|
||||||
ue_header: *mut uw::_Unwind_Exception,
|
context: *mut uw::_Unwind_Context)
|
||||||
context: *mut uw::_Unwind_Context
|
-> uw::_Unwind_Reason_Code {
|
||||||
) -> uw::_Unwind_Reason_Code
|
unsafe { __gcc_personality_v0(state, ue_header, context) }
|
||||||
{
|
|
||||||
unsafe {
|
|
||||||
__gcc_personality_v0(state, ue_header, context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "eh_personality_catch"]
|
#[lang = "eh_personality_catch"]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn rust_eh_personality_catch(
|
pub extern "C" fn rust_eh_personality_catch(state: uw::_Unwind_State,
|
||||||
state: uw::_Unwind_State,
|
ue_header: *mut uw::_Unwind_Exception,
|
||||||
ue_header: *mut uw::_Unwind_Exception,
|
context: *mut uw::_Unwind_Context)
|
||||||
context: *mut uw::_Unwind_Context
|
-> uw::_Unwind_Reason_Code {
|
||||||
) -> uw::_Unwind_Reason_Code
|
|
||||||
{
|
|
||||||
// Backtraces on ARM will call the personality routine with
|
// Backtraces on ARM will call the personality routine with
|
||||||
// state == _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND. In those cases
|
// state == _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND. In those cases
|
||||||
// we want to continue unwinding the stack, otherwise all our backtraces
|
// we want to continue unwinding the stack, otherwise all our backtraces
|
||||||
// would end at __rust_try.
|
// would end at __rust_try.
|
||||||
if (state as c_int & uw::_US_ACTION_MASK as c_int)
|
if (state as c_int & uw::_US_ACTION_MASK as c_int) ==
|
||||||
== uw::_US_VIRTUAL_UNWIND_FRAME 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
|
(state as c_int & uw::_US_FORCE_UNWIND as c_int) == 0 {
|
||||||
|
// search phase
|
||||||
uw::_URC_HANDLER_FOUND // catch!
|
uw::_URC_HANDLER_FOUND // catch!
|
||||||
}
|
} else {
|
||||||
else { // cleanup phase
|
// cleanup phase
|
||||||
unsafe {
|
unsafe { __gcc_personality_v0(state, ue_header, context) }
|
||||||
__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"))]
|
#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))]
|
||||||
#[lang = "eh_unwind_resume"]
|
#[lang = "eh_unwind_resume"]
|
||||||
#[unwind]
|
#[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);
|
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 {
|
pub mod eh_frame_registry {
|
||||||
#[link(name = "gcc_eh")]
|
#[link(name = "gcc_eh")]
|
||||||
#[cfg(not(cargobuild))]
|
#[cfg(not(cargobuild))]
|
||||||
extern {}
|
extern "C" {}
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
fn __register_frame_info(eh_frame_begin: *const u8, object: *mut u8);
|
fn __register_frame_info(eh_frame_begin: *const u8, object: *mut u8);
|
||||||
fn __deregister_frame_info(eh_frame_begin: *const u8, object: *mut u8);
|
fn __deregister_frame_info(eh_frame_begin: *const u8, object: *mut u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern fn rust_eh_register_frames(eh_frame_begin: *const u8,
|
pub unsafe extern "C" fn rust_eh_register_frames(eh_frame_begin: *const u8, object: *mut u8) {
|
||||||
object: *mut u8) {
|
|
||||||
__register_frame_info(eh_frame_begin, object);
|
__register_frame_info(eh_frame_begin, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern fn rust_eh_unregister_frames(eh_frame_begin: *const u8,
|
pub unsafe extern "C" fn rust_eh_unregister_frames(eh_frame_begin: *const u8,
|
||||||
object: *mut u8) {
|
object: *mut u8) {
|
||||||
__deregister_frame_info(eh_frame_begin, object);
|
__deregister_frame_info(eh_frame_begin, object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,11 +82,11 @@ mod windows;
|
||||||
// hairy and tightly coupled, for more information see the compiler's
|
// hairy and tightly coupled, for more information see the compiler's
|
||||||
// implementation of this.
|
// implementation of this.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8),
|
pub unsafe extern "C" fn __rust_maybe_catch_panic(f: fn(*mut u8),
|
||||||
data: *mut u8,
|
data: *mut u8,
|
||||||
data_ptr: *mut usize,
|
data_ptr: *mut usize,
|
||||||
vtable_ptr: *mut usize)
|
vtable_ptr: *mut usize)
|
||||||
-> u32 {
|
-> u32 {
|
||||||
let mut payload = imp::payload();
|
let mut payload = imp::payload();
|
||||||
if intrinsics::try(f, data, &mut payload as *mut _ as *mut _) == 0 {
|
if intrinsics::try(f, data, &mut payload as *mut _ as *mut _) == 0 {
|
||||||
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
|
// Entry point for raising an exception, just delegates to the platform-specific
|
||||||
// implementation.
|
// implementation.
|
||||||
#[no_mangle]
|
#[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 {
|
imp::panic(mem::transmute(raw::TraitObject {
|
||||||
data: data as *mut (),
|
data: data as *mut (),
|
||||||
vtable: vtable 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 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];
|
pub const NAME2: [u8; 7] = [b'.', b'P', b'E', b'A', b'X', 0, 0];
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
pub static __ImageBase: u8;
|
pub static __ImageBase: u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,10 +186,7 @@ static mut THROW_INFO: _ThrowInfo = _ThrowInfo {
|
||||||
|
|
||||||
static mut CATCHABLE_TYPE_ARRAY: _CatchableTypeArray = _CatchableTypeArray {
|
static mut CATCHABLE_TYPE_ARRAY: _CatchableTypeArray = _CatchableTypeArray {
|
||||||
nCatchableTypes: 2,
|
nCatchableTypes: 2,
|
||||||
arrayOfCatchableTypes: [
|
arrayOfCatchableTypes: [ptr!(0), ptr!(0)],
|
||||||
ptr!(0),
|
|
||||||
ptr!(0),
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static mut CATCHABLE_TYPE1: _CatchableType = _CatchableType {
|
static mut CATCHABLE_TYPE1: _CatchableType = _CatchableType {
|
||||||
|
@ -216,7 +213,7 @@ static mut CATCHABLE_TYPE2: _CatchableType = _CatchableType {
|
||||||
copy_function: ptr!(0),
|
copy_function: ptr!(0),
|
||||||
};
|
};
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
// The leading `\x01` byte here is actually a magical signal to LLVM to
|
// The leading `\x01` byte here is actually a magical signal to LLVM to
|
||||||
// *not* apply any other mangling like prefixing with a `_` character.
|
// *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 ETYPE: c::DWORD = 0b1110_u32 << 28;
|
||||||
const MAGIC: c::DWORD = 0x525354; // "RST"
|
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)]
|
#[repr(C)]
|
||||||
struct PanicData {
|
struct PanicData {
|
||||||
data: Box<Any + Send>
|
data: Box<Any + Send>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
|
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"]
|
#[lang = "eh_personality_catch"]
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
unsafe extern fn rust_eh_personality_catch(
|
unsafe extern "C" fn rust_eh_personality_catch(exceptionRecord: *mut c::EXCEPTION_RECORD,
|
||||||
exceptionRecord: *mut c::EXCEPTION_RECORD,
|
establisherFrame: c::LPVOID,
|
||||||
establisherFrame: c::LPVOID,
|
contextRecord: *mut c::CONTEXT,
|
||||||
contextRecord: *mut c::CONTEXT,
|
dispatcherContext: *mut c::DISPATCHER_CONTEXT)
|
||||||
dispatcherContext: *mut c::DISPATCHER_CONTEXT
|
-> c::EXCEPTION_DISPOSITION {
|
||||||
) -> c::EXCEPTION_DISPOSITION
|
rust_eh_personality(exceptionRecord,
|
||||||
{
|
establisherFrame,
|
||||||
rust_eh_personality(exceptionRecord, establisherFrame,
|
contextRecord,
|
||||||
contextRecord, dispatcherContext)
|
dispatcherContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "eh_personality"]
|
#[lang = "eh_personality"]
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
unsafe extern fn rust_eh_personality(
|
unsafe extern "C" fn rust_eh_personality(exceptionRecord: *mut c::EXCEPTION_RECORD,
|
||||||
exceptionRecord: *mut c::EXCEPTION_RECORD,
|
establisherFrame: c::LPVOID,
|
||||||
establisherFrame: c::LPVOID,
|
contextRecord: *mut c::CONTEXT,
|
||||||
contextRecord: *mut c::CONTEXT,
|
dispatcherContext: *mut c::DISPATCHER_CONTEXT)
|
||||||
dispatcherContext: *mut c::DISPATCHER_CONTEXT
|
-> c::EXCEPTION_DISPOSITION {
|
||||||
) -> c::EXCEPTION_DISPOSITION
|
|
||||||
{
|
|
||||||
let er = &*exceptionRecord;
|
let er = &*exceptionRecord;
|
||||||
let dc = &*dispatcherContext;
|
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 er.ExceptionCode == RUST_PANIC {
|
||||||
if let Some(lpad) = find_landing_pad(dc) {
|
if let Some(lpad) = find_landing_pad(dc) {
|
||||||
c::RtlUnwindEx(establisherFrame,
|
c::RtlUnwindEx(establisherFrame,
|
||||||
|
@ -122,7 +121,7 @@ unsafe extern fn rust_eh_personality(
|
||||||
|
|
||||||
#[lang = "eh_unwind_resume"]
|
#[lang = "eh_unwind_resume"]
|
||||||
#[unwind]
|
#[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];
|
let params = [panic_ctx as c::ULONG_PTR];
|
||||||
c::RaiseException(RUST_PANIC,
|
c::RaiseException(RUST_PANIC,
|
||||||
c::EXCEPTION_NONCONTINUABLE,
|
c::EXCEPTION_NONCONTINUABLE,
|
||||||
|
@ -136,7 +135,7 @@ unsafe fn find_landing_pad(dc: &c::DISPATCHER_CONTEXT) -> Option<usize> {
|
||||||
ip: dc.ControlPc as usize,
|
ip: dc.ControlPc as usize,
|
||||||
func_start: dc.ImageBase as usize + (*dc.FunctionEntry).BeginAddress as usize,
|
func_start: dc.ImageBase as usize + (*dc.FunctionEntry).BeginAddress as usize,
|
||||||
text_start: dc.ImageBase as usize,
|
text_start: dc.ImageBase as usize,
|
||||||
data_start: 0
|
data_start: 0,
|
||||||
};
|
};
|
||||||
eh::find_landing_pad(dc.HandlerData, &eh_ctx)
|
eh::find_landing_pad(dc.HandlerData, &eh_ctx)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
#![cfg(windows)]
|
#![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 DWORD = c_ulong;
|
||||||
pub type LONG = c_long;
|
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_EXIT_UNWIND: DWORD = 0x4; // Exit unwind is in progress
|
||||||
pub const EXCEPTION_TARGET_UNWIND: DWORD = 0x20; // Target unwind 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_COLLIDED_UNWIND: DWORD = 0x40; // Collided exception handler call
|
||||||
pub const EXCEPTION_UNWIND: DWORD = EXCEPTION_UNWINDING |
|
pub const EXCEPTION_UNWIND: DWORD = EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND |
|
||||||
EXCEPTION_EXIT_UNWIND |
|
|
||||||
EXCEPTION_TARGET_UNWIND |
|
EXCEPTION_TARGET_UNWIND |
|
||||||
EXCEPTION_COLLIDED_UNWIND;
|
EXCEPTION_COLLIDED_UNWIND;
|
||||||
|
|
||||||
|
@ -37,7 +36,7 @@ pub struct EXCEPTION_RECORD {
|
||||||
pub ExceptionRecord: *mut EXCEPTION_RECORD,
|
pub ExceptionRecord: *mut EXCEPTION_RECORD,
|
||||||
pub ExceptionAddress: LPVOID,
|
pub ExceptionAddress: LPVOID,
|
||||||
pub NumberParameters: DWORD,
|
pub NumberParameters: DWORD,
|
||||||
pub ExceptionInformation: [LPVOID; EXCEPTION_MAXIMUM_PARAMETERS]
|
pub ExceptionInformation: [LPVOID; EXCEPTION_MAXIMUM_PARAMETERS],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -75,7 +74,7 @@ pub enum EXCEPTION_DISPOSITION {
|
||||||
ExceptionContinueExecution,
|
ExceptionContinueExecution,
|
||||||
ExceptionContinueSearch,
|
ExceptionContinueSearch,
|
||||||
ExceptionNestedException,
|
ExceptionNestedException,
|
||||||
ExceptionCollidedUnwind
|
ExceptionCollidedUnwind,
|
||||||
}
|
}
|
||||||
pub use self::EXCEPTION_DISPOSITION::*;
|
pub use self::EXCEPTION_DISPOSITION::*;
|
||||||
|
|
||||||
|
@ -93,6 +92,5 @@ extern "system" {
|
||||||
OriginalContext: *const CONTEXT,
|
OriginalContext: *const CONTEXT,
|
||||||
HistoryTable: *const UNWIND_HISTORY_TABLE);
|
HistoryTable: *const UNWIND_HISTORY_TABLE);
|
||||||
#[unwind]
|
#[unwind]
|
||||||
pub fn _CxxThrowException(pExceptionObject: *mut c_void,
|
pub fn _CxxThrowException(pExceptionObject: *mut c_void, pThrowInfo: *mut u8);
|
||||||
pThrowInfo: *mut u8);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,6 @@ pub struct Options {
|
||||||
// with additional crate configurations during the compile process
|
// with additional crate configurations during the compile process
|
||||||
pub crate_types: Vec<CrateType>,
|
pub crate_types: Vec<CrateType>,
|
||||||
|
|
||||||
pub gc: bool,
|
|
||||||
pub optimize: OptLevel,
|
pub optimize: OptLevel,
|
||||||
pub debug_assertions: bool,
|
pub debug_assertions: bool,
|
||||||
pub debuginfo: DebugInfoLevel,
|
pub debuginfo: DebugInfoLevel,
|
||||||
|
@ -242,7 +241,6 @@ pub fn host_triple() -> &'static str {
|
||||||
pub fn basic_options() -> Options {
|
pub fn basic_options() -> Options {
|
||||||
Options {
|
Options {
|
||||||
crate_types: Vec::new(),
|
crate_types: Vec::new(),
|
||||||
gc: false,
|
|
||||||
optimize: OptLevel::No,
|
optimize: OptLevel::No,
|
||||||
debuginfo: NoDebugInfo,
|
debuginfo: NoDebugInfo,
|
||||||
lint_opts: Vec::new(),
|
lint_opts: Vec::new(),
|
||||||
|
@ -632,14 +630,10 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
|
||||||
"omit landing pads for unwinding"),
|
"omit landing pads for unwinding"),
|
||||||
debug_llvm: bool = (false, parse_bool,
|
debug_llvm: bool = (false, parse_bool,
|
||||||
"enable debug output from LLVM"),
|
"enable debug output from LLVM"),
|
||||||
count_type_sizes: bool = (false, parse_bool,
|
|
||||||
"count the sizes of aggregate types"),
|
|
||||||
meta_stats: bool = (false, parse_bool,
|
meta_stats: bool = (false, parse_bool,
|
||||||
"gather metadata statistics"),
|
"gather metadata statistics"),
|
||||||
print_link_args: bool = (false, parse_bool,
|
print_link_args: bool = (false, parse_bool,
|
||||||
"print the arguments passed to the linker"),
|
"print the arguments passed to the linker"),
|
||||||
gc: bool = (false, parse_bool,
|
|
||||||
"garbage collect shared data (experimental)"),
|
|
||||||
print_llvm_passes: bool = (false, parse_bool,
|
print_llvm_passes: bool = (false, parse_bool,
|
||||||
"prints the llvm optimization passes being run"),
|
"prints the llvm optimization passes being run"),
|
||||||
ast_json: bool = (false, parse_bool,
|
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 debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
|
||||||
let gc = debugging_opts.gc;
|
|
||||||
let debuginfo = if matches.opt_present("g") {
|
let debuginfo = if matches.opt_present("g") {
|
||||||
if cg.debuginfo.is_some() {
|
if cg.debuginfo.is_some() {
|
||||||
early_error(error_format, "-g and -C debuginfo both provided");
|
early_error(error_format, "-g and -C debuginfo both provided");
|
||||||
|
@ -1272,7 +1265,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
||||||
|
|
||||||
Options {
|
Options {
|
||||||
crate_types: crate_types,
|
crate_types: crate_types,
|
||||||
gc: gc,
|
|
||||||
optimize: opt_level,
|
optimize: opt_level,
|
||||||
debuginfo: debuginfo,
|
debuginfo: debuginfo,
|
||||||
lint_opts: lint_opts,
|
lint_opts: lint_opts,
|
||||||
|
|
|
@ -284,9 +284,6 @@ impl Session {
|
||||||
pub fn count_llvm_insns(&self) -> bool {
|
pub fn count_llvm_insns(&self) -> bool {
|
||||||
self.opts.debugging_opts.count_llvm_insns
|
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 {
|
pub fn time_llvm_passes(&self) -> bool {
|
||||||
self.opts.debugging_opts.time_llvm_passes
|
self.opts.debugging_opts.time_llvm_passes
|
||||||
}
|
}
|
||||||
|
|
|
@ -337,7 +337,7 @@ impl Class {
|
||||||
Class::MacroNonTerminal => "macro-nonterminal",
|
Class::MacroNonTerminal => "macro-nonterminal",
|
||||||
Class::String => "string",
|
Class::String => "string",
|
||||||
Class::Number => "number",
|
Class::Number => "number",
|
||||||
Class::Bool => "boolvalue",
|
Class::Bool => "bool-val",
|
||||||
Class::Ident => "ident",
|
Class::Ident => "ident",
|
||||||
Class::Lifetime => "lifetime",
|
Class::Lifetime => "lifetime",
|
||||||
Class::PreludeTy => "prelude-ty",
|
Class::PreludeTy => "prelude-ty",
|
||||||
|
|
|
@ -554,7 +554,7 @@ td.summary-column {
|
||||||
pre.rust .kw { color: #8959A8; }
|
pre.rust .kw { color: #8959A8; }
|
||||||
pre.rust .kw-2, pre.rust .prelude-ty { color: #4271AE; }
|
pre.rust .kw-2, pre.rust .prelude-ty { color: #4271AE; }
|
||||||
pre.rust .number, pre.rust .string { color: #718C00; }
|
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 .attribute, pre.rust .attribute .ident { color: #C82829; }
|
||||||
pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; }
|
pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; }
|
||||||
pre.rust .lifetime { color: #B76514; }
|
pre.rust .lifetime { color: #B76514; }
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
#![allow(unknown_features)]
|
#![allow(unknown_features)]
|
||||||
#![feature(box_syntax)]
|
#![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`)
|
// error-pattern:assertion failed: `(left == right)` (left: `14`, right: `15`)
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assert_eq!(14,15);
|
assert_eq!(14, 15);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,9 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern:quux
|
// error-pattern:quux
|
||||||
fn foo() -> ! { panic!("quux"); }
|
fn foo() -> ! {
|
||||||
|
panic!("quux");
|
||||||
|
}
|
||||||
fn main() {
|
fn main() {
|
||||||
foo() == foo(); // these types wind up being defaulted to ()
|
foo() == foo(); // these types wind up being defaulted to ()
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,5 +9,10 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern:quux
|
// error-pattern:quux
|
||||||
fn my_err(s: String) -> ! { println!("{}", s); panic!("quux"); }
|
fn my_err(s: String) -> ! {
|
||||||
fn main() { 3_usize == my_err("bye".to_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
|
// address of the 0th cell in the array (even though the index is
|
||||||
// huge).
|
// 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 base = x.as_ptr() as usize;
|
||||||
let idx = base / mem::size_of::<usize>();
|
let idx = base / mem::size_of::<usize>();
|
||||||
|
@ -28,7 +28,7 @@ fn main() {
|
||||||
println!("ov1 idx = 0x{:x}", idx);
|
println!("ov1 idx = 0x{:x}", idx);
|
||||||
println!("ov1 sizeof::<usize>() = 0x{:x}", mem::size_of::<usize>());
|
println!("ov1 sizeof::<usize>() = 0x{:x}", mem::size_of::<usize>());
|
||||||
println!("ov1 idx * sizeof::<usize>() = 0x{:x}",
|
println!("ov1 idx * sizeof::<usize>() = 0x{:x}",
|
||||||
idx * mem::size_of::<usize>());
|
idx * mem::size_of::<usize>());
|
||||||
|
|
||||||
// This should panic.
|
// This should panic.
|
||||||
println!("ov1 0x{:x}", x[idx]);
|
println!("ov1 0x{:x}", x[idx]);
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
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 task_id = isize;
|
||||||
type port_id = isize;
|
type port_id = isize;
|
||||||
|
@ -23,6 +25,10 @@ struct chan_t<T> {
|
||||||
marker: PhantomData<*mut 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)]
|
#![allow(unreachable_code)]
|
||||||
|
|
||||||
//error-pattern:One
|
// error-pattern:One
|
||||||
fn main() {
|
fn main() {
|
||||||
panic!("One");
|
panic!("One");
|
||||||
panic!("Two");
|
panic!("Two");
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
// error-pattern:wooooo
|
// error-pattern:wooooo
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut a = 1;
|
let mut a = 1;
|
||||||
if 1 == 1 { a = 2; }
|
if 1 == 1 {
|
||||||
|
a = 2;
|
||||||
|
}
|
||||||
panic!(format!("woooo{}", "o"));
|
panic!(format!("woooo{}", "o"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,4 +12,6 @@
|
||||||
|
|
||||||
|
|
||||||
// error-pattern:explicit
|
// error-pattern:explicit
|
||||||
fn main() { panic!(); }
|
fn main() {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
|
|
@ -10,6 +10,10 @@
|
||||||
|
|
||||||
// error-pattern:explicit panic
|
// error-pattern:explicit panic
|
||||||
|
|
||||||
fn f() -> ! { panic!() }
|
fn f() -> ! {
|
||||||
|
panic!()
|
||||||
|
}
|
||||||
|
|
||||||
fn main() { f(); }
|
fn main() {
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
|
|
@ -10,8 +10,19 @@
|
||||||
|
|
||||||
// error-pattern:explicit panic
|
// 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
|
// 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
|
// 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
|
// 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
|
// 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 {
|
fn even(x: usize) -> bool {
|
||||||
if x < 2 {
|
if x < 2 {
|
||||||
return false;
|
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) {
|
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.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern:quux
|
// error-pattern:quux
|
||||||
fn my_err(s: String) -> ! { println!("{}", s); panic!("quux"); }
|
fn my_err(s: String) -> ! {
|
||||||
fn main() { if my_err("bye".to_string()) { } }
|
println!("{}", s);
|
||||||
|
panic!("quux");
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
if my_err("bye".to_string()) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,5 +11,6 @@
|
||||||
// error-pattern:explicit panic
|
// error-pattern:explicit panic
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
panic!(); println!("{}", 1);
|
panic!();
|
||||||
|
println!("{}", 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,4 +20,4 @@ fn main() {
|
||||||
let pointer = other;
|
let pointer = other;
|
||||||
pointer();
|
pointer();
|
||||||
}
|
}
|
||||||
extern fn other() {}
|
extern "C" fn other() {}
|
||||||
|
|
|
@ -19,16 +19,13 @@ pub trait Parser {
|
||||||
|
|
||||||
impl Parser for () {
|
impl Parser for () {
|
||||||
type Input = ();
|
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!")
|
panic!("Hello, world!")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
many()
|
many().parse(());
|
||||||
.parse(());
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,14 @@
|
||||||
|
|
||||||
use std::sync::Arc;
|
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() {
|
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> {
|
impl<'i, 't> Parser<'i, 't> {
|
||||||
fn parse_nested_block<F, T>(&mut self, parse: F) -> Result<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() {
|
fn main() {
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
// error-pattern:so long
|
// error-pattern:so long
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut x = Vec::new();
|
let mut x = Vec::new();
|
||||||
let y = vec!(3);
|
let y = vec![3];
|
||||||
panic!("so long");
|
panic!("so long");
|
||||||
x.extend(y.into_iter());
|
x.extend(y.into_iter());
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,4 +11,6 @@
|
||||||
// error-pattern:explicit panic
|
// error-pattern:explicit panic
|
||||||
|
|
||||||
fn foo<T>(t: T) {}
|
fn foo<T>(t: T) {}
|
||||||
fn main() { foo(panic!()) }
|
fn main() {
|
||||||
|
foo(panic!())
|
||||||
|
}
|
||||||
|
|
|
@ -12,9 +12,12 @@
|
||||||
|
|
||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
|
|
||||||
struct Point { x: isize, y: isize }
|
struct Point {
|
||||||
|
x: isize,
|
||||||
|
y: isize,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let origin = Point {x: 0, y: 0};
|
let origin = Point { x: 0, y: 0 };
|
||||||
let f: Point = Point {x: (panic!("beep boop")),.. origin};
|
let f: Point = Point { x: (panic!("beep boop")), ..origin };
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,12 @@
|
||||||
#![allow(unreachable_code)]
|
#![allow(unreachable_code)]
|
||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
|
|
||||||
fn foo(s: String) { }
|
fn foo(s: String) {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let i =
|
let i = match Some::<isize>(3) {
|
||||||
match Some::<isize>(3) { None::<isize> => { panic!() } Some::<isize>(_) => { panic!() } };
|
None::<isize> => panic!(),
|
||||||
|
Some::<isize>(_) => panic!(),
|
||||||
|
};
|
||||||
foo(i);
|
foo(i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,15 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern:quux
|
// error-pattern:quux
|
||||||
fn f() -> ! { panic!("quux") }
|
fn f() -> ! {
|
||||||
fn g() -> isize { match f() { true => { 1 } false => { 0 } } }
|
panic!("quux")
|
||||||
fn main() { g(); }
|
}
|
||||||
|
fn g() -> isize {
|
||||||
|
match f() {
|
||||||
|
true => 1,
|
||||||
|
false => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
|
|
@ -11,10 +11,18 @@
|
||||||
// error-pattern:squirrelcupcake
|
// error-pattern:squirrelcupcake
|
||||||
fn cmp() -> isize {
|
fn cmp() -> isize {
|
||||||
match (Some('a'), None::<char>) {
|
match (Some('a'), None::<char>) {
|
||||||
(Some(_), _) => { panic!("squirrelcupcake"); }
|
(Some(_), _) => {
|
||||||
(_, Some(_)) => { panic!(); }
|
panic!("squirrelcupcake");
|
||||||
_ => { panic!("wat"); }
|
}
|
||||||
|
(_, Some(_)) => {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
panic!("wat");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { println!("{}", cmp()); }
|
fn main() {
|
||||||
|
println!("{}", cmp());
|
||||||
|
}
|
||||||
|
|
|
@ -16,7 +16,15 @@
|
||||||
//[foo] error-pattern:bar
|
//[foo] error-pattern:bar
|
||||||
//[bar] error-pattern:foo
|
//[bar] error-pattern:foo
|
||||||
|
|
||||||
#[cfg(foo)] fn die() {panic!("foo");}
|
#[cfg(foo)]
|
||||||
#[cfg(bar)] fn die() {panic!("bar");}
|
fn die() {
|
||||||
|
panic!("foo");
|
||||||
|
}
|
||||||
|
#[cfg(bar)]
|
||||||
|
fn die() {
|
||||||
|
panic!("bar");
|
||||||
|
}
|
||||||
|
|
||||||
fn main() { die(); }
|
fn main() {
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
|
@ -15,7 +15,15 @@
|
||||||
//[foo] error-pattern:foo
|
//[foo] error-pattern:foo
|
||||||
//[bar] error-pattern:bar
|
//[bar] error-pattern:bar
|
||||||
|
|
||||||
#[cfg(foo)] fn die() {panic!("foo");}
|
#[cfg(foo)]
|
||||||
#[cfg(bar)] fn die() {panic!("bar");}
|
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]
|
#[rustc_mir]
|
||||||
fn mir(){
|
fn mir() {
|
||||||
let (mut xv, mut yv) = (false, false);
|
let (mut xv, mut yv) = (false, false);
|
||||||
let x = Droppable(&mut xv, 1);
|
let x = Droppable(&mut xv, 1);
|
||||||
let y = Droppable(&mut yv, 2);
|
let y = Droppable(&mut yv, 2);
|
||||||
|
|
|
@ -26,7 +26,7 @@ impl<'a> Drop for Droppable<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_mir]
|
#[rustc_mir]
|
||||||
fn mir<'a>(d: Droppable<'a>){
|
fn mir<'a>(d: Droppable<'a>) {
|
||||||
loop {
|
loop {
|
||||||
let x = d;
|
let x = d;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -33,7 +33,7 @@ fn may_panic<'a>() -> Droppable<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_mir]
|
#[rustc_mir]
|
||||||
fn mir<'a>(d: Droppable<'a>){
|
fn mir<'a>(d: Droppable<'a>) {
|
||||||
let (mut a, mut b) = (false, false);
|
let (mut a, mut b) = (false, false);
|
||||||
let y = Droppable(&mut a, 2);
|
let y = Droppable(&mut a, 2);
|
||||||
let x = [Droppable(&mut b, 1), y, d, may_panic()];
|
let x = [Droppable(&mut b, 1), y, d, may_panic()];
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern:woe
|
// 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)]
|
#![feature(box_syntax)]
|
||||||
|
|
||||||
fn main() {
|
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.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern:moop
|
// error-pattern:moop
|
||||||
fn main() { panic!("moop"); }
|
fn main() {
|
||||||
|
panic!("moop");
|
||||||
|
}
|
||||||
|
|
|
@ -13,11 +13,15 @@
|
||||||
// error-pattern:oops
|
// error-pattern:oops
|
||||||
|
|
||||||
fn bigpanic() {
|
fn bigpanic() {
|
||||||
while (panic!("oops")) { if (panic!()) {
|
while (panic!("oops")) {
|
||||||
match (panic!()) { () => {
|
if (panic!()) {
|
||||||
|
match (panic!()) {
|
||||||
|
() => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { bigpanic(); }
|
fn main() {
|
||||||
|
bigpanic();
|
||||||
|
}
|
||||||
|
|
|
@ -13,8 +13,9 @@
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let r: Result<(),_> = thread::spawn(move|| {
|
let r: Result<(), _> = thread::spawn(move || {
|
||||||
panic!("test");
|
panic!("test");
|
||||||
}).join();
|
})
|
||||||
|
.join();
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,14 @@
|
||||||
use std::thread::Builder;
|
use std::thread::Builder;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let r: () = Builder::new().name("owned name".to_string()).spawn(move|| {
|
let r: () = Builder::new()
|
||||||
panic!("test");
|
.name("owned name".to_string())
|
||||||
()
|
.spawn(move || {
|
||||||
}).unwrap().join().unwrap();
|
panic!("test");
|
||||||
|
()
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
|
.join()
|
||||||
|
.unwrap();
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,4 +9,6 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern:1 == 2
|
// error-pattern:1 == 2
|
||||||
fn main() { assert!(1 == 2); }
|
fn main() {
|
||||||
|
assert!(1 == 2);
|
||||||
|
}
|
||||||
|
|
|
@ -13,5 +13,5 @@
|
||||||
use std::result::Result::Err;
|
use std::result::Result::Err;
|
||||||
|
|
||||||
fn main() {
|
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(unreachable_code)]
|
||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
|
|
||||||
struct T { t: String }
|
struct T {
|
||||||
|
t: String,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let pth = panic!("bye");
|
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`
|
// ignore-pretty: does not work well with `--test`
|
||||||
|
|
||||||
mod m {
|
mod m {
|
||||||
pub fn exported() { }
|
pub fn exported() {}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unexported() { panic!("runned an unexported test"); }
|
fn unexported() {
|
||||||
|
panic!("runned an unexported test");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,4 +9,6 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern:not yet implemented
|
// error-pattern:not yet implemented
|
||||||
fn main() { unimplemented!() }
|
fn main() {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
|
@ -10,4 +10,6 @@
|
||||||
|
|
||||||
// error-pattern: panic
|
// error-pattern: panic
|
||||||
|
|
||||||
fn main() { Box::new(panic!()); }
|
fn main() {
|
||||||
|
Box::new(panic!());
|
||||||
|
}
|
||||||
|
|
|
@ -9,4 +9,6 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern:internal error: entered unreachable code
|
// error-pattern:internal error: entered unreachable code
|
||||||
fn main() { unreachable!() }
|
fn main() {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
|
|
@ -9,4 +9,6 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern:internal error: entered unreachable code: uhoh
|
// 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.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern:internal error: entered unreachable code
|
// error-pattern:internal error: entered unreachable code
|
||||||
fn main() { unreachable!() }
|
fn main() {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
|
|
@ -10,13 +10,15 @@
|
||||||
|
|
||||||
// error-pattern:fail
|
// error-pattern:fail
|
||||||
|
|
||||||
fn a() { }
|
fn a() {}
|
||||||
|
|
||||||
fn b() { panic!(); }
|
fn b() {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _x = vec!(0);
|
let _x = vec![0];
|
||||||
a();
|
a();
|
||||||
let _y = vec!(0);
|
let _y = vec![0];
|
||||||
b();
|
b();
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,10 @@ fn build() -> Vec<isize> {
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Blk { node: Vec<isize> }
|
struct Blk {
|
||||||
|
node: Vec<isize>,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _blk = Blk {
|
let _blk = Blk { node: build() };
|
||||||
node: build()
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,18 +12,21 @@
|
||||||
|
|
||||||
|
|
||||||
fn build1() -> Vec<isize> {
|
fn build1() -> Vec<isize> {
|
||||||
vec!(0,0,0,0,0,0,0)
|
vec![0, 0, 0, 0, 0, 0, 0]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build2() -> Vec<isize> {
|
fn build2() -> Vec<isize> {
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Blk { node: Vec<isize> , span: Vec<isize> }
|
struct Blk {
|
||||||
|
node: Vec<isize>,
|
||||||
|
span: Vec<isize>,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _blk = Blk {
|
let _blk = Blk {
|
||||||
node: build1(),
|
node: build1(),
|
||||||
span: build2()
|
span: build2(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let v: Vec<isize> = vec!(10);
|
let v: Vec<isize> = vec![10];
|
||||||
let x: usize = 0;
|
let x: usize = 0;
|
||||||
assert_eq!(v[x], 10);
|
assert_eq!(v[x], 10);
|
||||||
// Bounds-check panic.
|
// Bounds-check panic.
|
||||||
|
|
|
@ -11,4 +11,11 @@
|
||||||
#![allow(while_true)]
|
#![allow(while_true)]
|
||||||
|
|
||||||
// error-pattern:quux
|
// 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
|
// error-pattern:giraffe
|
||||||
fn main() {
|
fn main() {
|
||||||
panic!({ while true { panic!("giraffe") }; "clandestine" });
|
panic!({
|
||||||
|
while true {
|
||||||
|
panic!("giraffe")
|
||||||
|
}
|
||||||
|
"clandestine"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue