-
Notifications
You must be signed in to change notification settings - Fork 1.6k
[ty] fix panic with direct recursive type alias #21434
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
Conversation
Diagnostic diff on typing conformance testsNo changes detected when running ty on typing conformance tests ✅ |
|
| reveal_type(y) # revealed: Never | ||
|
|
||
| # TODO emit a diagnostic on this line | ||
| type Itself = Itself |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this fix also work for compound types like list[Itself]?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those generally already work, without this PR: https://play.ty.dev/a65c2d75-e9c1-4a74-85e3-f96db2dd9c60
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another case that may be worth testing is multi-step direct recursion:
type A = B
type B = A
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, unfortunately, it seems the panic still persists in the case of mutually recursive aliases:
type A = B
type B = A
def bar(a: B):
x: aTherefore, the measure is insufficient, and we should check the consequences of eagerly expanding a type alias value type before we first use of it.
This may be an issue that needs to be resolved in #20566.
carljm
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
| def foo(Itself: Itself): | ||
| x: Itself |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO it's a bit odd to test that you can annotate a parameter as Itself, and then use that parameter again as an annotation. It may work due to how we treat Unknown in a type annotation, but I don't think this is something we want to commit to in a test.
I would probably just have done this instead:
| def foo(Itself: Itself): | |
| x: Itself | |
| def foo(x: Itself): | |
| reveal_type(x) # Unknown |
Is there a particular reason why you think it's important to test this "annotated value as annotation" behavior?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact, in that example, no panic occurs, and the revealed type is Never.
https://play.ty.dev/4732e30a-301c-4753-b95f-aed34cf08585
Should the original code be placed in the corpus as a regression test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I wondered if this part was necessary to reproduce the panic. That explains why I didn't catch this case in my previous work on recursive type aliases. Makes it much less likely people will run into this, but of course it should still be fixed.
I think it's OK for a test like this to be in mdtests, I would just expect some commentary (specifically about annotating with a value type) that "this is a very strange thing to do, but this is a regression test to ensure it doesn't panic"
Summary
I found that trying to use a directly recursive type alias like this would result in a stack overflow:
This should be reported as an invalid type alias, but a stack overflow should be fixed immediately anyway. We now consider the value type to be
Unknownin such cases.Test Plan
New test case in
mdtest\pep695_type_aliases.md