Compiler: fix abstract def check regarding generic ancestor lookup #8098
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.
Fixes #8096
Thank you @exilor ! Thanks to your bug report I was able to understand why other (rare) cases were failing too.
The code is this:
And the compiler will check that
ICallable(T)#call
is implemented by all concrete subtype. One such subtype isCaller:Module
(where class methods live). Does it provide acall
method? No. Then the compiler goes and check whether any ancestor ofCaller:Module
provides it. Because it extendsself
it checks whetherCaller
(where instance methods live) provides it. And it does! But we must check whether that matches the method in the generic type. For that the compiler will try to find the generic instantiation of that module. That is, because we are checking a subtype ofICallable(T)
then at some point there must have been someinclude ICallable(X)
in the chain, to know what typeX
is. The problem was that the compiler would start the search from the current ancestor, in this caseCaller
, and not from the main type we were checking in the first place (Caller:Module
).It's a bit confusing. That's why I also added a similar spec which is a bit simpler:
Here the compiler again will check whether
Caller:Module
implementscall
. It will find thatMoo
has it and then it will try to find theinclude/extend ICallable
, but it won't find starting fromMoo
, it will find it starting fromCaller:Module
. Well, at least in this case, in other cases it might happen thatMoo
is the one that is including the other module.