Let codegen decide when to `mem::swap` with immediates
Making `libcore` decide this is silly; the backend has so much better information about when it's a good idea.
Thus this PR introduces a new `typed_swap` intrinsic with a fallback body, and replaces that fallback implementation when swapping immediates or scalar pairs.
r? oli-obk
Replaces #111744, and means we'll never need more libs PRs like #111803 or #107140
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
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`
Suggest `_` for missing generic arguments in turbofish
The compiler may suggest unusable generic type names for missing generic arguments in an expression context:
```rust
fn main() {
(0..1).collect::<Vec>()
}
```
> help: add missing generic argument
>
> (0..1).collect::<Vec<T>>()
but `T` is not a valid name in this context, and this suggestion won't compile.
I've changed it to use `_` inside method calls (turbofish), so it will suggest `(0..1).collect::<Vec<_>>()` which _may_ compile.
It's possible that the suggested `_` will be ambiguous, but there is very extensive E0283 that will help resolve that, which is more helpful than a basic "cannot find type `T` in this scope" users would get otherwise.
Out of caution to limit scope of the change I've limited it to just turbofish, but I suspect `_` could be the better choice in more cases. Perhaps in all expressions?
Gracefully handle `AnonConst` in `diagnostic_hir_wf_check()`
Instead of running the WF check on the `AnonConst` itself we run it on the `ty` of the generic param of which the `AnonConst` is the default value.
Fixes#122199
This makes it easier to read the trait definition for newcomers:
Sorted from least “complex” to most “complex” followed by trivial “plumbing”
and grouped by area.
* Move `allow_infer` above all `*_infer` methods
* It's the least complex method of those
* Allows the `*_infer` to be placed right next to each other
* Move `probe_ty_param_bounds` further down right next to `lower_assoc_ty` and `probe_adt`
* It's more complex than the `infer` methods, it should come “later”
* Now all required lowering functions are grouped together
* Move the “plumbing” function `set_tainted_by_errors` further down
below any actual lowering methods.
* Provided method should come last
Most of the tracing calls didn't fully leverage the power of `tracing`.
For example, several of them used to hard-code method names / tracing spans
as well as variable names. Use `#[instrument]` and `?var` / `%var` (etc.) instead.
In my opinion, this is the proper way to migrate them from the old
AstConv nomenclature to the new HIR ty lowering one.
Several (doc) comments were super outdated or didn't provide enough context.
Some doc comments shoved everything in a single paragraph without respecting
the fact that the first paragraph should be a single sentence because rustdoc
treats these as item descriptions / synopses on module pages.
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.
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
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.
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.
```
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.
Making `libcore` decide this is silly; the backend has so much better information about when it's a good idea.
So introduce a new `typed_swap` intrinsic with a fallback body, but replace that implementation for immediates and scalar pairs.
Remove obsolete parameter `speculative` from `instantiate_poly_trait_ref`
In #122527 I totally missed that `speculative` has become obsolete with the removal of `hir_trait_to_predicates` / due to #113671.
Fixes#114635.
r? `@compiler-errors`
Split refining_impl_trait lint into _reachable, _internal variants
As discussed in https://github.com/rust-lang/rust/issues/119535#issuecomment-1909352040:
> We discussed this today in triage and developed a consensus to:
>
> * Add a separate lint against impls that refine a return type defined with RPITIT even when the trait is not crate public.
> * Place that in a lint group along with the analogous crate public lint.
> * Create an issue to solicit feedback on these lints (or perhaps two separate ones).
> * Have the warnings displayed with each lint reference this issue in a similar manner to how we do that today with the required `Self: '0'` bound on GATs.
> * Make a note to review this feedback on 2-3 release cycles.
This points users to https://github.com/rust-lang/rust/issues/121718 to leave feedback.
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.
Clean up AstConv
Split off from #120926 to make it only contain the renaming & (doc) comment updates.
Any changes other than that which have accumulated over time are now part of this PR.
Let's be disciplined ;) Inspired by https://github.com/rust-lang/rust/pull/120926#issuecomment-1997984483.
---
* Remove `hir_trait_to_predicates`
* Unused since #113671
* Inline `create_args_for_ast_trait_ref`
* Only had a single call site
* Having it as a separate method didn't gain us anything
* Use an if-let guard somewhere to avoid unwrapping
* Avoid explicit trait object lifetimes
* More legible, stylistic-only (the updated code is 100% semantically identical)
* Use explicitly elided lifetimes in impl headers, they get elaborated to distinct lifetimes
* Make use of [object lifetime defaulting](https://doc.rust-lang.org/reference/lifetime-elision.html#default-trait-object-lifetimes) for a trait object type inside of a reference type somewhere
* Use preexisting dedicated method `ItemCtxt::to_ty` over `<dyn AstConv<'_>>::ast_ty_to_ty`
* Use preexisting dedicated method `AstConv::astconv` over explicit coercions
* Simplify the function signature of `create_args_for_ast_path` and of `check_generic_arg_count`
* In both cases redundant information was passed rendering the call sites verbose and confusing
* No perf impact (tested in [#120926](https://github.com/rust-lang/rust/pull/120926))
* Move diagnostic method `report_ambiguous_associated_type` from `astconv` to `astconv::errors`
* The submodule `errors` exists specifically for that purpose
* Use it to keep the main module clean & short
Ensure RPITITs are created before def-id freezing
From the test:
```rust
// `ty::Error` in a trait ref will silence any missing item errors, but will also
// prevent the `associated_items` query from being called before def ids are frozen.
```
Essentially, the code that checks that `impl`s have all their items (`check_impl_items_against_trait`) is also (implicitly) responsible for fetching the `associated_items` query before, but since we early return here:
c2901f5435/compiler/rustc_hir_analysis/src/check/check.rs (L732-L737)
...that means that this never happens for trait refs that reference errors.
Fixes#122518
r? oli-obk
Create some minimal HIR for associated opaque types
`LocalDefId`s for opaque types in traits and impls are created after AST -> HIR lowering, so they don't have corresponding HIR and return their various properties through fed queries.
In this PR I also feed some core HIR-related queries for these `LocalDefId`s (which happen to be HIR owners).
As a result all `LocalDefId`s now have corresponding `HirId`s and HIR nodes, and "optional" methods like `opt_local_def_id_to_hir_id` and `opt_hir_node_by_def_id` can be removed.
Follow up to https://github.com/rust-lang/rust/pull/120206.