rust/compiler
Trevor Gross f27a9b15d3
Rollup merge of #127679 - RalfJung:raw_ref_op, r=jieyouxu
Stabilize `raw_ref_op` (RFC 2582)

This stabilizes the syntax `&raw const $expr` and `&raw mut $expr`. It has existed unstably for ~4 years now, and has been exposed on stable via the `addr_of` and `addr_of_mut` macros since Rust 1.51 (released more than 3 years ago). I think it has become clear that these operations are here to stay. So it is about time we give them proper primitive syntax. This has two advantages over the macro:

- Being macros, `addr_of`/`addr_of_mut` could in theory do arbitrary magic with the expression on which they work. The only "magic" they actually do is using the argument as a place expression rather than as a value expression. Place expressions are already a subtle topic and poorly understood by many programmers; having this hidden behind a macro using unstable language features makes this even worse. Conversely, people do have an idea of what happens below `&`/`&mut`, so we can make the subtle topic a lot more approachable by connecting to existing intuition.
- The name `addr_of` is quite unfortunate from today's perspective, given that we have accepted provenance as a reality, which means that a pointer is *not* just an address. Strict provenance has a method, `addr`, which extracts the address of a pointer; using the term `addr` in two different ways is quite unfortunate. That's why this PR soft-deprecates `addr_of` -- we will wait a long time before actually showing any warning here, but we should start telling people that the "addr" part of this name is somewhat misleading, and `&raw` avoids that potential confusion.

In summary, this syntax improves developers' ability to conceptualize the operational semantics of Rust, while making a fundamental operation frequently used in unsafe code feel properly built in.

