4

Fall back to bidirectional normalizes-to if no subst-relate candidate in alias-r...

 1 year ago
source link: https://github.com/rust-lang/rust/pull/112076
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Conversation

Member

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


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK