Give a message with a span on MIR validation error
It was handy to get a source+line link for rust-lang/rust#143833, even if it's just to the function and not necessarily to the statement.
r? mir
And introduce two new directives for ui tests:
* `run-crash`
* `run-fail-or-crash`
Normally a `run-fail` ui test like tests that panic shall not be
terminated by a signal like `SIGABRT`. So begin having that as a hard
requirement.
Some of our current tests do terminate by a signal/crash however.
Introduce and use `run-crash` for those tests. Note that Windows crashes
are not handled by signals but by certain high bits set on the process
exit code. Example exit code for crash on Windows: `0xc000001d`.
Because of this, we define "crash" on all platforms as "not exit with
success and not exit with a regular failure code in the range 1..=127".
Some tests behave differently on different targets:
* Targets without unwind support will abort (crash) instead of exit with
failure code 101 after panicking. As a special case, allow crashes for
`run-fail` tests for such targets.
* Different sanitizer implementations handle detected memory problems
differently. Some abort (crash) the process while others exit with
failure code 1. Introduce and use `run-fail-or-crash` for such tests.
Store the type of each GVN value
MIR is fully typed, so type information is an integral part of what defines a value. GVN currently tries to circumvent storing types, which creates all sorts of complexities.
This PR stores the type along with the enum `Value` when defining a value index. This allows to simplify a lot of code.
Fixesrust-lang/rust#128094Fixesrust-lang/rust#135128
r? ``````@ghost`````` for perf
The endianness can change the test expectation for the enum check.
This change is fixing the failing tests on big endian by changing
the tests so that they behave the same as on little endian.
Make the enum check work for negative discriminants
The discriminant check was not working correctly for negative numbers. This change fixes that by masking out the relevant bits correctly.
Fixesrust-lang/rust#143218.
Insert checks for enum discriminants when debug assertions are enabled
Similar to the existing null-pointer and alignment checks, this checks for valid enum discriminants on creation of enums through unsafe transmutes. Essentially this sanitizes patterns like the following:
```rust
let val: MyEnum = unsafe { std::mem::transmute<u32, MyEnum>(42) };
```
An extension of this check will be done in a follow-up that explicitly sanitizes for extern enum values that come into Rust from e.g. C/C++.
This check is similar to Miri's capabilities of checking for valid construction of enum values.
This PR is inspired by saethlin@'s PR
https://github.com/rust-lang/rust/pull/104862. Thank you so much for keeping this code up and the detailed comments!
I also pair-programmed large parts of this together with vabr-g@.
r? `@saethlin`
Similar to the existing nullpointer and alignment checks, this checks
for valid enum discriminants on creation of enums through unsafe
transmutes. Essentially this sanitizes patterns like the following:
```rust
let val: MyEnum = unsafe { std::mem::transmute<u32, MyEnum>(42) };
```
An extension of this check will be done in a follow-up that explicitly
sanitizes for extern enum values that come into Rust from e.g. C/C++.
This check is similar to Miri's capabilities of checking for valid
construction of enum values.
This PR is inspired by saethlin@'s PR
https://github.com/rust-lang/rust/pull/104862. Thank you so much for
keeping this code up and the detailed comments!
I also pair-programmed large parts of this together with vabr-g@.
The current alignment check does not include checks for creating
misaligned references from raw pointers, which is now added in this
patch.
When inserting the check we need to be careful with references to
field projections (e.g. `&(*ptr).a`), in which case the resulting
reference must be aligned according to the field type and not the
type of the pointer.
```
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
--> $DIR/attempted-access-non-fatal.rs:7:15
|
LL | let _ = 2.l;
| ^
|
help: if intended to be a floating point literal, consider adding a `0` after the period and a `f64` suffix
|
LL - let _ = 2.l;
LL + let _ = 2.0f64;
|
```
Similar to how the alignment is already checked, this adds a check
for null pointer dereferences in debug mode. It is implemented similarly
to the alignment check as a MirPass.
This is related to a 2025H1 project goal for better UB checks in debug
mode: https://github.com/rust-lang/rust-project-goals/pull/177.
Reword resolve errors caused by likely missing crate in dep tree
Reword label and add `help`:
```
error[E0432]: unresolved import `some_novel_crate`
--> f704.rs:1:5
|
1 | use some_novel_crate::Type;
| ^^^^^^^^^^^^^^^^ use of unresolved module or unlinked crate `some_novel_crate`
|
= help: if you wanted to use a crate named `some_novel_crate`, use `cargo add some_novel_crate` to add it to your `Cargo.toml`
```
Fix#133137.
```
error[E0432]: unresolved import `some_novel_crate`
--> file.rs:1:5
|
1 | use some_novel_crate::Type;
| ^^^^^^^^^^^^^^^^ use of unresolved module or unlinked crate `some_novel_crate`
```
On resolve errors where there might be a missing crate, mention `cargo add foo`:
```
error[E0433]: failed to resolve: use of unresolved module or unlinked crate `nope`
--> $DIR/conflicting-impl-with-err.rs:4:11
|
LL | impl From<nope::Thing> for Error {
| ^^^^ use of unresolved module or unlinked crate `nope`
|
= help: if you wanted to use a crate named `nope`, use `cargo add nope` to add it to your `Cargo.toml`
```
On nightly, we mention the trait is unstable
```
error[E0277]: the trait bound `T: Unstable` is not satisfied
--> $DIR/unstable-trait-suggestion.rs:13:9
|
LL | foo(t)
| --- ^ the trait `Unstable` is not implemented for `T`
| |
| required by a bound introduced by this call
|
note: required by a bound in `foo`
--> $DIR/unstable-trait-suggestion.rs:9:11
|
LL | fn foo<T: Unstable>(_: T) {}
| ^^^^^^^^ required by this bound in `foo`
help: consider restricting type parameter `T` but it is an `unstable` trait
|
LL | pub fn demo<T: Unstable>(t: T) {
| ++++++++++
```
On stable, we don't suggest the trait at all
```
error[E0277]: the trait bound `T: Unstable` is not satisfied
--> $DIR/unstable-trait-suggestion.rs:13:9
|
LL | foo(t)
| --- ^ the trait `Unstable` is not implemented for `T`
| |
| required by a bound introduced by this call
|
note: required by a bound in `foo`
--> $DIR/unstable-trait-suggestion.rs:9:11
|
LL | fn foo<T: Unstable>(_: T) {}
| ^^^^^^^^ required by this bound in `foo`
```