Rollup of 10 pull requests
Successful merges:
- #128627 (Special case DUMMY_SP to emit line 0/column 0 locations on DWARF platforms.)
- #128843 (Minor Refactor: Remove a Redundant Conditional Check)
- #129179 (CFI: Erase regions when projecting ADT to its transparent non-1zst field)
- #129281 (Tweak unreachable lint wording)
- #129312 (Fix stability attribute of `impl !Error for &str`)
- #129332 (Avoid extra `cast()`s after `CStr::as_ptr()`)
- #129339 (Make `ArgAbi::make_indirect_force` more specific)
- #129344 (Use `bool` in favor of `Option<()>` for diagnostics)
- #129345 (Use shorthand field initialization syntax more aggressively in the compiler)
- #129355 (fix comment on PlaceMention semantics)
r? `@ghost`
`@rustbot` modify labels: rollup
Use shorthand field initialization syntax more aggressively in the compiler
Caught these when cleaning up #129344 and decided to run clippy to find the rest
Use `bool` in favor of `Option<()>` for diagnostics
We originally only supported `Option<()>` for optional notes/labels, but we now support `bool`. Let's use that, since it usually leads to more readable code.
I'm not removing the support from the derive macro, though I guess we could error on it... 🤔
Make `ArgAbi::make_indirect_force` more specific
As the method is only needed for making ignored ZSTs indirect on some ABIs, rename and add a doc-comment and `self.mode` check to make it harder to accidentally misuse. Addresses review feedback from https://github.com/rust-lang/rust/pull/125854#discussion_r1721047899.
r? ``@RalfJung``
Avoid extra `cast()`s after `CStr::as_ptr()`
These used to be `&str` literals that did need a pointer cast, but that
became a no-op after switching to `c""` literals in #118566.
CFI: Erase regions when projecting ADT to its transparent non-1zst field
The output from `FieldDef::ty` (or `TyCtxt::type_of`) may have free regions (well, `'static`) -- erase it.
Fixes#129169Fixes#123685
Minor Refactor: Remove a Redundant Conditional Check
The existing code checks `where_bounds.is_empty()` twice when
it can be combined into one. Now, after combining, the refactored code reads
better and feels straightforward.
The diff doesn't make it clear. So, the current code looks like this:
``` rust
if !where_bounds.is_empty() {
err.help(format!(
"consider introducing a new type parameter `T` and adding `where` constraints:\
\n where\n T: {qself_str},\n{}",
where_bounds.join(",\n"),
));
}
let reported = err.emit();
if !where_bounds.is_empty() {
return Err(reported);
}
```
The proposed changes:
``` rust
if !where_bounds.is_empty() {
err.help(format!(
"consider introducing a new type parameter `T` and adding `where` constraints:\
\n where\n T: {qself_str},\n{}",
where_bounds.join(",\n"),
));
let reported = err.emit();
return Err(reported);
}
err.emit();
```
Special case DUMMY_SP to emit line 0/column 0 locations on DWARF platforms.
Line 0 has a special meaning in DWARF. From the version 5 spec:
The compiler may emit the value 0 in cases
where an instruction cannot be attributed to any
source line.
DUMMY_SP spans cannot be attributed to any line. However, because rustc internally stores line numbers starting at zero, lookup_debug_loc() adjusts every line number by one. Special casing DUMMY_SP to actually emit line 0 ensures rustc communicates to the debugger that there's no meaningful source code for this instruction, rather than telling the debugger to jump to line 1 randomly.
Add a precondition check for Layout::from_size_align_unchecked
Ran into this while looking into https://github.com/rust-lang/miri/issues/3679. This is of course not the cause of the ICE, but the reproducer doesn't encounter a precondition check and it ought to.
Rollup of 9 pull requests
Successful merges:
- #128662 (Lint on tail expr drop order change in Edition 2024)
- #128932 (skip updating when external binding is existed)
- #129270 (Don't consider locals to shadow inner items' generics)
- #129277 (Update annotate-snippets to 0.11)
- #129294 (Stabilize `iter::repeat_n`)
- #129308 (fix: simple typo in compiler directory)
- #129309 (ctfe: make CompileTimeInterpCx type alias public)
- #129314 (fix a broken link in `mir/mod.rs`)
- #129318 (Remove unneeded conversion to `DefId` for `ExtraInfo`)
r? `@ghost`
`@rustbot` modify labels: rollup
modularize rustdoc's write_shared
Refactor src/librustdoc/html/render/write_shared.rs to reduce code duplication, adding unit tests
* Extract + unit test code for sorting and rendering JSON, which is duplicated 9 times in the current impl
* Extract + unit test code for encoding JSON as single quoted strings, which is duplicated twice in the current impl
* Unit tests for cross-crate information file formats
* Generic interface to add new kinds of cross-crate information files in the future
* Intended to match current behavior exactly, except for a merge info comment it adds to the bottom of cci files
* This PR is intended to reduce the review burden from my [mergeable rustdoc rfc](https://github.com/rust-lang/rfcs/pull/3662) implementation PR, which is a [small commit based on this branch](https://github.com/EtomicBomb/rust/tree/rfc). This code is agnostic to the RFC and does not include any of the flags discussed there, but cleanly enables the addition of these flags in the future because it is more modular
Remove unneeded conversion to `DefId` for `ExtraInfo`
I'm working on adding support for "unit test doctests" and this first cleanup came up so just sending it ahead of the rest.
r? ``@notriddle``
fix a broken link in `mir/mod.rs`
I discovered that the internal link in mir/mod.rs is broken, so I will fix it. The AddCallGuards is now located under rustc_mir_transform.
The PR at that time is as follows.
c5fc2609f0
ctfe: make CompileTimeInterpCx type alias public
`CompileTimeMachine` is already public so there is no good reason to not also make this public.
Also add comment explaining why `CompileTimeMachine` is public.
Don't consider locals to shadow inner items' generics
We don't want to consider the bindings from a `RibKind::Module` itself, because for an inner item that module will contain the local bindings from the function body or wherever else the inner item is being defined.
Fixes#129265
r? petrochenkov
skip updating when external binding is existed
Fixes#128813
For following code:
```rs
extern crate core;
fn f() {
use ::core;
}
macro_rules! m {
() => {
extern crate std as core;
};
}
m!();
fn main() {}
```
- In the first loop, we define `extern crate core` and `use ::core` will be referred to `core` (yes, it does not consider if there are some macros that are not expanded. Ideally, this should be delayed if there are some unexpanded macros in the root, but I didn't change it like that because it seems like a huge change).
- Then `m` is expanded, which makes `extern_prelude('core')` return `std` rather than `core`, causing the inconsistency.
r? `@petrochenkov`
Lint on tail expr drop order change in Edition 2024
This lint warns users to consider extra discretion on the effect of a transposed drop order arising from Edition 2024, which involves temporaries in tail expression location with significant drop implementation.
cc `@traviscross`
Tracking:
- https://github.com/rust-lang/rust/issues/123739
Don't generate functions with the `rustc_intrinsic_must_be_overridden` attribute
Functions with the attribute `rustc_intrinsic_must_be_overridden` never be called.
r? compiler
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
Added "copy" to Debug fmt for copy operands
In MIR's debug mode (--emit mir) the printing for Operands is slightly inconsistent.
The RValues - values on the right side of an Assign - are usually printed with their Operand when they are Places.
Example:
_2 = move _3
But for arguments, the operand is omitted.
_2 = _1
I propose a change be made, to display the place with the operand.
_2 = copy _1
Move and copy have different semantics, meaning this difference is important and helpful to the user. It also adds consistency to the pretty printing.
-- EDIT --
Consider this example Rust program and its MIR output with the **updated pretty printer.**
This was generated with the arguments --emit mir --crate-type lib -Zmir-opt-level=0 (Otherwise, it's optimised away since it's a junk program).
```rust
fn main(foo: i32) {
let v = 10;
if v == 20 {
foo;
}
else {
v;
}
}
```
```MIR
// WARNING: This output format is intended for human consumers only
// and is subject to change without notice. Knock yourself out.
fn main(_1: i32) -> () {
debug foo => _1;
let mut _0: ();
let _2: i32;
let mut _3: bool;
let mut _4: i32;
let _5: i32;
let _6: i32;
scope 1 {
debug v => _2;
}
bb0: {
StorageLive(_2);
_2 = const 10_i32;
StorageLive(_3);
StorageLive(_4);
_4 = copy _2;
_3 = Eq(move _4, const 20_i32);
switchInt(move _3) -> [0: bb2, otherwise: bb1];
}
bb1: {
StorageDead(_4);
StorageLive(_5);
_5 = copy _1;
StorageDead(_5);
_0 = const ();
goto -> bb3;
}
bb2: {
StorageDead(_4);
StorageLive(_6);
_6 = copy _2;
StorageDead(_6);
_0 = const ();
goto -> bb3;
}
bb3: {
StorageDead(_3);
StorageDead(_2);
return;
}
}
```
In this example program, we can see that when we move a place, it is preceded by "move". e.g. ``` _3 = Eq(move _4, const 20_i32);```. However, when we copy a place such as ```_5 = _1;```, it is not preceded by the operand in the original printout. I propose to change the print to include the copy ```_5 = copy _1``` as in this example.
Regarding the arguments part. When I originally submitted this PR, I was under the impression this only affected the print for arguments to a function, but actually, it affects anything that uses a copy. This is preferable anyway with regard to consistency. The PR is about making ```copy``` explicit.