Implement `unsigned_signed_diff`
<!--
If this PR is related to an unstable feature or an otherwise tracked effort,
please link to the relevant tracking issue here. If you don't know of a related
tracking issue or there are none, feel free to ignore this.
This PR will get automatically assigned to a reviewer. In case you would like
a specific user to review your work, you can assign it to them by using
r? <reviewer name>
-->
Implements https://github.com/rust-lang/rust/issues/126041
Gate `AsyncFn*` under `async_closure` feature
T-lang has not come to a consensus on the naming of async closure callable bounds, and as part of allowing the async closures RFC merge, we agreed to place `AsyncFn` under the same gate as `async Fn` so that these syntaxes can be evaluated in parallel.
See https://github.com/rust-lang/rfcs/pull/3668#issuecomment-2246435537
r? oli-obk
Replace some `mem::forget`'s with `ManuallyDrop`
> but I would like to see a larger effort to replace all uses of `mem::forget`.
_Originally posted by `@saethlin` in https://github.com/rust-lang/rust/issues/127584#issuecomment-2226087767_
So,
r? `@saethlin`
Sorry, I have finished writing all of this before I got your response.
Add edge-case examples to `{count,leading,trailing}_{ones,zeros}` methods
Some architectures (i386) do not define a "count leading zeros" instruction, they define a "find first set bit" instruction (`bsf`) whose result is undefined when given zero (ie none of the bits are set). Of this family of bitwise operations, I always forget which of these things is potentially undefined for zero, and I'm also not 100% sure that Rust provides a hard guarantee for the results of these methods when given zero. So I figured there are others who have these same uncertainties, and it would be good to resolve them and answer the question via extending these doc examples/tests.
See https://en.wikipedia.org/wiki/Find_first_set#Hardware_support for more info on i386 and `bsf` on zero.
Remove generic lifetime parameter of trait `Pattern`
Use a GAT for `Searcher` associated type because this trait is always implemented for every lifetime anyway.
cc #27721
Start using `#[diagnostic::do_not_recommend]` in the standard library
This commit starts using `#[diagnostic::do_not_recommend]` in the standard library to improve some error messages. In this case we just hide a certain nightly only impl as suggested in #121521
The result in not perfect yet, but at least the `Yeet` suggestion is not shown anymore. I would consider that as a minor improvement.
This commit starts using `#[diagnostic::do_not_recommend]` in the
standard library to improve some error messages. In this case we just
hide a certain nightly only impl as suggested in #121521
Forbid borrows and unsized types from being used as the type of a const generic under `adt_const_params`
Fixes#112219Fixes#112124Fixes#112125
### Motivation
Currently the `adt_const_params` feature allows writing `Foo<const N: [u8]>` this is entirely useless as it is not possible to write an expression which evaluates to a type that is not `Sized`. In order to actually use unsized types in const generics they are typically written as `const N: &[u8]` which *is* possible to provide a value of.
Unfortunately allowing the types of const parameters to contain references is non trivial (#120961) as it introduces a number of difficult questions about how equality of references in the type system should behave. References in the types of const generics is largely only useful for using unsized types in const generics.
This PR introduces a new feature gate `unsized_const_parameters` and moves support for `const N: [u8]` and `const N: &...` from `adt_const_params` into it. The goal here hopefully is to experiment with allowing `const N: [u8]` to work without references and then eventually completely forbid references in const generics.
Splitting this out into a new feature gate means that stabilization of `adt_const_params` does not have to resolve#120961 which is the only remaining "big" blocker for the feature. Remaining issues after this are a few ICEs and naming bikeshed for `ConstParamTy`.
### Implementation
The implementation is slightly subtle here as we would like to ensure that a stabilization of `adt_const_params` is forwards compatible with any outcome of `unsized_const_parameters`. This is inherently tricky as we do not support unstable trait implementations and we determine whether a type is valid as the type of a const parameter via a trait bound.
There are a few constraints here:
- We would like to *allow for the possibility* of adding a `Sized` supertrait to `ConstParamTy` in the event that we wind up opting to not support unsized types and instead requiring people to write the 'sized version', e.g. `const N: [u8; M]` instead of `const N: [u8]`.
- Crates should be able to enable `unsized_const_parameters` and write trait implementations of `ConstParamTy` for `!Sized` types without downstream crates that only enable `adt_const_params` being able to observe this (required for std to be able to `impl<T> ConstParamTy for [T]`
Ultimately the way this is accomplished is via having two traits (sad), `ConstParamTy` and `UnsizedConstParamTy`. Depending on whether `unsized_const_parameters` is enabled or not we change which trait is used to check whether a type is allowed to be a const parameter.
Long term (when stabilizing `UnsizedConstParamTy`) it should be possible to completely merge these traits (and derive macros), only having a single `trait ConstParamTy` and `macro ConstParamTy`.
Under `adt_const_params` it is now illegal to directly refer to `ConstParamTy` it is only used as an internal impl detail by `derive(ConstParamTy)` and checking const parameters are well formed. This is necessary in order to ensure forwards compatibility with all possible future directions for `feature(unsized_const_parameters)`.
Generally the intuition here should be that `ConstParamTy` is the stable trait that everything uses, and `UnsizedConstParamTy` is that plus unstable implementations (well, I suppose `ConstParamTy` isn't stable yet :P).
Rollup of 6 pull requests
Successful merges:
- #127295 (CFI: Support provided methods on traits)
- #127814 (`C-cmse-nonsecure-call`: improved error messages)
- #127949 (fix: explain E0120 better cover cases when its raised)
- #127966 (Use structured suggestions for unconstrained generic parameters on impl blocks)
- #127976 (Lazy type aliases: Diagostics: Detect bivariant ty params that are only used recursively)
- #127978 (Avoid ref when using format! for perf)
r? `@ghost`
`@rustbot` modify labels: rollup
Avoid ref when using format! for perf
Clean up a few minor refs in `format!` macro, as it has a performance cost. Apparently the compiler is unable to inline `format!("{}", &variable)`, and does a run-time double-reference instead (format macro already does one level referencing). Inlining format args prevents accidental `&` misuse.
Use Option's discriminant as its size hint
I was looking at this in MIR after a question on discord, and noticed that it ends up with a switch in MIR (<https://rust.godbolt.org/z/3q4cYnnb3>), which it doesn't need because (as `Option::as_slice` uses) the discriminant is already the length.
ptr::metadata: avoid references to extern types
References to `extern types` are somewhat dubious entities, since generally we say that references must be dereferenceable for their size as determined via `size_of_val`, but with `extern type` that is an ill-defined statement. I'd like to make Miri warn for such cases since it interacts poorly with Stacked Borrows. To avoid warnings people can't fix, this requires not using references to `extern type` in the standard library, and I think `DynMetadata` is the only currently remaining use. so this changes `DynMetadata` to use a NonNull raw pointer instead. Given that the alignment was 1, this shouldn't really change anything meaningful.
I also updated a comment added by `@scottmcm` in https://github.com/rust-lang/rust/pull/125479, since I think the old comment is wrong. The `DynMetadata` type itself is not special, it is a normal aggregate. But computing field types for wide pointers (including references) is special.
Move a few intrinsics to Rust abi
Move a few more intrinsic functions to the convention added in #121192. In the second commit, I added documentation about their safety requirements. Let me know if you would like me to move the second commit to a different PR.
Note: I kept the same signature of `pref_align_of`, but I was wondering why this function is considered unsafe?
Clean up more comments near use declarations
#125443 will reformat all use declarations in the repository. There are a few edge cases involving comments on use declarations that require care. This PR fixes them up so #125443 can go ahead with a simple `x fmt --all`. A follow-up to #126717.
r? ``@cuviper``
Skip fast path for dec2flt when optimize_for_size
Tracking issue: https://github.com/rust-lang/rust/issues/125612
Skip the fast algorithm when optimizing for size.
When compiling for https://github.com/quartiq/stabilizer I get these numbers:
Before
```
text data bss dec hex filename
192192 8 49424 241624 3afd8 dual-iir
```
After
```
text data bss dec hex filename
191632 8 49424 241064 3ada8 dual-iir
```
This saves 560 bytes.
There are some comments describing multiple subsequent `use` items. When
the big `use` reformatting happens some of these `use` items will be
reordered, possibly moving them away from the comment. With this
additional level of formatting it's not really feasible to have comments
of this type. This commit removes them in various ways:
- merging separate `use` items when appropriate;
- inserting blank lines between the comment and the first `use` item;
- outright deletion (for comments that are relatively low-value);
- adding a separate "top-level" comment.
We also entirely skip formatting for four library files that contain
nothing but `pub use` re-exports, where reordering would be painful.
fix least significant digits of f128 associated constants
While the numbers are parsed to the correct value, the decimal numbers in the source were rounded to zero instead of to the nearest, making the literals different from the values shown in the documentation.
Rollup of 6 pull requests
Successful merges:
- #124921 (offset_from: always allow pointers to point to the same address)
- #127407 (Make parse error suggestions verbose and fix spans)
- #127684 (consolidate miri-unleashed tests for mutable refs into one file)
- #127729 (Stop using the `gen` identifier in the compiler)
- #127736 (Add myself to the review rotation)
- #127758 (coverage: Restrict `ExpressionUsed` simplification to `Code` mappings)
r? `@ghost`
`@rustbot` modify labels: rollup
offset_from: always allow pointers to point to the same address
This PR implements the last remaining part of the t-opsem consensus in https://github.com/rust-lang/unsafe-code-guidelines/issues/472: always permits offset_from when both pointers have the same address, no matter how they are computed. This is required to achieve *provenance monotonicity*.
Tracking issue: https://github.com/rust-lang/rust/issues/117945
### What is provenance monotonicity and why does it matter?
Provenance monotonicity is the property that adding arbitrary provenance to any no-provenance pointer must never make the program UB. More specifically, in the program state, data in memory is stored as a sequence of [abstract bytes](https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#abstract-byte), where each byte can optionally carry provenance. When a pointer is stored in memory, all of the bytes it is stored in carry that provenance. Provenance monotonicity means: if we take some byte that does not have provenance, and give it some arbitrary provenance, then that cannot change program behavior or introduce UB into a UB-free program.
We care about provenance monotonicity because we want to allow the optimizer to remove provenance-stripping operations. Removing a provenance-stripping operation effectively means the program after the optimization has provenance where the program before the optimization did not -- since the provenance removal does not happen in the optimized program. IOW, the compiler transformation added provenance to previously provenance-free bytes. This is exactly what provenance monotonicity lets us do.
We care about removing provenance-stripping operations because `*ptr = *ptr` is, in general, (likely) a provenance-stripping operation. Specifically, consider `ptr: *mut usize` (or any integer type), and imagine the data at `*ptr` is actually a pointer (i.e., we are type-punning between pointers and integers). Then `*ptr` on the right-hand side evaluates to the data in memory *without* any provenance (because [integers do not have provenance](https://rust-lang.github.io/rfcs/3559-rust-has-provenance.html#integers-do-not-have-provenance)). Storing that back to `*ptr` means that the abstract bytes `ptr` points to are the same as before, except their provenance is now gone. This makes `*ptr = *ptr` a provenance-stripping operation (Here we assume `*ptr` is fully initialized. If it is not initialized, evaluating `*ptr` to a value is UB, so removing `*ptr = *ptr` is trivially correct.)
### What does `offset_from` have to do with provenance monotonicity?
With `ptr = without_provenance(N)`, `ptr.offset_from(ptr)` is always well-defined and returns 0. By provenance monotonicity, I can now add provenance to the two arguments of `offset_from` and it must still be well-defined. Crucially, I can add *different* provenance to the two arguments, and it must still be well-defined. In other words, this must always be allowed: `ptr1.with_addr(N).offset_from(ptr2.with_addr(N))` (and it returns 0). But the current spec for `offset_from` says that the two pointers must either both be derived from an integer or both be derived from the same allocation, which is not in general true for arbitrary `ptr1`, `ptr2`.
To obtain provenance monotonicity, this PR hence changes the spec for offset_from to say that if both pointers have the same address, the function is always well-defined.
### What further consequences does this have?
It means the compiler can no longer transform `end2 = begin.offset(end.offset_from(begin))` into `end2 = end`. However, it can still be transformed into `end2 = begin.with_addr(end.addr())`, which later parts of the backend (when provenance has been erased) can trivially turn into `end2 = end`.
The only alternative I am aware of is a fundamentally different handling of zero-sized accesses, where a "no provenance" pointer is not allowed to do zero-sized accesses and instead we have a special provenance that indicates "may be used for zero-sized accesses (and nothing else)". `offset` and `offset_from` would then always be UB on a "no provenance" pointer, and permit zero-sized offsets on a "zero-sized provenance" pointer. This achieves provenance monotonicity. That is, however, a breaking change as it contradicts what we landed in https://github.com/rust-lang/rust/pull/117329. It's also a whole bunch of extra UB, which doesn't seem worth it just to achieve that transformation.
### What about the backend?
LLVM currently doesn't have an intrinsic for pointer difference, so we anyway cast to integer and subtract there. That's never UB so it is compatible with any relaxation we may want to apply.
If LLVM gets a `ptrsub` in the future, then plausibly it will be consistent with `ptradd` and [consider two equal pointers to be inbounds](https://github.com/rust-lang/rust/pull/124921#issuecomment-2205795829).
These constifications were blocked on classification functions being
added. Now that those methods are available, constify them.
This brings things more in line with `f32` and `f64`.
Remove memory leaks in doctests in `core`, `alloc`, and `std`
cc `@RalfJung` https://github.com/rust-lang/rust/issues/126067https://github.com/rust-lang/miri/issues/3670
Should be no actual *documentation* changes[^1], all added/modified lines in the doctests are hidden with `#`,
This PR splits the existing memory leaks in doctests in `core`, `alloc`, and `std` into two general categories:
1. "Non-focused" memory leaks that are incidental to the thing being documented, and/or are easy to remove, i.e. they are only there because preventing the leak would make the doctest less clear and/or concise.
- These doctests simply have a comment like `# // Prevent leaks for Miri.` above the added line that removes the memory leak.
- [^2]Some of these would perhaps be better as part of the public documentation part of the doctest, to clarify that a memory leak can happen if it is not otherwise mentioned explicitly in the documentation (specifically the ones in `(A)Rc::increment_strong_count(_in)`).
2. "Focused" memory leaks that are intentional and documented, and/or are possibly fragile to remove.
- These doctests have a `# // FIXME` comment above the line that removes the memory leak, with a note that once `-Zmiri-disable-leak-check` can be applied at test granularity, these tests should be "un-unleakified" and have `-Zmiri-disable-leak-check` enabled.
- Some of these are possibly fragile (e.g. unleaking the result of `Vec::leak`) and thus should definitely not be made part of the documentation.
This should be all of the leaks currently in `core` and `alloc`. I only found one leak in `std`, and it was in the first category (excluding the modules `@RalfJung` mentioned in https://github.com/rust-lang/rust/issues/126067 , and reducing the number of iterations of [one test](https://github.com/rust-lang/rust/blob/master/library/std/src/sync/once_lock.rs#L49-L94) from 1000 to 10)
[^1]: assuming [^2] is not added
[^2]: backlink
Stabilize const unchecked conversion from u32 to char
Closes https://github.com/rust-lang/rust/issues/89259.
The functions in this PR were left out of the initial set of `feature(const_char_convert)` stabilizations in https://github.com/rust-lang/rust/pull/102470, but have since been unblocked by https://github.com/rust-lang/rust/pull/118979.
If `unsafe { from_u32_unchecked(u) }` is called in const with a value for which `from_u32(u)` returns None, we get the following compile error.
```rust
fn main() {
let _ = const { unsafe { char::from_u32_unchecked(0xd800) } };
}
```
```console
error[E0080]: it is undefined behavior to use this value
--> src/main.rs:2:19
|
2 | let _ = const { unsafe { char::from_u32_unchecked(0xd800) } };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x0000d800, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 4, align: 4) {
00 d8 00 00 │ ....
}
note: erroneous constant encountered
--> src/main.rs:2:13
|
2 | let _ = const { unsafe { char::from_u32_unchecked(0xd800) } };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
Improved slice documentation
Improve slice documentation to include assert_eq checks for all the cases where there were existing examples. I think it makes things more clear when the documentation explicitly checks against values and shows the reader what it does.
I also started a rust internals discussion about it here: https://internals.rust-lang.org/t/improve-slice-documentaion/21168