rust/tests
Matthias Krüger 011289c9d4
Rollup merge of #129195 - RalfJung:const-mut-refs, r=fee1-dead
Stabilize `&mut` (and `*mut`) as well as `&Cell` (and `*const Cell`) in const

This stabilizes `const_mut_refs` and `const_refs_to_cell`. That allows a bunch of new things in const contexts:
- Mentioning `&mut` types
- Creating `&mut` and `*mut` values
- Creating `&T` and `*const T` values where `T` contains interior mutability
- Dereferencing `&mut` and `*mut` values (both for reads and writes)

The same rules as at runtime apply: mutating immutable data is UB. This includes mutation through pointers derived from shared references; the following is diagnosed with a hard error:
```rust
#[allow(invalid_reference_casting)]
const _: () = {
    let mut val = 15;
    let ptr = &val as *const i32 as *mut i32;
    unsafe { *ptr = 16; }
};
```

The main limitation that is enforced is that the final value of a const (or non-`mut` static) may not contain `&mut` values nor interior mutable `&` values. This is necessary because the memory those references point to becomes *read-only* when the constant is done computing, so (interior) mutable references to such memory would be pretty dangerous. We take a multi-layered approach here to ensuring no mutable references escape the initializer expression:
- A static analysis rejects (interior) mutable references when the referee looks like it may outlive the current MIR body.
- To be extra sure, this static check is complemented by a "safety net" of dynamic checks. ("Dynamic" in the sense of "running during/after const-evaluation, e.g. at runtime of this code" -- in contrast to "static" which works entirely by looking at the MIR without evaluating it.)
  - After the final value is computed, we do a type-driven traversal of the entire value, and if we find any `&mut` or interior-mutable `&` we error out.
  - However, the type-driven traversal cannot traverse `union` or raw pointers, so there is a second dynamic check where if the final value of the const contains any pointer that was not derived from a shared reference, we complain. This is currently a future-compat lint, but will become an ICE in #128543. On the off-chance that it's actually possible to trigger this lint on stable, I'd prefer if we could make it an ICE before stabilizing const_mut_refs, but it's not a hard blocker. This part of the "safety net" is only active for mutable references since with shared references, it has false positives.

Altogether this should prevent people from leaking (interior) mutable references out of the const initializer.

While updating the tests I learned that surprisingly, this code gets rejected:
```rust
const _: Vec<i32> = {
    let mut x = Vec::<i32>::new(); //~ ERROR destructor of `Vec<i32>` cannot be evaluated at compile-time
    let r = &mut x;
    let y = x;
    y
};
```
The analysis that rejects destructors in `const` is very conservative when it sees an `&mut` being created to `x`, and then considers `x` to be always live. See [here](https://github.com/rust-lang/rust/issues/65394#issuecomment-541499219) for a longer explanation. `const_precise_live_drops` will solve this, so I consider this problem to be tracked by https://github.com/rust-lang/rust/issues/73255.

Cc `@rust-lang/wg-const-eval` `@rust-lang/lang`
Cc https://github.com/rust-lang/rust/issues/57349
Cc https://github.com/rust-lang/rust/issues/80384
2024-09-15 11:55:45 +02:00
..
assembly small_data_threshold.rs: Adapt to LLVM head changes 2024-09-12 09:53:59 +02:00
auxiliary
codegen Update try_question_mark_nop.rs test 2024-09-14 13:30:36 +08:00
codegen-units Fix and enable disabled codegen-units tests 2024-08-10 14:03:27 -04:00
coverage coverage: Extract executor::block_on from several async coverage tests 2024-09-10 16:08:36 +10:00
coverage-run-rustdoc
crashes Auto merge of #128543 - RalfJung:const-interior-mut, r=fee1-dead 2024-09-14 21:11:04 +00:00
debuginfo Auto merge of #130052 - khuey:clear-dilocation-after-const-emission, r=michaelwoerister 2024-09-13 08:57:41 +00:00
incremental simd_shuffle: require index argument to be a vector 2024-09-14 14:43:24 +02:00
mir-opt Simplify the canonical clone method to copy 2024-09-14 13:30:35 +08:00
pretty Use doc(hidden) instead of allow(missing_docs) in the test harness 2024-09-11 12:14:35 +02:00
run-make Rollup merge of #130156 - nebulark:test_buildinfo, r=jieyouxu 2024-09-12 20:37:15 +10:00
run-pass-valgrind
rustdoc rustdoc: rename issue-\d+.rs tests to have meaningful names 2024-09-12 13:47:51 -07:00
rustdoc-gui Rollup merge of #129796 - GuillaumeGomez:unify-code-examples, r=notriddle 2024-09-05 18:58:56 +02:00
rustdoc-js rustdoc-search: allow trailing Foo -> arg search 2024-09-05 17:58:05 -07:00
rustdoc-js-std rustdoc-search: allow trailing Foo -> arg search 2024-09-05 17:58:05 -07:00
rustdoc-json rustdoc: normalise type/field names in rustdoc-json-types/jsondoclint 2024-09-01 23:58:08 +03:00
rustdoc-ui rustdoc: re-bless stderrs after renaming the test case 2024-09-12 13:48:51 -07:00
ui Rollup merge of #129195 - RalfJung:const-mut-refs, r=fee1-dead 2024-09-15 11:55:45 +02:00
ui-fulldeps Re-enable ConstArgKind::Path lowering by default 2024-09-12 13:56:01 -04:00
COMPILER_TESTS.md