Possible questions to consider, based on the RFC and [this](https://github.com/rust-lang/rust/issues/64490#issuecomment-1163802912) great summary by `@CAD97:`

- Some questions are entirely about the semantics. The semantics are the same as with the macros so I don't think this should have any impact on this syntax PR. Still, for completeness' sake:
  - Should `&raw const *mut_ref` give a read-only pointer?
    - Tracked at: https://github.com/rust-lang/unsafe-code-guidelines/issues/257
    - I think ideally the answer is "no". Stacked Borrows says that pointer is read-only, but Tree Borrows says it is mutable.
  - What exactly does `&raw const (*ptr).field` require? Answered in [the reference](https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html): the arithmetic to compute the field offset follows the rules of `ptr::offset`, making it UB if it goes out-of-bounds. Making this a safe operation (using `wrapping_offset` rules) is considered too much of a loss for alias analysis.
- Choose a different syntax? I don't want to re-litigate the RFC. The only credible alternative that has been proposed is `&raw $place` instead of `&raw const $place`, which (IIUC) could be achieved by making `raw` a contextual keyword in a new edition. The type is named `*const T`, so the explicit `const` is consistent in that regard. `&raw expr` lacks the explicit indication of immutability. However, `&raw const expr` is quite a but longer than `addr_of!(expr)`.
- Shouldn't we have a completely new, better raw pointer type instead? Yes we all want to see that happen -- but I don't think we should block stabilization on that, given that such a nicer type is not on the horizon currently and given the issues with `addr_of!` mentioned above. (If we keep the `&raw $place` syntax free for this, we could use it in the future for that new type.)
- What about the lint the RFC talked about? It hasn't been implemented yet.  Given that the problematic code is UB with or without this stabilization, I don't think the lack of the lint should block stabilization.
  - I created an issue to track adding it: https://github.com/rust-lang/rust/issues/127724
- Other points from the "future possibilites of the RFC
  - "Syntactic sugar" extension: this has not been implemented. I'd argue this is too confusing, we should stick to what the RFC suggested and if we want to do anything about such expressions, add the lint.
  - Encouraging / requiring `&raw` in situations where references are often/definitely incorrect: this has been / is being implemented. On packed fields this already is a hard error, and for `static mut` a lint suggesting raw pointers is being rolled out.
  - Lowering of casts: this has been implemented. (It's also an invisible implementation detail.)
  - `offsetof` woes: we now have native `offset_of` so this is not relevant any more.

To be done before landing:

- [x] Suppress `unused_parens` lint around `&raw {const|mut}` expressions
  - See bottom of https://github.com/rust-lang/rust/pull/127679#issuecomment-2264073752 for rationale
  - Implementation: https://github.com/rust-lang/rust/pull/128782
- [ ] Update the Reference.
  - https://github.com/rust-lang/reference/pull/1567

Fixes https://github.com/rust-lang/rust/issues/64490

cc `@rust-lang/lang` `@rust-lang/opsem`

try-job: x86_64-msvc
try-job: test-various
try-job: dist-various-1
try-job: armhf-gnu
try-job: aarch64-apple
2024-08-18 23:41:46 -05:00
..
rustc Link std statically in rustc_driver 2024-08-11 04:16:53 +02:00
rustc_abi interpret: simplify pointer arithmetic logic 2024-08-01 14:25:19 +02:00
rustc_arena Reformat use declarations. 2024-07-29 08:26:52 +10:00
rustc_ast Use more slice patterns inside the compiler 2024-08-07 13:37:52 +02:00
rustc_ast_ir Use dep: for crate dependencies 2024-07-15 12:40:10 -04:00
rustc_ast_lowering Use FnSig instead of raw FnDecl for ForeignItemKind::Fn 2024-08-16 14:10:06 -04:00
rustc_ast_passes stabilize raw_ref_op 2024-08-18 19:46:53 +02:00
rustc_ast_pretty Use more slice patterns inside the compiler 2024-08-07 13:37:52 +02:00
rustc_attr Rollup merge of #128886 - GrigorenkoPV:untranslatable-diagnostic, r=nnethercote 2024-08-12 17:09:17 +02:00
rustc_baked_icu_data
rustc_borrowck rename AddressOf -> RawBorrow inside the compiler 2024-08-18 19:46:53 +02:00
rustc_builtin_macros Auto merge of #128771 - carbotaniuman:stabilize_unsafe_attr, r=nnethercote 2024-08-17 22:48:42 +00:00
rustc_codegen_cranelift rename AddressOf -> RawBorrow inside the compiler 2024-08-18 19:46:53 +02:00
rustc_codegen_gcc stabilize raw_ref_op 2024-08-18 19:46:53 +02:00
rustc_codegen_llvm Rollup merge of #129173 - beetrees:statically-known-float, r=compiler-errors 2024-08-18 14:55:22 +08:00
rustc_codegen_ssa rename AddressOf -> RawBorrow inside the compiler 2024-08-18 19:46:53 +02:00
rustc_const_eval rename AddressOf -> RawBorrow inside the compiler 2024-08-18 19:46:53 +02:00
rustc_data_structures Update indexmap and use IndexMap::append 2024-08-13 16:16:57 -07:00
rustc_driver
rustc_driver_impl Rollup merge of #128762 - fmease:use-more-slice-pats, r=compiler-errors 2024-08-11 07:51:51 +02:00
rustc_error_codes stabilize raw_ref_op 2024-08-18 19:46:53 +02:00
rustc_error_messages Reformat use declarations. 2024-07-29 08:26:52 +10:00
rustc_errors Add | to make the html doc of Level rendered correctly 2024-08-14 13:38:03 +08:00
rustc_expand Auto merge of #128771 - carbotaniuman:stabilize_unsafe_attr, r=nnethercote 2024-08-17 22:48:42 +00:00
rustc_feature stabilize raw_ref_op 2024-08-18 19:46:53 +02:00
rustc_fluent_macro Reformat use declarations. 2024-07-29 08:26:52 +10:00
rustc_fs_util Reformat use declarations. 2024-07-29 08:26:52 +10:00
rustc_graphviz Reformat use declarations. 2024-07-29 08:26:52 +10:00
rustc_hir Use FnSig instead of raw FnDecl for ForeignItemKind::Fn 2024-08-16 14:10:06 -04:00
rustc_hir_analysis Use FnSig instead of raw FnDecl for ForeignItemKind::Fn 2024-08-16 14:10:06 -04:00
rustc_hir_pretty Use FnSig instead of raw FnDecl for ForeignItemKind::Fn 2024-08-16 14:10:06 -04:00
rustc_hir_typeck rename AddressOf -> RawBorrow inside the compiler 2024-08-18 19:46:53 +02:00
rustc_incremental Reformat use declarations. 2024-07-29 08:26:52 +10:00
rustc_index Add and use IndexVec::append 2024-08-13 13:40:05 -07:00
rustc_index_macros Remove usage of specialization from newtype_index! 2024-06-30 16:42:53 +00:00
rustc_infer Auto merge of #128812 - nnethercote:shrink-TyKind-FnPtr, r=compiler-errors 2024-08-14 00:56:53 +00:00
rustc_interface Stabilize std:🧵:Builder::spawn_unchecked 2024-08-16 10:43:47 -07:00
rustc_lexer Reformat use declarations. 2024-07-29 08:26:52 +10:00
rustc_lint Use FnSig instead of raw FnDecl for ForeignItemKind::Fn 2024-08-16 14:10:06 -04:00
rustc_lint_defs Auto merge of #128771 - carbotaniuman:stabilize_unsafe_attr, r=nnethercote 2024-08-17 22:48:42 +00:00
rustc_llvm Auto merge of #128936 - bjorn3:fix_thin_archive_reading, r=jieyouxu 2024-08-15 14:13:52 +00:00
rustc_log Reformat use declarations. 2024-07-29 08:26:52 +10:00
rustc_macros Reformat use declarations. 2024-07-29 08:26:52 +10:00
rustc_metadata Rollup merge of #128886 - GrigorenkoPV:untranslatable-diagnostic, r=nnethercote 2024-08-12 17:09:17 +02:00
rustc_middle rename AddressOf -> RawBorrow inside the compiler 2024-08-18 19:46:53 +02:00
rustc_mir_build rename AddressOf -> RawBorrow inside the compiler 2024-08-18 19:46:53 +02:00
rustc_mir_dataflow rename AddressOf -> RawBorrow inside the compiler 2024-08-18 19:46:53 +02:00
rustc_mir_transform rename AddressOf -> RawBorrow inside the compiler 2024-08-18 19:46:53 +02:00
rustc_monomorphize Rollup merge of #129067 - cuviper:append, r=wesleywiser 2024-08-15 00:02:27 +02:00
rustc_next_trait_solver Rollup merge of #128828 - lcnr:search-graph-11, r=compiler-errors 2024-08-14 21:43:07 +08:00
rustc_parse stabilize raw_ref_op 2024-08-18 19:46:53 +02:00
rustc_parse_format Reformat use declarations. 2024-07-29 08:26:52 +10:00
rustc_passes Rollup merge of #129203 - compiler-errors:extern_crate_data, r=jieyouxu 2024-08-18 14:55:23 +08:00
rustc_pattern_analysis Rollup merge of #128965 - Zalathar:no-pat, r=Nadrieril 2024-08-15 18:44:16 -07:00
rustc_privacy Reformat use declarations. 2024-07-29 08:26:52 +10:00
rustc_query_impl Reformat use declarations. 2024-07-29 08:26:52 +10:00
rustc_query_system Use more slice patterns inside the compiler 2024-08-07 13:37:52 +02:00
rustc_resolve Rollup merge of #128875 - bvanjoi:cleanup-import-used, r=petrochenkov 2024-08-11 07:51:52 +02:00
rustc_sanitizers Shrink TyKind::FnPtr. 2024-08-09 14:33:25 +10:00
rustc_serialize Reformat use declarations. 2024-07-29 08:26:52 +10:00
rustc_session Rollup merge of #128348 - dingxiangfei2009:allow-shadow-call-stack-sanitizer, r=tmandry 2024-08-15 19:32:35 +02:00
rustc_smir rename AddressOf -> RawBorrow inside the compiler 2024-08-18 19:46:53 +02:00
rustc_span #[deprecated_safe_2024]: Also use the // TODO: hint in the compiler error 2024-08-13 11:32:47 +02:00
rustc_symbol_mangling Shrink TyKind::FnPtr. 2024-08-09 14:33:25 +10:00
rustc_target Auto merge of #125854 - beetrees:zst-arg-abi, r=estebank 2024-08-18 22:15:41 +00:00
rustc_trait_selection Rollup merge of #129203 - compiler-errors:extern_crate_data, r=jieyouxu 2024-08-18 14:55:23 +08:00
rustc_traits Remove redundant type ops 2024-08-14 14:18:17 -04:00
rustc_transmute Update std and compiler 2024-08-10 12:07:17 +02:00
rustc_ty_utils Rollup merge of #127679 - RalfJung:raw_ref_op, r=jieyouxu 2024-08-18 23:41:46 -05:00
rustc_type_ir Rollup merge of #128828 - lcnr:search-graph-11, r=compiler-errors 2024-08-14 21:43:07 +08:00
rustc_type_ir_macros Reformat use declarations. 2024-07-29 08:26:52 +10:00
stable_mir Reformat use declarations. 2024-07-29 08:26:52 +10:00