Faster tool startup

Assert messages

num measureDistance(List waypoints) { if (waypoints.any((point) => point.isInaccessible)) { throw new ArgumentError('At least one waypoint is inaccessible.'); } // ... }

num measureDistance(List<Place> waypoints) { assert(waypoints.any((point) => point.isInaccessible), 'At least one waypoint is inaccessible.'); // ... }

measureDistance()

Covariant parameter override

class Widget { void addChild(Widget widget) {...} } class RadioButton extends Widget { void select() {...} } class RadioGroup extends Widget { void addChild(RadioButton button) { button.select(); super.addChild(button); } }

RadioGroup

Widget

RadioButton

RadioGroup.addChild()

RadioButton

Widget

Widget widget = new RadioGroup(); // Upcast to Widget. widget.addChild(new Widget()); // Add the wrong kind of child.

RadioGroup

Widget

RadioGroup

RadioButton

RadioGroup

class RadioGroup extends Widget { void addChild(Widget widget) { var button = widget as RadioButton; button.select(); super.addChild(button); } }

class Widget { void addChild(covariant Widget widget) {...} }

class RadioGroup extends Widget { void addChild(RadioButton button) { // ... } }

class Widget { covariant Widget child; }

class Widget { Widget _child; Widget get child => _child; set child(covariant Widget value) { _child = value; } }

The Null type is now a subtype of every other type

final empty = <Null>[]; String concatenate(List<String> parts) => parts.join(); int sum(List<int> numbers) => numbers.fold(0, (sum, n) => sum + n); concatenate(empty); // OK. sum(empty); // OK.

FutureOr<T>

Future<S> then<S>(onValue(T value), { Function onError });

Future<S> then<S>(FutureOr<S> onValue(T value), { Function onError });

Generalized tear-offs are going away

Use of Function as a class is now deprecated

// This is deprecated. class MyFunction extends Function { // … }

// This is okay. void myAwesomeMethod(Function callback) { // … }