Ceylon backend error: method invoked with incorrect number of arguments
This function:
{<Annot->ProgramElement>*} annotatedMembers<Annot, ProgramElement>(
Class<OptionalAnnotation<Annot, ProgramElement>> annotType,
Package pkg)
given Annot satisfies OptionalAnnotation<Annot, ProgramElement>
given ProgramElement satisfies NestableDeclaration {
variable {<Annot->ProgramElement>*} results = {};
for (element in pkg.annotatedMembers<ProgramElement,Annot>()) {
assert(exists annotation = optionalAnnotation(annotType, element));
results = results.follow(annotation->element);
}
return results;
}
And this annotation
final sealed annotation class SomeAnnotation()
satisfies OptionalAnnotation<SomeAnnotation,FunctionDeclaration> {
}
Generates a backend error:
shared void backendError() {
annotatedMembers(`SomeAnnotation`, `package`); //Ceylon backend error: method invoked with incorrect number of arguments; expected 4, found 0
annotatedMembers(`SharedAnnotation`, `package`); //Compiles
}
Thanks for reporting.
I can also reproduce this problem with VariableAnnotation.
The difference between VariableAnnotation and SharedAnnotation is that SharedAnnotation has a union-typed argument to the type parameter ProgramElement of OptionalAnnotation.
Alright, so the issue here is rooted in the fact that ProgramElement is (correctly, it seems to me, according to the rules, given that it occurs only contravariantly in the parameter list) assigned the inferred type Nothing.
This Nothing results in some sort of very complex interaction between type constraints that I still don't fully grok, and triggers the bug. But actually Nothing wasn't a useful type argument to begin with.
Supplying an explicit type argument fixes the code from a logical point of view, and avoids the bug:
annotatedMembers<SomeAnnotation,FunctionDeclaration>(`SomeAnnotation`, `package`);
I can also fix the code by introducing an intervening interface which redeclares ProgramElement as an invariant type parameter:
interface MyOptionalAnnotation<Annot, ProgramElement>
of Annot
satisfies OptionalAnnotation<Annot,ProgramElement>
given Annot satisfies MyOptionalAnnotation<Annot,ProgramElement>
given ProgramElement satisfies Annotated {}
{<Annot->ProgramElement>*} annotatedMembers<Annot,ProgramElement>(
Class<MyOptionalAnnotation<Annot,ProgramElement>> annotType,
Package pkg)
given Annot satisfies OptionalAnnotation<Annot, ProgramElement>
given ProgramElement satisfies NestableDeclaration {
variable {<Annot->ProgramElement>*} results = {};
for (element in pkg.annotatedMembers<ProgramElement,Annot>()) {
assert(exists annotation = optionalAnnotation(annotType, element));
results = results.follow(annotation->element);
}
return results;
}
final sealed annotation class SomeAnnotation()
satisfies MyOptionalAnnotation<SomeAnnotation,FunctionDeclaration> {
}