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
cleanup, restructure and merge `tests/ui/deriving` into `tests/ui/derives`
As a followup to https://github.com/rust-lang/rust/pull/155615, this PR deletes some outdated tests from these directories, splits up `ui/derives` into smaller directories to roughly group tests by the derive macros they use and moves over all tests from `ui/deriving` into `ui/derives`.
r? @Kivooeo
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
Handle index projections in call destinations in DSE
Since call destinations are evaluated after call arguments, we can't turn copy arguments into moves if the same local is later used as an index projection in the call destination.
DSE call arg optimization: rust-lang/rust#113758
r? @cjgillot
cc @RalfJung
Avoid redundant clone suggestions in borrowck diagnostics
Fixesrust-lang/rust#153886
Removed redundant `.clone()` suggestions.
I found that there are two patterns to handle this issue while I was implementing:
- Should suggest only UFCS
- Should suggest only simple `.clone()`
For the target issue, we can just remove the UFCS (`<Option<String> as Clone>::clone(&selection.1)`) side.
However, for the `BorrowedContentSource::OverloadedDeref` pattern like `Rc<Vec<i32>>`, for instance the `borrowck-move-out-of-overloaded-auto-deref.rs` test case, I think we need to employ the UFCS way. The actual test case is:
```rust
//@ run-rustfix
use std::rc::Rc;
pub fn main() {
let _x = Rc::new(vec![1, 2]).into_iter();
//~^ ERROR [E0507]
}
```
And another error will be shown if we simply use the simple `.clone()` pattern. Like:
```rust
use std::rc::Rc;
pub fn main() {
let _x = Rc::new(vec![1, 2]).clone().into_iter();
}
```
then we will get
```
error[E0507]: cannot move out of an `Rc`
--> src/main.rs:5:14
|
5 | let _x = Rc::new(vec![1, 2]).clone().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ----------- value moved due to this method call
| |
| move occurs because value has type `Vec<i32>`, which does not implement the `Copy` trait
|
note: `into_iter` takes ownership of the receiver `self`, which moves value
--> /playground/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/collect.rs:310:18
|
310 | fn into_iter(self) -> Self::IntoIter;
| ^^^^
help: you can `clone` the value and consume it, but this might not be your desired behavior
|
5 - let _x = Rc::new(vec![1, 2]).clone().into_iter();
5 + let _x = <Vec<i32> as Clone>::clone(&Rc::new(vec![1, 2])).into_iter();
|
For more information about this error, try `rustc --explain E0507`.
```
[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=7e767bed3f1c573c03642f20f454ed03)
In this case, `Rc::clone` only increments the reference count and returns a new `Rc<Vec<i32>>`; it does not grant ownership of the inner `Vec<i32>`. As a result, calling into_iter() attempts to move the `Vec<i32>`, leading to the same E0507 error again.
On the other hand, in UFCS form:
```
<Vec<i32> as Clone>::clone(&Rc::new(vec![1, 2])).into_iter()
```
This explicitly calls `<Vec<i32> as Clone>::clone`, and the argument `&Rc<Vec<i32>>` is treated as `&Vec<i32>` via Rc’s `Deref` implementation. As a result, the `Vec<i32>` itself is cloned, yielding an owned `Vec<i32>`, which allows `into_iter()` to succeed, if my understanding is correct.
I addressed the issue as far as I could find the edge cases but please advice me if I'm overlooking something.
Rollup of 3 pull requests
Successful merges:
- rust-lang/rust#155754 (make the `core::ffi::va_list` module private)
- rust-lang/rust#155522 (cmse: test returning `MaybeUninit<T>`)
- rust-lang/rust#155741 (std: Refactor BufWriter::flush to use the `?` operator)
cmse: test returning `MaybeUninit<T>`
tracking issue: https://github.com/rust-lang/rust/issues/81391
tracking issue: https://github.com/rust-lang/rust/issues/75835
Some tests from https://github.com/rust-lang/rust/pull/147697 that already work and are useful. Extracting them shrinks that (currently blocked) PR.
The code in `tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs` checks that `MaybeUninit<T>` is considered abi-compatible with `T`. The code in `tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs` really only tests that no errors/warnings are emitted.
r? davidtwco
Permit `{This}` in diagnostic attribute format literals
My motivation was that yesterday I wanted to write something like this and reference `$name` in the string literal.
```rust
pub mod sym {
// stuff here
}
macro_rules! my_macro {
($name:ident $(,)?) => {{
#[diagnostic::on_unknown(
message = "this is not present in symbol table",
note = "you must add it to rustc_span::symbol::symbol!"
)]
use sym::$name as name;
// ...
}}
}
```
That is (as far as I can tell) impossible or at least very unergonomic. This adds the ability to just reference the name of the item the attribute is on. I imagine that's useful for use inside macros generally, so it's also added for some other attributes.
The affected attributes are all unstable, it is not implemented for diagnostic::on_unimplemented (will do in its own PR).
Note that `{This}` is already usable in `#[rustc_on_unimplemented]`, so this does not implement it but just enables some more.
This PR also migrates one lint away from AttributeLintKind, and improves the messages for that lint.
Rollup of 12 pull requests
Successful merges:
- rust-lang/rust#149452 (Refactor out common code into a `IndexItem::new` constructor)
- rust-lang/rust#155621 (Document #[diagnostic::on_move] in the unstable book.)
- rust-lang/rust#155635 (delegation: rename `Self` generic param to `This` in recursive delegations)
- rust-lang/rust#155730 (Some cleanups around per parent disambiguators)
- rust-lang/rust#153537 (rustc_codegen_ssa: Define ELF flag value for sparc-unknown-linux-gnu)
- rust-lang/rust#155219 (Do not suggest borrowing enclosing calls for nested where-clause obligations)
- rust-lang/rust#155408 (rustdoc: Fix Managarm C Library name in cfg pretty printer)
- rust-lang/rust#155571 (Enable AddressSanitizer on arm-unknown-linux-gnueabihf and armv7-unknown-linux-gnueabihf)
- rust-lang/rust#155713 (test: Add a regression test for Apple platforms aborting on `free`)
- rust-lang/rust#155723 (Fix tier level for 5 thumb bare-metal ARM targets)
- rust-lang/rust#155735 (Fix typo by removing extra 'to')
- rust-lang/rust#155736 (Remove `AllVariants` workaround for rust-analyzer)
test: Add a regression test for Apple platforms aborting on `free`
Add a regression test for https://github.com/rust-lang/rust/issues/150898 to make users aware that if this test failures, they may encounter unusual behavior elsewhere.
Do not suggest borrowing enclosing calls for nested where-clause obligations
In rust-lang/rust#155088, the compiler was blaming the whole call expr instead of the value that actually failed the trait bound, so for foo(&[String::from("a")]) it was suggesting stuff like &foo(...). I changed the suggestion logic so it only emits borrow help if the expr it found actually matches the failed self type, and used the same check for the “similar impl exists” help too. So now the compiler should give the normal error + required bound note.
Fixrust-lang/rust#155088
delegation: rename `Self` generic param to `This` in recursive delegations
This PR supports renaming of `Self` generic parameter to `This` in recursive delegations scenario, this allows propagation of `This` as we rely on `Self` naming to check whether it is implicit Self of a trait. Comment with a bit deeper explanation is in `uplift_delegation_generic_params`. Part of rust-lang/rust#118212.
r? @petrochenkov
Add a regression test for RUST-150898 to make users aware that if this
test fails, they may encounter unusual behavior elsewhere.
Original repro authored by dianqk.
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.
Syntactically reject tuple index shorthands in struct patterns to fix a correctness regression
Split out of PR rust-lang/rust#154492. This fixes a correctness regression introduced in PR rust-lang/rust#81235 from 2021. Crater was run in my other PR and didn't report any real regressions (https://github.com/rust-lang/rust/pull/154492#issuecomment-4187544786); a rerun has been issued for a few spurious builds (https://github.com/rust-lang/rust/pull/154492#issuecomment-4237077272) but I'm certain it won't find anything either.
This is a theoretical breaking change that doesn't need any T-lang input IMHO since it's such a minute, niche and crystal clear bug that's not worth bothering them with (such a decision is not unprecedented). I'm adding it to the compatibility section of the release notes as is customary.
The Reference doesn't need updating since it didn't adopt this bug and thus accurately describes this part of the grammar as it used to be before 2021-02-23 and as it's meant to be.
The majority of the diff is doc comment additions & necessary UI test restructurings.
Move and clean up some ui test
`ui/reserved` -> `ui/keyword`
`ui/deref-patterns` -> `ui/pattern/deref-patterns`
`ui/unknown-unstable-lints` -> `ui/lint/unknown-lints`
Tests related to unknown_lints that were located above lint have also been moved to a subdirectory, and duplicate tests have been deleted.
And delete unnecessary `//@ check-fail`
r? Kivooeo
c-variadic: fix for sparc64
tracking issue: https://github.com/rust-lang/rust/issues/44930
Turns out it's a big-endian target that right-adjusts values in the stack slots.
Apparently these tests do get run occasionally, though i don't think test failures are usually turned into issues on this repo. I guess we could add an assembly test here too, though really you just have to run these tests. I've tried this locally with qemu, and it passes all c-variadic tests.
cc @thejpster @glaubitz
r? tgross35
Change keyword order for `impl` restrictions
Based on rust-lang/rust#155222, this PR reorders keywords in trait definitions to group restrictions with visibility. It changes the order from `pub(...) const unsafe auto impl(...) trait Foo {...}` to `pub(...) impl(...) const unsafe auto trait Foo {...}`.
Tracking issue for restrictions: rust-lang/rust#105077
r? @Urgau
cc @jhpratt
Fix ICE when const closure appears inside a non-const trait method
Fixesrust-lang/rust#153891
`hir_body_const_context()` unconditionally delegated to the parent's const context for const closures, returning `None` when the parent had no const context. This caused `mir_const_qualif()` to hit a `span_bug!`, since `mir_promoted()` had already decided to call it based on the closure's own syntactic constness. Fall back to `ConstContext::ConstFn` when the parent's const context is `None`, so that the const closure body is still properly const-checked rather than triggering an ICE.
Examining [another attempt](https://github.com/rust-lang/rust/pull/153900/changes) at this issue (which has already been closed), I thought that its approach represents a workaround fix to avoid inconsistencies in the caller of `mir_promoted()`, whereas I think the correct behavior is for `hir_body_const_context()` itself to return the proper value.
delegation: support self ty propagation for functions in free to trait reuse
This PR adds support for self types specified in free to trait reuse. Up to this point we always generated `Self` despite the fact whether self type was specified or not. Now we use it in signature inheritance. Moreover we no more generate `Self` for static methods. Part of rust-lang/rust#118212.
```rust
trait Trait<T> {
fn foo<const B: bool>(&self) {}
fn bar() {}
}
impl<T> Trait<T> for usize {}
reuse <usize as Trait>::foo;
// Desugaring (no `Self` as usize is specified)
fn foo<T, const B: bool>(self: &usize) {
<usize as Trait::<T>>::foo::<B>(self)
}
reuse Trait::bar;
// Desugaring (no `Self` as static method)
fn bar<T>() {
Trait::<T>::bar(); //~ERROR: type annotations needed
}
```
r? @petrochenkov
Since call destinations are evaluated after call arguments, we can't
turn copy arguments into moves if the same local is later used as an
index projection in the call destination.
Make `//@ skip-filecheck` a normal compiletest directive
The `skip-filecheck` directive is currently used by mir-opt tests, to suppress the default behaviour of running LLVM's `FileCheck` tool to check MIR output against FileCheck rules in the test file.
The `skip-filecheck` directive was not included in the big migration to `//@` directive syntax (https://github.com/rust-lang/rust/pull/121370), perhaps because it was parsed and processed in the *miropt-test-tools* helper crate, not in compiletest itself.
Recently I noticed that a small number of *codegen-llvm* tests were using the `//@ build-pass` directive, which has the non-obvious effect of skipping FileCheck in codegen tests. That's quite confusing, so I decided to have the mir-opt tests migrate over to a proper `//@ skip-filecheck` directive, which could then be used by codegen tests as well.
(I also added skip-filecheck support to assembly tests, which are very similar to codegen tests, though there are currently no assembly tests that actually use `//@ skip-filecheck`.)
---
Support for using `//@ build-pass` in codegen tests to skip FileCheck was introduced in https://github.com/rust-lang/rust/pull/113603. With hindsight, I think doing things that way was pretty clearly a mistake, and we'll be better off with `//@ skip-filecheck`.
r? jieyouxu