1
Fork 0

Auto merge of #62935 - Centril:rollup-hzj9att, r=Centril

Rollup of 10 pull requests

Successful merges:

 - #62641 (Regenerate character tables for Unicode 12.1)
 - #62716 (state also in the intro that UnsafeCell has no effect on &mut)
 - #62738 (Remove uses of mem::uninitialized from std::sys::cloudabi)
 - #62772 (Suggest trait bound on type parameter when it is unconstrained)
 - #62890 (Normalize use of backticks in compiler messages for libsyntax/*)
 - #62905 (Normalize use of backticks in compiler messages for doc)
 - #62916 (Add test `self-in-enum-definition`)
 - #62917 (Always emit trailing slash error)
 - #62926 (Fix typo in mem::uninitialized doc)
 - #62927 (use PanicMessage in MIR, kill InterpError::description)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-07-24 15:59:00 +00:00
commit 03f19f7ff1
49 changed files with 1309 additions and 1088 deletions

View file

@ -19,7 +19,7 @@ warning: unused variable: `x`
2 | let x = 5; 2 | let x = 5;
| ^ | ^
| |
= note: #[warn(unused_variables)] on by default = note: `#[warn(unused_variables)]` on by default
= note: to avoid this warning, consider using `_x` instead = note: to avoid this warning, consider using `_x` instead
``` ```

View file

@ -53,7 +53,7 @@ warning: unused variable: `x`
2 | let x = 5; 2 | let x = 5;
| ^ | ^
| |
= note: #[warn(unused_variables)] on by default = note: `#[warn(unused_variables)]` on by default
= note: to avoid this warning, consider using `_x` instead = note: to avoid this warning, consider using `_x` instead
``` ```
@ -76,7 +76,7 @@ error: bitshift exceeds the type's number of bits
2 | 100u8 << 10; 2 | 100u8 << 10;
| ^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: #[deny(exceeding_bitshifts)] on by default = note: `#[deny(exceeding_bitshifts)]` on by default
``` ```
What's the difference between an error from a lint and a regular old error? What's the difference between an error from a lint and a regular old error?
@ -236,7 +236,7 @@ warning: bitshift exceeds the type's number of bits
2 | 100u8 << 10; 2 | 100u8 << 10;
| ^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: #[warn(exceeding_bitshifts)] on by default = note: `#[warn(exceeding_bitshifts)]` on by default
warning: this expression will panic at run-time warning: this expression will panic at run-time
--> lib.rs:2:5 --> lib.rs:2:5

View file

@ -165,7 +165,7 @@ pub struct Foo;
When set to 'deny', this will produce: When set to 'deny', this will produce:
```text ```text
error: type does not implement `fmt::Debug`; consider adding #[derive(Debug)] or a manual implementation error: type does not implement `fmt::Debug`; consider adding `#[derive(Debug)]` or a manual implementation
--> src/main.rs:3:1 --> src/main.rs:3:1
| |
3 | pub struct Foo; 3 | pub struct Foo;

View file

@ -40,7 +40,7 @@ error: defaults for type parameters are only allowed in `struct`, `enum`, `type`
4 | fn foo<T=i32>(t: T) {} 4 | fn foo<T=i32>(t: T) {}
| ^ | ^
| |
= note: #[deny(invalid_type_param_default)] on by default = note: `#[deny(invalid_type_param_default)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887> = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
``` ```
@ -74,7 +74,7 @@ error: private struct constructors are not usable through re-exports in outer mo
5 | ::S; 5 | ::S;
| ^^^ | ^^^
| |
= note: #[deny(legacy_constructor_visibility)] on by default = note: `#[deny(legacy_constructor_visibility)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #39207 <https://github.com/rust-lang/rust/issues/39207> = note: for more information, see issue #39207 <https://github.com/rust-lang/rust/issues/39207>
``` ```
@ -84,9 +84,9 @@ error: private struct constructors are not usable through re-exports in outer mo
The legacy_directory_ownership warning is issued when The legacy_directory_ownership warning is issued when
* There is a non-inline module with a #[path] attribute (e.g. #[path = "foo.rs"] mod bar;), * There is a non-inline module with a `#[path]` attribute (e.g. `#[path = "foo.rs"] mod bar;`),
* The module's file ("foo.rs" in the above example) is not named "mod.rs", and * The module's file ("foo.rs" in the above example) is not named "mod.rs", and
* The module's file contains a non-inline child module without a #[path] attribute. * The module's file contains a non-inline child module without a `#[path]` attribute.
The warning can be fixed by renaming the parent module to "mod.rs" and moving The warning can be fixed by renaming the parent module to "mod.rs" and moving
it into its own directory if appropriate. it into its own directory if appropriate.
@ -139,7 +139,7 @@ const FOO: i32 = 5;
This will produce: This will produce:
```text ```text
error: const items should never be #[no_mangle] error: const items should never be `#[no_mangle]`
--> src/main.rs:3:1 --> src/main.rs:3:1
| |
3 | const FOO: i32 = 5; 3 | const FOO: i32 = 5;
@ -187,7 +187,7 @@ error: parenthesized parameters may only be used with a trait
2 | let x = 5 as usize(); 2 | let x = 5 as usize();
| ^^ | ^^
| |
= note: #[deny(parenthesized_params_in_types_and_modules)] on by default = note: `#[deny(parenthesized_params_in_types_and_modules)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238> = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
``` ```

View file

