Rollup merge of #155772 - oli-obk:const-closures-everywhere, r=fee1-dead
Check closure's constness validity in the constness query
fixesrust-lang/rust#155584
instead of checking during ast lowering, where it's not easily possible to obtain all the right information in time. While lowering an assoc item we don't know if the parent was a const trait or a const impl. Tracing this information is quite annoying, and complicates a lot of code, which checking here after the fact is trivial.
Avoid Vec allocation in TyCtxt::mk_place_elem
`mk_place_elem` appends a single `PlaceElem` to an existing (interned) projection. The current implementation copies the projection into a fresh `Vec`, pushes the new element, and re-interns the slice, which allocates on every call.
Feed the elements through `mk_place_elems_from_iter` so that `CollectAndApply`'s hand-unrolled stack fast path (up to 9 elements, in `rustc_type_ir::interner`) kicks in for the common case of short projections and the `Vec` allocation is skipped entirely. The behavior is identical for longer projections (the fast path falls back to a `Vec` internally).
Fix requires_lto targets needing lto set in cargo
Targets that set `requires_lto = true` were not actually using lto when compiling with cargo by default. They needed an extra `lto = true` in `Cargo.toml` to work.
Fix this by letting lto take precedence over the `embed_bitcode` flag when lto is required by a target.
If both these flags would be supplied by the user, an error is generated. However, this did not happen when lto was requested by the target instead of the user.
Fixesrust-lang/rust#148514
Tracking issue: rust-lang/rust#135024
Avoid improper spans when `...` or `..=` is recovered from non-ASCII
- Fixes https://github.com/rust-lang/rust/issues/155799
Adjusting span endpoints by `BytePos(1)` is almost always bad news.
In this case, the code assumed that it was skipping over a single ASCII character. But in the presence of parser recovery from other non-ASCII characters this resulted in an ICE due to bad string indexing when emitting suggestions.
Cleanups to `AttributeExt`
r? @mejrs
- Makes some functions take `ast::Attribute` instead of `impl AttributeExt`
- Remove `deprecation_note` from `AttributeExt`, since the two implementations are basically seperate
Suggest enclosing format string with `""` under special cases
This commit adds suggestions on enclosing format string with `""` when it falls into the following 3 cases: `{}`, `{:?}`, `{:#?}` as mentioned in rust-lang/rust#155508.
Currently, this commit only recognizes the above 3 cases. I wonder if we should generalize this to more cases, for example, appying this suggestion to `Block`s with only 0 or 1 `Stmt`, such as `{:#x}`, `{:^10}`, `{abc}`.
macro_metavar_expr_concat: explain why idents are invalid
Recently I've been playing around with `macro_metavar_expr_concat` and in the process wasted more time than I'd have liked on debugging my dodgy idents. This should make that experience much nicer going forward.
Prefer `-1` for `None`
Currently we pick "weird" numbers like `1114112` for `None::<char>`. While that's not *wrong*, it's kinda *unnatural* -- a human wouldn't make that choice.
This PR instead picks `-1` for thinge like `None::<char>` -- like [clang's `WEOF`](https://github.com/llvm/llvm-project/blob/63ae74b78a11f6c61136dbc445652929389eb9ab/libc/include/llvm-libc-macros/wchar-macros.h#L15) -- and `None::<bool>` and such.
Any enums with more than one niched value (so not `Result` nor `Option`) remain as they were before. Also we continue to use `0` when that's possible -- `-1` is only preferred when zero *isn't* possible.
---
Inspired when someone in discord posted an example like this <https://rust.godbolt.org/z/W94s9qdYW> and I thought it was odd that we're currently picking `-9223372036854775808` to be the value to store to mark an `Option<Vec<_>>` as `None`. (Especially since that needs an 8-byte immediate on x64, and writing `-1` is only a 4-byte immediate.)
* Suggest enclosing format string under special cases
This commit add suggestions about enclosing format string when it falls
into the following cases: `{}`, `{:?}`, `{:#?}`.
* Add HELP annotations in the UI test
Currently we pick "weird" numbers like `1114112` for `None::<char>`. While that's not *wrong*, it's kinda *unnatural* -- a human wouldn't make that choice.
This PR instead picks `-1` for thinge like `None::<char>` -- like clang's `WEOF` -- and `None::<bool>` and such.
Any enums with more than one niched value (so not `Result` nor `Option`) remain as they were before.
Reject implementing const Drop for types that are not const `Destruct` already
fixesrust-lang/rust#155618
While there is no soundness or otherwise issue currently, this PR ensures that people get what they expect. It seems wrong to allow implementing `const Drop`, but then the type still can't be dropped at compile-time.
r? @fee1-dead
Error on invalid macho section specifier
The macho section specifier used by `#[link_section = "..."]` is more strict than e.g. the one for elf. LLVM will error when you get it wrong, which is easy to do if you're used to elf. So, provide some guidance for the simplest mistakes, based on the LLVM validation.
Currently compilation fails with an LLVM error, see https://godbolt.org/z/WoE8EdK1K.
The LLVM validation logic is at
https://github.com/llvm/llvm-project/blob/a0f0d6342e0cd75b7f41e0e6aae0944393b68a62/llvm/lib/MC/MCSectionMachO.cpp#L199-L203
LLVM validates the other components of the section specifier too, but it feels a bit fragile to duplicate those checks. If you get that far, hopefully the LLVM errors will be sufficient to get unstuck.
---
sidequest from https://github.com/rust-lang/rust/pull/147811
r? JonathanBrouwer
specifically, is this the right place for this sort of validation? `rustc_attr_parsing` also does some validation.
Add intrinsic for launch-sized workgroup memory on GPUs
Workgroup memory is a memory region that is shared between all
threads in a workgroup on GPUs. Workgroup memory can be allocated
statically or after compilation, when launching a gpu-kernel.
The intrinsic added here returns the pointer to the memory that is
allocated at launch-time.
# Interface
With this change, workgroup memory can be accessed in Rust by
calling the new `gpu_launch_sized_workgroup_mem<T>() -> *mut T`
intrinsic.
It returns the pointer to workgroup memory guaranteeing that it is
aligned to at least the alignment of `T`.
The pointer is dereferencable for the size specified when launching the
current gpu-kernel (which may be the size of `T` but can also be larger
or smaller or zero).
All calls to this intrinsic return a pointer to the same address.
See the intrinsic documentation for more details.
## Alternative Interfaces
It was also considered to expose dynamic workgroup memory as extern
static variables in Rust, like they are represented in LLVM IR.
However, due to the pointer not being guaranteed to be dereferencable
(that depends on the allocated size at runtime), such a global must be
zero-sized, which makes global variables a bad fit.
# Implementation Details
Workgroup memory in amdgpu and nvptx lives in address space 3.
Workgroup memory from a launch is implemented by creating an
external global variable in address space 3. The global is declared with
size 0, as the actual size is only known at runtime. It is defined
behavior in LLVM to access an external global outside the defined size.
There is no similar way to get the allocated size of launch-sized
workgroup memory on amdgpu an nvptx, so users have to pass this
out-of-band or rely on target specific ways for now.
Tracking issue: rust-lang/rust#135516
privacy: Assert that compared visibilities are (usually) ordered
And make "greater than" (`>`) the new primary operation for comparing visibilities instead of "is at least" (`>=`).
`mk_place_elem` appends a single `PlaceElem` to an existing (interned)
projection. The current implementation copies the projection into a
fresh `Vec`, pushes the new element, and re-interns the slice, which
allocates on the heap on every call.
Feed the elements through `mk_place_elems_from_iter` so that
`CollectAndApply`'s hand-unrolled stack fast path (up to 9 elements,
in `rustc_type_ir::interner`) kicks in for the common case of short
projections and the `Vec` allocation is skipped entirely. The behavior
is identical for longer projections (the fast path falls back to a
`Vec` internally).
Do not modify resolver outputs during lowering
Split from https://github.com/rust-lang/rust/pull/142830
I believe this achieves the same thing as https://github.com/rust-lang/rust/pull/153656 but in a much simpler way.
This PR forces AST->HIR lowering to stop mutating resolver outputs. Instead, it manages a few override maps that only live during lowering and are dropped afterwards.
r? @petrochenkov
cc @aerooneqq