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
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
BinOpAssign always returns unit
I don't know why we treated assign ops as returning their binop type sometimes, but it's usually ignored later anyway and mostly affects infer vars.
Also updated a comment from 11 years ago when SIMD types apparently had builtin `==` logic.
codegen: Copy to an alloca when the argument is neither by-val nor by-move for indirect pointer.
Fixes https://github.com/rust-lang/rust/issues/155241.
When a value is passed via an indirect pointer, the value needs to be copied to a new alloca. For x86_64-unknown-linux-gnu, `Thing` is the case:
```rust
#[derive(Clone, Copy)]
struct Thing(usize, usize, usize);
pub fn foo() {
let thing = Thing(0, 0, 0);
bar(thing);
assert_eq!(thing.0, 0);
}
#[inline(never)]
#[unsafe(no_mangle)]
pub fn bar(mut thing: Thing) {
thing.0 = 1;
}
```
Before passing the thing to the bar function, the thing needs to be copied to an alloca that is passed to bar.
```llvm
%0 = alloca [24 x i8], align 8
call void @llvm.memcpy.p0.p0.i64(ptr align 8 %0, ptr align 8 %thing, i64 24, i1 false)
call void @bar(ptr %0)
```
This patch applies the rule to the untupled arguments as well.
```rust
#![feature(fn_traits)]
#[derive(Clone, Copy)]
struct Thing(usize, usize, usize);
#[inline(never)]
#[unsafe(no_mangle)]
pub fn foo() {
let thing = (Thing(0, 0, 0),);
(|mut thing: Thing| {
thing.0 = 1;
}).call(thing);
assert_eq!(thing.0.0, 0);
}
```
For this case, this patch changes from
```llvm
; call example::foo::{closure#0}
call void @_RNCNvCs15qdZVLwHPA_7example3foo0B3_(ptr ..., ptr %thing)
```
to
```llvm
%0 = alloca [24 x i8], align 8
call void @llvm.memcpy.p0.p0.i64(ptr align 8 %0, ptr align 8 %thing, i64 24, i1 false)
; call example::foo::{closure#0}
call void @_RNCNvCs15qdZVLwHPA_7example3foo0B3_(ptr ..., ptr %0)
```
However, the same rule cannot be applied to tail calls that would be unsound, because the caller's stack frame is overwritten by the callee's stack frame. Fortunately, https://github.com/rust-lang/rust/pull/151143 has already handled the special case. We must not copy again.
No copy is needed for by-move arguments, because the argument is passed to the called "in-place".
No copy is also needed for by-val arguments, because the attribute implies that a hidden copy of the pointee is made between the caller and the callee.
NOTE: The patch has a trick for tail calls that we pass by-move. We can choose to copy an alloca even for by-move arguments, but tail calls require MUST-by-move.
Skipping FileCheck in codegen/assembly tests is normally not very useful, but a
small number of existing tests were using `//@ build-pass` to do so anyway, so
it's clearer for them to explicitly use `//@ skip-filecheck` instead.
Rollup of 7 pull requests
Successful merges:
- rust-lang/rust#155589 (Forbid `check-pass`/`build-pass`/`run-pass` directives in incremental tests)
- rust-lang/rust#155610 (Add missing `dyn` keyword to `trait_alias` page of the Unstable Book)
- rust-lang/rust#155615 (test cleanups for `ui/derives` and `ui/deriving`)
- rust-lang/rust#154874 (Fix ICE for inherited const conditions on const closures)
- rust-lang/rust#155605 (std: Update support for `wasm32-wasip3`)
- rust-lang/rust#155613 (c-variadic: tweak `std` docs)
- rust-lang/rust#155619 (Remove a bunch of unnecessary explicit lifetimes from the ast validator)
Fix ICE for inherited const conditions on const closures
Synchronize `evaluate_host_effect_for_fn_goal` with the behavior of `extract_fn_def_from_const_callable` in new solver.
Closesrust-lang/rust#153861 .
test cleanups for `ui/derives` and `ui/deriving`
The eventual goal is for `ui/deriving` to be merged into `ui/derives` entirely. This PR focuses on the `issue-*.rs` tests in `deriving` and a few other no-longer-useful tests.
r? @Kivooeo
Forbid `check-pass`/`build-pass`/`run-pass` directives in incremental tests
- Follow-up to https://github.com/rust-lang/rust/pull/155474
---
This PR forbids the use of `//@ check-pass`, `//@ build-pass`, and `//@ run-pass` directives in incremental tests. Tests that would have used those directives should use a revision name beginning with `cpass`/`bpass`/`rpass` instead.
(The `*-fail` directives are already forbidden in incremental tests.)
Existing incremental tests that used the `check-pass` and `build-pass` directives have been migrated. To allow migration of the check-pass tests, this PR also adds support for revision names beginning with `cpass`. No incremental tests were using `run-pass`.
---
Several of the migrated `build-pass` tests have a FIXME indicating that they could potentially be migrated to `check-pass` instead. This PR does not perform that migration.
In the future, I intend to do more cleanup of how compiletest handles pass/fail expectations, but I didn't want to cram too much into one PR.
r? jieyouxu
This is the subset of incremental tests that have a FIXME to consider migrating
to check-pass instead.
That migration is beyond the scope of this PR, but might be attempted later.
This is the subset of incremental tests that should continue to use `bpass`
even after `cpass` is supported, because they (presumably) involve codegen.
Fix incorrect `let` to `const` suggestion for pattern bindings
When a variable from a pattern binding was referenced inside a `const {}` block, the compiler incorrectly suggested replacing `let` with `const`. This was reported in rust-lang/rust#152831 for `if let`, but also applies to `while let` and `let ... else`.
Improve E0308 error message for `impl Trait` return mismatches
When a function returns `impl Trait`, all branches must return the same concrete type. Previously, the compiler showed:
expected `First` because of return type
This was misleading, as it suggested the return type was `First`, rather than any single type implementing the trait.
Update the diagnostic to:
expected a single type implementing `Value` because of return type
Also highlight the first return expression to make it clearer why subsequent returns do not match.
Rollup of 4 pull requests
Successful merges:
- rust-lang/rust#152611 (Modify error message of importing inherent associated items when `#[feature(import_trait_associated_functions)]` is enabled)
- rust-lang/rust#155359 (Improperctypes refactor2.2)
- rust-lang/rust#155036 (Store a PathBuf rather than SerializedModule for cached modules)
- rust-lang/rust#155554 (add warning message when using x fix)
Modify error message of importing inherent associated items when `#[feature(import_trait_associated_functions)]` is enabled
Fixesrust-lang/rust#148009
This PR improves the diagnostic for importing inherent associated items from a struct or union when
`#[feature(import_trait_associated_functions)]` (rust-lang/rust#134691) is enabled.
Previously, this would result in a "not a module" error. This change provides a more specific error message clarifying that only trait associated items can be imported, while inherent associated items remain ineligible for import.
Enums are currently excluded from this change because their variants are valid import targets and require distinct handling.
Move diagnostic attribute target checks from check_attr
Move diagnostic attribute target checks into their targets. Part of https://github.com/rust-lang/rust/issues/131229#issuecomment-3959910413
This is much easier with `emit_dyn_lint` :) (thanks @GuillaumeGomez !)
I think there might be some opportunity to simplify all these `check_diagnostic_*` methods in `check_attr`. However there are some diagnostic attribute prs in flight and I'd like to wait for those to land first and then think about it. So that PR is not for today.
r? @JonathanBrouwer (or @GuillaumeGomez if you want)
Fix `#[expect(dead_code)]` liveness propagation
Fixes https://github.com/rust-lang/rust/issues/154324
Fixes https://github.com/rust-lang/rust/issues/152370 (cc @eggyal)
Previously, when traversing from a `ComesFromAllowExpect::Yes` item (i.e., with `#[allow(dead_code)]` or `#[expect(dead_code)]`), other `ComesFromAllowExpect::Yes` items reached during propagation would be updated to `ComesFromAllowExpect::No` and inserted into `live_symbols`. That caused `dead_code` lint couldn't be emitted correctly.
After this PR, `ComesFromAllowExpect::Yes` items no longer incorrectly update other `ComesFromAllowExpect::Yes` items during propagation or mark them live by mistake, then `dead_code` lint could behave as expected.