`Instance` is `Copy`
No reason to take it by value; it was confusing ``@rcvalle`` to see it being mutated when it's also being passed by ref in some places.
This makes `-Zprint-type-sizes`'s output easier to read, because the
name of an `async fn` is more immediately recognizable than its span.
I also deleted the comment "FIXME(eddyb) should use `def_span`." because
it appears to have already been fixed by commit 67727aa7c3.
Replace `mir_built` query with a hook and use mir_const everywhere instead
A small perf improvement due to less dep graph handling.
Mostly just a cleanup to get rid of one of our many mir queries
Unbox and unwrap the contents of `StatementKind::Coverage`
The payload of coverage statements was historically a structure with several fields, so it was boxed to avoid bloating `StatementKind`.
Now that the payload is a single relatively-small enum, we can replace `Box<Coverage>` with just `CoverageKind`.
This patch also adds a size assertion for `StatementKind`, to avoid accidentally bloating it in the future.
``@rustbot`` label +A-code-coverage
refactor check_{lang,library}_ub: use a single intrinsic
This enacts the plan I laid out [here](https://github.com/rust-lang/rust/pull/122282#issuecomment-1996917998): use a single intrinsic, called `ub_checks` (in aniticpation of https://github.com/rust-lang/compiler-team/issues/725), that just exposes the value of `debug_assertions` (consistently implemented in both codegen and the interpreter). Put the language vs library UB logic into the library.
This makes it easier to do something like https://github.com/rust-lang/rust/pull/122282 in the future: that just slightly alters the semantics of `ub_checks` (making it more approximating when crates built with different flags are mixed), but it no longer affects whether these checks can happen in Miri or compile-time.
The first commit just moves things around; I don't think these macros and functions belong into `intrinsics.rs` as they are not intrinsics.
r? `@saethlin`
Rename `hir::Local` into `hir::LetStmt`
Follow-up of #122776.
As discussed on [zulip](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Improve.20naming.20of.20.60ExprKind.3A.3ALet.60.3F).
I made this change into a separate PR because I'm less sure about this change as is. For example, we have `visit_local` and `LocalSource` items. Is it fine to keep these two as is (I supposed it is but I prefer to ask) or not? Having `Node::Local(LetStmt)` makes things more explicit but is it going too far?
r? ```@oli-obk```
The payload of coverage statements was historically a structure with several
fields, so it was boxed to avoid bloating `StatementKind`.
Now that the payload is a single relatively-small enum, we can replace
`Box<Coverage>` with just `CoverageKind`.
This patch also adds a size assertion for `StatementKind`, to avoid
accidentally bloating it in the future.
Rollup of 8 pull requests
Successful merges:
- #114009 (compiler: allow transmute of ZST arrays with generics)
- #122195 (Note that the caller chooses a type for type param)
- #122651 (Suggest `_` for missing generic arguments in turbofish)
- #122784 (Add `tag_for_variant` query)
- #122839 (Split out `PredicatePolarity` from `ImplPolarity`)
- #122873 (Merge my contributor emails into one using mailmap)
- #122885 (Adjust better spastorino membership to triagebot's adhoc_groups)
- #122888 (add a couple more tests)
r? `@ghost`
`@rustbot` modify labels: rollup
Remove `TypeAndMut` from `ty::RawPtr` variant, make it take `Ty` and `Mutability`
Pretty much mechanically converting `ty::RawPtr(ty::TypeAndMut { ty, mutbl })` to `ty::RawPtr(ty, mutbl)` and its fallout.
r? lcnr
cc rust-lang/types-team#124
Split out `PredicatePolarity` from `ImplPolarity`
Because having to deal with a third `Reservation` level in all the trait solver code is kind of weird.
r? `@lcnr` or `@oli-obk`
Add `tag_for_variant` query
This query allows for sharing code between `rustc_const_eval` and `rustc_transmutability`. It's a precursor to a PR I'm working on to entirely replace the bespoke layout computations in `rustc_transmutability`.
r? `@compiler-errors`
compiler: allow transmute of ZST arrays with generics
Extend the `SizeSkeleton` evaluator to shortcut zero-sized arrays, thus considering `[T; 0]` to have a compile-time fixed-size of 0.
The existing evaluator already deals with generic arrays under the feature-guard `transmute_const_generics`. However, it merely allows comparing fixed-size types with fixed-size types, and generic types with generic types. For generic types, it merely compares whether their arguments match (ordering them first). Even if their exact sizes are not known at compile time, it can ensure that they will eventually be the same.
This patch extends this by shortcutting the size-evaluation of zero sized arrays and thus allowing size comparisons of `()` with `[T; 0]`, where one contains generics and the other does not.
This code is guarded by `transmute_const_generics` (#109929), even though it is unclear whether it should be. However, this assumes that a separate stabilization PR is required to move this out of the feature guard.
Initially reported in #98104.
"Handle" calls to upstream monomorphizations in compiler_builtins
This is pretty cooked, but I think it works.
compiler-builtins has a long-standing problem that at link time, its rlib cannot contain any calls to `core`. And yet, in codegen we _love_ inserting calls to symbols in `core`, generally from various panic entrypoints.
I intend this PR to attack that problem as completely as possible. When we generate a function call, we now check if we are generating a function call from `compiler_builtins` and whether the callee is a function which was not lowered in the current crate, meaning we will have to link to it.
If those conditions are met, actually generating the call is asking for a linker error. So we don't. If the callee diverges, we lower to an abort with the same behavior as `core::intrinsics::abort`. If the callee does not diverge, we produce an error. This means that compiler-builtins can contain panics, but they'll SIGILL instead of panicking. I made non-diverging calls a compile error because I'm guessing that they'd mostly get into compiler-builtins by someone making a mistake while working on the crate, and compile errors are better than linker errors. We could turn such calls into aborts as well if that's preferred.
This skips emitting extra arguments at every callsite (of which there
can be many). For a librustc_driver build with overflow checks enabled,
this cuts 0.7MB from the resulting binary.
coverage: Clean up marker statements that aren't needed later
Some of the marker statements used by coverage are added during MIR building for use by the InstrumentCoverage pass (during analysis), and are not needed afterwards.
```@rustbot``` label +A-code-coverage
interpret/allocation: fix aliasing issue in interpreter and refactor getters a bit
That new raw getter will be needed to let Miri pass pointers to natively executed FFI code ("extern-so" mode).
While doing that I realized our get_bytes_mut are named less scary than get_bytes_unchecked so I rectified that. Also I realized `mem_copy_repeatedly` would break if we called it for multiple overlapping copies so I made sure this does not happen.
And I realized that we are actually [violating Stacked Borrows in the interpreter](https://rust-lang.zulipchat.com/#narrow/stream/136281-t-opsem/topic/I.20think.20Miri.20violates.20Stacked.20Borrows.20.F0.9F.99.88).^^ That was introduced in https://github.com/rust-lang/rust/pull/87777.
r? ```@oli-obk```
Some of the marker statements used by coverage are added during MIR building
for use by the InstrumentCoverage pass (during analysis), and are not needed
afterwards.
Implement macro-based deref!() syntax for deref patterns
Stop using `box PAT` syntax for deref patterns, and instead use a perma-unstable macro.
Blocked on #122222
r? `@Nadrieril`
Don't ICE when encountering bound regions in generator interior type
I'm pretty sure this meant to say "`has_free_regions`", probably just a typo in 4a4fc3bb5b. We can have bound regions (because we only convert non-bound regions into existential regions in generator interiors), but we can't have (non-ReErased) free regions.
r? lcnr
deref patterns: bare-bones feature gate and typechecking
I am restarting the deref patterns experimentation. This introduces a feature gate under the lang-team [experimental feature](https://github.com/rust-lang/lang-team/blob/master/src/how_to/experiment.md) process, with [````@cramertj```` as lang-team liaison](https://github.com/rust-lang/lang-team/issues/88) (it's been a while though, you still ok with this ````@cramertj?).```` Tracking issue: https://github.com/rust-lang/rust/issues/87121.
This is the barest-bones implementation I could think of:
- explicit syntax, reusing `box <pat>` because that saves me a ton of work;
- use `Deref` as a marker trait (instead of a yet-to-design `DerefPure`);
- no support for mutable patterns with `DerefMut` for now;
- MIR lowering will come in the next PR. It's the trickiest part.
My goal is to let us figure out the MIR lowering part, which might take some work. And hopefully get something working for std types soon.
This is in large part salvaged from ````@fee1-dead's```` https://github.com/rust-lang/rust/pull/119467.
r? ````@compiler-errors````
recursively evaluate the constants in everything that is 'mentioned'
This is another attempt at fixing https://github.com/rust-lang/rust/issues/107503. The previous attempt at https://github.com/rust-lang/rust/pull/112879 seems stuck in figuring out where the [perf regression](https://perf.rust-lang.org/compare.html?start=c55d1ee8d4e3162187214692229a63c2cc5e0f31&end=ec8de1ebe0d698b109beeaaac83e60f4ef8bb7d1&stat=instructions:u) comes from. In https://github.com/rust-lang/rust/pull/122258 I learned some things, which informed the approach this PR is taking.
Quoting from the new collector docs, which explain the high-level idea:
```rust
//! One important role of collection is to evaluate all constants that are used by all the items
//! which are being collected. Codegen can then rely on only encountering constants that evaluate
//! successfully, and if a constant fails to evaluate, the collector has much better context to be
//! able to show where this constant comes up.
//!
//! However, the exact set of "used" items (collected as described above), and therefore the exact
//! set of used constants, can depend on optimizations. Optimizing away dead code may optimize away
//! a function call that uses a failing constant, so an unoptimized build may fail where an
//! optimized build succeeds. This is undesirable.
//!
//! To fix this, the collector has the concept of "mentioned" items. Some time during the MIR
//! pipeline, before any optimization-level-dependent optimizations, we compute a list of all items
//! that syntactically appear in the code. These are considered "mentioned", and even if they are in
//! dead code and get optimized away (which makes them no longer "used"), they are still
//! "mentioned". For every used item, the collector ensures that all mentioned items, recursively,
//! do not use a failing constant. This is reflected via the [`CollectionMode`], which determines
//! whether we are visiting a used item or merely a mentioned item.
//!
//! The collector and "mentioned items" gathering (which lives in `rustc_mir_transform::mentioned_items`)
//! need to stay in sync in the following sense:
//!
//! - For every item that the collector gather that could eventually lead to build failure (most
//! likely due to containing a constant that fails to evaluate), a corresponding mentioned item
//! must be added. This should use the exact same strategy as the ecollector to make sure they are
//! in sync. However, while the collector works on monomorphized types, mentioned items are
//! collected on generic MIR -- so any time the collector checks for a particular type (such as
//! `ty::FnDef`), we have to just onconditionally add this as a mentioned item.
//! - In `visit_mentioned_item`, we then do with that mentioned item exactly what the collector
//! would have done during regular MIR visiting. Basically you can think of the collector having
//! two stages, a pre-monomorphization stage and a post-monomorphization stage (usually quite
//! literally separated by a call to `self.monomorphize`); the pre-monomorphizationn stage is
//! duplicated in mentioned items gathering and the post-monomorphization stage is duplicated in
//! `visit_mentioned_item`.
//! - Finally, as a performance optimization, the collector should fill `used_mentioned_item` during
//! its MIR traversal with exactly what mentioned item gathering would have added in the same
//! situation. This detects mentioned items that have *not* been optimized away and hence don't
//! need a dedicated traversal.
enum CollectionMode {
/// Collect items that are used, i.e., actually needed for codegen.
///
/// Which items are used can depend on optimization levels, as MIR optimizations can remove
/// uses.
UsedItems,
/// Collect items that are mentioned. The goal of this mode is that it is independent of
/// optimizations: the set of "mentioned" items is computed before optimizations are run.
///
/// The exact contents of this set are *not* a stable guarantee. (For instance, it is currently
/// computed after drop-elaboration. If we ever do some optimizations even in debug builds, we
/// might decide to run them before computing mentioned items.) The key property of this set is
/// that it is optimization-independent.
MentionedItems,
}
```
And the `mentioned_items` MIR body field docs:
```rust
/// Further items that were mentioned in this function and hence *may* become monomorphized,
/// depending on optimizations. We use this to avoid optimization-dependent compile errors: the
/// collector recursively traverses all "mentioned" items and evaluates all their
/// `required_consts`.
///
/// This is *not* soundness-critical and the contents of this list are *not* a stable guarantee.
/// All that's relevant is that this set is optimization-level-independent, and that it includes
/// everything that the collector would consider "used". (For example, we currently compute this
/// set after drop elaboration, so some drop calls that can never be reached are not considered
/// "mentioned".) See the documentation of `CollectionMode` in
/// `compiler/rustc_monomorphize/src/collector.rs` for more context.
pub mentioned_items: Vec<Spanned<MentionedItem<'tcx>>>,
```
Fixes#107503
Split an item bounds and an item's super predicates
This is the moral equivalent of #107614, but instead for predicates this applies to **item bounds**. This PR splits out the item bounds (i.e. *all* predicates that are assumed to hold for the alias) from the item *super predicates*, which are the subset of item bounds which share the same self type as the alias.
## Why?
Much like #107614, there are places in the compiler where we *only* care about super-predicates, and considering predicates that possibly don't have anything to do with the alias is problematic. This includes things like closure signature inference (which is at its core searching for `Self: Fn(..)` style bounds), but also lints like `#[must_use]`, error reporting for aliases, computing type outlives predicates.
Even in cases where considering all of the `item_bounds` doesn't lead to bugs, unnecessarily considering irrelevant bounds does lead to a regression (#121121) due to doing extra work in the solver.
## Example 1 - Trait Aliases
This is best explored via an example:
```
type TAIT<T> = impl TraitAlias<T>;
trait TraitAlias<T> = A + B where T: C;
```
The item bounds list for `Tait<T>` will include:
* `Tait<T>: A`
* `Tait<T>: B`
* `T: C`
While `item_super_predicates` query will include just the first two predicates.
Side-note: You may wonder why `T: C` is included in the item bounds for `TAIT`? This is because when we elaborate `TraitAlias<T>`, we will also elaborate all the predicates on the trait.
## Example 2 - Associated Type Bounds
```
type TAIT<T> = impl Iterator<Item: A>;
```
The `item_bounds` list for `TAIT<T>` will include:
* `Tait<T>: Iterator`
* `<Tait<T> as Iterator>::Item: A`
But the `item_super_predicates` will just include the first bound, since that's the only bound that is relevant to the *alias* itself.
## So what
This leads to some diagnostics duplication just like #107614, but none of it will be user-facing. We only see it in the UI test suite because we explicitly disable diagnostic deduplication.
Regarding naming, I went with `super_predicates` kind of arbitrarily; this can easily be changed, but I'd consider better names as long as we don't block this PR in perpetuity.
For async closures, cap closure kind, get rid of `by_mut_body`
Right now we have three `AsyncFn*` traits, and three corresponding futures that are returned by the `call_*` functions for them. This is fine, but it is a bit excessive, since the future returned by `AsyncFn` and `AsyncFnMut` are identical. Really, the only distinction we need to make with these bodies is "by ref" and "by move".
This PR removes `AsyncFn::CallFuture` and renames `AsyncFnMut::CallMutFuture` to `AsyncFnMut::CallRefFuture`. This simplifies MIR building for async closures, since we don't need to build an extra "by mut" body, but just a "by move" body which is materially different.
We need to do a bit of delicate handling of the ClosureKind for async closures, since we need to "cap" it to `AsyncFnMut` in some cases when we only care about what body we're looking for.
This also fixes a bug where `<{async closure} as Fn>::call` was returning a body that takes the async-closure receiver *by move*.
This also helps align the `AsyncFn` traits to the `LendingFn` traits' eventual designs.
Extend the `SizeSkeleton` evaluator to shortcut zero-sized arrays, thus
considering `[T; 0]` to have a compile-time fixed-size of 0.
The existing evaluator already deals with generic arrays under the
feature-guard `transmute_const_generics`. However, it merely allows
comparing fixed-size types with fixed-size types, and generic types with
generic types. For generic types, it merely compares whether their
arguments match (ordering them first). Even if their exact sizes are not
known at compile time, it can ensure that they will eventually be the
same.
This patch extends this by shortcutting the size-evaluation of zero
sized arrays and thus allowing size comparisons of `()` with `[T; 0]`,
where one contains generics and the other does not.
This code is guarded by `transmute_const_generics` (#109929), even
though it is unclear whether it should be. However, this assumes that a
separate stabilization PR is required to move this out of the feature
guard.
Initially reported in #98104.
various clippy fixes
We need to keep the order of the given clippy lint rules before passing them.
Since clap doesn't offer any useful interface for this purpose out of the box,
we have to handle it manually.
Additionally, this PR makes `-D` rules work as expected. Previously, lint rules were limited to `-W`. By enabling `-D`, clippy began to complain numerous lines in the tree, all of which have been resolved in this PR as well.
Fixes#121481
cc `@matthiaskrgr`
Silence unecessary !Sized binding error
When gathering locals, we introduce a `Sized` obligation for each
binding in the pattern. *After* doing so, we typecheck the init
expression. If this has a type failure, we store `{type error}`, for
both the expression and the pattern. But later we store an inference
variable for the pattern.
We now avoid any override of an existing type on a hir node when they've
already been marked as `{type error}`, and on E0277, when it comes from
`VariableType` we silence the error in support of the type error.
Fix https://github.com/rust-lang/rust/issues/117846
When gathering locals, we introduce a `Sized` obligation for each
binding in the pattern. *After* doing so, we typecheck the init
expression. If this has a type failure, we store `{type error}`, for
both the expression and the pattern. But later we store an inference
variable for the pattern.
We now avoid any override of an existing type on a hir node when they've
already been marked as `{type error}`, and on E0277, when it comes from
`VariableType` we silence the error in support of the type error.
Fix#117846.
Rollup of 10 pull requests
Successful merges:
- #122435 (Don't trigger `unused_qualifications` on global paths)
- #122556 (Extend format arg help for simple tuple index access expression)
- #122634 (compiletest: Add support for `//@ aux-bin: foo.rs`)
- #122677 (Fix incorrect mutable suggestion information for binding in ref pattern.)
- #122691 (Fix ICE: `global_asm!()` Don't Panic When Unable to Evaluate Constant)
- #122695 (Change only_local to a enum type.)
- #122717 (Ensure stack before parsing dot-or-call)
- #122719 (Ensure nested statics have a HIR node to prevent various queries from ICEing)
- #122720 ([doc]:fix error code example)
- #122724 (add test for casting pointer to union with unsized tail)
r? `@ghost`
`@rustbot` modify labels: rollup
misc cleanups from debugging something
rename `instantiate_canonical_with_fresh_inference_vars` to `instantiate_canonical` the substs for the canonical are not solely infer vars as that would be wildly wrong and it is rather confusing to see this method called and think that the entire canonicalization setup is completely broken when it is not 👍
also update region debug printing to be more like the custom impls for Ty/Const, right now regions in debug output are horribly verbose and make it incredibly hard to read but with this atleast boundvars and placeholders when debugging the new solver do not take up excessive amounts of space.
r? `@lcnr`
Use hir::Node helper methods instead of repeating the same impl multiple times
I wanted to do something entirely different and stumbled upon a bunch of cleanups
Fix representation when printing abstract consts
Previously, when printing a const generic expr, it would only display it as `{{const expr}}`. This allows for a more legible representation when printing these out.
I also zipped the types with their constants for abstract consts that contain function calls when using type annotations, eg: `foo(S: usize, true: bool) -> usize` insteaad of `foo(S, true): fn(usize, bool) -> usize` for conciseness.
clean up `Sized` checking
This PR cleans up `sized_constraint` and related functions to make them simpler and faster. This should not make more or less code compile, but it can change error output in some rare cases.
## enums and unions are `Sized`, even if they are not WF
The previous code has some special handling for enums, which made them sized if and only if the last field of each variant is sized. For example given this definition (which is not WF)
```rust
enum E<T1: ?Sized, T2: ?Sized, U1: ?Sized, U2: ?Sized> {
A(T1, T2),
B(U1, U2),
}
```
the enum was sized if and only if `T2` and `U2` are sized, while `T1` and `T2` were ignored for `Sized` checking. After this PR this enum will always be sized.
Unsized enums are not a thing in Rust and removing this special case allows us to return an `Option<Ty>` from `sized_constraint`, rather than a `List<Ty>`.
Similarly, the old code made an union defined like this
```rust
union Union<T: ?Sized, U: ?Sized> {
head: T,
tail: U,
}
```
sized if and only if `U` is sized, completely ignoring `T`. This just makes no sense at all and now this union is always sized.
## apply the "perf hack" to all (non-error) types, instead of just type parameters
This "perf hack" skips evaluating `sized_constraint(adt): Sized` if `sized_constraint(adt): Sized` exactly matches a predicate defined on `adt`, for example:
```rust
// `Foo<T>: Sized` iff `T: Sized`, but we know `T: Sized` from a predicate of `Foo`
struct Foo<T /*: Sized */>(T);
```
Previously this was only applied to type parameters and now it is applied to every type. This means that for example this type is now always sized:
```rust
// Note that this definition is WF, but the type `S<T>` not WF in the global/empty ParamEnv
struct S<T>([T]) where [T]: Sized;
```
I don't anticipate this to affect compile time of any real-world program, but it makes the code a bit nicer and it also makes error messages a bit more consistent if someone does write such a cursed type.
## tuples are sized if the last type is sized
The old solver already has this behavior and this PR also implements it for the new solver and `is_trivially_sized`. This makes it so that tuples work more like a struct defined like this:
```rust
struct TupleN<T1, T2, /* ... */ Tn: ?Sized>(T1, T2, /* ... */ Tn);
```
This might improve the compile time of programs with large tuples a little, but is mostly also a consistency fix.
## `is_trivially_sized` for more types
This function is used post-typeck code (borrowck, const eval, codegen) to skip evaluating `T: Sized` in some cases. It will now return `true` in more cases, most notably `UnsafeCell<T>` and `ManuallyDrop<T>` where `T.is_trivially_sized`.
I'm anticipating that this change will improve compile time for some real world programs.
Stabilize associated type bounds (RFC 2289)
This PR stabilizes associated type bounds, which were laid out in [RFC 2289]. This gives us a shorthand to express nested type bounds that would otherwise need to be expressed with nested `impl Trait` or broken into several `where` clauses.
### What are we stabilizing?
We're stabilizing the associated item bounds syntax, which allows us to put bounds in associated type position within other bounds, i.e. `T: Trait<Assoc: Bounds...>`. See [RFC 2289] for motivation.
In all position, the associated type bound syntax expands into a set of two (or more) bounds, and never anything else (see "How does this differ[...]" section for more info).
Associated type bounds are stabilized in four positions:
* **`where` clauses (and APIT)** - This is equivalent to breaking up the bound into two (or more) `where` clauses. For example, `where T: Trait<Assoc: Bound>` is equivalent to `where T: Trait, <T as Trait>::Assoc: Bound`.
* **Supertraits** - Similar to above, `trait CopyIterator: Iterator<Item: Copy> {}`. This is almost equivalent to breaking up the bound into two (or more) `where` clauses; however, the bound on the associated item is implied whenever the trait is used. See #112573/#112629.
* **Associated type item bounds** - This allows constraining the *nested* rigid projections that are associated with a trait's associated types. e.g. `trait Trait { type Assoc: Trait2<Assoc2: Copy>; }`.
* **opaque item bounds (RPIT, TAIT)** - This allows constraining associated types that are associated with the opaque without having to *name* the opaque. For example, `impl Iterator<Item: Copy>` defines an iterator whose item is `Copy` without having to actually name that item bound.
The latter three are not expressible in surface Rust (though for associated type item bounds, this will change in #120752, which I don't believe should block this PR), so this does represent a slight expansion of what can be expressed in trait bounds.
### How does this differ from the RFC?
Compared to the RFC, the current implementation *always* desugars associated type bounds to sets of `ty::Clause`s internally. Specifically, it does *not* introduce a position-dependent desugaring as laid out in [RFC 2289], and in particular:
* It does *not* desugar to anonymous associated items in associated type item bounds.
* It does *not* desugar to nested RPITs in RPIT bounds, nor nested TAITs in TAIT bounds.
This position-dependent desugaring laid out in the RFC existed simply to side-step limitations of the trait solver, which have mostly been fixed in #120584. The desugaring laid out in the RFC also added unnecessary complication to the design of the feature, and introduces its own limitations to, for example:
* Conditionally lowering to nested `impl Trait` in certain positions such as RPIT and TAIT means that we inherit the limitations of RPIT/TAIT, namely lack of support for higher-ranked opaque inference. See this code example: https://github.com/rust-lang/rust/pull/120752#issuecomment-1979412531.
* Introducing anonymous associated types makes traits no longer object safe, since anonymous associated types are not nameable, and all associated types must be named in `dyn` types.
This last point motivates why this PR is *not* stabilizing support for associated type bounds in `dyn` types, e.g, `dyn Assoc<Item: Bound>`. Why? Because `dyn` types need to have *concrete* types for all associated items, this would necessitate a distinct lowering for associated type bounds, which seems both complicated and unnecessary compared to just requiring the user to write `impl Trait` themselves. See #120719.
### Implementation history:
Limited to the significant behavioral changes and fixes and relevant PRs, ping me if I left something out--
* #57428
* #108063
* #110512
* #112629
* #120719
* #120584Closes#52662
[RFC 2289]: https://rust-lang.github.io/rfcs/2289-associated-type-bounds.html
`NormalizesTo`: return nested goals to caller
Fixes the regression of `paperclip-core`. see https://hackmd.io/IsVAafiOTAaPIFcUxRJufw for more details.
r? ```@compiler-errors```
Provide structured suggestion for `#![feature(foo)]`
```
error: `S2<'_>` is forbidden as the type of a const generic parameter
--> $DIR/lifetime-in-const-param.rs:5:23
|
LL | struct S<'a, const N: S2>(&'a ());
| ^^
|
= note: the only supported types are integers, `bool` and `char`
help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
|
LL + #![feature(adt_const_params)]
|
```
Fix#55941.
```
error: `S2<'_>` is forbidden as the type of a const generic parameter
--> $DIR/lifetime-in-const-param.rs:5:23
|
LL | struct S<'a, const N: S2>(&'a ());
| ^^
|
= note: the only supported types are integers, `bool` and `char`
help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
|
LL + #![feature(adt_const_params)]
|
```
Fix#55941.
`f16` and `f128` step 3: compiler support & feature gate
Continuation of https://github.com/rust-lang/rust/pull/121841, another portion of https://github.com/rust-lang/rust/pull/114607
This PR exposes the new types to the world and adds a feature gate. Marking this as a draft because I need some feedback on where I did the feature gate check. It also does not yet catch type via suffixed literals (so the feature gate test will fail, probably some others too because I haven't belssed).
If there is a better place to check all types after resolution, I can do that. If not, I figure maybe I can add a second gate location in AST when it checks numeric suffixes.
Unfortunately I still don't think there is much testing to be done for correctness (codegen tests or parsed value checks) until we have basic library support. I think that will be the next step.
Tracking issue: https://github.com/rust-lang/rust/issues/116909
r? `@compiler-errors`
cc `@Nilstrieb`
`@rustbot` label +F-f16_and_f128
hir: Remove `opt_local_def_id_to_hir_id` and `opt_hir_node_by_def_id`
Also replace a few `hir_node()` calls with `hir_node_by_def_id()`.
Follow up to https://github.com/rust-lang/rust/pull/120943.
Docs for `thir::ExprKind::Use` and `thir::ExprKind::Let`
These docs are based on my own recent investigations; hopefully they're reasonably accurate.
`Use` was particularly puzzling to me at first, since the name is not very suggestive, and the old docs were quite cryptic.
Rollup of 10 pull requests
Successful merges:
- #117118 ([AIX] Remove AixLinker's debuginfo() implementation)
- #121650 (change std::process to drop supplementary groups based on CAP_SETGID)
- #121764 (Make incremental sessions identity no longer depend on the crate names provided by source code)
- #122212 (Copy byval argument to alloca if alignment is insufficient)
- #122322 (coverage: Initial support for branch coverage instrumentation)
- #122373 (Fix the conflict problem between the diagnostics fixes of lint `unnecessary_qualification` and `unused_imports`)
- #122479 (Implement `Duration::as_millis_{f64,f32}`)
- #122487 (Rename `StmtKind::Local` variant into `StmtKind::Let`)
- #122498 (Update version of cc crate)
- #122503 (Make `SubdiagMessageOp` well-formed)
r? `@ghost`
`@rustbot` modify labels: rollup
coverage: Initial support for branch coverage instrumentation
(This is a review-ready version of the changes that were drafted in #118305.)
This PR adds support for branch coverage instrumentation, gated behind the unstable flag value `-Zcoverage-options=branch`. (Coverage instrumentation must also be enabled with `-Cinstrument-coverage`.)
During THIR-to-MIR lowering (MIR building), if branch coverage is enabled, we collect additional information about branch conditions and their corresponding then/else blocks. We inject special marker statements into those blocks, so that the `InstrumentCoverage` MIR pass can reliably identify them even after the initially-built MIR has been simplified and renumbered.
The rest of the changes are mostly just plumbing needed to gather up the information that was collected during MIR building, and include it in the coverage metadata that we embed in the final binary.
Note that `llvm-cov show` doesn't print branch coverage information in its source views by default; that needs to be explicitly enabled with `--show-branches=count` or similar.
---
The current implementation doesn't have any support for instrumenting `if let` or let-chains. I think it's still useful without that, and adding it would be non-trivial, so I'm happy to leave that for future work.
more eagerly instantiate binders
The old solver sometimes incorrectly used `sub`, change it to explicitly instantiate binders and use `eq` instead. While doing so I also moved the instantiation before the normalize calls. This caused some observable changes, will explain these inline. This PR therefore requires a crater run and an FCP.
r? types
Fix WF for `AsyncFnKindHelper` in new trait solver
`to_opt_closure_kind` ICEs when it sees placeholders... so don't do that
no test b/c I'm too lazy to write a no-core test for this, but I could be convinced otherwise
r? lcnr
This will allow MIR building to check whether a function is eligible for
coverage instrumentation, and avoid collecting branch coverage info if it is
not.
Distinguish between library and lang UB in assert_unsafe_precondition
As described in https://github.com/rust-lang/rust/pull/121583#issuecomment-1963168186, `assert_unsafe_precondition` now explicitly distinguishes between language UB (conditions we explicitly optimize on) and library UB (things we document you shouldn't do, and maybe some library internals assume you don't do).
`debug_assert_nounwind` was originally added to avoid the "only at runtime" aspect of `assert_unsafe_precondition`. Since then the difference between the macros has gotten muddied. This totally revamps the situation.
Now _all_ preconditions shall be checked with `assert_unsafe_precondition`. If you have a precondition that's only checkable at runtime, do a `const_eval_select` hack, as done in this PR.
r? RalfJung
Remove `Ord` from `ClosureKind`
Using `Ord` to accomplish a meaning of subset relationship can be hard to read. The existing uses for that are easily replaced with a `match`, and in my opinion, more readable without needing to resorting to comments to explain the intention.
cc `@compiler-errors`
Using `Ord` to accomplish a meaning of subset relationship
can be hard to read. The existing uses for that are easily
replaced with a `match`, and in my opinion, more readable
without needing to resorting to comments to explain the
intention.
Avoid invoking the `intrinsic` query for DefKinds other than `Fn` or `AssocFn`
fixes the perf regression from https://github.com/rust-lang/rust/pull/120675 by only invoking (and thus inserting into the dep graph) the `intrinsic` query if the `DefKind` matches items that can actually be intrinsics
Merge `collect_mod_item_types` query into `check_well_formed`
follow-up to https://github.com/rust-lang/rust/pull/121154
this removes more potential parallel-compiler bottlenecks and moves diagnostics for the same items next to each other, instead of grouping diagnostics by analysis kind
Make TAITs and ATPITs capture late-bound lifetimes in scope
This generalizes the behavior that RPITs have, where they duplicate their in-scope lifetimes so that they will always *reify* late-bound lifetimes that they capture. This allows TAITs and ATPITs to properly error when they capture in-scope late-bound lifetimes.
r? `@oli-obk` cc `@aliemjay`
Fixes#122093 and therefore https://github.com/rust-lang/rust/pull/120700#issuecomment-1981213868
Add asm goto support to `asm!`
Tracking issue: #119364
This PR implements asm-goto support, using the syntax described in "future possibilities" section of [RFC2873](https://rust-lang.github.io/rfcs/2873-inline-asm.html#asm-goto).
Currently I have only implemented the `label` part, not the `fallthrough` part (i.e. fallthrough is implicit). This doesn't reduce the expressive though, since you can use label-break to get arbitrary control flow or simply set a value and rely on jump threading optimisation to get the desired control flow. I can add that later if deemed necessary.
r? ``@Amanieu``
cc ``@ojeda``
Remove `feed_local_def_id`
best reviewed commit by commit
Basically I returned `TyCtxtFeed` from `create_def` and then preserved that in the local caches
based on https://github.com/rust-lang/rust/pull/121084
r? ````@petrochenkov````
Rollup of 9 pull requests
Successful merges:
- #121958 (Fix redundant import errors for preload extern crate)
- #121976 (Add an option to have an external download/bootstrap cache)
- #122022 (loongarch: add frecipe and relax target feature)
- #122026 (Do not try to format removed files)
- #122027 (Uplift some feeding out of `associated_type_for_impl_trait_in_impl` and into queries)
- #122063 (Make the lowering of `thir::ExprKind::If` easier to follow)
- #122074 (Add missing PartialOrd trait implementation doc for array)
- #122082 (remove outdated fixme comment)
- #122091 (Note why we're using a new thread in `test_get_os_named_thread`)
r? `@ghost`
`@rustbot` modify labels: rollup
Uplift some feeding out of `associated_type_for_impl_trait_in_impl` and into queries
This PR moves the `type_of` and `generics_of` query feeding out of `associated_type_for_impl_trait_in_impl`, since eagerly feeding results in query cycles due to a subtle interaction with `resolve_bound_vars`.
Fixes#122019
r? spastorino
Rework `untranslatable_diagnostic` lint
Currently it only checks calls to functions marked with `#[rustc_lint_diagnostics]`. This PR changes it to check calls to any function with an `impl Into<{D,Subd}iagnosticMessage>` parameter. This greatly improves its coverage and doesn't rely on people remembering to add `#[rustc_lint_diagnostics]`. It also lets us add `#[rustc_lint_diagnostics]` to a number of functions that don't have an `impl Into<{D,Subd}iagnosticMessage>`, such as `Diag::span`.
r? ``@davidtwco``
Rollup of 9 pull requests
Successful merges:
- #121065 (Add basic i18n guidance for `Display`)
- #121744 (Stop using Bubble in coherence and instead emulate it with an intercrate check)
- #121829 (Dummy tweaks (attempt 2))
- #121857 (Implement async closure signature deduction)
- #121894 (const_eval_select: make it safe but be careful with what we expose on stable for now)
- #122014 (Change some attributes to only_local.)
- #122016 (will_wake tests fail on Miri and that is expected)
- #122018 (only set noalias on Box with the global allocator)
- #122028 (Remove some dead code)
r? `@ghost`
`@rustbot` modify labels: rollup
Rollup of 8 pull requests
Successful merges:
- #121202 (Limit the number of names and values in check-cfg diagnostics)
- #121301 (errors: share `SilentEmitter` between rustc and rustfmt)
- #121658 (Hint user to update nightly on ICEs produced from outdated nightly)
- #121846 (only compare ambiguity item that have hard error)
- #121961 (add test for #78894#71450)
- #121975 (hir_analysis: enums return `None` in `find_field`)
- #121978 (Fix duplicated path in the "not found dylib" error)
- #121991 (Merge impl_trait_in_assoc_types_defined_by query back into `opaque_types_defined_by`)
r? `@ghost`
`@rustbot` modify labels: rollup
Instead, when we're collecting opaques for associated items, we choose the right collection mode depending on whether we're collecting for an associated item of a trait impl or not.
From `impl Into<DiagnosticMessage>` to `impl Into<Cow<'static, str>>`.
Because these functions don't produce user-facing output and we don't
want their strings to be translated.
Add a scheme for moving away from `extern "rust-intrinsic"` entirely
All `rust-intrinsic`s can become free functions now, either with a fallback body, or with a dummy body and an attribute, requiring backends to actually implement the intrinsic.
This PR demonstrates the dummy-body scheme with the `vtable_size` intrinsic.
cc https://github.com/rust-lang/rust/issues/63585
follow-up to #120500
MCP at https://github.com/rust-lang/compiler-team/issues/720
Existing names for values of this type are `sess`, `parse_sess`,
`parse_session`, and `ps`. `sess` is particularly annoying because
that's also used for `Session` values, which are often co-located, and
it can be difficult to know which type a value named `sess` refers to.
(That annoyance is the main motivation for this change.) `psess` is nice
and short, which is good for a name used this much.
The commit also renames some `parse_sess_created` values as
`psess_created`.
Add new `pattern_complexity` attribute to add possibility to limit and check recursion in pattern matching
Needed for https://github.com/rust-lang/rust-analyzer/issues/9528.
This PR adds a new attribute only available when running rust testsuite called `pattern_complexity` which allows to set the maximum recursion for the pattern matching. It is quite useful to ensure the complexity doesn't grow, like in `tests/ui/pattern/usefulness/issue-118437-exponential-time-on-diagonal-match.rs`.
r? `@Nadrieril`
`f16` and `f128` step 2: intrinsics
Continuation of https://github.com/rust-lang/rust/pull/121728, another portion of https://github.com/rust-lang/rust/pull/114607.
This PR adds `f16` and `f128` intrinsics, and hooks them up to both HIR and LLVM. This is all still unexposed to the frontend, which will probably be the next step. Also update itanium mangling per `@rcvalle's` in https://github.com/rust-lang/rust/pull/121728/files#r1506570300, and fix a typo from step 1.
Once these types are usable in code, I will add the codegen tests from #114607 (codegen is passing on that branch)
This does add more `unimplemented!`s to Clippy, but I still don't think we can do better until library support is added.
r? `@compiler-errors`
cc `@Nilstrieb`
`@rustbot` label +T-compiler +F-f16_and_f128
Improve error messages for generics with default parameters
Fixes#120785
Issue: Previously, all type parameters with default types were deliberately ignored to simplify error messages. For example, an error message for Box type would display `Box<T>` instead of `Box<T, _>`. But, this resulted in unclear error message when a concrete type was used instead of the default type.
Fix: This PR fixes it by checking if a concrete type is specified after a default type to display the entire type name or the simplified type name.
Combine `Sub` and `Equate`
Combine `Sub` and `Equate` into a new relation called `TypeRelating` (that name sounds familiar...)
Tracks the difference between `Sub` and `Equate` via `ambient_variance: ty::Variance` much like the `NllTypeRelating` relation, but implemented slightly jankier because it's a more general purpose relation.
r? lcnr
Add stubs in IR and ABI for `f16` and `f128`
This is the very first step toward the changes in https://github.com/rust-lang/rust/pull/114607 and the [`f16` and `f128` RFC](https://rust-lang.github.io/rfcs/3453-f16-and-f128.html). It adds the types to `rustc_type_ir::FloatTy` and `rustc_abi::Primitive`, and just propagates those out as `unimplemented!` stubs where necessary.
These types do not parse yet so there is no feature gate, and it should be okay to use `unimplemented!`.
The next steps will probably be AST support with parsing and the feature gate.
r? `@compiler-errors`
cc `@Nilstrieb` suggested breaking the PR up in https://github.com/rust-lang/rust/pull/120645#issuecomment-1925900572
allow statics pointing to mutable statics
Fixes https://github.com/rust-lang/rust/issues/120450 for good. We can even simplify our checks: no need to specifically go looking for mutable references in const, we can just reject any reference that points to something mutable.
r? `@oli-obk`
Count stashed errors again
Stashed diagnostics are such a pain. Their "might be emitted, might not" semantics messes with lots of things.
#120828 and #121206 made some big changes to how they work, improving some things, but still leaving some problems, as seen by the issues caused by #121206. This PR aims to fix all of them by restricting them in a way that eliminates the "might be emitted, might not" semantics while still allowing 98% of their benefit. Details in the individual commit logs.
r? `@oli-obk`
Skip unnecessary comparison with half-open range patterns
This is the last remaining detail in the implementation of half-open range patterns. Until now, a half-open range pattern like `10..` was converted to `10..T::MAX` before lowering to MIR, which generated an extra pointless comparison. With this PR we don't generate it.
Stashed errors used to be counted as errors, but could then be
cancelled, leading to `ErrorGuaranteed` soundness holes. #120828 changed
that, closing the soundness hole. But it introduced other difficulties
because you sometimes have to account for pending stashed errors when
making decisions about whether errors have occured/will occur and it's
easy to overlook these.
This commit aims for a middle ground.
- Stashed errors (not warnings) are counted immediately as emitted
errors, avoiding the possibility of forgetting to consider them.
- The ability to cancel (or downgrade) stashed errors is eliminated, by
disallowing the use of `steal_diagnostic` with errors, and introducing
the more restrictive methods `try_steal_{modify,replace}_and_emit_err`
that can be used instead.
Other things:
- `DiagnosticBuilder::stash` and `DiagCtxt::stash_diagnostic` now both
return `Option<ErrorGuaranteed>`, which enables the removal of two
`delayed_bug` calls and one `Ty::new_error_with_message` call. This is
possible because we store error guarantees in
`DiagCtxt::stashed_diagnostics`.
- Storing the guarantees also saves us having to maintain a counter.
- Calls to the `stashed_err_count` method are no longer necessary
alongside calls to `has_errors`, which is a nice simplification, and
eliminates two more `span_delayed_bug` calls and one FIXME comment.
- Tests are added for three of the four fixed PRs mentioned below.
- `issue-121108.rs`'s output improved slightly, omitting a non-useful
error message.
Fixes#121451.
Fixes#121477.
Fixes#121504.
Fixes#121508.
This gives one extra error message on one test, but is necessary to fix
bigger problems caused by the cancellation of stashed errors.
(Note: why not just avoid stashing altogether? Because that resulted in
additional output changes.)
Diagnostic renaming
Renaming various diagnostic types from `Diagnostic*` to `Diag*`. Part of https://github.com/rust-lang/compiler-team/issues/722. There are more to do but this is enough for one PR.
r? `@davidtwco`
Split rustc_type_ir to avoid rustc_ast from depending on it
unblocks #121576
and resolves a FIXME in `rustc_ast`'s `Cargo.toml`
The new crate is tiny, but it will get bigger in #121576
Delayed bug audit
I went through all the calls to `delayed_bug` and `span_delayed_bug` and found a few places where they could be avoided.
r? `@compiler-errors`
Add `StructurallyRelateAliases` to allow instantiating infer vars with rigid aliases.
Change `instantiate_query_response` to be infallible in the new solver. This requires canonicalization to not hide any information used by the query, so weaken
universe compression. It also modifies `term_is_fully_unconstrained` to allow
region inference variables in a higher universe.
mark `min_exhaustive_patterns` as complete
This is step 1 and 2 of my [proposal](https://github.com/rust-lang/rust/issues/119612#issuecomment-1918097361) to move `min_exhaustive_patterns` forward. The vast majority of in-tree use cases of `exhaustive_patterns` are covered by `min_exhaustive_patterns`. There are a few cases that still require `exhaustive_patterns` in tests and they're all behind references.
r? ``@ghost``
region unification: update universe of region vars
necessary for #119106. see inline comment for why this is necessary
r? `@compiler-errors` `@BoxyUwU`
Provide suggestions through `rustc_confusables` annotations
Help with common API confusion, like asking for `push` when the data structure really has `append`.
```
error[E0599]: no method named `size` found for struct `Vec<{integer}>` in the current scope
--> $DIR/rustc_confusables_std_cases.rs:17:7
|
LL | x.size();
| ^^^^
|
help: you might have meant to use `len`
|
LL | x.len();
| ~~~
help: there is a method with a similar name
|
LL | x.resize();
| ~~~~~~
```
Fix#59450 (we can open subsequent tickets for specific cases).
Fix#108437:
```
error[E0599]: `Option<{integer}>` is not an iterator
--> f101.rs:3:9
|
3 | opt.flat_map(|val| Some(val));
| ^^^^^^^^ `Option<{integer}>` is not an iterator
|
::: /home/gh-estebank/rust/library/core/src/option.rs:571:1
|
571 | pub enum Option<T> {
| ------------------ doesn't satisfy `Option<{integer}>: Iterator`
|
= note: the following trait bounds were not satisfied:
`Option<{integer}>: Iterator`
which is required by `&mut Option<{integer}>: Iterator`
help: you might have meant to use `and_then`
|
3 | opt.and_then(|val| Some(val));
| ~~~~~~~~
```
On type error of method call arguments, look at confusables for suggestion. Fix#87212:
```
error[E0308]: mismatched types
--> f101.rs:8:18
|
8 | stuff.append(Thing);
| ------ ^^^^^ expected `&mut Vec<Thing>`, found `Thing`
| |
| arguments to this method are incorrect
|
= note: expected mutable reference `&mut Vec<Thing>`
found struct `Thing`
note: method defined here
--> /home/gh-estebank/rust/library/alloc/src/vec/mod.rs:2025:12
|
2025 | pub fn append(&mut self, other: &mut Self) {
| ^^^^^^
help: you might have meant to use `push`
|
8 | stuff.push(Thing);
| ~~~~
```
Make --verbose imply -Z write-long-types-to-disk=no
When shortening the type it is necessary to take into account the `--verbose` flag, if it is activated, we must always show the entire type and not write it in a file.
Fixes: https://github.com/rust-lang/rust/issues/119130
Convert `delayed_bug`s to `bug`s.
I have a suspicion that quite a few delayed bug paths are impossible to reach, so I did an experiment.
I converted every `delayed_bug` to a `bug`, ran the full test suite, then converted back every `bug` that was hit. A surprising number were never hit.
This is too dangerous to merge. Increased coverage (fuzzing or a crater run) would likely hit more cases. But it might be useful for people to look at and think about which paths are genuinely unreachable.
r? `@ghost`
I have a suspicion that quite a few delayed bug paths are impossible to
reach, so I did an experiment.
I converted every `delayed_bug` to a `bug`, ran the full test suite,
then converted back every `bug` that was hit. A surprising number were
never hit.
The next commit will convert some more back, based on human judgment.
Overhaul `Diagnostic` and `DiagnosticBuilder`
Implements the first part of https://github.com/rust-lang/compiler-team/issues/722, which moves functionality and use away from `Diagnostic`, onto `DiagnosticBuilder`.
Likely follow-ups:
- Move things around, because this PR was written to minimize diff size, so some things end up in sub-optimal places. E.g. `DiagnosticBuilder` has impls in both `diagnostic.rs` and `diagnostic_builder.rs`.
- Rename `Diagnostic` as `DiagInner` and `DiagnosticBuilder` as `Diag`.
r? `@davidtwco`
When shortening the type it is necessary to take into account the
`--verbose` flag, if it is activated, we must always show the entire
type and not write it in a file.
Fixes: https://github.com/rust-lang/rust/issues/119130
Allow AST and HIR visitors to return `ControlFlow`
Alternative to #108598.
Since rust-lang/libs-team#187 was rejected, this implements our own version of the `Try` trait (`VisitorResult`) and the `try` macro (`try_visit`). Since this change still allows visitors to return `()`, no changes have been made to the existing ones. They can be done in a separate PR.
There are lots of functions that modify a diagnostic. This can be via a
`&mut Diagnostic` or a `&mut DiagnosticBuilder`, because the latter type
wraps the former and impls `DerefMut`.
This commit converts all the `&mut Diagnostic` occurrences to `&mut
DiagnosticBuilder`. This is a step towards greatly simplifying
`Diagnostic`. Some of the relevant function are made generic, because
they deal with both errors and warnings. No function bodies are changed,
because all the modifier methods are available on both `Diagnostic` and
`DiagnosticBuilder`.
fixes#117448
For example unnecessary imports in std::prelude that can be eliminated:
```rust
use std::option::Option::Some;//~ WARNING the item `Some` is imported redundantly
use std::option::Option::None; //~ WARNING the item `None` is imported redundantly
```
Add and use a simple extension trait derive macro in the compiler
Adds `#[extension]` to `rustc_macros` for implementing an extension trait. This expands an impl (with an optional visibility) into two parallel trait + impl definitions.
before:
```rust
pub trait Extension {
fn a();
}
impl Extension for () {
fn a() {}
}
```
to:
```rust
#[extension]
pub impl Extension for () {
fn a() {}
}
```
Opted to just implement it by hand because I couldn't figure if there was a "canonical" choice of extension trait macro in the ecosystem. It's really lightweight anyways, and can always be changed.
I'm interested in adding this because I'd like to later split up the large `TypeErrCtxtExt` traits into several different files. This should make it one step easier.
allow mutable references in const values when they point to no memory
Fixes https://github.com/rust-lang/rust/issues/120450
The second commit is just some drive-by test suite cleanup.
r? `@oli-obk`
Implement intrinsics with fallback bodies
fixes#93145 (though we can port many more intrinsics)
cc #63585
The way this works is that the backend logic for generating custom code for intrinsics has been made fallible. The only failure path is "this intrinsic is unknown". The `Instance` (that was `InstanceDef::Intrinsic`) then gets converted to `InstanceDef::Item`, which represents the fallback body. A regular function call to that body is then codegenned. This is currently implemented for
* codegen_ssa (so llvm and gcc)
* codegen_cranelift
other backends will need to adjust, but they can just keep doing what they were doing if they prefer (though adding new intrinsics to the compiler will then require them to implement them, instead of getting the fallback body).
cc `@scottmcm` `@WaffleLapkin`
### todo
* [ ] miri support
* [x] default intrinsic name to name of function instead of requiring it to be specified in attribute
* [x] make sure that the bodies are always available (must be collected for metadata)
Only point out non-diverging arms for match suggestions
Fixes#121144
There is no reason to point at diverging arms, which will always coerce to whatever is the match block's evaluated type.
This also removes the suggestion from #106601, since as I pointed out in https://github.com/rust-lang/rust/issues/72634#issuecomment-1946210898 the added suggestion is not firing in the right cases, but instead only when one of the match arms already *actually* evaluates to `()`.
r? estebank
Store static initializers in metadata instead of the MIR of statics.
This means that adding generic statics would be even more difficult, as we can't evaluate statics from other crates anymore, but the subtle issue I have encountered make me think that having this be an explicit problem is better.
The issue is that
```rust
static mut FOO: &mut u32 = &mut 42;
static mut BAR = unsafe { FOO };
```
gets different allocations, instead of referring to the same one. This is also true for non-static mut, but promotion makes `static FOO: &u32 = &42;` annoying to demo.
Fixes https://github.com/rust-lang/rust/issues/61345
## Why is this being done?
In order to ensure all crates see the same nested allocations (which is the last issue that needs fixing before we can stabilize [`const_mut_refs`](https://github.com/rust-lang/rust/issues/57349)), I am working on creating anonymous (from the Rust side, to LLVM it's like a regular static item) static items for the nested allocations in a static. If we evaluate the static item in a downstream crate again, we will end up duplicating its nested allocations (and in some cases, like the `match` case, even duplicate the main allocation).
Enforce coroutine-closure layouts are identical
Enforce that for an async closure, the by-ref and by-move coroutine layouts are identical. This is just a sanity check to make sure that optimizations aren't doing anything fishy.
r? oli-obk
Make sure `tcx.create_def` also depends on the forever red node, instead of just `tcx.at(span).create_def`
oversight from https://github.com/rust-lang/rust/pull/119136
Not actually an issue, because all uses of `tcx.create_def` were in the resolver, which is `eval_always`, but still good to harden against future uses of `create_def`
cc `@petrochenkov` `@WaffleLapkin`
Make sure `tcx.create_def` also depends on the forever red node, instead of just `tcx.at(span).create_def`
oversight from https://github.com/rust-lang/rust/pull/119136
Not actually an issue, because all uses of `tcx.create_def` were in the resolver, which is `eval_always`, but still good to harden against future uses of `create_def`
cc `@petrochenkov` `@WaffleLapkin`
Extend documentation for `Ty::to_opt_closure_kind` method
This API was... surprising to use. With a little extra documentation, the weirdness can be reduced quite a lot. :)
r? `@compiler-errors`
Uplift `TypeVisitableExt` into `rustc_type_ir`
This uplifts `TypeVisitableExt` into `rustc_type_ir` so it can be used in an interner-agnostic way. It also moves some `TypeSuperVisitable` bounds onto `Interner` since we don't expect to support libraries that have types which aren't foldable by default.
This restores a couple of asserts in the canonicalizer code we uplifted, and also makes it so that we can use type-flags-based helpers in the solver code, which I'm interested in uplifting.
r? lcnr
Fully stop using the HIR in trait impl checks
At least I hope I found all happy path usages. I'll need to check if I can figure out a way to make queries declare that they don't access the HIR except in error paths
Properly handle `async` block and `async fn` in `if` exprs without `else`
When encountering a tail expression in the then arm of an `if` expression without an `else` arm, account for `async fn` and `async` blocks to suggest `return`ing the value and pointing at the return type of the `async fn`.
We now also account for AFIT when looking for the return type to point at.
Fix#115405.
Merge `impl_polarity` and `impl_trait_ref` queries
Hopefully this is perf neutral. I want to finish https://github.com/rust-lang/rust/pull/120835 and stop using the HIR in `coherent_trait`, which should then give us a perf improvement.
It's only has a single remaining purpose: to ensure that a diagnostic is
printed when `trimmed_def_paths` is used. It's an annoying mechanism:
weak, with odd semantics, badly named, and gets in the way of other
changes.
This commit replaces it with a simpler `must_produce_diag` mechanism,
getting rid of a diagnostic `Level` along the way.
Dejargonize `subst`
In favor of #110793, replace almost every occurence of `subst` and `substitution` from rustc codes, but they still remains in subtrees under `src/tools/` like clippy and test codes (I'd like to replace them after this)
Fix async closures in CTFE
First commit renames `is_coroutine_or_closure` into `is_closure_like`, because `is_coroutine_or_closure_or_coroutine_closure` seems confusing and long.
Second commit fixes some forgotten cases where we want to handle `TyKind::CoroutineClosure` the same as closures and coroutines.
The test exercises the change to `ValidityVisitor::aggregate_field_path_elem` which is the source of #120946, but not the change to `UsedParamsNeedSubstVisitor`, though I feel like it's not that big of a deal. Let me know if you'd like for me to look into constructing a test for the latter, though I have no idea what it'd look like (we can't assert against `TooGeneric` anywhere?).
Fixes#120946
r? oli-obk cc ``@RalfJung``
When encountering a tail expression in the then arm of an `if` expression
without an `else` arm, account for `async fn` and `async` blocks to
suggest `return`ing the value and pointing at the return type of the
`async fn`.
We now also account for AFIT when looking for the return type to point at.
Fix#115405.
Rollup of 11 pull requests
Successful merges:
- #120765 (Reorder diagnostics API)
- #120833 (More internal emit diagnostics cleanups)
- #120899 (Gracefully handle non-WF alias in `assemble_alias_bound_candidates_recur`)
- #120917 (Remove a bunch of dead parameters in functions)
- #120928 (Add test for recently fixed issue)
- #120933 (check_consts: fix duplicate errors, make importance consistent)
- #120936 (improve `btree_cursors` functions documentation)
- #120944 (Check that the ABI of the instance we are inlining is correct)
- #120956 (Clean inlined type alias with correct param-env)
- #120962 (Add myself to library/std review)
- #120972 (fix ICE for deref coercions with type errors)
r? `@ghost`
`@rustbot` modify labels: rollup
Assert that params with the same *index* have the same *name*
Found this bug when trying to build libcore with the new solver, since it will canonicalize two params with the same index into *different* placeholders if those params differ by name.
Print kind of coroutine closure
Make sure that we print "async closure" when we have an async closure, rather than calling it generically a ["coroutine-closure"](https://github.com/rust-lang/rust/pull/120361).
Fixes#120886
r? oli-obk
Remove the FIXME and keep `CRATE_HIR_ID` being its own parent.
This scheme turned out to be more practical than having an `Option` on closer inspection.
Also make `hir_owner_parent` more readable.
improve normalization of `Pointee::Metadata`
This PR makes it so that `<Wrapper<Tail> as Pointee>::Metadata` is normalized to `<Tail as Pointee>::Metadata` if we don't know `Wrapper<Tail>: Sized`. With that, the trait solver can prove projection predicates like `<Wrapper<Tail> as Pointee>::Metadata == <Tail as Pointee>::Metadata`, which makes it possible to use the metadata APIs to cast between the tail and the wrapper:
```rust
#![feature(ptr_metadata)]
use std::ptr::{self, Pointee};
fn cast_same_meta<T: ?Sized, U: ?Sized>(ptr: *const T) -> *const U
where
T: Pointee<Metadata = <U as Pointee>::Metadata>,
{
let (thin, meta) = ptr.to_raw_parts();
ptr::from_raw_parts(thin, meta)
}
struct Wrapper<T: ?Sized>(T);
fn cast_to_wrapper<T: ?Sized>(ptr: *const T) -> *const Wrapper<T> {
cast_same_meta(ptr)
}
```
Previously, this failed to compile:
```
error[E0271]: type mismatch resolving `<Wrapper<T> as Pointee>::Metadata == <T as Pointee>::Metadata`
--> src/lib.rs:16:5
|
15 | fn cast_to_wrapper<T: ?Sized>(ptr: *const T) -> *const Wrapper<T> {
| - found this type parameter
16 | cast_same_meta(ptr)
| ^^^^^^^^^^^^^^ expected `Wrapper<T>`, found type parameter `T`
|
= note: expected associated type `<Wrapper<T> as Pointee>::Metadata`
found associated type `<T as Pointee>::Metadata`
= note: an associated type was expected, but a different one was found
```
(Yes, you can already do this with `as` casts. But using functions is so much ✨ *safer* ✨, because you can't change the metadata on accident.)
---
This PR essentially changes the built-in impls of `Pointee` from this:
```rust
// before
impl Pointee for u8 {
type Metadata = ();
}
impl Pointee for [u8] {
type Metadata = usize;
}
// ...
impl Pointee for Wrapper<u8> {
type Metadata = ();
}
impl Pointee for Wrapper<[u8]> {
type Metadata = usize;
}
// ...
// This impl is only selected if `T` is a type parameter or unnormalizable projection or opaque type.
fallback impl<T: ?Sized> Pointee for Wrapper<T>
where
Wrapper<T>: Sized
{
type Metadata = ();
}
// This impl is only selected if `T` is a type parameter or unnormalizable projection or opaque type.
fallback impl<T /*: Sized */> Pointee for T {
type Metadata = ();
}
```
to this:
```rust
// after
impl Pointee for u8 {
type Metadata = ();
}
impl Pointee for [u8] {
type Metadata = usize;
}
// ...
impl<T: ?Sized> Pointee for Wrapper<T> {
// in the old solver this will instead project to the "deep" tail directly,
// e.g. `Wrapper<Wrapper<T>>::Metadata = T::Metadata`
type Metadata = <T as Pointee>::Metadata;
}
// ...
// This impl is only selected if `T` is a type parameter or unnormalizable projection or opaque type.
fallback impl<T /*: Sized */> Pointee for T {
type Metadata = ();
}
```
Invert diagnostic lints.
That is, change `diagnostic_outside_of_impl` and `untranslatable_diagnostic` from `allow` to `deny`, because more than half of the compiler has been converted to use translated diagnostics.
This commit removes more `deny` attributes than it adds `allow` attributes, which proves that this change is warranted.
r? ````@davidtwco````
Toggle assert_unsafe_precondition in codegen instead of expansion
The goal of this PR is to make some of the unsafe precondition checks in the standard library available in debug builds. Some UI tests are included to verify that it does that.
The diff is large, but most of it is blessing mir-opt tests and I've also split up this PR so it can be reviewed commit-by-commit.
This PR:
1. Adds a new intrinsic, `debug_assertions` which is lowered to a new MIR NullOp, and only to a constant after monomorphization
2. Rewrites `assume_unsafe_precondition` to check the new intrinsic, and be monomorphic.
3. Skips codegen of the `assume` intrinsic in unoptimized builds, because that was silly before but with these checks it's *very* silly
4. The checks with the most overhead are `ptr::read`/`ptr::write` and `NonNull::new_unchecked`. I've simply added `#[cfg(debug_assertions)]` to the checks for `ptr::read`/`ptr::write` because I was unable to come up with any (good) ideas for decreasing their impact. But for `NonNull::new_unchecked` I found that the majority of callers can use a different function, often a safe one.
Yes, this PR slows down the compile time of some programs. But in our benchmark suite it's never more than 1% icount, and the average icount change in debug-full programs is 0.22%. I think that is acceptable for such an improvement in developer experience.
https://github.com/rust-lang/rust/issues/120539#issuecomment-1922687101
Remove unused args from functions
`#[instrument]` suppresses the unused arguments from a function, *and* suppresses unused methods too! This PR removes things which are only used via `#[instrument]` calls, and fixes some other errors (privacy?) that I will comment inline.
It's possible that some of these arguments were being passed in for the purposes of being instrumented, but I am unconvinced by most of them.
Introduce `enter_forall` to supercede `instantiate_binder_with_placeholders`
r? `@lcnr`
Long term we'd like to experiment with decrementing the universe count after "exiting" binders so that we do not end up creating infer vars in non-root universes even when they logically reside in the root universe. The fact that we dont do this currently results in a number of issues in the new trait solver where we consider goals to be ambiguous because otherwise it would require lowering the universe of an infer var. i.e. the goal `?x.0 eq <T as Trait<?y.1>>::Assoc` where the alias is rigid would not be able to instantiate `?x` with the alias as there would be a universe error.
This PR is the first-ish sort of step towards being able to implement this as eventually we would want to decrement the universe in `enter_forall`. Unfortunately its Difficult to actually implement decrementing universes nicely so this is a separate step which moves us closer to the long term goal ✨
improve pretty printing for associated items in trait objects
* Don't print a binder in front of associated items, because it's not valid syntax.
* e.g. print `dyn for<'a> Trait<'a, Assoc = &'a u8>` instead of `dyn for<'a> Trait<'a, for<'a> Assoc = &'a u8>`.
* Don't print associated items that are implied by a supertrait bound.
* e.g. if we have `trait Sub: Super<Assoc = u8> {}`, then just print `dyn Sub` instead of `dyn Sub<Assoc = u8>`.
I've added the test in the first commit, so you can see the diff of the compiler output in the second commit.
Reconstify `Add`
r? project-const-traits
I'm not happy with the ui test changes (or failures because I did not bless them and include the diffs in this PR). There is at least some bugs I need to look and try fix:
1. A third duplicated diagnostic when a consumer crate that does not have `effects` enabled has a trait selection error for an upstream const_trait trait. See tests/ui/ufcs/ufcs-qpath-self-mismatch.rs.
2. For some reason, making `Add` a const trait would stop us from suggesting `T: Add` when we try to add two `T`s without that bound. See tests/ui/suggestions/issue-97677.rs
Record coroutine kind in coroutine generics
Oops, added a new substitution (the "kind" ty) to coroutines but forgot to record it in the `generics_of`. I'm surprised I left this out of the coroutine-closure PR -- I thought I made this change; I possibly rebased it out by accident.
Fixes#120732
r? oli-obk
MirPass: make name more const
Continues #120161, this time applied to `MirPass` instead of `MirLint`, locally shaves few (very few) instructions off.
r? ``@cjgillot``
Don't expect early-bound region to be local when reporting errors in RPITIT well-formedness
The implicit lifetime in the example code gets replaced with `ReError`, which fails a `sub_regions` check in the lexical region solver. Error reporting ends up calling `is_suitable_region` on an early bound region in the *trait* definition. This causes an ICE because we `expect_local()`.
This is kind of a bad explanation, but this code just makes diagnostics reporting a bit more gracefully fallible. If the reviewer wants a thorough investigation of exactly where we get this region outlives obligation, I can write one up. Doesn't really seem worth it, though, imo.
Fixes#120638Fixes#120648
update indirect structural match lints to match RFC and to show up for dependencies
This is a large step towards implementing https://github.com/rust-lang/rfcs/pull/3535.
We currently have five lints related to "the structural match situation":
- nontrivial_structural_match
- indirect_structural_match
- pointer_structural_match
- const_patterns_without_partial_eq
- illegal_floating_point_literal_pattern
This PR concerns the first 3 of them. (The 4th already is set up to show for dependencies, and the 5th is removed by https://github.com/rust-lang/rust/pull/116284.) nontrivial_structural_match is being removed as per the RFC; the other two are enabled to show up in dependencies.
Fixes https://github.com/rust-lang/rust/issues/73448 by removing the affected analysis.
That is, change `diagnostic_outside_of_impl` and
`untranslatable_diagnostic` from `allow` to `deny`, because more than
half of the compiler has be converted to use translated diagnostics.
This commit removes more `deny` attributes than it adds `allow`
attributes, which proves that this change is warranted.
make matching on NaN a hard error, and remove the rest of illegal_floating_point_literal_pattern
These arms would never be hit anyway, so the pattern makes little sense. We have had a future-compat lint against float matches in general for a *long* time, so I hope we can get away with immediately making this a hard error.
This is part of implementing https://github.com/rust-lang/rfcs/pull/3535.
Closes https://github.com/rust-lang/rust/issues/41620 by removing the lint.
https://github.com/rust-lang/reference/pull/1456 updates the reference to match.
Move predicate, region, and const stuff into their own modules in middle
This PR mostly moves things around, and in a few cases adds some `ty::` to the beginning of names to avoid one-off imports.
I don't mean this to be the most *thorough* move/refactor. I just generally wanted to begin to split up `ty/mod.rs` and `ty/sty.rs` which are huge and hard to distinguish, and have a lot of non-ty stuff in them.
r? lcnr
it works when a non-const context that does not enable effects
calls into a const effects-enabled trait. We'd simply suggest the
non-const trait bound in this case consistent to its fallback.
hir: Remove the generic type parameter from `MaybeOwned`
It's only ever used with a reference to `OwnerInfo` as an argument.
Follow up to https://github.com/rust-lang/rust/pull/120346.
Deduplicate more sized errors on call exprs
Change the implicit `Sized` `Obligation` `Span` for call expressions to include the whole expression. This aids the existing deduplication machinery to reduce the number of errors caused by a single unsized expression.
The query accept arbitrary DefIds, not just owner DefIds.
The return can be an `Option` because if there are no nodes, then it doesn't matter whether it's due to NonOwner or Phantom.
Also rename the query to `opt_hir_owner_nodes`.
Because it's almost always static.
This makes `impl IntoDiagnosticArg for DiagnosticArgValue` trivial,
which is nice.
There are a few diagnostics constructed in
`compiler/rustc_mir_build/src/check_unsafety.rs` and
`compiler/rustc_mir_transform/src/errors.rs` that now need symbols
converted to `String` with `to_string` instead of `&str` with `as_str`,
but that' no big deal, and worth it for the simplifications elsewhere.
Error codes are integers, but `String` is used everywhere to represent
them. Gross!
This commit introduces `ErrCode`, an integral newtype for error codes,
replacing `String`. It also introduces a constant for every error code,
e.g. `E0123`, and removes the `error_code!` macro. The constants are
imported wherever used with `use rustc_errors::codes::*`.
With the old code, we have three different ways to specify an error code
at a use point:
```
error_code!(E0123) // macro call
struct_span_code_err!(dcx, span, E0123, "msg"); // bare ident arg to macro call
\#[diag(name, code = "E0123")] // string
struct Diag;
```
With the new code, they all use the `E0123` constant.
```
E0123 // constant
struct_span_code_err!(dcx, span, E0123, "msg"); // constant
\#[diag(name, code = E0123)] // constant
struct Diag;
```
The commit also changes the structure of the error code definitions:
- `rustc_error_codes` now just defines a higher-order macro listing the
used error codes and nothing else.
- Because that's now the only thing in the `rustc_error_codes` crate, I
moved it into the `lib.rs` file and removed the `error_codes.rs` file.
- `rustc_errors` uses that macro to define everything, e.g. the error
code constants and the `DIAGNOSTIC_TABLES`. This is in its new
`codes.rs` file.
ScopeTree: remove destruction_scopes as unused
last usages removed by https://github.com/rust-lang/rust/pull/116170
Unused, but still presented in memory at `t-gmax` (in DHAT termonology)
Remove unused/unnecessary features
~~The bulk of the actual code changes here is replacing try blocks with equivalent closures. I'm not entirely sure that's a good idea since it may have perf impact, happy to revert if that's the case/the change is unwanted.~~
I also removed a lot of `recursion_limit = "256"` since everything seems to build fine without that and most don't have any comment justifying it.
remove StructuralEq trait
The documentation given for the trait is outdated: *all* function pointers implement `PartialEq` and `Eq` these days. So the `StructuralEq` trait doesn't really seem to have any reason to exist any more.
One side-effect of this PR is that we allow matching on some consts that do not implement `Eq`. However, we already allowed matching on floats and consts containing floats, so this is not new, it is just allowed in more cases now. IMO it makes no sense at all to allow float matching but also sometimes require an `Eq` instance. If we want to require `Eq` we should adjust https://github.com/rust-lang/rust/pull/115893 to check for `Eq`, and rule out float matching for good.
Fixes https://github.com/rust-lang/rust/issues/115881
Remove coroutine info when building coroutine drop body
Coroutine drop shims are not themselves coroutines, so erase the "`coroutine`" field from the body so that helper fns like `yield_ty` and `coroutine_kind` properly return `None` for the drop shim.
Rollup of 10 pull requests
Successful merges:
- #119305 (Add `AsyncFn` family of traits)
- #119389 (Provide more context on recursive `impl` evaluation overflow)
- #119895 (Remove `track_errors` entirely)
- #120230 (Assert that a single scope is passed to `for_scope`)
- #120278 (Remove --fatal-warnings on wasm targets)
- #120292 (coverage: Dismantle `Instrumentor` and flatten span refinement)
- #120315 (On E0308 involving `dyn Trait`, mention trait objects)
- #120317 (pattern_analysis: Let `ctor_sub_tys` return any Iterator they want)
- #120318 (pattern_analysis: Reuse most of the `DeconstructedPat` `Debug` impl)
- #120325 (rustc_data_structures: use either instead of itertools)
r? `@ghost`
`@rustbot` modify labels: rollup
Remove `track_errors` entirely
follow up to https://github.com/rust-lang/rust/pull/119869
r? `@matthewjasper`
There are some diagnostic changes adding new diagnostics or not emitting some anymore. We can improve upon that in follow-up work imo.
Modify GenericArg and Term structs to use strict provenance rules
This is the first PR to solve issue #119217 . In this PR, I have modified the GenericArg struct to use the `NonNull` struct as the pointer instead of `NonZeroUsize`. The change were tested by running `./x test compiler/rustc_middle`.
Resolves https://github.com/rust-lang/rust/issues/119217
r? `@WaffleLapkin`
Remove all ConstPropNonsense
We track all locals and projections on them ourselves within the const propagator and only use the InterpCx to actually do some low level operations or read from constants (via `OpTy` we get for said constants).
This helps moving the const prop lint out from the normal pipeline and running it just based on borrowck information. This in turn allows us to make progress on https://github.com/rust-lang/rust/pull/108730#issuecomment-1875557745
there are various follow up cleanups that can be done after this PR (e.g. not matching on Rvalue twice and doing binop checks twice), but lets try landing this one first.
r? `@RalfJung`
Change the implicit `Sized` `Obligation` `Span` for call expressions to
include the whole expression. This aids the existing deduplication
machinery to reduce the number of errors caused by a single unsized
expression.
Rollup of 9 pull requests
Successful merges:
- #112806 (Small code improvements in `collect_intra_doc_links.rs`)
- #119766 (Split tait and impl trait in assoc items logic)
- #120139 (Do not normalize closure signature when building `FnOnce` shim)
- #120160 (Manually implement derived `NonZero` traits.)
- #120171 (Fix assume and assert in jump threading)
- #120183 (Add `#[coverage(off)]` to closures introduced by `#[test]` and `#[bench]`)
- #120195 (add several resolution test cases)
- #120259 (Split Diagnostics for Uncommon Codepoints: Add List to Display Characters Involved)
- #120261 (Provide structured suggestion to use trait objects in some cases of `if` arm type divergence)
r? `@ghost`
`@rustbot` modify labels: rollup
Do not normalize closure signature when building `FnOnce` shim
It is not necessary to normalize the closure signature when building an `FnOnce` shim for an `Fn`/`FnMut` closure. That closure shim is just calling `FnMut::call_mut(&mut self)` anyways.
It's also somewhat sketchy that we were ever doing this to begin with, since we're normalizing with a `ParamEnv::reveal_all()` param-env, which is definitely not right with possibly polymorphic substs.
This cuts out a tiny bit of unnecessary work in `Instance::resolve` and simplifies the signature because now we can unconditionally return an `Instance`.
A bunch of random modifications
r? oli-obk
Kitchen sink of changes that I didn't know where to put elsewhere. Documentation tweaks mostly, but also removing some unreachable code and simplifying the pretty printing for closures/coroutines.
const-eval interning: get rid of type-driven traversal
This entirely replaces our const-eval interner, i.e. the code that takes the final result of a constant evaluation from the local memory of the const-eval machine to the global `tcx` memory. The main goal of this change is to ensure that we can detect mutable references that sneak into this final value -- this is something we want to reject for `static` and `const`, and while const-checking performs some static analysis to ensure this, I would be much more comfortable stabilizing const_mut_refs if we had a dynamic check that sanitizes the final value. (This is generally the approach we have been using on const-eval: do a static check to give nice errors upfront, and then do a dynamic check to be really sure that the properties we need for soundness, actually hold.)
We can do this now that https://github.com/rust-lang/rust/pull/118324 landed and each pointer comes with a bit (completely independent of its type) storing whether mutation is permitted through this pointer or not.
The new interner is a lot simpler than the old one: previously we did a complete type-driven traversal to determine the mutability of all memory we see, and then a second pass to intern any leftover raw pointers. The new interner simply recursively traverses the allocation holding the final result, and all allocations reachable from it (which can be determined from the raw bytes of the result, without knowing anything about types), and ensures they all get interned. The initial allocation is interned as immutable for `const` and pomoted and non-interior-mutable `static`; all other allocations are interned as immutable for `static`, `const`, and promoted. The main subtlety is justifying that those inner allocations may indeed be interned immutably, i.e., that mutating them later would anyway already be UB:
- for promoteds, we rely on the analysis that does promotion to ensure that this is sound.
- for `const` and `static`, we check that all pointers in the final result that point to things that are new (i.e., part of this const evaluation) are immutable, i.e., were created via `&<expr>` at a non-interior-mutable type. Mutation through immutable pointers is UB so we are free to intern that memory as immutable.
Interning raises an error if it encounters a dangling pointer or a mutable pointer that violates the above rules.
I also extended our type-driven const validity checks to ensure that `&mut T` in the final value of a const points to mutable memory, at least if `T` is not zero-sized. This catches cases of people turning `&i32` into `&mut i32` (which would still be considered a read-only pointer). Similarly, when these checks encounter an `UnsafeCell`, they are checking that it lives in mutable memory. (Both of these only traverse the newly created values; if those point to other consts/promoteds, the check stops there. But that's okay, we don't have to catch all the UB.) I co-developed this with the stricter interner changes but I can split it out into a separate PR if you prefer.
This PR does have the immediate effect of allowing some new code on stable, for instance:
```rust
const CONST_RAW: *const Vec<i32> = &Vec::new() as *const _;
```
Previously that code got rejected since the type-based interner didn't know what to do with that pointer. It's a raw pointer, we cannot trust its type. The new interner does not care about types so it sees no issue with this code; there's an immutable pointer pointing to some read-only memory (storing a `Vec<i32>`), all is good. Accepting this code pretty much commits us to non-type-based interning, but I think that's the better strategy anyway.
This PR also leads to slightly worse error messages when the final value of a const contains a dangling reference. Previously we would complete interning and then the type-based validation would detect this dangling reference and show a nice error saying where in the value (i.e., in which field) the dangling reference is located. However, the new interner cannot distinguish dangling references from dangling raw pointers, so it must throw an error when it encounters either of them. It doesn't have an understanding of the value structure so all it can say is "somewhere in this constant there's a dangling pointer". (Later parts of the compiler don't like dangling pointers/references so we have to reject them either during interning or during validation.) This could potentially be improved by doing validation before interning, but that's a larger change that I have not attempted yet. (It's also subtle since we do want validation to use the final mutability bits of all involved allocations, and currently it is interning that marks a bunch of allocations as immutable -- that would have to still happen before validation.)
`@rust-lang/wg-const-eval` I hope you are okay with this plan. :)
`@rust-lang/lang` paging you in since this accepts new code on stable as explained above. Please let me know if you think FCP is necessary.
Revert stabilization of trait_upcasting feature
Reverts #118133
This reverts commit 6d2b84b3ed, reversing changes made to 73bc12199e.
The feature has a soundness bug:
* #120222
It is unclear to me whether we'll actually want to destabilize, but I thought it was still prudent to open the PR for easy destabilization once we get there.
Fix a `trimmed_def_paths` assertion failure.
`RegionHighlightMode::force_print_trimmed_def_path` can call `trimmed_def_paths` even when `tcx.sess.opts.trimmed_def_paths` is false. Based on the `force` in the method name, it seems this is deliberate, so I have removed the assertion.
Fixes#120035.
r? `@compiler-errors`
Consolidate logic around resolving built-in coroutine trait impls
Deduplicates a lot of code. Requires defining a new lang item for `Coroutine::resume` for consistency, but it seems not harmful at worst, and potentially later useful at best.
r? oli-obk
Pack u128 in the compiler to mitigate new alignment
This is based on #116672, adding a new `#[repr(packed(8))]` wrapper on `u128` to avoid changing any of the compiler's size assertions. This is needed in two places:
* `SwitchTargets`, otherwise its `SmallVec<[u128; 1]>` gets padded up to 32 bytes.
* `LitKind::Int`, so that entire `enum` can stay 24 bytes.
* This change definitely has far-reaching effects though, since it's public.
Rollup of 9 pull requests
Successful merges:
- #118714 ( Explanation that fields are being used when deriving `(Partial)Ord` on enums)
- #119710 (Improve `let_underscore_lock`)
- #119726 (Tweak Library Integer Division Docs)
- #119746 (rustdoc: hide modals when resizing the sidebar)
- #119986 (Fix error counting)
- #120194 (Shorten `#[must_use]` Diagnostic Message for `Option::is_none`)
- #120200 (Correct the anchor of an URL in an error message)
- #120203 (Replace `#!/bin/bash` with `#!/usr/bin/env bash` in rust-installer tests)
- #120212 (Give nnethercote more reviews)
r? `@ghost`
`@rustbot` modify labels: rollup
`RegionHighlightMode::force_print_trimmed_def_path` can call
`trimmed_def_paths` even when `tcx.sess.opts.trimmed_def_paths` is
false. Based on the `force` in the method name, it seems this is
deliberate, so I have removed the assertion.
Fixes#120035.
We have several methods indicating the presence of errors, lint errors,
and delayed bugs. I find it frustrating that it's very unclear which one
you should use in any particular spot. This commit attempts to instill a
basic principle of "use the least general one possible", because that
reflects reality in practice -- `has_errors` is the least general one
and has by far the most uses (esp. via `abort_if_errors`).
Specifics:
- Add some comments giving some usage guidelines.
- Prefer `has_errors` to comparing `err_count` to zero.
- Remove `has_errors_or_span_delayed_bugs` because it's a weird one: in
the cases where we need to count delayed bugs, we should really be
counting lint errors as well.
- Rename `is_compilation_going_to_fail` as
`has_errors_or_lint_errors_or_span_delayed_bugs`, for consistency with
`has_errors` and `has_errors_or_lint_errors`.
- Change a few other `has_errors_or_lint_errors` calls to `has_errors`,
as per the "least general" principle.
This didn't turn out to be as neat as I hoped when I started, but I
think it's still an improvement.
Make stable_mir::with_tables sound
See the first commit for the actual soundness fix. The rest is just fallout from that and is entirely safe code. Includes most of #120120
The major difference to #120120 is that we don't need an unsafe trait, as we can now rely on the type system (the only unsafe part, and the actual source of the unsoundness was in `with_tables`)
r? `@celinval`
LLVM 18 x86 data layout update
With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM.
This results in Rust overaligning things relative to LLVM on older LLVMs.
This implements MCP https://github.com/rust-lang/compiler-team/issues/683.
See #54341
With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to
16-bytes on x86 based platforms. This will be in LLVM-18. This patch
updates all our spec targets to be 16-byte aligned, and removes the
alignment when speaking to older LLVM.
This results in Rust overaligning things relative to LLVM on older LLVMs.
This alignment change was discussed in rust-lang/compiler-team#683
See #54341 for additional information about why this is happening and
where this will be useful in the future.
This *does not* stabilize `i128`/`u128` for FFI.
Get rid of the hir_owner query.
This query was meant as a firewall between `hir_owner_nodes` which is supposed to change often, and the queries that only depend on the item signature. That firewall was inefficient, leaking the contents of the HIR body through `HirId`s.
`hir_owner` incurs a significant cost, as we need to hash HIR twice in multiple modes. This PR proposes to remove it, and simplify the hashing scheme.
For the future, `def_kind`, `def_span`... are much more efficient for incremental decoupling, and should be preferred.
change `.unwrap()` to `?` on write where `fmt::Result` is returned
Fixes#120090 which points out that some of the `.unwrap()`s in `rustc_middle/src/mir/pretty.rs` are likely meant to be `?`s
Improved collapse_debuginfo attribute, added command-line flag
Improved attribute collapse_debuginfo with variants: `#[collapse_debuginfo=(no|external|yes)]`.
Added command-line flag for default behaviour.
Work-in-progress: will add more tests.
cc https://github.com/rust-lang/rust/issues/100758
Rollup of 8 pull requests
Successful merges:
- #119172 (Detect `NulInCStr` error earlier.)
- #119833 (Make tcx optional from StableMIR run macro and extend it to accept closures)
- #119967 (Add `PatKind::Err` to AST/HIR)
- #119978 (Move async closure parameters into the resultant closure's future eagerly)
- #120021 (don't store const var origins for known vars)
- #120038 (Don't create a separate "basename" when naming and opening a MIR dump file)
- #120057 (Don't ICE when deducing future output if other errors already occurred)
- #120073 (Remove spastorino from users_on_vacation)
r? `@ghost`
`@rustbot` modify labels: rollup
error on incorrect implied bounds in wfcheck except for Bevy dependents
Rebase of #109763
Additionally, special cases Bevy `ParamSet` types to not trigger the lint. This is tracked in #119956.
Fixes#109628
Don't create a separate "basename" when naming and opening a MIR dump file
These functions were split up by #77080, in order to support passing the dump file's “basename” (filename without extension) to the implementation of `-Zdump-mir-spanview`, so that it could be used as a page title.
That flag has since been removed (#119566), so now there's no particular reason for this code to handle the basename separately from the filename or full path.
This PR therefore restores things to (roughly) how they were before #77080.
Rework how diagnostic lints are stored.
`Diagnostic::code` has the type `DiagnosticId`, which has `Error` and
`Lint` variants. Plus `Diagnostic::is_lint` is a bool, which should be
redundant w.r.t. `Diagnostic::code`.
Seems simple. Except it's possible for a lint to have an error code, in
which case its `code` field is recorded as `Error`, and `is_lint` is
required to indicate that it's a lint. This is what happens with
`derive(LintDiagnostic)` lints. Which means those lints don't have a
lint name or a `has_future_breakage` field because those are stored in
the `DiagnosticId::Lint`.
It's all a bit messy and confused and seems unintentional.
This commit:
- removes `DiagnosticId`;
- changes `Diagnostic::code` to `Option<String>`, which means both
errors and lints can straightforwardly have an error code;
- changes `Diagnostic::is_lint` to `Option<IsLint>`, where `IsLint` is a
new type containing a lint name and a `has_future_breakage` bool, so
all lints can have those, error code or not.
r? `@oli-obk`
Cache local DefId-keyed queries without hashing
This caches local DefId-keyed queries using just an IndexVec. This costs ~5% extra max-rss at most but brings significant runtime improvement, up to 13% cycle counts (mean: 4%) on primary benchmarks. It's possible that further tweaks could reduce the memory overhead further but this win seems worth landing despite the increased memory, particularly with regards to eliminating the present set in non-incr or storing it inline (skip list?) with the main data.
We tried applying this scheme to all keys in the [first perf run] but found that it carried a significant memory hit (50%). instructions/cycle counts were also much more mixed, though that may have been due to the lack of the present set optimization (needed for fast iter() calls in incremental scenarios).
Closes https://github.com/rust-lang/rust/issues/45275
[first perf run]: https://perf.rust-lang.org/compare.html?start=30dfb9e046aeb878db04332c74de76e52fb7db10&end=6235575300d8e6e2cc6f449cb9048722ef43f9c7&stat=instructions:u
Simplify `closure_env_ty` and `closure_env_param`
Random cleanup that I found when working on async closures. This makes it easier to separate the latter into a new tykind.
Foreign maps are used to cache external DefIds, typically backed by
metadata decoding. In the future we might skip caching `V` there (since
loading from metadata usually is already cheap enough), but for now this
cuts down on the impact to memory usage and time to None-init a bunch of
memory. Foreign data is usually much sparser, since we're not usually
loading *all* entries from the foreign crate(s).
`OutputTypeParameterMismatch` -> `SignatureMismatch`
I'm probably missing something that made this rename more complicated. What did you end up getting stuck on when renaming this selection error, `@lcnr?`
**also** I renamed the `FulfillmentErrorCode` variants. This is just churn but I wanted to do it forever. I can move it out of this PR if desired.
r? lcnr
Inverting the condition lets us merge the two `Ok(false)` paths. I also
find the inverted condition easier to read: "all the things that must be
true for trimming to occur", instead of "any of the things that must be
true for trimming to not occur".
`Diagnostic::code` has the type `DiagnosticId`, which has `Error` and
`Lint` variants. Plus `Diagnostic::is_lint` is a bool, which should be
redundant w.r.t. `Diagnostic::code`.
Seems simple. Except it's possible for a lint to have an error code, in
which case its `code` field is recorded as `Error`, and `is_lint` is
required to indicate that it's a lint. This is what happens with
`derive(LintDiagnostic)` lints. Which means those lints don't have a
lint name or a `has_future_breakage` field because those are stored in
the `DiagnosticId::Lint`.
It's all a bit messy and confused and seems unintentional.
This commit:
- removes `DiagnosticId`;
- changes `Diagnostic::code` to `Option<String>`, which means both
errors and lints can straightforwardly have an error code;
- changes `Diagnostic::is_lint` to `Option<IsLint>`, where `IsLint` is a
new type containing a lint name and a `has_future_breakage` bool, so
all lints can have those, error code or not.
Suggest Upgrading Compiler for Gated Features
This PR addresses #117318
I have a few questions:
1. Do we want to specify the current version and release date of the compiler? I have added this in via environment variables, which I found in the code for the rustc cli where it handles the `--version` flag
a. How can I handle the changing message in the tests?
3. Do we want to only show this message when the compiler is old?
a. How can we determine when the compiler is old?
I'll wait until we figure out the message to bless the tests
Register even erroneous impls
Otherwise the specialization graph fails to pick it up, even though other code assumes that all impl blocks have an entry in the specialization graph.
also includes an unrelated cleanup of the specialization graph query
fixes #119827
next solver: provisional cache
this adds the cache removed in #115843. However, it should now correctly track whether a provisional result depends on an inductive or coinductive stack.
While working on this, I was using the following doc: https://hackmd.io/VsQPjW3wSTGUSlmgwrDKOA. I don't think it's too helpful to understanding this, but am somewhat hopeful that the inline comments are more useful.
There are quite a few future perf improvements here. Given that this is already very involved I don't believe it is worth it (for now). While working on this PR one of my few attempts to significantly improve perf ended up being unsound again because I was not careful enough ✨
r? `@compiler-errors`
Cleanup things in and around `Diagnostic`
These changes all arose when I was looking closely at how to simplify `DiagCtxtInner::emit_diagnostic`.
r? `@compiler-errors`
`is_force_warn` is only possible for diagnostics with `Level::Warning`,
but it is currently stored in `Diagnostic::code`, which every diagnostic
has.
This commit:
- removes the boolean `DiagnosticId::Lint::is_force_warn` field;
- adds a `ForceWarning` variant to `Level`.
Benefits:
- The common `Level::Warning` case now has no arguments, replacing
lots of `Warning(None)` occurrences.
- `rustc_session::lint::Level` and `rustc_errors::Level` are more
similar, both having `ForceWarning` and `Warning`.
In #119606 I added them and used a `_mv` suffix, but that wasn't great.
A `with_` prefix has three different existing uses.
- Constructors, e.g. `Vec::with_capacity`.
- Wrappers that provide an environment to execute some code, e.g.
`with_session_globals`.
- Consuming chaining methods, e.g. `Span::with_{lo,hi,ctxt}`.
The third case is exactly what we want, so this commit changes
`DiagnosticBuilder::foo_mv` to `DiagnosticBuilder::with_foo`.
Thanks to @compiler-errors for the suggestion.
We have `span_delayed_bug` and often pass it a `DUMMY_SP`. This commit
adds `delayed_bug`, which matches pairs like `err`/`span_err` and
`warn`/`span_warn`.
Because it takes an error code after the span. This avoids the confusing
overlap with the `DiagCtxt::struct_span_err` method, which doesn't take
an error code.
Merge dead bb pruning and unreachable bb deduplication.
Both routines share the same basic structure: iterate on all bbs to identify work, and then renumber bbs.
We can do both at once.
Support async recursive calls (as long as they have indirection)
Before #101692, we stored coroutine witness types directly inside of the coroutine. That means that a coroutine could not contain itself (as a witness field) without creating a cycle in the type representation of the coroutine, which we detected with the `OpaqueTypeExpander`, which is used to detect cycles when expanding opaque types after that are inferred to contain themselves.
After `-Zdrop-tracking-mir` was stabilized, we no longer store these generator witness fields directly, but instead behind a def-id based query. That means there is no technical obstacle in the compiler preventing coroutines from containing themselves per se, other than the fact that for a coroutine to have a non-infinite layout, it must contain itself wrapped in a layer of allocation indirection (like a `Box`).
This means that it should be valid for this code to work:
```
async fn async_fibonacci(i: u32) -> u32 {
if i == 0 || i == 1 {
i
} else {
Box::pin(async_fibonacci(i - 1)).await
+ Box::pin(async_fibonacci(i - 2)).await
}
}
```
Whereas previously, you'd need to coerce the future to `Pin<Box<dyn Future<Output = ...>>` before `await`ing it, to prevent the async's desugared coroutine from containing itself across as await point.
This PR does two things:
1. Only report an error if an opaque expansion cycle is detected *not* through coroutine witness fields.
* Instead, if we find an opaque cycle through coroutine witness fields, we compute the layout of the coroutine. If that results in a cycle error, we report it as a recursive async fn.
4. Reworks the way we report layout errors having to do with coroutines, to make up for the diagnostic regressions introduced by (1.). We actually do even better now, pointing out the call sites of the recursion!
Add helper for when we want to know if an item has a host param
r? ````@fmease```` since you're a good reviewer and no good deed goes unpunished
This helper will see far more usages as built-in traits get constified.
Improved support of collapse_debuginfo attribute for macros.
Added walk_chain_collapsed function to consider collapse_debuginfo attribute in parent macros in call chain.
Fixed collapse_debuginfo attribute processing for cranelift (there was if/else branches error swap).
cc https://github.com/rust-lang/rust/issues/100758
This works for most of its call sites. This is nice, because `emit` very
much makes sense as a consuming operation -- indeed,
`DiagnosticBuilderState` exists to ensure no diagnostic is emitted
twice, but it uses runtime checks.
For the small number of call sites where a consuming emit doesn't work,
the commit adds `DiagnosticBuilder::emit_without_consuming`. (This will
be removed in subsequent commits.)
Likewise, `emit_unless` becomes consuming. And `delay_as_bug` becomes
consuming, while `delay_as_bug_without_consuming` is added (which will
also be removed in subsequent commits.)
All this requires significant changes to `DiagnosticBuilder`'s chaining
methods. Currently `DiagnosticBuilder` method chaining uses a
non-consuming `&mut self -> &mut Self` style, which allows chaining to
be used when the chain ends in `emit()`, like so:
```
struct_err(msg).span(span).emit();
```
But it doesn't work when producing a `DiagnosticBuilder` value,
requiring this:
```
let mut err = self.struct_err(msg);
err.span(span);
err
```
This style of chaining won't work with consuming `emit` though. For
that, we need to use to a `self -> Self` style. That also would allow
`DiagnosticBuilder` production to be chained, e.g.:
```
self.struct_err(msg).span(span)
```
However, removing the `&mut self -> &mut Self` style would require that
individual modifications of a `DiagnosticBuilder` go from this:
```
err.span(span);
```
to this:
```
err = err.span(span);
```
There are *many* such places. I have a high tolerance for tedious
refactorings, but even I gave up after a long time trying to convert
them all.
Instead, this commit has it both ways: the existing `&mut self -> Self`
chaining methods are kept, and new `self -> Self` chaining methods are
added, all of which have a `_mv` suffix (short for "move"). Changes to
the existing `forward!` macro lets this happen with very little
additional boilerplate code. I chose to add the suffix to the new
chaining methods rather than the existing ones, because the number of
changes required is much smaller that way.
This doubled chainging is a bit clumsy, but I think it is worthwhile
because it allows a *lot* of good things to subsequently happen. In this
commit, there are many `mut` qualifiers removed in places where
diagnostics are emitted without being modified. In subsequent commits:
- chaining can be used more, making the code more concise;
- more use of chaining also permits the removal of redundant diagnostic
APIs like `struct_err_with_code`, which can be replaced easily with
`struct_err` + `code_mv`;
- `emit_without_diagnostic` can be removed, which simplifies a lot of
machinery, removing the need for `DiagnosticBuilderState`.
Avoid specialization in the metadata serialization code
With the exception of a perf-only specialization for byte slices and byte vectors.
This uses the same trick of introducing a new trait and having the Encodable and Decodable derives add a bound to it as used for TyEncoder/TyDecoder. The new code is clearer about which encoder/decoder uses which impl and it reduces the dependency of rustc on specialization, making it easier to remove support for specialization entirely or turn it into a construct that is only allowed for perf optimizations if we decide to do this.
Rollup of 9 pull requests
Successful merges:
- #119208 (coverage: Hoist some complex code out of the main span refinement loop)
- #119216 (Use diagnostic namespace in stdlib)
- #119414 (bootstrap: Move -Clto= setting from Rustc::run to rustc_cargo)
- #119420 (Handle ForeignItem as TAIT scope.)
- #119468 (rustdoc-search: tighter encoding for f index)
- #119628 (remove duplicate test)
- #119638 (fix cyle error when suggesting to use associated function instead of constructor)
- #119640 (library: Fix warnings in rtstartup)
- #119642 (library: Fix a symlink test failing on Windows)
r? `@ghost`
`@rustbot` modify labels: rollup
fix cyle error when suggesting to use associated function instead of constructor
Fixes https://github.com/rust-lang/rust/issues/119625.
The first commit fixes the infinite recursion and makes the cycle error actually show up. We do this by making the `Display` for `ty::Instance` impl respect `with_no_queries` so that it can be used in query descriptions.
The second commit fixes the cycle error `resolver_for_lowering` -> `normalize` -> `resolve_instance` (for evaluating const) -> `lang_items` (for `drop_in_place`) -> `resolver_for_lowering` (for collecting lang items). We do this by simply skipping the suggestion when encountering an unnormalized type.
Rollup of 8 pull requests
Successful merges:
- #119151 (Hide foreign `#[doc(hidden)]` paths in import suggestions)
- #119350 (Imply outlives-bounds on lazy type aliases)
- #119354 (Make `negative_bounds` internal & fix some of its issues)
- #119506 (Use `resolutions(()).effective_visiblities` to avoid cycle errors in `report_object_error`)
- #119554 (Fix scoping for let chains in match guards)
- #119563 (Check yield terminator's resume type in borrowck)
- #119589 (cstore: Remove unnecessary locking from `CrateMetadata`)
- #119622 (never patterns: Document behavior of never patterns with macros-by-example)
r? `@ghost`
`@rustbot` modify labels: rollup
Check yield terminator's resume type in borrowck
In borrowck, we didn't check that the lifetimes of the `TerminatorKind::Yield`'s `resume_place` were actually compatible with the coroutine's signature. That means that the lifetimes were totally going unchecked. Whoops!
This PR implements this checking.
Fixes#119564
r? types
Fix scoping for let chains in match guards
If let guards were previously represented as a different type of guard in HIR and THIR. This meant that let chains in match guards were not handled correctly because they were treated exactly like normal guards.
- Remove `hir::Guard` and `thir::Guard`.
- Make the scoping different between normal guards and if let guards also check for let chains.
closes#118593
Hide foreign `#[doc(hidden)]` paths in import suggestions
Stops the compiler from suggesting to import foreign `#[doc(hidden)]` paths.
```@rustbot``` label A-suggestion-diagnostics
Replace a number of FxHashMaps/Sets with stable-iteration-order alternatives
This PR replaces almost all of the remaining `FxHashMap`s in query results with either `FxIndexMap` or `UnordMap`. The only case that is missing is the `EffectiveVisibilities` struct which turned out to not be straightforward to transform. Once that is done too, we can remove the `HashStable` implementation from `HashMap`.
The first commit adds the `StableCompare` trait which is a companion trait to `StableOrd`. Some types like `Symbol` can be compared in a cross-session stable way, but their `Ord` implementation is not stable. In such cases, a `StableCompare` implementation can be provided to offer a lightweight way for stable sorting. The more heavyweight option is to sort via `ToStableHashKey`, but then sorting needs to have access to a stable hashing context and `ToStableHashKey` can also be expensive as in the case of `Symbol` where it has to allocate a `String`.
The rest of the commits are rather mechanical and don't overlap, so they are best reviewed individually.
Part of [MCP 533](https://github.com/rust-lang/compiler-team/issues/533).
Remove `-Zdump-mir-spanview`
The `-Zdump-mir-spanview` flag was added back in #76074, as a development/debugging aid for the initial work on what would eventually become `-Cinstrument-coverage`. It causes the compiler to emit an HTML file containing a function's source code, with various spans highlighted based on the contents of MIR.
When the suggestion was made to [triage and remove unnecessary `-Z` flags (Zulip)](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/.60-Z.60.20option.20triage), I noted that this flag could potentially be worth removing, but I wanted to keep it around to see whether I found it useful for my own coverage work.
But when I actually tried to use it, I ran into various issues (e.g. it crashes on `tests/coverage/closure.rs`). If I can't trust it to work properly without a full overhaul, then instead of diving down a rabbit hole of trying to fix arcane span-handling bugs, it seems better to just remove this obscure old code entirely.
---
````@rustbot```` label +A-code-coverage
Tweak suggestions for bare trait used as a type
```
error[E0782]: trait objects must include the `dyn` keyword
--> $DIR/not-on-bare-trait-2021.rs:11:11
|
LL | fn bar(x: Foo) -> Foo {
| ^^^
|
help: use a generic type parameter, constrained by the trait `Foo`
|
LL | fn bar<T: Foo>(x: T) -> Foo {
| ++++++++ ~
help: you can also use `impl Foo`, but users won't be able to specify the type paramer when calling the `fn`, having to rely exclusively on type inference
|
LL | fn bar(x: impl Foo) -> Foo {
| ++++
help: alternatively, use a trait object to accept any type that implements `Foo`, accessing its methods at runtime using dynamic dispatch
|
LL | fn bar(x: &dyn Foo) -> Foo {
| ++++
error[E0782]: trait objects must include the `dyn` keyword
--> $DIR/not-on-bare-trait-2021.rs:11:19
|
LL | fn bar(x: Foo) -> Foo {
| ^^^
|
help: use `impl Foo` to return an opaque type, as long as you return a single underlying type
|
LL | fn bar(x: Foo) -> impl Foo {
| ++++
help: alternatively, you can return an owned trait object
|
LL | fn bar(x: Foo) -> Box<dyn Foo> {
| +++++++ +
```
Fix#119525:
```
error[E0038]: the trait `Ord` cannot be made into an object
--> $DIR/bare-trait-dont-suggest-dyn.rs:3:33
|
LL | fn ord_prefer_dot(s: String) -> Ord {
| ^^^ `Ord` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
= note: the trait cannot be made into an object because it uses `Self` as a type parameter
::: $SRC_DIR/core/src/cmp.rs:LL:COL
|
= note: the trait cannot be made into an object because it uses `Self` as a type parameter
help: consider using an opaque type instead
|
LL | fn ord_prefer_dot(s: String) -> impl Ord {
| ++++
```
Reorder check_item_type diagnostics so they occur next to the corresponding `check_well_formed` diagnostics
The first commit is just a cleanup.
The second commit moves most checks from `check_mod_item_types` into `check_well_formed`, invoking the checks in lockstep per-item instead of iterating over all items twice.
StableCompare is a companion trait to `StableOrd`. Some types like `Symbol` can be compared in a cross-session stable way, but their `Ord` implementation is not stable. In such cases, a `StableOrd` implementation can be provided to offer a lightweight way for stable sorting. (The more heavyweight option is to sort via `ToStableHashKey`, but then sorting needs to have access to a stable hashing context and `ToStableHashKey` can also be expensive as in the case of `Symbol` where it has to allocate a `String`.)
Because it's redundant w.r.t. `Diagnostic::is_lint`, which is present
for every diagnostic level.
`struct_lint_level_impl` was the only place that set the `Error` field
to `true`, and it's also the only place that calls
`Diagnostic::is_lint()` to set the `is_lint` field.
`Diagnostic` has 40 methods that return `&mut Self` and could be
considered setters. Four of them have a `set_` prefix. This doesn't seem
necessary for a type that implements the builder pattern. This commit
removes the `set_` prefixes on those four methods.
Fix `<BoundConstness as Display>`
There was infinite recursion, which is not very good. I'm not sure what the best way to implement this is, I just did something that felt right.
r? `@fmease`
This involves lots of breaking changes. There are two big changes that
force changes. The first is that the bitflag types now don't
automatically implement normal derive traits, so we need to derive them
manually.
Additionally, bitflags now have a hidden inner type by default, which
breaks our custom derives. The bitflags docs recommend using the impl
form in these cases, which I did.
Introduce `const Trait` (always-const trait bounds)
Feature `const_trait_impl` currently lacks a way to express “always const” trait bounds. This makes it impossible to define generic items like fns or structs which contain types that depend on const method calls (\*). While the final design and esp. the syntax of effects / keyword generics isn't set in stone, some version of “always const” trait bounds will very likely form a part of it. Further, their implementation is trivial thanks to the `effects` backbone.
Not sure if this needs t-lang sign-off though.
(\*):
```rs
#![feature(const_trait_impl, effects, generic_const_exprs)]
fn compute<T: const Trait>() -> Type<{ T::generate() }> { /*…*/ }
struct Store<T: const Trait>
where
Type<{ T::generate() }>:,
{
field: Type<{ T::generate() }>,
}
```
Lastly, “always const” trait bounds are a perfect fit for `generic_const_items`.
```rs
#![feature(const_trait_impl, effects, generic_const_items)]
const DEFAULT<T: const Default>: T = T::default();
```
Previously, we (oli, fee1-dead and I) wanted to reinterpret `~const Trait` as `const Trait` in generic const items which would've been quite surprising and not very generalizable.
Supersedes #117530.
---
cc `@oli-obk`
As discussed
r? fee1-dead (or compiler)
Clean up some lifetimes in `rustc_pattern_analysis`
This PR removes some redundant lifetimes. I figured out that we were shortening the lifetime of an arena-allocated `&'p DeconstructedPat<'p>` to `'a DeconstructedPat<'p>`, which forced us to carry both lifetimes when we could otherwise carry just one.
This PR also removes and elides some unnecessary lifetimes.
I also cherry-picked 0292eb9bb9b897f5c0926c6a8530877f67e7cc9b, and then simplified more lifetimes in `MatchVisitor`, which should make #119233 a very simple PR!
r? Nadrieril
rework `-Zverbose`
implements the changes described in https://github.com/rust-lang/compiler-team/issues/706
the first commit is only a name change from `-Zverbose` to `-Zverbose-internals` and does not change behavior. the second commit changes diagnostics.
possible follow up work:
- `ty::pretty` could print more info with `--verbose` than it does currently. `-Z verbose-internals` shows too much info in a way that's not helpful to users. michael had ideas about this i didn't fully understand: https://rust-lang.zulipchat.com/#narrow/stream/233931-t-compiler.2Fmajor-changes/topic/uplift.20some.20-Zverbose.20calls.20and.20rename.20to.E2.80.A6.20compiler-team.23706/near/408984200
- `--verbose` should imply `-Z write-long-types-to-disk=no`. the code in `ty_string_with_limit` should take `--verbose` into account (apparently this affects `Ty::sort_string`, i'm not familiar with this code). writing a file to disk should suggest passing `--verbose`.
r? `@compiler-errors` cc `@estebank`
Make closures carry their own ClosureKind
Right now, we use the "`movability`" field of `hir::Closure` to distinguish a closure and a coroutine. This is paired together with the `CoroutineKind`, which is located not in the `hir::Closure`, but the `hir::Body`. This is strange and redundant.
This PR introduces `ClosureKind` with two variants -- `Closure` and `Coroutine`, which is put into `hir::Closure`. The `CoroutineKind` is thus removed from `hir::Body`, and `Option<Movability>` no longer needs to be a stand-in for "is this a closure or a coroutine".
r? eholk
Remove `DiagCtxt` API duplication
`DiagCtxt` defines the internal API for creating and emitting diagnostics: methods like `struct_err`, `struct_span_warn`, `note`, `create_fatal`, `emit_bug`. There are over 50 methods.
Some of these methods are then duplicated across several other types: `Session`, `ParseSess`, `Parser`, `ExtCtxt`, and `MirBorrowckCtxt`. `Session` duplicates the most, though half the ones it does are unused. Each duplicated method just calls forward to the corresponding method in `DiagCtxt`. So this duplication exists to (in the best case) shorten chains like `ecx.tcx.sess.parse_sess.dcx.emit_err()` to `ecx.emit_err()`.
This API duplication is ugly and has been bugging me for a while. And it's inconsistent: there's no real logic about which methods are duplicated, and the use of `#[rustc_lint_diagnostic]` and `#[track_caller]` attributes vary across the duplicates.
This PR removes the duplicated API methods and makes all diagnostic creation and emission go through `DiagCtxt`. It also adds `dcx` getter methods to several types to shorten chains. This approach scales *much* better than API duplication; indeed, the PR adds `dcx()` to numerous types that didn't have API duplication: `TyCtxt`, `LoweringCtxt`, `ConstCx`, `FnCtxt`, `TypeErrCtxt`, `InferCtxt`, `CrateLoader`, `CheckAttrVisitor`, and `Resolver`. These result in a lot of changes from `foo.tcx.sess.emit_err()` to `foo.dcx().emit_err()`. (You could do this with more types, but it gets into diminishing returns territory for types that don't emit many diagnostics.)
After all these changes, some call sites are more verbose, some are less verbose, and many are the same. The total number of lines is reduced, mostly because of the removed API duplication. And consistency is increased, because calls to `emit_err` and friends are always preceded with `.dcx()` or `.dcx`.
r? `@compiler-errors`
Unify SourceFile::name_hash and StableSourceFileId
This PR adapts the existing `StableSourceFileId` type so that it can be used instead of the `name_hash` field of `SourceFile`. This simplifies a few things that were kind of duplicated before.
The PR should also fix issues https://github.com/rust-lang/rust/issues/112700 and https://github.com/rust-lang/rust/issues/115835, but I was not able to reproduce these issues in a regression test. As far as I can tell, the root cause of these issues is that the id of the originating crate is not hashed in the `HashStable` impl of `Span` and thus cache entries that should have been considered invalidated were loaded. After this PR, the `stable_id` field of `SourceFile` includes information about the originating crate, so that ICE should not occur anymore.
Split coroutine desugaring kind from source
What a coroutine is desugared from (gen/async gen/async) should be separate from where it comes (fn/block/closure).
`IntoDiagnostic` defaults to `ErrorGuaranteed`, because errors are the
most common diagnostic level. It makes sense to do likewise for the
closely-related (and much more widely used) `DiagnosticBuilder` type,
letting us write `DiagnosticBuilder<'a, ErrorGuaranteed>` as just
`DiagnosticBuilder<'a>`. This cuts over 200 lines of code due to many
multi-line things becoming single line things.
We can just get the error level in the `match` and then use
`DiagnosticBuilder::new`. This then means a number of `DiagCtxt`
functions are no longer needed, because this was the one place that used
them.
Note: the commit changes the treatment of spans for `Expect`, which was
different to all the other cases, but this has no apparent effect.
-Znext-solver: adapt overflow rules to avoid breakage
Do not erase overflow constraints if they are from equating the impl header when normalizing[^1].
This should be the minimal change to not break crates depending on the old project behavior of "apply impl constraints while only lazily evaluating any nested goals".
Fixes https://github.com/rust-lang/trait-system-refactor-initiative/issues/70, see https://hackmd.io/ATf4hN0NRY-w2LIVgeFsVg for the reasoning behind this.
Only keeping constraints on overflow for `normalize-to` goals as that's the only thing needed for backcompat. It also allows us to not track the origin of root obligations. The issue with root goals would be something like the following:
```rust
trait Foo {}
trait Bar {}
trait FooBar {}
impl<T: Foo + Bar> FooBar for T {}
// These two should behave the same, rn we can drop constraints for both,
// but if we don't drop `Misc` goals we would only drop the constraints for
// `FooBar` unless we track origins of root obligations.
fn func1<T: Foo + Bar>() {}
fn func2<T: FooBaz>() {}
```
[^1]: mostly, the actual rules are slightly different
r? ``@compiler-errors``
Replace some instances of FxHashMap/FxHashSet with stable alternatives (mostly in rustc_hir and rustc_ast_lowering)
Part of https://github.com/rust-lang/compiler-team/issues/533. We should be getting close to being able to remove the HashStable impl of HashMap.
And make all hand-written `IntoDiagnostic` impls generic, by using
`DiagnosticBuilder::new(dcx, level, ...)` instead of e.g.
`dcx.struct_err(...)`.
This means the `create_*` functions are the source of the error level.
This change will let us remove `struct_diagnostic`.
Note: `#[rustc_lint_diagnostics]` is added to `DiagnosticBuilder::new`,
it's necessary to pass diagnostics tests now that it's used in
`into_diagnostic` functions.
Don't pass lint back out of lint decorator
Change the decorator function in the signature of the `emit_lint`/`span_lint`/etc family of methods from `impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>) -> &'b mut DiagnosticBuilder<'a, ()>` to `impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>)`. I consider it easier to read this way, especially when there's control flow involved.
r? nnethercote though feel free to reassign
Uplift `TypeAndMut` and `ClosureKind` to `rustc_type_ir`
Uplifts `TypeAndMut` and `ClosureKind`
I know I said I was just going to get rid of `TypeAndMut` (https://github.com/rust-lang/types-team/issues/124) but I think this is much simpler, lol
r? `@jackh726` or `@lcnr`
cache param env canonicalization
Canonicalize ParamEnv only once and store it. Then whenever we try to canonicalize `ParamEnvAnd<'tcx, T>` we only have to canonicalize `T` and then merge the results.
Prelimiary results show ~3-4% savings in diesel and serde benchmarks.
Best to review commits individually. Some commits have a short description.
Initial implementation had a soundness bug (https://github.com/rust-lang/rust/pull/117749#issuecomment-1840453387) due to cache invalidation:
- When canonicalizing `Ty<'?0>` we first try to resolve region variables in the current InferCtxt which may have a constraint `?0 == 'static`. This means that we register `Ty<'?0> => Canonical<Ty<'static>>` in the cache, which is obviously incorrect in another inference context.
- This is fixed by not doing region resolution when canonicalizing the query *input* (vs. response), which is the only place where ParamEnv is used, and then in a later commit we *statically* guard against any form of inference variable resolution of the cached canonical ParamEnv's.
r? `@ghost`
This doesn't change behavior.
It should prevent unintentional resolution of inference variables
during canonicalization, which previously caused a soundness bug.
See PR description for more.
ParamEnv is canonicalized in *queries input* rather than query response.
In such case we don't "preserve universes" of canonical variable.
This means that `universe_map` always has the default value, which is
wasteful to store in the cache.
Renamings:
- find -> opt_hir_node
- get -> hir_node
- find_by_def_id -> opt_hir_node_by_def_id
- get_by_def_id -> hir_node_by_def_id
Fix rebase changes using removed methods
Use `tcx.hir_node_by_def_id()` whenever possible in compiler
Fix clippy errors
Fix compiler
Apply suggestions from code review
Co-authored-by: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Add FIXME for `tcx.hir()` returned type about its removal
Simplify with with `tcx.hir_node_by_def_id`
Make most `rustc_type_ir` kinds `Copy` by default
1. There's no reason why `TyKind` and `ConstKind`/`ConstData` can't be `Copy`. This allows us to avoid needing a typed arena for the two types.
2. Simplify some impls into derives.
remove redundant imports
detects redundant imports that can be eliminated.
for #117772 :
In order to facilitate review and modification, split the checking code and removing redundant imports code into two PR.
r? `@petrochenkov`
Don't print host effect param in pretty `path_generic_args`
Make `own_args_no_defaults` pass back the `GenericParamDef`, so that we can pass both the args *and* param definitions into `path_generic_args`. That allows us to use the `GenericParamDef` to filter out effect params.
This allows us to filter out the host param regardless of whether it's `sym::host` or `true`/`false`.
This also renames a couple of `const_effect_param` -> `host_effect_param`, and restores `~const` pretty printing to `TraitPredPrintModifiersAndPath`.
cc #118785
r? `@fee1-dead` cc `@oli-obk`
detects redundant imports that can be eliminated.
for #117772 :
In order to facilitate review and modification, split the checking code and
removing redundant imports code into two PR.
Don't warn an empty pattern unreachable if we're not sure the data is valid
Exhaustiveness checking used to be naive about the possibility of a place containing invalid data. This could cause it to emit an "unreachable pattern" lint on an arm that was in fact reachable, as in https://github.com/rust-lang/rust/issues/117119.
This PR fixes that. We now track whether a place that is matched on may hold invalid data. This also forced me to be extra precise about how exhaustiveness manages empty types.
Note that this now errs in the opposite direction: the following arm is truly unreachable (because the binding causes a read of the value) but not linted as such. I'd rather not recommend writing a `match ... {}` that has the implicit side-effect of loading the value. [Never patterns](https://github.com/rust-lang/rust/issues/118155) will solve this cleanly.
```rust
match union.value {
_x => unreachable!(),
}
```
I recommend reviewing commit by commit. I went all-in on the test suite because this went through a lot of iterations and I kept everything. The bit I'm least confident in is `is_known_valid_scrutinee` in `check_match.rs`.
Fixes https://github.com/rust-lang/rust/issues/117119.
coverage: Use `SpanMarker` to improve coverage spans for `if !` expressions
Coverage instrumentation works by extracting source code spans from MIR. However, some kinds of syntax are effectively erased during MIR building, so their spans don't necessarily exist anywhere in MIR, making them invisible to the coverage instrumentor (unless we resort to various heuristics and hacks to recover them).
This PR introduces `CoverageKind::SpanMarker`, which is a new variant of `StatementKind::Coverage`. Its sole purpose is to represent spans that would otherwise not appear in MIR, so that the coverage instrumentor can extract them.
When coverage is enabled, the MIR builder can insert these dummy statements as needed, to improve the accuracy of spans used by coverage mappings.
Fixes#115468.
---
```@rustbot``` label +A-code-coverage
Rollup of 6 pull requests
Successful merges:
- #117586 (Uplift the (new solver) canonicalizer into `rustc_next_trait_solver`)
- #118502 (fix: correct the arg for 'suggest to use associated function syntax' diagnostic)
- #118694 (Add instance evaluation and methods to read an allocation in StableMIR)
- #118715 (privacy: visit trait def id of projections)
- #118730 (recurse into refs when comparing tys for diagnostics)
- #118736 (temporarily revert "ice on ambguity in mir typeck")
r? `@ghost`
`@rustbot` modify labels: rollup
This is for post-monomorphization cycles. These are only caught later
(in drop elaboration for the example that I saw), so we need to handle
them here.
This issue wasn't noticed before because exhaustiveness only checked
inhabitedness when `exhaustive_patterns` was on. The preceding commit
now check inhabitedness always, which revealed the problem.
Uplift the (new solver) canonicalizer into `rustc_next_trait_solver`
Uplifts the new trait solver's canonicalizer into a new crate called `rustc_next_trait_solver`.
The crate name is literally a bikeshed-avoidance name, so let's not block this PR on that -- renames are welcome later.
There are a host of other changes that were required to make this possible:
* Expose a `ConstTy` trait to get the `Interner::Ty` from a `Interner::Const`.
* Expose some constructor methods to construct `Bound` variants. These are currently methods defined on the interner themselves, but they could be pulled into traits later.
* Expose a `IntoKind` trait to turn a `Ty`/`Const`/`Region` into their corresponding `*Kind`s.
* Some minor tweaks to other APIs in `rustc_type_ir`.
The canonicalizer code itself is best reviewed **with whitespace ignored.**
r? ``@lcnr``
Explicitly implement `DynSync` and `DynSend` for `TyCtxt`
This is an attempt to short circuit trait resolution. It should get a perf run for bootstrap impact.
There are cases where coverage instrumentation wants to show a span for some
syntax element, but there is no MIR node that naturally carries that span, so
the instrumentor can't see it.
MIR building can now use this new kind of coverage statement to deliberately
include those spans in MIR, attached to a dummy statement that has no other
effect.
Avoid adding builtin functions to `symbols.o`
We found performance regressions in #113923. The problem seems to be that `--gc-sections` does not remove these symbols. I tested that lld removes these symbols, but ld and gold do not.
I found that `used` adds symbols to `symbols.o` at 3e202ead60/compiler/rustc_codegen_ssa/src/back/linker.rs (L1786-L1791).
The PR removes builtin functions.
Note that under LTO, ld still preserves these symbols. (lld will still remove them.)
The first commit also fixes#118559. But I think the second commit also makes sense.
compile-time evaluation: detect writes through immutable pointers
This has two motivations:
- it unblocks https://github.com/rust-lang/rust/pull/116745 (and therefore takes a big step towards `const_mut_refs` stabilization), because we can now detect if the memory that we find in `const` can be interned as "immutable"
- it would detect the UB that was uncovered in https://github.com/rust-lang/rust/pull/117905, which was caused by accidental stabilization of `copy` functions in `const` that can only be called with UB
When UB is detected, we emit a future-compat warn-by-default lint. This is not a breaking change, so completely in line with [the const-UB RFC](https://rust-lang.github.io/rfcs/3016-const-ub.html), meaning we don't need t-lang FCP here. I made the lint immediately show up for dependencies since it is nearly impossible to even trigger this lint without `const_mut_refs` -- the accidentally stabilized `copy` functions are the only way this can happen, so the crates that popped up in #117905 are the only causes of such UB (in the code that crater covers), and the three cases of UB that we know about have all been fixed in their respective crates already.
The way this is implemented is by making use of the fact that our interpreter is already generic over the notion of provenance. For CTFE we now use the new `CtfeProvenance` type which is conceptually an `AllocId` plus a boolean `immutable` flag (but packed for a more efficient representation). This means we can mark a pointer as immutable when it is created as a shared reference. The flag will be propagated to all pointers derived from this one. We can then check the immutable flag on each write to reject writes through immutable pointers.
I just hope perf works out.
`EvaluatedToUnknown` -> `EvaluatedToAmbigStackDependent`, `EvaluatedToRecur` -> `EvaluatedToErrStackDependent`
Less confusing names, since the only difference between them and their parallel `EvalutedTo..` is that they are stack dependent.
r? lcnr
Remove `PolyGenSig` since it's always a dummy binder
Coroutines are never polymorphic in their signature. This cleans up a FIXME in the code:
```
/// Returns the "coroutine signature", which consists of its yield
/// and return types.
///
/// N.B., some bits of the code prefers to see this wrapped in a
/// binder, but it never contains bound regions. Probably this
/// function should be removed.
```
rustc_arena: add `alloc_str`
Two places called `from_utf8_unchecked` for strings from `alloc_slice`,
and one's SAFETY comment said this was for lack of `alloc_str` -- so
let's just add that instead!
Remove `#[rustc_host]`, use internal desugaring
Also removed a way for users to explicitly specify the host param since that isn't particularly useful. This should eliminate any pain with encoding attributes across crates and etc.
r? `@compiler-errors`
Two places called `from_utf8_unchecked` for strings from `alloc_slice`,
and one's SAFETY comment said this was for lack of `alloc_str` -- so
let's just add that instead!
`DefPathData::(ClosureExpr,ImplTrait)` are renamed to match `DefKind::(Closure,OpaqueTy)`.
`DefPathData::ImplTraitAssocTy` is replaced with `DefPathData::TypeNS(kw::Empty)` because both correspond to `DefKind::AssocTy`.
It's possible that introducing `(DefKind,DefPathData)::AssocOpaqueTy` could be a better solution, but that would be a much more invasive change.
Const generic parameters introduced for effects are moved from `DefPathData::TypeNS` to `DefPathData::ValueNS`, because constants are values.
`DefPathData` is no longer passed to `create_def` functions to avoid redundancy.
Fix `PartialEq` args when `#[const_trait]` is enabled
This is based off of your PR that enforces effects on all methods, so just see the last commits.
r? fee1-dead
Add `never_patterns` feature gate
This PR adds the feature gate and most basic parsing for the experimental `never_patterns` feature. See the tracking issue (https://github.com/rust-lang/rust/issues/118155) for details on the experiment.
`@scottmcm` has agreed to be my lang-team liaison for this experiment.
Call FileEncoder::finish in rmeta encoding
Fixes https://github.com/rust-lang/rust/issues/117254
The bug here was that rmeta encoding never called FileEncoder::finish. Now it does. Most of the changes here are needed to support that, since rmeta encoding wants to finish _then_ access the File in the encoder, so finish can't move out.
I tried adding a `cfg(debug_assertions)` exploding Drop impl to FileEncoder that checked for finish being called before dropping, but fatal errors cause unwinding so this isn't really possible. If we encounter a fatal error with a dirty FileEncoder, the Drop impl ICEs even though the implementation is correct. If we try to paper over that by wrapping FileEncoder in ManuallyDrop then that just erases the fact that Drop automatically checks that we call finish on all paths.
I also changed the name of DepGraph::encode to DepGraph::finish_encoding, because that's what it does and it makes the fact that it is the path to FileEncoder::finish less confusing.
r? `@WaffleLapkin`
Currently we always do this:
```
use rustc_fluent_macro::fluent_messages;
...
fluent_messages! { "./example.ftl" }
```
But there is no need, we can just do this everywhere:
```
rustc_fluent_macro::fluent_messages! { "./example.ftl" }
```
which is shorter.
The `fluent_messages!` macro produces uses of
`crate::{D,Subd}iagnosticMessage`, which means that every crate using
the macro must have this import:
```
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
```
This commit changes the macro to instead use
`rustc_errors::{D,Subd}iagnosticMessage`, which avoids the need for the
imports.
Remove `HirId` from `QPath::LangItem`
Remove `HirId` from `QPath::LangItem`, since there was only *one* use-case (`ObligationCauseCode::AwaitableExpr`), which we can instead recover by walking the HIR tree.
Optimize QueryArena allocation
This shifts the WorkerLocal wrapper to be outside the QueryArena, meaning that instead of having each query allocate distinct arenas per-worker we allocate the full set of arenas per-worker. This is primarily a code size optimization (locally, ~85 kilobytes, [perf is reporting >100 kilobytes](https://perf.rust-lang.org/compare.html?start=1fd418f92ed13db88a21865ba5d909abcf16b6cc&end=884c95a3f1fe8d28630ec3cdb0c8f95b2e539fde&stat=instructions%3Au&tab=artifact-size)), saving a bunch of code in the initialization of the arenas which was previously duplicated lots of times (per arena type).
Additionally this tells LLVM that the thread count can't be zero in this code (I believe this is true?) which shaves some small amount of bytes off as well since we eliminate checks for zero in the vec allocations.
Cache flags for `ty::Const`
Not sure if this has been attempted yet, but worth a shot. It does make the code simpler in `rustc_type_ir`, since we can assume that consts have a `flags` method that is no-cost.
r? `@ghost`
Remove `PredicateKind::ClosureKind`
We don't need the `ClosureKind` predicate kind -- instead, `Fn`-family trait goals are left as ambiguous, and we only need to make progress on `FnOnce` projection goals for inference purposes.
This is similar to how we do confirmation of `Fn`-family trait and projection goals in the new trait solver, which also doesn't use the `ClosureKind` predicate.
Some hacky logic is added in the second commit so that we can keep the error messages the same.
Rollup of 6 pull requests
Successful merges:
- #118012 (Add support for global allocation in smir)
- #118013 (Enable Rust to use the EHCont security feature of Windows)
- #118100 (Enable profiler in dist-powerpc64-linux)
- #118142 (Tighten up link attributes for llvm-wrapper bindings)
- #118147 (Fix some unnecessary casts)
- #118161 (Allow defining opaques in `check_coroutine_obligations`)
r? `@ghost`
`@rustbot` modify labels: rollup
Allow defining opaques in `check_coroutine_obligations`
In the new trait solver, when an obligation stalls on an unresolved coroutine witness, we will stash away the *root* obligation, even if the stalled obligation is only a distant descendent of the root obligation, since the new solver is purely recursive.
This means that we may need to reprocess alias-relate obligations (and others) which may define opaque types in the new solver. Currently, we use the coroutine's def id as the defining anchor in `check_coroutine_obligations`, which will allow defining no opaque types, resulting in errors like:
```
error[E0271]: type mismatch resolving `{coroutine@<source>:6:5: 6:17} <: impl Clone`
--> <source>:6:5
|
6 | / move |_: ()| {
7 | | let () = yield ();
8 | | }
| |_____^ types differ
```
So this PR fixes the defining anchor and does the same trick as `check_opaque_well_formed`, where we manually compare opaques that were defined against their hidden types to make sure they weren't defined differently when processing these stalled coroutine obligations.
r? `@lcnr` cc `@cjgillot`
By default, `newtype_index!` types get a default `Encodable`/`Decodable`
impl. You can opt out of this with `custom_encodable`. Opting out is the
opposite to how Rust normally works with autogenerated (derived) impls.
This commit inverts the behaviour, replacing `custom_encodable` with
`encodable` which opts into the default `Encodable`/`Decodable` impl.
Only 23 of the 59 `newtype_index!` occurrences need `encodable`.
Even better, there were eight crates with a dependency on
`rustc_serialize` just from unused default `Encodable`/`Decodable`
impls. This commit removes that dependency from those eight crates.
Uplift `CanonicalVarInfo` and friends into `rustc_type_ir`
Depends on #117580 and #117578
Uplift `CanonicalVarInfo` and friends into `rustc_type_ir` so they can be consumed by an interner-agnostic `Canonicalizer` implementation for the new trait solver ❤️
r? `@ghost`
Rollup of 5 pull requests
Successful merges:
- #117972 (Add VarDebugInfo to Stable MIR)
- #118109 (rustdoc-search: simplify `checkPath` and `sortResults`)
- #118110 (Document `DefiningAnchor` a bit more)
- #118112 (Don't ICE when ambiguity is found when selecting `Index` implementation in typeck)
- #118135 (Remove quotation from filename in stable_mir)
Failed merges:
- #118012 (Add support for global allocation in smir)
r? `@ghost`
`@rustbot` modify labels: rollup
Expand Miri's BorTag GC to a Provenance GC
As suggested in https://github.com/rust-lang/miri/issues/3080#issuecomment-1732505573
We previously solved memory growth issues associated with the Stacked Borrows and Tree Borrows runtimes with a GC. But of course we also have state accumulation associated with whole allocations elsewhere in the interpreter, and this PR starts tackling those.
To do this, we expand the visitor for the GC so that it can visit a BorTag or an AllocId. Instead of collecting all live AllocIds into a single HashSet, we just collect from the Machine itself then go through an accessor `InterpCx::is_alloc_live` which checks a number of allocation data structures in the core interpreter. This avoids the overhead of all the inserts that collecting their keys would require.
r? ``@RalfJung``
Rollup of 8 pull requests
Successful merges:
- #117327 (Add documentation for some queries)
- #117835 (Note about object lifetime defaults in does not live long enough error)
- #117851 (Uplift `InferConst` to `rustc_type_ir`)
- #117973 (test: Add test for async-move in 2015 Rust proc macro)
- #117992 (Don't require intercrate mode for negative coherence)
- #118010 (Typeck break expr even if break is illegal)
- #118026 (Don't consider regions in `deref_into_dyn_supertrait` lint)
- #118089 (intercrate_ambiguity_causes: handle self ty infer + reservation impls)
r? `@ghost`
`@rustbot` modify labels: rollup
Uplift `InferConst` to `rustc_type_ir`
We need this in `rustc_type_ir` because the canonicalizer must understand the difference between a const vid and an effect vid. In that way, it's not an implementation detail of the representation of an infer const, but just part of the type ir.
If we find out later on that it's better to leave the representation up to the consumer of `rustc_type_ir`, we could abstract `InferConst` (and probably `InferTy` as well) with some traits, but I don't see the benefit of that indirection currently.
Note about object lifetime defaults in does not live long enough error
This is a aspect of Rust that frequently trips up people who are not aware of it yet. This diagnostic attempts to explain what's happening and why the lifetime constraint, that was never mentioned in the source, arose.
The implementation feels a bit questionable, I'm not sure whether there are better ways to do this. There probably are.
fixes#117835
r? types
interpret: simplify handling of shifts by no longer trying to handle signed and unsigned shift amounts in the same branch
While we're at it, also update comments in codegen and MIR building related to shifts, and fix the overflow error printed by Miri on negative shift amounts.
new solver normalization improvements
cool beans
At the core of this PR is a `try_normalize_ty` which stops for rigid aliases by using `commit_if_ok`.
Reworks alias-relate to fully normalize both the lhs and rhs and then equate the resulting rigid (or inference) types. This fixes https://github.com/rust-lang/trait-system-refactor-initiative/issues/68 by avoiding the exponential blowup. Also supersedes #116369 by only defining opaque types if the hidden type is rigid.
I removed the stability check in `EvalCtxt::evaluate_goal` due to https://github.com/rust-lang/trait-system-refactor-initiative/issues/75. While I personally have opinions on how to fix it, that still requires further t-types/`@nikomatsakis` buy-in, so I removed that for now. Once we've decided on our approach there, we can revert this commit.
r? `@compiler-errors`
This was made possible by the removal of plugin support, which
simplified lint store creation.
This simplifies the places in rustc and rustdoc that call
`describe_lints`, which are early on. The lint store is now built before
those places, so they don't have to create their own lint store for
temporary use, they can just use the main one.
finish `RegionKind` renaming
second step of https://github.com/rust-lang/types-team/issues/95
continues the work from #117876. While working on this and I encountered a bunch of further cleanup which I'll either open a tracking issue for or will do in a separate PR:
- rewrite the `RegionKind` docs, they still talk about `ReEmpty` and are generally out of date
- rename `DescriptionCtx` to `DescriptionCtxt`
- what is `CheckRegions::Bound`?
- `collect_late_bound_regions` et al
- `erase_late_bound_regions` -> `instantiate_bound_regions_with_erased`?
- `EraseEarlyRegions` visitor should be removed, feels duplicate
r? `@BoxyUwU`
make `LayoutError::Cycle` carry `ErrorGuaranteed`
Addresses a FIXME, and also I think it's wise for error variants to carry their `ErrorGuaranteed` -- makes it easier to use that `ErrorGuaranteed` for creating, e.g. `TyKind::Error` and other error kinds. Splitting out from #117703.
Rollup of 4 pull requests
Successful merges:
- #114224 (rustc_llvm: Link to libkstat on Solaris/SPARC)
- #117695 (Reorder checks to make sure potential missing expect on Option/Result…)
- #117870 (`fn args_ref_X` to `fn args_X`)
- #117879 (tests: update check for inferred nneg on zext)
r? `@ghost`
`@rustbot` modify labels: rollup
This is a aspect of Rust that frequently trips up people who are not
aware of it yet. This diagnostic attempts to explain what's happening
and why the lifetime constraint, that was never mentioned in the source,
arose.
Add `std:#️⃣:{DefaultHasher, RandomState}` exports (needs FCP)
This implements rust-lang/libs-team#267 to move the libstd hasher types to `std::hash` where they belong, instead of `std::collections::hash_map`.
<details><summary>The below no longer applies, but is kept for clarity.</summary>
This is a small refactor for #27242, which moves the definitions of `RandomState` and `DefaultHasher` into `std::hash`, but in a way that won't be noticed in the public API.
I've opened rust-lang/libs-team#267 as a formal ACP to move these directly into the root of `std::hash`, but for now, they're at least separated out from the collections code in a way that will make moving that around easier.
I decided to simply copy the rustdoc for `std::hash` from `core::hash` since I think it would be ideal for the two to diverge longer-term, especially if the ACP is accepted. However, I would be willing to factor them out into a common markdown document if that's preferred.
</details>
Fix some clippy perf lints
`@matthiaskrgr` gave me the output of a clippy run with perf lints enabled. This PR fixes ones that I thought were worth fixing.
r? `@cuviper`
Thir unsafeck fixes
- Recognise thread local statics in THIR unsafeck
- Add suggestion for unsafe_op_in_unsafe_fn
- Fix unsafe checking of let expressions
Make the randomize feature of rustc_abi additive
The goal here is to make rust-analyzer able to build with the `rustc_private` versions of the rustc crates it depends on. See #116847
Make sure that predicates with unmentioned bound vars are still considered global in the old solver
In the old solver, we consider predicates with late-bound vars to not be "global":
9c8a2694fa/compiler/rustc_trait_selection/src/traits/select/mod.rs (L1840-L1844)
The implementation of `has_late_bound_vars` was modified in #115834 so that we'd properly anonymize binders that had late-bound vars but didn't reference them. This fixed an ICE.
However, this also led to a behavioral change in https://github.com/rust-lang/rust/issues/117056#issuecomment-1775014545 for a couple of crates, which now consider `for<'a> GL33: Shader` (note the binder var that is *not* used in the predicate) to not be "global". This forces associated types to not be normalizable due to the old trait solver being dumb.
This PR distinguishes types which *reference* late-bound vars and binders which *have* late-bound vars. The latter is represented with the new type flag `TypeFlags::HAS_BINDER_VARS`, which is used when we only care about knowing whether binders have vars in their bound var list (even if they're not used, like for binder anonymization).
This should fix (after beta backport) the `luminance-gl` and `luminance-webgl` crates in #117056.
r? types
**(priority is kinda high on a review here given beta becomes stable on November 16.)**
They've been deprecated for four years.
This commit includes the following changes.
- It eliminates the `rustc_plugin_impl` crate.
- It changes the language used for lints in
`compiler/rustc_driver_impl/src/lib.rs` and
`compiler/rustc_lint/src/context.rs`. External lints are now called
"loaded" lints, rather than "plugins" to avoid confusion with the old
plugins. This only has a tiny effect on the output of `-W help`.
- E0457 and E0498 are no longer used.
- E0463 is narrowed, now only relating to unfound crates, not plugins.
- The `plugin` feature was moved from "active" to "removed".
- It removes the entire plugins chapter from the unstable book.
- It removes quite a few tests, mostly all of those in
`tests/ui-fulldeps/plugin/`.
Closes#29597.
Fix incorrect trait bound restriction suggestion
Suggest
```
error[E0308]: mismatched types
--> $DIR/restrict-assoc-type-of-generic-bound.rs:9:12
|
LL | pub fn foo<A: MyTrait, B>(a: A) -> B {
| - - expected `B` because of return type
| |
| expected this type parameter
LL | return a.bar();
| ^^^^^^^ expected type parameter `B`, found associated type
|
= note: expected type parameter `B`
found associated type `<A as MyTrait>::T`
help: consider further restricting this bound
|
LL | pub fn foo<A: MyTrait<T = B>, B>(a: A) -> B {
| +++++++
```
instead of
```
error[E0308]: mismatched types
--> $DIR/restrict-assoc-type-of-generic-bound.rs:9:12
|
LL | pub fn foo<A: MyTrait, B>(a: A) -> B {
| - - expected `B` because of return type
| |
| expected this type parameter
LL | return a.bar();
| ^^^^^^^ expected type parameter `B`, found associated type
|
= note: expected type parameter `B`
found associated type `<A as MyTrait>::T`
help: consider further restricting this bound
|
LL | pub fn foo<A: MyTrait + <T = B>, B>(a: A) -> B {
| +++++++++
```
Fix#117501.
Suggest
```
error[E0308]: mismatched types
--> $DIR/restrict-assoc-type-of-generic-bound.rs:9:12
|
LL | pub fn foo<A: MyTrait, B>(a: A) -> B {
| - - expected `B` because of return type
| |
| expected this type parameter
LL | return a.bar();
| ^^^^^^^ expected type parameter `B`, found associated type
|
= note: expected type parameter `B`
found associated type `<A as MyTrait>::T`
help: consider further restricting this bound
|
LL | pub fn foo<A: MyTrait<T = B>, B>(a: A) -> B {
| +++++++
```
instead of
```
error[E0308]: mismatched types
--> $DIR/restrict-assoc-type-of-generic-bound.rs:9:12
|
LL | pub fn foo<A: MyTrait, B>(a: A) -> B {
| - - expected `B` because of return type
| |
| expected this type parameter
LL | return a.bar();
| ^^^^^^^ expected type parameter `B`, found associated type
|
= note: expected type parameter `B`
found associated type `<A as MyTrait>::T`
help: consider further restricting this bound
|
LL | pub fn foo<A: MyTrait + <T = B>, B>(a: A) -> B {
| +++++++++
```
Fix#117501.
use global cache when computing proof trees
we're writing the solver while relying on the existence of the global cache to avoid exponential blowup. By disabling the global cache when building proof trees, it is easy to get hangs, e.g. when computing intercrate ambiguity causes.
Removes the unstable `-Zdump_solver_proof_tree_use_cache` option, as we now always return a full proof tree.
r? `@compiler-errors`
Most notably, this commit changes the `pub use crate::*;` in that file
to `use crate::*;`. This requires a lot of `use` items in other crates
to be adjusted, because everything defined within `rustc_span::*` was
also available via `rustc_span::source_map::*`, which is bizarre.
The commit also removes `SourceMap::span_to_relative_line_string`, which
is unused.
Support enum variants in offset_of!
This MR implements support for navigating through enum variants in `offset_of!`, placing the enum variant name in the second argument to `offset_of!`. The RFC placed it in the first argument, but I think it interacts better with nested field access in the second, as you can then write things like
```rust
offset_of!(Type, field.Variant.field)
```
Alternatively, a syntactic distinction could be made between variants and fields (e.g. `field::Variant.field`) but I'm not convinced this would be helpful.
[RFC 3308 # Enum Support](https://rust-lang.github.io/rfcs/3308-offset_of.html#enum-support-offset_ofsomeenumstructvariant-field_on_variant)
Tracking Issue #106655.
Match usize/isize exhaustively with half-open ranges
The long-awaited finale to the saga of [exhaustiveness checking for integers](https://github.com/rust-lang/rust/pull/50912)!
```rust
match 0usize {
0.. => {} // exhaustive!
}
match 0usize {
0..usize::MAX => {} // helpful error message!
}
```
Features:
- Half-open ranges behave as expected for `usize`/`isize`;
- Trying to use `0..usize::MAX` will tell you that `usize::MAX..` is missing and explain why. No more unhelpful "`_` is missing";
- Everything else stays the same.
This should unblock https://github.com/rust-lang/rust/issues/37854.
Review-wise:
- I recommend looking commit-by-commit;
- This regresses perf because of the added complexity in `IntRange`; hopefully not too much;
- I measured each `#[inline]`, they all help a bit with the perf regression (tho I don't get why);
- I did not touch MIR building; I expect there's an easy PR there that would skip unnecessary comparisons when the range is half-open.
Rollup of 5 pull requests
Successful merges:
- #116267 (Some codegen cleanups around SIMD checks)
- #116712 (When encountering unclosed delimiters during lexing, check for diff markers)
- #117416 (Also consider TAIT to be uncomputable if the MIR body is tainted)
- #117421 (coverage: Replace impossible `coverage::Error` with assertions)
- #117438 (Do not ICE on constant evaluation failure in GVN.)
r? `@ghost`
`@rustbot` modify labels: rollup
Store #[deprecated] attribute's `since` value in parsed form
This PR implements the first followup bullet listed in https://github.com/rust-lang/rust/pull/117148#issue-1960240108.
We centralize error handling to the attribute parsing code in `compiler/rustc_attr/src/builtin.rs`, and thereby remove some awkward error codepaths from later phases of compilation that had to make sense of these #\[deprecated\] attributes, namely `compiler/rustc_passes/src/stability.rs` and `compiler/rustc_middle/src/middle/stability.rs`.
Rollup of 7 pull requests
Successful merges:
- #116862 (Detect when trait is implemented for type and suggest importing it)
- #117389 (Some diagnostics improvements of `gen` blocks)
- #117396 (Don't treat closures/coroutine types as part of the public API)
- #117398 (Correctly handle nested or-patterns in exhaustiveness)
- #117403 (Poison check_well_formed if method receivers are invalid to prevent typeck from running on it)
- #117411 (Improve some diagnostics around `?Trait` bounds)
- #117414 (Don't normalize to an un-revealed opaque when we hit the recursion limit)
r? `@ghost`
`@rustbot` modify labels: rollup
share some track_caller logic between interpret and codegen
Also move the code that implements the track_caller intrinsics out of the core interpreter engine -- it's just a helper creating a const-allocation, doesn't need to be part of the interpreter core.
- Sort dependencies and features sections.
- Add `tidy` markers to the sorted sections so they stay sorted.
- Remove empty `[lib`] sections.
- Remove "See more keys..." comments.
Excluded files:
- rustc_codegen_{cranelift,gcc}, because they're external.
- rustc_lexer, because it has external use.
- stable_mir, because it has external use.
See through aggregates in GVN
This PR is extracted from https://github.com/rust-lang/rust/pull/111344
The first 2 commit are cleanups to avoid repeated work. I propose to stop removing useless assignments as part of this pass, and let a later `SimplifyLocals` do it. This makes tests easier to read (among others).
The next 3 commits add a constant folding mechanism to the GVN pass, presented in https://github.com/rust-lang/rust/pull/116012. ~This pass is designed to only use global allocations, to avoid any risk of accidental modification of the stored state.~
The following commits implement opportunistic simplifications, in particular:
- projections of aggregates: `MyStruct { x: a }.x` gets replaced by `a`, works with enums too;
- projections of arrays: `[a, b][0]` becomes `a`;
- projections of repeat expressions: `[a; N][x]` becomes `a`;
- transform arrays of equal operands into a repeat rvalue.
Fixes https://github.com/rust-lang/miri/issues/3090
r? `@oli-obk`
Implement `gen` blocks in the 2024 edition
Coroutines tracking issue https://github.com/rust-lang/rust/issues/43122
`gen` block tracking issue https://github.com/rust-lang/rust/issues/117078
This PR implements `gen` blocks that implement `Iterator`. Most of the logic with `async` blocks is shared, and thus I renamed various types that were referring to `async` specifically.
An example usage of `gen` blocks is
```rust
fn foo() -> impl Iterator<Item = i32> {
gen {
yield 42;
for i in 5..18 {
if i.is_even() { continue }
yield i * 2;
}
}
}
```
The limitations (to be resolved) of the implementation are listed in the tracking issue
Fix ICE: Restrict param constraint suggestion
When encountering an associated item with a type param that could be constrained, do not look at the parent item if the type param comes from the associated item.
Fix#117209, fix#89868.
Stash and cancel cycle errors for auto trait leakage in opaques
We don't need to emit a traditional cycle error when we have a selection error that explains what's going on but in more detail.
We may want to augment this error to actually point out the cycle, now that the cycle error is not being emitted. We could do that by storing the set of opaques that was in the `CyclePlaceholder` that gets returned from `type_of_opaque`.
r? `@oli-obk` cc `@estebank` #117235
Rework negative coherence to properly consider impls that only partly overlap
This PR implements a modified negative coherence that handles impls that only have partial overlap.
It does this by:
1. taking both impl trait refs, instantiating them with infer vars
2. equating both trait refs
3. taking the equated trait ref (which represents the two impls' intersection), and resolving any vars
4. plugging all remaining infer vars with placeholder types
these placeholder-plugged trait refs can then be used normally with the new trait solver, since we no longer have to worry about the issue with infer vars in param-envs.
We use the **new trait solver** to reason correctly about unnormalized trait refs (due to deferred projection equality), since this avoid having to normalize anything under param-envs with infer vars in them.
This PR then additionally:
* removes the `FnPtr` knowable hack by implementing proper negative `FnPtr` trait bounds for rigid types.
---
An example:
Consider these two partially overlapping impls:
```
impl<T, U> PartialEq<&U> for &T where T: PartialEq<U> {}
impl<F> PartialEq<F> for F where F: FnPtr {}
```
Under the old algorithm, we would take one of these impls and replace it with infer vars, then try unifying it with the other impl under identity substitutions. This is not possible in either direction, since it either sets `T = U`, or tries to equate `F = &?0`.
Under the new algorithm, we try to unify `?0: PartialEq<?0>` with `&?1: PartialEq<&?2>`. This gives us `?0 = &?1 = &?2` and thus `?1 = ?2`. The intersection of these two trait refs therefore looks like: `&?1: PartialEq<&?1>`. After plugging this with placeholders, we get a trait ref that looks like `&!0: PartialEq<&!0>`, with the first impl having substs `?T = ?U = !0` and the second having substs `?F = &!0`[^1].
Then we can take the param-env from the first impl, and try to prove the negated where clause of the second.
We know that `&!0: !FnPtr` never holds, since it's a rigid type that is also not a fn ptr, we successfully detect that these impls may never overlap.
[^1]: For the purposes of this example, I just ignored lifetimes, since it doesn't really matter.
Rename AsyncCoroutineKind to CoroutineSource
pulled out of https://github.com/rust-lang/rust/pull/116447
Also refactors the printing infra of `CoroutineSource` to be ready for easily extending it with a `Gen` variant for `gen` blocks
Uplift `Canonical` to `rustc_type_ir`
I plan on moving the new trait solver's canonicalizer into either `rustc_type_ir` or a child crate. One dependency on this is lifting `Canonical<V>` to `rustc_type_ir` so we can actually name the canonicalized values.
I may also later lift `CanonicalVarInfo` into the new trait solver. I can't really tell what other changes need to be done, but I'm just putting this up sooner than later since I'm almost certain it'll need to be done regardless of other design choices.
There are a couple of warts introduced by this PR, since we no longer can define inherent `Canonical` impls in `rustc_middle` -- see the changes to:
* `compiler/rustc_trait_selection/src/traits/query/normalize.rs`
* `compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs`
r? lcnr
Uplift `ClauseKind` and `PredicateKind` into `rustc_type_ir`
Uplift `ClauseKind` and `PredicateKind` into `rustc_type_ir`.
Blocked on #116951
r? `@ghost`
Get rid of `'tcx` lifetime on `ConstVid`, `EffectVid`
These are simply newtyped numbers, so don't really have a reason (per se) to have a lifetime -- `TyVid` and `RegionVid` do not, for example.
The only consequence of this is that we need to use a new key type for `UnifyKey` that mentions `'tcx`. This is already done for `RegionVid`, with `RegionVidKey<'tcx>`, but this `UnifyKey` trait implementation may have been the original reason to give `ConstVid` a lifetime. See the changes to `compiler/rustc_middle/src/infer/unify_key.rs` specifically.
I consider the code cleaner this way, though -- we removed quite a few unnecessary `'tcx` in the process. This also makes it easier to uplift these two ids to `rustc_type_ir`, which I plan on doing in a follow-up PR.
r? `@BoxyUwU`
`OptWithInfcx` naming nits, trait bound simplifications
* Use an associated type `Interner` on `InferCtxtLike` to remove a redundant interner parameter (`I: Interner, Infcx: InferCtxtLike<I>` -> `Infcx: InferCtxtLike`).
* Remove double-`Option` between `infcx: Option<Infcx>` and `fn universe_of_ty(&self, ty: ty::InferTy) -> Option<ty::UniverseIndex>`. We don't need the infcx to be optional if we can provide a "noop" (`NoInfcx`) implementation that just always returns `None` for universe index.
* Also removes the `core::convert::Infallible` implementation which I found a bit weird...
* Some naming nits with params.
* I found `InferCtxt` + `InfCtx` and `Infcx` to be a lot of different ways to spell "inference context", so I got rid of the `InfCtx` type parameter name in favor of `Infcx` which is a more standard name.
* I found `OptWithInfcx` to be a bit redundant -> `WithInfcx`.
I'm making these changes because I intend to reuse the `InferCtxtLike` trait for uplifting the canonicalizer into a new trait -- conveniently, the information I need for uplifting the canonicalizer also is just the universe information of a type var, so it's super convenient 😸
r? `@BoxyUwU` or `@lcnr`
Rollup of 6 pull requests
Successful merges:
- #107159 (rand use getrandom for freebsd (available since 12.x))
- #116859 (Make `ty::print::Printer` take `&mut self` instead of `self`)
- #117046 (return unfixed len if pat has reported error)
- #117070 (rustdoc: wrap Type with Box instead of Generics)
- #117074 (Remove smir from triage and add me to stablemir)
- #117086 (Update .mailmap to promote my livename)
r? `@ghost`
`@rustbot` modify labels: rollup
Make `ty::print::Printer` take `&mut self` instead of `self`
based on #116815
This simplifies the code by removing all the `self` assignments and
makes the flow of data clearer - always into the printer.
Especially in v0 mangling, which already used `&mut self` in some
places, it gets a lot more uniform.
report `unused_import` for empty reexports even it is pub
Fixes#116032
An easy fix. r? `@petrochenkov`
(Discovered this issue while reviewing #115993.)
Implement jump threading MIR opt
This pass is an attempt to generalize `ConstGoto` and `SeparateConstSwitch` passes into a more complete jump threading pass.
This pass is rather heavy, as it performs a truncated backwards DFS on MIR starting from each `SwitchInt` terminator. This backwards DFS remains very limited, as it only walks through `Goto` terminators.
It is build to support constants and discriminants, and a propagating through a very limited set of operations.
The pass successfully manages to disentangle the `Some(x?)` use case and the DFA use case. It still needs a few tests before being ready.
Avoid a `track_errors` by bubbling up most errors from `check_well_formed`
I believe `track_errors` is mostly papering over issues that a sufficiently convoluted query graph can hit. I made this change, while the actual change I want to do is to stop bailing out early on errors, and instead use this new `ErrorGuaranteed` to invoke `check_well_formed` for individual items before doing all the `typeck` logic on them.
This works towards resolving https://github.com/rust-lang/rust/issues/97477 and various other ICEs, as well as allowing us to use parallel rustc more (which is currently rather limited/bottlenecked due to the very sequential nature in which we do `rustc_hir_analysis::check_crate`)
cc `@SparrowLii` `@Zoxc` for the new `try_par_for_each_in` function
coverage: Emit mappings for unused functions without generating stubs
For a while I've been annoyed by the fact that generating coverage maps for unused functions involves generating a stub function at the LLVM level.
As I suspected, generating that stub function isn't actually necessary, as long as we specifically tell LLVM about the symbol names of all the functions that have coverage mappings but weren't codegenned (due to being unused).
---
There is some helper code that gets moved around in the follow-up patches, so look at the first patch to see the most important functional changes.
---
`@rustbot` label +A-code-coverage
This simplifies the code by removing all the `self` assignments and
makes the flow of data clearer - always into the printer.
Especially in v0 mangling, which already used `&mut self` in some
places, it gets a lot more uniform.
This query has a name that sounds general-purpose, but in fact it has
coverage-specific semantics, and (fortunately) is only used by coverage code.
Because it is only ever called once (from one designated CGU), it doesn't need
to be a query, and we can change it to a regular function instead.
Uplift movability and mutability, the simple way
Just make type_ir a dependency of ast. This can be relaxed later if we want to make the dependency less heavy. Part of rust-lang/types-team#124.
r? `@lcnr` or `@jackh726`
coverage: Move most per-function coverage info into `mir::Body`
Currently, all of the coverage information collected by the `InstrumentCoverage` pass is smuggled through MIR in the form of individual `StatementKind::Coverage` statements, which must then be reassembled by coverage codegen.
That's awkward for a number of reasons:
- While some of the coverage statements do care about their specific position in the MIR control-flow graph, many of them don't, and are just tacked onto the function's first BB as metadata carriers.
- MIR inlining can result in coverage statements being duplicated, so coverage codegen has to jump through hoops to avoid emitting duplicate mappings.
- MIR optimizations that would delete coverage statements need to carefully copy them into the function's first BB so as not to omit them from coverage reports.
- The order in which coverage codegen sees coverage statements is dependent on MIR optimizations/inlining, which can cause unnecessary churn in the emitted coverage mappings.
- We don't have a good way to annotate MIR-level functions with extra coverage info that doesn't belong in a statement.
---
This PR therefore takes most of the per-function coverage info and stores it in a field in `mir::Body` as `Option<Box<FunctionCoverageInfo>>`.
(This adds one pointer to the size of `mir::Body`, even when coverage is not enabled.)
Coverage statements still need to be injected into MIR in some cases, but only when they actually affect codegen (counters) or are needed to detect code that has been optimized away as unreachable (counters/expressions).
---
By the end of this PR, the information stored in `FunctionCoverageInfo` is:
- A hash of the function's source code (needed by LLVM's coverage map format)
- The number of coverage counters added by coverage instrumentation
- A table of coverage expressions, associating each expression ID with its operator (add or subtract) and its two operands
- The list of mappings, associating each covered code region with a counter/expression/zero value
---
~~This is built on top of #115301, so I'll rebase and roll a reviewer once that lands.~~
r? `@ghost`
`@rustbot` label +A-code-coverage
This new description reflects the changes made in this PR, and should hopefully
be more useful to non-coverage developers who need to care about coverage
statements.
Even though expression details are now stored in the info structure, we still
need to inject `ExpressionUsed` statements into MIR, because if one is missing
during codegen then we know that it was optimized out and we can remap all of
its associated code regions to zero.
Previously, mappings were attached to individual coverage statements in MIR.
That necessitated special handling in MIR optimizations to avoid deleting those
statements, since otherwise codegen would be unable to reassemble the original
list of mappings.
With this change, a function's list of mappings is now attached to its MIR
body, and survives intact even if individual statements are deleted by
optimizations.
Don't compare host param by name
Seems sketchy to be searching for `sym::host` by name, especially when we can get the actual index with not very much work.
r? fee1-dead
Coverage codegen can now allocate arrays based on the number of
counters/expressions originally used by the instrumentor.
The existing query that inspects coverage statements is still used for
determining the number of counters passed to `llvm.instrprof.increment`. If
some high-numbered counters were removed by MIR optimizations, the instrumented
binary can potentially use less memory and disk space at runtime.
This allows coverage information to be attached to the function as a whole when
appropriate, instead of being smuggled through coverage statements in the
function's basic blocks.
As an example, this patch moves the `function_source_hash` value out of
individual `CoverageKind::Counter` statements and into the per-function info.
When synthesizing unused functions for coverage purposes, the absence of this
info is taken to indicate that a function was not eligible for coverage and
should not be synthesized.
Remove lots of generics from `ty::print`
All of these generics mostly resolve to the same thing, which means we can remove them, greatly simplifying the types involved in pretty printing and unlocking another simplification (that is not performed in this PR): Using `&mut self` instead of passing `self` through the return type.
cc `@eddyb` you probably know why it's like this, just checking in and making sure I didn't do anything bad
r? oli-obk
These are `Self` in almost all printers except one, which can just store
the state as a field instead. This simplifies the printer and allows for
further simplifications, for example using `&mut self` instead of
passing around the printer.
THIR unsafety checking was getting a cycle of
function unsafety checking
-> building THIR for the function
-> evaluating pattern inline constants in the function
-> building MIR for the inline constant
-> checking unsafety of functions (so that THIR can be stolen)
This is fixed by not stealing THIR when generating MIR but instead when
unsafety checking.
This leaves an issue with pattern inline constants not being unsafety
checked because they are evaluated away when generating THIR.
To fix that we now represent inline constants in THIR patterns and
visit them in THIR unsafety checking.
don't UB on dangling ptr deref, instead check inbounds on projections
This implements https://github.com/rust-lang/reference/pull/1387 in Miri. See that PR for what the change is about.
Detecting dangling references in `let x = &...;` is now done by validity checking only, so some tests need to have validity checking enabled. There is no longer inherently a "nodangle" check in evaluating the expression `&*ptr` (aside from the aliasing model).
r? `@oli-obk`
Based on:
- https://github.com/rust-lang/reference/pull/1387
- https://github.com/rust-lang/rust/pull/115524
interpret: clean up AllocBytes
Fixes https://github.com/rust-lang/miri/issues/2836
Nothing has moved here in half a year, so let's just remove these unused stubs -- they need a proper re-design anyway.
r? `@oli-obk`
Format all the let-chains in compiler crates
Since rust-lang/rustfmt#5910 has landed, soon we will have support for formatting let-chains (as soon as rustfmt syncs and beta gets bumped).
This PR applies the changes [from master rustfmt to rust-lang/rust eagerly](https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/out.20formatting.20of.20prs/near/374997516), so that the next beta bump does not have to deal with a 200+ file diff and can remain concerned with other things like `cfg(bootstrap)` -- #113637 was a pain to land, for example, because of let-else.
I will also add this commit to the ignore list after it has landed.
The commands that were run -- I'm not great at bash-foo, but this applies rustfmt to every compiler crate, and then reverts the two crates that should probably be formatted out-of-tree.
```
~/rustfmt $ ls -1d ~/rust/compiler/* | xargs -I@ cargo run --bin rustfmt -- `@/src/lib.rs` --config-path ~/rust --edition=2021 # format all of the compiler crates
~/rust $ git checkout HEAD -- compiler/rustc_codegen_{gcc,cranelift} # revert changes to cg-gcc and cg-clif
```
cc `@rust-lang/rustfmt`
r? `@WaffleLapkin` or `@Nilstrieb` who said they may be able to review this purely mechanical PR :>
cc `@Mark-Simulacrum` and `@petrochenkov,` who had some thoughts on the order of operations with big formatting changes in https://github.com/rust-lang/rust/pull/95262#issue-1178993801. I think the situation has changed since then, given that let-chains support exists on master rustfmt now, and I'm fairly confident that this formatting PR should land even if *bootstrap* rustfmt doesn't yet format let-chains in order to lessen the burden of the next beta bump.
Relate alias ty with variance
In the new solver, turns out that the subst-relate branch of the alias-relate predicate was relating args invariantly even for opaques, which have variance 💀.
This change is a bit more invasive, but I'd rather not special-case it [here](aeaa5c30e5/compiler/rustc_trait_selection/src/solve/alias_relate.rs (L171-L190)) and then have it break elsewhere. I'm doing a perf run to see if the extra call to `def_kind` is that expensive, if it is, I'll reconsider.
r? ``@lcnr``
Extend `impl`'s `def_span` to include its where clauses
Typically, we highlight the def-span of an impl in a diagnostic due to either:
1. coherence error
2. trait evaluation cycle
3. invalid implementation of built-in trait
I find that an impl's where clauses are very often required to understanding why these errors come about, which is unfortunate since where clauses may be located on different lines and don't show up in the error. This PR expands the def-span of impls to include these where clauses.
r? cjgillot since you've touched this code a while back to make some spans shorter, but you can also reassign to wg-diagnostics or compiler if you're busy or have no strong opinions.
improve the suggestion of `generic_bound_failure`
- Fixes#115375
- suggest the bound in the correct scope: trait or impl header vs assoc item. See `tests/ui/suggestions/lifetimes/type-param-bound-scope.rs`
- don't suggest a lifetime name that conflicts with the other late-bound regions of the function:
```rust
type Inv<'a> = *mut &'a ();
fn check_bound<'a, T: 'a>(_: T, _: Inv<'a>) {}
fn test<'a, T>(_: &'a str, t: T, lt: Inv<'_>) { // suggests a new name `'a`
check_bound(t, lt); //~ ERROR
}
```
Generalize small dominators optimization
* Use small dominators optimization from 640ede7b0a more generally.
* Merge `DefLocation` and `LocationExtended` since they serve the same purpose.
remove Key impls for types that involve an AllocId
I don't understand how but somehow that leads to issues like https://github.com/rust-lang/rust/issues/83085? Anyway removing unused impls doesn't seem like a bad idea. The concerning part is that of course nothing will stop us from having such impls again in the future, alongside re-introducing bugs like #83085.
r? `@oli-obk`
Bring back generic parameters for indices in rustc_abi and make it compile on stable
This effectively reverses https://github.com/rust-lang/rust/pull/107163, allowing rust-analyzer to depend on this crate again,
It also moves some glob imports / expands them in the first commit because they made it more difficult for me to reason about things.
The word "active" is currently used in two different and confusing ways:
- `ACTIVE_FEATURES` actually means "available unstable features"
- `Features::active_features` actually means "features declared in the
crate's code", which can include feature within `ACTIVE_FEATURES` but
also others.
(This is also distinct from "enabled" features which includes declared
features but also some edition-specific features automatically enabled
depending on the edition in use.)
This commit changes the `Features::active_features` to
`Features::declared_features` which actually matches its meaning.
Likewise, `Features::active` becomes `Features::declared`.
Remove the `TypedArena::alloc_from_iter` specialization.
It was added in #78569. It's complicated and doesn't actually help
performance.
r? `@cjgillot`
All other impls replace type generics with `()` (or a type implementing the necessery traits)
and lifetimes with `'static`, do the same for those impls.
coverage: Allow each coverage statement to have multiple code regions
The original implementation of coverage instrumentation was built around the assumption that a coverage counter/expression would be associated with *up to one* code region. When it was discovered that *multiple* regions would sometimes need to share a counter, a workaround was found: for the remaining regions, the instrumentor would create a fresh expression that adds zero to the existing counter/expression.
That got the job done, but resulted in some awkward code, and produces unnecessarily complicated coverage maps in the final binary.
---
This PR removes that tension by changing `StatementKind::Coverage`'s code region field from `Option<CodeRegion>` to `Vec<CodeRegion>`.
The changes on the codegen side are fairly straightforward. As long as each `CoverageKind::Counter` only injects one `llvm.instrprof.increment`, the rest of coverage codegen is happy to handle multiple regions mapped to the same counter/expression, with only minor option-to-vec adjustments.
On the instrumentor/mir-transform side, we can get rid of the code that creates extra (x + 0) expressions. Instead we gather all of the code regions associated with a single BCB, and inject them all into one coverage statement.
---
There are several patches here but they can be divided in to three phases:
- Preparatory work
- Actually switching over to multiple regions per coverage statement
- Cleaning up
So viewing the patches individually may be easier.
a small wf and clause cleanup
- remove `Clause::from_projection_clause`, instead use `ToPredicate`
- change `predicate_obligations` to directly take a `Clause`
- remove some unnecessary `&`
- use clause in `min_specialization` checks where easily applicable
Rollup of 5 pull requests
Successful merges:
- #115863 (Add check_unused_messages in tidy)
- #116210 (Ensure that `~const` trait bounds on associated functions are in const traits or impls)
- #116358 (Rename both of the `Match` relations)
- #116371 (Remove unused features from `rustc_llvm`.)
- #116374 (Print normalized ty)
r? `@ghost`
`@rustbot` modify labels: rollup
When these methods were originally written, I wasn't aware that
`newtype_index!` already supports addition with ordinary numbers, without
needing to unwrap and re-wrap.
Cleanup number handling in match exhaustiveness
Doing a little bit of cleanup; handling number constants was somewhat messy. In particular, this:
- evals float consts once instead of repetitively
- reduces `Constructor` from 88 bytes to 56 (`mir::Const` is big!)
The `fast_try_eval_bits` function was mostly constructed from inlining existing code but I don't fully understand it; I don't follow how consts work and are evaluated very well.
Assorted improvements for `rustc_middle::mir::traversal`
r? `@cjgillot`
I'm not _entirely_ sure about all changes, although I do like all of them. If you'd like I can drop some commits. Best reviewed on a commit-by-commit basis, I think, since they are fairly isolated.
Implement a global value numbering MIR optimization
The aim of this pass is to avoid repeated computations by reusing past assignments. It is based on an analysis of SSA locals, in order to perform a restricted form of common subexpression elimination.
By opportunity, this pass allows for some simplifications by combining assignments. For instance, this pass could be able to see through projections of aggregates to directly reuse the aggregate field (not in this PR).
We handle references by assigning a different "provenance" index to each `Ref`/`AddressOf` rvalue. This ensure that we do not spuriously merge borrows that should not be merged. Meanwhile, we consider all the derefs of an immutable reference to a freeze type to give the same value:
```rust
_a = *_b // _b is &Freeze
_c = *_b // replaced by _c = _a
```
Don't store lazyness in `DefKind::TyAlias`
1. Don't store lazyness of a type alias in its `DefKind`, but instead via a query.
2. This allows us to treat type aliases as lazy if `#[feature(lazy_type_alias)]` *OR* if the alias contains a TAIT, rather than having checks for both in separate parts of the codebase.
r? `@oli-obk` cc `@fmease`