Initial implementation of `#[feature(default_field_values]`, proposed in https://github.com/rust-lang/rfcs/pull/3681.
Support default fields in enum struct variant
Allow default values in an enum struct variant definition:
```rust
pub enum Bar {
Foo {
bar: S = S,
baz: i32 = 42 + 3,
}
}
```
Allow using `..` without a base on an enum struct variant
```rust
Bar::Foo { .. }
```
`#[derive(Default)]` doesn't account for these as it is still gating `#[default]` only being allowed on unit variants.
Support `#[derive(Default)]` on enum struct variants with all defaulted fields
```rust
pub enum Bar {
#[default]
Foo {
bar: S = S,
baz: i32 = 42 + 3,
}
}
```
Check for missing fields in typeck instead of mir_build.
Expand test with `const` param case (needs `generic_const_exprs` enabled).
Properly instantiate MIR const
The following works:
```rust
struct S<A> {
a: Vec<A> = Vec::new(),
}
S::<i32> { .. }
```
Add lint for default fields that will always fail const-eval
We *allow* this to happen for API writers that might want to rely on users'
getting a compile error when using the default field, different to the error
that they would get when the field isn't default. We could change this to
*always* error instead of being a lint, if we wanted.
This will *not* catch errors for partially evaluated consts, like when the
expression relies on a const parameter.
Suggestions when encountering `Foo { .. }` without `#[feature(default_field_values)]`:
- Suggest adding a base expression if there are missing fields.
- Suggest enabling the feature if all the missing fields have optional values.
- Suggest removing `..` if there are no missing fields.
Eliminate magic numbers from expression precedence
Context: see https://github.com/rust-lang/rust/pull/133140.
This PR continues on backporting Syn's expression precedence design into rustc. Rustc's design used mysterious integer quantities represented variously as `i8` or `usize` (e.g. `PREC_CLOSURE = -40i8`), a special significance around `0` that is never named, and an extra `PREC_FORCE_PAREN` precedence level that does not correspond to any expression. Syn's design uses a C-like enum with variants that clearly correspond to specific sets of expression kinds.
This PR is a refactoring that has no intended behavior change on its own, but it unblocks other precedence work that rustc's precedence design was poorly suited to accommodate.
- Asymmetrical precedence, so that a pretty-printer can tell `(return 1) + 1` needs parens but `1 + return 1` does not.
- Squashing the `Closure` and `Jump` cases into a single precedence level.
- Numerous remaining false positives and false negatives in rustc pretty-printer's parenthesization of macro metavariables, for example in `$e < rhs` where $e is `lhs as Thing<T>`.
FYI `@fmease` — you don't need to review if rustbot picks someone else, but you mentioned being interested in the followup PRs.
Remove `hir::ArrayLen`
This refactoring removes `hir::ArrayLen`, replacing it with `hir::ConstArg`. To represent inferred array lengths (previously `hir::ArrayLen::Infer`), a new variant `ConstArgKind::Infer` is added.
r? `@BoxyUwU`
Inline ExprPrecedence::order into Expr::precedence
The representation of expression precedence in rustc_ast has been an obstacle to further improvements in the pretty-printer (continuing from #119105 and #119427).
Previously the operation of *"does this expression have lower precedence than that one"* (relevant for parenthesis insertion in macro-generated syntax trees) consisted of 3 steps:
1. Convert `Expr` to `ExprPrecedence` using `.precedence()`
2. Convert `ExprPrecedence` to `i8` using `.order()`
3. Compare using `<`
As far as I can guess, the reason for the separation between `precedence()` and `order()` was so that both `rustc_ast::Expr` and `rustc_hir::Expr` could convert as straightforwardly as possible to the same `ExprPrecedence` enum, and then the more finicky logic performed by `order` could be present just once.
The mapping between `Expr` and `ExprPrecedence` was intended to be as straightforward as possible:
```rust
match self.kind {
ExprKind::Closure(..) => ExprPrecedence::Closure,
...
}
```
although there were exceptions of both many-to-one, and one-to-many:
```rust
ExprKind::Underscore => ExprPrecedence::Path,
ExprKind::Path(..) => ExprPrecedence::Path,
...
ExprKind::Match(_, _, MatchKind::Prefix) => ExprPrecedence::Match,
ExprKind::Match(_, _, MatchKind::Postfix) => ExprPrecedence::PostfixMatch,
```
Where the nature of `ExprPrecedence` becomes problematic is when a single expression kind might be associated with multiple different precedence levels depending on context (outside the expression) and contents (inside the expression). For example consider what is the precedence of an ExprKind::Closure `$closure`. Well, on the left-hand side of a binary operator it would need parentheses in order to avoid the trailing binary operator being absorbed into the closure body: `($closure) + Rhs`, so the precedence is something lower than that of `+`. But on the right-hand side of a binary operator, a closure is just a straightforward prefix expression like a unary op, which is a relatively high precedence level, higher than binops but lower than method calls: `Lhs + $closure` is fine without parens but `($closure).method()` needs them. But as a third case, if the closure contains an explicit return type, then the precedence is an even higher level than that, never needing parenthesization even in a binop left-hand side or method call: `|| -> bool { false } + Rhs` or `|| -> bool { false }.method()`.
You can see that trying to capture all of this resolution about expressions into `ExprPrecedence` violates the intention of `ExprPrecedence` being a straightforward one-to-one correspondence from each AST and HIR `ExprKind` variant. It would be possible to attempt that by doing stuff like `ExprPrecedence::Closure(Side::Leading, ReturnType::No)`, but I don't foresee the original envisioned benefit of the `precedence()`/`order()` distinction being retained in this approach. Instead I want to move toward a model that Syn has been using successfully. In Syn, there is a Precedence enum but it differs from rustc in the following ways:
- There are [relatively few variants](https://github.com/dtolnay/syn/blob/2.0.87/src/precedence.rs#L11-L47) compared to rustc's `ExprPrecedence`. For example there is no distinction at the precedence level between returns and closures, or between loops and method calls.
- We distinguish between [leading](https://github.com/dtolnay/syn/blob/2.0.87/src/fixup.rs#L293) and [trailing](https://github.com/dtolnay/syn/blob/2.0.87/src/fixup.rs#L309) precedence, taking into account an expression's context such as what token follows it (for various syntactic bail-outs in Rust's grammar, like ambiguities around break-with-value) and how it relates to operators from the surrounding syntax tree.
- There are no hardcoded mysterious integer quantities like rustc's `PREC_CLOSURE = -40`. All precedence comparisons are performed via PartialOrd on a C-like enum.
This PR is just a first step in these changes. As you can tell from Syn, I definitely think there is value in having a dedicated type to represent precedence, instead of what `order()` is doing with `i8`. But that is a whole separate adventure because rustc_ast doesn't even agree consistently on `i8` being the type for precedence order; `AssocOp::precedence` instead uses `usize` and there are casts in both directions. It is likely that a type called `ExprPrecedence` will re-appear, but it will look substantially different from the one that existed before this PR.
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
Fix malformed suggestion for repeated maybe unsized bounds
Fixes#127441
Now when we encounter something like `foo(a : impl ?Sized + ?Sized)`, instead of suggesting removal of both bounds and leaving `foo(a: impl )` behind, we suggest changing the first bound to `Sized` and removing the second bound, resulting in `foo(a: impl Sized)`.
Although the issue was reported for impl trait types, it also occurred with regular param bounds. So if we encounter `foo<T: ?Sized + ?Sized>(a: T)` we now detect that all the bounds are `?Sized` and therefore emit the suggestion to remove the entire predicate `: ?Sized + ?Sized` resulting in `foo<T>(a: T)`.
Lastly, if we encounter a situation where some of the bounds are something other than `?Sized`, then we emit separate removal suggestions for each `?Sized` bound. E.g. if we see `foo(a: impl ?Sized + Bar + ?Sized)` or `foo<T: ?Sized + Bar + ?Sized>(a: T)` we emit suggestions such that the user will be left with `foo(a : impl Bar)` or `foo<T: Bar>(a: T)` respectively.
Forbid borrows and unsized types from being used as the type of a const generic under `adt_const_params`
Fixes#112219Fixes#112124Fixes#112125
### Motivation
Currently the `adt_const_params` feature allows writing `Foo<const N: [u8]>` this is entirely useless as it is not possible to write an expression which evaluates to a type that is not `Sized`. In order to actually use unsized types in const generics they are typically written as `const N: &[u8]` which *is* possible to provide a value of.
Unfortunately allowing the types of const parameters to contain references is non trivial (#120961) as it introduces a number of difficult questions about how equality of references in the type system should behave. References in the types of const generics is largely only useful for using unsized types in const generics.
This PR introduces a new feature gate `unsized_const_parameters` and moves support for `const N: [u8]` and `const N: &...` from `adt_const_params` into it. The goal here hopefully is to experiment with allowing `const N: [u8]` to work without references and then eventually completely forbid references in const generics.
Splitting this out into a new feature gate means that stabilization of `adt_const_params` does not have to resolve#120961 which is the only remaining "big" blocker for the feature. Remaining issues after this are a few ICEs and naming bikeshed for `ConstParamTy`.
### Implementation
The implementation is slightly subtle here as we would like to ensure that a stabilization of `adt_const_params` is forwards compatible with any outcome of `unsized_const_parameters`. This is inherently tricky as we do not support unstable trait implementations and we determine whether a type is valid as the type of a const parameter via a trait bound.
There are a few constraints here:
- We would like to *allow for the possibility* of adding a `Sized` supertrait to `ConstParamTy` in the event that we wind up opting to not support unsized types and instead requiring people to write the 'sized version', e.g. `const N: [u8; M]` instead of `const N: [u8]`.
- Crates should be able to enable `unsized_const_parameters` and write trait implementations of `ConstParamTy` for `!Sized` types without downstream crates that only enable `adt_const_params` being able to observe this (required for std to be able to `impl<T> ConstParamTy for [T]`
Ultimately the way this is accomplished is via having two traits (sad), `ConstParamTy` and `UnsizedConstParamTy`. Depending on whether `unsized_const_parameters` is enabled or not we change which trait is used to check whether a type is allowed to be a const parameter.
Long term (when stabilizing `UnsizedConstParamTy`) it should be possible to completely merge these traits (and derive macros), only having a single `trait ConstParamTy` and `macro ConstParamTy`.
Under `adt_const_params` it is now illegal to directly refer to `ConstParamTy` it is only used as an internal impl detail by `derive(ConstParamTy)` and checking const parameters are well formed. This is necessary in order to ensure forwards compatibility with all possible future directions for `feature(unsized_const_parameters)`.
Generally the intuition here should be that `ConstParamTy` is the stable trait that everything uses, and `UnsizedConstParamTy` is that plus unstable implementations (well, I suppose `ConstParamTy` isn't stable yet :P).
This is a very large commit since a lot needs to be changed in order to
make the tests pass. The salient changes are:
- `ConstArgKind` gets a new `Path` variant, and all const params are now
represented using it. Non-param paths still use `ConstArgKind::Anon`
to prevent this change from getting too large, but they will soon use
the `Path` variant too.
- `ConstArg` gets a distinct `hir_id` field and its own variant in
`hir::Node`. This affected many parts of the compiler that expected
the parent of an `AnonConst` to be the containing context (e.g., an
array repeat expression). They have been changed to check the
"grandparent" where necessary.
- Some `ast::AnonConst`s now have their `DefId`s created in
rustc_ast_lowering rather than `DefCollector`. This is because in some
cases they will end up becoming a `ConstArgKind::Path` instead, which
has no `DefId`. We have to solve this in a hacky way where we guess
whether the `AnonConst` could end up as a path const since we can't
know for sure until after name resolution (`N` could refer to a free
const or a nullary struct). If it has no chance as being a const
param, then we create a `DefId` in `DefCollector` -- otherwise we
decide during ast_lowering. This will have to be updated once all path
consts use `ConstArgKind::Path`.
- We explicitly use `ConstArgHasType` for array lengths, rather than
implicitly relying on anon const type feeding -- this is due to the
addition of `ConstArgKind::Path`.
- Some tests have their outputs changed, but the changes are for the
most part minor (including removing duplicate or almost-duplicate
errors). One test now ICEs, but it is for an incomplete, unstable
feature and is now tracked at #127009.
Added an associated `const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED`
to the `StableOrd` trait to ensure that implementors carefully consider
whether the trait's contract is upheld, as incorrect implementations can
cause miscompilations.
local_def_path_hash_to_def_id is used by Debug impl for DepNode and it
looks for DefPathHash inside the current compilation. During incremental
compilation we are going through nodes that belong to a previous
compilation and might not be present and a simple attempt to print such
node with tracing::debug (try_mark_parent_green does it for example)
results in a otherwise avoidable panic
Panic was added in https://github.com/rust-lang/rust/pull/82183,
specifically in 2b60338ee9, with a comment "We only use this mapping for
cases where we know that it must succeed.", but I'm not sure if this
property holds when we traverse nodes from the old compilation in order
to figure out if they are valid or not
`E0229`: Suggest Moving Type Constraints to Type Parameter Declaration
Fixes#113073
This PR suggests `impl<T: Bound> Trait<T> for Foo` when finding `impl Trait<T: Bound> for Foo`. Tangentially, it also improves a handful of other error messages.
It accomplishes this in two steps:
1. Check if constrained arguments and parameter names appear in the same order and delay emitting "incorrect number of generic arguments" error because it can be confusing for the programmer to see `0 generic arguments provided` when there are `n` constrained generic arguments.
2. Inside `E0229`, suggest declaring the type parameter right after the `impl` keyword by finding the relevant impl block's span for type parameter declaration. This also handles lifetime declarations correctly.
Also, the multi part suggestion doesn't use the fluent error mechanism because translating all the errors to fluent style feels outside the scope of this PR. I will handle it in a separate PR if this gets approved.
Urls to docs in rust_hir
<!--
If this PR is related to an unstable feature or an otherwise tracked effort,
please link to the relevant tracking issue here. If you don't know of a related
tracking issue or there are none, feel free to ignore this.
This PR will get automatically assigned to a reviewer. In case you would like
a specific user to review your work, you can assign it to them by using
r? <reviewer name>
-->
Use `tidy` to sort crate attributes for all compiler crates.
We already do this for a number of crates, e.g. `rustc_middle`, `rustc_span`, `rustc_metadata`, `rustc_span`, `rustc_errors`.
For the ones we don't, in many cases the attributes are a mess.
- There is no consistency about order of attribute kinds (e.g. `allow`/`deny`/`feature`).
- Within attribute kind groups (e.g. the `feature` attributes), sometimes the order is alphabetical, and sometimes there is no particular order.
- Sometimes the attributes of a particular kind aren't even grouped all together, e.g. there might be a `feature`, then an `allow`, then another `feature`.
This commit extends the existing sorting to all compiler crates, increasing consistency. If any new attribute line is added there is now only one place it can go -- no need for arbitrary decisions.
Exceptions:
- `rustc_log`, `rustc_next_trait_solver` and `rustc_type_ir_macros`, because they have no crate attributes.
- `rustc_codegen_gcc`, because it's quasi-external to rustc (e.g. it's ignored in `rustfmt.toml`).
r? `@davidtwco`
For E0277 suggest adding `Result` return type for function when using QuestionMark `?` in the body.
Adding suggestions for following function in E0277.
```rust
fn main() {
let mut _file = File::create("foo.txt")?;
}
```
to
```rust
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut _file = File::create("foo.txt")?;
return Ok(());
}
```
According to the issue #125997, only the code examples in the issue are targeted, but the issue covers a wider range of situations.
<!--
If this PR is related to an unstable feature or an otherwise tracked effort,
please link to the relevant tracking issue here. If you don't know of a related
tracking issue or there are none, feel free to ignore this.
This PR will get automatically assigned to a reviewer. In case you would like
a specific user to review your work, you can assign it to them by using
r? <reviewer name>
-->
We already do this for a number of crates, e.g. `rustc_middle`,
`rustc_span`, `rustc_metadata`, `rustc_span`, `rustc_errors`.
For the ones we don't, in many cases the attributes are a mess.
- There is no consistency about order of attribute kinds (e.g.
`allow`/`deny`/`feature`).
- Within attribute kind groups (e.g. the `feature` attributes),
sometimes the order is alphabetical, and sometimes there is no
particular order.
- Sometimes the attributes of a particular kind aren't even grouped
all together, e.g. there might be a `feature`, then an `allow`, then
another `feature`.
This commit extends the existing sorting to all compiler crates,
increasing consistency. If any new attribute line is added there is now
only one place it can go -- no need for arbitrary decisions.
Exceptions:
- `rustc_log`, `rustc_next_trait_solver` and `rustc_type_ir_macros`,
because they have no crate attributes.
- `rustc_codegen_gcc`, because it's quasi-external to rustc (e.g. it's
ignored in `rustfmt.toml`).