rustc_target: ppc64 target string fixes for LLVM 20
LLVM continues to clean these up, and we continue to make this consistent. This is similar to 9caced7bad, e985396145, and
a10e744faf.
```@rustbot``` label: +llvm-main
Add the `power8-crypto` target feature
Add the `power8-crypto` target feature. This will enable adding some new PPC intrinsics in stdarch (specifically AES, SHA and CLMUL intrinsics). The implied target feature is from [here](https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/PowerPC/PPC.td)
```@rustbot``` label A-target-feature O-PowerPC
When we expand a `mod foo;` and parse `foo.rs`, we now track whether that file had an unrecovered parse error that reached the end of the file. If so, we keep that information around. When resolving a path like `foo::bar`, we do not emit any errors for "`bar` not found in `foo`", as we know that the parse error might have caused `bar` to not be parsed and accounted for.
When this happens in an existing project, every path referencing `foo` would be an irrelevant compile error. Instead, we now skip emitting anything until `foo.rs` is fixed. Tellingly enough, we didn't have any test for errors caused by `mod` expansion.
Fix#97734.
Don't use `AsyncFnOnce::CallOnceFuture` bounds for signature deduction
We shouldn't be using `AsyncFnOnce::CallOnceFuture` projection bounds to deduce anything about the return type of an async closure, **only** `AsyncFnOnce::Output`. This was accidental b/c all we were looking at was the def id of the trait, rather than the projection. This PR fixes that.
This doesn't affect stable code, since `CallOnceFuture` bounds cannot be written on stable.
Fixes#134015
Make `Copy` unsafe to implement for ADTs with `unsafe` fields
As a rule, the application of `unsafe` to a declaration requires that use-sites of that declaration also entail `unsafe`. For example, a field declared `unsafe` may only be read in the lexical context of an `unsafe` block.
For nearly all safe traits, the safety obligations of fields are explicitly discharged when they are mentioned in method definitions. For example, idiomatically implementing `Clone` (a safe trait) for a type with unsafe fields will require `unsafe` to clone those fields.
Prior to this commit, `Copy` violated this rule. The trait is marked safe, and although it has no explicit methods, its implementation permits reads of `Self`.
This commit resolves this by making `Copy` conditionally safe to implement. It remains safe to implement for ADTs without unsafe fields, but unsafe to implement for ADTs with unsafe fields.
Tracking: #132922
r? ```@compiler-errors```
[AIX] Pass -bnoipath when adding rust upstream dynamic crates
Unlike ELF linkers, AIX doesn't feature `DT_SONAME` to override
the dependency name when outputing a shared library, which is something
we rely on for dylib crates.
See for reference:
bc145cec45/compiler/rustc_codegen_ssa/src/back/linker.rs (L464))
Thus, `ld` on AIX will use the full path to shared libraries as the dependency if passed it
by default unless `noipath` is passed, so pass it here so we don't end up with full path dependencies
for dylib crates.
LLVM continues to clean these up, and we continue to make this
consistent. This is similar to 9caced7bad,
e985396145, and
a10e744faf.
`@rustbot` label: +llvm-main
Stop pessimizing the use of local variables in core by skipping debug info for MIR temporaries in tiny (single-BB) functions.
For functions as simple as this -- `Pin::new`, etc -- nobody every actually wants debuginfo for them in the first place. They're more like intrinsics than real functions, and stepping over them is good.
coverage: Use a query to find counters/expressions that must be zero
As of #133446, this query (`coverage_ids_info`) determines which counter/expression IDs are unused. So with only a little extra work, we can take the code that was using that information to determine which coverage counters/expressions must be zero, and move that inside the query as well.
There should be no change in compiler output.
fix ICE on type error in promoted
Fixes https://github.com/rust-lang/rust/issues/133968
Ensure that when we turn a type error into a "this promoted failed to evaluate" error, we do record this as something that may happen even in "infallible" promoteds.
coverage: Prefer to visit nodes whose predecessors have been visited
In coverage instrumentation, we need to traverse the control-flow graph and decide what kind of counter (physical counter or counter-expression) should be used for each node that needs a counter.
The existing traversal order is complex and hard to tweak. This new traversal order tries to be a bit more principled, by always preferring to visit nodes whose predecessors have already been visited, which is a good match for how the counter-creation code ends up dealing with a node's in-edges and out-edges.
For several of the coverage tests, this ends up being a strict improvement in reducing the size of the coverage metadata, and also reducing the number of physical counters needed.
(The new traversal should hopefully also allow some further code simplifications in the future.)
---
This is made possible by the separate simplification pass introduced by #133849. Without that, almost any change to the traversal order ends up increasing the size of the expression table or the number of physical counters.
Lint on combining `#[no_mangle]` and `#[export_name]`
This is my very first contribution to the compiler, even though I read the [chapter about lints](https://rustc-dev-guide.rust-lang.org/diagnostics.html) I'm not very certain that this ~~new lint is done right as a builtin lint~~ PR is right. I appreciate any guidance on how to improve the code.
- Add test for issue #47446
- ~~Implement the new lint `mixed_export_name_and_no_mangle` as a builtin lint (not sure if that is the right way to go)~~ Extend `unused_attributes` lint
- Add suggestion how to fix it
<details>
<summary>Old proposed new lint</summary>
> The `mixed_export_name_and_no_mangle` lint detects usage of both `#[export_name]` and `#[no_mangle]` on the same item which results on `#[no_mangle]` being ignored.
>
> *warn-by-default*
>
> ### Example
>
> ```rust
> #[no_mangle] // ignored
> #[export_name = "foo"] // takes precedences
> pub fn bar() {}
> ```
>
> ### Explanation
>
> The compiler will not respect the `#[no_mangle]` attribute when generating the symbol name for the function, as the `#[export_name]` attribute takes precedence. This can lead to confusion and is unnecessary.
</details>
In most places, the `early` method is listed before the corresponding
`primary` method, like you'd expect. This commit fixes two places where
that isn't the case.
The words "before" and "after" have an obvious temporal meaning, e.g.
`seek_before_primary_effect`,
`visit_statement_{before,after}_primary_effect`. But "before" is also
used to name the effect that occurs before the primary effect of a
statement/terminator; this is `Effect::Before`. This leads to the
confusing possibility of talking about things happening "before/after
the before event".
This commit removes this awkward overloading of "before" by renaming
`Effect::Before` as `Effect::Early`. It also renames some of the
`Analysis` and `ResultsVisitor` methods to be more consistent.
Here are the before and after names:
- `Effect::{Before,Primary}` -> `Effect::{Early,Primary}`
- `apply_before_statement_effect` -> `apply_early_statement_effect`
- `apply_statement_effect` -> `apply_primary_statement_effect`
- `visit_statement_before_primary_effect` -> `visit_after_early_statement_effect`
- `visit_statement_after_primary_effect` -> `visit_after_primary_statement_effect`
(And s/statement/terminator/ for all the terminator events.)
It uses `MaybeInitializedPlaces` and `MaybeUninitializedPlaces`, but
calls the results `live` and `dead`. This is very confusing given that
there are also analyses called `MaybeLiveLocals` and `MaybeStorageLive`
and `MaybeStorageDead`.
This commit changes it to use `maybe_init` and `maybe_uninit`.
Currently they are called (most common) `state`, or `trans`, or (rare)
`on_entry`. I think `trans` is short for "transfer function", which
perhaps made more sense when `GenKillAnalysis` existed. Using `state`
everywhere now is more consistent.
They are only present because it's currently defined in terms of the
domains of `Borrows` and `MaybeUninitializedPlaces` and
`EverInitializedPlaces` via associated types. This commit introduces
typedefs for those domains, avoiding the lifetimes.
Introduce `default_field_values` feature
Initial implementation of `#[feature(default_field_values]`, proposed in https://github.com/rust-lang/rfcs/pull/3681.
We now parse const expressions after a `=` in a field definition, to specify a `struct` field default value.
We now allow `Struct { field, .. }` where there's no base after `..`.
`#[derive(Default)]` now uses the default value if present, continuing to use `Default::default()` if not.
```rust
#[derive(Debug)]
pub struct S;
#[derive(Debug, Default)]
pub struct Foo {
pub bar: S = S,
pub baz: i32 = 42 + 3,
}
fn main () {
let x = Foo { .. };
let y = Foo::default();
let z = Foo { baz: 1, .. };
assert_eq!(45, x.baz);
assert_eq!(45, y.baz);
assert_eq!(1, z.baz);
}
```
interpret: clean up deduplicating allocation functions
The "align" and "kind" arguments would be largely ignored in the "dedup" case, so let's move that to entirely separate function.
Let's also remove support for old-style miri_resolve_frame while we are at it. The docs have already said for a while that this must be set to 1.
Add test to check unicode identifier version
This adds a test to verify which version of Unicode is used for identifiers. This is part of the language, documented at https://doc.rust-lang.org/nightly/reference/identifiers.html#r-ident.unicode. The version here often changes implicitly due to dependency updates pulling in new versions, and thus we often don't notice it has changed leaving the documentation out of date. The intent here is to have a canary to give us a notification when it changes so that we can update the documentation.
Initial implementation of `#[feature(default_field_values]`, proposed in https://github.com/rust-lang/rfcs/pull/3681.
Support default fields in enum struct variant
Allow default values in an enum struct variant definition:
```rust
pub enum Bar {
Foo {
bar: S = S,
baz: i32 = 42 + 3,
}
}
```
Allow using `..` without a base on an enum struct variant
```rust
Bar::Foo { .. }
```
`#[derive(Default)]` doesn't account for these as it is still gating `#[default]` only being allowed on unit variants.
Support `#[derive(Default)]` on enum struct variants with all defaulted fields
```rust
pub enum Bar {
#[default]
Foo {
bar: S = S,
baz: i32 = 42 + 3,
}
}
```
Check for missing fields in typeck instead of mir_build.
Expand test with `const` param case (needs `generic_const_exprs` enabled).
Properly instantiate MIR const
The following works:
```rust
struct S<A> {
a: Vec<A> = Vec::new(),
}
S::<i32> { .. }
```
Add lint for default fields that will always fail const-eval
We *allow* this to happen for API writers that might want to rely on users'
getting a compile error when using the default field, different to the error
that they would get when the field isn't default. We could change this to
*always* error instead of being a lint, if we wanted.
This will *not* catch errors for partially evaluated consts, like when the
expression relies on a const parameter.
Suggestions when encountering `Foo { .. }` without `#[feature(default_field_values)]`:
- Suggest adding a base expression if there are missing fields.
- Suggest enabling the feature if all the missing fields have optional values.
- Suggest removing `..` if there are no missing fields.
Revert #131669 due to ICEs
Revert [lint: change help for pointers to dyn types in FFI #131669](https://github.com/rust-lang/rust/pull/131669) due to ICE reports:
- <https://github.com/rust-lang/rust/issues/134059> (real-world)
- <https://github.com/rust-lang/rust/issues/134060> (fuzzing)
Closes#134060.
The revert criteria I used to assess whether to post this revert was:
1. It's not trivial to fix-forward. (1) The implementation itself is tricky due to `tcx.is_sized` query not being very trivial. (2) It will need more extensive test coverage for different ty kinds.
2. It is impacting real-world crates, i.e. #134059.
3. `improper_ctypes_definitions` is a warn-by-default lint.
This revert is without prejudice to relanding the changes. The changes can be re-landed with those cases addressed and stronger test coverage.
A rough regression test corresponding to the fuzzed example reported in #134060 is added to check that the revert worked, it is not sufficient for the lint test coverage when the lint improvements are to be relanded. Please feel free to improve the test in the reland.
r? `@workingjubilee` (or compiler)
cc `@niacdoial` (PR author)
The part about zero-sized structures is totally wrong. The rest of
it has almost no explanatory value; there are better explanations in
comments elsewhere.
Introduce `MixedBitSet`
`ChunkedBitSet` is good at avoiding excessive memory usage for programs with very large functgions where dataflow bitsets have very large domain sizes. But it's overly heavyweight for small bitsets, because any non-empty `ChunkedBitSet` takes up at least 256 bytes.
This PR introduces `MixedBitSet`, which is a simple bitset that uses `BitSet` for small/medium bitsets and `ChunkedBitSet` for large bitsets. It's a speed and memory usage win.
r? `@Mark-Simulacrum`
A bunch of cleanups
These are all extracted from a branch I have to get rid of driver queries. Most of the commits are not directly necessary for this, but were found in the process of implementing the removal of driver queries.
Previous PR: https://github.com/rust-lang/rust/pull/132410
A `ChunkedBitSet` has to be at least 2048 bits for it to outperform a
`BitSet`, because that's the chunk size. The largest `SparseBitMatrix`
encountered when compiling the compiler and the entire rustc-perf
benchmark suite is less than 600 bits.
This change is a tiny perf win, but the motivation is more about
avoiding uses of `ChunkedBitSet` outside of `MixedBitSet`.
The test change is necessary to avoid hitting the `<BitSet<T> as
BitRelations<ChunkedBitSet<T>>>::subtract` method that has
`unimplemented!` in its body and isn't otherwise used.
Remove unnecessary `int_type_width_signed` function
This can just use `Ty::int_size_and_signed` instead of making its own version.
You might want to look at this [ignoring whitespace](https://github.com/rust-lang/rust/pull/134020/files?w=1) since a huge bunch of code got un-indented.
Fix: typo in E0751 error explanation
Corrected a grammatical error in the explanation for E0751. Changed "exists" to "exist" to improve clarity and ensure proper grammar in the error message.
Actually walk into lifetimes and attrs in `EarlyContextAndPass`
Visitors that don't also call `walk_*` are kinda a footgun...
I believe all the other early lint functions walk into their types correctly at this point.
Add allocate_bytes and refactor allocate_str in InterpCx for raw byte…
Fixes https://github.com/rust-lang/miri/issues/4025
This PR introduces a new `allocate_bytes` function in InterpCx and refactors `allocate_str` to use it internally. This change improves memory allocation handling in the interpreter by:
1. Adding `allocate_bytes`:
- Direct byte slice allocation support
- Handles both mutable and immutable allocations
- Maintains proper memory alignment and deduplication
2. Refactoring `allocate_str`:
- Now uses `allocate_bytes` internally
- Adds string-specific metadata handling
- Preserves existing string allocation behavior
This is part 1 of the planned changes to improve timezone string handling in Miri. A follow-up PR will update Miri's timezone logic to use this new allocation mechanism.
Related: https://github.com/rust-lang/miri/pull/4069
Add more info on type/trait mismatches for different crate versions
When encountering a type or trait mismatch for two types coming from two different crates with the same name, detect if it is either mixing two types/traits from the same crate on different versions:
```
error[E0308]: mismatched types
--> replaced
|
LL | do_something_type(Type);
| ----------------- ^^^^ expected `dependency::Type`, found `dep_2_reexport::Type`
| |
| arguments to this function are incorrect
|
note: two different versions of crate `dependency` are being used; two types coming from two different versions of the same crate are different types even if they look the same
--> replaced
|
LL | pub struct Type(pub i32);
| ^^^^^^^^^^^^^^^ this is the expected type `dependency::Type`
|
::: replaced
|
LL | pub struct Type;
| ^^^^^^^^^^^^^^^ this is the found type `dep_2_reexport::Type`
|
::: replaced
|
LL | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
LL | extern crate dependency;
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate
= help: you can use `cargo tree` to explore your dependency tree
note: function defined here
--> replaced
|
LL | pub fn do_something_type(_: Type) {}
| ^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> replaced
|
LL | do_something_trait(Box::new(Type) as Box<dyn Trait2>);
| ------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `dependency::Trait2`, found trait `dep_2_reexport::Trait2`
| |
| arguments to this function are incorrect
|
note: two different versions of crate `dependency` are being used; two types coming from two different versions of the same crate are different types even if they look the same
--> replaced
|
LL | pub trait Trait2 {}
| ^^^^^^^^^^^^^^^^ this is the expected trait `dependency::Trait2`
|
::: replaced
|
LL | pub trait Trait2 {}
| ^^^^^^^^^^^^^^^^ this is the found trait `dep_2_reexport::Trait2`
|
::: replaced
|
LL | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
LL | extern crate dependency;
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate
= help: you can use `cargo tree` to explore your dependency tree
note: function defined here
--> replaced
|
LL | pub fn do_something_trait(_: Box<dyn Trait2>) {}
| ^^^^^^^^^^^^^^^^^^
```
or if it is different crates that were renamed to the same name:
```
error[E0308]: mismatched types
--> $DIR/type-mismatch-same-crate-name.rs:21:20
|
LL | a::try_foo(foo2);
| ---------- ^^^^ expected `main:🅰️:Foo`, found a different `main:🅰️:Foo`
| |
| arguments to this function are incorrect
|
note: two types coming from two different crates are different types even if they look the same
--> $DIR/auxiliary/crate_a2.rs:1:1
|
LL | pub struct Foo;
| ^^^^^^^^^^^^^^ this is the found type `crate_a2::Foo`
|
::: $DIR/auxiliary/crate_a1.rs:1:1
|
LL | pub struct Foo;
| ^^^^^^^^^^^^^^ this is the expected type `crate_a1::Foo`
|
::: $DIR/type-mismatch-same-crate-name.rs:13:17
|
LL | let foo2 = {extern crate crate_a2 as a; a::Foo};
| --------------------------- one type comes from crate `crate_a2` is used here, which is renamed locally to `a`
...
LL | extern crate crate_a1 as a;
| --------------------------- one type comes from crate `crate_a1` is used here, which is renamed locally to `a`
note: function defined here
--> $DIR/auxiliary/crate_a1.rs:10:8
|
LL | pub fn try_foo(x: Foo){}
| ^^^^^^^
error[E0308]: mismatched types
--> $DIR/type-mismatch-same-crate-name.rs:27:20
|
LL | a::try_bar(bar2);
| ---------- ^^^^ expected trait `main:🅰️:Bar`, found a different trait `main:🅰️:Bar`
| |
| arguments to this function are incorrect
|
note: two types coming from two different crates are different types even if they look the same
--> $DIR/auxiliary/crate_a2.rs:3:1
|
LL | pub trait Bar {}
| ^^^^^^^^^^^^^ this is the found trait `crate_a2::Bar`
|
::: $DIR/auxiliary/crate_a1.rs:3:1
|
LL | pub trait Bar {}
| ^^^^^^^^^^^^^ this is the expected trait `crate_a1::Bar`
|
::: $DIR/type-mismatch-same-crate-name.rs:13:17
|
LL | let foo2 = {extern crate crate_a2 as a; a::Foo};
| --------------------------- one trait comes from crate `crate_a2` is used here, which is renamed locally to `a`
...
LL | extern crate crate_a1 as a;
| --------------------------- one trait comes from crate `crate_a1` is used here, which is renamed locally to `a`
note: function defined here
--> $DIR/auxiliary/crate_a1.rs:11:8
|
LL | pub fn try_bar(x: Box<Bar>){}
| ^^^^^^^
```
This new output unifies the E0308 errors detail with the pre-existing E0277 errors, and better differentiates the "`extern crate` renamed" and "same crate, different versions" cases.
lint: change help for pointers to dyn types in FFI
### Context
while playing around, I encountered the warning for dyn types in `extern "C"` functions, but even after that I assumed that a (rust) raw pointer could be interpreted in C ('s ABI) as a `void *`... to be fair part of why I ignored the warning is because I wanted to poke at the generated assembly, not make useful code.
### Example
```rust
extern "C"
fn caller(callee: *const dyn Fn(i32)->i32){
// -- snip --
}
```
old warning:
```
warning: `extern` fn uses type `dyn Fn(i32) -> i32`, which is not FFI-safe
--> file/name.rs:42:19
|
42 | fn caller(callee: *const dyn Fn(i32)->i32) {
| ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
= note: trait objects have no C equivalent
= note: `#[warn(improper_ctypes_definitions)]` on by default
```
new warning:
```
warning: `extern` fn uses type `dyn Fn(i32) -> i32`, which is not FFI-safe
--> file/name.rs:42:19
|
42 | fn caller(callee: *const dyn Fn(i32)->i32) -> (){
| ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
= note: this pointer to an unsized type contains metadata, which makes it incompatible with a C pointer
= note: `#[warn(improper_ctypes_definitions)]` on by default
```
This query (`coverage_ids_info`) already determines which counter/expression
IDs are unused, so it only takes a little extra effort to also determine which
counters/expressions must have a value of zero.
On nightly, we mention the trait is unstable
```
error[E0277]: the trait bound `T: Unstable` is not satisfied
--> $DIR/unstable-trait-suggestion.rs:13:9
|
LL | foo(t)
| --- ^ the trait `Unstable` is not implemented for `T`
| |
| required by a bound introduced by this call
|
note: required by a bound in `foo`
--> $DIR/unstable-trait-suggestion.rs:9:11
|
LL | fn foo<T: Unstable>(_: T) {}
| ^^^^^^^^ required by this bound in `foo`
help: consider restricting type parameter `T` but it is an `unstable` trait
|
LL | pub fn demo<T: Unstable>(t: T) {
| ++++++++++
```
On stable, we don't suggest the trait at all
```
error[E0277]: the trait bound `T: Unstable` is not satisfied
--> $DIR/unstable-trait-suggestion.rs:13:9
|
LL | foo(t)
| --- ^ the trait `Unstable` is not implemented for `T`
| |
| required by a bound introduced by this call
|
note: required by a bound in `foo`
--> $DIR/unstable-trait-suggestion.rs:9:11
|
LL | fn foo<T: Unstable>(_: T) {}
| ^^^^^^^^ required by this bound in `foo`
```
As a rule, the application of `unsafe` to a declaration requires that use-sites
of that declaration also require `unsafe`. For example, a field declared
`unsafe` may only be read in the lexical context of an `unsafe` block.
For nearly all safe traits, the safety obligations of fields are explicitly
discharged when they are mentioned in method definitions. For example,
idiomatically implementing `Clone` (a safe trait) for a type with unsafe fields
will require `unsafe` to clone those fields.
Prior to this commit, `Copy` violated this rule. The trait is marked safe, and
although it has no explicit methods, its implementation permits reads of `Self`.
This commit resolves this by making `Copy` conditionally safe to implement. It
remains safe to implement for ADTs without unsafe fields, but unsafe to
implement for ADTs with unsafe fields.
Tracking: #132922
When encountering a type or trait mismatch for two types coming from two different crates with the same name, detect if it is either mixing two types/traits from the same crate on different versions:
```
error[E0308]: mismatched types
--> replaced
|
LL | do_something_type(Type);
| ----------------- ^^^^ expected `dependency::Type`, found `dep_2_reexport::Type`
| |
| arguments to this function are incorrect
|
note: two different versions of crate `dependency` are being used; two types coming from two different versions of the same crate are different types even if they look the same
--> replaced
|
LL | pub struct Type(pub i32);
| ^^^^^^^^^^^^^^^ this is the expected type `dependency::Type`
|
::: replaced
|
LL | pub struct Type;
| ^^^^^^^^^^^^^^^ this is the found type `dep_2_reexport::Type`
|
::: replaced
|
LL | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
LL | extern crate dependency;
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate
= help: you can use `cargo tree` to explore your dependency tree
note: function defined here
--> replaced
|
LL | pub fn do_something_type(_: Type) {}
| ^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> replaced
|
LL | do_something_trait(Box::new(Type) as Box<dyn Trait2>);
| ------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `dependency::Trait2`, found trait `dep_2_reexport::Trait2`
| |
| arguments to this function are incorrect
|
note: two different versions of crate `dependency` are being used; two types coming from two different versions of the same crate are different types even if they look the same
--> replaced
|
LL | pub trait Trait2 {}
| ^^^^^^^^^^^^^^^^ this is the expected trait `dependency::Trait2`
|
::: replaced
|
LL | pub trait Trait2 {}
| ^^^^^^^^^^^^^^^^ this is the found trait `dep_2_reexport::Trait2`
|
::: replaced
|
LL | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
LL | extern crate dependency;
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate
= help: you can use `cargo tree` to explore your dependency tree
note: function defined here
--> replaced
|
LL | pub fn do_something_trait(_: Box<dyn Trait2>) {}
| ^^^^^^^^^^^^^^^^^^
```
or if it is different crates that were renamed to the same name:
```
error[E0308]: mismatched types
--> $DIR/type-mismatch-same-crate-name.rs:21:20
|
LL | a::try_foo(foo2);
| ---------- ^^^^ expected `main:🅰️:Foo`, found a different `main:🅰️:Foo`
| |
| arguments to this function are incorrect
|
note: two types coming from two different crates are different types even if they look the same
--> $DIR/auxiliary/crate_a2.rs:1:1
|
LL | pub struct Foo;
| ^^^^^^^^^^^^^^ this is the found type `crate_a2::Foo`
|
::: $DIR/auxiliary/crate_a1.rs:1:1
|
LL | pub struct Foo;
| ^^^^^^^^^^^^^^ this is the expected type `crate_a1::Foo`
|
::: $DIR/type-mismatch-same-crate-name.rs:13:17
|
LL | let foo2 = {extern crate crate_a2 as a; a::Foo};
| --------------------------- one type comes from crate `crate_a2` is used here, which is renamed locally to `a`
...
LL | extern crate crate_a1 as a;
| --------------------------- one type comes from crate `crate_a1` is used here, which is renamed locally to `a`
note: function defined here
--> $DIR/auxiliary/crate_a1.rs:10:8
|
LL | pub fn try_foo(x: Foo){}
| ^^^^^^^
error[E0308]: mismatched types
--> $DIR/type-mismatch-same-crate-name.rs:27:20
|
LL | a::try_bar(bar2);
| ---------- ^^^^ expected trait `main:🅰️:Bar`, found a different trait `main:🅰️:Bar`
| |
| arguments to this function are incorrect
|
note: two types coming from two different crates are different types even if they look the same
--> $DIR/auxiliary/crate_a2.rs:3:1
|
LL | pub trait Bar {}
| ^^^^^^^^^^^^^ this is the found trait `crate_a2::Bar`
|
::: $DIR/auxiliary/crate_a1.rs:3:1
|
LL | pub trait Bar {}
| ^^^^^^^^^^^^^ this is the expected trait `crate_a1::Bar`
|
::: $DIR/type-mismatch-same-crate-name.rs:13:17
|
LL | let foo2 = {extern crate crate_a2 as a; a::Foo};
| --------------------------- one trait comes from crate `crate_a2` is used here, which is renamed locally to `a`
...
LL | extern crate crate_a1 as a;
| --------------------------- one trait comes from crate `crate_a1` is used here, which is renamed locally to `a`
note: function defined here
--> $DIR/auxiliary/crate_a1.rs:11:8
|
LL | pub fn try_bar(x: Box<Bar>){}
| ^^^^^^^
```
This new output unifies the E0308 errors detail with the pre-existing E0277 errors, and better differentiates the "`extern crate` renamed" and "same crate, different versions" cases.
Remove a lit_to_const call
We have so many special cases of `match expr.kind { Lit() => {}, Unary(Neg, Lit()) => {} }`... I'm trying to figure out how to get these all unified, but outright removing some is good, too. So let's try it.
Tho we don't have many `const {}` blocks in the perf test suite... But I also don't know how common `const { 42 }` blocks are, I'd expect these to occur mostly from macros (like `thread_local!`)
Corrected a grammatical error in the explanation for E0751. Changed "exists" to "exist" to improve clarity and ensure proper grammar in the error message.
Hide errors whose suggestions would contain error constants or types
best reviewed commit-by-commit.
This is work towards cleaning up everything around `lit_to_const` and its mir equivalent.
fixes#123809
Do not implement unsafe auto traits for types with unsafe fields
If a type has unsafe fields, its safety invariants are not simply the conjunction of its field types' safety invariants. Consequently, it's invalid to reason about the safety properties of these types in a purely structural manner — i.e., the manner in which `auto` traits are implemented. Consequently, auto implementations of unsafe auto traits should not be generated for types with unsafe fields.
Tracking: #132922
r? `@compiler-errors`
It was inconsistently done (sometimes even within a single function) and
most of the rest of the compiler uses fatal errors instead, which need
to be caught using catch_with_exit_code anyway. Using fatal errors
instead of ErrorGuaranteed everywhere in the driver simplifies things a
bit.
Sync cg clif 2024 12 06
The main highlights this time are a Cranelift update disabling the clif ir verifier by default for better performance.
r? `@ghost`
`@rustbot` label +A-codegen +A-cranelift +T-compiler
Only allow PassMode::Direct for aggregates on wasm when using the C ABI
For the Rust ABI we don't have any ABI compat reasons to allow PassMode::Direct for aggregates.
Extend Miri to correctly pass mutable pointers through FFI
Based off of https://github.com/rust-lang/rust/pull/129684, this PR further extends Miri to execute native calls that make use of pointers to *mutable* memory.
We adapt Miri's bookkeeping of internal state upon any FFI call that gives external code permission to mutate memory.
Native code may now possibly write and therefore initialize and change the pointer provenance of bytes it has access to: Such memory is assumed to be *initialized* afterwards and bytes are given *arbitrary (wildcard) provenance*. This enables programs that correctly use mutating FFI calls to run Miri without errors, at the cost of possibly missing Undefined Behaviour caused by incorrect usage of mutating FFI.
> <details>
>
> <summary> Simple example </summary>
>
> ```rust
> extern "C" {
> fn init_int(ptr: *mut i32);
> }
>
> fn main() {
> let mut x = std::mem::MaybeUninit::<i32>::uninit();
> let x = unsafe {
> init_int(x.as_mut_ptr());
> x.assume_init()
> };
>
> println!("C initialized my memory to: {x}");
> }
> ```
> ```c
> void init_int(int *ptr) {
> *ptr = 42;
> }
> ```
> should now show `C initialized my memory to: 42`.
>
> </details>
r? ``@RalfJung``
rust_for_linux: -Zreg-struct-return commandline flag for X86 (#116973)
Command line flag `-Zreg-struct-return` for X86 (32-bit) for rust-for-linux.
This flag enables the same behavior as the `abi_return_struct_as_int` target spec key.
- Tracking issue: https://github.com/rust-lang/rust/issues/116973
If a type has unsafe fields, its safety invariants are not simply
the conjunction of its field types' safety invariants. Consequently,
it's invalid to reason about the safety properties of these types
in a purely structural manner — i.e., the manner in which `auto`
traits are implemented.
Makes progress towards #132922.
implement checks for tail calls
Quoting the [RFC draft](https://github.com/phi-go/rfcs/blob/guaranteed-tco/text/0000-explicit-tail-calls.md):
> The argument to become is a function (or method) call, that exactly matches the function signature and calling convention of the callee. The intent is to ensure a matching ABI. Note that lifetimes may differ as long as they pass borrow checking, see [below](https://github.com/phi-go/rfcs/blob/guaranteed-tco/text/0000-explicit-tail-calls.md#return-type-coercion) for specifics on the return type.
> Tail calling closures and tail calling from closures is not allowed. This is due to the high implementation effort, see below, this restriction can be lifted by a future RFC.
> Invocations of operators were considered as valid targets but were rejected on grounds of being too error-prone. In any case, these can still be called as methods.
> Tail calling [variadic functions](https://doc.rust-lang.org/beta/unstable-book/language-features/c-variadic.html) and tail calling from variadic functions is not allowed. As support for variadic function is stabilized on a per target level, support for tail-calls regarding variadic functions would need to follow a similar approach. To avoid this complexity and to minimize implementation effort for backends, this interaction is currently not allowed but support can be added with a future RFC.
-----
The checks are implemented as a query, similarly to `check_unsafety`.
The code is cherry-picked straight out of #112657 which was written more than a year ago, so I expect we might need to change some things ^^"
Fix "std" support status of some tier 3 targets
https://github.com/rust-lang/rust/pull/127265 marked targets with empty "std" support status as no-std targets in target-spec metadata:
> * Where a targets 'std' or 'host tools' support is listed as '?' in the rust docs, these are left as 'None' with this PR. The corresponding changes in cargo will only reject an attempt to build std if the 'std' field is 'Some(false)'. In the case it is 'None', cargo will continue trying to build
However, this is not accurate because "std" support status has a marker indicating that it is a no-std target. (empty status is just invalid.)
https://doc.rust-lang.org/nightly/rustc/platform-support.html#tier-3
> The `std` column in the table below has the following meanings:
>
> * ✓ indicates the full standard library is available.
> * \* indicates the target only supports [`no_std`] development.
> * ? indicates the standard library support is unknown or a work-in-progress.
>
> [`no_std`]: https://rust-embedded.github.io/book/intro/no-std.html
This PR fixes the status of targets whose "std" support status is currently set to empty and update target-spec metadata.
The new status is set based on the following criteria:
- Set to ✓ for targets that I regularly check in [rust-cross-toolchain](https://github.com/taiki-e/rust-cross-toolchain) that the `cargo test` works. (riscv32-unknown-linux-gnu,{riscv64,s390x}-unknown-linux-musl)
- Targets where `cargo run` works but `cargo test` does not work tend to have incomplete std support (e.g., riscv32 musl f3068b66e0), so I included them in the group below that means “work in progress” rather than in this group.
- Set powerpc64le FreeBSD to ✓ on both std and host_tools, because the [Rust package](https://www.freshports.org/lang/rust/) is available.
- Set to ? (which means "unknown" or “work in progress”) for all other affected targets because these are Linux, Android, FreeBSD, or Fuchsia, all of which are operating systems that support std if properly supported.
r? Noratrieb
cc ``@harmou01``
It's a performance win because `MixedBitSet` is faster and uses less
memory than `ChunkedBitSet`.
Also reflow some overlong comment lines in
`lint_tail_expr_drop_order.rs`.
It just uses `BitSet` for small/medium sizes (<= 2048 bits) and
`ChunkedBitSet` for larger sizes. This is good because `ChunkedBitSet`
is slow and memory-hungry at smaller sizes.
Rollup of 10 pull requests
Successful merges:
- #118833 (Add lint against function pointer comparisons)
- #122161 (Fix suggestion when shorthand `self` has erroneous type)
- #133233 (Add context to "const in pattern" errors)
- #133761 (Update books)
- #133843 (Do not emit empty suggestion)
- #133863 (Rename `core_pattern_type` and `core_pattern_types` lib feature gates to `pattern_type_macro`)
- #133872 (No need to create placeholders for GAT args in confirm_object_candidate)
- #133874 (`fn_sig_for_fn_abi` should return a `ty::FnSig`, no need for a binder)
- #133890 (Add a new test ui/incoherent-inherent-impls/no-other-unrelated-errors to check E0116 does not cause unrelated errors)
- #133892 (Revert #133817)
r? `@ghost`
`@rustbot` modify labels: rollup
No need to create placeholders for GAT args in confirm_object_candidate
We no longer need this logic to add placeholders for GAT args since with the removal of the `gat_extended` feature gate (https://github.com/rust-lang/rust/pull/133768) we no longer allow GATs in dyn trait anyways.
r? oli-obk
Do not emit empty suggestion
The `println!();` statement's span doesn't include the `;`, and the modified suggestions where trying to get the `;` by getting the differenece between the statement's and the expression's spans, which was an empty suggestion.
Fix#133833, fix#133834.
Add context to "const in pattern" errors
*Each commit addresses specific diagnostics.*
- Add primary span labels
- Point at `const` item, and `const` generic param definition
- Reword messages and notes
- Point at generic param through which an associated `const` is being referenced
- Silence const in pattern with evaluation errors when they come from `const` items that already emit a diagnostic
- On non-structural type in const used as pattern, point at the type that should derive `PartialEq`
Add lint against function pointer comparisons
This is kind of a follow-up to https://github.com/rust-lang/rust/pull/117758 where we added a lint against wide pointer comparisons for being ambiguous and unreliable; well function pointer comparisons are also unreliable. We should IMO follow a similar logic and warn people about it.
-----
## `unpredictable_function_pointer_comparisons`
*warn-by-default*
The `unpredictable_function_pointer_comparisons` lint checks comparison of function pointer as the operands.
### Example
```rust
fn foo() {}
let a = foo as fn();
let _ = a == foo;
```
### Explanation
Function pointers comparisons do not produce meaningful result since they are never guaranteed to be unique and could vary between different code generation units. Furthermore different function could have the same address after being merged together.
----
This PR also uplift the very similar `clippy::fn_address_comparisons` lint, which only linted on if one of the operand was an `ty::FnDef` while this PR lints proposes to lint on all `ty::FnPtr` and `ty::FnDef`.
```@rustbot``` labels +I-lang-nominated
~~Edit: Blocked on https://github.com/rust-lang/libs-team/issues/323 being accepted and it's follow-up pr~~
Make sure to record deps from cached task in new solver on first run
We weren't actually performing a read of the dep node in `with_cached_task` in the new solver, which meant that all queries that computed a goal for the first time were just not recording the query dependencies that we call in that query.
In the incremental test, the typeck query for `fn poll` isn't being marked red even tho it's invalidated due to its writeback results changing. This happens b/c we normalize `Self::Error` into `Error`, which should call `type_of` which is a red query (since `ty::Adt` contains an `AdtDef`, and that `AdtDef`'s stable hash changes since it's ). However, since we weren't tracking deps in that normalize query, the typeck result was remaining green, and we were trying to decode a def id that no longer exists (the field that got removed).
r? lcnr
Point at types that need to be marked with `#[derive(PartialEq)]`.
We use a visitor to look at a type that isn't structural, looking for all ADTs that don't derive `PartialEq`. These can either be manual `impl PartialEq`s or no `impl` at all, so we differentiate between those two cases to provide more context to the user. We also only point at types and impls from the local crate, otherwise show only a note.
```
error: constant of non-structural type `&[B]` in a pattern
--> $DIR/issue-61188-match-slice-forbidden-without-eq.rs:15:9
|
LL | struct B(i32);
| -------- must be annotated with `#[derive(PartialEq)]` to be usable in patterns
LL |
LL | const A: &[B] = &[];
| ------------- constant defined here
...
LL | A => (),
| ^ constant of non-structural type
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
```
- Point at type that should derive `PartialEq` to be structural.
- Point at manual `impl PartialEq`, explaining that it is not sufficient to be structural.
```
error: constant of non-structural type `MyType` in a pattern
--> $DIR/const-partial_eq-fallback-ice.rs:14:12
|
LL | struct MyType;
| ------------- `MyType` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const CONSTANT: &&MyType = &&MyType;
| ------------------------ constant defined here
...
LL | if let CONSTANT = &&MyType {
| ^^^^^^^^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/const-partial_eq-fallback-ice.rs:5:1
|
LL | impl PartialEq<usize> for MyType {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
```
error: trait object `dyn Send` cannot be used in patterns
--> $DIR/issue-70972-dyn-trait.rs:6:9
|
LL | const F: &'static dyn Send = &7u32;
| -------------------------- constant defined here
...
LL | F => panic!(),
| ^ trait object can't be used in patterns
```
- Add primary span labels.
- Point at const generic parameter used as pattern.
- Point at statics used as pattern.
- Point at let bindings used in const pattern.
Centralize emitting an error in `const_to_pat` so that all errors from that evaluating a `const` in a pattern can add addditional information. With this, now point at the `const` item's definition:
```
error[E0158]: constant pattern depends on a generic parameter
--> $DIR/associated-const-type-parameter-pattern.rs:20:9
|
LL | pub trait Foo {
| -------------
LL | const X: EFoo;
| ------------- constant defined here
...
LL | A::X => println!("A::X"),
| ^^^^
```
The `println!();` statement's span doesn't include the `;`, and the modified suggestions where trying to get the `;` by getting the differenece between the statement's and the expression's spans, which was an empty suggestion.
Fix#133833, fix#133834.
Avoid `opaque type not constrained` errors in the presence of other errors
pulled out of https://github.com/rust-lang/rust/pull/128440
These errors carry no new information if the opaque type was actually used in a constraining (but erroneous) way somewhere.
coverage: Use a separate counter type and simplification step during counter creation
When instrumenting a function's MIR for coverage, there is a point where we need to decide, for each node in the control-flow graph, whether its execution count will be tracked by a physical counter, or by an expression that combines physical counters from other parts of the graph.
Currently the code for doing that is heavily tied to the final form of the LLVM coverage mapping format, and performs some important simplification steps on-the-fly. These factors make the code extremely difficult to modify without breaking or massively worsening the resulting coverage-instrumentation metadata.
---
This PR aims to improve that situation somewhat by adding an extra intermediate representation between the code that chooses how each node will be counted, and the code that converts those decisions into actual tables of physical counters and trees of counter expressions.
As part of doing that, some of the simplifications that are currently performed during the main counter creation step have been pulled out into a separate step.
In most cases the resulting coverage metadata is equivalent, slightly better, or slightly worse. The biggest outlier is `counters.rs`, where the coverage metadata ends up about 10% larger. This seems to be the result of the new approach having less subexpression sharing (because it relies on flatten-sort-cancel), and therefore being less effective at taking advantage of MIR optimizations to replace counters for unused control-flow with zeroes. I think the modest downside is acceptable in light of the future possibilities opened up by this decoupling.
Remove `-Zshow-span`.
It's very old (added in #12087). It's strange, and it's not clear what its use cases are. It only works with the crate root file because it runs before expansion. I suspect it won't be missed.
r? `@estebank`
Don't try and handle unfed `type_of` on anon consts
The `type_of` query for anon consts in the type system is actually implemented by feeding the return value during hir ty lowering, not the hir-based logic in `const_arg_anon_type_of`. The HIR based logic is incomplete (doesn't handle all hir nodes) and also generally wrong to call (re-lowers HIR or invokes typeck which can result in query cycles).
r? `@compiler-errors`
Make CoercePointee errors translatable
Tracked by #123430
Just in case that a translatable error message would become a blocker to stabilization, this PR switches over to fluent error messages, which also slightly improve the wordings and use more accurate span information.
cc `@Darksonn` `@traviscross`
It's very old (added in #12087). It's strange, and it's not clear what
its use cases are. It only works with the crate root file because it
runs before expansion. I suspect it won't be missed.
stop replacing bivariant args with `'static` when computing closure requirements
It is unnecessary, these get constrained when checking that the opaque type is well-formed.
It also results in the opaque type no longer being well formed. If you've got `fn foo<'a>() -> impl Sized + 'a` the opaque is `type Opaque<'a, 'aDummy> where 'a: 'aDummy, 'aDummy: 'a` where `'aDummy` is bivariant. If we call `foo::<'b>()` inside of a closure and its return type ends up in a type test, we start out with the WF `Opaque<'b, 'b>`, and then replace the bivariant `'b` with `'static`. `Opaque<'b, 'static>` is no longer well-formed. Given how these type tests are used, I don't think this caused any practical issues.
r? types
Fix MutVisitor's default implementations to visit Stmt's and BinOp's spans
The `Stmt` case is a bug introduced almost certainly unintentionally by https://github.com/rust-lang/rust/pull/126993. The code _used_ to visit and mutate `span` correctly, but got changed as follows by that PR. Notice how `span` is **copied** into the output by `|kind| Stmt { id, kind, span }` which happens after the mutation in the correct code (red) and before the mutation in the incorrect code (green).
```diff
pub fn noop_flat_map_stmt<T: MutVisitor>(
Stmt { kind, mut span, mut id }: Stmt,
vis: &mut T,
) -> SmallVec<[Stmt; 1]> {
vis.visit_id(&mut id);
- vis.visit_span(&mut span);
let stmts: SmallVec<_> = noop_flat_map_stmt_kind(kind, vis)
.into_iter()
.map(|kind| Stmt { id, kind, span })
.collect();
if stmts.len() > 1 {
panic!(...);
}
+ vis.visit_span(&mut span);
stmts
}
```
[AIX] change AIX default codemodel=large
On AIX, for most libraries, we run out of Table of Contents (TOC) offsets very quickly due to the default 16-bit offset limit. We want the large code model should be used as the default to provide more TOC entries so the end user does not have to specify `-Ccode-model=large` for all their packages. This is even more of an issue with ThinLTO as the ThinLTO globals can very quickly use all available TOC entry.
In addition, on AIX, code with different code-model across different compilation units will not cause undefined behavior, so this is safe to do.
Remove `generic_associated_types_extended` feature gate
This PR retires nightly support for the `generic_associated_types_extended` feature. This feature hasn't received much attention in the last two years or so, and I believe the feature still remains both unsound and ICEy to use. I think that if we were to redesign and reimplement it, we'd want to first figure out how to implement it soundly, but in the mean time I'd prefer to clean this up.
r? ``@lcnr`` cc ``@jackh726`` who added this feature gate I think
improve TagEncoding::Niche docs, sanity check, and UB checks
Turns out the `niche_variants` range can actually contain the `untagged_variant`. We should report this as UB in Miri, so this PR implements that.
Also rename `partially_check_layout` to `layout_sanity_check` for better consistency with how similar functions are called in other parts of the compiler.
Turns out my adjustments to the transmutation logic also fix https://github.com/rust-lang/rust/issues/126267.
Use correct `hir_id` for array const arg infers
Fixes#133771
`self.next_id()` results in the `DefId` for the const argument, created from the hack introduced by #133468, having no `HirId` associated with it. This then results in an ICE in metadata encoding. Fixing this then results in *another* ICE where `encode_defs` was not skipping encoding `type_of` and other queries for `DefId`s when they correspond to a `ConstArgKind::Infer` node.
This only reproduces with a library crate as metadata is not encoded for binaries, and apparently we had 0 tests for `generic_arg_infer` for array lengths in a library crate so this was not caught :<
cc #133589 `@voidc`
r? `@compiler-errors` `@lcnr`
Reduce false positives on some common cases from if-let-rescope lint
r? `@jieyouxu`
We would like to identify a very common case in the ecosystem in which we do not need to apply the lint suggestion for the new Edition 2024 `if let` semantics.
In this patch we excluded linting from `if let`s in statements and block tail expressions. In these simple cases, new Edition 2024 drop orders are identical to those of Edition 2021 and prior.
However, conservatively we should still lint for the other cases, because [this example](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2113df5ce78f161d32a1190faf5c7469) shows that the drop order changes are very pronounced, some of which are even sensitive to runtime data.
Gate async fn trait bound modifier on `async_trait_bounds`
This PR moves `async Fn()` trait bounds into a new feature gate: `feature(async_trait_bounds)`. The general vibe is that we will most likely stabilize the `feature(async_closure)` *without* the `async Fn()` trait bound modifier, so we need to gate that separately.
We're trying to work on the general vision of `async` trait bound modifier general in: https://github.com/rust-lang/rfcs/pull/3710, however that RFC still needs more time for consensus to converge, and we've decided that the value that users get from calling the bound `async Fn()` is *not really* worth blocking landing async closures in general.
switch `jemalloc-sys` back to `tikv-jemalloc-sys`, and update to 0.6.0
Some context:
- we used to use jemalloc bindings from https://github.com/gnzlbg/jemallocator, since #55238
- that crate was abandoned, picked up as a fork in https://github.com/tikv/jemallocator, so we switched to that in #83152.
- then they were able to publish to the original `jemalloc-sys` bindings crate, and `jemalloc-sys` and `tikv-jemalloc-sys` became the same thing -- so I switched back to the OG crate in #96790
- they're now having publishing problems again: I've been waiting for https://github.com/tikv/jemallocator/pull/96 for the `jemalloc-sys` 0.6.0 update for a few months, but `tikv-jemalloc-sys` is already updated to 0.6.0.
A perf run showed some improvements, so this PR switches back to `tikv-jemalloc-sys` to update to 0.6.0.