Add `-Ztrait-solver=next-coherence`
Flag that conditionally uses the trait solver *only* during coherence, for more testing and/or eventual partial-migration onto the trait solver (in the medium- to long-term).
* This still uses the selection context in some of the coherence methods I think, so it's not "complete". Putting this up for review and/or for further work in-tree.
* I probably need to spend a bit more time making sure that we don't sneakily create any other infcx's during coherence that also need the new solver enabled.
r? `@lcnr`
Fall back to bidirectional normalizes-to if no subst-relate candidate in alias-relate goal
Sometimes we get into the case where the choice of normalizes-to branch in alias-relate are both valid, but we cannot make a choice of which one to take because they are different -- either returning equivalent but permuted region constraints, or equivalent opaque type definitions but differing modulo normalization.
In this case, we can make progress by considering a fourth candidate where we compute both normalizes-to branches together and canonicalize that as a response. This is essentially the AND intersection of both normalizes-to branches. In an ideal world, we'd be returning something more like the OR intersection of both branches, but we have no way of representing that either for regions (maybe eventually) or opaques (don't see that happening ever).
This is incomplete, so like the subst-relate fallback it's only considered outside of coherence. But it doesn't seem like a dramatic strengthening of inference or anything, and is useful for helping opaque type inference succeed when the hidden type is a projection.
## Example
Consider the goal - `AliasRelate(Tait, <[i32; 32] as IntoIterator>::IntoIter)`.
We have three ways of currently solving this goal:
1. SubstRelate - fails because we can't directly equate the substs of different alias kinds.
2. NormalizesToRhs - `Tait normalizes-to <[i32; 32] as IntoIterator>::IntoIter`
* Ends up infering opaque definition - `Tait := <[i32; 32] as IntoIterator>::IntoIter`
3. NormalizesToLhs - `<[i32; 32] as IntoIterator>::IntoIter normalizes-to Tait`
* Find impl candidate, substitute the associated type - `std::array::IntoIter<i32, 32>`
* Equate `std::array::IntoIter<i32, 32>` and `Tait`
* Ends up infering opaque definition - `Tait := std::array::IntoIter<i32, 32>`
The problem here is that 2 and 3 are essentially both valid, since we have aliases that normalize on both sides, but due to lazy norm, they end up inferring different opaque type definitions that are only equal *after* normalizing them further.
---
r? `@lcnr`
Merge method, type and const object safety checks
cc `@spastorino` and `@compiler-errors` on the first commit. I believe it to be correct, as the field is only `Some` for assoc types, so just checking the field without checking the assoc kind to be `Type` is fine.
The second commit avoids going through all associated items thrice and just goes over all of them once, running the object safety checks per assoc item kind.
Normalize in infcx instead of globally for `Option::as_deref` suggestion
fixes#112293
The projection may contain inference variables. These inference variables are local to the local inference context. Using `tcx.normalize_erasing_regions` doesn't work here because this method is global and does not have access to the inference context. It's therefore unable to deal with the inference variables. We normalize in the local inference context instead, which knowns about the inference variables.
The test looks a little different than the issue example, I made it more minimal and verified that it still ICEs on nightly.
Also contains a drive-by fix to properly compare the types.
r? `@compiler-errors`
The projection may contain inference variables. These inference
variables are local to the local inference context. Using
`tcx.normalize_erasing_regions` doesn't work here because this method is
global and does not have access to the inference context. It's therefore
unable to deal with the inference variables. We normalize in the local
inference context instead, which knowns about the inference variables.
suggest `Option::as_deref(_mut)` on type mismatch in option combinator if it passes typeck
Fixes#106342.
This adds a suggestion to call `.as_deref()` (or `.as_deref_mut()` resp.) if typeck fails due to a type mismatch in the function passed to an `Option` combinator such as `.map()` or `.and_then()`.
For example:
```rs
fn foo(_: &str) {}
Some(String::new()).map(foo);
```
The `.map()` method requires its argument to satisfy `F: FnOnce(String)`, but it received `fn(&str)`, which won't pass. However, placing a `.as_deref()` before the `.map()` call fixes this since `&str == &<String as Deref>::Target`
refactor and cleanup the leak check, add it to new solver
ended up being a bit more involved than I wanted but is hopefully still easy enough to review as a single PR, can split it into separate ones otherwise.
this can be reviewed commit by commit:
a473d55cdb9284aa2b01282d1b529a2a4d26547b 31a686646534ca006d906ec757ece4e771d6f973 949039c107852a5e36361c08b62821a0613656f5 242917bf5170d9a723c6c8e23e9d9d0c2fa8dc9d ed2b25a7aa28be3184be9e3022c2796a30eaad87 are all pretty straightforward.
03dd83b4c3f4ff27558f5c8ab859bd9f83db1d04 makes it easier to refactor coherence in a later commit, see the commit description, cc `@oli-obk`
4fe311d807a77b6270f384e41689bf5d58f46aec I don't quite remember what we wanted to test here, this definitely doesn't test that the occurs check doesn't cause incorrect errors in coherence, also cc `@oli-obk` here. I may end up writing a new test for this myself later.
5c200d88a91b75bd0875b973150655bd581ef97a is the main refactor of the leak check, changing it to take the `outer_universe` instead of getting it from a snapshot. Using a snapshot requires us to be in a probe which we aren't in the new solver, it also just feels dirty as snapshots don't really have anything to do with universes.
with all of this cfc230d54188d9c7ed867a9a0d1f51be77b485f9 is now kind of trivial.
r? `@nikomatsakis`
`EarlyBinder::new` -> `EarlyBinder::bind`
for consistency with `Binder::bind`. it may make sense to also add `EarlyBinder::dummy` in places where we know that no parameters exist, but I left that out of this PR.
r? `@jackh726` `@kylematsuda`
Each of `{D,Subd}iagnosticMessage::{Str,Eager}` has a comment:
```
// FIXME(davidtwco): can a `Cow<'static, str>` be used here?
```
This commit answers that question in the affirmative. It's not the most
compelling change ever, but it might be worth merging.
This requires changing the `impl<'a> From<&'a str>` impls to `impl
From<&'static str>`, which involves a bunch of knock-on changes that
require/result in call sites being a little more precise about exactly
what kind of string they use to create errors, and not just `&str`. This
will result in fewer unnecessary allocations, though this will not have
any notable perf effects given that these are error paths.
Note that I was lazy within Clippy, using `to_string` in a few places to
preserve the existing string imprecision. I could have used `impl
Into<{D,Subd}iagnosticMessage>` in various places as is done in the
compiler, but that would have required changes to *many* call sites
(mostly changing `&format("...")` to `format!("...")`) which didn't seem
worthwhile.