rust/library/std/src
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
..
backtrace remove redundant imports 2023-12-10 10:56:22 +08:00
collections Stabilize entry_insert 2024-09-13 11:45:44 +12:00
env remove redundant imports 2023-12-10 10:56:22 +08:00
error Reformat use declarations. 2024-07-29 08:26:52 +10:00
f16 std float tests: special-case Miri in feature detection 2024-08-08 12:17:50 +02:00
f32 these tests seem to work fine on i586 these days 2024-09-10 15:57:40 -07:00
f64 these tests seem to work fine on i586 these days 2024-09-10 15:57:40 -07:00
f128 Add core functions for f16 and f128 that require math routines 2024-08-01 15:38:53 -04:00
ffi fix: correct {Path,OsStr}::to_string_lossy() docs 2024-09-05 00:48:00 +09:00
fs Remove now redundant check in symlink_hard_link test 2024-09-07 13:24:16 +02:00
hash Reformat use declarations. 2024-07-29 08:26:52 +10:00
io Rollup merge of #130042 - lolbinarycat:bufreaker_peek_eof, r=Amanieu 2024-09-15 12:14:55 +10:00
net Reformat use declarations. 2024-07-29 08:26:52 +10:00
num removed nonfunctioning benchmark 2024-01-11 11:30:12 -05:00
os Rollup merge of #130168 - juliusl:pr/fix-win-fs-change-time-links, r=ChrisDenton 2024-09-11 15:53:23 -07:00
panic review: fix nits and move panic safety tests to the correct place 2020-09-25 23:10:24 +02:00
path impl CloneToUninit for Path and OsStr 2024-07-29 20:44:39 +03:00
pipe Cleanup sys module to match house style 2024-07-30 19:22:54 +00:00
prelude Avoid comments that describe multiple use items. 2024-07-17 08:02:46 +10:00
process Reformat use declarations. 2024-07-29 08:26:52 +10:00
sync Adjust doc comment of Condvar::wait_while 2024-09-06 13:36:09 +02:00
sys Rollup merge of #130101 - RalfJung:const-cleanup, r=fee1-dead 2024-09-12 19:03:41 +02:00
sys_common Rollup merge of #127623 - lolbinarycat:fix_remove_dir_all, r=Amanieu 2024-08-23 06:26:51 +02:00
thread replace placeholder version 2024-09-03 20:54:02 +01:00
time Reformat use declarations. 2024-07-29 08:26:52 +10:00
alloc.rs Reformat use declarations. 2024-07-29 08:26:52 +10:00
ascii.rs Reformat use declarations. 2024-07-29 08:26:52 +10:00
backtrace.rs Reformat use declarations. 2024-07-29 08:26:52 +10:00
env.rs update cfgs 2024-09-05 17:24:01 +01:00
error.rs chore: refactor backtrace formatting 2024-08-02 00:24:29 +09:00
f16.rs copysign with sign being a NaN is non-portable 2024-08-28 12:06:28 +02:00
f32.rs copysign with sign being a NaN is non-portable 2024-08-28 12:06:28 +02:00
f64.rs copysign with sign being a NaN is non-portable 2024-08-28 12:06:28 +02:00
f128.rs copysign with sign being a NaN is non-portable 2024-08-28 12:06:28 +02:00
fs.rs fix: fs::remove_dir_all: treat ENOENT as success 2024-08-22 14:18:42 -04:00
keyword_docs.rs Trivial grammar fix in const keyword docs 2024-08-06 21:59:04 -05:00
lib.miri.rs add 'x.py miri', and make it work for 'library/{core,alloc,std}' 2024-04-03 20:27:20 +02:00
lib.rs stabilize const_mut_refs 2024-09-15 09:51:32 +02:00
macros.rs Add math functions for f16 and f128 2024-08-01 15:38:51 -04:00
num.rs Reformat use declarations. 2024-07-29 08:26:52 +10:00
panic.rs std: do not overwrite style in get_backtrace_style 2024-08-12 10:08:56 +02:00
panicking.rs Auto merge of #129019 - kromych:master, r=workingjubilee 2024-09-08 10:28:26 +00:00
pat.rs Add pattern types to parser 2024-04-08 11:57:17 +00:00
path.rs Fixup docs for PathBuf 2024-09-11 22:46:06 -07:00
pipe.rs Reformat use declarations. 2024-07-29 08:26:52 +10:00
process.rs process.rs: remove "Basic usage" text where not useful 2024-09-02 22:36:25 +02:00
rt.rs Fixed some typos in the standard library documentation/comments 2024-08-31 14:41:01 +09:00
time.rs Reformat use declarations. 2024-07-29 08:26:52 +10:00