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.
Fix bad span for explicit lifetime suggestions
Fixes#121267
Current explicit lifetime suggestions are not showing correct spans for some lifetimes - e.g. elided lifetime generic parameters;
This should be done correctly regarding elided lifetime kind like the following code
43fdd4916d/compiler/rustc_resolve/src/late/diagnostics.rs (L3015-L3044)
coverage: Remove incorrect assertions from counter allocation
These assertions detect situations where a BCB node (in the coverage graph) would have both a physical counter and one or more in-edge counters/expressions.
For most BCBs that situation would indicate an implementation bug. However, it's perfectly fine in the case of a BCB having an edge that loops back to itself.
Given the complexity and risk involved in fixing the assertions, and the fact that nothing relies on them actually being true, this patch just removes them instead.
Fixes#122738.
`````@rustbot````` label +A-code-coverage
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.
These assertions detect situations where a BCB node would have both a physical
counter and one or more in-edge counters/expressions.
For most BCBs that situation would indicate an implementation bug. However,
it's perfectly fine in the case of a BCB having an edge that loops back to
itself.
Given the complexity and risk involved in fixing the assertions, and the fact
that nothing relies on them actually being true, this patch just removes them
instead.
Remove redundant coroutine captures note
This note is redundant, since we'll always be printing this "captures the following types..." between *more* descriptive `BuiltinDerivedObligationCause`s.
Please review with whitespace disabled, since I also removed an unnecessary labeled break.
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
Ensure stack before parsing dot-or-call
There are many cases where, due to codegen or a massively unruly codebase, a deeply nested `call(call(call(call(call(call(call(call(call(f())))))))))` can happen. This is a spot where it would be good to grow our stack, so that we can survive to tell the programmer their code is dubiously written.
Closes https://github.com/rust-lang/rust/issues/122715
Fix ICE: `global_asm!()` Don't Panic When Unable to Evaluate Constant
Fixes#121099
A bit of an inelegant fix but given that the error is created only
after call to `const_eval_poly()` and that the calling function
cannot propagate the error anywhere else, the error has to be
explicitly handled inside `mono_item.rs`.
r? `@Amanieu`
Fix incorrect mutable suggestion information for binding in ref pattern.
For ref pattern in func param, the mutability suggestion has to apply to the binding.
For example: `fn foo(&x: &i32)` -> `fn foo(&(mut x): &i32)`
fixes#122415
compiletest: Add support for `//@ aux-bin: foo.rs`
Which enables ui tests to use auxiliary binaries. See the added
self-test for an example.
This is an enabler for the test in https://github.com/rust-lang/rust/pull/121573.
Extend format arg help for simple tuple index access expression
The help is only applicable for simple field access `a.b` and (with this PR) simple tuple index access expressions `a.0`.
Closes#122535.
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`
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.
Remove some only- clauses from mir-opt tests
Derived from https://github.com/rust-lang/rust/pull/122295
Many of these tests were originally codegen tests, and MIR is more trivially portable than LLVM IR. We simply don't need to restrict the platform in most cases.
r? Nadrieril
There are many cases where, due to codegen or a massively unruly codebase,
a deeply nested call(call(call(call(call(call(call(call(call(f())))))))))
can happen. This is a spot where it would be good to grow our stack, so that
we can survive to tell the programmer their code is dubiously written.
For ref pattern in func param, the mutability suggestion has to apply to the binding.
For example: `fn foo(&x: &i32)` -> `fn foo(&(mut x): &i32)`
fixes#122415
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.
CFI: Break tests into smaller files
Break type metadata identifiers tests into smaller set of tests/files, and move CFI (and KCFI) codegen tests to a cfi (and kcfi) subdirectory,
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.
never patterns: suggest `!` patterns on non-exhaustive matches
When a match is non-exhaustive we now suggest never patterns whenever it makes sense.
r? ``@compiler-errors``
Reject overly generic assoc const binding types
Split off from #119385 to make #119385 easier to review.
---
In the *instantiated* type of assoc const bindings
1. reject **early-bound generic params**
* Provide a rich error message instead of ICE'ing ([#108271](https://github.com/rust-lang/rust/issues/108271)).
* This is a temporary and semi-artificial restriction until the arrival of *generic const generics*.
* It's quite possible that rustc could already perfectly support this subset of generic const generics if we just removed some checks (some `.no_bound_vars().expect(…)`) but even if that was the case, I'd rather gate it behind a new feature flag. Reporting an error instead of ICE'ing is a good first step towards an eventual feature gate error.
2. reject **escaping late-bound generic params**
* They lead to ICEs before & I'm pretty sure that they remain incorrect even in a world with *generic const generics*
---
Together with #118668 & #119385, this supersedes #118360.
Fixes#108271.