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
Rollup of 6 pull requests
Successful merges:
- #125447 (Allow constraining opaque types during subtyping in the trait system)
- #125766 (MCDC Coverage: instrument last boolean RHS operands from condition coverage)
- #125880 (Remove `src/tools/rust-demangler`)
- #126154 (StorageLive: refresh storage (instead of UB) when local is already live)
- #126572 (override user defined channel when using precompiled rustc)
- #126662 (Unconditionally warn on usage of `wasm32-wasi`)
r? `@ghost`
`@rustbot` modify labels: rollup
Make pretty printing for `f16` and `f128` consistent
Currently the docs show e.g.
{transmute(0xfffeffffffffffffffffffffffffffff): f128}
for f128 constants. This should fix that to instead use apfloat for printing, as is done for `f32` and `f64`.
Currently the docs show e.g.
{transmute(0xfffeffffffffffffffffffffffffffff): f128}
for f128 constants. This should fix that to instead use apfloat for
printing, as is done for `f32` and `f64`.
Uplift next trait solver to `rustc_next_trait_solver`
🎉
There's so many FIXMEs! Sorry! Ideally this merges with the FIXMEs and we track and squash them over the near future.
Also, this still doesn't build on anything other than rustc. I still need to fix `feature = "nightly"` in `rustc_type_ir`, and remove and fix all the nightly feature usage in the new trait solver (notably: let-chains).
Also, sorry `@lcnr` I know you asked for me to separate the commit where we `mv rustc_trait_selection/solve/... rustc_next_trait_solver/solve/...`, but I had already done all the work by that point. Luckily, `git` understands the file moves so it should still be relatively reviewable.
If this is still very difficult to review, then I can do some rebasing magic to try to separate this out. Please let me know!
r? lcnr
Replace all `&DiagCtxt` with a `DiagCtxtHandle<'_>` wrapper type
r? `@davidtwco`
This paves the way for tracking more state (e.g. error tainting) in the diagnostic context handle
Basically I will add a field to the `DiagCtxtHandle` that refers back to the `InferCtxt`'s (and others) `Option<ErrorHandled>`, allowing us to immediately taint these contexts when emitting an error and not needing manual tainting anymore (which is easy to forget and we don't do in general anyway)
Rename `InstanceDef` -> `InstanceKind`
Renames `InstanceDef` to `InstanceKind`. The `Def` here is confusing, and makes it hard to distinguish `Instance` and `InstanceDef`. `InstanceKind` makes this more obvious, since it's really just describing what *kind* of instance we have.
Not sure if this is large enough to warrant a types team MCP -- it's only 53 files. I don't personally think it does, but happy to write one if anyone disagrees. cc ``@rust-lang/types``
r? types
Only compute vtable information during codegen
This PR removes vtable information from the `Object` and `TraitUpcasting` candidate sources in the trait solvers, and defers the computation of relevant information to `Instance::resolve`. This is because vtables really aren't a thing in the trait world -- they're an implementation detail in codegen.
Previously it was just easiest to tangle this information together since we were already doing the work of looking at all the supertraits in the trait solver, and specifically because we use traits to represent when it's possible to call a method via a vtable (`Object` candidate) and do upcasting (`Unsize` candidate). but I am somewhat suspicious we're doing a *lot* of extra work, especially in polymorphic contexts, so let's see what perf says.
smir: merge identical Constant and ConstOperand types
The first commit renames the const operand visitor functions on regular MIR to match the type name, that was forgotten in the original rename.
The second commit changes stable MIR, fixing https://github.com/rust-lang/project-stable-mir/issues/71. Previously there were two different smir types for the MIR type `ConstOperand`, one used in `Operand` and one in `VarDebugInfoContents`.
Maybe we should have done this with https://github.com/rust-lang/rust/pull/125967, so there's only a single breaking change... but I saw that PR too late.
Fixes https://github.com/rust-lang/project-stable-mir/issues/71
Rollup of 9 pull requests
Successful merges:
- #125829 (rustc_span: Add conveniences for working with span formats)
- #126361 (Unify intrinsics body handling in StableMIR)
- #126417 (Add `f16` and `f128` inline ASM support for `x86` and `x86-64`)
- #126424 ( Also sort `crt-static` in `--print target-features` output)
- #126428 (Polish `std::path::absolute` documentation.)
- #126429 (Add `f16` and `f128` const eval for binary and unary operationations)
- #126448 (End support for Python 3.8 in tidy)
- #126488 (Use `std::path::absolute` in bootstrap)
- #126511 (.mailmap: Associate both my work and my private email with me)
r? `@ghost`
`@rustbot` modify labels: rollup
Add `f16` and `f128` const eval for binary and unary operationations
Add const evaluation and Miri support for f16 and f128, including unary and binary operations. Casts are not yet included.
Fixes https://github.com/rust-lang/rust/issues/124583
r? ``@RalfJung``
Use `Variance` glob imported variants everywhere
Fully commit to using the globbed variance. Could be convinced the other way, and change this PR to not use the globbed variants anywhere, but I'd rather we do one or the other.
r? lcnr
change method resolution to constrain hidden types instead of rejecting method candidates
Some of these are in probes and may affect inference. This is therefore a breaking change.
This allows new code to compile on stable:
```rust
trait Trait {}
impl Trait for u32 {}
struct Bar<T>(T);
impl Bar<u32> {
fn foo(self) {}
}
fn foo(x: bool) -> Bar<impl Sized> {
if x {
let x = foo(false);
x.foo();
//^ this used to not find the `foo` method, because while we did equate `x`'s type with possible candidates, we didn't allow opaque type inference while doing so
}
todo!()
}
```
r? ```````@compiler-errors```````
fixes #121404
cc https://github.com/rust-lang/rust/issues/116652
Remove `DebugWithInfcx` machinery
This PR removes `DebugWithInfcx` after having a lot of second thoughts about it due to recent type system uplifting work. We could add it back later if we want, but I don't think the amount of boilerplate in the complier and the existence of (kindof) hacks like `NoInfcx` currently justify the existence of `DebugWithInfcx`, especially since it's not even being used anywhere in the compiler currently.
The motivation for `DebugWithInfcx` is that we want to be able to print infcx-aware information, such as universe information[^1] (though if there are other usages that I'm overlooking, please let me know). I think there are probably more tailored solutions that can specifically be employed in places where this infcx-aware printing is necessary. For example, one way of achieving this is by implementing a custom `FmtPrinter` which overloads `ty_infer_name` (perhaps also extending it to have overrideable stubs for printing placeholders too) to print the `?u.i` name for an infer var. This will necessitate uplifting `Print` from `rustc_middle::ty::print`, but this seems a bit more extensible and reusable than `DebugWithInfcx`.
One of the problems w/ `DebugWithInfcx` is its opt-in-ness. Even if a compiler dev adds a new `debug!(ty)` in a context where there is an `infcx` we can access, they have to *opt-in* to using `DebugWithInfcx` with something like `debug!(infcx.with(ty))`. This feels to me like it risks a lot of boilerplate, and very easy to just forget adding it at all, especially in cases like `#[instrument]`.
A second problem is the `NoInfcx` type itself. It's necessary to have this dummy infcx implementation since we often want to print types outside of the scope of a valid `Infcx`. Right now, `NoInfcx` is only *partially* a valid implementation of `InferCtxtLike`, except for the methods that we specifically need for `DebugWithInfcx`. As I work on uplifting the trait solver, I actually want to add a lot more methods to `InferCtxtLike` and having to add `unreachable!("this should never be called")` stubs for uplifted methods like `next_ty_var` is quite annoying.
In reality, I actually only *really* care about the second problem -- we could, perhaps, instead just try to get rid of `NoInfcx` and just just duplicate `Debug` and `DebugWithInfcx` for most types. If we're okay with duplicating all these implementations (though most of them would just be trivial `#[derive(Debug, DebugWithInfcx)]`), I'd be okay with that too 🤔
r? `@BoxyUwU` `@lcnr` would like to know your thoughts -- happy to discuss this further, mainly trying to bring this problem up
[^1]: Which in my experience is only really necessary when we're debugging things like generalizer bugs.
interpret: ensure we check bool/char for validity when they are used in a cast
In general, `Scalar::to_bits` is a bit dangerous as it bypasses all type information. We should usually prefer matching on the type and acting according to that. So I also refactored `unary_op` handling of integers to do that. The remaining `to_bits` uses are operations that just fundamentally don't care about the sign (and only work on integers).
invalid_char_cast.rs is the key new test, the others already passed before this PR.
r? `@oli-obk`
Only compute `specializes` query if (min)specialization is enabled in the crate of the specializing impl
Fixes (after backport) https://github.com/rust-lang/rust/issues/125197
### What
https://github.com/rust-lang/rust/pull/122791 makes it so that inductive cycles are no longer hard errors. That means that when we are testing, for example, whether these impls overlap:
```rust
impl PartialEq<Self> for AnyId {
fn eq(&self, _: &Self) -> bool {
todo!()
}
}
impl<T: Identifier> PartialEq<T> for AnyId {
fn eq(&self, _: &T) -> bool {
todo!()
}
}
```
...given...
```rust
pub trait Identifier: Display + 'static {}
impl<T> Identifier for T where T: PartialEq + Display + 'static {}
```
Then we try to see if the second impl holds given `T = AnyId`. That requires `AnyId: Identifier`, which requires that `AnyId: PartialEq`, which is satisfied by these two impl candidates... The `PartialEq<T>` impl is a cycle, and we used to winnow it when we used to treat inductive cycles as errors.
However, now that we don't winnow it, this means that we *now* try calling `candidate_should_be_dropped_in_favor_of`, which tries to check whether one of the impls specializes the other: the `specializes` query. In that query, we currently bail early if the impl is local.
However, in a foreign crate, we try to compute if the two impls specialize each other by doing trait solving. This may itself lead to the same situation where we call `specializes`, which will lead to a query cycle.
### How does this fix the problem
We now record whether specialization is enabled in foreign crates, and extend this early-return behavior to foreign impls too. This means that we can only encounter these cycles if we truly have a specializing impl from a crate with specialization enabled.
-----
r? `@oli-obk` or `@lcnr`
offset_of: allow (unstably) taking the offset of slice tail fields
Fields of type `[T]` have a statically known offset, so there is no reason to forbid them in `offset_of!`. This PR adds the `offset_of_slice` feature to allow them.
I created a tracking issue: https://github.com/rust-lang/rust/issues/126151.
Revert: create const block bodies in typeck via query feeding
as per the discussion in https://github.com/rust-lang/rust/pull/125806#discussion_r1622563948
It was a mistake to try to shoehorn const blocks and some specific anon consts into the same box and feed them during typeck. It turned out not simplifying anything (my hope was that we could feed `type_of` to start avoiding the huge HIR matcher, but that didn't work out), but instead making a few things more fragile.
reverts the const-block-specific parts of https://github.com/rust-lang/rust/pull/124650
`@bors` rollup=never had a small perf impact previously
fixes https://github.com/rust-lang/rust/issues/125846
r? `@compiler-errors`
Remove the `ty` field from type system `Const`s
Fixes#125556Fixes#122908
Part of the work on `adt_const_params`/`generic_const_param_types`/`min_generic_const_exprs`/generally making the compiler nicer. cc rust-lang/project-const-generics#44
Please review commit-by-commit otherwise I wasted a lot of time not just squashing this into a giant mess (and also it'll be SO much nicer because theres a lot of fluff changes mixed in with other more careful changes if looking via File Changes
---
Why do this?
- The `ty` field keeps causing ICEs and weird behaviour due to it either being treated as "part of the const" or it being forgotten about leading to ICEs.
- As we move forward with `adt_const_params` and a potential `min_generic_const_exprs` it's going to become more complex to actually lower the correct `Ty<'tcx>`
- It muddles the idea behind how we check `Const` arguments have the correct type. By having the `ty` field it may seem like we ought to be relating it when we relate two types, or that its generally important information about the `Const`.
- Brings the compiler more in line with `a-mir-formality` as that also tracks the type of type system `Const`s via `ConstArgHasType` bounds in the env instead of on the `Const` itself.
- A lot of stuff is a lot nicer when you dont have to pass around the type of a const lol. Everywhere we construct `Const` is now significantly nicer 😅
See #125671's description for some more information about the `ty` field
---
General summary of changes in this PR:
- Add `Ty` to `ConstKind::Value` as otherwise there is no way to implement `ConstArgHasType` to ensure that const arguments are correctly typed for the parameter when we stop creating anon consts for all const args. It's also just incredibly difficult/annoying to thread the correct `Ty` around to a bunch of ctfe functions otherwise.
- Fully implement `ConstArgHasType` in both the old and new solver. Since it now has no reliance on the `ty` field it serves its originally intended purpose of being able to act as a double check that trait vs impls have correctly typed const parameters. It also will now be able to be responsible for checking types of const arguments to parameters under `min_generic_const_exprs`.
- Add `Ty` to `mir::Const::Ty`. I dont have a great understanding of why mir constants are setup like this to be honest. Regardless they need to be able to determine the type of the const and the easiest way to make this happen was to simply store the `Ty` along side the `ty::Const`. Maybe we can do better here in the future but I'd have to spend way more time looking at everywhere we use `mir::Const`.
- rustdoc has its own `Const` which also has a `ty` field. It was relatively easy to remove this.
---
r? `@lcnr` `@compiler-errors`
Don't walk the bodies of free constants for reachability.
follow-up to #122371
cc #119214
This avoids codegening items (e.g. functions) that are only used during const eval, but do not reach their final constant value (e.g. via function pointers).
r? `@tmiasko`
Add intra-doc-links to rustc_middle crate-level docs.
Makes it slightly faster to find these modules, as you don't need to hunt for them in the big list.
Add `size_of` and `size_of_val` and `align_of` and `align_of_val` to the prelude
(Note: need to update the PR to add `align_of` and `align_of_val`, and remove the second commit with the myriad changes to appease the lint.)
Many, many projects use `size_of` to get the size of a type. However,
it's also often equally easy to hardcode a size (e.g. `8` instead of
`size_of::<u64>()`). Minimizing friction in the use of `size_of` helps
ensure that people use it and make code more self-documenting.
The name `size_of` is unambiguous: the name alone, without any prefix or
path, is self-explanatory and unmistakeable for any other functionality.
Adding it to the prelude cannot produce any name conflicts, as any local
definition will silently shadow the one from the prelude. Thus, we don't
need to wait for a new edition prelude to add it.
Store the types of `ty::Expr` arguments in the `ty::Expr`
Part of #125958
In attempting to remove the `ty` field on `Const` it will become necessary to store the `Ty<'tcx>` inside of `Expr<'tcx>`. In order to do this without blowing up the size of `ConstKind`, we start storing the type/const args as `GenericArgs`
r? `@oli-obk`
Align `Term` methods with `GenericArg` methods, add `Term::expect_*`
* `Term::ty` -> `Term::as_type`.
* `Term::ct` -> `Term::as_const`.
* Adds `Term::expect_type` and `Term::expect_const`, and uses them in favor of `.ty().unwrap()`, etc.
I could also shorten these to `as_ty` and then do `GenericArg::as_ty` as well, but I do think the `as_` is important to signal that this is a conversion method, and not a getter, like `Const::ty` is.
r? types
Use parenthetical notation for `Fn` traits
Always use the `Fn(T) -> R` format when printing closure traits instead of `Fn<(T,), Output = R>`.
Address #67100:
```
error[E0277]: expected a `Fn()` closure, found `F`
--> file.rs:6:13
|
6 | call_fn(f)
| ------- ^ expected an `Fn()` closure, found `F`
| |
| required by a bound introduced by this call
|
= note: wrap the `F` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `call_fn`
--> file.rs:1:15
|
1 | fn call_fn<F: Fn() -> ()>(f: &F) {
| ^^^^^^^^^^ required by this bound in `call_fn`
help: consider further restricting this bound
|
5 | fn call_any<F: std::any::Any + Fn()>(f: &F) {
| ++++++
```
Uplift `{Closure,Coroutine,CoroutineClosure}Args` and friends to `rustc_type_ir`
Part of converting the new solver's `structural_traits.rs` to be interner-agnostic.
I decided against aliasing `ClosureArgs<TyCtxt<'tcx>>` to `ClosureArgs<'tcx>` because it seemed so rare. I could do so if desired, though.
r? lcnr
Implement `needs_async_drop` in rustc and optimize async drop glue
This PR expands on #121801 and implements `Ty::needs_async_drop` which works almost exactly the same as `Ty::needs_drop`, which is needed for #123948.
Also made compiler's async drop code to look more like compiler's regular drop code, which enabled me to write an optimization where types which do not use `AsyncDrop` can simply forward async drop glue to `drop_in_place`. This made size of the async block from the [async_drop test](67980dd6fb/tests/ui/async-await/async-drop.rs) to decrease by 12%.
Rename HIR `TypeBinding` to `AssocItemConstraint` and related cleanup
Rename `hir::TypeBinding` and `ast::AssocConstraint` to `AssocItemConstraint` and update all items and locals using the old terminology.
Motivation: The terminology *type binding* is extremely outdated. "Type bindings" not only include constraints on associated *types* but also on associated *constants* (feature `associated_const_equality`) and on RPITITs of associated *functions* (feature `return_type_notation`). Hence the word *item* in the new name. Furthermore, the word *binding* commonly refers to a mapping from a binder/identifier to a "value" for some definition of "value". Its use in "type binding" made sense when equality constraints (e.g., `AssocTy = Ty`) were the only kind of associated item constraint. Nowadays however, we also have *associated type bounds* (e.g., `AssocTy: Bound`) for which the term *binding* doesn't make sense.
---
Old terminology (HIR, rustdoc):
```
`TypeBinding`: (associated) type binding
├── `Constraint`: associated type bound
└── `Equality`: (associated) equality constraint (?)
├── `Ty`: (associated) type binding
└── `Const`: associated const equality (constraint)
```
Old terminology (AST, abbrev.):
```
`AssocConstraint`
├── `Bound`
└── `Equality`
├── `Ty`
└── `Const`
```
New terminology (AST, HIR, rustdoc):
```
`AssocItemConstraint`: associated item constraint
├── `Bound`: associated type bound
└── `Equality`: associated item equality constraint OR associated item binding (for short)
├── `Ty`: associated type equality constraint OR associated type binding (for short)
└── `Const`: associated const equality constraint OR associated const binding (for short)
```
r? compiler-errors
coverage: Rename MC/DC `conditions_num` to `num_conditions`
Updated version of #124571, without the other changes that were split out into #125108 and #125700.
This value represents a quantity of conditions, not an ID, so the new spelling is more appropriate.
Some of the code touched by this PR could perhaps use some other changes, but I would prefer to keep this PR as a simple renaming and avoid scope creep.
`@rustbot` label +A-code-coverage
Always use the `Fn(T) -> R` format when printing closure traits instead of `Fn<(T,), Output = R>`.
Fix#67100:
```
error[E0277]: expected a `Fn()` closure, found `F`
--> file.rs:6:13
|
6 | call_fn(f)
| ------- ^ expected an `Fn()` closure, found `F`
| |
| required by a bound introduced by this call
|
= note: wrap the `F` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `call_fn`
--> file.rs:1:15
|
1 | fn call_fn<F: Fn() -> ()>(f: &F) {
| ^^^^^^^^^^ required by this bound in `call_fn`
help: consider further restricting this bound
|
5 | fn call_any<F: std::any::Any + Fn()>(f: &F) {
| ++++++
```
Omit non-needs_drop drop_in_place in vtables
This replaces the drop_in_place reference with null in vtables. On librustc_driver.so, this drops about ~17k (11%) dynamic relocations from the output, since many vtables can now be placed in read-only memory, rather than having a relocated pointer included.
This makes a tradeoff by adding a null check at vtable call sites. I'm not sure that's readily avoidable without changing the vtable format (e.g., so that we can use a pc-relative relocation instead of an absolute address, and avoid the dynamic relocation that way). But it seems likely that the check is cheap at runtime.
Accepted MCP: https://github.com/rust-lang/compiler-team/issues/730
This replaces the drop_in_place reference with null in vtables. On
librustc_driver.so, this drops about ~17k dynamic relocations from the
output, since many vtables can now be placed in read-only memory, rather
than having a relocated pointer included.
This makes a tradeoff by adding a null check at vtable call sites.
That's hard to avoid without changing the vtable format (e.g., to use a
pc-relative relocation instead of an absolute address, and avoid the
dynamic relocation that way). But it seems likely that the check is
cheap at runtime.
Uplift `EarlyBinder` into `rustc_type_ir`
We also need to give `EarlyBinder` a `'tcx` param, so that we can carry the `Interner` in the `EarlyBinder` too. This is necessary because otherwise we have an unconstrained `I: Interner` parameter in many of the `EarlyBinder`'s inherent impls.
I also generally think that this is desirable to have, in case we later want to track some state in the `EarlyBinder`.
r? lcnr
[perf] Delay the construction of early lint diag structs
Attacks some of the perf regressions from https://github.com/rust-lang/rust/pull/124417#issuecomment-2123700666.
See individual commits for details. The first three commits are not strictly necessary.
However, the 2nd one (06bc4fc671, *Remove `LintDiagnostic::msg`*) makes the main change way nicer to implement.
It's also pretty sweet on its own if I may say so myself.
Remove `DefId` from `EarlyParamRegion`
Currently we represent usages of `Region` parameters via the `ReEarlyParam` or `ReLateParam` variants. The `ReEarlyParam` is effectively equivalent to `TyKind::Param` and `ConstKind::Param` (i.e. it stores a `Symbol` and a `u32` index) however it also stores a `DefId` for the definition of the lifetime parameter.
This was used in roughly two places:
- Borrowck diagnostics instead of threading the appropriate `body_id` down to relevant locations. Interestingly there were already some places that had to pass down a `DefId` manually.
- Some opaque type checking logic was using the `DefId` field to track captured lifetimes
I've split this PR up into a commit for generate rote changes to diagnostics code to pass around a `DefId` manually everywhere, and another commit for the opaque type related changes which likely require more careful review as they might change the semantics of lints/errors.
Instead of manually passing the `DefId` around everywhere I previously tried to bundle it in with `TypeErrCtxt` but ran into issues with some call sites of `infcx.err_ctxt` being unable to provide a `DefId`, particularly places involved with trait solving and normalization. It might be worth investigating adding some new wrapper type to pass this around everywhere but I think this might be acceptable for now.
This pr also has the effect of reducing the size of `EarlyParamRegion` from 16 bytes -> 8 bytes. I wouldn't expect this to have any direct performance improvement however, other variants of `RegionKind` over `8` bytes are all because they contain a `BoundRegionKind` which is, as far as I know, mostly there for diagnostics. If we're ever able to remove this it would shrink the `RegionKind` type from `24` bytes to `12` (and with clever bit packing we might be able to get it to `8` bytes). I am curious what the performance impact would be of removing interning of `Region`'s if we ever manage to shrink `RegionKind` that much.
Sidenote: by removing the `DefId` the `Debug` output for `Region` has gotten significantly nicer. As an example see this opaque type debug print before vs after this PR:
`Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), [DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a)_'a/#0, T, DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a)_'a/#0])`
`Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), ['a/#0, T, 'a/#0])`
r? `@compiler-errors` (I would like someone who understands the opaque type setup to atleast review the type system commit, but the rest is likely reviewable by anyone)
remove proof tree formatting, make em shallow
Debugging via tracing `RUSTC_LOG=rustc_trait_selection::solve=debug` is now imo slightly more readable then the actual proof tree formatter. Removing everything that's not needed for the `analyse` visitor allows us to remove a bunch of code.
I personally believe that we should continue to use tracing over proof trees for debugging:
- it eagerly prints, allowing us to debug ICEs
- the proof tree builder ends up going out of sync with the actual runtime behavior, which is confusing
- using shallow proof trees is a lot more performant as we frequently do not recurse into all nested goals when using an analyse visitor
- this allows us to clean up the implementation and remove some code
r? ```@compiler-errors```
Fail relating constants of different types
fixes#121585fixes#121858fixes#124151
I gave this several attempts before, but we lost too many important diagnostics until I managed to make compilation never bail out early. We have reached this point, so now we can finally fix all those ICEs by bubbling up an error instead of continueing when we encounter a bug.
Warn (or error) when `Self` ctor from outer item is referenced in inner nested item
This implements a warning `SELF_CONSTRUCTOR_FROM_OUTER_ITEM` when a self constructor from an outer impl is referenced in an inner nested item. This is a proper fix mentioned https://github.com/rust-lang/rust/pull/117246#discussion_r1374648388.
This warning is additionally bumped to a hard error when the self type references generic parameters, since it's almost always going to ICE, and is basically *never* correct to do.
This also reverts part of https://github.com/rust-lang/rust/pull/117246, since I believe this is the proper fix and we shouldn't need the helper functions (`opt_param_at`/`opt_type_param`) any longer, since they shouldn't really ever be used in cases where we don't have this problem.
Remove more `#[macro_use] extern crate tracing`
Because explicit importing of macros via use items is nicer (more standard and readable) than implicit importing via `#[macro_use]`. Continuing the work from #124511 and #124914.
r? `@jackh726`
With the removal of `LintDiagnostic::msg` / the `msg` param from
lint diag APIs, primary messages for lint diags are always constructed
lazily inside decorator fns rendering this wrapper type unused / useless.
* instead simply set the primary message inside the lint decorator functions
* it used to be this way before [#]101986 which introduced `msg` to prevent
good path delayed bugs (which no longer exist) from firing under certain
circumstances when lints were suppressed / silenced
* this is no longer necessary for various reasons I presume
* it shaves off complexity and makes further changes easier to implement
Rollup of 7 pull requests
Successful merges:
- #125043 (reference type safety invariant docs: clarification)
- #125306 (Force the inner coroutine of an async closure to `move` if the outer closure is `move` and `FnOnce`)
- #125355 (Use Backtrace::force_capture instead of Backtrace::capture in rustc_log)
- #125382 (rustdoc: rename `issue-\d+.rs` tests to have meaningful names (part 7))
- #125391 (Minor serialize/span tweaks)
- #125395 (Remove unnecessary `.md` from the documentation sidebar)
- #125399 (Stop using `to_hir_binop` in codegen)
r? `@ghost`
`@rustbot` modify labels: rollup
Stop using `to_hir_binop` in codegen
This came up in https://github.com/rust-lang/rust/pull/125359#discussion_r1609401311 , and looking into it we can just use the `mir::BinOp`s directly instead of `hir::BinOpKind`s.
(AKA rather than going `mir::BinOp` → `hir::BinOpKind` → `IntPredicate`, just go `mir::BinOp` → `IntPredicate`.)
An async closure may implement `FnMut`/`Fn` if it has no self-borrows
There's no reason that async closures may not implement `FnMut` or `Fn` if they don't actually borrow anything with the closure's env lifetime. Specifically, #123660 made it so that we don't always need to borrow captures from the closure's env.
See the doc comment on `should_reborrow_from_env_of_parent_coroutine_closure`:
c00957a3e2/compiler/rustc_hir_typeck/src/upvar.rs (L1777-L1823)
If there are no such borrows, then we are free to implement `FnMut` and `Fn` as permitted by our closure's inferred `ClosureKind`.
As far as I can tell, this change makes `async || {}` work in precisely the set of places they used to work before #120361.
Fixes#125247.
r? oli-obk
Add a footer in FileEncoder and check for it in MemDecoder
We have a few reports of ICEs due to decoding failures, where the fault does not lie with the compiler. The goal of this PR is to add some very lightweight and on-by-default validation to the compiler's outputs. If validation fails, we emit a fatal error for rmeta files in general that mentions the path that didn't load, and for incremental compilation artifacts we emit a verbose warning that tries to explain the situation and treat the artifacts as outdated.
The validation currently implemented here is very crude, and yet I think we have 11 ICE reports currently open (you can find them by searching issues for `1002111927320821928687967599834759150`) which this simple validation would have detected. The structure of the code changes here should permit the addition of further validation code, such as a checksum, if it is merited. I would like to have code to detect corruption such as reported in https://github.com/rust-lang/rust/issues/124719, but I'm not yet sure how to do that efficiently, and this PR is already a good size.
The ICE reports I have in mind that this PR would have smoothed over are:
https://github.com/rust-lang/rust/issues/124469https://github.com/rust-lang/rust/issues/123352https://github.com/rust-lang/rust/issues/123376 [^1]
https://github.com/rust-lang/rust/issues/99763https://github.com/rust-lang/rust/issues/93900.
---
[^1]: This one might be a compiler bug, but even if it is I think the workflow described is pushing the envelope of what we can support. This issue is one of the reasons this warning still asks people to file an issue.
Move `#[do_not_recommend]` to the `#[diagnostic]` namespace
This commit moves the `#[do_not_recommend]` attribute to the `#[diagnostic]` namespace. It still requires
`#![feature(do_not_recommend)]` to work.
r? `@compiler-errors`
Translation of the lint message happens when the actual diagnostic is
created, not when the lint is buffered. Generating the message from
BuiltinLintDiag ensures that all required data to construct the message
is preserved in the LintBuffer, eventually allowing the messages to be
moved to fluent.
Remove the `msg` field from BufferedEarlyLint, it is either generated
from the data in the BuiltinLintDiag or stored inside
BuiltinLintDiag::Normal.
Add `IntoIterator` for `Box<[T]>` + edition 2024-specific lints
* Adds a similar method probe opt-out mechanism to the `[T;N]: IntoIterator` implementation for edition 2021.
* Adjusts the relevant lints (shadowed `.into_iter()` calls, new source of method ambiguity).
* Adds some tests.
* Took the liberty to rework the logic in the `ARRAY_INTO_ITER` lint, since it was kind of confusing.
Based mostly off of #116607.
ACP: rust-lang/libs-team#263
References #59878
Tracking for Rust 2024: https://github.com/rust-lang/rust/issues/123759
Crater run was done here: https://github.com/rust-lang/rust/pull/116607#issuecomment-1770293013
Consensus afaict was that there is too much breakage, so let's do this in an edition-dependent way much like `[T; N]: IntoIterator`.
Follow-up fixes to `report_return_mismatched_types`
Some renames, simplifications, fixes, etc. Follow-ups to #123804. I don't think it totally disentangles this code, but it does remove some of the worst offenders on the "I am so confused" scale (e.g. `get_node_fn_decl`).
Uplift `RegionVid`, `TermKind` to `rustc_type_ir`, and `EagerResolver` to `rustc_next_trait_solver`
- Uplift `RegionVid`. This was complicated due to the fact that we implement `polonius_engine::Atom` for `RegionVid` -- but I just separated that into `PoloniusRegionVid`, and added `From`/`Into` impls so it can be defined in `rustc_borrowck` separately. Coherence 😵
- Change `InferCtxtLike` to expose `opportunistically_resolve_{ty,ct,lt,int,float}_var` so that we can uplift `EagerResolver` for use in the canonicalization methods.
- Uplift `TermKind` much like `GenericArgKind`
All of this is miscellaneous dependencies for making more `EvalCtxt` methods generic.
coverage: Memoize and simplify counter expressions
When creating coverage counter expressions as part of coverage instrumentation, we often end up creating obviously-redundant expressions like `c1 + (c0 - c1)`, which is equivalent to just `c0`.
To avoid doing so, this PR checks when we would create an expression matching one of 5 patterns, and uses the simplified form instead:
- `(a - b) + b` → `a`.
- `(a + b) - b` → `a`.
- `(a + b) - a` → `b`.
- `a + (b - a)` → `b`.
- `a - (a - b)` → `b`.
Of all the different ways to combine 3 operands and 2 operators, these are the patterns that allow simplification.
(Some of those patterns currently don't occur in practice, but are included anyway for completeness, to avoid having to add them later as branch coverage and MC/DC coverage support expands.)
---
This PR also adds memoization for newly-created (or newly-simplified) counter expressions, to avoid creating duplicates.
This currently makes no difference to the final mappings, but is expected to be useful for MC/DC coverage of match expressions, as proposed by https://github.com/rust-lang/rust/pull/124278#issuecomment-2106754753.
Uplift more query stuff
- Uplift various query input/response internals
- Uplift the `ProofTree` structures and make the `ProofTreeBuilder` stuff (mostly) generic over `Interner`
- Stop using `TyCtxt::def_kind` in favor of `AliasTerm::kind`
r? lcnr
Rename Unsafe to Safety
Alternative to #124455, which is to just have one Safety enum to use everywhere, this opens the posibility of adding `ast::Safety::Safe` that's useful for unsafe extern blocks.
This leaves us today with:
```rust
enum ast::Safety {
Unsafe(Span),
Default,
// Safe (going to be added for unsafe extern blocks)
}
enum hir::Safety {
Unsafe,
Safe,
}
```
We would convert from `ast::Safety::Default` into the right Safety level according the context.
MIR operators: clarify Shl/Shr handling of negative offsets
"made unsigned" was not fully clear (made unsigned how? by using `abs`? no), so let's say "re-interpreted as an unsigned value of the same size" instead.
r? `@scottmcm`
coverage: `CoverageIdsInfo::mcdc_bitmap_bytes` is never needed
This code for recalculating `mcdc_bitmap_bytes` in a query doesn't provide any benefit, because its result won't have changed from the value in `FunctionCoverageInfo` that was computed during the MIR instrumentation pass.
Extracted from #124571, to avoid having this held up by unrelated issues with condition count checks.
`@rustbot` label +A-code-coverage
Also expand weak alias tys inside consts inside `expand_weak_alias_tys`
Ever since #121344 has been merged, I couldn't let go of the fear that I might've slipped a tiny bug into rustc (:P).
Checking the type flags of the `Const` is strictly more correct than only checking the ones of the `Const`'s `Ty`. I don't think it's possible to trigger an ICE rn (i.e., one of the two `bug!("unexpected weak alias type")` I added in branches where `expand_weak_alias_tys` should've expanded *all* weak alias tys) because presently const exprs aren't allowed to capture late-bound vars. To be future-proof however, we should iron this out.
A possible reproducer would be the following if I'm not mistaken (currently fails to compile due to the aforementioned restriction):
```rs
#![feature(lazy_type_alias, adt_const_params, generic_const_exprs)]
type F = for<'a> fn(A<{ S::<Weak<'a>>(loop {}) }>) -> &'a ();
type A<const N: S<Weak<'static>>> = ();
#[derive(PartialEq, Eq, std::marker::ConstParamTy)]
struct S<T>(T);
type Weak<'a> = &'a ();
```
Whether a late-bound region should actually be considered constrained by a const expr is a separate question — one which we don't need to answer until / unless we actually allow them in such contexts (probable answer: only inside the return exprs of a block but not inside the stmts).
r? oli-obk (he's not available rn but that's fine) or types or compiler
These comments appear to be inspired by the similar comments on
`CounterIncrement` and `ExpressionUsed`. But those comments refer to specific
simplification steps performed during coverage codegen, and there is no
corresponding step for the MC/DC coverage statements.
If these statements do not survive optimization, they will simply not
participate in code generation, just like any other statement.
This code for recalculating `mcdc_bitmap_bytes` doesn't provide any benefit,
because its result won't have changed from the value in `FunctionCoverageInfo`
that was computed during the MIR instrumentation pass.
Split out `ty::AliasTerm` from `ty::AliasTy`
Splitting out `AliasTerm` (for use in project and normalizes goals) and `AliasTy` (for use in `ty::Alias`)
r? lcnr
Many, many projects use `size_of` to get the size of a type. However,
it's also often equally easy to hardcode a size (e.g. `8` instead of
`size_of::<u64>()`). Minimizing friction in the use of `size_of` helps
ensure that people use it and make code more self-documenting.
The name `size_of` is unambiguous: the name alone, without any prefix or
path, is self-explanatory and unmistakeable for any other functionality.
Adding it to the prelude cannot produce any name conflicts, as any local
definition will silently shadow the one from the prelude. Thus, we don't
need to wait for a new edition prelude to add it.
Add `size_of_val`, `align_of`, and `align_of_val` as well, with similar
justification: widely useful, self-explanatory, unmistakeable for
anything else, won't produce conflicts.
Remove `#[macro_use] extern crate rustc middle` from numerous crates
Because explicit importing of macros via `use` items is nicer (more standard and readable) than implicit importing via `#[macro_use]`. This PR mops up some cases I didn't get to in #124511.
r? `@saethlin`
Unfortunately, we can't always offer a machine-applicable suggestion when there are subpatterns from macro expansion.
Co-Authored-By: Guillaume Boisseau <Nadrieril@users.noreply.github.com>
Rename some `FulfillmentErrorCode`/`ObligationCauseCode` variants to be less redundant
1. Rename some `FulfillmentErrorCode` variants.
2. Always use `ObligationCauseCode::` to prefix a code, rather than using a glob import and naming them through `traits::`.
3. Rename some `ObligationCauseCode` variants -- I wasn't particularly thorough with thinking of a new names for these, so could workshop them if necessary.
4. Misc stuff from renaming.
r? lcnr
Refactor float `Primitive`s to a separate `Float` type
Now there are 4 of them, it makes sense to refactor `F16`, `F32`, `F64` and `F128` out of `Primitive` and into a separate `Float` type (like integers already are). This allows patterns like `F16 | F32 | F64 | F128` to be simplified into `Float(_)`, and is consistent with `ty::FloatTy`.
As a side effect, this PR also makes the `Ty::primitive_size` method work with `f16` and `f128`.
Tracking issue: #116909
`@rustbot` label +F-f16_and_f128
Eliminate some `FIXME(lcnr)` comments
In some cases this involved changing code. In some cases the comment was able to removed or replaced.
r? ``@lcnr``
Rename `Generics::params` to `Generics::own_params`
I hope this makes it slightly more obvious that `generics.own_params` is insufficient when considering nested items. I didn't actually audit any of the usages, for the record.
r? lcnr
Fix#124819, where a if-less block causes a wrong output. It is
caused by get_return_block in get_fn_decl. In get_return_block,
when a else-less if expression is the tail expression, the check
for next_node will keep iterating. So it is necessary to make a
early return in the check.
It is optimized for lists with a single element, avoiding the need for
an allocation in that case. But `SmallVec<[T; 1]>` also avoids the
allocation, and is better in general: more standard, log2 number of
allocations if the list exceeds one item, and a much more capable API.
This commit removes `TinyList` and converts the two uses to
`SmallVec<[T; 1]>`. It also reorders the `use` items in the relevant
file so they are in just two sections (`pub` and non-`pub`), ordered
alphabetically, instead of many sections. (This is a relevant part of
the change because I had to decide where to add a `use` item for
`SmallVec`.)
Handle normalization failure in `struct_tail_erasing_lifetimes`
Fixes#113272
The ICE occurred because the struct being normalized had an error. This PR adds some defensive code to guard against that.
never patterns: lower never patterns to `Unreachable` in MIR
This lowers a `!` pattern to "goto Unreachable". Ideally I'd like to read from the place to make it clear that the UB is coming from an invalid value, but that's tricky so I'm leaving it for later.
r? `@compiler-errors` how do you feel about a lil bit of MIR lowering
Use a proof tree visitor to refine the `Obligation` for error reporting in new solver
With the magic of `ProofTreeVisitor`, we can close the gap that we have on `ObligationCause`s being not as descriptive in the new trait solver.
r? lcnr
Needs some work and obviously documentation.
Some hir cleanups
It seemed odd to not put `AnonConst` in the arena, compared with the other types that we did put into an arena. This way we can also give it a `Span` without growing a lot of other HIR data structures because of the extra field.
r? compiler
coverage: Clean up creation of MC/DC condition bitmaps
This PR improves the code for creating and initializing [MC/DC](https://en.wikipedia.org/wiki/Modified_condition/decision_coverage) condition bitmap variables, as introduced by #123409 and modified by #124255.
- The condition bitmap variables are now created eagerly at the start of per-function codegen, via a new `init_coverage` method in `CoverageInfoBuilderMethods`. This avoids having to retroactively create the bitmaps while doing codegen for an individual coverage statement.
- As a result, we can now create and initialize those bitmaps using existing safe APIs, instead of having to perform our own unsafe call to `llvm::LLVMBuildAlloca`.
- This PR also tweaks the way we count the number of condition bitmaps needed, by tracking the total number of bitmaps needed (max depth + 1), instead of only tracking the maximum depth. This reduces the potential for subtle off-by-one confusion.
Stabilize the size of incr comp object file names
The current implementation does not produce stable-length paths, and we create the paths in a way that makes our allocation behavior is nondeterministic. I think `@eddyb` fixed a number of other cases like this in the past, and this PR fixes another one. Whether that actually matters I have no idea, but we still have bimodal behavior in rustc-perf and the non-uniformity in `find` and `ls` was bothering me.
I've also removed the truncation of the mangled CGU names. Before this PR incr comp paths look like this:
```
target/debug/incremental/scratch-38izrrq90cex7/s-gux6gz0ow8-1ph76gg-ewe1xj434l26w9up5bedsojpd/261xgo1oqnd90ry5.o
```
And after, they look like this:
```
target/debug/incremental/scratch-035omutqbfkbw/s-gux6borni0-16r3v1j-6n64tmwqzchtgqzwwim5amuga/55v2re42sztc8je9bva6g8ft3.o
```
On the one hand, I'm sure this will break some people's builds because they're on Windows and only a few bytes from the path length limit. But if we're that seriously worried about the length of our file names, I have some other ideas on how to make them smaller. And last time I deleted some hash truncations from the compiler, there was a huge drop in the number if incremental compilation ICEs that were reported: https://github.com/rust-lang/rust/pull/110367https://github.com/rust-lang/rust/pull/110367
---
Upon further reading, this PR actually fixes a bug. This comment says the CGU names are supposed to be a fixed-length hash, and before this PR they aren't: ca7d34efa9/compiler/rustc_monomorphize/src/partitioning.rs (L445-L448)
Generalize `adjust_from_tcx` for `Allocation`
Previously, `adjust_from_tcx` would take an `Allocation` and "adjust allocation from the ones in `tcx` to a custom Machine instance [...]".
This PR generalizes this so the Machine instance can also determine the `Bytes` type of the output `Allocation`.
r? `@RalfJung`
`ConstKind::Value` is the only variant where control flow leaves the
first match on `impl_ct.kind()`, so there is no need for a second match
on the same expression later on.
Use `tcx.types.unit` instead of `Ty::new_unit(tcx)`
I don't think there is any need for the function, given that we can just access the `.types`, similarly to all other primitives?
Remove many `#[macro_use] extern crate foo` items
This requires the addition of more `use` items, which often make the code more verbose. But they also make the code easier to read, because `#[macro_use]` obscures where macros are defined.
r? `@fee1-dead`
MCDC coverage: support nested decision coverage
#123409 provided the initial MCDC coverage implementation.
As referenced in #124144, it does not currently support "nested" decisions, like the following example :
```rust
fn nested_if_in_condition(a: bool, b: bool, c: bool) {
if a && if b || c { true } else { false } {
say("yes");
} else {
say("no");
}
}
```
Note that there is an if-expression (`if b || c ...`) embedded inside a boolean expression in the decision of an outer if-expression.
This PR proposes a workaround for this cases, by introducing a Decision context stack, and by handing several `temporary condition bitmaps` instead of just one.
When instrumenting boolean expressions, if the current node is a leaf condition (i.e. not a `||`/`&&` logical operator nor a `!` not operator), we insert a new decision context, such that if there are more boolean expressions inside the condition, they are handled as separate expressions.
On the codegen LLVM side, we allocate as many `temp_cond_bitmap`s as necessary to handle the maximum encountered decision depth.
Add decision_depth field to TVBitmapUpdate/CondBitmapUpdate statements
Add decision_depth field to BcbMappingKinds MCDCBranch and MCDCDecision
Add decision_depth field to MCDCBranchSpan and MCDCDecisionSpan
Record certainty of `evaluate_added_goals_and_make_canonical_response` call in candidate
Naming subject to bikeshedding, but I will need this when moving `select` to a proof tree visitor.
r? lcnr
Do not ICE on invalid consts when walking mono-reachable blocks
The `bug!` here was written under the logic of "this condition is impossible, right?" except that of course, if the compiler is given code that results in an compile error, then the situation is possible.
So now we just direct errors into the already-existing path for when we can't do a mono-time optimization.
`obligations_for_self_ty`: use `ProofTreeVisitor` for nested goals
As always, dealing with proof trees continues to be a hacked together mess. After this PR and #124380 the only remaining blocker for core is https://github.com/rust-lang/trait-system-refactor-initiative/issues/90. There is also a `ProofTreeVisitor` issue causing an ICE when compiling `alloc` which I will handle in a separate PR. This issue likely affects coherence diagnostics more generally.
The core idea is to extend the proof tree visitor to support visiting nested candidates without using a `probe`. We then simply recurse into nested candidates if they are the only potentially applicable candidate for a given goal and check whether the self type matches the expected one.
For that to work, we need to improve `CanonicalState` to also handle unconstrained inference variables created inside of the trait solver. This is done by extending the `var_values` of `CanoncalState` with each fresh inference variables. Furthermore, we also store the state of all inference variables at the end of each probe. When recursing into `InspectCandidates` we then unify the values of all these states.
r? `@compiler-errors`
Remove special-casing for `SimplifiedType` for next solver
It's unnecessary due to the way that we fully normalize the self type before assembly begins.
r? lcnr
uses a `ProofTreeVisitor` to look into nested
goals when looking at the pending obligations
during hir typeck. Used by closure signature
inference, coercion, and for async functions.
`-Z debug-macros` is "stabilized" by enabling it by default and removing.
`-Z collapse-macro-debuginfo` is stabilized as `-C collapse-macro-debuginfo`.
It now supports all typical boolean values (`parse_opt_bool`) in addition to just yes/no.
Default value of `collapse_debuginfo` was changed from `false` to `external` (i.e. collapsed if external, not collapsed if local).
`#[collapse_debuginfo]` attribute without a value is no longer supported to avoid guessing the default.
Stabilise inline_const
# Stabilisation Report
## Summary
This PR will stabilise `inline_const` feature in expression position. `inline_const_pat` is still unstable and will *not* be stabilised.
The feature will allow code like this:
```rust
foo(const { 1 + 1 })
```
which is roughly desugared into
```rust
struct Foo;
impl Foo {
const FOO: i32 = 1 + 1;
}
foo(Foo::FOO)
```
This feature is from https://github.com/rust-lang/rfcs/pull/2920 and is tracked in #76001 (the tracking issue should *not* be closed as it needs to track inline const in pattern position). The initial implementation is done in #77124.
## Difference from RFC
There are two major differences (enhancements) as implemented from the RFC. First thing is that the RFC says that the type of an inline const block inferred from the content *within* it, but we currently can infer the type using the information from outside the const block as well. This is a frequently requested feature to the initial implementation (e.g. #89964). The inference is implemented in #89561 and is done by treating inline const similar to a closure and therefore share inference context with its parent body.
This allows code like:
```rust
let v: Vec<i32> = const { Vec::new() };
```
Another enhancement that differs from the RFC is that we currently allow inline consts to reference generic parameters. This is implemented in #96557.
This allows code like:
```rust
fn create_none_array<T, const N: usize>() -> [Option<T>; N] {
[const { None::<T> }; N]
}
```
This enhancement also makes inline const usable as static asserts:
```rust
fn require_zst<T>() {
const { assert!(std::mem::size_of::<T>() == 0) }
}
```
## Documentation
Reference: rust-lang/reference#1295
## Unresolved issues
We still have a few issues that are not resolved, but I don't think it necessarily has to block stabilisation:
* expr fragment specifier issue: #86730
* ~~`const {}` behaves similar to `async {}` but not to `{}` and `unsafe {}` (they are treated as `ExpressionWithoutBlock` rather than `ExpressionWithBlock`): https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/const.20blocks.20differ.20from.20normal.20and.20from.20unsafe.20blocks/near/290229453~~
## Tests
There are a few tests in https://github.com/rust-lang/rust/tree/master/src/test/ui/inline-const
delegation: Support renaming, and async, const, extern "ABI" and C-variadic functions
Also allow delegating to functions with opaque types (`impl Trait`).
The delegation item will refer to the original opaque type from the callee, fresh opaque type won't be created, which seems like a reasonable behavior.
(Such delegation items will cause query cycles when used in trait impls, but it can be fixed later.)
Part of https://github.com/rust-lang/rust/issues/118212.
restrict promotion of `const fn` calls
We only promote them in `const`/`static` initializers, but even that is still unfortunate -- we still cannot add promoteds to required_consts. But we should add them there to make sure it's always okay to evaluate every const we encounter in a MIR body. That effort of not promoting things that can fail to evaluate is tracked in https://github.com/rust-lang/rust/issues/80619. These `const fn` calls are the last missing piece.
So I propose that we do not promote const-fn calls in const when that may fail without the entire const failing, thereby completing https://github.com/rust-lang/rust/issues/80619. Unfortunately we can't just reject promoting these functions outright due to backwards compatibility. So let's see if we can find a hack that makes crater happy...
For the record, this is the [crater analysis](https://github.com/rust-lang/rust/pull/80243#issuecomment-751885520) from when I tried to entirely forbid this kind of promotion. It's a tiny amount of breakage and if we had a nice alternative for code like that, we could conceivably push it through... but sadly, inline const expressions are still blocked on t-lang concerns about post-monomorphization errors and we haven't yet figured out an implementation that can resolve those concerns. So we're forced to make progress via other means, such as terrible hacks like this.
Attempt one: only promote calls on the "safe path" at the beginning of a MIR block. This is the path that starts at the start block and continues via gotos and calls, but stops at the first branch. If we had imposed this restriction before stabilizing `if` and `match` in `const`, this would have definitely been sufficient...
EDIT: Turns out that works. :)
**Here's the t-lang [nomination comment](https://github.com/rust-lang/rust/pull/121557#issuecomment-1990902440).** And here's the [FCP comment](https://github.com/rust-lang/rust/pull/121557#issuecomment-2010306165).
r? `@oli-obk`
Enable `CrateNum` query feeding via `TyCtxt`
Instead of having a magic function that violates some `TyCtxtFeed` invariants, add a `create_def` equivalent for `CrateNum`s.
Note that this still isn't tracked by the query system (unlike `create_def`), and that feeding most `CrateNum` queries for crates other than the local one will likely cause performance regressions.
These things should be attempted on their own separately, but this PR should stand on its own
Also allow `impl Trait` in delegated functions.
The delegation item will refer to the original opaque type from the callee, fresh opaque type won't be created.
Do `check_coroutine_obligations` once per typeck root
We only need to do `check_coroutine_obligations` once per typeck root, especially since the new solver can't really (easily) associate which obligations correspond to which coroutines.
This requires us to move the checks for sized coroutine fields into `mir_coroutine_witnesses`, but that's fine imo.
r? lcnr
deref patterns: lower deref patterns to MIR
This lowers deref patterns to MIR. This is a bit tricky because this is the first kind of pattern that requires storing a value in a temporary. Thanks to https://github.com/rust-lang/rust/pull/123324 false edges are no longer a problem.
The thing I'm not confident about is the handling of fake borrows. This PR ignores any fake borrows inside a deref pattern. We are guaranteed to at least fake borrow the place of the first pointer value, which could be enough, but I'm not certain.
weak lang items are not allowed to be #[track_caller]
For instance the panic handler will be called via this import
```rust
extern "Rust" {
#[lang = "panic_impl"]
fn panic_impl(pi: &PanicInfo<'_>) -> !;
}
```
A `#[track_caller]` would add an extra argument and thus make this the wrong signature.
The 2nd commit is a consistency rename; based on the docs [here](https://doc.rust-lang.org/unstable-book/language-features/lang-items.html) and [here](https://rustc-dev-guide.rust-lang.org/lang-items.html) I figured "lang item" is more widely used. (In the compiler output, "lang item" and "language item" seem to be pretty even.)
Rollup of 7 pull requests
Successful merges:
- #123680 (Deny gen keyword in `edition_2024_compat` lints)
- #124057 (Fix ICE when ADT tail has type error)
- #124168 (Use `DefiningOpaqueTypes::Yes` in rustdoc, where the `InferCtxt` is guaranteed to have no opaque types it can define)
- #124197 (Move duplicated code in functions in `tests/rustdoc-gui/notable-trait.goml`)
- #124200 (Improve handling of expr->field errors)
- #124220 (Miri: detect wrong vtables in wide pointers)
- #124266 (remove an unused type from the reentrant lock tests)
r? `@ghost`
`@rustbot` modify labels: rollup
Add simple async drop glue generation
This is a prototype of the async drop glue generation for some simple types. Async drop glue is intended to behave very similar to the regular drop glue except for being asynchronous. Currently it does not execute synchronous drops but only calls user implementations of `AsyncDrop::async_drop` associative function and awaits the returned future. It is not complete as it only recurses into arrays, slices, tuples, and structs and does not have same sensible restrictions as the old `Drop` trait implementation like having the same bounds as the type definition, while code assumes their existence (requires a future work).
This current design uses a workaround as it does not create any custom async destructor state machine types for ADTs, but instead uses types defined in the std library called future combinators (deferred_async_drop, chain, ready_unit).
Also I recommend reading my [explainer](https://zetanumbers.github.io/book/async-drop-design.html).
This is a part of the [MCP: Low level components for async drop](https://github.com/rust-lang/compiler-team/issues/727) work.
Feature completeness:
- [x] `AsyncDrop` trait
- [ ] `async_drop_in_place_raw`/async drop glue generation support for
- [x] Trivially destructible types (integers, bools, floats, string slices, pointers, references, etc.)
- [x] Arrays and slices (array pointer is unsized into slice pointer)
- [x] ADTs (enums, structs, unions)
- [x] tuple-like types (tuples, closures)
- [ ] Dynamic types (`dyn Trait`, see explainer's [proposed design](https://github.com/zetanumbers/posts/blob/main/async-drop-design.md#async-drop-glue-for-dyn-trait))
- [ ] coroutines (https://github.com/rust-lang/rust/pull/123948)
- [x] Async drop glue includes sync drop glue code
- [x] Cleanup branch generation for `async_drop_in_place_raw`
- [ ] Union rejects non-trivially async destructible fields
- [ ] `AsyncDrop` implementation requires same bounds as type definition
- [ ] Skip trivially destructible fields (optimization)
- [ ] New [`TyKind::AdtAsyncDestructor`](https://github.com/zetanumbers/posts/blob/main/async-drop-design.md#adt-async-destructor-types) and get rid of combinators
- [ ] [Synchronously undroppable types](https://github.com/zetanumbers/posts/blob/main/async-drop-design.md#exclusively-async-drop)
- [ ] Automatic async drop at the end of the scope in async context
coverage: Prepare for improved branch coverage
When trying to rebase my new branch coverage work (including #124154) on top of the introduction of MC/DC coverage (#123409), I found it a lot harder than anticipated. With the benefit of hindsight, the branch coverage code and MC/DC code have become more interdependent than I'm happy with.
This PR therefore disentangles them a bit, so that it will be easier for both areas of code to evolve independently without interference.
---
This PR also includes a few extra branch coverage tests that I had sitting around from my current branch coverage work. They mostly just demonstrate that certain language constructs listed in #124118 currently don't have branch coverage support.
``@rustbot`` label +A-code-coverage
PatRangeBoundary::compare_with: als add a fast-path for signed integers
Not sure if we have a benchmark that hits this... but it seems odd to only do this for unsigned integers.
Implement Modified Condition/Decision Coverage
This is an implementation based on llvm backend support (>= 18) by `@evodius96` and branch coverage support by `@Zalathar.`
### Major changes:
* Add -Zcoverage-options=mcdc as switch. Now coverage options accept either `no-branch`, `branch`, or `mcdc`. `mcdc` also enables `branch` because it is essential to work.
* Add coverage mapping for MCDCBranch and MCDCDecision. Note that MCDCParameter evolves from llvm 18 to llvm 19. The mapping in rust side mainly references to 19 and is casted to 18 types in llvm wrapper.
* Add wrapper for mcdc instrinc functions from llvm. And inject associated statements to mir.
* Add BcbMappingKind::Decision, I'm not sure is it proper but can't find a better way temporarily.
* Let coverage-dump support parsing MCDCBranch and MCDCDecision from llvm ir.
* Add simple tests to check whether mcdc works.
* Same as clang, currently rustc does not generate instrument for decision with more than 6 condtions or only 1 condition due to considerations of resource.
### Implementation Details
1. To get information about conditions and decisions, `MCDCState` in `BranchInfoBuilder` is used during hir lowering to mir. For expressions with logical op we call `Builder::visit_coverage_branch_operation` to record its sub conditions, generate condition ids for them and save their spans (to construct the span of whole decision). This process mainly references to the implementation in clang and is described in comments over `MCDCState::record_conditions`. Also true marks and false marks introduced by branch coverage are used to detect where the decision evaluation ends: the next id of the condition == 0.
2. Once the `MCDCState::decision_stack` popped all recorded conditions, we can ensure that the decision is checked over and push it into `decision_spans`. We do not manually insert decision span to avoid complexity from then_else_break in nested if scopes.
3. When constructing CoverageSpans, add condition info to BcbMappingKind::Branch and decision info to BcbMappingKind::Decision. If the branch mapping has non-zero condition id it will be transformed to MCDCBranch mapping and insert `CondBitmapUpdate` statements to its evaluated blocks. While decision bcb mapping will insert `TestVectorBitmapUpdate` in all its end blocks.
### Usage
```bash
echo "[build]\nprofiler=true" >> config.toml
./x build --stage 1
./x test tests/coverage/mcdc_if.rs
```
to build the compiler and run tests.
```shell
export PATH=path/to/llvm-build:$PATH
rustup toolchain link mcdc build/host/stage1
cargo +mcdc rustc --bin foo -- -Cinstrument-coverage -Zcoverage-options=mcdc
cd target/debug
LLVM_PROFILE_FILE="foo.profraw" ./foo
llvm-profdata merge -sparse foo.profraw -o foo.profdata
llvm-cov show ./foo -instr-profile=foo.profdata --show-mcdc
```
to check "foo" code.
### Problems to solve
For now decision mapping will insert statements to its all end blocks, which may be optimized by inserting a final block of the decision. To do this we must also trace the evaluated value at each end of the decision and join them separately.
This implementation is not heavily tested so there should be some unrevealed issues. We are going to check our rust products in the next. Please let me know if you had any suggestions or comments.
Introduce perma-unstable `wasm-c-abi` flag
Now that `wasm-bindgen` v0.2.88 supports the spec-compliant C ABI, the idea is to switch to that in a future version of Rust. In the meantime it would be good to let people test and play around with it.
This PR introduces a new perma-unstable `-Zwasm-c-abi` compiler flag, which switches to the new spec-compliant C ABI when targeting `wasm32-unknown-unknown`.
Alternatively, we could also stabilize this and then deprecate it when we switch. I will leave this to the Rust maintainers to decide.
This is a companion PR to #117918, but they could be merged independently.
MCP: https://github.com/rust-lang/compiler-team/issues/703
Tracking issue: https://github.com/rust-lang/rust/issues/122532
Outline default query and hook provider function implementations
The default query and hook provider functions call `bug!` with a decently long message.
Due to argument inlining in `format_args!` ([`flatten_format_args`](https://github.com/rust-lang/rust/issues/78356)), this ends up duplicating the message for each query, adding ~90KB to `librustc_driver.so` of unreachable panic messages.
To avoid this, we can outline the common `bug!` logic.
Move size assertions for `mir::syntax` types into the same file
A redundant size assertion for `StatementKind` was added in #122937, because the existing assertion was in a different file.
This PR cleans that up, and also moves the `TerminatorKind` assertion into the same file where it belongs, to avoid the same thing happening again.
r? `@nnethercote`
Implement syntax for `impl Trait` to specify its captures explicitly (`feature(precise_capturing)`)
Implements `impl use<'a, 'b, T, U> Sized` syntax that allows users to explicitly list the captured parameters for an opaque, rather than inferring it from the opaque's bounds (or capturing *all* lifetimes under 2024-edition capture rules). This allows us to exclude some implicit captures, so this syntax may be used as a migration strategy for changes due to #117587.
We represent this list of captured params as `PreciseCapturingArg` in AST and HIR, resolving them between `rustc_resolve` and `resolve_bound_vars`. Later on, we validate that the opaques only capture the parameters in this list.
We artificially limit the feature to *require* mentioning all type and const parameters, since we don't currently have support for non-lifetime bivariant generics. This can be relaxed in the future.
We also may need to limit this to require naming *all* lifetime parameters for RPITIT, since GATs have no variance. I have to investigate this. This can also be relaxed in the future.
r? `@oli-obk`
Tracking issue:
- https://github.com/rust-lang/rust/issues/123432
A redundant size assertion for `StatementKind` was added in #122937, because
the existing assertion was in a different file.
This patch cleans that up, and also moves the `TerminatorKind` assertion into
the same file where it belongs, to avoid the same thing happening again.
Fix pretty HIR for anon consts in diagnostics
This removes the `NoAnn` printer which skips over nested bodies altogether, which is confusing, and requires users of `{ty|qpath|pat}_to_string` to pass in `&tcx` which now impleemnts `hir_pretty::PpAnn`.
There's one case where this "regresses" by actually printing out the body of the anon const -- we could suppress that, but I don't expect people to actually get anon consts like that unless they're fuzzing, tbh.
r? estebank
Don't even parse an intrinsic unless the feature gate is enabled
Don't return true in `tcx.is_intrinsic` if the function is defined locally and `#![feature(intrinsics)]` is not enabled. This is a slightly more general fix than #123526, since #123587 shows that we have simplifying assumptions about intrinsics elsewhere in the compiler.
This will make the code ICE again if the user **enables** `#[feature(intrinsics)]`, but I kind of feel like if we want to fix that, we should make the `INTERNAL_FEATURES` lint `Deny` again. Perhaps we could do that on non-nightly compilers. Or we should just stop compilation altogether if they have `#![feature]` enabled on a non-nightly compiler.
As for the UX of *real* cases of hitting these ICEs, I believe pretty strongly that if a compiler/stdlib dev is modifying internal intrinsics (intentionally, like when making a change to rustc) we have no guarantee to make the ICE better looking for them. Honestly, *not* spitting out a stack trace is probably a disservice to the people who hit those ICEs in that case.
r? `@Nilstrieb` `@estebank`
Remove `TypeVariableOriginKind` and `ConstVariableOriginKind`
It's annoying to have to import `TypeVariableOriginKind` just to fill it with `MiscVariable` for almost every use. Every other usage other than `TypeParameterDefinition` wasn't even used -- I can see how it may have been useful once for debugging, but I do quite a lot of typeck debugging and I've never really needed it.
So let's just remove it, and keep around the only useful thing which is the `DefId` of the param for `var_for_def`.
This is based on #123006, which removed the special use of `TypeVariableOriginKind::OpaqueInference`, which I'm pretty sure I was the one that added.
r? lcnr or re-roll to types
Make the computation of `coroutine_captures_by_ref_ty` more sophisticated
Currently, we treat all the by-(mut/)ref borrows of a coroutine-closure as having a "closure env" borrowed lifetime.
When we have the given code:
```rust
let x: &'a i32 = ...;
let c = async || {
let _x = *x;
};
```
Then when we call:
```rust
c()
// which, because `AsyncFn` takes a `&self`, we insert an autoref:
(&c /* &'env {coroutine-closure} */)()
```
We will return a future whose captures contain `&'env i32` instead of `&'a i32`, which is way more restrictive than necessary. We should be able to drop `c` while the future is alive since it's not actually borrowing any data *originating from within* the closure's captures, but since the capture has that `'env` lifetime, this is not possible.
This wouldn't be true, for example, if the closure captured `i32` instead of `&'a i32`, because the `'env` lifetime is actually *necessary* since the data (`i32`) is owned by the closure.
This PR identifies two criteria where we *need* to take the borrow with the closure env lifetime:
1. If the closure borrows data from inside the closure's captures. This is not true if the parent capture is by-ref, OR if the parent capture is by-move and the child capture begins with a deref projection. This is the example described above.
2. If we're dealing with mutable references, since we cannot reborrow `&'env mut &'a mut i32` into `&'a mut i32`, *only* `&'env mut i32`.
See the documentation on `should_reborrow_from_env_of_parent_coroutine_closure` for more info.
**important:** As disclaimer states on that function, luckily, if this heuristic is not correct, then the program is not unsound, since we still borrowck and validate the choices made from this function -- the only side-effect is that the user may receive unnecessary borrowck errors.
Fixes#123241