TLDR: The flutter framework uses an early experimental extension of Dart mixins which allow calls to super. In Dart 2.1, we propose to make this feature a supported part of the language on all platforms with new syntax. If you have flutter code that defines a mixin which makes super calls or inherits from something other than Object, this change will break you. We are soliciting early feedback and examples of code that will break with this change (our own investigation has found very few examples outside of the Flutter framework).
Dart mixins as implemented and supported across all platforms do not allow a class which inherits from anything other than Object, or which has a reference to super, to be used as a mixin. However, experimental (and deprecated) support for allowing super calls within mixins is present in the Dart VM and the Dart analyzer (hidden behind a flag). This code:
abstract class Super {
void method() {
print("Super");
}
}
abstract class Mixin extends Super {
void method() {
super.method();
print("Sub");
}
}
class MySuper implements Super {
void method() {
print("MySuper");
}
}
class Client extends MySuper with Mixin {
}
void main() {
Client().method();
}
prints
MySuper
Super
when run on the Dart VM (and hence with the flutter engine), but will crash if run with dart2js. The Dart analyzer will emit static errors on this code unless the enableSuperMixins option is set.
We propose to provide official support for this feature across all of the platforms for the Dart 2.1 release. However, in order to make this feature friendlier to static analysis and ahead of time compilation (and in order to better support uses cases identified in the flutter framework), we are proposing to change the way that these kind of mixins are defined to use a separate syntax from classes. Under this proposal, all of the code above would remain the same, except the definition of Mixin, which would look as follows:
mixin Mixin on Super {
void method() {
super.method();
print("Sub");
}
}
Note that the syntax for using the mixin remains unchanged, and hence existing uses of super mixins should still be syntactically valid.
More details on the proposal are
here.
What will break?
If your code defines a super mixin class (that is, a class which has a superclass other than Object, or which has a reference to super), and this class is used as a mixin, then your code would break under this proposal, and you would have to change your code to use the explicit mixin syntax as described above.
If your code extends a super mixin class, then your code will have to change from extends Mixin to with Mixin .
If your code instantiates a super mixin class directly (most existing super mixin classes prevent this), then you will have to change your code to instantiate an application of the mixin instead.
If your code uses a super mixin class correctly, no changes should be required.
We expect that all of these cases will be exceptionally rare. As discussed
here, we have analyzed the most popular flutter packages as well as all Google Dart code, and found only a handful of places where changes will be required. We have found very few packages outside of flutter that define super mixins, and essentially none that extend one.
We don't yet have the tooling to check for invalid uses of super mixin classes, but most code that works and passes the existing static analysis should continue to work. For code that runs correctly on the VM, the principle missing check is the verification that the actual superclass nominally satisfies the requirement of the mixin. So this code:
abstract class Super {}
abstract class Mixin extends Super {}
class Client extends Object with Mixin {}will break with this change, since Mixin claims to require something nominally satisfying the Super interface, but is used as a mixin with a superclass which does not.
I think this might break me, what should I do?
If you believe that you have code which will be broken by this please follow up here, on
this issue, or via email with me directly.
If you are worried that you might be broken (but are not sure) and would like me to analyze your code for forward compatibility, please reach out to me with instructions for obtaining your code (preferably as a github repo).
I want to give feedback about this feature, what should I do?
Comments welcome
here, or open a
new issue for specific comments or concerns with the
proposal.
What should I expect going forward?
We will continue to gather data on potential breakage and work to mitigate as necessary. I will follow up here when the implementation of the new mixin syntax is available in the flutter tooling. Once the new syntax is supported and we are confident that any required migration is complete, we will remove support for the deprecated experimental version.
thanks,
-leaf