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.