Flutter/Dart breaking change proposal: super mixin declarations

737 views
Skip to first unread message

Leaf Petersen

unread,
Aug 13, 2018, 2:13:25 PM8/13/18
to Dart Misc
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).

Background.

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

Leaf Petersen

unread,
Aug 13, 2018, 3:14:48 PM8/13/18
to Dart Misc
Correction:

prints 
  MySuper
  Super

Should be

prints
  MySuper
  Sub

-leaf

tatumizer-v0.2

unread,
Aug 13, 2018, 4:51:52 PM8/13/18
to Dart Misc
There's an old thread containing the openings salvos of this discussion
https://groups.google.com/a/dartlang.org/d/msg/misc/RBV4wvG7DcU/CLsUqjevDAAJ

My question is: does this new proposal fixes the problem exactly in line with our earlier discussion?
That is, is it true that the definition
mixin Mixin on Super {
  void method() {
    super.method();
    print("Sub");
  }
}

should be read as: here's the definition of a class that can be applied as mixin to any class that implements Super?



Lasse R.H. Nielsen

unread,
Aug 14, 2018, 1:30:59 AM8/14/18
to mi...@dartlang.org
Yes, basically. It requires Super to declare a `method` member compatbile with the super-invocations, and it can be applied to classes implementing Super that have a concrete implementation of `Super.method`, and where the result of the mixin application is a valid and sound class.

/L
--
Lasse R.H. Nielsen - l...@google.com  
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K - Denmark - CVR nr. 28 86 69 84
Reply all
Reply to author
Forward
0 new messages