Add link to closed PR for future optimizers of ChunkedBitSet relations
While optimizing these operations proved unfruitful w.r.t. improving compiler performance right now, faster versions might be needed at a later time. This PR adds a link in the FIXME to save any future optimizers some time, as requested by `@nnethercote` in https://github.com/rust-lang/rust/pull/94625.
r? `@nnethercote`
Rollup of 4 pull requests
Successful merges:
- #93350 (libunwind: readd link attrs to _Unwind_Backtrace)
- #93827 (Stabilize const_fn_fn_ptr_basics, const_fn_trait_bound, and const_impl_trait)
- #94696 (Remove whitespaces and use CSS to align line numbers to the right instead)
- #94700 (rustdoc: Update minifier version)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
rustdoc: Update minifier version
This new version includes a fix for the CSS minifier which was badly handling inline media queries like ``@import` 'i';`.
r? `@notriddle`
Remove whitespaces and use CSS to align line numbers to the right instead
Instead of generating whitespaces to create padding, we simply use the CSS rule: `text-align: right`.
Nice side-effect: it reduces the generated HTML size from **75.004** to **74.828** (MegaBytes) on the std source pages (it's not much but it's always a nice plus 😆 ).
There are no changes in the generated UI.
r? `@notriddle`
Stabilize const_fn_fn_ptr_basics, const_fn_trait_bound, and const_impl_trait
# Stabilization Report
This PR serves as a request for stabilization for three const evaluation features:
1. `const_fn_fn_ptr_basics`
2. `const_fn_trait_bound`
3. `const_impl_trait`
These are being stabilized together because they are relatively minor and related updates to existing functionality.
## `const_fn_fn_ptr_basics`
Allows creating, passing, and casting function pointers in a `const fn`.
The following is an example of what is now allowed:
```rust
const fn get_function() -> fn() {
fn foo() {
println!("Hello, World!");
}
foo
}
```
Casts between function pointer types are allowed, as well as transmuting from integers:
```rust
const fn get_function() -> fn() {
unsafe {
std::mem::transmute(0x1234usize)
}
}
```
However, casting from a function pointer to an integer is not allowed:
```rust
const fn fn_to_usize(f: fn()) -> usize {
f as usize //~ pointers cannot be cast to integers during const eval
}
```
Calling function pointers is also not allowed.
```rust
const fn call_fn_ptr(f: fn()) {
f() //~ function pointers are not allowed in const fn
}
```
### Test Coverage
The following tests include code that exercises this feature:
- `src/test/ui/consts/issue-37550.rs`
- `src/test/ui/consts/issue-46553.rs`
- `src/test/ui/consts/issue-56164.rs`
- `src/test/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs`
- `src/test/ui/consts/min_const_fn/cast_fn.rs`
- `src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs`
## `const_fn_trait_bound`
Allows trait bounds in `const fn`. Additionally, this feature allows creating and passing `dyn Trait` objects.
Examples such as the following are allowed by this feature:
```rust
const fn do_thing<T: Foo>(_x: &T) {
// ...
}
```
Previously only `Sized` was allowed as a trait bound.
There is no way to call methods from the trait because trait methods cannot currently be marked as const. Allowing trait bounds in const functions does allow the const function to use the trait's associated types and constants.
This feature also allowes `dyn Trait` types. These work equivalently to non-const code. Similar to other pointers in const code, the value of a `dyn Trait` pointer cannot be observed.
Note that due to https://github.com/rust-lang/rust/issues/90912, it was already possible to do the example above as follows:
```rust
const fn do_thing<T>(_x: &T) where (T,): Foo {
// ...
}
```
### Test Coverage
The following tests include code that exercises `const_fn_trait_bound`:
- `src/test/ui/consts/const-fn.rs`
- `src/test/ui/consts/issue-88071.rs`
- `src/test/ui/consts/min_const_fn/min_const_fn.rs`
- `src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs`
- `src/test/ui/nll/issue-55825-const-fn.rs`
- Many of the tests in `src/test/ui/rfc-2632-const-trait-impl/` also exercise this feature.
## `const_impl_trait`
Allows argument and return position `impl Trait` in a `const fn`, such as in the following example:
```rust
const fn do_thing(x: impl Foo) -> impl Foo {
x
}
```
Similar to generic parameters and function pointers, this allows the creation of such opaque types, but not doing anything with them beyond accessing associated types and constants.
### Test Coverage
The following tests exercise this feature:
- `src/test/ui/type-alias-impl-trait/issue-53096.rs`
- `src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs`
## Documentation
These features are documented along with the other const evaluation features in the Rust Reference at https://doc.rust-lang.org/stable/reference/const_eval.html.
There is a PR that updates this documentation to reflect the capabilities enabled by these features at https://github.com/rust-lang/reference/pull/1166.
Tracking issues: #57563, #63997, #93706
libunwind: readd link attrs to _Unwind_Backtrace
It seems the removal of these in 1c07096a45 was unintended; readding them fixes the build.
fixesrust-lang/rust#93349
r? `@alexcrichton`
Clarify `Layout` interning.
`Layout` is another type that is sometimes interned, sometimes not, and
we always use references to refer to it so we can't take any advantage
of the uniqueness properties for hashing or equality checks.
This commit renames `Layout` as `LayoutS`, and then introduces a new
`Layout` that is a newtype around an `Interned<LayoutS>`. It also
interns more layouts than before. Previously layouts within layouts
(via the `variants` field) were never interned, but now they are. Hence
the lifetime on the new `Layout` type.
Unlike other interned types, these ones are in `rustc_target` instead of
`rustc_middle`. This reflects the existing structure of the code, which
does layout-specific stuff in `rustc_target` while `TyAndLayout` is
generic over the `Ty`, allowing the type-specific stuff to occur in
`rustc_middle`.
The commit also adds a `HashStable` impl for `Interned`, which was
needed. It hashes the contents, unlike the `Hash` impl which hashes the
pointer.
r? `@fee1-dead`
interpret: move saturating_add/sub into (pub) helper method
I plan to use them for `simd_saturating_add/sub`.
The first commit just moves code, the 2nd simplifies it a bit with some helper methods that did not exist yet when the code was originally written.
Remove ordering traits from `rustc_span::hygiene::LocalExpnId`
Part of work on #90317.
Also adds a negative impl block as a form of documentation and a roadblock to regression.
Rollup of 4 pull requests
Successful merges:
- #94636 (Check extra function arg exprs even if the fn is not C-variadic)
- #94676 (Remove unnecessary `..` patterns)
- #94681 (CTFE engine: expose misc_cast to Miri)
- #94684 (Fix rustdoc for GATs with with anonymous bound regions)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
CTFE engine: expose misc_cast to Miri
We need that to implement `simd_cast`/`simd_as` in Miri.
While at it, also change other code outside `cast.rs` to use `misc_cast` instead of lower-level methods.
r? `@oli-obk`
Check extra function arg exprs even if the fn is not C-variadic
We should still call check_expr on the args that exceed the formal input ty count, so that we have expr types to emit during writeback.
Not sure where this regressed, but it wasn't due to the same root cause as #94334 I think. I thought this might've regressed in #92360, but I think that is in stable, ad the test I provided (which minimizes #94599) passes on stable in playground. Maybe it regressed in #93118.
Anywho, fixes#94599.
`Layout` is another type that is sometimes interned, sometimes not, and
we always use references to refer to it so we can't take any advantage
of the uniqueness properties for hashing or equality checks.
This commit renames `Layout` as `LayoutS`, and then introduces a new
`Layout` that is a newtype around an `Interned<LayoutS>`. It also
interns more layouts than before. Previously layouts within layouts
(via the `variants` field) were never interned, but now they are. Hence
the lifetime on the new `Layout` type.
Unlike other interned types, these ones are in `rustc_target` instead of
`rustc_middle`. This reflects the existing structure of the code, which
does layout-specific stuff in `rustc_target` while `TyAndLayout` is
generic over the `Ty`, allowing the type-specific stuff to occur in
`rustc_middle`.
The commit also adds a `HashStable` impl for `Interned`, which was
needed. It hashes the contents, unlike the `Hash` impl which hashes the
pointer.
Introduce `ConstAllocation`.
Currently some `Allocation`s are interned, some are not, and it's very
hard to tell at a use point which is which.
This commit introduces `ConstAllocation` for the known-interned ones,
which makes the division much clearer. `ConstAllocation::inner()` is
used to get the underlying `Allocation`.
In some places it's natural to use an `Allocation`, in some it's natural
to use a `ConstAllocation`, and in some places there's no clear choice.
I've tried to make things look as nice as possible, while generally
favouring `ConstAllocation`, which is the type that embodies more
information. This does require quite a few calls to `inner()`.
The commit also tweaks how `PartialOrd` works for `Interned`. The
previous code was too clever by half, building on `T: Ord` to make the
code shorter. That caused problems with deriving `PartialOrd` and `Ord`
for `ConstAllocation`, so I changed it to build on `T: PartialOrd`,
which is slightly more verbose but much more standard and avoided the
problems.
r? `@fee1-dead`
Currently some `Allocation`s are interned, some are not, and it's very
hard to tell at a use point which is which.
This commit introduces `ConstAllocation` for the known-interned ones,
which makes the division much clearer. `ConstAllocation::inner()` is
used to get the underlying `Allocation`.
In some places it's natural to use an `Allocation`, in some it's natural
to use a `ConstAllocation`, and in some places there's no clear choice.
I've tried to make things look as nice as possible, while generally
favouring `ConstAllocation`, which is the type that embodies more
information. This does require quite a few calls to `inner()`.
The commit also tweaks how `PartialOrd` works for `Interned`. The
previous code was too clever by half, building on `T: Ord` to make the
code shorter. That caused problems with deriving `PartialOrd` and `Ord`
for `ConstAllocation`, so I changed it to build on `T: PartialOrd`,
which is slightly more verbose but much more standard and avoided the
problems.
explain why shift with signed offset works the way it does
I was worried for a bit here that Miri/CTFE would be inconsistent with codegen, but I *think* everything is all right, actually.
Cc `@oli-obk` `@eddyb`
Always include global target features in function attributes
This ensures that information about target features configured with
`-C target-feature=...` or detected with `-C target-cpu=native` is
retained for subsequent consumers of LLVM bitcode.
This is crucial for linker plugin LTO, since this information is not
conveyed to the plugin otherwise.
<details><summary>Additional test case demonstrating the issue</summary>
```rust
extern crate core;
#[inline]
#[target_feature(enable = "aes")]
unsafe fn f(a: u128, b: u128) -> u128 {
use core::arch::x86_64::*;
use core::mem::transmute;
transmute(_mm_aesenc_si128(transmute(a), transmute(b)))
}
pub fn g(a: u128, b: u128) -> u128 {
unsafe { f(a, b) }
}
fn main() {
let mut args = std::env::args();
let _ = args.next().unwrap();
let a: u128 = args.next().unwrap().parse().unwrap();
let b: u128 = args.next().unwrap().parse().unwrap();
println!("{}", g(a, b));
}
```
```console
$ rustc --edition=2021 a.rs -Clinker-plugin-lto -Clink-arg=-fuse-ld=lld -Ctarget-feature=+aes -O
...
= note: LLVM ERROR: Cannot select: intrinsic %llvm.x86.aesni.aesenc
```
</details>
r? `@nagisa`