Restore region uniquification in the new solver 🎉
All of the bugs that were "due" to uniquification have been settled via other means (e.g. bidirectional alias-relate, param-env incompleteness, etc).
Firstly, revert the functional changes in #110180. 😸
Secondly, we need to ignore regions when considering if a goal has changed (the "has_changed" boolean returned from `evaluate_goal`) -- otherwise, because we're doing region uniquification, we may perpetually consider a goal to be changed. See the UI test I committed for an explanation.
Don't treat negative trait predicates as always knowable
We don't need this. It was added in #90104 but I don't really know why. It's not sound afaict -- negative trait predicates need the same coherence-ambiguity/orphan check rules as positive ones.
r? `@lcnr`
cc `@spastorino,` do you remember why?
Double check that hidden types match the expected hidden type
Fixes https://github.com/rust-lang/rust/issues/113278 specifically, but I left a TODO for where we should also add some hardening.
It feels a bit like papering over the issue, but at least this way we don't get unsoundness, but just surprising errors. Errors will be improved and given spans before this PR lands.
r? `@compiler-errors` `@lcnr`
rustdoc: handle cross-crate RPITITs correctly
Filter out the internal associated types synthesized during the desugaring of RPITITs, they really shouldn't show up in the docs.
This also fixes#113929 since we're no longer invoking `is_impossible_associated_item` (renamed from `is_impossible_method`) which cannot handle them (leading to an ICE). I don't think it makes sense to try to make `is_impossible_associated_item` handle this exotic kind of associated type (CC original author `@compiler-errors).`
@ T-rustdoc reviewers, currently I'm throwing out ITIT assoc tys before cleaning assoc tys at each usage-site. I'm thinking about making `clean_middle_assoc_item` return an `Option<_>` instead and doing the check inside of it to prevent any call sites from forgetting the check for ITITs. Since I wasn't sure if you would like that approach, I didn't go through with it. Let me know what you think.
<details><summary>Explanation on why <code>is_impossible_associated_item(itit_assoc_ty)</code> leads to an ICE</summary>
Given the following code:
```rs
pub trait Trait { fn def<T>() -> impl Default {} }
impl Trait for () {}
```
The generated associated type looks something like (simplified):
```rs
type {opaque#0}<T>: Default = impl Default; // the name is actually `kw::Empty` but this is the `def_path_str` repr
```
The query `is_impossible_associated_item` goes through all predicates of the associated item – in this case `<T as Sized>` – to check if they contain any generic parameters from the (generic) associated type itself. For predicates that don't contain any *own* generics, it does further processing, part of which is instantiating the predicate with the generic arguments of the impl block (which is only correct if they truly don't contain any own generics since they wouldn't get instantiated this way leading to an ICE).
It checks if `parent_def_id(T) == assoc_ty_def_id` to get to know if `T` is owned by the assoc ty. Unfortunately this doesn't work for ITIT assoc tys. In this case, the parent of `T` is `Trait::def` (!) which is the associated function (I'm pretty sure this is very intentional) which is of course not equal to the assoc ty `Trait::{opaque#0}`.
</details>
`@rustbot` label A-cross-crate-reexports
Get rid of subst-relate incompleteness in new solver
We shouldn't need subst-relate if we have bidirectional-normalizes-to in the new solver.
The only potential issue may happen if we have an unconstrained projection like `<Wrapper<?0> as Trait>::Assoc == <Wrapper<T> as Trait>::Assoc` where they both normalize to something that doesn't mention any substs, which would possibly prefer `?0 = T` if we fall back to subst-relate. But I'd prefer if we remove incompleteness until we can determine some case where we need them, and the bidirectional-normalizes-to seems better to have in general.
I can update https://github.com/rust-lang/trait-system-refactor-initiative/issues/26 and https://github.com/rust-lang/trait-system-refactor-initiative/issues/25 once this lands.
r? `@lcnr`
Tweak spans for self arg, fix borrow suggestion for signature mismatch
1. Adjust a suggestion message that was annoying me
2. Fix#112503 by recording the right spans for the `self` part of the `&self` 0th argument
3. Remove the suggestion for adjusting a trait signature on type mismatch, bc that's gonna probably break all the other impls of the trait even if it fixes its one usage 😅
Rollup of 4 pull requests
Successful merges:
- #113887 (new solver: add a separate cache for coherence)
- #113910 (Add FnPtr ty to SMIR)
- #113913 (error/E0691: include alignment in error message)
- #113914 (rustc_target: drop duplicate code)
r? `@ghost`
`@rustbot` modify labels: rollup
THis significantly complicates `NaiveLayout` logic, but is necessary to
ensure that bounds like `NonNull<T>: PointerLike` hold in generic
contexts.
Also implement exact layout computation for structs.
Refactor vtable encoding and optimize it for the case of multiple marker traits
This PR does two things
- Refactor `prepare_vtable_segments` (this was motivated by the other change, `prepare_vtable_segments` was quite hard to understand and while trying to edit it I've refactored it)
- Mostly remove `loop`s labeled `break`s/`continue`s whenever there is a simpler solution
- Also use `?`
- Make vtable format a bit more efficient wrt to marker traits
- See the tests for an example
Fixes https://github.com/rust-lang/rust/issues/113840
cc `@crlf0710`
----
Review wise it's probably best to review each commit individually, as then it's more clear why the refactoring is correct.
I can split the last two commits (which change behavior) into a separate PR if it makes reviewing easier
Reasoning: if the stack is empty, the loop will be infinite,
so the assumption is that the stack can't be non empty. Unwrap
makes the assumption more clear (and removes an indentation level)
allow opaques to be defined by trait queries, again
This basically reverts #112963.
Moreover, all call-sites of `enter_canonical_trait_query` can now define opaque types, see the ui test `defined-by-user-annotation.rs`.
Fixes#113689
r? `@compiler-errors` `@oli-obk`
Add support for inherent projections in new solver
Not hard to support these, and it cuts out a really big chunk of failing UI tests with `--compare-mode=next-solver`
r? `@lcnr` (feel free to reassign, anyone can review this)
Don't call `predicate_must_hold`-esque functions during fulfillment in intercrate
Fixes#113415
Given that this only happens in `translate_substs`, I don't actually think that this is something that you can weaponize, but it's still sketchy regardless.
r? `@lcnr`
Structurally normalize in selection
We need to do this because of the fact that we're checking the `Ty::kind` on a type during selection, but goals passed into select are not necessarily normalized.
Right now, we're (kinda) unnecessarily normalizing the RHS of a trait upcasting goal, which is broken for different reasons (#113393). But I'm waiting for this PR to land before discussing that one.
r? `@lcnr`
Allow escaping bound vars during `normalize_erasing_regions` in new solver
Add `AllowEscapingBoundVars` to `deeply_normalize`, and use it in the new solver in the `query_normalize` routine.
Ideally, we'd make all `query_normalize` calls handle pass in `AllowEscapingBoundVars` individually, because really the only `query_normalize` call that needs `AllowEscapingBoundVars::Yes` is the one in `try_normalize_generic_arg_after_erasing_regions`, but I think that's kind of overkill. I am happy to be convinced otherwise, though.
r? `@lcnr`
Make it clearer that we're just checking for an RPITIT
Tiny nit to use `is_impl_trait_in_trait` more, to make it clearer that we're just checking whether a def-id is an RPITIT, rather than doing something meaningful with the `opt_rpitit_info`.
r? `@spastorino`
Implement selection for `Unsize` for better coercion behavior
In order for much of coercion to succeed, we need to be able to deal with partial ambiguity of `Unsize` traits during selection. However, I pessimistically implemented selection in the new trait solver to just bail out with ambiguity if it was a built-in impl:
9227ff28af/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs (L126)
This implements a proper "rematch" procedure for dealing with built-in `Unsize` goals, so that even if the goal is ambiguous, we are able to get nested obligations which are used in the coercion selection-like loop:
9227ff28af/compiler/rustc_hir_typeck/src/coercion.rs (L702)
Second commit just moves a `resolve_vars_if_possible` call to fix a bug where we weren't detecting a trait upcasting to occur.
r? ``@lcnr``
Structurally resolve in pattern matching when peeling refs in new solver
Let me know if you want me to commit the minimized test:
```rust
fn test() {}
fn test2() {}
fn main() {
let tests: &[(_, fn())] = &[
("test", test),
("test2", test2),
];
for (a, b) in tests {
todo!();
}
}
```
In that test above, the match scrutinee is `<std::vec::Iter<(&'static str, fn())> as Iterator>::Item`, which we cannot peel the refs from.
We also need to structurally resolve in the loop, since structural resolve is inherently shallow. I haven't come up with a test where this matters, but I can if you care.
Also, I removed two other calls to `resolve_vars_with_obligations` in diagnostics code that I'm pretty convinced are not useful.
r? `@lcnr`
Replace RPITIT current impl with new strategy that lowers as a GAT
This PR replaces the current implementation of RPITITs with the new implementation that we had under -Zlower-impl-trait-in-trait-to-assoc-ty flag that lowers the RPIT as a GAT on the trait and on the impls that implement that trait.
Opening this PR as a draft because this goes after #112682, ~#112981~ and ~#112983~.
As soon as those are merged, I can rebase and we should run perf, crater and test a lot.
r? `@compiler-errors`
Don't call `query_normalize` when reporting similar impls
Firstly, It's sketchy to be using `query_normalize` at all during HIR typeck -- it's asking for an ICE 😅. Secondly, we're normalizing an impl trait ref that potentially has parameter types in `ty::ParamEnv::empty()`, which is kinda sketchy as well.
The only UI test change from removing this normalization is that we don't evaluate anonymous constants in impls, which end up giving us really ugly suggestions:
```
error[E0277]: the trait bound `[X; 35]: Default` is not satisfied
--> /home/gh-compiler-errors/test.rs:4:5
|
4 | <[X; 35] as Default>::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `[X; 35]`
|
= help: the following other types implement trait `Default`:
&[T]
&mut [T]
[T; 32]
[T; core::::array::{impl#30}::{constant#0}]
[T; core::::array::{impl#31}::{constant#0}]
[T; core::::array::{impl#32}::{constant#0}]
[T; core::::array::{impl#33}::{constant#0}]
[T; core::::array::{impl#34}::{constant#0}]
and 27 others
```
So just fold the impls with a `BottomUpFolder` that calls `ty::Const::eval`. This doesn't work totally correctly with generic-const-exprs, but it's fine for stable code, and this is error reporting after all.
Reveal opaques in new solver
We were testing against the wrong reveal mode 😨
Also a couple of misc commits that I don't want to really put in separate prs
r? ``@lcnr``
Rollup of 8 pull requests
Successful merges:
- #113413 (Add needs-triage to all new issues)
- #113426 (Don't ICE in `resolve_bound_vars` when associated return-type bounds are in bad positions)
- #113427 (Remove `variances_of` on RPITIT GATs, remove its one use-case)
- #113441 (miri: check that assignments do not self-overlap)
- #113453 (Remove unused from_method from rustc_on_unimplemented)
- #113456 (Avoid calling report_forbidden_specialization for RPITITs)
- #113466 (Update cargo)
- #113467 (Fix comment of `fn_can_unwind`)
r? `@ghost`
`@rustbot` modify labels: rollup
Remove unused from_method from rustc_on_unimplemented
Fixes#113439
`on_unimplemented_note` was calling `item_name` for RPITITs and that produced ICEs. I've added a regression test for that but also have removed `from_method` symbol entirely because it wasn't even used and by doing that the `item_name` call was also removed.
r? ``@compiler-errors``
Split `SelectionContext::select` into fns that take a binder and don't
*most* usages of `SelectionContext::select` don't need to use a binder, but wrap them in a dummy because of the signature. Let's split this out into `SelectionContext::{select,poly_select}` and limit the usages of the latter.
Right now, we only have 3 places where we're calling `poly_select` -- fulfillment, internally within the old solver, and the auto-trait finder.
r? `@lcnr`
Prefer object candidates in new selection
`dyn Any` shouldn't be using [this implementation](https://doc.rust-lang.org/std/any/trait.Any.html#impl-Any-for-T) during codegen.
Prefer object candidates over other candidates, except for other object candidates.