Arbitrary self types v2: (unused) Receiver trait
This commit contains a new `Receiver` trait, which is the basis for the Arbitrary Self Types v2 RFC. This allows smart pointers to be method receivers even if they're not Deref.
This is currently unused by the compiler - a subsequent PR will start to use this for method resolution if the `arbitrary_self_types` feature gate is enabled. This is being landed first simply to make review simpler: if people feel this should all be in an atomic PR let me know.
This is a part of the arbitrary self types v2 project, https://github.com/rust-lang/rfcs/pull/3519https://github.com/rust-lang/rust/issues/44874
r? `@wesleywiser`
remove const-support for align_offset and is_aligned
As part of the recent discussion to stabilize `ptr.is_null()` in const context, the general vibe was that it's okay for a const function to panic when the same operation would work at runtime (that's just a case of "dynamically detecting that something is not supported as a const operation"), but it is *not* okay for a const function to just return a different result.
Following that, `is_aligned` and `is_aligned_to` have their const status revoked in this PR, since they do return actively wrong results at const time. In the future we can consider having a new intrinsic or so that can check whether a pointer is "guaranteed to be aligned", but the current implementation based on `align_offset` does not have the behavior we want.
In fact `align_offset` itself behaves quite strangely in const, and that support needs a bunch of special hacks. That doesn't seem worth it. Instead, the users that can fall back to a different implementation should just use const_eval_select directly, and everything else should not be made const-callable. So this PR does exactly that, and entirely removes const support for align_offset.
Closes some tracking issues by removing the associated features:
Closes https://github.com/rust-lang/rust/issues/90962
Closes https://github.com/rust-lang/rust/issues/104203
Cc `@rust-lang/wg-const-eval` `@rust-lang/libs-api`
Operations like is_aligned would return actively wrong results at compile-time,
i.e. calling it on the same pointer at compiletime and runtime could yield
different results. That's no good.
Instead of having hacks to make align_offset kind-of work in const-eval, just
use const_eval_select in the few places where it makes sense, which also ensures
those places are all aware they need to make sure the fallback behavior is
consistent.
This commit contains a new Receiver trait, which is the basis for the
Arbitrary Self Types v2 RFC. This allows smart pointers to be method
receivers even if they're not Deref.
This is currently unused by the compiler - a subsequent PR will start to
use this for method resolution if the arbitrary_self_types feature gate
is enabled. This is being landed first simply to make review
simpler: if people feel this should all be in an atomic PR let me know.
This is a part of the arbitrary self types v2 project,
https://github.com/rust-lang/rfcs/pull/3519https://github.com/rust-lang/rust/issues/44874
r? @wesleywiser
Rename Receiver -> LegacyReceiver
As part of the "arbitrary self types v2" project, we are going to replace the current `Receiver` trait with a new mechanism based on a new, different `Receiver` trait.
This PR renames the old trait to get it out the way. Naming is hard. Options considered included:
* HardCodedReceiver (because it should only be used for things in the standard library, and hence is sort-of hard coded)
* LegacyReceiver
* TargetLessReceiver
* OldReceiver
These are all bad names, but fortunately this will be temporary. Assuming the new mechanism proceeds to stabilization as intended, the legacy trait will be removed altogether.
Although we expect this trait to be used only in the standard library, we suspect it may be in use elsehwere, so we're landing this change separately to identify any surprising breakages.
It's known that this trait is used within the Rust for Linux project; a patch is in progress to remove their dependency.
This is a part of the arbitrary self types v2 project,
https://github.com/rust-lang/rfcs/pull/3519https://github.com/rust-lang/rust/issues/44874
r? `@wesleywiser`
As part of the "arbitrary self types v2" project, we are going to
replace the current `Receiver` trait with a new mechanism based on a
new, different `Receiver` trait.
This PR renames the old trait to get it out the way. Naming is hard.
Options considered included:
* HardCodedReceiver (because it should only be used for things in the
standard library, and hence is sort-of hard coded)
* LegacyReceiver
* TargetLessReceiver
* OldReceiver
These are all bad names, but fortunately this will be temporary.
Assuming the new mechanism proceeds to stabilization as intended, the
legacy trait will be removed altogether.
Although we expect this trait to be used only in the standard library,
we suspect it may be in use elsehwere, so we're landing this change
separately to identify any surprising breakages.
It's known that this trait is used within the Rust for Linux project; a
patch is in progress to remove their dependency.
This is a part of the arbitrary self types v2 project,
https://github.com/rust-lang/rfcs/pull/3519https://github.com/rust-lang/rust/issues/44874
r? @wesleywiser
Rollup of 9 pull requests
Successful merges:
- #122670 (Fix bug where `option_env!` would return `None` when env var is present but not valid Unicode)
- #131095 (Use environment variables instead of command line arguments for merged doctests)
- #131339 (Expand set_ptr_value / with_metadata_of docs)
- #131652 (Move polarity into `PolyTraitRef` rather than storing it on the side)
- #131675 (Update lint message for ABI not supported)
- #131681 (Fix up-to-date checking for run-make tests)
- #131702 (Suppress import errors for traits that couldve applied for method lookup error)
- #131703 (Resolved python deprecation warning in publish_toolstate.py)
- #131710 (Remove `'apostrophes'` from `rustc_parse_format`)
r? `@ghost`
`@rustbot` modify labels: rollup
Add `&pin (mut|const) T` type position sugar
This adds parser support for `&pin mut T` and `&pin const T` references. These are desugared to `Pin<&mut T>` and `Pin<&T>` in the AST lowering phases.
This PR currently includes #130526 since that one is in the commit queue. Only the most recent commits (bd450027eb4a94b814a7dd9c0fa29102e6361149 and following) are new.
Tracking:
- #130494
r? `@compiler-errors`
Fix a few relative paths in rustc doc
## Changes
- Don't inline the doc for re-exporting some structs that have relative paths in doc.
## Context
See #124028.
- Most of the relative links in rustdoc are there because of circular import (so syntax like `[MyType]: rustc_foo::bar` is difficult to achieve when we cannot import `rustc_xxx` due to circular import)
- Here, I disable new links for re-exports. I think it's fine for re-exported items in `hir::*`.
- There is a few more relative links in other `rustc` crates, however they are not addressed in this PR, as they are not re-exported and/so the relative paths are working.
Closes#124028.
r? `@fmease`
Let me know if I miss anything or there's any other way to address this issue.
Introduce `structurally_normalize_const`, use it in `rustc_hir_typeck`
Introduces `structurally_normalize_const` to typecking to separate the "eval a const" step from the "try to turn a valtree into a target usize" in HIR typeck, where we may still have infer vars and stuff around.
I also changed `check_expr_repeat` to move a double evaluation of a const into a single one. I'll leave inline comments.
r? ```@BoxyUwU```
I hesitated to really test this on the new solver where it probably matters for unevaluated consts. If you're worried about the side-effects, I'd be happy to craft some more tests 😄
For example, the two following statements are desugared into a block
whose `LetStmt` source is `AssignDesugar`:
```rust
_ = ignoring_some_result();
(a, b) = (b, a);
```
Make sure that def id <=> lang item map is bidirectional
Self-explanatory from assertion. Just makes sure of an invariant that I forgot to enforce when I added `LanguageItems::from_def_id`.
Use the same precedence for all macro-like exprs
No need to make these have a different precedence since they're all written like `whatever!(expr)`, and it makes it simpler when adding new macro-based built-in operators in the future.
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.
Stabilize opaque type precise capturing (RFC 3617)
This PR partially stabilizes opaque type *precise capturing*, which was specified in [RFC 3617](https://github.com/rust-lang/rfcs/pull/3617), and whose syntax was amended by FCP in [#125836](https://github.com/rust-lang/rust/issues/125836).
This feature, as stabilized here, gives us a way to explicitly specify the generic lifetime parameters that an RPIT-like opaque type captures. This solves the problem of overcapturing, for lifetime parameters in these opaque types, and will allow the Lifetime Capture Rules 2024 ([RFC 3498](https://github.com/rust-lang/rfcs/pull/3498)) to be fully stabilized for RPIT in Rust 2024.
### What are we stabilizing?
This PR stabilizes the use of a `use<'a, T>` bound in return-position impl Trait opaque types. Such a bound fully specifies the set of generic parameters captured by the RPIT opaque type, entirely overriding the implicit default behavior. E.g.:
```rust
fn does_not_capture<'a, 'b>() -> impl Sized + use<'a> {}
// ~~~~~~~~~~~~~~~~~~~~
// This RPIT opaque type does not capture `'b`.
```
The way we would suggest thinking of `impl Trait` types *without* an explicit `use<..>` bound is that the `use<..>` bound has been *elided*, and that the bound is filled in automatically by the compiler according to the edition-specific capture rules.
All non-`'static` lifetime parameters, named (i.e. non-APIT) type parameters, and const parameters in scope are valid to name, including an elided lifetime if such a lifetime would also be valid in an outlives bound, e.g.:
```rust
fn elided(x: &u8) -> impl Sized + use<'_> { x }
```
Lifetimes must be listed before type and const parameters, but otherwise the ordering is not relevant to the `use<..>` bound. Captured parameters may not be duplicated. For now, only one `use<..>` bound may appear in a bounds list. It may appear anywhere within the bounds list.
### How does this differ from the RFC?
This stabilization differs from the RFC in one respect: the RFC originally specified `use<'a, T>` as syntactically part of the RPIT type itself, e.g.:
```rust
fn capture<'a>() -> impl use<'a> Sized {}
```
However, settling on the final syntax was left as an open question. T-lang later decided via FCP in [#125836](https://github.com/rust-lang/rust/issues/125836) to treat `use<..>` as a syntactic bound instead, e.g.:
```rust
fn capture<'a>() -> impl Sized + use<'a> {}
```
### What aren't we stabilizing?
The key goal of this PR is to stabilize the parts of *precise capturing* that are needed to enable the migration to Rust 2024.
There are some capabilities of *precise capturing* that the RFC specifies but that we're not stabilizing here, as these require further work on the type system. We hope to lift these limitations later.
The limitations that are part of this PR were specified in the [RFC's stabilization strategy](https://rust-lang.github.io/rfcs/3617-precise-capturing.html#stabilization-strategy).
#### Not capturing type or const parameters
The RFC addresses the overcapturing of type and const parameters; that is, it allows for them to not be captured in opaque types. We're not stabilizing that in this PR. Since all in scope generic type and const parameters are implicitly captured in all editions, this is not needed for the migration to Rust 2024.
For now, when using `use<..>`, all in scope type and const parameters must be nameable (i.e., APIT cannot be used) and included as arguments. For example, this is an error because `T` is in scope and not included as an argument:
```rust
fn test<T>() -> impl Sized + use<> {}
//~^ ERROR `impl Trait` must mention all type parameters in scope in `use<...>`
```
This is due to certain current limitations in the type system related to how generic parameters are represented as captured (i.e. bivariance) and how inference operates.
We hope to relax this in the future, and this stabilization is forward compatible with doing so.
#### Precise capturing for return-position impl Trait **in trait** (RPITIT)
The RFC specifies precise capturing for RPITIT. We're not stabilizing that in this PR. Since RPITIT already adheres to the Lifetime Capture Rules 2024, this isn't needed for the migration to Rust 2024.
The effect of this is that the anonymous associated types created by RPITITs must continue to capture all of the lifetime parameters in scope, e.g.:
```rust
trait Foo<'a> {
fn test() -> impl Sized + use<Self>;
//~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
}
```
To allow this involves a meaningful amount of type system work related to adding variance to GATs or reworking how generics are represented in RPITITs. We plan to do this work separately from the stabilization. See:
- https://github.com/rust-lang/rust/pull/124029
Supporting precise capturing for RPITIT will also require us to implement a new algorithm for detecting refining capture behavior. This may involve looking through type parameters to detect cases where the impl Trait type in an implementation captures fewer lifetimes than the corresponding RPITIT in the trait definition, e.g.:
```rust
trait Foo {
fn rpit() -> impl Sized + use<Self>;
}
impl<'a> Foo for &'a () {
// This is "refining" due to not capturing `'a` which
// is implied by the trait's `use<Self>`.
fn rpit() -> impl Sized + use<>;
// This is not "refining".
fn rpit() -> impl Sized + use<'a>;
}
```
This stabilization is forward compatible with adding support for this later.
### The technical details
This bound is purely syntactical and does not lower to a [`Clause`](https://doc.rust-lang.org/1.79.0/nightly-rustc/rustc_middle/ty/type.ClauseKind.html) in the type system. For the purposes of the type system (and for the types team's curiosity regarding this stabilization), we have no current need to represent this as a `ClauseKind`.
Since opaques already capture a variable set of lifetimes depending on edition and their syntactical position (e.g. RPIT vs RPITIT), a `use<..>` bound is just a way to explicitly rather than implicitly specify that set of lifetimes, and this only affects opaque type lowering from AST to HIR.
### FCP plan
While there's much discussion of the type system here, the feature in this PR is implemented internally as a transformation that happens before lowering to the type system layer. We already support impl Trait types partially capturing the in scope lifetimes; we just currently only expose that implicitly.
So, in my (errs's) view as a types team member, there's nothing for types to weigh in on here with respect to the implementation being stabilized, and I'd suggest a lang-only proposed FCP (though we'll of course CC the team below).
### Authorship and acknowledgments
This stabilization report was coauthored by compiler-errors and TC.
TC would like to acknowledge the outstanding and speedy work that compiler-errors has done to make this feature happen.
compiler-errors thanks TC for authoring the RFC, for all of his involvement in this feature's development, and pushing the Rust 2024 edition forward.
### Open items
We're doing some things in parallel here. In signaling the intention to stabilize, we want to uncover any latent issues so we can be sure they get addressed. We want to give the maximum time for discussion here to happen by starting it while other remaining miscellaneous work proceeds. That work includes:
- [x] Look into `syn` support.
- https://github.com/dtolnay/syn/issues/1677
- https://github.com/dtolnay/syn/pull/1707
- [x] Look into `rustfmt` support.
- https://github.com/rust-lang/rust/pull/126754
- [x] Look into `rust-analyzer` support.
- https://github.com/rust-lang/rust-analyzer/issues/17598
- https://github.com/rust-lang/rust-analyzer/pull/17676
- [x] Look into `rustdoc` support.
- https://github.com/rust-lang/rust/issues/127228
- https://github.com/rust-lang/rust/pull/127632
- https://github.com/rust-lang/rust/pull/127658
- [x] Suggest this feature to RfL (a known nightly user).
- [x] Add a chapter to the edition guide.
- https://github.com/rust-lang/edition-guide/pull/316
- [x] Update the Reference.
- https://github.com/rust-lang/reference/pull/1577
### (Selected) implementation history
* https://github.com/rust-lang/rfcs/pull/3498
* https://github.com/rust-lang/rfcs/pull/3617
* https://github.com/rust-lang/rust/pull/123468
* https://github.com/rust-lang/rust/issues/125836
* https://github.com/rust-lang/rust/pull/126049
* https://github.com/rust-lang/rust/pull/126753Closes#123432.
cc `@rust-lang/lang` `@rust-lang/types`
`@rustbot` labels +T-lang +I-lang-nominated +A-impl-trait +F-precise_capturing
Tracking:
- https://github.com/rust-lang/rust/issues/123432
----
For the compiler reviewer, I'll leave some inline comments about diagnostics fallout :^)
r? compiler
Fix ICE Caused by Incorrectly Delaying E0107
Fixes #128249
For the following code:
```rust
trait Foo<T> {}
impl Foo<T: Default> for u8 {}
```
#126054 added some logic to delay emitting E0107 as the names of associated type `T` in the impl header and generic parameter `T` in `trait Foo` match.
But it failed to ensure whether such unexpected associated type bounds are coming from a impl block header. This caused an ICE as the compiler was delaying E0107 for code like:
```rust
trait Trait<Type> {
type Type;
fn method(&self) -> impl Trait<Type: '_>;
}
```
because it assumed the associated type bound `Type: '_` is for the generic parameter `Type` in `trait Trait` since the names are same.
This PR adds a check to ensure that E0107 is delayed only in the context of impl block header.
Support ?Trait bounds in supertraits and dyn Trait under a feature gate
This patch allows `maybe` polarity bounds under a feature gate. The only language change here is that corresponding hard errors are replaced by feature gates. Example:
```rust
#![feature(allow_maybe_polarity)]
...
trait Trait1 : ?Trait { ... } // ok
fn foo(_: Box<(dyn Trait2 + ?Trait)>) {} // ok
fn bar<T: ?Sized + ?Trait>(_: &T) {} // ok
```
Maybe bounds still don't do anything (except for `Sized` trait), however this patch will allow us to [experiment with default auto traits](https://github.com/rust-lang/rust/pull/120706#issuecomment-1934006762).
This is a part of the [MCP: Low level components for async drop](https://github.com/rust-lang/compiler-team/issues/727)
Make Clone::clone a lang item
I want to absorb all the logic for picking whether an Instance is LocalCopy or GloballyShared into one place. As part of this, I wanted to identify Clone shims inside `cross_crate_inlinable` and found that rather tricky. `@compiler-errors` suggested that I add a lang item for `Clone::clone` because that would produce other cleanups in the compiler.
That sounds good to me, but I have looked and I've only been able to find one.
r? compiler-errors