Rollup of 10 pull requests
Successful merges:
- #122707 (Fix a typo in the alloc::string::String docs)
- #122769 (extend comments for reachability set computation)
- #122892 (fix(bootstrap/dist): use versioned dirs when vendoring)
- #122896 (Update stdarch submodule)
- #122923 (In `pretty_print_type()`, print `async fn` futures' paths instead of spans.)
- #122950 (Add regression tests for #101903)
- #123039 (Update books)
- #123042 (Import the 2021 prelude in the core crate)
- #123044 (`Instance` is `Copy`)
- #123051 (did I mention that tests are super cool? )
r? `@ghost`
`@rustbot` modify labels: rollup
Print a backtrace in const eval if interrupted
Demo:
```rust
#![feature(const_eval_limit)]
#![const_eval_limit = "0"]
const OW: u64 = {
let mut res: u64 = 0;
let mut i = 0;
while i < u64::MAX {
res = res.wrapping_add(i);
i += 1;
}
res
};
fn main() {
println!("{}", OW);
}
```
```
╭ ➜ ben@archlinux:~/rust
╰ ➤ rustc +stage1 spin.rs
^Cerror[E0080]: evaluation of constant value failed
--> spin.rs:8:33
|
8 | res = res.wrapping_add(i);
| ^ Compilation was interrupted
note: erroneous constant used
--> spin.rs:15:20
|
15 | println!("{}", OW);
| ^^
note: erroneous constant used
--> spin.rs:15:20
|
15 | println!("{}", OW);
| ^^
|
= note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
```
`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