-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Fasta: Missing override checks for mixins #34235
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
Comments
That program should have a compile-time error, so it's the "Undefined" case that applies, for exactly the reason stated. With the new Also, based on the specification of mixin composition (current spec, 12.2 Mixin Composition), application of a mixin to a superclass is 'equivalent to' a particular ordinary class declaration, which would also ensure that this is a compile-time error because of an override that does not satisfy the associated constraints. [Edit: PS: It may be helpful to consider the sequence of mixins: |
Yeah, it's an error that should be signaled by the front end. |
Stray thought: I thought that the common front end would eliminate mixins by rewriting them (pretty much like section 12.2 says) into regular class declarations, so why doesn't that override relation get checked just like all other override relations? |
We don't eliminate mixins that way because it's a whole-program transformation and hostile to separate compilation. (It's ML defunctorization.) What we do do is we name all the mixin application classes, so the output of Fasta doesn't have anonymous mixin applications. We could check the mixin application classes for invalid overrides, but we don't and that's why I say it's a bug in Fasta. |
By looking at the implementation of bool checkMethodOverride(
ClassHierarchy hierarchy,
TypeEnvironment typeEnvironment,
Procedure declaredMember,
Procedure interfaceMember) {
if (declaredMember.enclosingClass != cls) {
// TODO(ahe): Include these checks as well, but the message needs to
// explain that [declaredMember] is inherited.
return false;
}
(the remainder is omitted)
} I suppose the "these checks" refer to the subsequent ~140 lines of code. Indeed I have confirmed that by removing the conditional statement fasta detects the error (the program
|
Change-Id: I7e5d2e63bfd018d21ff9587f178440da39a5078d Reviewed-on: https://dart-review.googlesource.com/71232 Reviewed-by: Konstantin Shcheglov <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Paul Berry <[email protected]>
I've uploaded a CL adding a variant of my example code as a test case to |
Change-Id: Icaf6329729a17b20a591ae6e9b8bf7c0d2e21265 Reviewed-on: https://dart-review.googlesource.com/71368 Reviewed-by: Konstantin Shcheglov <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]> Reviewed-by: Daniel Hillerström <[email protected]> Commit-Queue: Paul Berry <[email protected]>
The signature of the overridden method buildCompoundAssignment in KernelUnresolvedNameGenerator (c.f. kernel_expression_generator.dart) was illegal, because its (named parameter) arity was four, whilst the same method in one of its supertypes has arity five. Furthermore, there was a signature conflict for buildCompoundAssignment amongst the supertypes of KernelUnresolvedNameGenerator: KernelUnresolvedNameGenerator extends KernelGenerator | = Generator with KernelExpressionGenerator | arity(buildCompoundAssignment) = 5 with ErroneousExpressionGenerator, UnresolvedNameGenerator. | arity(buildCompoundAssignment) = 4 In this CL the conflict is resolved by the "greatest common denominator" approach, that is, now each implementation of buildCompoundAssignment has arity five. This CL is a necessary step towards fixing #34235 Related change: c95ef87 Change-Id: If1992b8fb2bb994f83557c48fb0ac276b2d1a8d3 Reviewed-on: https://dart-review.googlesource.com/71520 Reviewed-by: Kevin Millikin <[email protected]> Commit-Queue: Daniel Hillerström <[email protected]>
…ixin." This reverts commit 03c7184. Reason for revert: Flutter doesn't build with after this CL because the following (kind of) program abstract class RenderObject { String toString({int minLevel}) => "foo"; } abstract class ContainerRenderObjectMixin extends RenderObject {} abstract class RenderBoxContainerDefaultsMixin implements ContainerRenderObjectMixin {} is wrongfully rejected. In patching this, I stumbled upon what seems to be bug in Fasta where some concrete classes arising from mixed in applications are marked as abstract, which causes the patch to produce false-positives. This needs some more investigation. Original change's description: > Enables arity check for overridden methods inherited from a mixin. > > The return type and parameter types checks are still disabled for > mixins as there is an issue with type parameters being uninstantiated > in mixin applications which causes the two checks to produce > false-positives. As a result the SDK fails to compile with the two > checks enabled because the libraries (such as collections) makes > extensive use of mixin application with generic types. I've opened a > separate ticket to track this issue [c.f. #34285]. > > Furthermore this CL abstracts the arity check, return type check, and > method parameter type check in checkMethodOverride to make it easier > to understand the logic of the method. > > Closes #34235 and closes #32014 > > Change-Id: Iae224926c2e99e6e89ccc3c19ec4bc7919ee48a5 > Reviewed-on: https://dart-review.googlesource.com/71781 > Commit-Queue: Daniel Hillerström <[email protected]> > Reviewed-by: Aske Simon Christensen <[email protected]> [email protected],[email protected] Change-Id: Idee6f53c2d6a17ea8a4103872b1183c01e4d30ce No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://dart-review.googlesource.com/72108 Reviewed-by: Daniel Hillerström <[email protected]> Commit-Queue: Daniel Hillerström <[email protected]>
Consider the following program:
I'm not certain what the behavior of this program should be, but I think it should be either:
BaseWithM1 with M2
attempts to overridefoo({x})
withfoo()
, and overrides may not drop optional parameters.M2.foo called
.If I run this under the VM, it reports no errors and prints
M1.foo called, with x=null
. That seems definitely wrong. So even though I'm not certain what the correct behavior should be I'm filing this as a VM bug. Feel free to reclassify if I'm wrong about this.Note that this is a reduction of a situation arose in practice during development of the analyzer/front_end integration. The actual classes/methods involved were:
Base
->Generator
M1
->KernelExpressionGenerator
BaseWithM1
->KernelGenerator
M2
->ContextAwareGenerator
Derived
->KernelContextAwareGenerator
foo
->buildCompoundAssignment
I'll shortly upload a CL that modifies the parameters of
buildCompoundAssignment
to work around this issue.Cc @leafpetersen, @eernstg, and @lrhn to weigh in on what the correct behavior should be.
The text was updated successfully, but these errors were encountered: