about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2023-06-07 18:01:28 +0530
committerGitHub <noreply@github.com>2023-06-07 18:01:28 +0530
commitcbe429c7a5fba9f77d76f214a45c03b67a1328c1 (patch)
tree63239b37325b12270d1045d99d729f24ab405dd4 /compiler/rustc_mir_transform/src
parente94bda3bf13303671427363d1cd93ac5e089f090 (diff)
parent3ea7c512bd1587006a1c196df841e9b7ec60fb0b (diff)
downloadrust-cbe429c7a5fba9f77d76f214a45c03b67a1328c1.tar.gz
rust-cbe429c7a5fba9f77d76f214a45c03b67a1328c1.zip
Rollup merge of #112076 - compiler-errors:bidirectional-alias-eq, 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`
Diffstat (limited to 'compiler/rustc_mir_transform/src')
0 files changed, 0 insertions, 0 deletions