rust/compiler
bors 6265a95b37 Auto merge of #119044 - RalfJung:intern-without-types, r=oli-obk
const-eval interning: get rid of type-driven traversal

This entirely replaces our const-eval interner, i.e. the code that takes the final result of a constant evaluation from the local memory of the const-eval machine to the global `tcx` memory. The main goal of this change is to ensure that we can detect mutable references that sneak into this final value -- this is something we want to reject for `static` and `const`, and while const-checking performs some static analysis to ensure this, I would be much more comfortable stabilizing const_mut_refs if we had a dynamic check that sanitizes the final value. (This is generally the approach we have been using on const-eval: do a static check to give nice errors upfront, and then do a dynamic check to be really sure that the properties we need for soundness, actually hold.)

We can do this now that https://github.com/rust-lang/rust/pull/118324 landed and each pointer comes with a bit (completely independent of its type) storing whether mutation is permitted through this pointer or not.

The new interner is a lot simpler than the old one: previously we did a complete type-driven traversal to determine the mutability of all memory we see, and then a second pass to intern any leftover raw pointers. The new interner simply recursively traverses the allocation holding the final result, and all allocations reachable from it (which can be determined from the raw bytes of the result, without knowing anything about types), and ensures they all get interned. The initial allocation is interned as immutable for `const` and pomoted and non-interior-mutable `static`; all other allocations are interned as immutable for `static`, `const`, and promoted. The main subtlety is justifying that those inner allocations may indeed be interned immutably, i.e., that mutating them later would anyway already be UB:
- for promoteds, we rely on the analysis that does promotion to ensure that this is sound.
- for `const` and `static`, we check that all pointers in the final result that point to things that are new (i.e., part of this const evaluation) are immutable, i.e., were created via `&<expr>` at a non-interior-mutable type. Mutation through immutable pointers is UB so we are free to intern that memory as immutable.

Interning raises an error if it encounters a dangling pointer or a mutable pointer that violates the above rules.

I also extended our type-driven const validity checks to ensure that `&mut T` in the final value of a const points to mutable memory, at least if `T` is not zero-sized. This catches cases of people turning `&i32` into `&mut i32` (which would still be considered a read-only pointer). Similarly, when these checks encounter an `UnsafeCell`, they are checking that it lives in mutable memory. (Both of these only traverse the newly created values; if those point to other consts/promoteds, the check stops there. But that's okay, we don't have to catch all the UB.) I co-developed this with the stricter interner changes but I can split it out into a separate PR if you prefer.

This PR does have the immediate effect of allowing some new code on stable, for instance:
```rust
const CONST_RAW: *const Vec<i32> = &Vec::new() as *const _;
```
Previously that code got rejected since the type-based interner didn't know what to do with that pointer. It's a raw pointer, we cannot trust its type. The new interner does not care about types so it sees no issue with this code; there's an immutable pointer pointing to some read-only memory (storing a `Vec<i32>`), all is good. Accepting this code pretty much commits us to non-type-based interning, but I think that's the better strategy anyway.

This PR also leads to slightly worse error messages when the final value of a const contains a dangling reference. Previously we would complete interning and then the type-based validation would detect this dangling reference and show a nice error saying where in the value (i.e., in which field) the dangling reference is located. However, the new interner cannot distinguish dangling references from dangling raw pointers, so it must throw an error when it encounters either of them. It doesn't have an understanding of the value structure so all it can say is "somewhere in this constant there's a dangling pointer". (Later parts of the compiler don't like dangling pointers/references so we have to reject them either during interning or during validation.) This could potentially be improved by doing validation before interning, but that's a larger change that I have not attempted yet. (It's also subtle since we do want validation to use the final mutability bits of all involved allocations, and currently it is interning that marks a bunch of allocations as immutable -- that would have to still happen before validation.)

