Remove invalid suggestion of into_iter for extern macro
Fixes#137345#109082 is closed due to performance issue, do we have any other solution for this kind of issue?
compiler: untangle SIMD alignment assumptions
There were a number of puzzling assumptions being made about SIMD types and their layout that I have corrected in this diff. These are mostly no-op edits in actual fact, but they do subtly alter a pair of checks in our invariant-checking and union layout computation that rested on those peculiar assumptions. Those unfortunately stand in the way of any further actual fixes. I submit this for review, even though it's not clearly motivated without its followups, because it should still be possible to independently conclude whether this is correct.
Give `global_asm` a fake body to store typeck results, represent `sym fn` as a hir expr to fix `sym fn` operands with lifetimes
There are a few intertwined problems with `sym fn` operands in both inline and global asm macros.
Specifically, unlike other anon consts, they may evaluate to a type with free regions in them without actually having an item-level type annotation to give them a "proper" type. This is in contrast to named constants, which always have an item-level type annotation, or unnamed constants which are constrained by their position (e.g. a const arg in a turbofish, or a const array length).
Today, we infer the type of the operand by looking at the HIR typeck results; however, those results are region-erased, so during borrowck we ICE since we don't expect to encounter erased regions. We can't just fill this type with something like `'static`, since we may want to use real (free) regions:
```rust
fn foo<'a>() {
asm!("/* ... */", sym bar::<&'a ()>);
}
```
The first idea may be to represent `sym fn` operands using *inline* consts instead of anon consts. This makes sense, since inline consts can reference regions from the parent body (like the `'a` in the example above). However, this introduces a problem with `global_asm!`, which doesn't *have* a parent body; inline consts *must* be associated with a parent body since they are not a body owner of their own. In #116087, I attempted to fix this by using two separate `sym` operands for global and inline asm. However, this led to a lot of confusion and also some unattractive code duplication.
In this PR, I adjust the lowering of `global_asm!` so that it's lowered in a "fake" HIR body. This body contains a single expression which is `ExprKind::InlineAsm`; we don't *use* this HIR body, but it's used in typeck and borrowck so that we can properly infer and validate the the lifetimes of `sym fn` operands.
I then adjust the lowering of `sym fn` to instead be represented with a HIR expression. This is both because it's no longer necessary to represent this operand as an anon const, since it's *just* a path expression, and also more importantly to sidestep yet another ICE (https://github.com/rust-lang/rust/issues/137179), which has to do with the existing code breaking an invariant of def-id creation and anon consts. Specifically, we are not allowed to synthesize a def-id for an anon const when that anon const contains expressions with def-ids whose parent is *not* that anon const. This is somewhat related to https://github.com/rust-lang/rust/pull/130443#issuecomment-2445678945, which is also a place in the compiler where synthesizing anon consts leads to def-id parenting issue.
As a side-effect, this consolidates the type checking for inline and global asm, so it allows us to simplify `InlineAsmCtxt` a bit. It also allows us to delete a bit of hacky code from anon const `type_of` which was there to detect `sym fn` operands specifically. This also could be generalized to support `const` asm operands with types with lifetimes in them. Since we specifically reject these consts today, I'm not going to change the representation of those consts (but they'd just be turned into inline consts).
r? oli-obk -- mostly b/c you're patient and also understand the breadth of the code that this touches, please reassign if you don't want to review this.
Fixes#111709Fixes#96304Fixes#137179
Inject `compiler_builtins` during postprocessing and ensure it is made private
Follow up of https://github.com/rust-lang/rust/pull/135278
Do the following:
* Inject `compiler_builtins` during postprocessing, rather than injecting `extern crate compiler_builtins as _` into the AST
* Do not make dependencies of `std` private by default (this was added in #135278)
* Make sure sysroot crates correctly mark their dependencies private/public
* Ensure that marking a dependency private makes its dependents private by default as well, unless otherwise specified
* Do the `compiler_builtins` update that has been blocked on this
There is more detail in the commit messages. This includes the changes I was working on in https://github.com/rust-lang/rust/pull/136226.
try-job: test-various
try-job: x86_64-msvc-1
try-job: x86_64-msvc-2
try-job: i686-mingw-1
try-job: i686-mingw-2
Include the match arm guard in the gated span, so that the suggestion to add a body is correct instead of inserting the body before the guard.
Make the suggestion verbose.
```
error: `match` arm with no body
--> $DIR/feature-gate-never_patterns.rs:43:9
|
LL | Some(_) if false,
| ^^^^^^^^^^^^^^^^
|
help: add a body after the pattern
|
LL | Some(_) if false => { todo!() },
| ++++++++++++++
```
Use StableHasher + Hash64 for dep_tracking_hash
This is similar to https://github.com/rust-lang/rust/pull/137095. We currently have a +/- 1 byte jitter in the size of dep graphs reported on perf.rust-lang.org. I think this fixes that jitter.
When I introduced `Hash64`, I wired it through most of the compiler by making it an output of `StableHasher::finalize` then fixing the compile errors. I missed this case because the `u64` hash in this function is being produced by `DefaultHasher` instead. That seems pretty sketchy because the code seems confident that the hash needs to be stable, and we have a mechanism for stable hashing that we weren't using here.
Always allow reusing cratenum in CrateLoader::load
The only case where can_reuse_cratenum could have been false in the past are rustc plugins, support for which has been removed over a year ago now. Nowadays the only case where locator.tuple is not target_triple is when loading a proc macro, in which case we also set can_reuse_cratenum to true. As such it is always true and we can remove some dead code.
Ferris 🦀 Identifier naming conventions
You cannot use Ferris as an identifier in Rust, this code will suggest to correct the 🦀 to `ferris`:
```rs
fn main() {
let 🦀 = 4;
}
```
But it also suggests to correct to `ferris` in these cases, too:
```rs
struct 🦀 {}
fn main() {}
```
^ suggests: `ferris`
~ with this PR: `Ferris`
```rs
static 🦀: &str = "ferris!";
fn main() {}
```
^ suggests: `ferris`
~ with this PR: `FERRIS`
This is my first pull requests here!
Use `edition = "2024"` in the compiler (redux)
Most of this is binding mode changes, which I fixed by running `x.py fix`.
Also adds some miscellaneous `unsafe` blocks for new unsafe standard library functions (the setenv ones), and a missing `unsafe extern` block in some enzyme codegen code, and fixes some precise capturing lifetime changes (but only when they led to errors).
cc ``@ehuss`` ``@traviscross``
Prune dead regionck code
We never encounter `ObligationCauseCode`s that correspond to region obligations that originate from "within" a body, since we don't do HIR regionck anymore on bodies. So prune some dead code.
test building enzyme in CI
1) This PR fixes a significant compile-time regression, by only running the expensive autodiff pipeline, if the users pass the newly introduced Enable value to the `-Zautodiff=` flag. It updates the test(s) accordingly. It gives a nice error if users forget that.
2) It fixes macos support by explicitly linking against the Enzyme build folder. This doesn't cover CI macos yet.
3) It fixes the issue that setting ENZYME_RUNPASS was ignored by enzyme and in fact did not schedule enzyme's opt pass.
4) It also re-enables support for various other values for the autodiff flag, which were ignored since the refactor.
5) I merged some improvements to Enzyme core, which means we do not longer depend on LLVM being build with the Plugin Interface enabled.
6) Unrelated to other fixes, this changes `rustc_autodiff` to `EncodeCrossCrate::Yes`. It is not enough on it's own to enable usage of Enzyme in libraries, but it is for sure a piece of the fixes needed to get this to work.
try-job: x86_64-gnu
r? `@oli-obk`
Tracking:
- https://github.com/rust-lang/rust/issues/124509
Remove `NtVis` and `NtTy`
The next part of #124141. The first actual remove of `Nonterminal` variants. `NtVis` is a simple case that doesn't get much use, but `NtTy` is more complex.
r? `@petrochenkov`
Rollup of 8 pull requests
Successful merges:
- #136458 (Do not deduplicate list of associated types provided by dyn principal)
- #136474 ([`compiletest`-related cleanups 3/7] Make the distinction between sources root vs test suite sources root in compiletest less confusing)
- #136592 (Make sure we don't overrun the stack in canonicalizer)
- #136787 (Remove `lifetime_capture_rules_2024` feature)
- #137207 (Add #[track_caller] to Duration Div impl)
- #137245 (Tweak E0277 when predicate comes indirectly from ?)
- #137257 (Ignore fake borrows for packed field check)
- #137399 (fix ICE in layout computation with unnormalizable const)
r? `@ghost`
`@rustbot` modify labels: rollup
fix ICE in layout computation with unnormalizable const
The first commit reverts half of 7a667d206c, where I removed a case from `layout_of` for handling non-generic unevaluated consts in array length, that I incorrectly assumed to be unreachable. This can actually happen with the combination of `feature(generic_const_exprs)` and `feature(trivial_bounds)`, because GCE makes anon consts inherit their parent's predicates and with an impossible predicate like `u8: A` it's possible to have an array whose length is an associated const like `<u8 as A>::B` that is not generic, but also can't be normalized:
```rust
#![feature(generic_const_exprs)]
#![feature(trivial_bounds)]
trait A {
const B: usize;
}
// With GCE + trivial bounds this definition is not a compile error.
// Computing the layout of this type shouldn't ICE.
struct S([u8; <u8 as A>::B])
where
u8: A;
```
---
The first commit also incidentally fixes https://github.com/rust-lang/rust/issues/137308, which also managed to get an unnormalizable assoc const into an array length:
```rust
trait A {
const B: usize;
}
impl<C: ?Sized> A for u8 { //~ ERROR: the type parameter `C` is not constrained
const B: usize = 42;
}
// Computing the layout of this type shouldn't ICE, even with the compile error above.
struct S([u8; <u8 as A>::B]);
```
This happens, because we bail out from `codegen_select_candidate` with an error if the selected impl has unconstrained params to avoid leaking infer vars out of a query. `Instance::try_resolve` will then return `Ok(None)`, which for assoc consts roughly means "this const can't be evaluated in a generic context" and is treated as such: 71e06b9c59/compiler/rustc_middle/src/mir/interpret/queries.rs (L84) (and this can ICE if the const isn't generic: https://github.com/rust-lang/rust/issues/135617).
However, here `<u8 as A>::B` is definitely not "too generic" and also not unresolvable due to an unsatisfiable `u8: A` bound, so I've included the second commit to change the result of `Instance::try_resolve` from `Ok(None)` to `Err(ErrorGuaranteed)` when resolving an assoc item to an impl with unconstrained generic params. This has the effect that `<u8 as A>::B` will now be normalized to `ConstKind::Error` in the example above.
This properly fixes https://github.com/rust-lang/rust/issues/137308, by no longer treating `<u8 as A>::B` as unresolvable even though it clearly has a unique impl that it resolves to. It also has the effect of changing the layout error from `Unknown` ("the type may be valid but has no sensible layout") to `ReferencesError` ("a non-layout error is reported elsewhere") which seems more appropriate.
r? ```@compiler-errors```
Ignore fake borrows for packed field check
We should not emit unaligned packed field reference errors for the fake borrows that we generate during match lowering.
These fake borrows are there to ensure in *borrow-checking* that we don't modify the value being matched (which is why this only occurs when there's a match guard, in this case `if true`), but they are removed after the MIR is processed by `CleanupPostBorrowck`, since they're really just there to cause borrowck errors if necessary.
I modified `PlaceContext::is_borrow` since that's used by the packed field check:
17c1c329a5/compiler/rustc_mir_transform/src/check_packed_ref.rs (L40)
It's only used in one other place, in the SROA optimization (by which fake borrows are removed, so it doesn't matter):
17c1c329a5/compiler/rustc_mir_dataflow/src/value_analysis.rs (L922)
Fixes https://github.com/rust-lang/rust/issues/137250
Tweak E0277 when predicate comes indirectly from ?
When a `?` operation requires an `Into` conversion with additional bounds (like having a concrete error but wanting to convert to a trait object), we handle it speficically and provide the same kind of information we give other `?` related errors.
```
error[E0277]: `?` couldn't convert the error: `E: std::error::Error` is not satisfied
--> $DIR/bad-question-mark-on-trait-object.rs:7:13
|
LL | fn foo() -> Result<(), Box<dyn std::error::Error>> {
| -------------------------------------- required `E: std::error::Error` because of this
LL | Ok(bar()?)
| -----^ the trait `std::error::Error` is not implemented for `E`
| |
| this has type `Result<_, E>`
|
note: `E` needs to implement `std::error::Error`
--> $DIR/bad-question-mark-on-trait-object.rs:1:1
|
LL | struct E;
| ^^^^^^^^
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= note: required for `Box<dyn std::error::Error>` to implement `From<E>`
```
Avoid talking about `FromResidual` when other more relevant information is being given, particularly from `rust_on_unimplemented`.
Fix#137238.
-----
CC #137232, which was a smaller step related to this.
Do not deduplicate list of associated types provided by dyn principal
## Background
The way that we handle a dyn trait type's projection bounds is very *structural* today. A dyn trait is represented as a list of `PolyExistentialPredicate`s, which in most cases will be a principal trait (like `Iterator`) and a list of projections (like `Item = u32`). Importantly, the list of projections comes from user-written associated type bounds on the type *and* from elaborating the projections from the principal's supertraits.
For example, given a set of traits like:
```rust
trait Foo<T> {
type Assoc;
}
trait Bar<A, B>: Foo<A, Assoc = A> + Foo<B, Assoc = B> {}
```
For the type `dyn Bar<i32, u32>`, the list of projections will be something like `[Foo<i32>::Assoc = i32, Foo<u32>::Assoc = u32]`. We deduplicate these projections when they're identical, so for `dyn Bar<(), ()>` would be something like `[Foo<()>::Assoc = ()]`.
## Shortcomings 1: inference
We face problems when we begin to mix this structural notion of projection bounds with inference and associated type normalization. For example, let's try calling a generic function that takes `dyn Bar<A, B>` with a value of type `dyn Bar<(), ()>`:
```rust
trait Foo<T> {
type Assoc;
}
trait Bar<A, B>: Foo<A, Assoc = A> + Foo<B, Assoc = B> {}
fn call_bar<A, B>(_: &dyn Bar<A, B>) {}
fn test(x: &dyn Bar<(), ()>) {
call_bar(x);
// ^ ERROR mismatched types
}
```
```
error[E0308]: mismatched types
--> /home/mgx/test.rs:10:14
|
10 | call_bar(x);
| -------- ^ expected trait `Bar<_, _>`, found trait `Bar<(), ()>`
```
What's going on here? Well, when calling `call_bar`, the generic signature `&dyn Bar<?A, ?B>` does not unify with `&dyn Bar<(), ()>` because the list of projections differ -- `[Foo<?A>::Assoc = ?A, Foo<?B>::Assoc = ?B]` vs `[Foo<()>::Assoc = ()]`.
A simple solution to this may be to unify the principal traits first, then attempt to deduplicate them after inference. In this case, if we constrain `?A = ?B = ()`, then we would be able to deduplicate those projections in the first list.
However, this idea is still pretty fragile, and it's not a complete solution.
## Shortcomings 2: normalization
Consider a slightly modified example:
```rust
//@ compile-flags: -Znext-solver
trait Mirror {
type Assoc;
}
impl<T> Mirror for T {
type Assoc = T;
}
fn call_bar(_: &dyn Bar<(), <() as Mirror>::Assoc>) {}
fn test(x: &dyn Bar<(), ()>) {
call_bar(x);
}
```
This fails in the new solver. In this example, we try to unify `dyn Bar<(), ()>` and `dyn Bar<(), <() as Mirror>::Assoc>`. We are faced with the same problem even though there are no inference variables, and making this work relies on eagerly and deeply normalizing all projections so that they can be structurally deduplicated.
This is incompatible with how we handle associated types in the new trait solver, and while we could perhaps support it with some major gymnastics in the new solver, it suggests more fundamental shortcomings with how we deal with projection bounds in the new solver.
## Shortcomings 3: redundant projections
Consider a final example:
```rust
trait Foo {
type Assoc;
}
trait Bar: Foo<Assoc = ()> {}
fn call_bar1(_: &dyn Bar) {}
fn call_bar2(_: &dyn Bar<Assoc = ()>) {}
fn main() {
let x: &dyn Bar<Assoc = _> = todo!();
call_bar1(x);
//~^ ERROR mismatched types
call_bar2(x);
//~^ ERROR mismatched types
}
```
In this case, we have a user-written associated type bound (`Assoc = _`) which overlaps the bound that comes from the supertrait projection of `Bar` (namely, `Foo<Assoc = ()>`). In a similar way to the two examples above, this causes us to have a projection list mismatch that the compiler is not able to deduplicate.
## Solution
### Do not deduplicate after elaborating projections when lowering `dyn` types
The root cause of this issue has to do with mismatches of the deduplicated projection list before and after substitution or inference. This PR aims to avoid these issues by *never* deduplicating the projection list after elaborating the list of projections from the *identity* substituted principal trait ref.
For example,
```rust
trait Foo<T> {
type Assoc;
}
trait Bar<A, B>: Foo<A, Assoc = A> + Foo<B, Assoc = B> {}
```
When computing the projections for `dyn Bar<(), ()>`, before this PR we'd elaborate `Bar<(), ()>` to find a (deduplicated) projection list of `[Foo<()>::Assoc = ()]`.
After this PR, we take the principal trait and use its *identity* substitutions `Bar<A, B>` during elaboration, giving us projections `[Foo<A>::Assoc = A, Foo<B>::Assoc = B]`. Only after this elaboration do we substitute `A = (), B = ()` to get `[Foo<()>::Assoc = (), Foo<()>::Assoc = ()]`. This allows the type to be unified with the projections for `dyn Bar<?A, ?B>`, which are `[Foo<?A>::Assoc = ?A, Foo<?B>::Assoc = ?B]`.
This helps us avoid shorcomings 1 noted above.
### Do not deduplicate projections when relating `dyn` types
Similarly, we also do not call deduplicate when relating dyn types. This means that the list of projections does not differ depending on if the type has been normalized or not, which should avoid shortcomings 2 noted above.
Following from the example above, when relating projection lists like `[Foo<()>::Assoc = (), Foo<()>::Assoc = ()]` and `[Foo<?A>::Assoc = ?A, Foo<?B>::Assoc = ?B]`, the latter won't be deduplicated to a list of length 1 which would immediately fail to relate to the latter which is a list of length 2.
### Implement proper precedence between supertrait and user-written projection bounds when lowering `dyn` types
```rust
trait Foo {
type Assoc;
}
trait Bar: Foo<Assoc = ()> {}
```
Given a type like `dyn Foo<Assoc = _>`, we used to previously include *both* the supertrait and user-written associated type bounds in the projection list, giving us `[Foo::Assoc = (), Foo::Assoc = _]`. This would never unify with `dyn Foo`. However, this PR implements a strategy which overwrites the supertrait associated type bound with the one provided by the user, giving us a projection list of `[Foo::Assoc = _]`.
Why is this OK? Well, if a user wrote an associated type bound that is unsatisfiable (e.g. `dyn Bar<Assoc = i32>`) then the dyn type would never implement `Bar` or `Foo` anyways. If the user wrote something that is either structurally equal or equal modulo normalization to the supertrait bound, then it should be unaffected. And if the user wrote something that needs inference guidance (e.g. `dyn Bar<Assoc = _>`), then it'll be constrained when proving `dyn Bar<Assoc = _>: Bar`.
Importantly, this differs from the strategy in https://github.com/rust-lang/rust/pull/133397, which preferred the *supertrait* bound and ignored the user-written bound. While that's also theoretically justifiable in its own way, it does lead to code which does not (and probably should not) compile either today or after this PR, like:
```rust
trait IteratorOfUnit: Iterator<Item = ()> {}
impl<T> IteratorOfUnit for T where T: Iterator<Item = ()> {}
fn main() {
let iter = [()].into_iter();
let iter: &dyn IteratorOfUnit<Item = i32> = &iter;
}
```
### Conclusion
This is a far less invasive change compared to #133397, and doesn't necessarily necessitate the addition of new lints or any breakage of existing code. While we could (and possibly should) eventually introduce lints to warn users of redundant or mismatched associated type bounds, we don't *need* to do so as part of fixing this unsoundness, which leads me to believe this is a much safer solution.
More sophisticated span trimming for suggestions
Previously #136958 only cared about prefixes or suffixes. Now it detects more cases where a suggestion is "sandwiched" by unchanged code on the left or the right. Would be cool if we could detect several insertions, like `ACE` going to `ABCDE`, extracting `B` and `D`, but that seems unwieldy.
r? `@estebank`
```
error[E0277]: `?` couldn't convert the error: `E: std::error::Error` is not satisfied
--> $DIR/bad-question-mark-on-trait-object.rs:7:13
|
LL | fn foo() -> Result<(), Box<dyn std::error::Error>> {
| -------------------------------------- required `E: std::error::Error` because of this
LL | Ok(bar()?)
| -----^ the trait `std::error::Error` is not implemented for `E`
| |
| this has type `Result<_, E>`
|
note: `E` needs to implement `std::error::Error`
--> $DIR/bad-question-mark-on-trait-object.rs:1:1
|
LL | struct E;
| ^^^^^^^^
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= note: required for `Box<dyn std::error::Error>` to implement `From<E>`
error[E0277]: `?` couldn't convert the error to `X`
--> $DIR/bad-question-mark-on-trait-object.rs:18:13
|
LL | fn bat() -> Result<(), X> {
| ------------- expected `X` because of this
LL | Ok(bar()?)
| -----^ the trait `From<E>` is not implemented for `X`
| |
| this can't be annotated with `?` because it has type `Result<_, E>`
|
note: `X` needs to implement `From<E>`
--> $DIR/bad-question-mark-on-trait-object.rs:4:1
|
LL | struct X;
| ^^^^^^^^
note: alternatively, `E` needs to implement `Into<X>`
--> $DIR/bad-question-mark-on-trait-object.rs:1:1
|
LL | struct E;
| ^^^^^^^^
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
```
Refactor `OperandRef::extract_field` to prep for MCP838
cc https://github.com/rust-lang/compiler-team/issues/838
This still supports exactly the same cases as it did before, just rearranged a bit to better emphasize what doesn't work.
Currently, marking a dependency private does not automatically make all
its child dependencies private. Resolve this by making its children
private by default as well.
This also resolves some FIXMEs for tests that are intended to fail but
previously passed.
[1]: https://github.com/rust-lang/rust/pull/135501#issuecomment-2620242419
In [1], most dependencies of `std` and other sysroot crates were marked
private, but this did not happen for `alloc` and `test`. Update these
here, marking public standard library crates as the only non-private
dependencies.
[1]: https://github.com/rust-lang/rust/pull/111076
Remove the portion of ed63539282 that automatically sets crates private
based on whether they are dependencies of `std`. Instead, this is
controlled by dependency configuration in `Cargo.toml`.
`compiler_builtins` is currently injected as `extern crate
compiler_builtins as _`. This has made gating via diagnostics difficult
because it appears in the crate graph as a non-private dependency, and
there isn't an easy way to differentiate between the injected AST and
user-specified `extern crate compiler_builtins`.
Resolve this by injecting `compiler_builtins` during postprocessing
rather than early in the AST. Most of the time this isn't even needed
because it shows up in `std` or `core`'s crate graph, but injection is
still needed to ensure `#![no_core]` works correctly.
A similar change was attempted at [1] but this encountered errors
building `proc_macro` and `rustc-std-workspace-std`. Similar failures
showed up while working on this patch, which were traced back to
`compiler_builtins` showing up in the graph twice (once via dependency
and once via injection). This is resolved by not injecting if a
`#![compiler_builtins]` crate already exists.
[1]: https://github.com/rust-lang/rust/pull/113634
The only case where can_reuse_cratenum could have been false in the past
are rustc plugins, support for which has been removed over a year ago
now. Nowadays the only case where locator.tuple is not target_triple is
when loading a proc macro, in which case we also set can_reuse_cratenum
to true. As such it is always true and we can remove some dead code.
Some codegen_llvm cleanups
Using some more safe wrappers and thus being able to remove a large unsafe block.
As a next step we should probably look into safe extern fns
Use a probe to avoid registering stray region obligations when re-checking drops in MIR typeck
Fixes#137288.
See the comment I left on the probe. I'm not totally sure why this depends on *both* an unconstrained type parameter in the impl and a type error for the self type, but I think the fix is at least theoretically well motivated.
r? ```@matthewjasper```
Simplify `Postorder` customization.
`Postorder` has a `C: Customization<'tcx>` parameter, that gives it flexibility about how it computes successors. But in practice, there are only two `impls` of `Customization`, and one is for the unit type.
This commit simplifies things by removing the generic parameter and replacing it with an `Option`.
r? ````@saethlin````
add more `s390x` target features
Closes#88937
tracking issue: https://github.com/rust-lang/rust/issues/130869
The target feature names are, right now, just the llvm target feature names. These mostly line up well with the names of [Facility Indications](https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf#page=301) names. The linux kernel (and `/proc/cpuinfo`) uses shorter, more cryptic names. (e.g. "vector" is `vx`). We can deviate from the llvm names, but the CPU vendor (IBM) does not appear to use e.g. `vx` for what they call `vector`.
There are a number of implied target features between the vector facilities (based on the [Facility Indications](https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf#page=301) table):
- 129 The vector facility for z/Architecture is installed in the z/Architecture architectural mode.
- 134 The vector packed decimal facility is installed in the z/Architecture architectural mode. When bit 134 is one, bit 129 is also one.
- 135 The vector enhancements facility 1 is installed in the z/Architecture architectural mode. When bit 135 is one, bit 129 is also one.
- 148 The vector-enhancements facility 2 is installed in the z/Architecture architectural mode. When bit 148 is one, bits 129 and 135 are also one.
- 152 The vector-packed-decimal-enhancement facility 1 is installed in the z/Architecture architectural mode. When bit 152 is one, bits 129 and 134 are also one.
- 165 The neural-network-processing-assist facility is installed in the z/Architecture architectural mode. When bit 165 is one, bit 129 is also one.
- 192 The vector-packed-decimal-enhancement facility 2 is installed in the z/Architecture architectural mode. When bit 192 is one, bits 129, 134, and 152 are also one.
The remaining facilities do not have any implied target features (that we provide):
- 45 The distinct-operands, fast-BCR-serialization, high-word, and population-count facilities, the interlocked-access facility 1, and the load/store-oncondition facility 1 are installed in the z/Architecture architectural mode.
- 73 The transactional-execution facility is installed in the z/Architecture architectural mode. Bit 49 is one when bit 73 is one.
- 133 The guarded-storage facility is installed in the z/Architecture architectural mode.
- 150 The enhanced-sort facility is installed in the z/Architecture architectural mode.
- 151 The DEFLATE-conversion facility is installed in the z/Architecture architectural mode.
The added target features are those that have ISA implications, can be queried at runtime, and have LLVM support. LLVM [defines more target features](d49a2d2bc9/llvm/lib/Target/SystemZ/SystemZFeatures.td), but I'm not sure those are useful. They can always be added later, and can already be set globally using `-Ctarget-feature`.
I'll also update the `is_s390x_feature_supported` macro (added in https://github.com/rust-lang/stdarch/pull/1699, not yet on nightly, that needs an stdarch sync) to include these target features.
``@Amanieu`` you had some reservations about the `"vector"` target feature name. It does appear to be the most "official" name we have. On the one hand the name is very generic, and some of the other names are rather long. For the `neural-network-processing-assist` even LLVM thought that was a bit much and shortened it to `nnp-assist`. Also for `vector-packed-decimal-enhancement facility 1` the llvm naming is inconsistent. On the other hand, the cpuinfo names are very cryptic, and aren't found in the IBM documentation.
r? ``@Amanieu``
cc ``@uweigand`` ``@taiki-e``
Specify scope in `out_of_scope_macro_calls` lint
```
warning: cannot find macro `in_root` in the crate root
--> $DIR/key-value-expansion-scope.rs:1:10
|
LL | #![doc = in_root!()]
| ^^^^^^^ not found in the crate root
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #124535 <https://github.com/rust-lang/rust/issues/124535>
= help: import `macro_rules` with `use` to make it callable above its definition
= note: `#[warn(out_of_scope_macro_calls)]` on by default
```
r? ```@petrochenkov```
Notes about tests:
- tests/ui/parser/macro/trait-object-macro-matcher.rs: the syntax error
is duplicated, because it occurs now when parsing the decl macro
input, and also when parsing the expanded decl macro. But this won't
show up for normal users due to error de-duplication.
- tests/ui/associated-consts/issue-93835.rs: similar, plus there are
some additional errors about this very broken code.
- The changes to metavariable descriptions in #132629 are now visible in
error message for several tests.
This pair of fn was introduced to perform invariant checks for scalars.
Their current behavior doesn't mesh as well with checking SIMD types,
so change the name of the fn to reflect their actual use-case and
refactor the corresponding checks.
Also simplify the returns from Option<AbiAndPrefAlign> to Option<Align>,
because every site was mapping away the "preferred" alignment anyways.
The target feature names are, right now, based on the llvm target feature names. These mostly line up well with the names of [Facility Inidications](https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf#page=301) names. The linux kernel uses shorter, more cryptic names. (e.g. "vector" is `vx`). We can deviate from the llvm names, but the CPU vendor (IBM) does not appear to use e.g. `vx` for what they call `vector`.
There are a number of implied target features between the vector facilities (based on the [Facility Inidications](https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf#page=301) table):
- 129 The vector facility for z/Architecture is installed in the z/Architecture architectural mode.
- 134 The vector packed decimal facility is installed in the z/Architecture architectural mode. When bit 134 is one, bit 129 is also one.
- 135 The vector enhancements facility 1 is installed in the z/Architecture architectural mode. When bit 135 is one, bit 129 is also one.
- 148 The vector-enhancements facility 2 is installed in the z/Architecture architectural mode. When bit 148 is one, bits 129 and 135 are also one.
- 152 The vector-packed-decimal-enhancement facility 1 is installed in the z/Architecture architectural mode. When bit 152 is one, bits 129 and 134 are also one.
- 165 The neural-network-processing-assist facility is installed in the z/Architecture architectural mode. When bit 165 is one, bit 129 is also one.
- 192 The vector-packed-decimal-enhancement facility 2 is installed in the z/Architecture architectural mode. When bit 192 is one, bits 129, 134, and 152 are also one.
And then there are a number of facilities without any implied target features
- 45 The distinct-operands, fast-BCR-serialization, high-word, and population-count facilities, the interlocked-access facility 1, and the load/store-oncondition facility 1 are installed in the z/Architecture architectural mode.
- 73 The transactional-execution facility is installed in the z/Architecture architectural mode. Bit 49 is one when bit 73 is one.
- 133 The guarded-storage facility is installed in the z/Architecture architectural mode.
- 150 The enhanced-sort facility is installed in the z/Architecture architectural mode.
- 151 The DEFLATE-conversion facility is installed in the z/Architecture architectural mode.
The added target features are those that have ISA implications, can be queried at runtime, and have LLVM support. LLVM [defines more target features](d49a2d2bc9/llvm/lib/Target/SystemZ/SystemZFeatures.td), but I'm not sure those are useful. They can always be added later, and can already be set globally using `-Ctarget-feature`.
Make x86 QNX target name consistent with other Rust targets
Rename target to be consistent with other Rust targets: Use `i686` instead of `i586`
See also
- #136495
- #109173
CC: `@jonathanpallant` `@japaric` `@gh-tr` `@samkearney`
Workaround Cranelift not yet properly supporting vectors smaller than 128bit
While it would technically be possible to workaround this in cg_clif, it quickly becomes very messy and would likely cause correctness issues. Working around it in rustc instead is much simper and won't have any negative impact for code running on stable as vectors smaller than 128bit can only be made on nightly using core::simd or #[repr(simd)].
Do not ignore uninhabited types for function-call ABI purposes. (Remove BackendRepr::Uninhabited)
Accepted MCP: https://github.com/rust-lang/compiler-team/issues/832Fixes#135802
Do not consider the inhabitedness of a type for function call ABI purposes.
* Remove the [`rustc_abi::BackendRepr::Uninhabited`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_abi/enum.BackendRepr.html) variant
* Instead calculate the `BackendRepr` of uninhabited types "normally" (as though they were not uninhabited "at the top level", but still considering inhabitedness of variants to determine enum layout, etc)
* Add an `uninhabited: bool` field to [`rustc_abi::LayoutData`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_abi/struct.LayoutData.html) so inhabitedness of a `LayoutData` can still be queried when necessary (e.g. when determining if an enum variant needs a tag value allocated to it).
This should not affect type layouts (size/align/field offset); this should only affect function call ABI, and only of uninhabited types.
cc ``@RalfJung``
Pass through of target features to llvm-bitcode-linker and handling them
When using the llvm-bitcode-linker (`linker-flavor=llbc`) target-features are not passed through and are not handled by it.
The llvm-bitcode-linker is mainly used as a self contained linker to link llvm bitcode for the nvptx64 target. It uses `llvm-link`, `opt` and `llc` internally. To produce a `.ptx` file of a specific ptx-version it is necessary to pass the version to llc with the `--mattr` option. Without explicitly setting it, the emitted `.ptx`-version is the minimum supported version of the `--target-cpu`.
I would like to be able to explicitly set the ptx version as [some llvm problems only occur in earlier `.ptx`-versions](https://github.com/llvm/llvm-project/issues/112998).
Therefore this pull request adds support for passing target features to llvm-bitcode-linker and handling them.
I was not quite sure if adding these features to `rustc_target/src/target_features.rs` is necessary or not. If so I will gladly add these.
r? ``@kjetilkjeka``
infer linker flavor by linker name if it's sufficiently specific
Fix: `rustc` does not infer `llvm-bitcode-linker` uses `llbc` linker flavor if targeting `nvptx64-nvidia-cuda`.
Create a generic AVR target: avr-none
This commit removes the `avr-unknown-gnu-atmega328` target and replaces it with a more generic `avr-none` variant that must be specialized using `-C target-cpu` (e.g. `-C target-cpu=atmega328p`).
Seizing the day, I'm adding myself as the maintainer of this target - I've been already fixing the bugs anyway, might as well make it official 🙂
Related discussions:
- https://github.com/rust-lang/rust/pull/131171
- https://github.com/rust-lang/compiler-team/issues/800
try-job: x86_64-gnu-debug
The comments didn't make much sense to me. I asked Matthew Jasper on
Zulip about it and they said:
> I think that at the time I wanted to replace all (or most of) this
> with a reference to the HIR Id of the variable. I'll give this a look
> to see if it's still a reasonable idea, but removing the comments is
> fine.
and then:
> I don't think that changing this to an HirId would be better,
> recovering the information from the HIR seems like too much effort in
> exchange for making the MIR a little smaller.
Fix codegen of uninhabited PassMode::Indirect return types.
Add codegen test for uninhabited PassMode::Indirect return types.
Enable optimizations for uninhabited return type codegen test
When a `?` operation requires an `Into` conversion with additional bounds (like having a concrete error but wanting to convert to a trait object), we handle it speficically and provide the same kind of information we give other `?` related errors.
```
error[E0277]: `?` couldn't convert the error: `E: std::error::Error` is not satisfied
--> $DIR/bad-question-mark-on-trait-object.rs:5:13
|
LL | fn foo() -> Result<(), Box<dyn std::error::Error>> {
| -------------------------------------- required `E: std::error::Error` because of this
LL | Ok(bar()?)
| ^ the trait `std::error::Error` is not implemented for `E`
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= note: required for `Box<dyn std::error::Error>` to implement `From<E>`
```
Avoid talking about `FromResidual` when other more relevant information is being given, particularly from `rust_on_unimplemented`.
While it would technically be possible to workaround this in cg_clif, it
quickly becomes very messy and would likely cause correctness issues.
Working around it in rustc instead is much simper and won't have any
negative impact for code running on stable as vectors smaller than
128bit can only be made on nightly using core::simd or #[repr(simd)].
Don't store a redundant span in user-type projections
While experimenting with some larger changes, I noticed that storing this span here is unnecessary, because it is also present in the corresponding `CanonicalUserTypeAnnotation` and can be retrieved via the annotation's ID.
Emit `trunc nuw` for unchecked shifts and `to_immediate_scalar`
- For shifts this shrinks the IR by no longer needing an `assume` while still providing the UB information
- Having this on the `i8`→`i1` truncations will hopefully help with some places that have to load `i8`s or pass those in LLVM structs without range information
I had to do a lot of debug by printing; having these `Debug` traits in
place made it easier. Additionally, add some more information to
existing `info!` statements.
Introduce an enum that represents the different possible sources for
dependencies, and use them where possible. This will enable more fine
grained control and provides better context than passing the `dep_root`
tuple.
Use this to ensure that injected crates always show up as private by
default.
`Postorder` has a `C: Customization<'tcx>` parameter, that gives it
flexibility about how it computes successors. But in practice, there are
only two `impls` of `Customization`, and one is for the unit type.
This commit simplifies things by removing the generic parameter and
replacing it with an `Option`.
Tweak "expected ident" parse error to avoid talking about doc comments
When encountering a doc comment without an identifier after, we'd unconditionally state "this doc comment doesn't document anything", swallowing the *actual* error which is that the thing *after* the doc comment wasn't expected. Added a check that the found token is something that "conceptually" closes the previous item before emitting that error, otherwise just complain about the missing identifier.
In both of the following cases, the syntax error follows a doc comment:
```
error: expected identifier, found keyword `Self`
--> $DIR/doc-before-bad-variant.rs:4:5
|
LL | enum TestEnum {
| -------- while parsing this enum
...
LL | Self,
| ^^^^ expected identifier, found keyword
|
= help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
```
```
error: expected identifier, found `<`
--> $DIR/doc-before-syntax-error.rs:2:1
|
LL | <>
| ^ expected identifier
```
Fix#71982.
Pattern Migration 2024: properly label `&` patterns whose subpatterns are from macro expansions
See the failing test output in the first commit for an example of what this going wrong looks like. The error/lint diagnostic tries to point to just the `&` or `&mut` of reference patterns when labeling the causes, to make the output clearer (#134394). The trimming there wasn't quite right though: it used the interior of the reference pattern as a cutoff and extended backwards to find where to trim the pattern's span, but this breaks if the `&` and the interior are from different sources. This PR instead trims by starting at the start of the pattern and ending at the final character of the `&` (or `&mut`, `ref`, `ref mut`, or `mut`, depending on what the error/lint is labeling); that way, there's no opportunity for failure from mixing sources.
I'm not 100% happy with this approach, but I'm also not sure what the best practices are as far as hacky `SourceMap` munching goes, so please let me know if something else would be preferred.
Since `SourceMap::span_through_char` can't change the syntax context of the span, I've also removed a call to `Span::with_ctxt` (we care about the edition of the span in question since this is a hard error in Rust 2024). If we want to be extra safe in case that changes, I can re-add it or track error hardness separately in the `rust_2024_migration_desugared_pats` table.
Register `USAGE_OF_TYPE_IR_INHERENT`, remove inherent usages
I implemented a lint to discourage the usage of `rustc_type_ir::inherent` but never actually enabled it. People started using `rustc_type_ir::inherent` methods through globs, lol.
r? fmease or reassign as you please
Make fewer crates depend on `rustc_ast_ir`
I think it simplifies the crate graph and also exposes people less to confusion if downstream crates don't interact with `rustc_ast_ir` directly and instead just use its functionality reexported through more familiar paths.
r? oli-obk since you introduced ast-ir
Restrict `bevy_ecs` `ParamSet` hack
This limits the bevy WF hack to only apply to ADTs named `ParamSet` that come from crates named `bevy_ecs`, and references to the latter.
Previously, we were applying it to all ADTs that contained the substring `"ParamSet"`. This could show up anywhere in the ADT name, and it could come from any crate. It's a bit concerning since other code could theoretically begin to rely on this behavior too (though I don't expect it to)
This simplifies the logic a bit and turns it into a visitor.
r? `@jackh726`
interpret: adjust vtable validity check for higher-ranked types
## What
Transmuting between trait objects where a generic argument or associated type only differs in bound regions (not bound at or above the trait object's binder) is now UB. For example
* transmuting between `&dyn Trait<for<'a> fn(&'a u8)>` and `&dyn Trait<fn(&'static u8)>` is UB.
* transmuting between `&dyn Trait<Assoc = for<'a> fn(&'a u8)>` and `&dyn Trait<Assoc = fn(&'static u8)>` is UB.
* transmuting between `&dyn Trait<for<'a> fn(&'a u8) -> (&'a u8, &'static u8)>` and `&dyn Trait<for<'a> fn(&'a u8) -> (&'static u8, &'a u8)>` is UB.
Transmuting between subtypes (in either direction) is still allowed, which means that bound regions that are bound at or above the trait object's binder can still be changed:
* transmuting between `&dyn for<'a> Trait<fn(&'a u8)>` and `&dyn for Trait<fn(&'static u8)>` is fine.
* transmuting between `&dyn for<'a> Trait<dyn Trait<fn(&'a u8)>>` and `&dyn for Trait<dyn Trait<fn(&'static u8)>>` is fine.
## Why
Very similar to https://github.com/rust-lang/rust/issues/120217 and https://github.com/rust-lang/rust/issues/120222, changing a trait object's generic argument to a type that only differs in bound regions can still affect the vtable layout and lead to segfaults at runtime (for an example see `src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.rs`).
Since we already already require that the trait object predicates must be equal modulo bound regions, it is only natural to extend this check to also require type equality considering bound regions.
However, it also makes sense to allow transmutes between a type and a subtype thereof. For example `&dyn for<'a> Trait<&'a u8>` is a subtype of `&dyn Trait<&'static ()>` and they are guaranteed to have the same vtable, so it makes sense to allow this transmute. So that's why bound lifetimes that are bound to the trait object itself are treated as free lifetime for the purpose of this check.
Note that codegen already relies on the property that subtyping cannot change the the vtable and this is asserted here (note the leak check): 251206c27b/compiler/rustc_codegen_ssa/src/base.rs (L106-L153)
Furthermore, we allow some pointer-to-pointer casts like `*const dyn for<'a> Trait<&'a u8>` to `*const Wrapper<dyn Trait<&'static u8>>` that instantiate the trait object binder and are currently lowered to a single pointer-to-pointer cast in MIR (`CastKind::PtrToPtr`) and *not* an unsizing coercion (`CastKind::PointerCoercion(Unsize)`), so the current MIR lowering of these would be UB if we didn't allow subtyping transmutes.
---
fixes https://github.com/rust-lang/rust/issues/135230
cc `@rust-lang/opsem`
r? `@compiler-errors` for the implementation
The only visible change is to the filenames produce by `-Zdump-mir`.
E.g. before and after:
```
h.main.003-000.analysis-post-cleanup.after.mir
h.main.2-2-000.analysis-post-cleanup.after.mir
```
It also fixes a FIXME comment.
Lint `#[must_use]` attributes applied to methods in trait impls
The `#[must_use]` attribute has no effect when applied to methods in trait implementations. This PR adds it to the unused `#[must_use]` lint, and cleans the extra attributes in portable-simd and Clippy.
Suggest replacing `.` with `::` in more error diagnostics.
First commit makes the existing "help: use the path separator to refer to an item" also work when the base is a type alias, not just a trait/module/struct.
The existing unconditional `DefKind::Mod | DefKind::Trait` match arm is changed to a conditional `DefKind::Mod | DefKind::Trait | DefKind::TyAlias` arm that only matches if the `path_sep` suggestion-adding closure succeeds, so as not to stop the later `DefKind::TyAlias`-specific suggestions if the path-sep suggestion does not apply. This shouldn't change behavior for `Mod` or `Trait` (due to the default arm's `return false` etc).
This commit also updates `tests/ui/resolve/issue-22692.rs` to reflect this, and also renames it to something more meaningful.
This commit also makes the `bad_struct_syntax_suggestion` closure take `err` as a parameter instead of capturing it, since otherwise caused borrowing errors due to the change to using `path_sep` in a pattern guard.
<details> <summary> Type alias diagnostic example </summary>
```rust
type S = String;
fn main() {
let _ = S.new;
}
```
```diff
error[E0423]: expected value, found type alias `S`
--> diag7.rs:4:13
|
4 | let _ = S.new;
| ^
|
- = note: can't use a type alias as a constructor
+ help: use the path separator to refer to an item
+ |
+4 | let _ = S::new;
+ | ~~
```
</details>
Second commit adds some cases for `enum`s, where if there is a field/method expression where the field/method has the name of a unit/tuple variant, we assume the user intended to create that variant[^1] and suggest replacing the `.` from the field/method suggestion with a `::` path separator. If no such variant is found (or if the error is not a field/method expression), we give the existing suggestion that suggests adding `::TupleVariant(/* fields */)` after the enum.
<details> <summary> Enum diagnostic example </summary>
```rust
enum Foo {
A(u32),
B,
C { x: u32 },
}
fn main() {
let _ = Foo.A(42); // changed
let _ = Foo.B; // changed
let _ = Foo.D(42); // no change
let _ = Foo.D; // no change
let _ = Foo(42); // no change
}
```
```diff
error[E0423]: expected value, found enum `Foo`
--> diag8.rs:8:13
|
8 | let _ = Foo.A(42); // changed
| ^^^
|
note: the enum is defined here
--> diag8.rs:1:1
|
1 | / enum Foo {
2 | | A(u32),
3 | | B,
4 | | C { x: u32 },
5 | | }
| |_^
-help: you might have meant to use the following enum variant
- |
-8 | let _ = Foo::B.A(42); // changed
- | ~~~~~~
-help: alternatively, the following enum variant is available
+help: use the path separator to refer to a variant
|
-8 | let _ = (Foo::A(/* fields */)).A(42); // changed
- | ~~~~~~~~~~~~~~~~~~~~~~
+8 | let _ = Foo::A(42); // changed
+ | ~~
error[E0423]: expected value, found enum `Foo`
--> diag8.rs:9:13
|
9 | let _ = Foo.B; // changed
| ^^^
|
note: the enum is defined here
--> diag8.rs:1:1
|
1 | / enum Foo {
2 | | A(u32),
3 | | B,
4 | | C { x: u32 },
5 | | }
| |_^
-help: you might have meant to use the following enum variant
- |
-9 | let _ = Foo::B.B; // changed
- | ~~~~~~
-help: alternatively, the following enum variant is available
+help: use the path separator to refer to a variant
|
-9 | let _ = (Foo::A(/* fields */)).B; // changed
- | ~~~~~~~~~~~~~~~~~~~~~~
+9 | let _ = Foo::B; // changed
+ | ~~
error[E0423]: expected value, found enum `Foo`
--> diag8.rs:10:13
|
10 | let _ = Foo.D(42); // no change
| ^^^
|
note: the enum is defined here
--> diag8.rs:1:1
|
1 | / enum Foo {
2 | | A(u32),
3 | | B,
4 | | C { x: u32 },
5 | | }
| |_^
help: you might have meant to use the following enum variant
|
10 | let _ = Foo::B.D(42); // no change
| ~~~~~~
help: alternatively, the following enum variant is available
|
10 | let _ = (Foo::A(/* fields */)).D(42); // no change
| ~~~~~~~~~~~~~~~~~~~~~~
error[E0423]: expected value, found enum `Foo`
--> diag8.rs:11:13
|
11 | let _ = Foo.D; // no change
| ^^^
|
note: the enum is defined here
--> diag8.rs:1:1
|
1 | / enum Foo {
2 | | A(u32),
3 | | B,
4 | | C { x: u32 },
5 | | }
| |_^
help: you might have meant to use the following enum variant
|
11 | let _ = Foo::B.D; // no change
| ~~~~~~
help: alternatively, the following enum variant is available
|
11 | let _ = (Foo::A(/* fields */)).D; // no change
| ~~~~~~~~~~~~~~~~~~~~~~
error[E0423]: expected function, tuple struct or tuple variant, found enum `Foo`
--> diag8.rs:12:13
|
12 | let _ = Foo(42); // no change
| ^^^ help: try to construct one of the enum's variants: `Foo::A`
|
= help: you might have meant to construct the enum's non-tuple variant
note: the enum is defined here
--> diag8.rs:1:1
|
1 | / enum Foo {
2 | | A(u32),
3 | | B,
4 | | C { x: u32 },
5 | | }
| |_^
error: aborting due to 5 previous errors
```
</details>
[^1]: or if it's a field expression and a tuple variant, that they meant to refer the variant constructor.
Match Ergonomics 2024: update old-edition behavior of feature gates
This updates the behavior of the feature gates `ref_pat_eat_one_layer_2024_structural` and `ref_pat_eat_one_layer_2024` in Editions 2021 and earlier to correspond to the left and right typing rules compared [here](https://nadrieril.github.io/typing-rust-patterns/?opts1=AQEBAQIBAQEBAAAAAAAAAAAAAAAAAAA%3D&style=UserVisible&compare=true&opts2=AQEBAQIBAQABAAAAAQEBAAEBAAABAAA%3D&mode=rules), respectively. Compared to the `stable_rust` rules:
- they both allow reference patterns to match a lone inherited ref,
- they both allow `&` patterns to eat `&mut` reference types (and lone `&mut` inherited refs) as if they're shared,
- they both allow `&mut` patterns to eat `&` reference types when there's a `&mut` inherited reference to also eat,
- and the left ruleset has RFC 3627's Rule 3: after encountering a shared reference type in the scrutinee, the default binding mode will be treated as by-shared-ref when it would otherwise be by-mutable-ref.
I think there's already tests for all of those typing rules, so I've added revisions to use the existing tests with the new rulesets. Additionally, I've added a few tests to make sure we handle mixed-edition patterns appropriately, and I've added references to the unstable book.
Relevant tracking issue: #123076
r? ``@ghost``
- For shifts this shrinks the IR by no longer needing an `assume` while still providing the UB information
- Having this on the `i8`→`i1` truncations will hopefully help with some places that have to load `i8`s or pass those in LLVM structs without range information
```
warning: cannot find macro `in_root` in the crate root
--> $DIR/key-value-expansion-scope.rs:1:10
|
LL | #![doc = in_root!()]
| ^^^^^^^ not found in the crate root
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #124535 <https://github.com/rust-lang/rust/issues/124535>
= help: import `macro_rules` with `use` to make it callable above its definition
= note: `#[warn(out_of_scope_macro_calls)]` on by default
```
This commit removes the `avr-unknown-gnu-atmega328` target and replaces
it with a more generic `avr-none` variant that must be specialized with
the `-C target-cpu` flag (e.g. `-C target-cpu=atmega328p`).
coverage: Get hole spans from nested items without fully visiting them
This is a small simplification to the code that collects the spans of nested items within a function, so that those spans can be treated as “holes” to be avoided by the current function's coverage mappings.
The old code was using `nested_filter::All` to ensure that the visitor would see nested items. But we don't need the actual items themselves; we just need their spans, which we can obtain via a custom implementation of `visit_nested_item`.
This avoids the more expansive queries required by `nested_filter::All`.
Don't mention `FromResidual` on bad `?`
Unless `try_trait_v2` is enabled, don't mention that `FromResidual` isn't implemented for a specific type when the implicit `From` conversion of a `?` fails. For the end user on stable, `?` might as well be a compiler intrinsic, so we remove that note to avoid further confusion and allowing other parts of the error to be more prominent.
```
error[E0277]: `?` couldn't convert the error to `u8`
--> $DIR/bad-interconversion.rs:4:20
|
LL | fn result_to_result() -> Result<u64, u8> {
| --------------- expected `u8` because of this
LL | Ok(Err(123_i32)?)
| ------------^ the trait `From<i32>` is not implemented for `u8`
| |
| this can't be annotated with `?` because it has type `Result<_, i32>`
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= help: the following other types implement trait `From<T>`:
`u8` implements `From<Char>`
`u8` implements `From<bool>`
```
When encountering a doc comment without an identifier after, we'd unconditionally state "this doc comment doesn't document anything", swallowing the *actual* error which is that the thing *after* the doc comment wasn't expected. Added a check that the found token is something that "conceptually" closes the previous item before emitting that error, otherwise just complain about the missing identifier.
In both of the following cases, the syntax error follows a doc comment:
```
error: expected identifier, found keyword `Self`
--> $DIR/doc-before-bad-variant.rs:4:5
|
LL | enum TestEnum {
| -------- while parsing this enum
...
LL | Self,
| ^^^^ expected identifier, found keyword
|
= help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
```
```
error: expected identifier, found `<`
--> $DIR/doc-before-syntax-error.rs:2:1
|
LL | <>
| ^ expected identifier
```
Fix#71982.
rustfmt doesn't touch it because it's a macro body, but it's large
enough that the misformatting is annoying. This commit improves it. The
most common problems fixed:
- Unnecessary multi-line patterns reduced to one line.
- Multi-line function headers adjusted so the parameter indentation
doesn't depend on the length of the function name. (This is Rust code,
not C.)
- `|` used at the start of lines, not the end.
- More consistent formatting of empty function bodies.
- Overly long lines are broken.
The `MirVisitable` trait is just a complicated way to visit either a
statement or a terminator. (And its impl for `Terminator` is unused.) It
has a single use.
This commit removes it, replacing it with an if/else, which is shorter
and simpler.
`visit_local` is the only method that doesn't call a corresponding
`super_local` method. This is valid, because `super_local` would be
empty. But it's inconsistent with every other case; we have multiple
other empty `super` methods: `super_span`, `super_ty`, etc.
This commit adds an empty `super_local` and makes `visit_local` call it.
Emit dropck normalization errors in borrowck
Borrowck generally assumes that any queries it runs for type checking will succeed, thinking that HIR typeck will have errored first if there was a problem. However as of #98641, dropck isn't run on HIR, so there's no direct guarantee that it doesn't error. While a type being well-formed might be expected to ensure that its fields are well-formed, this is not the case for types containing a type projection:
```rust
pub trait AuthUser {
type Id;
}
pub trait AuthnBackend {
type User: AuthUser;
}
pub struct AuthSession<Backend: AuthnBackend> {
data: Option<<<Backend as AuthnBackend>::User as AuthUser>::Id>,
}
pub trait Authz: Sized {
type AuthnBackend: AuthnBackend<User = Self>;
}
pub fn run_query<User: Authz>(auth: AuthSession<User::AuthnBackend>) {}
// ^ No User: AuthUser bound is required or inferred.
```
While improvements to trait solving might fix this in the future, for now we go for a pragmatic solution of emitting an error from borrowck (by rerunning dropck outside of a query) and making drop elaboration check if an error has been emitted previously before panicking for a failed normalization.
Closes#103899Closes#135039
r? `@compiler-errors` (feel free to re-assign)
Rollup of 9 pull requests
Successful merges:
- #136936 (Use 'yes' instead of 'while-echo' in tests/ui/process/process-sigpipe.rs except 'nto')
- #137026 (Stabilize (and const-stabilize) `integer_sign_cast`)
- #137059 (fix: Alloc new errorcode E0803 for E0495)
- #137177 (Update `minifier-rs` version to `0.3.5`)
- #137210 (compiler: Stop reexporting stuff in cg_llvm::abi)
- #137213 (Remove `rustc_middle::mir::tcx` module.)
- #137216 (eval_outlives: bail out early if both regions are in the same SCC)
- #137228 (Fix typo in hidden internal docs of `TrustedRandomAccess`)
- #137242 (Add reference annotations for the `do_not_recommend` attribute)
r? `@ghost`
`@rustbot` modify labels: rollup
It turns out that this visitor doesn't actually need `nested_filter::All` to
handle nested items; it just needs to override `visit_nested_item` and look up
the item's span.
My reasoning: the ruleset implemented by the same feature gate in
Edition 2024 always tries to eat the inherited reference first. For
consistency, it makes sense to me to say across all editions that users
should consider the inherited reference's mutability when wondering if a
`&mut` pattern will type.
x86: use SSE2 to pass float and SIMD types
This builds on the new X86Sse2 ABI landed in https://github.com/rust-lang/rust/pull/137037 to actually make it a separate ABI from the default x86 ABI, and use SSE2 registers. Specifically, we use it in two ways: to return `f64` values in a register rather than by-ptr, and to pass vectors of size up to 128bit in a register (or, well, whatever LLVM does when passing `<4 x float>` by-val, I don't actually know if this ends up in a register).
Cc `@workingjubilee`
Fixes#133611
try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
try-job: x86_64-gnu-nopt
try-job: dist-i586-gnu-i586-i686-musl
try-job: x86_64-msvc-1
eval_outlives: bail out early if both regions are in the same SCC
A drive-by optimisation of region outlives evaluation: if we are evaluating whether an outlives holds for two regions, bail out early if they are both in the same SCC.
This probably won't make a huge difference, but the cost is one comparison of SCC indices (integers).
May want a perf run, depending on how confident whomever reviewing this is!
Remove `rustc_middle::mir::tcx` module.
This is a really weird module. For example, what does `tcx` in `rustc_middle::mir::tcx::PlaceTy` mean? The answer is "not much".
The top-level module comment says:
> Methods for the various MIR types. These are intended for use after
> building is complete.
Awfully broad for a module that has a handful of impl blocks for some MIR types, none of which really relates to `TyCtxt`. `git blame` indicates the comment is ancient, from 2015, and made sense then.
This module is now vestigial. This commit removes it and moves all the code within into `rustc_middle::mir::statement`. Some specifics:
- `Place`, `PlaceRef`, `Rvalue`, `Operand`, `BorrowKind`: they all have `impl` blocks in both the `tcx` and `statement` modules. The commit merges the former into the latter.
- `BinOp`, `UnOp`: they only have `impl` blocks in `tcx`. The commit moves these into `statement`.
- `PlaceTy`, `RvalueInitializationState`: they are defined in `tcx`. This commit moves them into `statement` *and* makes them available in `mir::*`, like many other MIR types.
r? `@tmandry`
compiler: Stop reexporting stuff in cg_llvm::abi
The reexports confuse tooling like rustdoc into thinking cg_llvm is the source of key types that originate in rustc_target.
This is a really weird module. For example, what does `tcx` in
`rustc_middle::mir::tcx::PlaceTy` mean? The answer is "not much".
The top-level module comment says:
> Methods for the various MIR types. These are intended for use after
> building is complete.
Awfully broad for a module that has a handful of impl blocks for some
MIR types, none of which really relates to `TyCtxt`. `git blame`
indicates the comment is ancient, from 2015, and made sense then.
This module is now vestigial. This commit removes it and moves all the
code within into `rustc_middle::mir::statement`. Some specifics:
- `Place`, `PlaceRef`, `Rvalue`, `Operand`, `BorrowKind`: they all have `impl`
blocks in both the `tcx` and `statement` modules. The commit merges
the former into the latter.
- `BinOp`, `UnOp`: they only have `impl` blocks in `tcx`. The commit
moves these into `statement`.
- `PlaceTy`, `RvalueInitializationState`: they are defined in `tcx`.
This commit moves them into `statement` *and* makes them available in
`mir::*`, like many other MIR types.
Suggest replacing `.` with `::` when encountering "expected value, found enum":
- in a method-call expression and the method has the same name as a tuple variant
- in a field-access expression and the field has the same name as a unit or tuple variant
When `Foo.field` or `Foo.method()` exprs are encountered, suggest `Foo::field` or `Foo::method()` when Foo is a type alias, not just
a struct, trait, or module.
Also rename test for this suggestion from issue-22692.rs to something more meaningful.
Pattern Migration 2024: fix incorrect messages/suggestions when errors arise in macro expansions
See the diff between the two commits for how this affected the error message and suggestion. In order to decide how to format those, the pattern migration diagnostic keeps track of which parts of the user's pattern cause problems in Edition 2024. However, it neglected to do some of this bookkeeping when pointing to macro expansion sites. This fixes that.
Do not ICE on default_field_value const with lifetimes
`#![feature(default_field_values)]` uses a `const` body that should be treated as inline `const`s, but is actually being detected otherwise. This is similar to the situation in #78174, so we take the same solution: we check if the const actually comes from a field, and if it does, we use that logic to get the appropriate lifetimes and not ICE during borrowck.
Fix#135649.
Unless `try_trait_v2` is enabled, don't mention that `FromResidual` isn't implemented for a specific type when the implicit `From` conversion of a `?` fails. For the end user on stable, `?` might as well be a compiler intrinsic, so we remove that note to avoid further confusion and allowing other parts of the error to be more prominent.
```
error[E0277]: `?` couldn't convert the error to `u8`
--> $DIR/bad-interconversion.rs:4:20
|
LL | fn result_to_result() -> Result<u64, u8> {
| --------------- expected `u8` because of this
LL | Ok(Err(123_i32)?)
| ------------^ the trait `From<i32>` is not implemented for `u8`
| |
| this can't be annotated with `?` because it has type `Result<_, i32>`
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= help: the following other types implement trait `From<T>`:
`u8` implements `From<Char>`
`u8` implements `From<bool>`
```
Enforce T: Hash for Interned<...>
This adds panicking Hash impls for several resolver types that don't actually satisfy this condition. It's not obvious to me that rustc_resolve actually upholds the Interned guarantees but fixing that seems pretty hard (the structures have at minimum some interior mutability, so it's not really recursively hashable in place...). FIXME comments as such on those impls.
cc https://github.com/rust-lang/rust/pull/137196#issuecomment-2664350287
r? ``@saethlin``
cg_clif: use exclusively ABI alignment
This will minimize possible conflict with future updates to AbiAndPrefAlign that may remove some fields. It is also almost a bug to consider them.
r? ``@bjorn3``
Install more signal stack trace handlers
This PR install the signal stack handler to more signals (`SIGILL`, ~~`SIGTRAP`~~, ~~`SIGABRT`~~, ~~`SIGFPE`~~, `SIGBUS`, ~~`SIGQUIT`~~).
Noticed in https://github.com/rust-lang/rust/issues/137138 that we didn't print anything for `SIGILL`, so I though we could just handle more signals.
r? `````@workingjubilee````` since you last touched it
- change function parameter order to `cx, ty, ...` to match the other
functions in this file
- use `ct` identifier for `ty::Const` to match the majority of the
compiler codebase
- remove useless return
- bring match arms in a more natural order
Remove the `repr` parameter from the wrappers around `calc.univariant`,
because it's always defaulted. Only ADTs can have a repr and those call
`calc.layout_of_struct_or_enum` and not `calc.univariant`.
- we normalize before calling `layout_of_uncached`, so we don't need to
normalize again later
- we check for type/const errors at the top of `layout_of_uncached`, so
we don't need to check again later
`ty::Placeholder` is used by the trait solver and computing its layout
was necessary, because the `PointerLike` trait used to be automatically
implemented for all types with pointer-like layout.
Nowadays, `PointerLike` requires user-written impls and the trait solver
no longer computes any layouts, so this can be removed.
Unevaluated constants that aren't generic should have caused a const eval
error earlier during normalization.
improve cold_path()
#120370 added a new instrinsic `cold_path()` and used it to fix `likely` and `unlikely`
However, in order to limit scope, the information about cold code paths is only used in 2-target switch instructions. This is sufficient for `likely` and `unlikely`, but limits usefulness of `cold_path` for idiomatic rust. For example, code like this:
```
if let Some(x) = y { ... }
```
may generate 3-target switch:
```
switch y.discriminator:
0 => true branch
1 = > false branch
_ => unreachable
```
and therefore marking a branch as cold will have no effect.
This PR improves `cold_path()` to work with arbitrary switch instructions.
Note that for 2-target switches, we can use `llvm.expect`, but for multiple targets we need to manually emit branch weights. I checked Clang and it also emits weights in this situation. The Clang's weight calculation is more complex that this PR, which I believe is mainly because `switch` in `C/C++` can have multiple cases going to the same target.
Move methods from `Map` to `TyCtxt`, part 2.
Continuing the work started in #136466.
Every method gains a `hir_` prefix, though for the ones that already have a `par_` or `try_par_` prefix I added the `hir_` after that.
r? Zalathar
This adds panicking Hash impls for several resolver types that don't
actually satisfy this condition. It's not obvious to me that
rustc_resolve actually upholds the Interned guarantees but fixing that
seems pretty hard (the structures have at minimum some interior
mutability, so it's not really recursively hashable in place...).
It's currently lacking comments. This commit adds some, which is useful
because there are some methods with non-obvious behaviour.
The commit also renames two things:
- `patch_map` becomes `term_patch_map`, because it's only about
terminators.
- `is_patched` becomes `is_term_patched`, for the same reason.
(I would guess that originally `MirPatch` only handled terminators, and
then over time it expanded to allow other modifications, but these names
weren't updated.)
Instead of `expand_statements`. This makes the code shorter and
consistent with other MIR transform passes.
The tests require updating because there is a slight change in
MIR output:
- the old code replaced the original statement with twelve new
statements.
- the new code inserts converts the original statement to a `nop` and
then insert twelve new statements in front of it.
I.e. we now end up with an extra `nop`, which doesn't matter at all.
Continuing the work started in #136466.
Every method gains a `hir_` prefix, though for the ones that already
have a `par_` or `try_par_` prefix I added the `hir_` after that.
Drop elaboration looks at fields of a type, which may error when we try
to normalize them. Borrowck will have detected this if HIR typeck
didn't, but we don't delete the MIR body for errors in borrowck so
still have to handle this happening in drop elaboration by checking
whether an error has been emitted.
HIR type checking no longer runs dropck, so we may get new errors when
we run it in borrowck. If this happens then rerun the query in a local
infcx and report errors for it.
Rollup of 7 pull requests
Successful merges:
- #137095 (Replace some u64 hashes with Hash64)
- #137100 (HIR analysis: Remove unnecessary abstraction over list of clauses)
- #137105 (Restrict DerefPure for Cow<T> impl to T = impl Clone, [impl Clone], str.)
- #137120 (Enable `relative-path-include-bytes-132203` rustdoc-ui test on Windows)
- #137125 (Re-add missing empty lines in the releases notes)
- #137145 (use add-core-stubs / minicore for a few more tests)
- #137149 (Remove SSE ABI from i586-pc-windows-msvc)
r? `@ghost`
`@rustbot` modify labels: rollup
Remove SSE ABI from i586-pc-windows-msvc
As an i586 target, it should not have SSE. This caused the following warning to be emitted:
```
warning: target feature `sse2` must be enabled to ensure that the ABI of the current target can be implemented correctly
|
= note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
warning: 1 warning emitted
```
see #116344.
r? RalfJung
HIR analysis: Remove unnecessary abstraction over list of clauses
`rustc_hir_analysis::bounds::Bounds` with its methods is nowadays a paper-thin wrapper around `Vec<(Clause, Span)>`s and `Vec::push` essentially.
Its existence slightly annoyed me (and I keep opening its corresp. file instead of the identically named `bounds.rs` in `hir_ty_lowering/` that I actually want most of the time :P).
Opening to check if you agree with inlining it.
r? compiler-errors or reassign