Don't use `typeck_root_def_id` in codegen for finding closure's root
Generating debuginfo in codegen currently peels off all the closure-specific generics (which presumably is done because they're redundant). This doesn't currently work correctly for the bodies we synthesize for async closures's returned coroutines (#128506), leading to #129702.
Specifically, `typeck_root_def_id` for some `DefKind::SyntheticCoroutineBody` just returns itself (because it loops while `is_typeck_child` is `true`, and that returns `false` for this defkind), which means we don't end up peeling off the coroutine-specific generics, and we end up encountering an otherwise unreachable `CoroutineWitness` type leading to an ICE.
This PR fixes `is_typeck_child` to consider `DefKind::SyntheticCorotuineBody` to be a typeck child, fixing `typeck_root_def_id` and suppressing this debuginfo bug.
Fixes#129702
simplify float::classify logic
I played around with the float-classify test in the hope of triggering x87 bugs by strategically adding `black_box`, and still the exact expression `@beetrees` suggested [here](https://github.com/rust-lang/rust/pull/129835#issuecomment-2325661597) remains the only case I found where we get the wrong result on x87. Curiously, this bug only occurs when MIR optimizations are enabled -- probably the extra inlining that does is required for LLVM to hit the right "bad" case in the backend. But even for that case, it makes no difference whether `classify` is implemented in the simple bit-pattern-based version or the more complicated version we had before.
Without even a single testcase that can distinguish our `classify` from the naive version, I suggest we switch to the naive version.
interpret, miri: fix dealing with overflow during slice indexing and allocation
This is mostly to fix https://github.com/rust-lang/rust/issues/130284.
I then realized we're using somewhat sketchy arguments for a similar multiplication in `copy`/`copy_nonoverlapping`/`write_bytes`, so I made them all share the same function that checks exactly the right thing. (The intrinsics would previously fail on allocations larger than `1 << 47` bytes... which are theoretically possible maybe? Anyway it seems conceptually wrong to use any other bound than `isize::MAX` here.)
Correctly account for niche-optimized tags in rustc_transmute
This is a bit hacky, but it fixes the ICE and makes it possible to run the safe transmute check on every `mem::transmute` check we instantiate. I want to write a lint that needs to do that, but this stands well on its own.
cc `@jswrenn` here's the fix I alluded to yesterday :)
Fixes#123693
Stabilize `&mut` (and `*mut`) as well as `&Cell` (and `*const Cell`) in const
This stabilizes `const_mut_refs` and `const_refs_to_cell`. That allows a bunch of new things in const contexts:
- Mentioning `&mut` types
- Creating `&mut` and `*mut` values
- Creating `&T` and `*const T` values where `T` contains interior mutability
- Dereferencing `&mut` and `*mut` values (both for reads and writes)
The same rules as at runtime apply: mutating immutable data is UB. This includes mutation through pointers derived from shared references; the following is diagnosed with a hard error:
```rust
#[allow(invalid_reference_casting)]
const _: () = {
let mut val = 15;
let ptr = &val as *const i32 as *mut i32;
unsafe { *ptr = 16; }
};
```
The main limitation that is enforced is that the final value of a const (or non-`mut` static) may not contain `&mut` values nor interior mutable `&` values. This is necessary because the memory those references point to becomes *read-only* when the constant is done computing, so (interior) mutable references to such memory would be pretty dangerous. We take a multi-layered approach here to ensuring no mutable references escape the initializer expression:
- A static analysis rejects (interior) mutable references when the referee looks like it may outlive the current MIR body.
- To be extra sure, this static check is complemented by a "safety net" of dynamic checks. ("Dynamic" in the sense of "running during/after const-evaluation, e.g. at runtime of this code" -- in contrast to "static" which works entirely by looking at the MIR without evaluating it.)
- After the final value is computed, we do a type-driven traversal of the entire value, and if we find any `&mut` or interior-mutable `&` we error out.
- However, the type-driven traversal cannot traverse `union` or raw pointers, so there is a second dynamic check where if the final value of the const contains any pointer that was not derived from a shared reference, we complain. This is currently a future-compat lint, but will become an ICE in #128543. On the off-chance that it's actually possible to trigger this lint on stable, I'd prefer if we could make it an ICE before stabilizing const_mut_refs, but it's not a hard blocker. This part of the "safety net" is only active for mutable references since with shared references, it has false positives.
Altogether this should prevent people from leaking (interior) mutable references out of the const initializer.
While updating the tests I learned that surprisingly, this code gets rejected:
```rust
const _: Vec<i32> = {
let mut x = Vec::<i32>::new(); //~ ERROR destructor of `Vec<i32>` cannot be evaluated at compile-time
let r = &mut x;
let y = x;
y
};
```
The analysis that rejects destructors in `const` is very conservative when it sees an `&mut` being created to `x`, and then considers `x` to be always live. See [here](https://github.com/rust-lang/rust/issues/65394#issuecomment-541499219) for a longer explanation. `const_precise_live_drops` will solve this, so I consider this problem to be tracked by https://github.com/rust-lang/rust/issues/73255.
Cc `@rust-lang/wg-const-eval` `@rust-lang/lang`
Cc https://github.com/rust-lang/rust/issues/57349
Cc https://github.com/rust-lang/rust/issues/80384
Add `NonNull` convenience methods to `Box` and `Vec`
Implements the ACP: https://github.com/rust-lang/libs-team/issues/418.
The docs for the added methods are mostly copied from the existing methods that use raw pointers instead of `NonNull`.
I'm new to this "contributing to rustc" thing, so I'm sorry if I did something wrong. In particular, I don't know what the process is for creating a new unstable feature. Please advise me if I should do something. Thank you.
stabilize `const_extern_fn`
closes https://github.com/rust-lang/rust/issues/64926
tracking issue: https://github.com/rust-lang/rust/issues/64926
reference PR: https://github.com/rust-lang/reference/pull/1596
## Stabilizaton Report
### Summary
Using `const extern "Rust"` and `const extern "C"` was already stabilized (since version 1.62.0, see https://github.com/rust-lang/rust/pull/95346). This PR stabilizes the other calling conventions: it is now possible to write `const unsafe extern "calling-convention" fn` and `const extern "calling-convention" fn` for any supported calling convention:
```rust
const extern "C-unwind" fn foo1(val: u8) -> u8 { val + 1}
const extern "stdcall" fn foo2(val: u8) -> u8 { val + 1}
const unsafe extern "C-unwind" fn bar1(val: bool) -> bool { !val }
const unsafe extern "stdcall" fn bar2(val: bool) -> bool { !val }
```
This can be used to const-ify an `extern fn`, or conversely, to make a `const fn` callable from external code.
r? T-lang
cc `@RalfJung`
const-eval interning: accept interior mutable pointers in final value
…but keep rejecting mutable references
This fixes https://github.com/rust-lang/rust/issues/121610 by no longer firing the lint when there is a pointer with interior mutability in the final value of the constant. On stable, such pointers can be created with code like:
```rust
pub enum JsValue {
Undefined,
Object(Cell<bool>),
}
impl Drop for JsValue {
fn drop(&mut self) {}
}
// This does *not* get promoted since `JsValue` has a destructor.
// However, the outer scope rule applies, still giving this 'static lifetime.
const UNDEFINED: &JsValue = &JsValue::Undefined;
```
It's not great to accept such values since people *might* think that it is legal to mutate them with unsafe code. (This is related to how "infectious" `UnsafeCell` is, which is a [wide open question](https://github.com/rust-lang/unsafe-code-guidelines/issues/236).) However, we [explicitly document](https://doc.rust-lang.org/reference/behavior-considered-undefined.html) that things created by `const` are immutable. Furthermore, we also accept the following even more questionable code without any lint today:
```rust
let x: &'static Option<Cell<i32>> = &None;
```
This is even more questionable since it does *not* involve a `const`, and yet still puts the data into immutable memory. We could view this as promotion [potentially introducing UB](https://github.com/rust-lang/unsafe-code-guidelines/issues/493). However, we've accepted this since ~forever and it's [too late to reject this now](https://github.com/rust-lang/rust/pull/122789); the pattern is just too useful.
So basically, if you think that `UnsafeCell` should be tracked fully precisely, then you should want the lint we currently emit to be removed, which this PR does. If you think `UnsafeCell` should "infect" surrounding `enum`s, the big problem is really https://github.com/rust-lang/unsafe-code-guidelines/issues/493 which does not trigger the lint -- the cases the lint triggers on are actually the "harmless" ones as there is an explicit surrounding `const` explaining why things end up being immutable.
What all this goes to show is that the hard error added in https://github.com/rust-lang/rust/pull/118324 (later turned into the future-compat lint that I am now suggesting we remove) was based on some wrong assumptions, at least insofar as it concerns shared references. Furthermore, that lint does not help at all for the most problematic case here where the potential UB is completely implicit. (In fact, the lint is actively in the way of [my preferred long-term strategy](https://github.com/rust-lang/unsafe-code-guidelines/issues/493#issuecomment-2028674105) for dealing with this UB.) So I think we should go back to square one and remove that error/lint for shared references. For mutable references, it does seem to work as intended, so we can keep it. Here it serves as a safety net in case the static checks that try to contain mutable references to the inside of a const initializer are not working as intended; I therefore made the check ICE to encourage users to tell us if that safety net is triggered.
Closes https://github.com/rust-lang/rust/issues/122153 by removing the lint.
Cc `@rust-lang/opsem` `@rust-lang/lang`
Fix `Parser::break_up_float`'s right span
```rs
use std::mem::offset_of;
fn main() {
offset_of!((u8,), 0.0);
}
```
Before:
```
error[E0609]: no field `0` on type `u8`
--> ./main.rs:4:25
|
4 | offset_of!((u8,), 0.0);
| _____--------------------^-
| | |
| | in this macro invocation
5 | | }
... |
|
= note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 1 previous error
```
After:
```
error[E0609]: no field `0` on type `u8`
--> ./main.rs:4:25
|
4 | offset_of!((u8,), 0.0);
| ^
error: aborting due to 1 previous error
```
---
`@rustbot` label +A-parser +D-imprecise-spans
simd_shuffle: require index argument to be a vector
Remove some codegen hacks by forcing the SIMD shuffle `index` argument to be a vector, which means (thanks to https://github.com/rust-lang/rust/pull/128537) that it will automatically be passed as an immediate in LLVM. The only special-casing we still have is for the extra sanity-checks we add that ensure that the indices are all in-bounds. (And the GCC backend needs to do a bunch of work since the Rust intrinsic is modeled after what LLVM expects, which seems to be quite different from what GCC expects.)
Fixes https://github.com/rust-lang/rust/issues/128738, see that issue for more context.
(fix) conflicting negative impl marker
## Context
This MR fixes the error message for conflicting negative trait impls by adding the corresponding the polarity marker to the trait name.
## Issues
- closes#70849
r? `@fmease`
Don't call closure_by_move_body_def_id on FnOnce async closures in MIR validation
Refactors the check in #129847 to not unncessarily call the `closure_by_move_body_def_id` query for async closures that don't *need* a by-move body.
Fixes#130167
some fixes for clashing_extern_declarations lint
There were two issues with the clashing_extern_declarations lint:
- It would accept non-`repr(C)` structs as compatible with each other by comparing their fields in declaration order, but the fields could have different memory order (and with `-Zrandomize-layout`, this can really happen).
- It would accept two types as compatible if `compare_layouts` returns `true`, but that function actually just compared the *ABI*, not the fully layout -- and all sized structs with more than 2 fields have the same ABI (`Abi::Aggregate`), so this missed a *lot* of cases.
We don't currently have a clear spec for what we *want* to consider "clashing" and what is fine, so I otherwise kept the original logic. I hope to have a t-lang discussion about this at some point. But meanwhile, these changes seem like clear bugfixes.
Fix crash when labeling arguments for call_once and friends
When calling a method on Fn* traits explicitly, argument diagnostics should point at the called method (eg Fn::call_once), not the underlying callee.
This PR makes 3 main changes:
* It uses TupleArguments to detect if the user called a Fn* method directly (`my_fn.call_once(…)`) or implicitly (`my_fn(…)`). If it was explicit, argument diagnostics should point at the call_once method, not the underlying callable.
* The previous state was causing confusion between the two arguments lists (which could be different lengths), causing an out-of-bounds slice indexing in #128848. I added a length assert to capture the requirement in case this regresses or happens in another case.
* Unfortunately, this assert tripped when the required arguments information was not available (`self.get_hir_params_with_generics` was returning an empty Vec), so I've updated that to return None when that information is not available. (cc `@strottos` if you have any comments, since you added this function in #121595) Sorry this causes a bunch of indentation changes, recommend reviewing [ignoring whitespace](https://github.com/rust-lang/rust/pull/129320/files?w=1).)
This is my first rustc PR, so please call out if you'd like this split into more commits (or PRs), style nits, etc. I will add a few comments/questions inline. Thank you!
Fixes#128848
Rescope temp lifetime in if-let into IfElse with migration lint
Tracking issue #124085
This PR shortens the temporary lifetime to cover only the pattern matching and consequent branch of a `if let`.
At the expression location, means that the lifetime is shortened from previously the deepest enclosing block or statement in Edition 2021. This warrants an Edition change.
Coming with the Edition change, this patch also implements an edition lint to warn about the change and a safe rewrite suggestion to preserve the 2021 semantics in most cases.
Related to #103108.
Related crater runs: https://github.com/rust-lang/rust/pull/129466.
Fix anon const def-creation when macros are involved
Fixes#128016.
Ever since #125915, some `ast::AnonConst`s turn into `hir::ConstArgKind::Path`s,
which don't have associated `DefId`s. To deal with the fact that we don't have
resolution information in `DefCollector`, we decided to implement a process
where if the anon const *appeared* to be trivial (i.e., `N` or `{ N }`), we
would avoid creating a def for it in `DefCollector`. If later, in AST lowering,
we realized it turned out to be a unit struct literal, or we were lowering it
to something that didn't use `hir::ConstArg`, we'd create its def there.
However, let's say we have a macro `m!()` that expands to a reference to a free
constant `FOO`. If we use `m!()` in the body of an anon const (e.g., `Foo<{ m!() }>`),
then in def collection, it appears to be a nontrivial anon const and we create
a def. But the macro expands to something that looks like a trivial const arg,
but is not, so in AST lowering we "fix" the mistake we assumed def collection
made and create a def for it. This causes a duplicate definition ICE.
The long-term fix for this is to delay the creation of defs for all expression-like
nodes until AST lowering (see #128844 for an incomplete attempt at this). This
would avoid issues like this one that are caused by hacky workarounds. However,
doing this uncovers a pre-existing bug with opaque types that is quite involved
to fix (see #129023).
In the meantime, this PR fixes the bug by delaying def creation for anon consts
whose bodies are macro invocations until after we expand the macro and know
what is inside it. This is accomplished by adding information to create the
anon const's def to the data in `Resolver.invocation_parents`.
r? `@BoxyUwU`
...and remove the `const_arg_path` feature gate as a result. It was only
a stopgap measure to fix the regression that the new lowering introduced
(which should now be fixed by this PR).
more eagerly discard constraints on overflow
We always discard the results of overflowing goals inside of the trait solver. We previously did so when instantiating the response in `evaluate_goal`. Canonicalizing results only to later discard them is also inefficient 🤷
It's simpler and nicer to debug to eagerly discard constraints inside of the query itself.
r? ``@compiler-errors``
some const cleanup: remove unnecessary attributes, add const-hack indications
I learned that we use `FIXME(const-hack)` on top of the "const-hack" label. That seems much better since it marks the right place in the code and moves around with the code. So I went through the PRs with that label and added appropriate FIXMEs in the code. IMO this means we can then remove the label -- Cc ``@rust-lang/wg-const-eval.``
I also noticed some const stability attributes that don't do anything useful, and removed them.
r? ``@fee1-dead``
Properly report error on `const gen fn`
Fixes#130232
Also removes some (what I thought were unused) functions, and fixes a bug in clippy where we considered `gen fn` to be the same as `fn` because it was only built to consider asyncness.
enable const-float-classify test, and test_next_up/down on 32bit x86
The test_next_up/down tests have been disabled on all 32bit x86 targets, which goes too far -- they should definitely work on our (tier 1) i686 target, it is only without SSE that we might run into trouble due to https://github.com/rust-lang/rust/issues/114479. However, I cannot reproduce that trouble any more -- maybe that got fixed by https://github.com/rust-lang/rust/pull/123351?
The const-float-classify test relied on const traits "because we can", and got disabled when const traits got removed. That's an unfortunate reduction in test coverage of our float functionality, so let's restore the test in a way that does not rely on const traits.
The const-float tests are actually testing runtime behavior as well, and I don't think that runtime behavior is covered anywhere else. Probably they shouldn't be called "const-float", but we don't have a `tests/ui/float` folder... should I create one and move them there? Are there any other ui tests that should be moved there?
I also removed some FIXME referring to not use x87 for Rust-to-Rust-calls -- that has happened in #123351 so this got fixed indeed. Does that mean we can simplify all that float code again? I am not sure how to test it. Is running the test suite with an i586 target enough?
Cc ```@tgross35``` ```@workingjubilee```
Don't warn empty branches unreachable for now
The [stabilization](https://github.com/rust-lang/rust/pull/122792) of `min_exhaustive_patterns` updated the `unreachable_pattern` lint to trigger on empty arms too. This has caused some amount of churn, and imposes an unjoyful `#[allow(unreachable_patterns)]` onto library authors who want to stay backwards-compatible.
While I think the lint should eventually cover these cases, for transition's sake I'd prefer to revert linting to what it was prior to stabilization, at least for now.
Fixes https://github.com/rust-lang/rust/issues/129031.
r? ``@compiler-errors``
Fix false positive with `missing_docs` and `#[test]`
Since #130025, the compiler don't ignore missing_docs when compiling the tests. But there is now a false positive warning for every `#[test]`
For example, this code
```rust
//! Crate docs
fn just_a_test() {}
```
Would emit this warning when running `cargo test`
```
warning: missing documentation for a constant
--> src/lib.rs:5:1
|
4 | #[test]
| ------- in this procedural macro expansion
5 | fn just_a_test() {}
| ^^^^^^^^^^^^^^^^^^^
```
Report the `note` when specified in `diagnostic::on_unimplemented`
Before this PR the `note` field was completely ignored for some reason, now it is shown (I think) correctly during the hir typechecking phase.
1. Report the `note` when specified in `diagnostic::on_unimplemented`
2. Added a test for unimplemented trait diagnostic
3. Added a test for custom unimplemented trait diagnostic
Close#130084
P.S. This is my first PR to rustc.
Suggest the correct pattern syntax on usage of unit variant pattern for a struct variant
Closes#126243
I add a suggestion on usage of unit variant pattern for a struct variant.
Since #130025, the compiler don't ignore missing_docs when compiling the tests.
But there is now a false positive warning for every `#[test]`
For example, this code
```rust
//! Crate docs
fn just_a_test() {}
```
Would emit this warning when running `cargo test`
```
warning: missing documentation for a constant
--> src/lib.rs:5:1
|
4 | #[test]
| ------- in this procedural macro expansion
5 | fn just_a_test() {}
| ^^^^^^^^^^^^^^^^^^^
```
generalize: track relevant info in cache key
This was previously theoretically incomplete as we could incorrectly generalize as if the type was in an invariant context even though we're in a covariant one. Similar with the `in_alias` flag.
r? `@compiler-errors`
Enumerate lint expectations using AttrId
This PR implements the idea I outlined in https://github.com/rust-lang/rust/issues/127884#issuecomment-2240338547
We can uniquely identify a lint expectation `#[expect(lint0, lint1...)]` using the `AttrId` and the index of the lint inside the attribute. This PR uses this property in `check_expectations`.
In addition, this PR stops stashing expected diagnostics to wait for the unstable -> stable `LintExpectationId` mapping: if the lint is emitted with an unstable attribute, it must have been emitted by an `eval_always` query (like inside the resolver), so won't be loaded from cache. Decoding an `AttrId` from the on-disk cache ICEs, so we have no risk of accidentally checking an expectation.
Fixes https://github.com/rust-lang/rust/issues/127884
cc `@xFrednet`
abi/compatibility test: remove tests inside repr(C) wrappers
When I wrote the test I assumed we'd guarantee ABI compatibility to be "structural" wrt `repr(C)` types, i.e. if two `repr(C)` types have all their fields be pairwise ABI-compatible then the types are ABI-compatible. That got removed from the ABI compatibility docs before they landed, though, so let's also remove it from this test.
Also emit `missing_docs` lint with `--test` to fulfil expectations
This PR removes the "test harness" suppression of the `missing_docs` lint to be able to fulfil `#[expect]` (expectations) as it is now "relevant".
I think the goal was to maybe avoid false-positive while linting on public items under `#[cfg(test)]` but with effective visibility we should no longer have any false-positive.
Another possibility would be to query the lint level and only emit the lint if it's of expect level, but that is even more hacky.
Fixes https://github.com/rust-lang/rust/issues/130021
try-job: x86_64-gnu-aux
bootstrap `naked_asm!` for `compiler-builtins`
tracking issue: https://github.com/rust-lang/rust/issues/90957
parent PR: https://github.com/rust-lang/rust/pull/128651
in this PR, `naked_asm!` is added as an alias for `asm!` with one difference: `options(noreturn)` is always enabled by `naked_asm!`. That makes it future-compatible for when `naked_asm!` starts disallowing `options(noreturn)` later.
The `naked_asm!` macro must be introduced first so that we can upgrade `compiler-builtins` to use it, and can then change the implementation of `naked_asm!` in https://github.com/rust-lang/rust/pull/128651
I've added some usages for `naked_asm!` in the tests, so we can be confident that it works, but I've left upgrading the whole test suite to the parent PR.
r? ``@Amanieu``
Inform the solver if evaluation is concurrent
Parallel compilation of a program can cause unexpected event sequencing. Inform the solver when this is true so it can skip invalid asserts.
Parallel compilation of a program can cause unexpected event sequencing.
Inform the solver when this is true so it can skip invalid asserts, then
assert replaced solutions are equal if Some
in this commit, `naked_asm!` is an alias for `asm!` with one difference: `options(noreturn)` is always enabled by `naked_asm!`. That makes it future-compatible for when `naked_asm!` starts disallowing `options(noreturn)` later.
Fix double handling in `collect_tokens`
Double handling of AST nodes can occur in `collect_tokens`. This is when an inner call to `collect_tokens` produces an AST node, and then an outer call to `collect_tokens` produces the same AST node. This can happen in a few places, e.g. expression statements where the statement delegates `HasTokens` and `HasAttrs` to the expression. It will also happen more after #124141.
This PR fixes some double handling cases that cause problems, including #129166.
r? `@petrochenkov`
Supress niches in coroutines to avoid aliasing violations
As mentioned [here](https://github.com/rust-lang/rust/issues/63818#issuecomment-2264915918), using niches in fields of coroutines that are referenced by other fields is unsound: the discriminant accesses violate the aliasing requirements of the reference pointing to the relevant field. This issue causes [Miri errors in practice](https://github.com/rust-lang/miri/issues/3780).
The "obvious" fix for this is to suppress niches in coroutines. That's what this PR does. However, we have several tests explicitly ensuring that we *do* use niches in coroutines. So I see two options:
- We guard this behavior behind a `-Z` flag (that Miri will set by default). There is no known case of these aliasing violations causing miscompilations. But absence of evidence is not evidence of absence...
- (What this PR does right now.) We temporarily adjust the coroutine layout logic and the associated tests until the proper fix lands. The "proper fix" here is to wrap fields that other fields can point to in [`UnsafePinned`](https://github.com/rust-lang/rust/issues/125735) and make `UnsafePinned` suppress niches; that would then still permit using niches of *other* fields (those that never get borrowed). However, I know that coroutine sizes are already a problem, so I am not sure if this temporary size regression is acceptable.
`@compiler-errors` any opinion? Also who else should be Cc'd here?
Do not call query to compute coroutine layout for synthetic body of async closure
There is code in the MIR validator that attempts to prevent query cycles when inlining a coroutine into itself, and will use the coroutine layout directly from the body when it detects that's the same coroutine as the one that's being validated. After #128506, this logic didn't take into account the fact that the coroutine def id will differ if it's the "by-move body" of an async closure. This PR implements that.
Fixes#129811
Implement raw lifetimes and labels (`'r#ident`)
This PR does two things:
1. Reserve lifetime prefixes, e.g. `'prefix#lt` in edition 2021.
2. Implements raw lifetimes, e.g. `'r#async` in edition 2021.
This PR additionally extends the `keyword_idents_2024` lint to also check lifetimes.
cc `@traviscross`
r? parser
Add Suggestions for Misspelled Keywords
Fixes#97793
This PR detects misspelled keywords using two heuristics:
1. Lowercasing the unexpected identifier.
2. Using edit distance to find a keyword similar to the unexpected identifier.
However, it does not detect each and every misspelled keyword to
minimize false positives and ambiguities. More details about the
implementation can be found in the comments.
This PR detects misspelled keywords using two heuristics:
1. Lowercasing the unexpected identifier.
2. Using edit distance to find a keyword similar to the unexpected identifier.
However, it does not detect each and every misspelled keyword to
minimize false positives and ambiguities. More details about the
implementation can be found in the comments.
stabilize `-Znext-solver=coherence`
r? `@compiler-errors`
---
This PR stabilizes the use of the next generation trait solver in coherence checking by enabling `-Znext-solver=coherence` by default. More specifically its use in the *implicit negative overlap check*. The tracking issue for this is https://github.com/rust-lang/rust/issues/114862. Closes#114862.
## Background
### The next generation trait solver
The new solver lives in [`rustc_trait_selection::solve`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_trait_selection/src/solve/mod.rs) and is intended to replace the existing *evaluate*, *fulfill*, and *project* implementation. It also has a wider impact on the rest of the type system, for example by changing our approach to handling associated types.
For a more detailed explanation of the new trait solver, see the [rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/solve/trait-solving.html). This does not stabilize the current behavior of the new trait solver, only the behavior impacting the implicit negative overlap check. There are many areas in the new solver which are not yet finalized. We are confident that their final design will not conflict with the user-facing behavior observable via coherence. More on that further down.
Please check out [the chapter](https://rustc-dev-guide.rust-lang.org/solve/significant-changes.html) summarizing the most significant changes between the existing and new implementations.
### Coherence and the implicit negative overlap check
Coherence checking detects any overlapping impls. Overlapping trait impls always error while overlapping inherent impls result in an error if they have methods with the same name. Coherence also results in an error if any other impls could exist, even if they are currently unknown. This affects impls which may get added to upstream crates in a backwards compatible way and impls from downstream crates.
Coherence failing to detect overlap is generally considered to be unsound, even if it is difficult to actually get runtime UB this way. It is quite easy to get ICEs due to bugs in coherence.
It currently consists of two checks:
The [orphan check] validates that impls do not overlap with other impls we do not know about: either because they may be defined in a sibling crate, or because an upstream crate is allowed to add it without being considered a breaking change.
The [overlap check] validates that impls do not overlap with other impls we know about. This is done as follows:
- Instantiate the generic parameters of both impls with inference variables
- Equate the `TraitRef`s of both impls. If it fails there is no overlap.
- [implicit negative]: Check whether any of the instantiated `where`-bounds of one of the impls definitely do not hold when using the constraints from the previous step. If a `where`-bound does not hold, there is no overlap.
- *explicit negative (still unstable, ignored going forward)*: Check whether the any negated `where`-bounds can be proven, e.g. a `&mut u32: Clone` bound definitely does not hold as an explicit `impl<T> !Clone for &mut T` exists.
The overlap check has to *prove that unifying the impls does not succeed*. This means that **incorrectly getting a type error during coherence is unsound** as it would allow impls to overlap: coherence has to be *complete*.
Completeness means that we never incorrectly error. This means that during coherence we must only add inference constraints if they are definitely necessary. During ordinary type checking [this does not hold](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=01d93b592bd9036ac96071cbf1d624a9), so the trait solver has to behave differently, depending on whether we're in coherence or not.
The implicit negative check only considers goals to "definitely not hold" if they could not be implemented downstream, by a sibling, or upstream in a backwards compatible way. If the goal is is "unknowable" as it may get added in another crate, we add an ambiguous candidate: [source](bea5bebf3d/compiler/rustc_trait_selection/src/solve/assembly/mod.rs (L858-L883)).
[orphan check]: fd80c02c16/compiler/rustc_trait_selection/src/traits/coherence.rs (L566-L579)
[overlap check]: fd80c02c16/compiler/rustc_trait_selection/src/traits/coherence.rs (L92-L98)
[implicit negative]: fd80c02c16/compiler/rustc_trait_selection/src/traits/coherence.rs (L223-L281)
## Motivation
Replacing the existing solver in coherence fixes soundness bugs by removing sources of incompleteness in the type system. The new solver separately strengthens coherence, resulting in more impls being disjoint and passing the coherence check. The concrete changes will be elaborated further down. We believe the stabilization to reduce the likelihood of future bugs in coherence as the new implementation is easier to understand and reason about.
It allows us to remove the support for coherence and implicit-negative reasoning in the old solver, allowing us to remove some code and simplifying the old trait solver. We will only remove the old solver support once this stabilization has reached stable to make sure we're able to quickly revert in case any unexpected issues are detected before then.
Stabilizing the use of the next-generation trait solver expresses our confidence that its current behavior is intended and our work towards enabling its use everywhere will not require any breaking changes to the areas used by coherence checking. We are also confident that we will be able to replace the existing solver everywhere, as maintaining two separate systems adds a significant maintainance burden.
## User-facing impact and reasoning
### Breakage due to improved handling of associated types
The new solver fixes multiple issues related to associated types. As these issues caused coherence to consider more types distinct, fixing them results in more overlap errors. This is therefore a breaking change.
#### Structurally relating aliases containing bound vars
Fixes https://github.com/rust-lang/rust/issues/102048. In the existing solver relating ambiguous projections containing bound variables is structural. This is *incomplete* and allows overlapping impls. These was mostly not exploitable as the same issue also caused impls to not apply when trying to use them. The new solver defers alias-relating to a nested goal, fixing this issue:
```rust
// revisions: current next
//[next] compile-flags: -Znext-solver=coherence
trait Trait {}
trait Project {
type Assoc<'a>;
}
impl Project for u32 {
type Assoc<'a> = &'a u32;
}
// Eagerly normalizing `<?infer as Project>::Assoc<'a>` is ambiguous,
// so the old solver ended up structurally relating
//
// (?infer, for<'a> fn(<?infer as Project>::Assoc<'a>))
//
// with
//
// ((u32, fn(&'a u32)))
//
// Equating `&'a u32` with `<u32 as Project>::Assoc<'a>` failed, even
// though these types are equal modulo normalization.
impl<T: Project> Trait for (T, for<'a> fn(<T as Project>::Assoc<'a>)) {}
impl<'a> Trait for (u32, fn(&'a u32)) {}
//[next]~^ ERROR conflicting implementations of trait `Trait` for type `(u32, for<'a> fn(&'a u32))`
```
A crater run did not discover any breakage due to this change.
#### Unknowable candidates for higher ranked trait goals
This avoids an unsoundness by attempting to normalize in `trait_ref_is_knowable`, fixing https://github.com/rust-lang/rust/issues/114061. This is a side-effect of supporting lazy normalization, as that forces us to attempt to normalize when checking whether a `TraitRef` is knowable: [source](47dd709bed/compiler/rustc_trait_selection/src/solve/assembly/mod.rs (L754-L764)).
```rust
// revisions: current next
//[next] compile-flags: -Znext-solver=coherence
trait IsUnit {}
impl IsUnit for () {}
pub trait WithAssoc<'a> {
type Assoc;
}
// We considered `for<'a> <T as WithAssoc<'a>>::Assoc: IsUnit`
// to be knowable, even though the projection is ambiguous.
pub trait Trait {}
impl<T> Trait for T
where
T: 'static,
for<'a> T: WithAssoc<'a>,
for<'a> <T as WithAssoc<'a>>::Assoc: IsUnit,
{
}
impl<T> Trait for Box<T> {}
//[next]~^ ERROR conflicting implementations of trait `Trait`
```
The two impls of `Trait` overlap given the following downstream crate:
```rust
use dep::*;
struct Local;
impl WithAssoc<'_> for Box<Local> {
type Assoc = ();
}
```
There a similar coherence unsoundness caused by our handling of aliases which is fixed separately in https://github.com/rust-lang/rust/pull/117164.
This change breaks the [`derive-visitor`](https://crates.io/crates/derive-visitor) crate. I have opened an issue in that repo: nikis05/derive-visitor#16.
### Evaluating goals to a fixpoint and applying inference constraints
In the old implementation of the implicit-negative check, each obligation is [checked separately without applying its inference constraints](bea5bebf3d/compiler/rustc_trait_selection/src/traits/coherence.rs (L323-L338)). The new solver instead [uses a `FulfillmentCtxt`](bea5bebf3d/compiler/rustc_trait_selection/src/traits/coherence.rs (L315-L321)) for this, which evaluates all obligations in a loop until there's no further inference progress.
This is necessary for backwards compatibility as we do not eagerly normalize with the new solver, resulting in constraints from normalization to only get applied by evaluating a separate obligation. This also allows more code to compile:
```rust
// revisions: current next
//[next] compile-flags: -Znext-solver=coherence
trait Mirror {
type Assoc;
}
impl<T> Mirror for T {
type Assoc = T;
}
trait Foo {}
trait Bar {}
// The self type starts out as `?0` but is constrained to `()`
// due to the where-clause below. Because `(): Bar` is known to
// not hold, we can prove the impls disjoint.
impl<T> Foo for T where (): Mirror<Assoc = T> {}
//[current]~^ ERROR conflicting implementations of trait `Foo` for type `()`
impl<T> Foo for T where T: Bar {}
fn main() {}
```
The old solver does not run nested goals to a fixpoint in evaluation. The new solver does do so, strengthening inference and improving the overlap check:
```rust
// revisions: current next
//[next] compile-flags: -Znext-solver=coherence
trait Foo {}
impl<T> Foo for (u8, T, T) {}
trait NotU8 {}
trait Bar {}
impl<T, U: NotU8> Bar for (T, T, U) {}
trait NeedsFixpoint {}
impl<T: Foo + Bar> NeedsFixpoint for T {}
impl NeedsFixpoint for (u8, u8, u8) {}
trait Overlap {}
impl<T: NeedsFixpoint> Overlap for T {}
impl<T, U: NotU8, V> Overlap for (T, U, V) {}
//[current]~^ ERROR conflicting implementations of trait `Foo`
```
### Breakage due to removal of incomplete candidate preference
Fixes#107887. In the old solver we incompletely prefer the builtin trait object impl over user defined impls. This can break inference guidance, inferring `?x` in `dyn Trait<u32>: Trait<?x>` to `u32`, even if an explicit impl of `Trait<u64>` also exists.
This caused coherence to incorrectly allow overlapping impls, resulting in ICEs and a theoretical unsoundness. See https://github.com/rust-lang/rust/issues/107887#issuecomment-1997261676. This compiles on stable but results in an overlap error with `-Znext-solver=coherence`:
```rust
// revisions: current next
//[next] compile-flags: -Znext-solver=coherence
struct W<T: ?Sized>(*const T);
trait Trait<T: ?Sized> {
type Assoc;
}
// This would trigger the check for overlap between automatic and custom impl.
// They actually don't overlap so an impl like this should remain possible
// forever.
//
// impl Trait<u64> for dyn Trait<u32> {}
trait Indirect {}
impl Indirect for dyn Trait<u32, Assoc = ()> {}
impl<T: Indirect + ?Sized> Trait<u64> for T {
type Assoc = ();
}
// Incomplete impl where `dyn Trait<u32>: Trait<_>` does not hold, but
// `dyn Trait<u32>: Trait<u64>` does.
trait EvaluateHack<U: ?Sized> {}
impl<T: ?Sized, U: ?Sized> EvaluateHack<W<U>> for T
where
T: Trait<U, Assoc = ()>, // incompletely constrains `_` to `u32`
U: IsU64,
T: Trait<U, Assoc = ()>, // incompletely constrains `_` to `u32`
{
}
trait IsU64 {}
impl IsU64 for u64 {}
trait Overlap<U: ?Sized> {
type Assoc: Default;
}
impl<T: ?Sized + EvaluateHack<W<U>>, U: ?Sized> Overlap<U> for T {
type Assoc = Box<u32>;
}
impl<U: ?Sized> Overlap<U> for dyn Trait<u32, Assoc = ()> {
//[next]~^ ERROR conflicting implementations of trait `Overlap<_>`
type Assoc = usize;
}
```
### Considering region outlives bounds in the `leak_check`
For details on the `leak_check`, see the FCP proposal in #119820.[^leak_check]
[^leak_check]: which should get moved to the dev-guide once that PR lands :3
In both coherence and during candidate selection, the `leak_check` relies on the region constraints added in `evaluate`. It therefore currently does not register outlives obligations: [source](ccb1415eac/compiler/rustc_trait_selection/src/traits/select/mod.rs (L792-L810)). This was likely done as a performance optimization without considering its impact on the `leak_check`. This is the case as in the old solver, *evaluatation* and *fulfillment* are split, with evaluation being responsible for candidate selection and fulfillment actually registering all the constraints.
This split does not exist with the new solver. The `leak_check` can therefore eagerly detect errors caused by region outlives obligations. This improves both coherence itself and candidate selection:
```rust
// revisions: current next
//[next] compile-flags: -Znext-solver=coherence
trait LeakErr<'a, 'b> {}
// Using this impl adds an `'b: 'a` bound which results
// in a higher-ranked region error. This bound has been
// previously ignored but is now considered.
impl<'a, 'b: 'a> LeakErr<'a, 'b> for () {}
trait NoOverlapDir<'a> {}
impl<'a, T: for<'b> LeakErr<'a, 'b>> NoOverlapDir<'a> for T {}
impl<'a> NoOverlapDir<'a> for () {}
//[current]~^ ERROR conflicting implementations of trait `NoOverlapDir<'_>`
// --------------------------------------
// necessary to avoid coherence unknowable candidates
struct W<T>(T);
trait GuidesSelection<'a, U> {}
impl<'a, T: for<'b> LeakErr<'a, 'b>> GuidesSelection<'a, W<u32>> for T {}
impl<'a, T> GuidesSelection<'a, W<u8>> for T {}
trait NotImplementedByU8 {}
trait NoOverlapInd<'a, U> {}
impl<'a, T: GuidesSelection<'a, W<U>>, U> NoOverlapInd<'a, U> for T {}
impl<'a, U: NotImplementedByU8> NoOverlapInd<'a, U> for () {}
//[current]~^ conflicting implementations of trait `NoOverlapInd<'_, _>`
```
### Removal of `fn match_fresh_trait_refs`
The old solver tries to [eagerly detect unbounded recursion](b14fd2359f/compiler/rustc_trait_selection/src/traits/select/mod.rs (L1196-L1211)), forcing the affected goals to be ambiguous. This check is only an approximation and has not been added to the new solver.
The check is not necessary in the new solver and it would be problematic for caching. As it depends on all goals currently on the stack, using a global cache entry would have to always make sure that doing so does not circumvent this check.
This changes some goals to error - or succeed - instead of failing with ambiguity. This allows more code to compile:
```rust
// revisions: current next
//[next] compile-flags: -Znext-solver=coherence
// Need to use this local wrapper for the impls to be fully
// knowable as unknowable candidate result in ambiguity.
struct Local<T>(T);
trait Trait<U> {}
// This impl does not hold, but is ambiguous in the old
// solver due to its overflow approximation.
impl<U> Trait<U> for Local<u32> where Local<u16>: Trait<U> {}
// This impl holds.
impl Trait<Local<()>> for Local<u8> {}
// In the old solver, `Local<?t>: Trait<Local<?u>>` is ambiguous,
// resulting in `Local<?u>: NoImpl`, also being ambiguous.
//
// In the new solver the first impl does not apply, constraining
// `?u` to `Local<()>`, causing `Local<()>: NoImpl` to error.
trait Indirect<T> {}
impl<T, U> Indirect<U> for T
where
T: Trait<U>,
U: NoImpl
{}
// Not implemented for `Local<()>`
trait NoImpl {}
impl NoImpl for Local<u8> {}
impl NoImpl for Local<u16> {}
// `Local<?t>: Indirect<Local<?u>>` cannot hold, so
// these impls do not overlap.
trait NoOverlap<U> {}
impl<T: Indirect<U>, U> NoOverlap<U> for T {}
impl<T, U> NoOverlap<Local<U>> for Local<T> {}
//~^ ERROR conflicting implementations of trait `NoOverlap<Local<_>>`
```
### Non-fatal overflow
The old solver immediately emits a fatal error when hitting the recursion limit. The new solver instead returns overflow. This both allows more code to compile and is results in performance and potential future compatability issues.
Non-fatal overflow is generally desirable. With fatal overflow, changing the order in which we evaluate nested goals easily causes breakage if we have goal which errors and one which overflows. It is also required to prevent breakage due to the removal of `fn match_fresh_trait_refs`, e.g. [in `typenum`](https://github.com/rust-lang/trait-system-refactor-initiative/issues/73).
#### Enabling more code to compile
In the below example, the old solver first tried to prove an overflowing goal, resulting in a fatal error. The new solver instead returns ambiguity due to overflow for that goal, causing the implicit negative overlap check to succeed as `Box<u32>: NotImplemented` does not hold.
```rust
// revisions: current next
//[next] compile-flags: -Znext-solver=coherence
//[current] ERROR overflow evaluating the requirement
trait Indirect<T> {}
impl<T: Overflow<()>> Indirect<T> for () {}
trait Overflow<U> {}
impl<T, U> Overflow<U> for Box<T>
where
U: Indirect<Box<Box<T>>>,
{}
trait NotImplemented {}
trait Trait<U> {}
impl<T, U> Trait<U> for T
where
// T: NotImplemented, // causes old solver to succeed
U: Indirect<T>,
T: NotImplemented,
{}
impl Trait<()> for Box<u32> {}
```
#### Avoiding hangs with non-fatal overflow
Simply returning ambiguity when reaching the recursion limit can very easily result in hangs, e.g.
```rust
trait Recur {}
impl<T, U> Recur for ((T, U), (U, T))
where
(T, U): Recur,
(U, T): Recur,
{}
trait NotImplemented {}
impl<T: NotImplemented> Recur for T {}
```
This can happen quite frequently as it's easy to have exponential blowup due to multiple nested goals at each step. As the trait solver is depth-first, this immediately caused a fatal overflow error in the old solver. In the new solver we have to handle the whole proof tree instead, which can very easily hang.
To avoid this we restrict the recursion depth after hitting the recursion limit for the first time. We also **ignore all inference constraints from goals resulting in overflow**. This is mostly backwards compatible as any overflow in the old solver resulted in a fatal error.
### sidenote about normalization
We return ambiguous nested goals of `NormalizesTo` goals to the caller and ignore their impact when computing the `Certainty` of the current goal. See the [normalization chapter](https://rustc-dev-guide.rust-lang.org/solve/normalization.html) for more details.This means we apply constraints resulting from other nested goals and from equating the impl header when normalizing, even if a nested goal results in overflow. This is necessary to avoid breaking the following example:
```rust
trait Trait {
type Assoc;
}
struct W<T: ?Sized>(*mut T);
impl<T: ?Sized> Trait for W<W<T>>
where
W<T>: Trait,
{
type Assoc = ();
}
// `W<?t>: Trait<Assoc = u32>` does not hold as
// `Assoc` gets normalized to `()`. However, proving
// the where-bounds of the impl results in overflow.
//
// For this to continue to compile we must not discard
// constraints from normalizing associated types.
trait NoOverlap {}
impl<T: Trait<Assoc = u32>> NoOverlap for T {}
impl<T: ?Sized> NoOverlap for W<T> {}
```
#### Future compatability concerns
Non-fatal overflow results in some unfortunate future compatability concerns. Changing the approach to avoid more hangs by more strongly penalizing overflow can cause breakage as we either drop constraints or ignore candidates necessary to successfully compile. Weakening the overflow penalities instead allows more code to compile and strengthens inference while potentially causing more code to hang.
While the current approach is not perfect, we believe it to be good enough. We believe it to apply the necessary inference constraints to avoid breakage and expect there to not be any desirable patterns broken by our current penalities. Similarly we believe the current constraints to avoid most accidental hangs. Ignoring constraints of overflowing goals is especially useful, as it may allow major future optimizations to our overflow handling. See [this summary](https://hackmd.io/ATf4hN0NRY-w2LIVgeFsVg) and the linked documents in case you want to know more.
### changes to performance
In general, trait solving during coherence checking is not significant for performance. Enabling the next-generation trait solver in coherence does not impact our compile time benchmarks. We are still unable to compile the benchmark suite when fully enabling the new trait solver.
There are rare cases where the new solver has significantly worse performance due to non-fatal overflow, its reliance on fixpoint algorithms and the removal of the `fn match_fresh_trait_refs` approximation. We encountered such issues in [`typenum`](https://crates.io/crates/typenum) and believe it should be [pretty much as bad as it can get](https://github.com/rust-lang/trait-system-refactor-initiative/issues/73).
Due to an improved structure and far better caching, we believe that there is a lot of room for improvement and that the new solver will outperform the existing implementation in nearly all cases, sometimes significantly. We have not yet spent any time micro-optimizing the implementation and have many unimplemented major improvements, such as fast-paths for trivial goals.
TODO: get some rough results here and put them in a table
### Unstable features
#### Unsupported unstable features
The new solver currently does not support all unstable features, most notably `#![feature(generic_const_exprs)]`, `#![feature(associated_const_equality)]` and `#![feature(adt_const_params)]` are not yet fully supported in the new solver. We are confident that supporting them is possible, but did not consider this to be a priority. This stabilization introduces new ICE when using these features in impl headers.
#### fixes to `#![feature(specialization)]`
- fixes#105782
- fixes#118987
#### fixes to `#![feature(type_alias_impl_trait)]`
- fixes#119272
- https://github.com/rust-lang/rust/issues/105787#issuecomment-1750112388
- fixes#124207
## This does not stabilize the whole solver
While this stabilizes the use of the new solver in coherence checking, there are many parts of the solver which will remain fully unstable. We may still adapt these areas while working towards stabilizing the new solver everywhere. We are confident that we are able to do so without negatively impacting coherence.
### goals with a non-empty `ParamEnv`
Coherence always uses an empty environment. We therefore do not depend on the behavior of `AliasBound` and `ParamEnv` candidates. We only stabilizes the behavior of user-defined and builtin implementations of traits. There are still many open questions there.
### opaque types in the defining scope
The handling of opaque types - `impl Trait` - in both the new and old solver is still not fully figured out. Luckily this can be ignored for now. While opaque types are reachable during coherence checking by using `impl_trait_in_associated_types`, the behavior during coherence is separate and self-contained. The old and new solver fully agree here.
### normalization is hard
This stabilizes that we equate associated types involving bound variables using deferred-alias-equality. We also stop eagerly normalizing in coherence, which should not have any user-facing impact.
We do not stabilize the normalization behavior outside of coherence, e.g. we currently deeply normalize all types during writeback with the new solver. This may change going forward
### how to replace `select` from the old solver
We sometimes depend on getting a single `impl` for a given trait bound, e.g. when resolving a concrete method for codegen/CTFE. We do not depend on this during coherence, so the exact approach here can still be freely changed going forward.
## Acknowledgements
This work would not have been possible without `@compiler-errors.` He implemented large chunks of the solver himself but also and did a lot of testing and experimentation, eagerly discovering multiple issues which had a significant impact on our approach. `@BoxyUwU` has also done some amazing work on the solver. Thank you for the endless hours of discussion resulting in the current approach. Especially the way aliases are handled has gone through multiple revisions to get to its current state.
There were also many contributions from - and discussions with - other members of the community and the rest of `@rust-lang/types.` This solver builds upon previous improvements to the compiler, as well as lessons learned from `chalk` and `a-mir-formality`. Getting to this point would not have been possible without that and I am incredibly thankful to everyone involved. See the [list of relevant PRs](https://github.com/rust-lang/rust/pulls?q=is%3Apr+is%3Amerged+label%3AWG-trait-system-refactor+-label%3Arollup+closed%3A%3C2024-03-22+).
Check WF of source type's signature on fn pointer cast
This PR patches the implied bounds holes slightly for #129005, #25860.
Like most implied bounds related unsoundness fixes, this isn't complete w.r.t. higher-ranked function signatures, but I believe it implements a pretty good heuristic for now.
### What does this do?
This PR makes a partial patch for a soundness hole in a `FnDef` -> `FnPtr` "reifying" pointer cast where we were never checking that the signature we are casting *from* is actually well-formed. Because of this, and because `FnDef` doesn't require its signature to be well-formed (just its predicates must hold), we are essentially allowed to "cast away" implied bounds that are assumed within the body of the `FnDef`:
```
fn foo<'a, 'b, T>(_: &'a &'b (), v: &'b T) -> &'a T { v }
fn bad<'short, T>(x: &'short T) -> &'static T {
let f: fn(_, &'short T) -> &'static T = foo;
f(&&(), x)
}
```
In this example, subtyping ends up casting the `_` type (which should be `&'static &'short ()`) to some other type that no longer serves as a "witness" to the lifetime relationship `'short: 'static` which would otherwise be required for this call to be WF. This happens regardless of if `foo`'s lifetimes are early- or late-bound.
This PR implements two checks:
1. We check that the signature of the `FnDef` is well-formed *before* casting it. This ensures that there is at least one point in the MIR where we ensure that the `FnDef`'s implied bounds are actually satisfied by the caller.
2. Implements a special case where if we're casting from a higher-ranked `FnDef` to a non-higher-ranked, we instantiate the binder of the `FnDef` with *infer vars* and ensure that it is a supertype of the target of the cast.
The (2.) is necessary to validate that these pointer casts are valid for higher-ranked `FnDef`. Otherwise, the example above would still pass even if `help`'s `'a` lifetime were late-bound.
### Further work
The WF checks for function calls are scattered all over the MIR. We check the WF of args in call terminators, we check the WF of `FnDef` when we create a `const` operand referencing it, and we check the WF of the return type in #115538, to name a few.
One way to make this a bit cleaner is to simply extend #115538 to always check that the signature is WF for `FnDef` types. I may do this as a follow-up, but I wanted to keep this simple since this leads to some pretty bad NLL diagnostics regressions, and AFAICT this solution is *complete enough*.
### Crater triage
Done here: https://github.com/rust-lang/rust/pull/129021#issuecomment-2297702647
r? lcnr
fix ICE when `asm_const` and `const_refs_to_static` are combined
fixes https://github.com/rust-lang/rust/issues/129462fixes#126896fixes#124164
I think this is a case that was missed in the fix for https://github.com/rust-lang/rust/pull/125558, which inserts a type error in the case of an invalid (that is, non-integer) type being passed to an asm `const` operand.
I'm not 100% sure that `span_mirbug_and_err` is the right macro here, but it is used earlier with `builtin_deref` and seems to do the trick.
r? ``@lcnr``
Arbitrary self types v2: pointers feature gate.
The main `arbitrary_self_types` feature gate will shortly be reused for a new version of arbitrary self types which we are amending per [this RFC](https://github.com/rust-lang/rfcs/blob/master/text/3519-arbitrary-self-types-v2.md). The main amendments are:
* _do_ support `self` types which can't safely implement `Deref`
* do _not_ support generic `self` types
* do _not_ support raw pointers as `self` types.
This PR relates to the last of those bullet points: this strips pointer support from the current `arbitrary_self_types` feature. We expect this to cause some amount of breakage for crates using this unstable feature to allow raw pointer self types. If that's the case, we want to know about it, and we want crate authors to know of the upcoming changes.
For now, this can be resolved by adding the new
`arbitrary_self_types_pointers` feature to such crates. If we determine that use of raw pointers as self types is common, then we may maintain that as an unstable feature even if we come to stabilize the rest of the `arbitrary_self_types` support in future. If we don't hear that this PR is causing breakage, then perhaps we don't need it at all, even behind an unstable feature gate.
[Tracking issue](https://github.com/rust-lang/rust/issues/44874)
This is [step 4 of the plan outlined here](https://github.com/rust-lang/rust/issues/44874#issuecomment-2122179688)
Add target support for RTEMS Arm
# `armv7-rtems-eabihf`
This PR adds a new target for the RTEMS RTOS. To get things started it focuses on Xilinx/AMD Zynq-based targets, but in theory it should also support other armv7-based board support packages in the future.
Given that RTEMS has support for many POSIX functions it is mostly enabling corresponding unix features for the new target.
I also previously started a PR in libc (https://github.com/rust-lang/libc/pull/3561) to add the needed OS specific C-bindings and was told that a PR in this repo is needed first. I will update the PR to the newest version after approval here.
I will probably also need to change one line in the backtrace repo.
Current status is that I could compile rustc for the new target locally (with the updated libc and backtrace) and could compile binaries, link, and execute a simple "Hello World" RTEMS application for the target hardware.
> A proposed target or target-specific patch that substantially changes code shared with other targets (not just target-specific code) must be reviewed and approved by the appropriate team for that shared code before acceptance.
There should be no breaking changes for existing targets. Main changes are adding corresponding `cfg` switches for the RTEMS OS and adding the C binding in libc.
# Tier 3 target policy
> - A tier 3 target must have a designated developer or developers (the "target maintainers") on record to be CCed when issues arise regarding the target. (The mechanism to track and CC such developers may evolve over time.)
I will do the maintenance (for now) further members of the RTEMS community will most likely join once the first steps have been done.
> - Targets must use naming consistent with any existing targets; for instance, a target for the same CPU or OS as an existing Rust target should use the same name for that CPU or OS. Targets should normally use the same names and naming conventions as used elsewhere in the broader ecosystem beyond Rust (such as in other toolchains), unless they have a very good reason to diverge. Changing the name of a target can be highly disruptive, especially once the target reaches a higher tier, so getting the name right is important even for a tier 3 target.
> - Target names should not introduce undue confusion or ambiguity unless absolutely necessary to maintain ecosystem compatibility. For example, if the name of the target makes people extremely likely to form incorrect beliefs about what it targets, the name should be changed or augmented to disambiguate it.
> - If possible, use only letters, numbers, dashes and underscores for the name. Periods (`.`) are known to cause issues in Cargo.
The proposed triple is `armv7-rtems-eabihf`
> - Tier 3 targets may have unusual requirements to build or use, but must not create legal issues or impose onerous legal terms for the Rust project or for Rust developers or users.
> - The target must not introduce license incompatibilities.
> - Anything added to the Rust repository must be under the standard Rust license (`MIT OR Apache-2.0`).
> - The target must not cause the Rust tools or libraries built for any other host (even when supporting cross-compilation to the target) to depend on any new dependency less permissive than the Rust licensing policy. This applies whether the dependency is a Rust crate that would require adding new license exceptions (as specified by the `tidy` tool in the rust-lang/rust repository), or whether the dependency is a native library or binary. In other words, the introduction of the target must not cause a user installing or running a version of Rust or the Rust tools to be subject to any new license requirements.
> - Compiling, linking, and emitting functional binaries, libraries, or other code for the target (whether hosted on the target itself or cross-compiling from another target) must not depend on proprietary (non-FOSS) libraries. Host tools built for the target itself may depend on the ordinary runtime libraries supplied by the platform and commonly used by other applications built for the target, but those libraries must not be required for code generation for the target; cross-compilation to the target must not require such libraries at all. For instance, `rustc` built for the target may depend on a common proprietary C runtime library or console output library, but must not depend on a proprietary code generation library or code optimization library. Rust's license permits such combinations, but the Rust project has no interest in maintaining such combinations within the scope of Rust itself, even at tier 3.
> - "onerous" here is an intentionally subjective term. At a minimum, "onerous" legal/licensing terms include but are _not_ limited to: non-disclosure requirements, non-compete requirements, contributor license agreements (CLAs) or equivalent, "non-commercial"/"research-only"/etc terms, requirements conditional on the employer or employment of any particular Rust developers, revocable terms, any requirements that create liability for the Rust project or its developers or users, or any requirements that adversely affect the livelihood or prospects of the Rust project or its developers or users.
The tools consists of the cross-compiler toolchain (gcc-based). The RTEMS kernel (BSD license) and parts of the driver stack of FreeBSD (BSD license). All tools are FOSS and publicly available here: https://gitlab.rtems.org/rtems
There are also no new features or dependencies introduced to the Rust code.
> - Neither this policy nor any decisions made regarding targets shall create any binding agreement or estoppel by any party. If any member of an approving Rust team serves as one of the maintainers of a target, or has any legal or employment requirement (explicit or implicit) that might affect their decisions regarding a target, they must recuse themselves from any approval decisions regarding the target's tier status, though they may otherwise participate in discussions.
N/A to me. I am not a reviewer nor Rust team member.
> - Tier 3 targets should attempt to implement as much of the standard libraries as possible and appropriate (`core` for most targets, `alloc` for targets that can support dynamic memory allocation, `std` for targets with an operating system or equivalent layer of system-provided functionality), but may leave some code unimplemented (either unavailable or stubbed out as appropriate), whether because the target makes it impossible to implement or challenging to implement. The authors of pull requests are not obligated to avoid calling any portions of the standard library on the basis of a tier 3 target not implementing those portions.
`core` and `std` compile. Some advanced features of the `std` lib might not work yet. However, the goal of this tier 3 target it to make it easier for other people to build and run test applications to better identify the unsupported features and work towards enabling them.
> - The target must provide documentation for the Rust community explaining how to build for the target, using cross-compilation if possible. If the target supports running binaries, or running tests (even if they do not pass), the documentation must explain how to run such binaries or tests for the target, using emulation if possible or dedicated hardware if necessary.
Building is described in platform support doc. Running simple unit tests works. Running the test suite of the stdlib is currently not that easy. Trying to work towards that after the this target has been added to the nightly.
> - Tier 3 targets must not impose burden on the authors of pull requests, or other developers in the community, to maintain the target. In particular, do not post comments (automated or manual) on a PR that derail or suggest a block on the PR based on a tier 3 target. Do not send automated messages or notifications (via any medium, including via ````@`)``` to a PR author or others involved with a PR regarding a tier 3 target, unless they have opted into such messages.
Understood.
> - Backlinks such as those generated by the issue/PR tracker when linking to an issue or PR are not considered a violation of this policy, within reason. However, such messages (even on a separate repository) must not generate notifications to anyone involved with a PR who has not requested such notifications.
Ok
> - Patches adding or updating tier 3 targets must not break any existing tier 2 or tier 1 target, and must not knowingly break another tier 3 target without approval of either the compiler team or the maintainers of the other tier 3 target.
> - In particular, this may come up when working on closely related targets, such as variations of the same architecture with different features. Avoid introducing unconditional uses of features that another variation of the target may not have; use conditional compilation or runtime detection, as appropriate, to let each target run code supported by that target.
I think, I didn't add any breaking changes for any existing targets (see the comment regarding features above).
> - Tier 3 targets must be able to produce assembly using at least one of rustc's supported backends from any host target.
Can produce assembly code via the llvm backend (tested on Linux).
>
> If a tier 3 target stops meeting these requirements, or the target maintainers no longer have interest or time, or the target shows no signs of activity and has not built for some time, or removing the target would improve the quality of the Rust codebase, we may post a PR to remove it; any such PR will be CCed to the target maintainers (and potentially other people who have previously worked on the target), to check potential interest in improving the situation.GIAt this tier, the Rust project provides no official support for a target, so we place minimal requirements on the introduction of targets.
Understood.
r? compiler-team
enable -Zrandomize-layout in debug CI builds
This builds rustc/libs/tools with `-Zrandomize-layout` on *-debug CI runners.
Only a handful of tests and asserts break with that enabled, which is promising. One test was fixable, the rest is dealt with by disabling them through new cargo features or compiletest directives.
The config.toml flag `rust.randomize-layout` defaults to false, so it has to be explicitly enabled for now.
Rollup of 9 pull requests
Successful merges:
- #127692 (Suggest `impl Trait` for References to Bare Trait in Function Header)
- #128701 (Don't Suggest Labeling `const` and `unsafe` Blocks )
- #128934 (Non-exhaustive structs may be empty)
- #129630 (Document the broken C ABI of `wasm32-unknown-unknown`)
- #129863 (update comment regarding TargetOptions.features)
- #129896 (do not attempt to prove unknowable goals)
- #129926 (Move `SanityCheck` and `MirPass`)
- #129928 (rustc_driver_impl: remove some old dead logic)
- #129930 (include 1.80.1 release notes on master)
r? `@ghost`
`@rustbot` modify labels: rollup
do not attempt to prove unknowable goals
In case a goal is unknowable, we previously still checked all other possible ways to prove this goal, even though its final result is already guaranteed to be ambiguous. By ignoring all other candidates in that case we can avoid a lot of unnecessary work, fixing the performance regression in typenum found in #121848.
This is already the behavior in the old solver. This could in theory cause future-compatability issues as considering fewer goals unknowable may end up causing performance regressions/hangs. I am quite confident that this will not be an issue.
r? ``@compiler-errors``
Non-exhaustive structs may be empty
This is a follow-up to a discrepancy noticed in https://github.com/rust-lang/rust/pull/122792: today, the following struct is considered inhabited (non-empty) outside its defining crate:
```rust
#[non_exhaustive]
pub struct UninhabitedStruct {
pub never: !,
// other fields
}
```
`#[non_exhaustive]` on a struct should mean that adding fields to it isn't a breaking change. There is no way that adding fields to this struct could make it non-empty since the `never` field must stay and is inconstructible. I suspect this was implemented this way due to confusion with `#[non_exhaustive]` enums, which indeed should be considered non-empty outside their defining crate.
I propose that we consider such a struct uninhabited (empty), just like it would be without the `#[non_exhaustive]` annotation.
Code that doesn't pass today and will pass after this:
```rust
// In a different crate
fn empty_match_on_empty_struct<T>(x: UninhabitedStruct) -> T {
match x {}
}
```
This is not a breaking change.
r? ``@compiler-errors``
Don't Suggest Labeling `const` and `unsafe` Blocks
Fixes#128604
Previously, both anonymous constant blocks (E.g. The labeled block
inside `['_'; 'block: { break 'block 1 + 2; }]`) and inline const
blocks (E.g. `const { ... }`) were considered to be the same
kind of blocks. This caused the compiler to incorrectly suggest
labeling both the blocks when only anonymous constant blocks can be
labeled.
This PR adds an other enum variant to `Context` so that both the
blocks can be handled appropriately.
Also, adds some doc comments and removes unnecessary `&mut` in a
couple of places.
Suggest `impl Trait` for References to Bare Trait in Function Header
Fixes#125139
This PR suggests `impl Trait` when `&Trait` is found as a function parameter type or return type. This makes use of existing diagnostics by adding `peel_refs()` when checking for type equality.
Additionaly, it makes a few other improvements:
1. Checks if functions inside impl blocks have bare trait in their headers.
2. Introduces a trait `NextLifetimeParamName` similar to the existing `NextTypeParamName` for suggesting a lifetime name. Also, abstracts out the common logic between the two trait impls.
### Related Issues
I ran into a bunch of related diagnostic issues but couldn't fix them within the scope of this PR. So, I have created the following issues:
1. [Misleading Suggestion when Returning a Reference to a Bare Trait from a Function](https://github.com/rust-lang/rust/issues/127689)
2. [Verbose Error When a Function Takes a Bare Trait as Parameter](https://github.com/rust-lang/rust/issues/127690)
3. [Incorrect Suggestion when Returning a Bare Trait from a Function](https://github.com/rust-lang/rust/issues/127691)
r? ```@estebank``` since you implemented #119148
Replace walk with visit so we dont skip outermost expr kind in def collector
This affects async closures with macros as their body expr. Fixes#129855.
r? ``@cjgillot`` or anyone else
Rewrite lint_expectations in a single pass.
This PR aims at reducing the perf regression from https://github.com/rust-lang/rust/pull/120924#issuecomment-2202486203 with drive-by simplifications.
Basically, instead of using the lint level builder, which is slow, this PR splits `lint_expectations` logic in 2:
- listing the `LintExpectations` is done in `shallow_lint_levels_on`, on a per-owner basis;
- building the unstable->stable expectation id map is done by iterating on attributes.
r? ghost for perf
Rollup of 11 pull requests
Successful merges:
- #128523 (Add release notes for 1.81.0)
- #129605 (Add missing `needs-llvm-components` directives for run-make tests that need target-specific codegen)
- #129650 (Clean up `library/profiler_builtins/build.rs`)
- #129651 (skip stage 0 target check if `BOOTSTRAP_SKIP_TARGET_SANITY` is set)
- #129684 (Enable Miri to pass pointers through FFI)
- #129762 (Update the `wasm-component-ld` binary dependency)
- #129782 (couple more crash tests)
- #129816 (tidy: say which feature gate has a stability issue mismatch)
- #129818 (make the const-unstable-in-stable error more clear)
- #129824 (Fix code examples buttons not appearing on click on mobile)
- #129826 (library: Fix typo in `core::mem`)
r? `@ghost`
`@rustbot` modify labels: rollup
make the const-unstable-in-stable error more clear
The default should be to add `rustc_const_unstable`, not `rustc_allow_const_fn_unstable`.
Also I discovered our check for missing const stability attributes on stable functions -- but strangely that check only kicks in for "reachable" functions. `check_missing_stability` checks for reachability since all reachable functions must have a stability attribute, but I would say if a function has `#[stable]` it should also have const-stability attributes regardless of reachability.
Make the "detect-old-time" UI test more representative
The test code did have an inference failure, but that would have failed
on Rust 1.79 and earlier too. Now it is rewritten to be specifically
affected by 1.80's `impl FromIterator<_> for Box<str>`.
const fn stability checking: also check declared language features
Fixes https://github.com/rust-lang/rust/issues/129656
`@oli-obk` I assume it is just an oversight that this didn't use `features().declared()`? Or is there a deep reason that this must only check `declared_lib_features`?
Don't make statement nonterminals match pattern nonterminals
Right now, the heuristic we use to check if a token may begin a pattern nonterminal falls back to `may_be_ident`:
ef71f1047e/compiler/rustc_parse/src/parser/nonterminal.rs (L21-L37)
This has the unfortunate side effect that a `stmt` nonterminal eagerly matches against a `pat` nonterminal, leading to a parse error:
```rust
macro_rules! m {
($pat:pat) => {};
($stmt:stmt) => {};
}
macro_rules! m2 {
($stmt:stmt) => {
m! { $stmt }
};
}
m2! { let x = 1 }
```
This PR fixes it by more accurately reflecting the set of nonterminals that may begin a pattern nonterminal.
As a side-effect, I modified `Token::can_begin_pattern` to work correctly and used that in `Parser::nonterminal_may_begin_with`.
The test code did have an inference failure, but that would have failed
on Rust 1.79 and earlier too. Now it is rewritten to be specifically
affected by 1.80's `impl FromIterator<_> for Box<str>`.
debug-fmt-detail option
I'd like to propose a new option that makes `#[derive(Debug)]` generate no-op implementations that don't print anything, and makes `{:?}` in format strings a no-op.
There are a couple of motivations for this:
1. A more thorough stripping of debug symbols. Binaries stripped of debug symbols still retain some of them through `Debug` implementations. It's hard to avoid that without compiler's help, because debug formatting can be used in many places, including dependencies, and their loggers, asserts, panics, etc.
* In my testing it gives about 2% binary size reduction on top of all other binary-minimizing best practices (including `panic_immediate_abort`). There are targets like Web WASM or embedded where users pay attention to binary sizes.
* Users distributing closed-source binaries may not want to "leak" any symbol names as a matter of principle.
2. Adds ability to test whether code depends on specifics of the `Debug` format implementation in unwise ways (e.g. trying to get data unavailable via public interface, or using it as a serialization format). Because current Rust's debug implementation doesn't change, there's a risk of it becoming a fragile de-facto API that [won't be possible to change in the future](https://www.hyrumslaw.com/). An option that "breaks" it can act as a [grease](https://www.rfc-editor.org/rfc/rfc8701.html).
This implementation is a `-Z fmt-debug=opt` flag that takes:
* `full` — the default, current state.
* `none` — makes derived `Debug` and `{:?}` no-ops. Explicit `impl Debug for T` implementations are left unharmed, but `{:?}` format won't use them, so they may get dead-code eliminated if they aren't invoked directly.
* `shallow` — makes derived `Debug` print only the type's name, without recursing into fields. Fieldless enums print their variant names. `{:?}` works.
The `shallow` option is a compromise between minimizing the `Debug` code, and compatibility. There are popular proc-macro crates that use `Debug::fmt` as a way to convert enum values into their Rust source code.
There's a corresponding `cfg` flag: `#[cfg(fmt_debug = "none")]` that can be used in user code to react to this setting to minimize custom `Debug` implementations or remove unnecessary formatting helper functions.
derive(SmartPointer): assume pointee from the single generic and better error messages
Fix#129465
Actually RFC says that `#[pointee]` can be inferred when there is no ambiguity, or there is only one generic type parameter so to say.
cc ```@Darksonn```
r? ```@compiler-errors```
Emit specific message for time<=0.3.35
```
error[E0282]: type annotations needed for `Box<_>`
--> /home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/time-0.3.34/src/format_description/parse/mod.rs:83:9
|
83 | let items = format_items
| ^^^^^
...
86 | Ok(items.into())
| ---- type must be known at this point
|
= note: this is an inference error on `time` caused by a change in Rust 1.80.0; update `time` to version `>=0.3.36`
```
Partially mitigate the fallout from https://github.com/rust-lang/rust/issues/127343. Although the biggest benefit of this would have been if we had had this in 1.80 before it became stable, the long-tail of that change will be felt for a *long* time, so better late than never.
We can also emit an even more targeted error instead of this inference failure.
rustc_target: Add various aarch64 features
Add various aarch64 features already supported by LLVM and Linux.
Additionally include some comment fixes to ensure consistency of feature names with the Arm ARM.
Compiler support for features added to stdarch by https://github.com/rust-lang/stdarch/pull/1614.
Tracking issue for unstable aarch64 features is https://github.com/rust-lang/rust/issues/127764.
List of added features:
- FEAT_CSSC
- FEAT_ECV
- FEAT_FAMINMAX
- FEAT_FLAGM2
- FEAT_FP8
- FEAT_FP8DOT2
- FEAT_FP8DOT4
- FEAT_FP8FMA
- FEAT_HBC
- FEAT_LSE128
- FEAT_LSE2
- FEAT_LUT
- FEAT_MOPS
- FEAT_LRCPC3
- FEAT_SVE_B16B16
- FEAT_SVE2p1
- FEAT_WFxT
- FEAT_SME
- FEAT_SME_F16F16
- FEAT_SME_F64F64
- FEAT_SME_F8F16
- FEAT_SME_F8F32
- FEAT_SME_FA64
- FEAT_SME_I16I64
- FEAT_SME_LUTv2
- FEAT_SME2
- FEAT_SME2p1
- FEAT_SSVE_FP8DOT2
- FEAT_SSVE_FP8DOT4
- FEAT_SSVE_FP8FMA
FEAT_FPMR is added in the first commit and then removed in a separate one to highlight it being removed from upstream LLVM 19. The intention is for it to be detectable at runtime through stdarch but not have a corresponding Rust compile-time feature.
Implement a first version of RFC 3525: struct target features
This PR is an attempt at implementing https://github.com/rust-lang/rfcs/pull/3525, behind a feature gate `struct_target_features`.
There's obviously a few tasks that ought to be done before this is merged; in no particular order:
- add proper error messages
- add tests
- create a tracking issue for the RFC
- properly serialize/deserialize the new target_features field in `rmeta` (assuming I even understood that correctly :-))
That said, as I am definitely not a `rustc` expert, I'd like to get some early feedback on the overall approach before fixing those things (and perhaps some pointers for `rmeta`...), hence this early PR :-)
Here's an example piece of code that I have been using for testing - with the new code, the calls to intrinsics get correctly inlined:
```rust
#![feature(struct_target_features)]
use std::arch::x86_64::*;
/*
// fails to compile
#[target_feature(enable = "avx")]
struct Invalid(u32);
*/
#[target_feature(enable = "avx")]
struct Avx {}
#[target_feature(enable = "sse")]
struct Sse();
/*
// fails to compile
extern "C" fn bad_fun(_: Avx) {}
*/
/*
// fails to compile
#[inline(always)]
fn inline_fun(_: Avx) {}
*/
trait Simd {
fn do_something(&self);
}
impl Simd for Avx {
fn do_something(&self) {
unsafe {
println!("{:?}", _mm256_setzero_ps());
}
}
}
impl Simd for Sse {
fn do_something(&self) {
unsafe {
println!("{:?}", _mm_setzero_ps());
}
}
}
struct WithAvx {
#[allow(dead_code)]
avx: Avx,
}
impl Simd for WithAvx {
fn do_something(&self) {
unsafe {
println!("{:?}", _mm256_setzero_ps());
}
}
}
#[inline(never)]
fn dosomething<S: Simd>(simd: &S) {
simd.do_something();
}
fn main() {
/*
// fails to compile
Avx {};
*/
if is_x86_feature_detected!("avx") {
let avx = unsafe { Avx {} };
dosomething(&avx);
dosomething(&WithAvx { avx });
}
if is_x86_feature_detected!("sse") {
dosomething(&unsafe { Sse {} })
}
}
```
Tracking:
- https://github.com/rust-lang/rust/issues/129107
```
error[E0282]: type annotations needed for `Box<_>`
--> ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/time-0.3.34/src/format_description/parse/mod.rs:83:9
|
83 | let items = format_items
| ^^^^^
...
86 | Ok(items.into())
| ---- type must be known at this point
|
= note: this is an inference error on crate `time` caused by a change in Rust 1.80.0; update `time` to version `>=0.3.35`
```
Partially address #127343.
Rename `BikeshedIntrinsicFrom` to `TransmuteFrom`
As our implementation of MCP411 nears completion and we begin to solicit testing, it's no longer reasonable to expect testers to type or remember `BikeshedIntrinsicFrom`. The name degrades the ease-of-reading of documentation, and the overall experience of using compiler safe transmute.
Tentatively, we'll instead adopt `TransmuteFrom`.
This name seems to be the one most likely to be stabilized, after discussion on Zulip [1]. We may want to revisit the ordering of `Src` and `Dst` before stabilization, at which point we'd likely consider `TransmuteInto` or `Transmute`.
[1] https://rust-lang.zulipchat.com/#narrow/stream/216762-project-safe-transmute/topic/What.20should.20.60BikeshedIntrinsicFrom.60.20be.20named.3F
Tracking Issue: https://github.com/rust-lang/rust/issues/99571
r? `@compiler-errors`
interpret: do not make const-eval query result depend on tcx.sess
The check against calling functions with missing target features uses `tcx.sess` to determine which target features are available. However, this can differ between different crates in a crate graph, so the same const-eval query can come to different conclusions about whether a constant evaluates successfully or not -- which is bad, we should consistently get the same result everywhere.
add repr to the allowlist for naked functions
Fixes#129412 (combining unstable features #90957 (`#![feature(naked_functions)]`) and #82232 (`#![feature(fn_align)]`)
Get rid of `predicates_defined_on`
This is the uncontroversial part of #129532. This simply inlines the `predicates_defined_on` into into `predicates_of`. Nothing should change here logically.
Stop storing a special inner body for the coroutine by-move body for async closures
...and instead, just synthesize an item which is treated mostly normally by the MIR pipeline.
This PR does a few things:
* We synthesize a new `DefId` for the by-move body of a closure, which has its `mir_built` fed with the output of the `ByMoveBody` MIR transformation, and some other relevant queries.
* This has the `DefKind::ByMoveBody`, which we use to distinguish it from "real" bodies (that come from HIR) which need to be borrowck'd. Introduce `TyCtxt::is_synthetic_mir` to skip over `mir_borrowck` which is called by `mir_promoted`; borrowck isn't really possible to make work ATM since it heavily relies being called on a body generated from HIR, and is redundant by the construction of the by-move-body.
* Remove the special `PassManager` hacks for handling the inner `by_move_body` stored within the coroutine's mir body. Instead, this body is fed like a regular MIR body, so it's goes through all of the `tcx.*_mir` stages normally (build -> promoted -> ...etc... -> optimized) ✨.
* Remove the `InstanceKind::ByMoveBody` shim, since now we have a "regular" def id, we can just use `InstanceKind::Item`. This also allows us to remove the corresponding hacks from codegen, such as in `fn_sig_for_fn_abi` ✨.
Notable remarks:
* ~~I know it's kind of weird to be using `DefKind::Closure` here, since it's not a distinct closure but just a new MIR body. I don't believe it really matters, but I could also use a different `DefKind`... maybe one that we could use for synthetic MIR bodies in general?~~ edit: We're doing this now.
The main `arbitrary_self_types` feature gate will shortly be reused for
a new version of arbitrary self types which we are amending per [this
RFC](https://github.com/rust-lang/rfcs/blob/master/text/3519-arbitrary-self-types-v2.md).
The main amendments are:
* _do_ support `self` types which can't safely implement `Deref`
* do _not_ support generic `self` types
* do _not_ support raw pointers as `self` types.
This PR relates to the last of those bullet points: this strips pointer
support from the current `arbitrary_self_types` feature.
We expect this to cause some amount of breakage for crates using this
unstable feature to allow raw pointer self types. If that's the case, we
want to know about it, and we want crate authors to know of the upcoming
changes.
For now, this can be resolved by adding the new
`arbitrary_self_types_pointers` feature to such crates. If we determine
that use of raw pointers as self types is common, then we may maintain
that as an unstable feature even if we come to stabilize the rest of the
`arbitrary_self_types` support in future. If we don't hear that this PR
is causing breakage, then perhaps we don't need it at all, even behind
an unstable feature gate.
[Tracking issue](https://github.com/rust-lang/rust/issues/44874)
This is [step 4 of the plan outlined here](https://github.com/rust-lang/rust/issues/44874#issuecomment-2122179688)
make it possible to enable const_precise_live_drops per-function
This makes const_precise_live_drops work with rustc_allow_const_fn_unstable so that we can stabilize individual functions that rely on const_precise_live_drops.
The goal is that we can use that to stabilize some of https://github.com/rust-lang/rust/issues/67441 without having to stabilize const_precise_live_drops.
As our implementation of MCP411 nears completion and we begin to
solicit testing, it's no longer reasonable to expect testers to
type or remember `BikeshedIntrinsicFrom`. The name degrades the
ease-of-reading of documentation, and the overall experience of
using compiler safe transmute.
Tentatively, we'll instead adopt `TransmuteFrom`.
This name seems to be the one most likely to be stabilized, after
discussion on Zulip [1]. We may want to revisit the ordering of
`Src` and `Dst` before stabilization, at which point we'd likely
consider `TransmuteInto` or `Transmute`.
[1] https://rust-lang.zulipchat.com/#narrow/stream/216762-project-safe-transmute/topic/What.20should.20.60BikeshedIntrinsicFrom.60.20be.20named.3F
Add various aarch64 features already supported by LLVM and Linux.
The features are marked as unstable using a newly added symbol, i.e.
aarch64_unstable_target_feature.
Additionally include some comment fixes to ensure consistency of
feature names with the Arm ARM and support for architecture version
target features up to v9.5a.
This commit adds compiler support for the following features:
- FEAT_CSSC
- FEAT_ECV
- FEAT_FAMINMAX
- FEAT_FLAGM2
- FEAT_FP8
- FEAT_FP8DOT2
- FEAT_FP8DOT4
- FEAT_FP8FMA
- FEAT_FPMR
- FEAT_HBC
- FEAT_LSE128
- FEAT_LSE2
- FEAT_LUT
- FEAT_MOPS
- FEAT_LRCPC3
- FEAT_SVE_B16B16
- FEAT_SVE2p1
- FEAT_WFxT