`@rust-lang/wg-const-eval` I hope you are okay with this plan. :)
`@rust-lang/lang` paging you in since this accepts new code on stable as explained above. Please let me know if you think FCP is necessary.
2024-01-23 14:08:08 +00:00
..
rustc Clean up rustc_*/Cargo.toml. 2023-10-30 08:46:02 +11:00
rustc_abi Fix rustc_abi build on stable 2024-01-16 21:15:31 +01:00
rustc_arena Fix Stable trait and its impls to work with the new with_tables 2024-01-19 09:42:51 +00:00
rustc_ast Pack the u128 in LitKind::Int 2024-01-19 20:10:39 -08:00
rustc_ast_lowering Pack the u128 in LitKind::Int 2024-01-19 20:10:39 -08:00
rustc_ast_passes add help message for exclusive_range_pattern error 2024-01-19 13:38:24 -05:00
rustc_ast_pretty Add PatKind::Err 2024-01-17 03:14:16 +01:00
rustc_attr Pack the u128 in LitKind::Int 2024-01-19 20:10:39 -08:00
rustc_baked_icu_data Bump cfg(bootstrap)s 2023-11-15 19:41:28 -05:00
rustc_borrowck Auto merge of #116152 - cjgillot:unchunck, r=nnethercote 2024-01-23 11:56:30 +00:00
rustc_builtin_macros Auto merge of #120080 - cuviper:128-align-packed, r=nikic 2024-01-22 13:08:19 +00:00
rustc_codegen_cranelift Rollup merge of #119815 - nagisa:nagisa/polishes-libloading-use-somewhat, r=bjorn3 2024-01-19 19:27:00 +01:00
rustc_codegen_gcc Rename {create,emit}_warning as {create,emit}_warn. 2024-01-10 07:33:06 +11:00
rustc_codegen_llvm LLVM 18 x86 data layout update 2024-01-19 10:52:01 +01:00
rustc_codegen_ssa Rename TyCtxt::struct_span_lint_hir as TyCtxt::node_span_lint. 2024-01-23 08:09:01 +11:00
rustc_const_eval Auto merge of #119044 - RalfJung:intern-without-types, r=oli-obk 2024-01-23 14:08:08 +00:00
rustc_data_structures Auto merge of #120080 - cuviper:128-align-packed, r=nikic 2024-01-22 13:08:19 +00:00
rustc_driver Bump cfg(bootstrap)s 2023-11-15 19:41:28 -05:00
rustc_driver_impl Replace TrimmedDefPaths with a bool. 2024-01-15 09:16:14 +11:00
rustc_error_codes Stabilize simple offset_of 2024-01-19 20:38:51 +00:00
rustc_error_messages Remove rustc_error_messages/messages.ftl. 2023-11-26 08:37:27 +11:00
rustc_errors Tweak error counting. 2024-01-22 10:14:01 +11:00
rustc_expand Pack the u128 in LitKind::Int 2024-01-19 20:10:39 -08:00
rustc_feature Revert "Auto merge of #118133 - Urgau:stabilize_trait_upcasting, r=WaffleLapkin" 2024-01-22 14:24:31 +00:00
rustc_fluent_macro annotate-snippets: update to 0.10 2024-01-07 16:53:32 +03:00
rustc_fs_util Clean up rustc_*/Cargo.toml. 2023-10-30 08:46:02 +11:00
rustc_graphviz remove unused pub fn 2023-11-23 14:11:02 +03:00
rustc_hir Rollup merge of #120143 - compiler-errors:consolidate-instance-resolve-for-coroutines, r=oli-obk 2024-01-22 22:12:08 +01:00
rustc_hir_analysis Rename TyCtxt::emit_spanned_lint as TyCtxt::emit_node_span_lint. 2024-01-23 08:09:05 +11:00
rustc_hir_pretty Add PatKind::Err 2024-01-17 03:14:16 +01:00
rustc_hir_typeck Auto merge of #120017 - nnethercote:lint-api, r=oli-obk 2024-01-23 00:06:57 +00:00
rustc_incremental Tweak error counting. 2024-01-22 10:14:01 +11:00
rustc_index Remove uses of HybridBitSet. 2024-01-22 22:53:20 +00:00
rustc_index_macros Restrict access to the private field of newtype indexes 2024-01-19 15:38:47 +00:00
rustc_infer Make generic const type mismatches not hide trait impls from the trait solver 2024-01-22 13:23:45 +00:00
rustc_interface Rollup merge of #120159 - jyn514:track-verbose, r=wesleywiser 2024-01-22 22:12:09 +01:00
rustc_lexer Rollup merge of #118639 - fmease:deny-features-in-stable-rustc-crates, r=WaffleLapkin 2024-01-22 16:54:56 +01:00
rustc_lint Auto merge of #120017 - nnethercote:lint-api, r=oli-obk 2024-01-23 00:06:57 +00:00
rustc_lint_defs Rollup merge of #119948 - asquared31415:unsafe_op_in_unsafe_fn_fix, r=TaKO8Ki 2024-01-22 16:13:28 +01:00
rustc_llvm Revert "Auto merge of #113923 - DianQK:restore-no-builtins-lto, r=pnkfelix" 2024-01-12 18:23:04 +08:00
rustc_log rustc_log: provide a way to init logging based on the values, not names, of the env vars 2023-11-11 15:24:33 +01:00
rustc_macros Rename LintContext::struct_span_lint as LintContext::span_lint. 2024-01-23 07:59:45 +11:00
rustc_metadata Rollup merge of #119815 - nagisa:nagisa/polishes-libloading-use-somewhat, r=bjorn3 2024-01-19 19:27:00 +01:00
rustc_middle Auto merge of #119044 - RalfJung:intern-without-types, r=oli-obk 2024-01-23 14:08:08 +00:00
rustc_mir_build Rename TyCtxt::emit_spanned_lint as TyCtxt::emit_node_span_lint. 2024-01-23 08:09:05 +11:00
rustc_mir_dataflow Use a plain bitset for liveness analyses. 2024-01-22 23:18:45 +00:00
rustc_mir_transform Auto merge of #116152 - cjgillot:unchunck, r=nnethercote 2024-01-23 11:56:30 +00:00
rustc_monomorphize Rename TyCtxt::emit_spanned_lint as TyCtxt::emit_node_span_lint. 2024-01-23 08:09:05 +11:00
rustc_next_trait_solver Remove movability from TyKind::Coroutine 2023-12-28 16:35:01 +00:00
rustc_parse Rollup merge of #120063 - clubby789:remove-box-handling, r=Nilstrieb 2024-01-20 20:06:34 +01:00
rustc_parse_format Rollup merge of #118639 - fmease:deny-features-in-stable-rustc-crates, r=WaffleLapkin 2024-01-22 16:54:56 +01:00
rustc_passes Rename TyCtxt::emit_spanned_lint as TyCtxt::emit_node_span_lint. 2024-01-23 08:09:05 +11:00
rustc_pattern_analysis Rename TyCtxt::emit_spanned_lint as TyCtxt::emit_node_span_lint. 2024-01-23 08:09:05 +11:00
rustc_privacy Rename TyCtxt::emit_spanned_lint as TyCtxt::emit_node_span_lint. 2024-01-23 08:09:05 +11:00
rustc_query_impl Update measureme crate to version 11 2024-01-13 16:32:03 +01:00
rustc_query_system Tweak error counting. 2024-01-22 10:14:01 +11:00
rustc_resolve Rollup merge of #119369 - bvanjoi:fix-119301, r=petrochenkov 2024-01-22 16:13:25 +01:00
rustc_serialize Rollup merge of #117561 - tgross35:split-array, r=scottmcm 2024-01-19 19:26:59 +01:00
rustc_session Auto merge of #120017 - nnethercote:lint-api, r=oli-obk 2024-01-23 00:06:57 +00:00
rustc_smir Use the new with_tables everywhere 2024-01-19 11:25:38 +00:00
rustc_span Rollup merge of #120143 - compiler-errors:consolidate-instance-resolve-for-coroutines, r=oli-obk 2024-01-22 22:12:08 +01:00
rustc_symbol_mangling Rename consuming chaining methods on DiagnosticBuilder. 2024-01-10 07:40:00 +11:00
rustc_target rustc: implement support for riscv32im_risc0_zkvm_elf 2024-01-22 10:07:36 -08:00
rustc_trait_selection Auto merge of #120017 - nnethercote:lint-api, r=oli-obk 2024-01-23 00:06:57 +00:00
rustc_traits Correctly handle normalization in implied bounds 2024-01-17 21:27:34 -05:00
rustc_transmute Fix an ICE that occurs after an error has already been reported 2024-01-09 16:09:30 +00:00
rustc_ty_utils Consolidate logic around resolving built-in coroutine trait impls 2024-01-19 21:28:37 +00:00
rustc_type_ir Restrict access to the private field of newtype indexes 2024-01-19 15:38:47 +00:00
stable_mir Make the remaining "private" fields actually private 2024-01-19 16:37:50 +00:00