You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
classP(Protocol[T_co]):
defmeth(self) ->P[T_co]: ...
classC(Generic[T]):
defmeth(self) ->C[T]: ...
deffun(arg: P[T]) ->T: ...
x: C[int]
reveal_type(f(x)) # I think this should be 'int'
But currently the inferred type is UninhabitedType, since we don't find any constraints for T due to a purely structural inference cycle. Unfortunately, it looks like this doesn't have simple solutions.
Here is a possible idea how this can be implemented (semi-heuristically):
We would record a pair of Instances that we tried to match instead of just the template's TypeInfo like now.
Then if we hit the same pair (using is_same_type), instead of just "backtracking" (like now, we simple say no luck here, try another options) we can try "forceful unpacking". For example if we started from C[int] <: P[T] we continue with int <: T (which is a leaf in this simple case).
Ideally this should be done with something like map_instance_to_supertype, but the essence of the problem is that there is no such thing for structural subtypes, however it seems to me the fact that we recursed to the same pair of Instances already tells that the types can be "mapped".
Obviously we should do this only if the instance matches the protocol with typevars erased. Also we should probably do some variance checks to avoid problems.
I don't have a proof but we can call this heuristics :-)
We need to think is there a possibility for any "fake" constraints because of this.
Consider this example:
But currently the inferred type is
UninhabitedType
, since we don't find any constraints forT
due to a purely structural inference cycle. Unfortunately, it looks like this doesn't have simple solutions.This is a follow-up for #3132
The text was updated successfully, but these errors were encountered: