Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Break cycle in computeAsSeenFrom when type-checking mutually referencing abstract type members #20236

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

pweisenburger
Copy link
Contributor

@pweisenburger pweisenburger commented Apr 19, 2024

Quite some time ago I reported a typing issue involving subtyping with type members whose definitions refer to each other (#4560).

I ran into this issue again recently and would like code like this to compile.

In the current compiler versions, both examples from the issue (#4560 (comment), #4560 (comment)) still result in a "recursion limit exceeded" error due to the compiler running into a cycle.

I found that the cycle manifests in computeAsSeenFrom being called again on the same SingleDenotation object with the exact same argument pre at some point in the nested info.asSeenFrom call.

I don't know the internals of the compiler well enough to judge whether this is the best approach, but what this pull request does is detecting such nested calls to computeAsSeenFrom by storing the argument of the previous call until the function returns and, if a nested call is detected, breaking the cycle by immediately returning a preliminary result. This result is then updated by the outer computeAsSeenFrom call to its correct info. I think, the only interesting case is if the SingleDenotation refers to an abstract type member.

This PR fixes #4560, fixes #13937, fixes #19618, and fixes #20243.

@sjrd
Copy link
Member

sjrd commented Apr 19, 2024

asSeenFrom is a specified function. In order to make more powerful you need to update the spec. ;)

@pweisenburger
Copy link
Contributor Author

Thanks for the info! I wasn't aware that this method has a spec. There are two things that are unclear to me:

First, the computeAsSeenFrom I adapted does call asSeenFrom through info.asSeenFrom. It seems to me TypeOps.asSeenFrom (with arguments T, C, and p) is spec'd. I find it hard to identify the SingleDenotation.computeAsSeenFrom (with argument p) in the spec. Is this method part of the spec or simply a caller of the spec'd method?

Second, as far as I can see, the conditions given in the spec (like "If T is a reference to the ith class type parameter of some class D and baseType(p, D) = r.D[W1, ..., Wm] is defined, then asSeenFrom(T, C, p) = Wi" and the following) still hold. I would be happy for any hint which part of the spec is violated?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants