Fix type restriction logic for generic module instances #10519
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Revival of #5132. Fixes #4287. Fixes #4684. Does not affect #9660.
The union above is essentially all including types of
Indexable(Int64)
in the standard librarydefined prior to thistypeof
. This is not ideal because if the other type implements the current type then we could simply returnIndexable(Int64)
here (see also #2404 (comment)), but this behaviour is consistent with non-generic module instances:The reason that previous PR fails seems to be that without the type restriction in
Crystal::GenericModuleInstanceType#restrict
it catches all AST node restrictions too, and leads to an infinite recursion insideGenericInstanceType#restrict(other : Generic, context)
. From my own experience it happened betweenComparable
andPointer
in the prelude:Comparable(Array(T))
v.s.Pointer(T)
(Array(Array(Crystal::DWARF::LineNumbers::Row)) | Array(Array(PrettyPrint::Group)) | ...)
v.s.Pointer(T)
Array(Array(Crystal::DWARF::LineNumbers::Row))
v.s.Pointer(T)
Comparable(Array(T))
v.s.Pointer(T)