Reduce FormattingOptions to 64 bits
This is part of https://github.com/rust-lang/rust/issues/99012
This reduces FormattingOptions from 6-7 machine words (384 bits on 64-bit platforms, 224 bits on 32-bit platforms) to just 64 bits (a single register on 64-bit platforms).
Before:
```rust
pub struct FormattingOptions {
flags: u32, // only 6 bits used
fill: char,
align: Option<Alignment>,
width: Option<usize>,
precision: Option<usize>,
}
```
After:
```rust
pub struct FormattingOptions {
/// Bits:
/// - 0-20: fill character (21 bits, a full `char`)
/// - 21: `+` flag
/// - 22: `-` flag
/// - 23: `#` flag
/// - 24: `0` flag
/// - 25: `x?` flag
/// - 26: `X?` flag
/// - 27: Width flag (if set, the width field below is used)
/// - 28: Precision flag (if set, the precision field below is used)
/// - 29-30: Alignment (0: Left, 1: Right, 2: Center, 3: Unknown)
/// - 31: Always set to 1
flags: u32,
/// Width if width flag above is set. Otherwise, always 0.
width: u16,
/// Precision if precision flag above is set. Otherwise, always 0.
precision: u16,
}
```
Add an attribute that makes the spans from a macro edition 2021, and fix pin on edition 2024 with it
Fixes a regression, see issue below. This is a temporary fix, super let is the real solution.
Closes#138596
add `naked_functions_target_feature` unstable feature
tracking issue: https://github.com/rust-lang/rust/issues/138568
tagging https://github.com/rust-lang/rust/pull/134213https://github.com/rust-lang/rust/issues/90957
This PR puts `#[target_feature(/* ... */)]` on `#[naked]` functions behind its own feature gate, so that naked functions can be stabilized. It turns out that supporting `target_feature` on naked functions is tricky on some targets, so we're splitting it out to not block stabilization of naked functions themselves. See the tracking issue for more information and workarounds.
Note that at the time of writing, the `target_features` attribute is ignored when generating code for naked functions.
r? ``@Amanieu``
The idea is to identify cases of symbols/identifiers that are not
expected to be used. There isn't a perfectly sharp line between "dummy"
and "not dummy", but I think it's useful nonetheless.
Add `#[define_opaques]` attribute and require it for all type-alias-impl-trait sites that register a hidden type
Instead of relying on the signature of items to decide whether they are constraining an opaque type, the opaque types that the item constrains must be explicitly listed.
A previous version of this PR used an actual attribute, but had to keep the resolved `DefId`s in a side table.
Now we just lower to fields in the AST that have no surface syntax, instead a builtin attribute macro fills in those fields where applicable.
Note that for convenience referencing opaque types in associated types from associated methods on the same impl will not require an attribute. If that causes problems `#[defines()]` can be used to overwrite the default of searching for opaques in the signature.
One wart of this design is that closures and static items do not have generics. So since I stored the opaques in the generics of functions, consts and methods, I would need to add a custom field to closures and statics to track this information. During a T-types discussion we decided to just not do this for now.
fixes#131298
Reduce formatting `width` and `precision` to 16 bits
This is part of https://github.com/rust-lang/rust/issues/99012
This is reduces the `width` and `precision` fields in format strings to 16 bits. They are currently full `usize`s, but it's a bit nonsensical that we need to support the case where someone wants to pad their value to eighteen quintillion spaces and/or have eighteen quintillion digits of precision.
By reducing these fields to 16 bit, we can reduce `FormattingOptions` to 64 bits (see https://github.com/rust-lang/rust/pull/136974) and improve the in memory representation of `format_args!()`. (See additional context below.)
This also fixes a bug where the width or precision is silently truncated when cross-compiling to a target with a smaller `usize`. By reducing the width and precision fields to the minimum guaranteed size of `usize`, 16 bits, this bug is eliminated.
This is a breaking change, but affects almost no existing code.
---
Details of this change:
There are three ways to set a width or precision today:
1. Directly a formatting string, e.g. `println!("{a:1234}")`
2. Indirectly in a formatting string, e.g. `println!("{a:width$}", width=1234)`
3. Through the unstable `FormattingOptions::width` method.
This PR:
- Adds a compiler error for 1. (`println!("{a:9999999}")` no longer compiles and gives a clear error.)
- Adds a runtime check for 2. (`println!("{a:width$}, width=9999999)` will panic.)
- Changes the signatures of the (unstable) `FormattingOptions::[get_]width` methods to use a `u16` instead.
---
Additional context for improving `FormattingOptions` and `fmt::Arguments`:
All the formatting flags and options are currently:
- The `+` flag (1 bit)
- The `-` flag (1 bit)
- The `#` flag (1 bit)
- The `0` flag (1 bit)
- The `x?` flag (1 bit)
- The `X?` flag (1 bit)
- The alignment (2 bits)
- The fill character (21 bits)
- Whether a width is specified (1 bit)
- Whether a precision is specified (1 bit)
- If used, the width (a full usize)
- If used, the precision (a full usize)
Everything except the last two can simply fit in a `u32` (those add up to 31 bits in total).
If we can accept a max width and precision of u16::MAX, we can make a `FormattingOptions` that is exactly 64 bits in size; the same size as a thin reference on most platforms.
If, additionally, we also limit the number of formatting arguments, we can also reduce the size of `fmt::Arguments` (that is, of a `format_args!()` expression).
Revert <https://github.com/rust-lang/rust/pull/138084> to buy time to
consider options that avoids breaking downstream usages of cargo on
distributed `rustc-src` artifacts, where such cargo invocations fail due
to inability to inherit `lints` from workspace root manifest's
`workspace.lints` (this is only valid for the source rust-lang/rust
workspace, but not really the distributed `rustc-src` artifacts).
This breakage was reported in
<https://github.com/rust-lang/rust/issues/138304>.
This reverts commit 48caf81484, reversing
changes made to c6662879b2.
add a "future" edition
This idea has been discussed previously [on Zulip](https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/Continuous.20edition-like.20changes.3F/near/432559262) (though what I've implemented isn't exactly the "next"/"future" editions proposed in that message, just the "future" edition). I've found myself prototyping changes that involve edition migrations and wanting to target an upcoming edition for those migrations, but none exists. This should be permanently unstable and not removed.
By naming them in `[workspace.lints.rust]` in the top-level
`Cargo.toml`, and then making all `compiler/` crates inherit them with
`[lints] workspace = true`. (I omitted `rustc_codegen_{cranelift,gcc}`,
because they're a bit different.)
The advantages of this over the current approach:
- It uses a standard Cargo feature, rather than special handling in
bootstrap. So, easier to understand, and less likely to get
accidentally broken in the future.
- It works for proc macro crates.
It's a shame it doesn't work for rustc-specific lints, as the comments
explain.
Rollup of 25 pull requests
Successful merges:
- #135733 (Implement `&pin const self` and `&pin mut self` sugars)
- #135895 (Document workings of successors more clearly)
- #136922 (Pattern types: Avoid having to handle an Option for range ends in the type system or the HIR)
- #137303 (Remove `MaybeForgetReturn` suggestion)
- #137327 (Undeprecate env::home_dir)
- #137358 (Match Ergonomics 2024: add context and examples to the unstable book)
- #137534 ([rustdoc] hide item that is not marked as doc(inline) and whose src is doc(hidden))
- #137565 (Try to point of macro expansion from resolver and method errors if it involves macro var)
- #137637 (Check dyn flavor before registering upcast goal on wide pointer cast in MIR typeck)
- #137643 (Add DWARF test case for non-C-like `repr128` enums)
- #137744 (Re-add `Clone`-derive on `Thir`)
- #137758 (fix usage of ty decl macro fragments in attributes)
- #137764 (Ensure that negative auto impls are always applicable)
- #137772 (Fix char count in `Display` for `ByteStr`)
- #137798 (ci: use ubuntu 24 on arm large runner)
- #137802 (miri native-call support: all previously exposed provenance is accessible to the callee)
- #137805 (adjust Layout debug printing to match the internal field name)
- #137808 (Do not require that unsafe fields lack drop glue)
- #137820 (Clarify why InhabitedPredicate::instantiate_opt exists)
- #137825 (Provide more context on resolve error caused from incorrect RTN)
- #137834 (rustc_fluent_macro: use CARGO_CRATE_NAME instead of CARGO_PKG_NAME)
- #137868 (Add minimal platform support documentation for powerpc-unknown-linux-gnuspe)
- #137910 (Improve error message for `AsyncFn` trait failure for RPIT)
- #137920 (interpret/provenance_map: consistently use range_is_empty)
- #138038 (Update `compiler-builtins` to 0.1.151)
r? `@ghost`
`@rustbot` modify labels: rollup
Try to point of macro expansion from resolver and method errors if it involves macro var
In the case that a macro caller passes an identifier into a macro generating a path or method expression, point out that identifier in the context of the *macro* so it's a bit more clear how the macro is involved in causing the error.
r? ``````````@estebank`````````` or reassign
mgca: Lower all const paths as `ConstArgKind::Path`
When `#![feature(min_generic_const_args)]` is enabled, we now lower all
const paths in generic arg position to `hir::ConstArgKind::Path`. We
then lower assoc const paths to `ty::ConstKind::Unevaluated` since we
can no longer use the anon const expression lowering machinery. In the
process of implementing this, I factored out `hir_ty_lowering` code that
is now shared between lowering assoc types and assoc consts.
This PR also introduces a `#[type_const]` attribute for trait assoc
consts that are allowed as const args. However, we still need to
implement code to check that assoc const definitions satisfy
`#[type_const]` if present (basically is it a const path or a
monomorphic anon const).
r? `@BoxyUwU`
Support raw-dylib link kind on ELF
raw-dylib is a link kind that allows rustc to link against a library without having any library files present.
This currently only exists on Windows. rustc will take all the symbols from raw-dylib link blocks and put them in an import library, where they can then be resolved by the linker.
While import libraries don't exist on ELF, it would still be convenient to have this same functionality. Not having the libraries present at build-time can be convenient for several reasons, especially cross-compilation. With raw-dylib, code linking against a library can be cross-compiled without needing to have these libraries available on the build machine. If the libc crate makes use of this, it would allow cross-compilation without having any libc available on the build machine. This is not yet possible with this implementation, at least against libc's like glibc that use symbol versioning. The raw-dylib kind could be extended with support for symbol versioning in the future.
This implementation is very experimental and I have not tested it very well. I have tested it for a toy example and the lz4-sys crate, where it was able to successfully link a binary despite not having a corresponding library at build-time.
I was inspired by Björn's comments in https://internals.rust-lang.org/t/bundle-zig-cc-in-rustup-by-default/22096/27
Tracking issue: #135694
r? bjorn3
try-job: aarch64-apple
try-job: x86_64-msvc-1
try-job: x86_64-msvc-2
try-job: test-various
When `#![feature(min_generic_const_args)]` is enabled, we now lower all
const paths in generic arg position to `hir::ConstArgKind::Path`. We
then lower assoc const paths to `ty::ConstKind::Unevaluated` since we
can no longer use the anon const expression lowering machinery. In the
process of implementing this, I factored out `hir_ty_lowering` code that
is now shared between lowering assoc types and assoc consts.
This PR also introduces a `#[type_const]` attribute for trait assoc
consts that are allowed as const args. However, we still need to
implement code to check that assoc const definitions satisfy
`#[type_const]` if present (basically is it a const path or a
monomorphic anon const).
Implement `#[cfg]` in `where` clauses
This PR implements #115590, which supports `#[cfg]` attributes in `where` clauses.
The biggest change is, that it adds `AttrsVec` and `NodeId` to the `ast::WherePredicate` and `HirId` to the `hir::WherePredicate`.
raw-dylib is a link kind that allows rustc to link against a library
without having any library files present.
This currently only exists on Windows. rustc will take all the symbols
from raw-dylib link blocks and put them in an import library, where they
can then be resolved by the linker.
While import libraries don't exist on ELF, it would still be convenient
to have this same functionality. Not having the libraries present at
build-time can be convenient for several reasons, especially
cross-compilation. With raw-dylib, code linking against a library can be
cross-compiled without needing to have these libraries available on the
build machine. If the libc crate makes use of this, it would allow
cross-compilation without having any libc available on the build
machine. This is not yet possible with this implementation, at least
against libc's like glibc that use symbol versioning.
The raw-dylib kind could be extended with support for symbol versioning
in the future.
This implementation is very experimental and I have not tested it very
well. I have tested it for a toy example and the lz4-sys crate, where it
was able to successfully link a binary despite not having a
corresponding library at build-time.
Rollup of 8 pull requests
Successful merges:
- #137370 (adjust_abi: make fallback logic for ABIs a bit easier to read)
- #137444 (Improve behavior of `IF_LET_RESCOPE` around temporaries and place expressions)
- #137464 (Fix invalid suggestion from type error for derive macro)
- #137539 ( Add rustdoc-gui regression test for #137082 )
- #137576 (Don't doc-comment BTreeMap<K, SetValZST, A>)
- #137595 (remove `simd_fpow` and `simd_fpowi`)
- #137600 (type_ir: remove redundant part of comment)
- #137602 (feature: fix typo in attribute description)
r? `@ghost`
`@rustbot` modify labels: rollup
remove `simd_fpow` and `simd_fpowi`
Discussed in https://github.com/rust-lang/rust/issues/137555
These functions are not exposed from `std::intrinsics::simd`, and not used anywhere outside of the compiler. They also don't lower to particularly good code at least on the major ISAs (I checked x86_64, aarch64, s390x, powerpc), where the vector is just spilled to the stack and scalar functions are used for the actual logic.
r? `@RalfJung`
intrinsics: unify rint, roundeven, nearbyint in a single round_ties_even intrinsic
LLVM has three intrinsics here that all do the same thing (when used in the default FP environment). There's no reason Rust needs to copy that historically-grown mess -- let's just have one intrinsic and leave it up to the LLVM backend to decide how to lower that.
Suggested by `@hanna-kruppe` in https://github.com/rust-lang/rust/issues/136459; Cc `@tgross35`
try-job: test-various
Rollup of 7 pull requests
Successful merges:
- #137095 (Replace some u64 hashes with Hash64)
- #137100 (HIR analysis: Remove unnecessary abstraction over list of clauses)
- #137105 (Restrict DerefPure for Cow<T> impl to T = impl Clone, [impl Clone], str.)
- #137120 (Enable `relative-path-include-bytes-132203` rustdoc-ui test on Windows)
- #137125 (Re-add missing empty lines in the releases notes)
- #137145 (use add-core-stubs / minicore for a few more tests)
- #137149 (Remove SSE ABI from i586-pc-windows-msvc)
r? `@ghost`
`@rustbot` modify labels: rollup
Fix const items not being allowed to be called `r#move` or `r#static`
Because of an ambiguity with const closures, the parser needs to ensure that for a const item, the `const` keyword isn't followed by a `move` or `static` keyword, as that would indicate a const closure:
```rust
fn main() {
const move // ...
}
```
This check did not take raw identifiers into account, therefore being unable to distinguish between `const move` and `const r#move`. The latter is obviously not a const closure, so it should be allowed as a const item.
This fixes the check in the parser to only treat `const ...` as a const closure if it's followed by the *proper keyword*, and not a raw identifier.
Additionally, this adds a large test that tests for all raw identifiers in all kinds of positions, including `const`, to prevent issues like this one from occurring again.
fixes#137128
Because of an ambiguity with const closures, the parser needs to ensure
that for a const item, the `const` keyword isn't followed by a `move` or
`static` keyword, as that would indicate a const closure:
```rust
fn main() {
const move // ...
}
```
This check did not take raw identifiers into account, therefore being
unable to distinguish between `const move` and `const r#move`. The
latter is obviously not a const closure, so it should be allowed as a
const item.
This fixes the check in the parser to only treat `const ...` as a const
closure if it's followed by the *proper keyword*, and not a raw
identifier.
Additionally, this adds a large test that tests for all raw identifiers in
all kinds of positions, including `const`, to prevent issues like this
one from occurring again.
Simplify `rustc_span` `analyze_source_file`
Simplifies the logic to what the code *actually* does, which is to just record newlines and multibyte characters. Checking for other ASCII control characters is unnecessary because the generic fallback doesn't do anything for those cases.
Also uses a simpler (and more efficient) means of iterating the set bits of the mask.
Rollup of 8 pull requests
Successful merges:
- #134999 (Add cygwin target.)
- #136559 (Resolve named regions when reporting type test failures in NLL)
- #136660 (Use a trait to enforce field validity for union fields + `unsafe` fields + `unsafe<>` binder types)
- #136858 (Parallel-compiler-related cleanup)
- #136881 (cg_llvm: Reduce visibility of all functions in the llvm module)
- #136888 (Always perform discr read for never pattern in EUV)
- #136948 (Split out the `extern_system_varargs` feature)
- #136949 (Fix import in bench for wasm)
r? `@ghost`
`@rustbot` modify labels: rollup
Split out the `extern_system_varargs` feature
After the stabilization PR was opened, `extern "system"` functions were added to `extended_varargs_abi_support`. This has a number of questions regarding it that were not discussed and were somewhat surprising. It deserves to be considered as its own feature, separate from `extended_varargs_abi_support`.
Tracking issue:
- https://github.com/rust-lang/rust/issues/136946
Use a trait to enforce field validity for union fields + `unsafe` fields + `unsafe<>` binder types
This PR introduces a new, internal-only trait called `BikeshedGuaranteedNoDrop`[^1] to faithfully model the field check that used to be implemented manually by `allowed_union_or_unsafe_field`.
942db6782f/compiler/rustc_hir_analysis/src/check/check.rs (L84-L115)
Copying over the doc comment from the trait:
```rust
/// Marker trait for the types that are allowed in union fields, unsafe fields,
/// and unsafe binder types.
///
/// Implemented for:
/// * `&T`, `&mut T` for all `T`,
/// * `ManuallyDrop<T>` for all `T`,
/// * tuples and arrays whose elements implement `BikeshedGuaranteedNoDrop`,
/// * or otherwise, all types that are `Copy`.
///
/// Notably, this doesn't include all trivially-destructible types for semver
/// reasons.
///
/// Bikeshed name for now.
```
As far as I am aware, there's no new behavior being guaranteed by this trait, since it operates the same as the manually implemented check. We could easily rip out this trait and go back to using the manually implemented check for union fields, however using a trait means that this code can be shared by WF for `unsafe<>` binders too. See the last commit.
The only diagnostic changes are that this now fires false-negatives for fields that are ill-formed. I don't consider that to be much of a problem though.
r? oli-obk
[^1]: Please let's not bikeshed this name lol. There's no good name for `ValidForUnsafeFieldsUnsafeBindersAndUnionFields`.
After the stabilization PR was opened, `extern "system"` functions were
added to `extended_varargs_abi_support`. This has a number of questions
regarding it that were not discussed and were somewhat surprising.
It deserves to be considered as its own feature, separate from
`extended_varargs_abi_support`.
Prevent generic pattern types from being used in libstd
Pattern types should follow the same rules that patterns follow. So a pattern type range must not wrap and not be empty. While we reject such invalid ranges at layout computation time, that only happens during monomorphization in the case of const generics. This is the exact same issue as other const generic math has, and since there's no solution there yet, I put these pattern types behind a separate incomplete feature.
These are not necessary for the pattern types MVP (replacing the layout range attributes in libcore and rustc).
cc #136574 (new tracking issue for the `generic_pattern_types` feature gate)
r? ``@lcnr``
cc ``@scottmcm`` ``@joshtriplett``
tree-wide: parallel: Fully removed all `Lrc`, replaced with `Arc`
tree-wide: parallel: Fully removed all `Lrc`, replaced with `Arc`
This is continuation of https://github.com/rust-lang/rust/pull/132282 .
I'm pretty sure I did everything right. In particular, I searched all occurrences of `Lrc` in submodules and made sure that they don't need replacement.
There are other possibilities, through.
We can define `enum Lrc<T> { Rc(Rc<T>), Arc(Arc<T>) }`. Or we can make `Lrc` a union and on every clone we can read from special thread-local variable. Or we can add a generic parameter to `Lrc` and, yes, this parameter will be everywhere across all codebase.
So, if you think we should take some alternative approach, then don't merge this PR. But if it is decided to stick with `Arc`, then, please, merge.
cc "Parallel Rustc Front-end" ( https://github.com/rust-lang/rust/issues/113349 )
r? SparrowLii
`@rustbot` label WG-compiler-parallel
#[contracts::requires(...)] + #[contracts::ensures(...)]
cc https://github.com/rust-lang/rust/issues/128044
Updated contract support: attribute syntax for preconditions and postconditions, implemented via a series of desugarings that culminates in:
1. a compile-time flag (`-Z contract-checks`) that, similar to `-Z ub-checks`, attempts to ensure that the decision of enabling/disabling contract checks is delayed until the end user program is compiled,
2. invocations of lang-items that handle invoking the precondition, building a checker for the post-condition, and invoking that post-condition checker at the return sites for the function, and
3. intrinsics for the actual evaluation of pre- and post-condition predicates that third-party verification tools can intercept and reinterpret for their own purposes (e.g. creating shims of behavior that abstract away the function body and replace it solely with the pre- and post-conditions).
Known issues:
* My original intent, as described in the MCP (https://github.com/rust-lang/compiler-team/issues/759) was to have a rustc-prefixed attribute namespace (like rustc_contracts::requires). But I could not get things working when I tried to do rewriting via a rustc-prefixed builtin attribute-macro. So for now it is called `contracts::requires`.
* Our attribute macro machinery does not provide direct support for attribute arguments that are parsed like rust expressions. I spent some time trying to add that (e.g. something that would parse the attribute arguments as an AST while treating the remainder of the items as a token-tree), but its too big a lift for me to undertake. So instead I hacked in something approximating that goal, by semi-trivially desugaring the token-tree attribute contents into internal AST constucts. This may be too fragile for the long-term.
* (In particular, it *definitely* breaks when you try to add a contract to a function like this: `fn foo1(x: i32) -> S<{ 23 }> { ... }`, because its token-tree based search for where to inject the internal AST constructs cannot immediately see that the `{ 23 }` is within a generics list. I think we can live for this for the short-term, i.e. land the work, and continue working on it while in parallel adding a new attribute variant that takes a token-tree attribute alongside an AST annotation, which would completely resolve the issue here.)
* the *intent* of `-Z contract-checks` is that it behaves like `-Z ub-checks`, in that we do not prematurely commit to including or excluding the contract evaluation in upstream crates (most notably, `core` and `std`). But the current test suite does not actually *check* that this is the case. Ideally the test suite would be extended with a multi-crate test that explores the matrix of enabling/disabling contracts on both the upstream lib and final ("leaf") bin crates.
Implement unstable `new_range` feature
Switches `a..b`, `a..`, and `a..=b` to resolve to the new range types.
For rust-lang/rfcs#3550
Tracking issue #123741
also adds the re-export that was missed in the original implementation of `new_range_api`
Add `kl` and `widekl` target features, and the feature gate
This is an effort towards #134813. This PR adds the target-features and the feature gate to `rustc`
<!--
```@rustbot``` label O-x86_64 O-x86_32 A-target-feature
r? compiler
-->
This has now been approved as a language feature and no longer needs
a `rustc_` prefix.
Also change the `contracts` feature to be marked as incomplete and
`contracts_internals` as internal.
The extended syntax for function signature that includes contract clauses
should never be user exposed versus the interface we want to ship
externally eventually.
includes post-developed commit: do not suggest internal-only keywords as corrections to parse failures.
includes post-developed commit: removed tabs that creeped in into rustfmt tool source code.
includes post-developed commit, placating rustfmt self dogfooding.
includes post-developed commit: add backquotes to prevent markdown checking from trying to treat an attr as a markdown hyperlink/
includes post-developed commit: fix lowering to keep contracts from being erroneously inherited by nested bodies (like closures).
Rebase Conflicts:
- compiler/rustc_parse/src/parser/diagnostics.rs
- compiler/rustc_parse/src/parser/item.rs
- compiler/rustc_span/src/hygiene.rs
Remove contracts keywords from diagnostic messages
Convert two `rustc_middle::lint` functions to `Span` methods.
`rustc_middle` is a huge crate and it's always good to move stuff out of it. There are lots of similar methods already on `Span`, so these two functions, `in_external_macro` and `is_from_async_await`, fit right in. The diff is big because `in_external_macro` is used a lot by clippy lints.
r? ``@Noratrieb``
`rustc_middle` is a huge crate and it's always good to move stuff out of
it. There are lots of similar methods already on `Span`, so these two
functions, `in_external_macro` and `is_from_async_await`, fit right in.
The diff is big because `in_external_macro` is used a lot by clippy
lints.
Implement MIR lowering for unsafe binders
This is the final bit of the unsafe binders puzzle. It implements MIR, CTFE, and codegen for unsafe binders, and enforces that (for now) they are `Copy`. Later on, I'll introduce a new trait that relaxes this requirement to being "is `Copy` or `ManuallyDrop<T>`" which more closely models how we treat union fields.
Namely, wrapping unsafe binders is now `Rvalue::WrapUnsafeBinder`, which acts much like an `Rvalue::Aggregate`. Unwrapping unsafe binders are implemented as a MIR projection `ProjectionElem::UnwrapUnsafeBinder`, which acts much like `ProjectionElem::Field`.
Tracking:
- https://github.com/rust-lang/rust/issues/130516
Insert null checks for pointer dereferences when debug assertions are enabled
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 inserts checks in the same places as the `CheckAlignment` pass and additionally
also inserts checks for `Borrows`, so code like
```rust
let ptr: *const u32 = std::ptr::null();
let val: &u32 = unsafe { &*ptr };
```
will have a check inserted on dereference. This is done because null references
are UB. The alignment check doesn't cover these places, because in `&(*ptr).field`,
the exact requirement is that the final reference must be aligned. This is something to
consider further enhancements of the alignment check.
For now this is implemented as a separate `MirPass`, to make it easy to disable
this check if necessary.
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.
r? `@saethlin`
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.