@ -90,7 +90,7 @@ warning: floating-point literals cannot be used in patterns
4 | 5.0 => {}, 4 | 5.0 => {},
| ^^^ | ^^^
| |
= note: #[warn(illegal_floating_point_literal_pattern)] on by default = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620> = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
``` ```
@ -109,7 +109,7 @@ extern "C" {
This will produce: This will produce:
```text ```text
warning: found struct without foreign-function-safe representation annotation in foreign module, consider adding a #[repr(C)] attribute to the type warning: found struct without foreign-function-safe representation annotation in foreign module, consider adding a `#[repr(C)]` attribute to the type
--> src/main.rs:2:20 --> src/main.rs:2:20
| |
2 | static STATIC: String; 2 | static STATIC: String;
@ -146,7 +146,7 @@ warning: cannot specify lifetime arguments explicitly if late bound lifetime par
8 | S.late::<'static>(&0, &0); 8 | S.late::<'static>(&0, &0);
| ^^^^^^^ | ^^^^^^^
| |
= note: #[warn(late_bound_lifetime_arguments)] on by default = note: `#[warn(late_bound_lifetime_arguments)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868> = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
``` ```
@ -327,7 +327,7 @@ warning: patterns aren't allowed in methods without bodies
2 | fn foo(mut arg: u8); 2 | fn foo(mut arg: u8);
| ^^^^^^^ | ^^^^^^^
| |
= note: #[warn(patterns_in_fns_without_body)] on by default = note: `#[warn(patterns_in_fns_without_body)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #35203 <https://github.com/rust-lang/rust/issues/35203> = note: for more information, see issue #35203 <https://github.com/rust-lang/rust/issues/35203>
``` ```
@ -406,7 +406,7 @@ fn foo() {}
This will produce: This will produce:
```text ```text
warning: function is marked #[no_mangle], but not exported warning: function is marked `#[no_mangle]`, but not exported
--> src/main.rs:2:1 --> src/main.rs:2:1
| |
2 | fn foo() {} 2 | fn foo() {}
@ -433,7 +433,7 @@ static X: i32 = 4;
This will produce: This will produce:
```text ```text
warning: static is marked #[no_mangle], but not exported warning: static is marked `#[no_mangle]`, but not exported
--> src/main.rs:2:1 --> src/main.rs:2:1
| |
2 | static X: i32 = 4; 2 | static X: i32 = 4;
@ -496,7 +496,7 @@ warning: borrow of packed field requires unsafe function or block (error E0133)
11 | let y = &x.data.0; 11 | let y = &x.data.0;
| ^^^^^^^^^ | ^^^^^^^^^
| |
= note: #[warn(safe_packed_borrows)] on by default = note: `#[warn(safe_packed_borrows)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043> = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
``` ```
@ -542,7 +542,7 @@ warning: bounds on generic parameters are not enforced in type aliases
2 | type SendVec<T: Send> = Vec<T>; 2 | type SendVec<T: Send> = Vec<T>;
| ^^^^ | ^^^^
| |
= note: #[warn(type_alias_bounds)] on by default = note: `#[warn(type_alias_bounds)]` on by default
= help: the bound will not be checked when the type alias is used, and should be removed = help: the bound will not be checked when the type alias is used, and should be removed
``` ```
@ -567,7 +567,7 @@ warning: type annotations needed
4 | if data.is_null() {} 4 | if data.is_null() {}
| ^^^^^^^ | ^^^^^^^
| |
= note: #[warn(tyvar_behind_raw_pointer)] on by default = note: `#[warn(tyvar_behind_raw_pointer)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
= note: for more information, see issue #46906 <https://github.com/rust-lang/rust/issues/46906> = note: for more information, see issue #46906 <https://github.com/rust-lang/rust/issues/46906>
``` ```
@ -787,7 +787,7 @@ warning: doc comment not used by rustdoc
## unused-features ## unused-features
This lint detects unused or unknown features found in crate-level #[feature] directives. This lint detects unused or unknown features found in crate-level `#[feature]` directives.
To fix this, simply remove the feature flag. To fix this, simply remove the feature flag.
## unused-imports ## unused-imports
@ -839,7 +839,7 @@ warning: unused macro definition
## unused-must-use ## unused-must-use
This lint detects unused result of a type flagged as #[must_use]. Some This lint detects unused result of a type flagged as `#[must_use]`. Some
example code that triggers this lint: example code that triggers this lint:
```rust ```rust

View file

@ -1412,8 +1412,9 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
/// If you have a reference `&SomeStruct`, then normally in Rust all fields of `SomeStruct` are /// If you have a reference `&SomeStruct`, then normally in Rust all fields of `SomeStruct` are
/// immutable. The compiler makes optimizations based on the knowledge that `&T` is not mutably /// immutable. The compiler makes optimizations based on the knowledge that `&T` is not mutably
/// aliased or mutated, and that `&mut T` is unique. `UnsafeCell<T>` is the only core language /// aliased or mutated, and that `&mut T` is unique. `UnsafeCell<T>` is the only core language
/// feature to work around this restriction. All other types that allow internal mutability, such as /// feature to work around the restriction that `&T` may not be mutated. All other types that
/// `Cell<T>` and `RefCell<T>`, use `UnsafeCell` to wrap their internal data. /// allow internal mutability, such as `Cell<T>` and `RefCell<T>`, use `UnsafeCell` to wrap their
/// internal data. There is *no* legal way to obtain aliasing `&mut`, not even with `UnsafeCell<T>`.
/// ///
/// The `UnsafeCell` API itself is technically very simple: it gives you a raw pointer `*mut T` to /// The `UnsafeCell` API itself is technically very simple: it gives you a raw pointer `*mut T` to
/// its contents. It is up to _you_ as the abstraction designer to use that raw pointer correctly. /// its contents. It is up to _you_ as the abstraction designer to use that raw pointer correctly.

View file

@ -456,7 +456,7 @@ pub unsafe fn zeroed<T>() -> T {
/// Bypasses Rust's normal memory-initialization checks by pretending to /// Bypasses Rust's normal memory-initialization checks by pretending to
/// produce a value of type `T`, while doing nothing at all. /// produce a value of type `T`, while doing nothing at all.
/// ///
/// **This functon is deprecated.** Use [`MaybeUninit<T>`] instead. /// **This function is deprecated.** Use [`MaybeUninit<T>`] instead.
/// ///
/// The reason for deprecation is that the function basically cannot be used /// The reason for deprecation is that the function basically cannot be used
/// correctly: [the Rust compiler assumes][inv] that values are properly initialized. /// correctly: [the Rust compiler assumes][inv] that values are properly initialized.

View file

@ -111,17 +111,17 @@ def compress_normal(normal):
return compressed return compressed
def print_singletons(uppers, lowers, uppersname, lowersname): def print_singletons(uppers, lowers, uppersname, lowersname):
print("const {}: &'static [(u8, u8)] = &[".format(uppersname)) print("const {}: &[(u8, u8)] = &[".format(uppersname))
for u, c in uppers: for u, c in uppers:
print(" ({:#04x}, {}),".format(u, c)) print(" ({:#04x}, {}),".format(u, c))
print("];") print("];")
print("const {}: &'static [u8] = &[".format(lowersname)) print("const {}: &[u8] = &[".format(lowersname))
for i in range(0, len(lowers), 8): for i in range(0, len(lowers), 8):
print(" {}".format(" ".join("{:#04x},".format(l) for l in lowers[i:i+8]))) print(" {}".format(" ".join("{:#04x},".format(l) for l in lowers[i:i+8])))
print("];") print("];")
def print_normal(normal, normalname): def print_normal(normal, normalname):
print("const {}: &'static [u8] = &[".format(normalname)) print("const {}: &[u8] = &[".format(normalname))
for v in normal: for v in normal:
print(" {}".format(" ".join("{:#04x},".format(i) for i in v))) print(" {}".format(" ".join("{:#04x},".format(i) for i in v)))
print("];") print("];")

View file

@ -82,7 +82,7 @@ const SINGLETONS0U: &[(u8, u8)] = &[
(0x0b, 25), (0x0b, 25),
(0x0c, 20), (0x0c, 20),
(0x0d, 18), (0x0d, 18),
(0x0e, 22), (0x0e, 13),
(0x0f, 4), (0x0f, 4),
(0x10, 3), (0x10, 3),
(0x12, 18), (0x12, 18),
@ -96,13 +96,14 @@ const SINGLETONS0U: &[(u8, u8)] = &[
(0x1d, 1), (0x1d, 1),
(0x1f, 22), (0x1f, 22),
(0x20, 3), (0x20, 3),
(0x2b, 6), (0x2b, 4),
(0x2c, 2), (0x2c, 2),
(0x2d, 11), (0x2d, 11),
(0x2e, 1), (0x2e, 1),
(0x30, 3), (0x30, 3),
(0x31, 2), (0x31, 2),
(0x32, 2), (0x32, 1),
(0xa7, 2),
(0xa9, 2), (0xa9, 2),
(0xaa, 4), (0xaa, 4),
(0xab, 8), (0xab, 8),
@ -130,27 +131,26 @@ const SINGLETONS0L: &[u8] = &[
0xbb, 0xc5, 0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x04, 0xbb, 0xc5, 0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x04,
0x0d, 0x11, 0x45, 0x49, 0x64, 0x65, 0x80, 0x81, 0x0d, 0x11, 0x45, 0x49, 0x64, 0x65, 0x80, 0x81,
0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5, 0xd7, 0xf0, 0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5, 0xd7, 0xf0,
0xf1, 0x83, 0x85, 0x86, 0x89, 0x8b, 0x8c, 0x98, 0xf1, 0x83, 0x85, 0x8b, 0xa4, 0xa6, 0xbe, 0xbf,
0xa0, 0xa4, 0xa6, 0xa8, 0xa9, 0xac, 0xba, 0xbe, 0xc5, 0xc7, 0xce, 0xcf, 0xda, 0xdb, 0x48, 0x98,
0xbf, 0xc5, 0xc7, 0xce, 0xcf, 0xda, 0xdb, 0x48, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49, 0x4e, 0x4f,
0x98, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49, 0x4e, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f, 0xb1,
0x4f, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f, 0xb6, 0xb7, 0xbf, 0xc1, 0xc6, 0xc7, 0xd7, 0x11,
0xb1, 0xb6, 0xb7, 0xbf, 0xc1, 0xc6, 0xc7, 0xd7, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7, 0xfe, 0xff,
0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7, 0xfe, 0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e, 0x0f,
0xff, 0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e, 0x1f, 0x6e, 0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e,
0x0f, 0x1f, 0x6e, 0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0xae, 0xaf, 0xbb, 0xbc, 0xfa, 0x16, 0x17, 0x1e,
0x7e, 0xae, 0xaf, 0xbb, 0xbc, 0xfa, 0x16, 0x17, 0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c,
0x1e, 0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5e, 0x7e, 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc,
0x5c, 0x5e, 0x7e, 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f, 0x74, 0x75,
0xdc, 0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f, 0x74, 0x96, 0x97, 0x2f, 0x5f, 0x26, 0x2e, 0x2f, 0xa7,
0x75, 0x96, 0x97, 0xc9, 0xff, 0x2f, 0x5f, 0x26, 0xaf, 0xb7, 0xbf, 0xc7, 0xcf, 0xd7, 0xdf, 0x9a,
0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf, 0xc7, 0xcf, 0x40, 0x97, 0x98, 0x30, 0x8f, 0x1f, 0xc0, 0xc1,
0xd7, 0xdf, 0x9a, 0x40, 0x97, 0x98, 0x30, 0x8f, 0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b, 0x07, 0x08,
0x1f, 0xff, 0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b, 0x0f, 0x10, 0x27, 0x2f, 0xee, 0xef, 0x6e, 0x6f,
0x07, 0x08, 0x0f, 0x10, 0x27, 0x2f, 0xee, 0xef, 0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90, 0x91, 0xfe,
0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9, 0xd0, 0xd1,
0x91, 0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9, 0xd8, 0xd9, 0xe7, 0xfe, 0xff,
0xd0, 0xd1, 0xd8, 0xd9, 0xe7, 0xfe, 0xff,
]; ];
const SINGLETONS1U: &[(u8, u8)] = &[ const SINGLETONS1U: &[(u8, u8)] = &[
(0x00, 6), (0x00, 6),
@ -168,7 +168,7 @@ const SINGLETONS1U: &[(u8, u8)] = &[
(0x14, 2), (0x14, 2),
(0x15, 2), (0x15, 2),
(0x17, 2), (0x17, 2),
(0x1a, 2), (0x19, 4),
(0x1c, 5), (0x1c, 5),
(0x1d, 8), (0x1d, 8),
(0x24, 1), (0x24, 1),
@ -182,10 +182,12 @@ const SINGLETONS1U: &[(u8, u8)] = &[
(0xd7, 2), (0xd7, 2),
(0xda, 1), (0xda, 1),
(0xe0, 5), (0xe0, 5),
(0xe1, 2),
(0xe8, 2), (0xe8, 2),
(0xee, 32), (0xee, 32),
(0xf0, 4), (0xf0, 4),
(0xf9, 4), (0xf9, 6),
(0xfa, 2),
]; ];
const SINGLETONS1L: &[u8] = &[ const SINGLETONS1L: &[u8] = &[
0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e, 0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e,
@ -195,19 +197,20 @@ const SINGLETONS1L: &[u8] = &[
0x12, 0x87, 0x89, 0x8e, 0x9e, 0x04, 0x0d, 0x0e, 0x12, 0x87, 0x89, 0x8e, 0x9e, 0x04, 0x0d, 0x0e,
0x11, 0x12, 0x29, 0x31, 0x34, 0x3a, 0x45, 0x46, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a, 0x45, 0x46,
0x49, 0x4a, 0x4e, 0x4f, 0x64, 0x65, 0x5a, 0x5c, 0x49, 0x4a, 0x4e, 0x4f, 0x64, 0x65, 0x5a, 0x5c,
0xb6, 0xb7, 0x1b, 0x1c, 0x84, 0x85, 0x09, 0x37, 0xb6, 0xb7, 0x1b, 0x1c, 0xa8, 0xa9, 0xd8, 0xd9,
0x90, 0x91, 0xa8, 0x07, 0x0a, 0x3b, 0x3e, 0x66, 0x09, 0x37, 0x90, 0x91, 0xa8, 0x07, 0x0a, 0x3b,
0x69, 0x8f, 0x92, 0x6f, 0x5f, 0xee, 0xef, 0x5a, 0x3e, 0x66, 0x69, 0x8f, 0x92, 0x6f, 0x5f, 0xee,
0x62, 0x9a, 0x9b, 0x27, 0x28, 0x55, 0x9d, 0xa0, 0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27, 0x28, 0x55,
0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad, 0xba, 0xbc, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad,
0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d, 0x3a, 0x3f, 0xba, 0xbc, 0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d,
0x45, 0x51, 0xa6, 0xa7, 0xcc, 0xcd, 0xa0, 0x07, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7, 0xcc, 0xcd,
0x19, 0x1a, 0x22, 0x25, 0xc5, 0xc6, 0x04, 0x20, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0x3e, 0x3f,
0x23, 0x25, 0x26, 0x28, 0x33, 0x38, 0x3a, 0x48, 0xc5, 0xc6, 0x04, 0x20, 0x23, 0x25, 0x26, 0x28,
0x4a, 0x4c, 0x50, 0x53, 0x55, 0x56, 0x58, 0x5a, 0x33, 0x38, 0x3a, 0x48, 0x4a, 0x4c, 0x50, 0x53,
0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66, 0x6b, 0x73, 0x55, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63,
0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0, 0x65, 0x66, 0x6b, 0x73, 0x78, 0x7d, 0x7f, 0x8a,
0xc0, 0xd0, 0x3f, 0x71, 0x72, 0x7b, 0xa4, 0xaa, 0xaf, 0xb0, 0xc0, 0xd0, 0x0c, 0x72,
0xa3, 0xa4, 0xcb, 0xcc, 0x6e, 0x6f,
]; ];
const NORMAL0: &[u8] = &[ const NORMAL0: &[u8] = &[
0x00, 0x20, 0x00, 0x20,
@ -246,8 +249,8 @@ const NORMAL0: &[u8] = &[
0x3a, 0x03, 0x3a, 0x03,
0x11, 0x07, 0x11, 0x07,
0x06, 0x05, 0x06, 0x05,
0x10, 0x08, 0x10, 0x07,
0x56, 0x07, 0x57, 0x07,
0x02, 0x07, 0x02, 0x07,
0x15, 0x0d, 0x15, 0x0d,
0x50, 0x04, 0x50, 0x04,
@ -258,8 +261,7 @@ const NORMAL0: &[u8] = &[
0x0f, 0x0c, 0x0f, 0x0c,
0x3a, 0x04, 0x3a, 0x04,
0x1d, 0x25, 0x1d, 0x25,
0x0d, 0x06, 0x5f, 0x20,
0x4c, 0x20,
0x6d, 0x04, 0x6d, 0x04,
0x6a, 0x25, 0x6a, 0x25,
0x80, 0xc8, 0x05, 0x80, 0xc8, 0x05,
@ -294,7 +296,7 @@ const NORMAL0: &[u8] = &[
0x0f, 0x03, 0x0f, 0x03,
0x3c, 0x07, 0x3c, 0x07,
0x38, 0x08, 0x38, 0x08,
0x2a, 0x06, 0x2b, 0x05,
0x82, 0xff, 0x11, 0x82, 0xff, 0x11,
0x18, 0x08, 0x18, 0x08,
0x2f, 0x11, 0x2f, 0x11,
@ -309,7 +311,7 @@ const NORMAL0: &[u8] = &[
0x3b, 0x07, 0x3b, 0x07,
0x02, 0x0e, 0x02, 0x0e,
0x18, 0x09, 0x18, 0x09,
0x80, 0xaf, 0x31, 0x80, 0xb0, 0x30,
0x74, 0x0c, 0x74, 0x0c,
0x80, 0xd6, 0x1a, 0x80, 0xd6, 0x1a,
0x0c, 0x05, 0x0c, 0x05,
@ -322,7 +324,7 @@ const NORMAL0: &[u8] = &[
0x37, 0x09, 0x37, 0x09,
0x81, 0x5c, 0x14, 0x81, 0x5c, 0x14,
0x80, 0xb8, 0x08, 0x80, 0xb8, 0x08,
0x80, 0xba, 0x3d, 0x80, 0xc7, 0x30,
0x35, 0x04, 0x35, 0x04,
0x0a, 0x06, 0x0a, 0x06,
0x38, 0x08, 0x38, 0x08,
@ -335,7 +337,7 @@ const NORMAL0: &[u8] = &[
0x80, 0x83, 0x18, 0x80, 0x83, 0x18,
0x1c, 0x0a, 0x1c, 0x0a,
0x16, 0x09, 0x16, 0x09,
0x46, 0x0a, 0x48, 0x08,
0x80, 0x8a, 0x06, 0x80, 0x8a, 0x06,
0xab, 0xa4, 0x0c, 0xab, 0xa4, 0x0c,
0x17, 0x04, 0x17, 0x04,
@ -405,7 +407,8 @@ const NORMAL1: &[u8] = &[
0x0a, 0x81, 0x26, 0x0a, 0x81, 0x26,
0x1f, 0x80, 0x81, 0x1f, 0x80, 0x81,
0x28, 0x08, 0x28, 0x08,
0x2a, 0x80, 0xa6, 0x2a, 0x80, 0x86,
0x17, 0x09,
0x4e, 0x04, 0x4e, 0x04,
0x1e, 0x0f, 0x1e, 0x0f,
0x43, 0x0e, 0x43, 0x0e,
@ -422,20 +425,21 @@ const NORMAL1: &[u8] = &[
0x01, 0x05, 0x01, 0x05,
0x10, 0x03, 0x10, 0x03,
0x05, 0x80, 0x8b, 0x05, 0x80, 0x8b,
0x5f, 0x21, 0x60, 0x20,
0x48, 0x08, 0x48, 0x08,
0x0a, 0x80, 0xa6, 0x0a, 0x80, 0xa6,
0x5e, 0x22, 0x5e, 0x22,
0x45, 0x0b, 0x45, 0x0b,
0x0a, 0x06, 0x0a, 0x06,
0x0d, 0x13, 0x0d, 0x13,
0x38, 0x08, 0x39, 0x07,
0x0a, 0x36, 0x0a, 0x36,
0x2c, 0x04, 0x2c, 0x04,
0x10, 0x80, 0xc0, 0x10, 0x80, 0xc0,
0x3c, 0x64, 0x3c, 0x64,
0x53, 0x0c, 0x53, 0x0c,
0x01, 0x81, 0x00, 0x01, 0x80, 0xa0,
0x45, 0x1b,
0x48, 0x08, 0x48, 0x08,
0x53, 0x1d, 0x53, 0x1d,
0x39, 0x81, 0x07, 0x39, 0x81, 0x07,
@ -447,8 +451,9 @@ const NORMAL1: &[u8] = &[
0x0a, 0x06, 0x0a, 0x06,
0x39, 0x07, 0x39, 0x07,
0x0a, 0x81, 0x36, 0x0a, 0x81, 0x36,
0x19, 0x81, 0x07, 0x19, 0x80, 0xc7,
0x83, 0x9a, 0x66, 0x32, 0x0d,
0x83, 0x9b, 0x66,
0x75, 0x0b, 0x75, 0x0b,
0x80, 0xc4, 0x8a, 0xbc, 0x80, 0xc4, 0x8a, 0xbc,
0x84, 0x2f, 0x8f, 0xd1, 0x84, 0x2f, 0x8f, 0xd1,
@ -461,13 +466,15 @@ const NORMAL1: &[u8] = &[
0x28, 0x05, 0x28, 0x05,
0x13, 0x82, 0xb0, 0x13, 0x82, 0xb0,
0x5b, 0x65, 0x5b, 0x65,
0x45, 0x0b, 0x4b, 0x04,
0x2f, 0x10, 0x39, 0x07,
0x11, 0x40, 0x11, 0x40,
0x02, 0x1e, 0x04, 0x1c,
0x97, 0xf2, 0x0e, 0x97, 0xf8, 0x08,
0x82, 0xf3, 0xa5, 0x0d, 0x82, 0xf3, 0xa5, 0x0d,
0x81, 0x1f, 0x51, 0x81, 0x1f, 0x31,
0x03, 0x11,
0x04, 0x08,
0x81, 0x8c, 0x89, 0x04, 0x81, 0x8c, 0x89, 0x04,
0x6b, 0x05, 0x6b, 0x05,
0x0d, 0x03, 0x0d, 0x03,
@ -483,12 +490,18 @@ const NORMAL1: &[u8] = &[
0x81, 0x47, 0x03, 0x81, 0x47, 0x03,
0x85, 0x42, 0x0f, 0x85, 0x42, 0x0f,
0x15, 0x85, 0x50, 0x15, 0x85, 0x50,
0x2b, 0x87, 0xd5, 0x2b, 0x80, 0xd5,
0x2d, 0x03,
0x1a, 0x04,
0x02, 0x81, 0x70,
0x3a, 0x05,
0x01, 0x85, 0x00,
0x80, 0xd7, 0x29, 0x80, 0xd7, 0x29,
0x4b, 0x05, 0x4c, 0x04,
0x0a, 0x04, 0x0a, 0x04,
0x02, 0x83, 0x11, 0x02, 0x83, 0x11,
0x44, 0x81, 0x4b, 0x44, 0x4c,
0x3d, 0x80, 0xc2,
0x3c, 0x06, 0x3c, 0x06,
0x01, 0x04, 0x01, 0x04,
0x55, 0x05, 0x55, 0x05,
@ -498,28 +511,29 @@ const NORMAL1: &[u8] = &[
0x64, 0x0c, 0x64, 0x0c,
0x56, 0x0a, 0x56, 0x0a,
0x0d, 0x03, 0x0d, 0x03,
0x5c, 0x04, 0x5d, 0x03,
0x3d, 0x39, 0x3d, 0x39,
0x1d, 0x0d, 0x1d, 0x0d,
0x2c, 0x04, 0x2c, 0x04,
0x09, 0x07, 0x09, 0x07,
0x02, 0x0e, 0x02, 0x0e,
0x06, 0x80, 0x9a, 0x06, 0x80, 0x9a,
0x83, 0xd5, 0x0b, 0x83, 0xd6, 0x0a,
0x0d, 0x03, 0x0d, 0x03,
0x0a, 0x06, 0x0b, 0x05,
0x74, 0x0c, 0x74, 0x0c,
0x59, 0x27, 0x59, 0x07,
0x0c, 0x14,
0x0c, 0x04, 0x0c, 0x04,
0x38, 0x08, 0x38, 0x08,
0x0a, 0x06, 0x0a, 0x06,
0x28, 0x08, 0x28, 0x08,
0x1e, 0x52, 0x1e, 0x52,
0x0c, 0x04, 0x77, 0x03,
0x67, 0x03, 0x31, 0x03,
0x29, 0x0d, 0x80, 0xa6, 0x0c,
0x0a, 0x06, 0x14, 0x04,
0x03, 0x05,
0x03, 0x0d, 0x03, 0x0d,
0x30, 0x60, 0x06, 0x85, 0x6a,
0x0e, 0x85, 0x92,
]; ];

File diff suppressed because it is too large Load diff

View file

@ -81,8 +81,8 @@ PREAMBLE = """\
#![allow(missing_docs, non_upper_case_globals, non_snake_case)] #![allow(missing_docs, non_upper_case_globals, non_snake_case)]
use unicode::version::UnicodeVersion; use crate::unicode::version::UnicodeVersion;
use unicode::bool_trie::{{BoolTrie, SmallBoolTrie}}; use crate::unicode::bool_trie::{{BoolTrie, SmallBoolTrie}};
""".format(year=datetime.datetime.now().year) """.format(year=datetime.datetime.now().year)
# Mapping taken from Table 12 from: # Mapping taken from Table 12 from:

View file

@ -47,7 +47,7 @@ pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)] #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct ConstEvalErr<'tcx> { pub struct ConstEvalErr<'tcx> {
pub span: Span, pub span: Span,
pub error: crate::mir::interpret::InterpError<'tcx, u64>, pub error: crate::mir::interpret::InterpError<'tcx>,
pub stacktrace: Vec<FrameInfo<'tcx>>, pub stacktrace: Vec<FrameInfo<'tcx>>,
} }
@ -185,11 +185,18 @@ pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<'
/// macro for this. /// macro for this.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct InterpErrorInfo<'tcx> { pub struct InterpErrorInfo<'tcx> {
pub kind: InterpError<'tcx, u64>, pub kind: InterpError<'tcx>,
backtrace: Option<Box<Backtrace>>, backtrace: Option<Box<Backtrace>>,
} }
impl<'tcx> InterpErrorInfo<'tcx> {
impl fmt::Display for InterpErrorInfo<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.kind)
}
}
impl InterpErrorInfo<'_> {
pub fn print_backtrace(&mut self) { pub fn print_backtrace(&mut self) {
if let Some(ref mut backtrace) = self.backtrace { if let Some(ref mut backtrace) = self.backtrace {
print_backtrace(&mut *backtrace); print_backtrace(&mut *backtrace);
@ -202,8 +209,8 @@ fn print_backtrace(backtrace: &mut Backtrace) {
eprintln!("\n\nAn error occurred in miri:\n{:?}", backtrace); eprintln!("\n\nAn error occurred in miri:\n{:?}", backtrace);
} }
impl<'tcx> From<InterpError<'tcx, u64>> for InterpErrorInfo<'tcx> { impl<'tcx> From<InterpError<'tcx>> for InterpErrorInfo<'tcx> {
fn from(kind: InterpError<'tcx, u64>) -> Self { fn from(kind: InterpError<'tcx>) -> Self {
let backtrace = match env::var("RUST_CTFE_BACKTRACE") { let backtrace = match env::var("RUST_CTFE_BACKTRACE") {
// Matching `RUST_BACKTRACE` -- we treat "0" the same as "not present". // Matching `RUST_BACKTRACE` -- we treat "0" the same as "not present".
Ok(ref val) if val != "0" => { Ok(ref val) if val != "0" => {
@ -226,8 +233,6 @@ impl<'tcx> From<InterpError<'tcx, u64>> for InterpErrorInfo<'tcx> {
} }
} }
pub type AssertMessage<'tcx> = InterpError<'tcx, mir::Operand<'tcx>>;
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
pub enum PanicMessage<O> { pub enum PanicMessage<O> {
Panic { Panic {
@ -244,10 +249,68 @@ pub enum PanicMessage<O> {
OverflowNeg, OverflowNeg,
DivisionByZero, DivisionByZero,
RemainderByZero, RemainderByZero,
GeneratorResumedAfterReturn,
GeneratorResumedAfterPanic,
}
/// Type for MIR `Assert` terminator error messages.
pub type AssertMessage<'tcx> = PanicMessage<mir::Operand<'tcx>>;
impl<O> PanicMessage<O> {
/// Getting a description does not require `O` to be printable, and does not
/// require allocation.
/// The caller is expected to handle `Panic` and `BoundsCheck` separately.
pub fn description(&self) -> &'static str {
use PanicMessage::*;
match self {
Overflow(mir::BinOp::Add) =>
"attempt to add with overflow",
Overflow(mir::BinOp::Sub) =>
"attempt to subtract with overflow",
Overflow(mir::BinOp::Mul) =>
"attempt to multiply with overflow",
Overflow(mir::BinOp::Div) =>
"attempt to divide with overflow",
Overflow(mir::BinOp::Rem) =>
"attempt to calculate the remainder with overflow",
OverflowNeg =>
"attempt to negate with overflow",
Overflow(mir::BinOp::Shr) =>
"attempt to shift right with overflow",
Overflow(mir::BinOp::Shl) =>
"attempt to shift left with overflow",
Overflow(op) =>
bug!("{:?} cannot overflow", op),
DivisionByZero =>
"attempt to divide by zero",
RemainderByZero =>
"attempt to calculate the remainder with a divisor of zero",
GeneratorResumedAfterReturn =>
"generator resumed after completion",
GeneratorResumedAfterPanic =>
"generator resumed after panicking",
Panic { .. } | BoundsCheck { .. } =>
bug!("Unexpected PanicMessage"),
}
}
}
impl<O: fmt::Debug> fmt::Debug for PanicMessage<O> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use PanicMessage::*;
match self {
Panic { ref msg, line, col, ref file } =>
write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col),
BoundsCheck { ref len, ref index } =>
write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index),
_ =>
write!(f, "{}", self.description()),
}
}
} }
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
pub enum InterpError<'tcx, O> { pub enum InterpError<'tcx> {
/// This variant is used by machines to signal their own errors that do not /// This variant is used by machines to signal their own errors that do not
/// match an existing variant. /// match an existing variant.
MachineError(String), MachineError(String),
@ -311,7 +374,7 @@ pub enum InterpError<'tcx, O> {
HeapAllocZeroBytes, HeapAllocZeroBytes,
HeapAllocNonPowerOfTwoAlignment(u64), HeapAllocNonPowerOfTwoAlignment(u64),
Unreachable, Unreachable,
Panic(PanicMessage<O>), Panic(PanicMessage<u64>),
ReadFromReturnPointer, ReadFromReturnPointer,
PathNotFound(Vec<String>), PathNotFound(Vec<String>),
UnimplementedTraitSelection, UnimplementedTraitSelection,
@ -322,173 +385,21 @@ pub enum InterpError<'tcx, O> {
/// Cannot compute this constant because it depends on another one /// Cannot compute this constant because it depends on another one
/// which already produced an error /// which already produced an error
ReferencedConstant, ReferencedConstant,
GeneratorResumedAfterReturn,
GeneratorResumedAfterPanic,
InfiniteLoop, InfiniteLoop,
} }
pub type InterpResult<'tcx, T = ()> = Result<T, InterpErrorInfo<'tcx>>; pub type InterpResult<'tcx, T = ()> = Result<T, InterpErrorInfo<'tcx>>;
impl<'tcx, O> InterpError<'tcx, O> { impl fmt::Display for InterpError<'_> {
pub fn description(&self) -> &str {
use self::InterpError::*;
match *self {
MachineError(ref inner) => inner,
Exit(..) =>
"exited",
FunctionAbiMismatch(..) | FunctionArgMismatch(..) | FunctionRetMismatch(..)
| FunctionArgCountMismatch =>
"tried to call a function through a function pointer of incompatible type",
InvalidMemoryAccess =>
"tried to access memory through an invalid pointer",
DanglingPointerDeref =>
"dangling pointer was dereferenced",
DoubleFree =>
"tried to deallocate dangling pointer",
InvalidFunctionPointer =>
"tried to use a function pointer after offsetting it",
InvalidBool =>
"invalid boolean value read",
InvalidDiscriminant(..) =>
"invalid enum discriminant value read",
PointerOutOfBounds { .. } =>
"pointer offset outside bounds of allocation",
InvalidNullPointerUsage =>
"invalid use of NULL pointer",
ValidationFailure(..) =>
"type validation failed",
ReadPointerAsBytes =>
"a raw memory access tried to access part of a pointer value as raw bytes",
ReadBytesAsPointer =>
"a memory access tried to interpret some bytes as a pointer",
ReadForeignStatic =>
"tried to read from foreign (extern) static",
InvalidPointerMath =>
"attempted to do invalid arithmetic on pointers that would leak base addresses, \
e.g., comparing pointers into different allocations",
ReadUndefBytes(_) =>
"attempted to read undefined bytes",
DeadLocal =>
"tried to access a dead local variable",
InvalidBoolOp(_) =>
"invalid boolean operation",
Unimplemented(ref msg) => msg,
DerefFunctionPointer =>
"tried to dereference a function pointer",
ExecuteMemory =>
"tried to treat a memory pointer as a function pointer",
Intrinsic(..) =>
"intrinsic failed",
NoMirFor(..) =>
"mir not found",
InvalidChar(..) =>
"tried to interpret an invalid 32-bit value as a char",
StackFrameLimitReached =>
"reached the configured maximum number of stack frames",
OutOfTls =>
"reached the maximum number of representable TLS keys",
TlsOutOfBounds =>
"accessed an invalid (unallocated) TLS key",
AbiViolation(ref msg) => msg,
AlignmentCheckFailed{..} =>
"tried to execute a misaligned read or write",
CalledClosureAsFunction =>
"tried to call a closure through a function pointer",
VtableForArgumentlessMethod =>
"tried to call a vtable function without arguments",
ModifiedConstantMemory =>
"tried to modify constant memory",
ModifiedStatic =>
"tried to modify a static's initial value from another static's initializer",
AssumptionNotHeld =>
"`assume` argument was false",
InlineAsm =>
"miri does not support inline assembly",
TypeNotPrimitive(_) =>
"expected primitive type, got nonprimitive",
ReallocatedWrongMemoryKind(_, _) =>
"tried to reallocate memory from one kind to another",
DeallocatedWrongMemoryKind(_, _) =>
"tried to deallocate memory of the wrong kind",
ReallocateNonBasePtr =>
"tried to reallocate with a pointer not to the beginning of an existing object",
DeallocateNonBasePtr =>
"tried to deallocate with a pointer not to the beginning of an existing object",
IncorrectAllocationInformation(..) =>
"tried to deallocate or reallocate using incorrect alignment or size",
Layout(_) =>
"rustc layout computation failed",
UnterminatedCString(_) =>
"attempted to get length of a null terminated string, but no null found before end \
of allocation",
HeapAllocZeroBytes =>
"tried to re-, de- or allocate zero bytes on the heap",
HeapAllocNonPowerOfTwoAlignment(_) =>
"tried to re-, de-, or allocate heap memory with alignment that is not a power of \
two",
Unreachable =>
"entered unreachable code",
Panic(PanicMessage::Panic{..}) =>
"the evaluated program panicked",
Panic(PanicMessage::BoundsCheck{..}) =>
"array index out of bounds",
Panic(PanicMessage::Overflow(mir::BinOp::Add)) =>
"attempt to add with overflow",
Panic(PanicMessage::Overflow(mir::BinOp::Sub)) =>
"attempt to subtract with overflow",
Panic(PanicMessage::Overflow(mir::BinOp::Mul)) =>
"attempt to multiply with overflow",
Panic(PanicMessage::Overflow(mir::BinOp::Div)) =>
"attempt to divide with overflow",
Panic(PanicMessage::Overflow(mir::BinOp::Rem)) =>
"attempt to calculate the remainder with overflow",
Panic(PanicMessage::OverflowNeg) =>
"attempt to negate with overflow",
Panic(PanicMessage::Overflow(mir::BinOp::Shr)) =>
"attempt to shift right with overflow",
Panic(PanicMessage::Overflow(mir::BinOp::Shl)) =>
"attempt to shift left with overflow",
Panic(PanicMessage::Overflow(op)) =>
bug!("{:?} cannot overflow", op),
Panic(PanicMessage::DivisionByZero) =>
"attempt to divide by zero",
Panic(PanicMessage::RemainderByZero) =>
"attempt to calculate the remainder with a divisor of zero",
ReadFromReturnPointer =>
"tried to read from the return pointer",
PathNotFound(_) =>
"a path could not be resolved, maybe the crate is not loaded",
UnimplementedTraitSelection =>
"there were unresolved type arguments during trait selection",
TypeckError =>
"encountered constants with type errors, stopping evaluation",
TooGeneric =>
"encountered overly generic constant",
ReferencedConstant =>
"referenced constant has errors",
GeneratorResumedAfterReturn => "generator resumed after completion",
GeneratorResumedAfterPanic => "generator resumed after panicking",
InfiniteLoop =>
"duplicate interpreter state observed here, const evaluation will never terminate",
}
}
}
impl<'tcx> fmt::Display for InterpErrorInfo<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.kind)
}
}
impl<'tcx> fmt::Display for InterpError<'tcx, u64> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// Forward `Display` to `Debug`
write!(f, "{:?}", self) write!(f, "{:?}", self)
} }
} }
impl<'tcx, O: fmt::Debug> fmt::Debug for InterpError<'tcx, O> { impl fmt::Debug for InterpError<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use self::InterpError::*; use InterpError::*;
match *self { match *self {
PointerOutOfBounds { ptr, msg, allocation_size } => { PointerOutOfBounds { ptr, msg, allocation_size } => {
write!(f, "{} failed: pointer must be in-bounds at offset {}, \ write!(f, "{} failed: pointer must be in-bounds at offset {}, \
@ -516,8 +427,6 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for InterpError<'tcx, O> {
write!(f, "tried to reallocate memory from {} to {}", old, new), write!(f, "tried to reallocate memory from {} to {}", old, new),
DeallocatedWrongMemoryKind(ref old, ref new) => DeallocatedWrongMemoryKind(ref old, ref new) =>
write!(f, "tried to deallocate {} memory but gave {} as the kind", old, new), write!(f, "tried to deallocate {} memory but gave {} as the kind", old, new),
Intrinsic(ref err) =>
write!(f, "{}", err),
InvalidChar(c) => InvalidChar(c) =>
write!(f, "tried to interpret an invalid 32-bit value as a char: {}", c), write!(f, "tried to interpret an invalid 32-bit value as a char: {}", c),
AlignmentCheckFailed { required, has } => AlignmentCheckFailed { required, has } =>
@ -529,21 +438,101 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for InterpError<'tcx, O> {
write!(f, "rustc layout computation failed: {:?}", err), write!(f, "rustc layout computation failed: {:?}", err),
PathNotFound(ref path) => PathNotFound(ref path) =>
write!(f, "Cannot find path {:?}", path), write!(f, "Cannot find path {:?}", path),
MachineError(ref inner) =>
write!(f, "{}", inner),
IncorrectAllocationInformation(size, size2, align, align2) => IncorrectAllocationInformation(size, size2, align, align2) =>
write!(f, "incorrect alloc info: expected size {} and align {}, \ write!(f, "incorrect alloc info: expected size {} and align {}, \
got size {} and align {}", got size {} and align {}",
size.bytes(), align.bytes(), size2.bytes(), align2.bytes()), size.bytes(), align.bytes(), size2.bytes(), align2.bytes()),
Panic(PanicMessage::Panic { ref msg, line, col, ref file }) =>
write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col),
Panic(PanicMessage::BoundsCheck { ref len, ref index }) =>
write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index),
InvalidDiscriminant(val) => InvalidDiscriminant(val) =>
write!(f, "encountered invalid enum discriminant {}", val), write!(f, "encountered invalid enum discriminant {}", val),
Exit(code) => Exit(code) =>
write!(f, "exited with status code {}", code), write!(f, "exited with status code {}", code),
_ => write!(f, "{}", self.description()), InvalidMemoryAccess =>
write!(f, "tried to access memory through an invalid pointer"),
DanglingPointerDeref =>
write!(f, "dangling pointer was dereferenced"),
DoubleFree =>
write!(f, "tried to deallocate dangling pointer"),
InvalidFunctionPointer =>
write!(f, "tried to use a function pointer after offsetting it"),
InvalidBool =>
write!(f, "invalid boolean value read"),
InvalidNullPointerUsage =>
write!(f, "invalid use of NULL pointer"),
ReadPointerAsBytes =>
write!(f, "a raw memory access tried to access part of a pointer value as raw \
bytes"),
ReadBytesAsPointer =>
write!(f, "a memory access tried to interpret some bytes as a pointer"),
ReadForeignStatic =>
write!(f, "tried to read from foreign (extern) static"),
InvalidPointerMath =>
write!(f, "attempted to do invalid arithmetic on pointers that would leak base \
addresses, e.g., comparing pointers into different allocations"),
DeadLocal =>
write!(f, "tried to access a dead local variable"),
DerefFunctionPointer =>
write!(f, "tried to dereference a function pointer"),
ExecuteMemory =>
write!(f, "tried to treat a memory pointer as a function pointer"),
StackFrameLimitReached =>
write!(f, "reached the configured maximum number of stack frames"),
OutOfTls =>
write!(f, "reached the maximum number of representable TLS keys"),
TlsOutOfBounds =>
write!(f, "accessed an invalid (unallocated) TLS key"),
CalledClosureAsFunction =>
write!(f, "tried to call a closure through a function pointer"),
VtableForArgumentlessMethod =>
write!(f, "tried to call a vtable function without arguments"),
ModifiedConstantMemory =>
write!(f, "tried to modify constant memory"),
ModifiedStatic =>
write!(f, "tried to modify a static's initial value from another static's \
initializer"),
AssumptionNotHeld =>
write!(f, "`assume` argument was false"),
InlineAsm =>
write!(f, "miri does not support inline assembly"),
ReallocateNonBasePtr =>
write!(f, "tried to reallocate with a pointer not to the beginning of an \
existing object"),
DeallocateNonBasePtr =>
write!(f, "tried to deallocate with a pointer not to the beginning of an \
existing object"),
HeapAllocZeroBytes =>
write!(f, "tried to re-, de- or allocate zero bytes on the heap"),
Unreachable =>
write!(f, "entered unreachable code"),
ReadFromReturnPointer =>
write!(f, "tried to read from the return pointer"),
UnimplementedTraitSelection =>
write!(f, "there were unresolved type arguments during trait selection"),
TypeckError =>
write!(f, "encountered constants with type errors, stopping evaluation"),
TooGeneric =>
write!(f, "encountered overly generic constant"),
ReferencedConstant =>
write!(f, "referenced constant has errors"),
InfiniteLoop =>
write!(f, "duplicate interpreter state observed here, const evaluation will never \
terminate"),
InvalidBoolOp(_) =>
write!(f, "invalid boolean operation"),
UnterminatedCString(_) =>
write!(f, "attempted to get length of a null terminated string, but no null \
found before end of allocation"),
ReadUndefBytes(_) =>
write!(f, "attempted to read undefined bytes"),
HeapAllocNonPowerOfTwoAlignment(_) =>
write!(f, "tried to re-, de-, or allocate heap memory with alignment that is \
not a power of two"),
MachineError(ref msg) |
Unimplemented(ref msg) |
AbiViolation(ref msg) |
Intrinsic(ref msg) =>
write!(f, "{}", msg),
Panic(ref msg) =>
write!(f, "{:?}", msg),
} }
} }
} }

View file

@ -7,7 +7,7 @@
use crate::hir::def::{CtorKind, Namespace}; use crate::hir::def::{CtorKind, Namespace};
use crate::hir::def_id::DefId; use crate::hir::def_id::DefId;
use crate::hir::{self, InlineAsm as HirInlineAsm}; use crate::hir::{self, InlineAsm as HirInlineAsm};
use crate::mir::interpret::{ConstValue, PanicMessage, InterpError::Panic, Scalar}; use crate::mir::interpret::{ConstValue, PanicMessage, Scalar};
use crate::mir::visit::MirVisitable; use crate::mir::visit::MirVisitable;
use crate::rustc_serialize as serialize; use crate::rustc_serialize as serialize;
use crate::ty::adjustment::PointerCast; use crate::ty::adjustment::PointerCast;
@ -3152,13 +3152,16 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
} }
} }
Assert { ref cond, expected, ref msg, target, cleanup } => { Assert { ref cond, expected, ref msg, target, cleanup } => {
let msg = if let Panic(PanicMessage::BoundsCheck { ref len, ref index }) = *msg { use PanicMessage::*;
Panic(PanicMessage::BoundsCheck { let msg = match msg {
len: len.fold_with(folder), BoundsCheck { ref len, ref index } =>
index: index.fold_with(folder), BoundsCheck {
}) len: len.fold_with(folder),
} else { index: index.fold_with(folder),
msg.clone() },
Panic { .. } | Overflow(_) | OverflowNeg | DivisionByZero | RemainderByZero |
GeneratorResumedAfterReturn | GeneratorResumedAfterPanic =>
msg.clone(),
}; };
Assert { cond: cond.fold_with(folder), expected, msg, target, cleanup } Assert { cond: cond.fold_with(folder), expected, msg, target, cleanup }
} }
@ -3197,10 +3200,14 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
} }
Assert { ref cond, ref msg, .. } => { Assert { ref cond, ref msg, .. } => {
if cond.visit_with(visitor) { if cond.visit_with(visitor) {
if let Panic(PanicMessage::BoundsCheck { ref len, ref index }) = *msg { use PanicMessage::*;
len.visit_with(visitor) || index.visit_with(visitor) match msg {
} else { BoundsCheck { ref len, ref index } =>
false len.visit_with(visitor) || index.visit_with(visitor),
Panic { .. } | Overflow(_) | OverflowNeg |
DivisionByZero | RemainderByZero |
GeneratorResumedAfterReturn | GeneratorResumedAfterPanic =>
false
} }
} else { } else {
false false

View file

@ -514,11 +514,16 @@ macro_rules! make_mir_visitor {
fn super_assert_message(&mut self, fn super_assert_message(&mut self,
msg: & $($mutability)? AssertMessage<'tcx>, msg: & $($mutability)? AssertMessage<'tcx>,
location: Location) { location: Location) {
use crate::mir::interpret::InterpError::*; use crate::mir::interpret::PanicMessage::*;
use crate::mir::interpret::PanicMessage::BoundsCheck; match msg {
if let Panic(BoundsCheck { len, index }) = msg { BoundsCheck { len, index } => {
self.visit_operand(len, location); self.visit_operand(len, location);
self.visit_operand(index, location); self.visit_operand(index, location);
}
Panic { .. } | Overflow(_) | OverflowNeg | DivisionByZero | RemainderByZero |
GeneratorResumedAfterReturn | GeneratorResumedAfterPanic => {
// Nothing to visit
}
} }
} }

View file

@ -2,7 +2,7 @@ use rustc::middle::lang_items;
use rustc::ty::{self, Ty, TypeFoldable, Instance}; use rustc::ty::{self, Ty, TypeFoldable, Instance};
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, FnTypeExt}; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, FnTypeExt};
use rustc::mir::{self, Place, PlaceBase, Static, StaticKind}; use rustc::mir::{self, Place, PlaceBase, Static, StaticKind};
use rustc::mir::interpret::{InterpError, PanicMessage}; use rustc::mir::interpret::PanicMessage;
use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode}; use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode};
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
use crate::base; use crate::base;
@ -368,7 +368,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// checked operation, just a comparison with the minimum // checked operation, just a comparison with the minimum
// value, so we have to check for the assert message. // value, so we have to check for the assert message.
if !bx.check_overflow() { if !bx.check_overflow() {
if let InterpError::Panic(PanicMessage::OverflowNeg) = *msg { if let PanicMessage::OverflowNeg = *msg {
const_cond = Some(expected); const_cond = Some(expected);
} }
} }
@ -402,8 +402,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let col = bx.const_u32(loc.col.to_usize() as u32 + 1); let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
// Put together the arguments to the panic entry point. // Put together the arguments to the panic entry point.
let (lang_item, args) = match *msg { let (lang_item, args) = match msg {
InterpError::Panic(PanicMessage::BoundsCheck { ref len, ref index }) => { PanicMessage::BoundsCheck { ref len, ref index } => {
let len = self.codegen_operand(&mut bx, len).immediate(); let len = self.codegen_operand(&mut bx, len).immediate();
let index = self.codegen_operand(&mut bx, index).immediate(); let index = self.codegen_operand(&mut bx, index).immediate();

View file

@ -733,8 +733,8 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx
cleanup: _, cleanup: _,
} => { } => {
self.consume_operand(loc, (cond, span), flow_state); self.consume_operand(loc, (cond, span), flow_state);
use rustc::mir::interpret::{InterpError::Panic, PanicMessage}; use rustc::mir::interpret::PanicMessage;
if let Panic(PanicMessage::BoundsCheck { ref len, ref index }) = *msg { if let PanicMessage::BoundsCheck { ref len, ref index } = *msg {
self.consume_operand(loc, (len, span), flow_state); self.consume_operand(loc, (len, span), flow_state);
self.consume_operand(loc, (index, span), flow_state); self.consume_operand(loc, (index, span), flow_state);
} }

View file

@ -207,8 +207,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
cleanup: _, cleanup: _,
} => { } => {
self.consume_operand(location, cond); self.consume_operand(location, cond);
use rustc::mir::interpret::{InterpError::Panic, PanicMessage::BoundsCheck}; use rustc::mir::interpret::PanicMessage;
if let Panic(BoundsCheck { ref len, ref index }) = *msg { if let PanicMessage::BoundsCheck { ref len, ref index } = *msg {
self.consume_operand(location, len); self.consume_operand(location, len);
self.consume_operand(location, index); self.consume_operand(location, index);
} }

View file

@ -28,7 +28,7 @@ use rustc::infer::canonical::QueryRegionConstraints;
use rustc::infer::outlives::env::RegionBoundPairs; use rustc::infer::outlives::env::RegionBoundPairs;
use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin}; use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin};
use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc::mir::interpret::{InterpError::Panic, ConstValue, PanicMessage}; use rustc::mir::interpret::{ConstValue, PanicMessage};
use rustc::mir::tcx::PlaceTy; use rustc::mir::tcx::PlaceTy;
use rustc::mir::visit::{PlaceContext, Visitor, NonMutatingUseContext}; use rustc::mir::visit::{PlaceContext, Visitor, NonMutatingUseContext};
use rustc::mir::*; use rustc::mir::*;
@ -1606,7 +1606,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty); span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
} }
if let Panic(PanicMessage::BoundsCheck { ref len, ref index }) = *msg { if let PanicMessage::BoundsCheck { ref len, ref index } = *msg {
if len.ty(body, tcx) != tcx.types.usize { if len.ty(body, tcx) != tcx.types.usize {
span_mirbug!(self, len, "bounds-check length non-usize {:?}", len) span_mirbug!(self, len, "bounds-check length non-usize {:?}", len)
} }

View file

@ -4,7 +4,7 @@ use crate::build::expr::category::Category;
use crate::build::ForGuard::{OutsideGuard, RefWithinGuard}; use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
use crate::build::{BlockAnd, BlockAndExtension, Builder}; use crate::build::{BlockAnd, BlockAndExtension, Builder};
use crate::hair::*; use crate::hair::*;
use rustc::mir::interpret::{InterpError::Panic, PanicMessage::BoundsCheck}; use rustc::mir::interpret::{PanicMessage::BoundsCheck};
use rustc::mir::*; use rustc::mir::*;
use rustc::ty::{CanonicalUserTypeAnnotation, Variance}; use rustc::ty::{CanonicalUserTypeAnnotation, Variance};
@ -105,10 +105,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
), ),
); );
let msg = Panic(BoundsCheck { let msg = BoundsCheck {
len: Operand::Move(len), len: Operand::Move(len),
index: Operand::Copy(Place::from(idx)), index: Operand::Copy(Place::from(idx)),
}); };
let success = this.assert(block, Operand::Move(lt), true, msg, expr_span); let success = this.assert(block, Operand::Move(lt), true, msg, expr_span);
success.and(slice.index(idx)) success.and(slice.index(idx))
} }

View file

@ -7,7 +7,7 @@ use crate::build::expr::category::{Category, RvalueFunc};
use crate::build::{BlockAnd, BlockAndExtension, Builder}; use crate::build::{BlockAnd, BlockAndExtension, Builder};
use crate::hair::*; use crate::hair::*;
use rustc::middle::region; use rustc::middle::region;
use rustc::mir::interpret::{InterpError::Panic, PanicMessage}; use rustc::mir::interpret::PanicMessage;
use rustc::mir::*; use rustc::mir::*;
use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty, UpvarSubsts}; use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty, UpvarSubsts};
use syntax_pos::Span; use syntax_pos::Span;
@ -101,7 +101,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block, block,
Operand::Move(is_min), Operand::Move(is_min),
false, false,
Panic(PanicMessage::OverflowNeg), PanicMessage::OverflowNeg,
expr_span, expr_span,
); );
} }
@ -401,7 +401,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let val = result_value.clone().field(val_fld, ty); let val = result_value.clone().field(val_fld, ty);
let of = result_value.field(of_fld, bool_ty); let of = result_value.field(of_fld, bool_ty);
let err = Panic(PanicMessage::Overflow(op)); let err = PanicMessage::Overflow(op);
block = self.assert(block, Operand::Move(of), false, err, span); block = self.assert(block, Operand::Move(of), false, err, span);
@ -411,11 +411,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// Checking division and remainder is more complex, since we 1. always check // Checking division and remainder is more complex, since we 1. always check
// and 2. there are two possible failure cases, divide-by-zero and overflow. // and 2. there are two possible failure cases, divide-by-zero and overflow.
let (zero_err, overflow_err) = if op == BinOp::Div { let zero_err = if op == BinOp::Div {
(Panic(PanicMessage::DivisionByZero), Panic(PanicMessage::Overflow(op))) PanicMessage::DivisionByZero
} else { } else {
(Panic(PanicMessage::RemainderByZero), Panic(PanicMessage::Overflow(op))) PanicMessage::RemainderByZero
}; };
let overflow_err = PanicMessage::Overflow(op);
// Check for / 0 // Check for / 0
let is_zero = self.temp(bool_ty, span); let is_zero = self.temp(bool_ty, span);

View file

@ -7,7 +7,7 @@ use syntax::source_map::Span;
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
use super::{ use super::{
InterpResult, PointerArithmetic, InterpError, Scalar, PanicMessage, InterpResult, PointerArithmetic, InterpError, Scalar,
InterpCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal, InterpCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal,
}; };
@ -135,28 +135,31 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.goto_block(Some(target))?; self.goto_block(Some(target))?;
} else { } else {
// Compute error message // Compute error message
use rustc::mir::interpret::InterpError::*; use rustc::mir::interpret::PanicMessage::*;
return match *msg { return match msg {
Panic(PanicMessage::BoundsCheck { ref len, ref index }) => { BoundsCheck { ref len, ref index } => {
let len = self.read_immediate(self.eval_operand(len, None)?) let len = self.read_immediate(self.eval_operand(len, None)?)
.expect("can't eval len").to_scalar()? .expect("can't eval len").to_scalar()?
.to_bits(self.memory().pointer_size())? as u64; .to_bits(self.memory().pointer_size())? as u64;
let index = self.read_immediate(self.eval_operand(index, None)?) let index = self.read_immediate(self.eval_operand(index, None)?)
.expect("can't eval index").to_scalar()? .expect("can't eval index").to_scalar()?
.to_bits(self.memory().pointer_size())? as u64; .to_bits(self.memory().pointer_size())? as u64;
err!(Panic(PanicMessage::BoundsCheck { len, index })) err!(Panic(BoundsCheck { len, index }))
} }
Panic(PanicMessage::Overflow(op)) => Overflow(op) =>
Err(Panic(PanicMessage::Overflow(op)).into()), err!(Panic(Overflow(*op))),
Panic(PanicMessage::OverflowNeg) => OverflowNeg =>
Err(Panic(PanicMessage::OverflowNeg).into()), err!(Panic(OverflowNeg)),
Panic(PanicMessage::DivisionByZero) => DivisionByZero =>
Err(Panic(PanicMessage::DivisionByZero).into()), err!(Panic(DivisionByZero)),
Panic(PanicMessage::RemainderByZero) => RemainderByZero =>
Err(Panic(PanicMessage::RemainderByZero).into()), err!(Panic(RemainderByZero)),
GeneratorResumedAfterReturn | GeneratorResumedAfterReturn =>
GeneratorResumedAfterPanic => unimplemented!(), err!(Panic(GeneratorResumedAfterReturn)),
_ => bug!(), GeneratorResumedAfterPanic =>
err!(Panic(GeneratorResumedAfterPanic)),
Panic { .. } =>
bug!("`Panic` variant cannot occur in MIR"),
}; };
} }
} }

View file

@ -13,7 +13,7 @@ use rustc::mir::{
use rustc::mir::visit::{ use rustc::mir::visit::{
Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext, Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext,
}; };
use rustc::mir::interpret::{InterpError::Panic, Scalar, GlobalId, InterpResult, PanicMessage}; use rustc::mir::interpret::{Scalar, GlobalId, InterpResult, InterpError, PanicMessage};
use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt}; use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt};
use syntax_pos::{Span, DUMMY_SP}; use syntax_pos::{Span, DUMMY_SP};
use rustc::ty::subst::InternalSubsts; use rustc::ty::subst::InternalSubsts;
@ -314,8 +314,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
| HeapAllocNonPowerOfTwoAlignment(_) | HeapAllocNonPowerOfTwoAlignment(_)
| Unreachable | Unreachable
| ReadFromReturnPointer | ReadFromReturnPointer
| GeneratorResumedAfterReturn
| GeneratorResumedAfterPanic
| ReferencedConstant | ReferencedConstant
| InfiniteLoop | InfiniteLoop
=> { => {
@ -595,7 +593,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
) )
} else { } else {
if overflow { if overflow {
let err = Panic(PanicMessage::Overflow(op)).into(); let err = InterpError::Panic(PanicMessage::Overflow(op)).into();
let _: Option<()> = self.use_ecx(source_info, |_| Err(err)); let _: Option<()> = self.use_ecx(source_info, |_| Err(err));
return None; return None;
} }
@ -809,7 +807,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
self.super_terminator(terminator, location); self.super_terminator(terminator, location);
let source_info = terminator.source_info; let source_info = terminator.source_info;
match &mut terminator.kind { match &mut terminator.kind {
TerminatorKind::Assert { expected, msg, ref mut cond, .. } => { TerminatorKind::Assert { expected, ref msg, ref mut cond, .. } => {
if let Some(value) = self.eval_operand(&cond, source_info) { if let Some(value) = self.eval_operand(&cond, source_info) {
trace!("assertion on {:?} should be {:?}", value, expected); trace!("assertion on {:?} should be {:?}", value, expected);
let expected = ScalarMaybeUndef::from(Scalar::from_bool(*expected)); let expected = ScalarMaybeUndef::from(Scalar::from_bool(*expected));
@ -831,13 +829,13 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
.hir() .hir()
.as_local_hir_id(self.source.def_id()) .as_local_hir_id(self.source.def_id())
.expect("some part of a failing const eval must be local"); .expect("some part of a failing const eval must be local");
use rustc::mir::interpret::InterpError::*;
let msg = match msg { let msg = match msg {
Panic(PanicMessage::Overflow(_)) | PanicMessage::Overflow(_) |
Panic(PanicMessage::OverflowNeg) | PanicMessage::OverflowNeg |
Panic(PanicMessage::DivisionByZero) | PanicMessage::DivisionByZero |
Panic(PanicMessage::RemainderByZero) => msg.description().to_owned(), PanicMessage::RemainderByZero =>
Panic(PanicMessage::BoundsCheck { ref len, ref index }) => { msg.description().to_owned(),
PanicMessage::BoundsCheck { ref len, ref index } => {
let len = self let len = self
.eval_operand(len, source_info) .eval_operand(len, source_info)
.expect("len must be const"); .expect("len must be const");

View file

@ -1016,7 +1016,7 @@ fn create_generator_resume_function<'tcx>(
let mut cases = create_cases(body, &transform, |point| Some(point.resume)); let mut cases = create_cases(body, &transform, |point| Some(point.resume));
use rustc::mir::interpret::InterpError::{ use rustc::mir::interpret::PanicMessage::{
GeneratorResumedAfterPanic, GeneratorResumedAfterPanic,
GeneratorResumedAfterReturn, GeneratorResumedAfterReturn,
}; };

View file

@ -643,13 +643,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
fn suggest_traits_to_import<'b>(&self, fn suggest_traits_to_import<'b>(
err: &mut DiagnosticBuilder<'_>, &self,
span: Span, err: &mut DiagnosticBuilder<'_>,
rcvr_ty: Ty<'tcx>, span: Span,
item_name: ast::Ident, rcvr_ty: Ty<'tcx>,
source: SelfSource<'b>, item_name: ast::Ident,
valid_out_of_scope_traits: Vec<DefId>) { source: SelfSource<'b>,
valid_out_of_scope_traits: Vec<DefId>,
) {
if self.suggest_valid_traits(err, valid_out_of_scope_traits) { if self.suggest_valid_traits(err, valid_out_of_scope_traits) {
return; return;
} }
@ -683,30 +685,96 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
candidates.sort_by(|a, b| a.cmp(b).reverse()); candidates.sort_by(|a, b| a.cmp(b).reverse());
candidates.dedup(); candidates.dedup();
// FIXME #21673: this help message could be tuned to the case let param_type = match rcvr_ty.sty {
// of a type parameter: suggest adding a trait bound rather ty::Param(param) => Some(param),
// than implementing. ty::Ref(_, ty, _) => match ty.sty {
err.help("items from traits can only be used if the trait is implemented and in scope"); ty::Param(param) => Some(param),
let mut msg = format!("the following {traits_define} an item `{name}`, \ _ => None,
perhaps you need to implement {one_of_them}:", }
traits_define = if candidates.len() == 1 { _ => None,
"trait defines" };
} else { err.help(if param_type.is_some() {
"traits define" "items from traits can only be used if the type parameter is bounded by the trait"
}, } else {
one_of_them = if candidates.len() == 1 { "items from traits can only be used if the trait is implemented and in scope"
"it" });
} else { let mut msg = format!(
"one of them" "the following {traits_define} an item `{name}`, perhaps you need to {action} \
}, {one_of_them}:",
name = item_name); traits_define = if candidates.len() == 1 {
"trait defines"
} else {
"traits define"
},
action = if let Some(param) = param_type {
format!("restrict type parameter `{}` with", param)
} else {
"implement".to_string()
},
one_of_them = if candidates.len() == 1 {
"it"
} else {
"one of them"
},
name = item_name,
);
// Obtain the span for `param` and use it for a structured suggestion.
let mut suggested = false;
if let (Some(ref param), Some(ref table)) = (param_type, self.in_progress_tables) {
let table = table.borrow();
if let Some(did) = table.local_id_root {
let generics = self.tcx.generics_of(did);
let type_param = generics.type_param(param, self.tcx);
let hir = &self.tcx.hir();
if let Some(id) = hir.as_local_hir_id(type_param.def_id) {
// Get the `hir::Param` to verify whether it already has any bounds.
// We do this to avoid suggesting code that ends up as `T: FooBar`,
// instead we suggest `T: Foo + Bar` in that case.
let mut has_bounds = false;
if let Node::GenericParam(ref param) = hir.get(id) {
has_bounds = !param.bounds.is_empty();
}
let sp = hir.span(id);
// `sp` only covers `T`, change it so that it covers
// `T:` when appropriate
let sp = if has_bounds {
sp.to(self.tcx
.sess
.source_map()
.next_point(self.tcx.sess.source_map().next_point(sp)))
} else {
sp
};
for (i, trait_info) in candidates.iter().enumerate() { // FIXME: contrast `t.def_id` against `param.bounds` to not suggest traits
msg.push_str(&format!("\ncandidate #{}: `{}`", // already there. That can happen when the cause is that we're in a const
i + 1, // scope or associated function used as a method.
self.tcx.def_path_str(trait_info.def_id))); err.span_suggestions(
sp,
&msg[..],
candidates.iter().map(|t| format!(
"{}: {}{}",
param,
self.tcx.def_path_str(t.def_id),
if has_bounds { " +"} else { "" },
)),
Applicability::MaybeIncorrect,
);
suggested = true;
}
};
}
if !suggested {
for (i, trait_info) in candidates.iter().enumerate() {
msg.push_str(&format!(
"\ncandidate #{}: `{}`",
i + 1,
self.tcx.def_path_str(trait_info.def_id),
));
}
err.note(&msg[..]);
} }
err.note(&msg[..]);
} }
} }

View file

@ -1319,7 +1319,7 @@ impl Clean<Option<Lifetime>> for ty::RegionKind {
ty::ReEmpty | ty::ReEmpty |
ty::ReClosureBound(_) | ty::ReClosureBound(_) |
ty::ReErased => { ty::ReErased => {
debug!("Cannot clean region {:?}", self); debug!("cannot clean region {:?}", self);
None None
} }
} }
@ -4082,7 +4082,7 @@ impl ToSource for syntax_pos::Span {
fn name_from_pat(p: &hir::Pat) -> String { fn name_from_pat(p: &hir::Pat) -> String {
use rustc::hir::*; use rustc::hir::*;
debug!("Trying to get a name from pattern: {:?}", p); debug!("trying to get a name from pattern: {:?}", p);
match p.node { match p.node {
PatKind::Wild => "_".to_string(), PatKind::Wild => "_".to_string(),

View file

@ -250,7 +250,7 @@ impl Options {
None => ColorConfig::Auto, None => ColorConfig::Auto,
Some(arg) => { Some(arg) => {
early_error(ErrorOutputType::default(), early_error(ErrorOutputType::default(),
&format!("argument for --color must be `auto`, `always` or `never` \ &format!("argument for `--color` must be `auto`, `always` or `never` \
(instead was `{}`)", arg)); (instead was `{}`)", arg));
} }
}; };
@ -269,7 +269,7 @@ impl Options {
Some("short") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Short(color)), Some("short") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Short(color)),
Some(arg) => { Some(arg) => {
early_error(ErrorOutputType::default(), early_error(ErrorOutputType::default(),
&format!("argument for --error-format must be `human`, `json` or \ &format!("argument for `--error-format` must be `human`, `json` or \
`short` (instead was `{}`)", arg)); `short` (instead was `{}`)", arg));
} }
}; };

View file

@ -432,7 +432,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
}, },
sym::plugins => { sym::plugins => {
report_deprecated_attr("plugins = \"...\"", diag); report_deprecated_attr("plugins = \"...\"", diag);
eprintln!("WARNING: #![doc(plugins = \"...\")] no longer functions; \ eprintln!("WARNING: `#![doc(plugins = \"...\")]` no longer functions; \
see CVE-2018-1000622"); see CVE-2018-1000622");
continue continue
}, },

View file

@ -730,7 +730,7 @@ impl Tester for Collector {
let edition = config.edition.unwrap_or(self.edition); let edition = config.edition.unwrap_or(self.edition);
let persist_doctests = self.persist_doctests.clone(); let persist_doctests = self.persist_doctests.clone();
debug!("Creating test {}: {}", name, test); debug!("creating test {}: {}", name, test);
self.tests.push(testing::TestDescAndFn { self.tests.push(testing::TestDescAndFn {
desc: testing::TestDesc { desc: testing::TestDesc {
name: testing::DynTestName(name), name: testing::DynTestName(name),

View file

@ -96,7 +96,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
pub fn visit_variant_data(&mut self, item: &'tcx hir::Item, pub fn visit_variant_data(&mut self, item: &'tcx hir::Item,
name: ast::Name, sd: &'tcx hir::VariantData, name: ast::Name, sd: &'tcx hir::VariantData,
generics: &'tcx hir::Generics) -> Struct<'tcx> { generics: &'tcx hir::Generics) -> Struct<'tcx> {
debug!("Visiting struct"); debug!("visiting struct");
let struct_type = struct_type_from_def(&*sd); let struct_type = struct_type_from_def(&*sd);
Struct { Struct {
id: item.hir_id, id: item.hir_id,
@ -115,7 +115,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
pub fn visit_union_data(&mut self, item: &'tcx hir::Item, pub fn visit_union_data(&mut self, item: &'tcx hir::Item,
name: ast::Name, sd: &'tcx hir::VariantData, name: ast::Name, sd: &'tcx hir::VariantData,
generics: &'tcx hir::Generics) -> Union<'tcx> { generics: &'tcx hir::Generics) -> Union<'tcx> {
debug!("Visiting union"); debug!("visiting union");
let struct_type = struct_type_from_def(&*sd); let struct_type = struct_type_from_def(&*sd);
Union { Union {
id: item.hir_id, id: item.hir_id,
@ -134,7 +134,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
pub fn visit_enum_def(&mut self, it: &'tcx hir::Item, pub fn visit_enum_def(&mut self, it: &'tcx hir::Item,
name: ast::Name, def: &'tcx hir::EnumDef, name: ast::Name, def: &'tcx hir::EnumDef,
generics: &'tcx hir::Generics) -> Enum<'tcx> { generics: &'tcx hir::Generics) -> Enum<'tcx> {
debug!("Visiting enum"); debug!("visiting enum");
Enum { Enum {
name, name,
variants: def.variants.iter().map(|v| Variant { variants: def.variants.iter().map(|v| Variant {
@ -161,7 +161,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
header: hir::FnHeader, header: hir::FnHeader,
generics: &'tcx hir::Generics, generics: &'tcx hir::Generics,
body: hir::BodyId) { body: hir::BodyId) {
debug!("Visiting fn"); debug!("visiting fn");
let macro_kind = item.attrs.iter().filter_map(|a| { let macro_kind = item.attrs.iter().filter_map(|a| {
if a.check_name(sym::proc_macro) { if a.check_name(sym::proc_macro) {
Some(MacroKind::Bang) Some(MacroKind::Bang)
@ -371,7 +371,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
pub fn visit_item(&mut self, item: &'tcx hir::Item, pub fn visit_item(&mut self, item: &'tcx hir::Item,
renamed: Option<ast::Ident>, om: &mut Module<'tcx>) { renamed: Option<ast::Ident>, om: &mut Module<'tcx>) {
debug!("Visiting item {:?}", item); debug!("visiting item {:?}", item);
let ident = renamed.unwrap_or(item.ident); let ident = renamed.unwrap_or(item.ident);
if item.vis.node.is_pub() { if item.vis.node.is_pub() {

View file

@ -273,6 +273,7 @@
#![feature(link_args)] #![feature(link_args)]
#![feature(linkage)] #![feature(linkage)]
#![feature(maybe_uninit_ref)] #![feature(maybe_uninit_ref)]
#![feature(maybe_uninit_slice)]
#![feature(mem_take)] #![feature(mem_take)]
#![feature(needs_panic_runtime)] #![feature(needs_panic_runtime)]
#![feature(never_type)] #![feature(never_type)]

View file

@ -1884,7 +1884,7 @@ pub unsafe fn clock_res_get(clock_id_: clockid, resolution_: &mut timestamp) ->
/// **time**: /// **time**:
/// The time value of the clock. /// The time value of the clock.
#[inline] #[inline]
pub unsafe fn clock_time_get(clock_id_: clockid, precision_: timestamp, time_: &mut timestamp) -> errno { pub unsafe fn clock_time_get(clock_id_: clockid, precision_: timestamp, time_: *mut timestamp) -> errno {
cloudabi_sys_clock_time_get(clock_id_, precision_, time_) cloudabi_sys_clock_time_get(clock_id_, precision_, time_)
} }
@ -2643,7 +2643,7 @@ pub unsafe fn mem_unmap(mapping_: &mut [u8]) -> errno {
/// **nevents**: /// **nevents**:
/// The number of events stored. /// The number of events stored.
#[inline] #[inline]
pub unsafe fn poll(in_: *const subscription, out_: *mut event, nsubscriptions_: usize, nevents_: &mut usize) -> errno { pub unsafe fn poll(in_: *const subscription, out_: *mut event, nsubscriptions_: usize, nevents_: *mut usize) -> errno {
cloudabi_sys_poll(in_, out_, nsubscriptions_, nevents_) cloudabi_sys_poll(in_, out_, nsubscriptions_, nevents_)
} }

View file

@ -79,16 +79,21 @@ impl Condvar {
}, },
..mem::zeroed() ..mem::zeroed()
}; };
let mut event: abi::event = mem::uninitialized(); let mut event: mem::MaybeUninit<abi::event> = mem::MaybeUninit::uninit();
let mut nevents: usize = mem::uninitialized(); let mut nevents: mem::MaybeUninit<usize> = mem::MaybeUninit::uninit();
let ret = abi::poll(&subscription, &mut event, 1, &mut nevents); let ret = abi::poll(
&subscription,
event.as_mut_ptr(),
1,
nevents.as_mut_ptr()
);
assert_eq!( assert_eq!(
ret, ret,
abi::errno::SUCCESS, abi::errno::SUCCESS,
"Failed to wait on condition variable" "Failed to wait on condition variable"
); );
assert_eq!( assert_eq!(
event.error, event.assume_init().error,
abi::errno::SUCCESS, abi::errno::SUCCESS,
"Failed to wait on condition variable" "Failed to wait on condition variable"
); );
@ -131,21 +136,27 @@ impl Condvar {
..mem::zeroed() ..mem::zeroed()
}, },
]; ];
let mut events: [abi::event; 2] = mem::uninitialized(); let mut events: [mem::MaybeUninit<abi::event>; 2] = [mem::MaybeUninit::uninit(); 2];
let mut nevents: usize = mem::uninitialized(); let mut nevents: mem::MaybeUninit<usize> = mem::MaybeUninit::uninit();
let ret = abi::poll(subscriptions.as_ptr(), events.as_mut_ptr(), 2, &mut nevents); let ret = abi::poll(
subscriptions.as_ptr(),
mem::MaybeUninit::first_ptr_mut(&mut events),
2,
nevents.as_mut_ptr()
);
assert_eq!( assert_eq!(
ret, ret,
abi::errno::SUCCESS, abi::errno::SUCCESS,
"Failed to wait on condition variable" "Failed to wait on condition variable"
); );
let nevents = nevents.assume_init();
for i in 0..nevents { for i in 0..nevents {
assert_eq!( assert_eq!(
events[i].error, events[i].assume_init().error,
abi::errno::SUCCESS, abi::errno::SUCCESS,
"Failed to wait on condition variable" "Failed to wait on condition variable"
); );
if events[i].type_ == abi::eventtype::CONDVAR { if events[i].assume_init().type_ == abi::eventtype::CONDVAR {
return true; return true;
} }
} }

View file

@ -61,8 +61,11 @@ pub use libc::strlen;
pub fn hashmap_random_keys() -> (u64, u64) { pub fn hashmap_random_keys() -> (u64, u64) {
unsafe { unsafe {
let mut v = mem::uninitialized(); let mut v: mem::MaybeUninit<(u64, u64)> = mem::MaybeUninit::uninit();
libc::arc4random_buf(&mut v as *mut _ as *mut libc::c_void, mem::size_of_val(&v)); libc::arc4random_buf(
v v.as_mut_ptr() as *mut libc::c_void,
mem::size_of_val(&v)
);
v.assume_init()
} }
} }

View file

@ -1,5 +1,6 @@
use crate::cell::UnsafeCell; use crate::cell::UnsafeCell;
use crate::mem; use crate::mem;
use crate::mem::MaybeUninit;
use crate::sync::atomic::{AtomicU32, Ordering}; use crate::sync::atomic::{AtomicU32, Ordering};
use crate::sys::cloudabi::abi; use crate::sys::cloudabi::abi;
use crate::sys::rwlock::{self, RWLock}; use crate::sys::rwlock::{self, RWLock};
@ -47,24 +48,27 @@ impl Mutex {
} }
pub struct ReentrantMutex { pub struct ReentrantMutex {
lock: UnsafeCell<AtomicU32>, lock: UnsafeCell<MaybeUninit<AtomicU32>>,
recursion: UnsafeCell<u32>, recursion: UnsafeCell<MaybeUninit<u32>>,
} }
impl ReentrantMutex { impl ReentrantMutex {
pub unsafe fn uninitialized() -> ReentrantMutex { pub unsafe fn uninitialized() -> ReentrantMutex {
mem::uninitialized() ReentrantMutex {
lock: UnsafeCell::new(MaybeUninit::uninit()),
recursion: UnsafeCell::new(MaybeUninit::uninit())
}
} }
pub unsafe fn init(&mut self) { pub unsafe fn init(&mut self) {
self.lock = UnsafeCell::new(AtomicU32::new(abi::LOCK_UNLOCKED.0)); self.lock = UnsafeCell::new(MaybeUninit::new(AtomicU32::new(abi::LOCK_UNLOCKED.0)));
self.recursion = UnsafeCell::new(0); self.recursion = UnsafeCell::new(MaybeUninit::new(0));
} }
pub unsafe fn try_lock(&self) -> bool { pub unsafe fn try_lock(&self) -> bool {
// Attempt to acquire the lock. // Attempt to acquire the lock.
let lock = self.lock.get(); let lock = (*self.lock.get()).as_mut_ptr();
let recursion = self.recursion.get(); let recursion = (*self.recursion.get()).as_mut_ptr();
if let Err(old) = (*lock).compare_exchange( if let Err(old) = (*lock).compare_exchange(
abi::LOCK_UNLOCKED.0, abi::LOCK_UNLOCKED.0,
__pthread_thread_id.0 | abi::LOCK_WRLOCKED.0, __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
@ -109,8 +113,8 @@ impl ReentrantMutex {
} }
pub unsafe fn unlock(&self) { pub unsafe fn unlock(&self) {
let lock = self.lock.get(); let lock = (*self.lock.get()).as_mut_ptr();
let recursion = self.recursion.get(); let recursion = (*self.recursion.get()).as_mut_ptr();
assert_eq!( assert_eq!(
(*lock).load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0, (*lock).load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0,
__pthread_thread_id.0 | abi::LOCK_WRLOCKED.0, __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
@ -136,8 +140,8 @@ impl ReentrantMutex {
} }
pub unsafe fn destroy(&self) { pub unsafe fn destroy(&self) {
let lock = self.lock.get(); let lock = (*self.lock.get()).as_mut_ptr();
let recursion = self.recursion.get(); let recursion = (*self.recursion.get()).as_mut_ptr();
assert_eq!( assert_eq!(
(*lock).load(Ordering::Relaxed), (*lock).load(Ordering::Relaxed),
abi::LOCK_UNLOCKED.0, abi::LOCK_UNLOCKED.0,

View file

@ -18,10 +18,10 @@ pub fn checked_dur2intervals(dur: &Duration) -> Option<abi::timestamp> {
impl Instant { impl Instant {
pub fn now() -> Instant { pub fn now() -> Instant {
unsafe { unsafe {
let mut t = mem::uninitialized(); let mut t: mem::MaybeUninit<abi::timestamp> = mem::MaybeUninit::uninit();
let ret = abi::clock_time_get(abi::clockid::MONOTONIC, 0, &mut t); let ret = abi::clock_time_get(abi::clockid::MONOTONIC, 0, t.as_mut_ptr());
assert_eq!(ret, abi::errno::SUCCESS); assert_eq!(ret, abi::errno::SUCCESS);
Instant { t } Instant { t: t.assume_init() }
} }
} }
@ -59,10 +59,10 @@ pub struct SystemTime {
impl SystemTime { impl SystemTime {
pub fn now() -> SystemTime { pub fn now() -> SystemTime {
unsafe { unsafe {
let mut t = mem::uninitialized(); let mut t: mem::MaybeUninit<abi::timestamp> = mem::MaybeUninit::uninit();
let ret = abi::clock_time_get(abi::clockid::REALTIME, 0, &mut t); let ret = abi::clock_time_get(abi::clockid::REALTIME, 0, t.as_mut_ptr());
assert_eq!(ret, abi::errno::SUCCESS); assert_eq!(ret, abi::errno::SUCCESS);
SystemTime { t } SystemTime { t: t.assume_init() }
} }
} }

View file

@ -30,7 +30,7 @@ use std::iter;
use std::ops::DerefMut; use std::ops::DerefMut;
pub fn mark_used(attr: &Attribute) { pub fn mark_used(attr: &Attribute) {
debug!("Marking {:?} as used.", attr); debug!("marking {:?} as used", attr);
GLOBALS.with(|globals| { GLOBALS.with(|globals| {
globals.used_attrs.lock().insert(attr.id); globals.used_attrs.lock().insert(attr.id);
}); });
@ -43,7 +43,7 @@ pub fn is_used(attr: &Attribute) -> bool {
} }
pub fn mark_known(attr: &Attribute) { pub fn mark_known(attr: &Attribute) {
debug!("Marking {:?} as known.", attr); debug!("marking {:?} as known", attr);
GLOBALS.with(|globals| { GLOBALS.with(|globals| {
globals.known_attrs.lock().insert(attr.id); globals.known_attrs.lock().insert(attr.id);
}); });

View file

@ -182,7 +182,7 @@ beta compilers will not comply.
Example of erroneous code (on a stable compiler): Example of erroneous code (on a stable compiler):
```ignore (depends on release channel) ```ignore (depends on release channel)
#![feature(non_ascii_idents)] // error: #![feature] may not be used on the #![feature(non_ascii_idents)] // error: `#![feature]` may not be used on the
// stable release channel // stable release channel
``` ```

View file

@ -602,7 +602,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
None => return TokenStream::empty(), None => return TokenStream::empty(),
} }
self.cx.span_err(span, "custom attribute invocations must be \ self.cx.span_err(span, "custom attribute invocations must be \
of the form #[foo] or #[foo(..)], the macro name must only be \ of the form `#[foo]` or `#[foo(..)]`, the macro name must only be \
followed by a delimiter token"); followed by a delimiter token");
TokenStream::empty() TokenStream::empty()
} }

View file

@ -190,7 +190,7 @@ pub(crate) fn emit_unescape_error(
handler.span_err(span, "empty character literal") handler.span_err(span, "empty character literal")
} }
EscapeError::LoneSlash => { EscapeError::LoneSlash => {
panic!("lexer accepted unterminated literal with trailing slash") handler.span_err(span, "invalid trailing slash in literal")
} }
} }
} }

View file

@ -414,7 +414,7 @@ fn get_test_runner(sd: &errors::Handler, krate: &ast::Crate) -> Option<ast::Path
test_attr.meta_item_list().map(|meta_list| { test_attr.meta_item_list().map(|meta_list| {
if meta_list.len() != 1 { if meta_list.len() != 1 {
sd.span_fatal(test_attr.span, sd.span_fatal(test_attr.span,
"#![test_runner(..)] accepts exactly 1 argument").raise() "`#![test_runner(..)]` accepts exactly 1 argument").raise()
} }
match meta_list[0].meta_item() { match meta_list[0].meta_item() {
Some(meta_item) if meta_item.is_word() => meta_item.path.clone(), Some(meta_item) if meta_item.is_word() => meta_item.path.clone(),

View file

@ -4,9 +4,11 @@ error[E0599]: no function or associated item named `dim` found for type `D` in t
LL | entries: [T; D::dim()], LL | entries: [T; D::dim()],
| ^^^ function or associated item not found in `D` | ^^^ function or associated item not found in `D`
| |
= help: items from traits can only be used if the trait is implemented and in scope = help: items from traits can only be used if the type parameter is bounded by the trait
= note: the following trait defines an item `dim`, perhaps you need to implement it: help: the following trait defines an item `dim`, perhaps you need to restrict type parameter `D` with it:
candidate #1: `Dim` |
LL | pub struct Vector<T, D: Dim + Dim> {
| ^^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View file

@ -0,0 +1,3 @@
"\u\\"
//~^ ERROR incorrect unicode escape sequence
//~| ERROR invalid trailing slash in literal

View file

@ -0,0 +1,16 @@
error: incorrect unicode escape sequence
--> $DIR/issue-62913.rs:1:2
|
LL | "\u\"
| ^^^ incorrect unicode escape sequence
|
= help: format of unicode escape sequences is `\u{...}`
error: invalid trailing slash in literal
--> $DIR/issue-62913.rs:1:5
|
LL | "\u\"
| ^
error: aborting due to 2 previous errors

View file

@ -34,7 +34,7 @@ LL | #![empty_attr]
= note: for more information, see https://github.com/rust-lang/rust/issues/54727 = note: for more information, see https://github.com/rust-lang/rust/issues/54727
= help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable
error: custom attribute invocations must be of the form #[foo] or #[foo(..)], the macro name must only be followed by a delimiter token error: custom attribute invocations must be of the form `#[foo]` or `#[foo(..)]`, the macro name must only be followed by a delimiter token
--> $DIR/proc-macro-gates.rs:21:1 --> $DIR/proc-macro-gates.rs:21:1
| |
LL | #[empty_attr = "y"] LL | #[empty_attr = "y"]

View file

@ -61,9 +61,11 @@ note: the candidate is defined in the trait `ManyImplTrait`
LL | fn is_str() -> bool { LL | fn is_str() -> bool {
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^
= help: to disambiguate the method call, write `ManyImplTrait::is_str(t)` instead = help: to disambiguate the method call, write `ManyImplTrait::is_str(t)` instead
= help: items from traits can only be used if the trait is implemented and in scope = help: items from traits can only be used if the type parameter is bounded by the trait
= note: the following trait defines an item `is_str`, perhaps you need to implement it: help: the following trait defines an item `is_str`, perhaps you need to restrict type parameter `T` with it:
candidate #1: `ManyImplTrait` |
LL | fn param_bound<T: ManyImplTrait + ManyImplTrait>(t: T) -> bool {
| ^^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors error: aborting due to 3 previous errors

View file

@ -0,0 +1,13 @@
trait Foo {
fn method(&self) {}
}
fn call_method<T: std::fmt::Debug>(x: &T) {
x.method() //~ ERROR E0599
}
fn call_method_2<T>(x: T) {
x.method() //~ ERROR E0599
}
fn main() {}

View file

@ -0,0 +1,27 @@
error[E0599]: no method named `method` found for type `&T` in the current scope
--> $DIR/issue-21673.rs:6:7
|
LL | x.method()
| ^^^^^^
|
= help: items from traits can only be used if the type parameter is bounded by the trait
help: the following trait defines an item `method`, perhaps you need to restrict type parameter `T` with it:
|
LL | fn call_method<T: Foo + std::fmt::Debug>(x: &T) {
| ^^^^^^^^
error[E0599]: no method named `method` found for type `T` in the current scope
--> $DIR/issue-21673.rs:10:7
|
LL | x.method()
| ^^^^^^
|
= help: items from traits can only be used if the type parameter is bounded by the trait
help: the following trait defines an item `method`, perhaps you need to restrict type parameter `T` with it:
|
LL | fn call_method_2<T: Foo>(x: T) {
| ^^^^^^
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0599`.

View file

@ -0,0 +1,8 @@
#[repr(u8)]
enum Alpha {
V1 = 41,
V2 = Self::V1 as u8 + 1, // OK; See #50072.
V3 = Self::V1 {} as u8 + 2, //~ ERROR cycle detected when const-evaluating
}
fn main() {}

View file

@ -0,0 +1,28 @@
error[E0391]: cycle detected when const-evaluating + checking `Alpha::V3::{{constant}}#0`
--> $DIR/self-in-enum-definition.rs:5:10
|
LL | V3 = Self::V1 {} as u8 + 2,
| ^^^^^^^^
|
note: ...which requires const-evaluating `Alpha::V3::{{constant}}#0`...
--> $DIR/self-in-enum-definition.rs:5:10
|
LL | V3 = Self::V1 {} as u8 + 2,
| ^^^^^^^^
= note: ...which requires computing layout of `Alpha`...
= note: ...which again requires const-evaluating + checking `Alpha::V3::{{constant}}#0`, completing the cycle
note: cycle used when collecting item types in top-level module
--> $DIR/self-in-enum-definition.rs:1:1
|
LL | / #[repr(u8)]
LL | | enum Alpha {
LL | | V1 = 41,
LL | | V2 = Self::V1 as u8 + 1, // OK; See #50072.
... |
LL | |
LL | | fn main() {}
| |____________^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0391`.