'Leaf Petersen' via Dart Misc
2018-10-24 21:19:07 UTC
*TL;DR: Dart 2.1 will include a number of small bug fixes to places where
the tools accepted non spec-compliant code. These fixes have landed in
development versions of Dart and in the Flutter master branch, and we have
fixed any breakage that we have seen, but it is possible that apps or
packages that have not been tested on recent development versions could
break with the next stable release of Dart (2.1) or Flutter. See below for
a summary of the changes, or see this rollup issue
<https://github.com/dart-lang/sdk/issues/34611>. Please reach out here or
in the issue tracker if you need help resolving breakage caused by these
fixes. *
*Setters with the same name as the enclosing class aren't allowed.*
It is not allowed to have a class member with the same name as the
enclosing class:
class A {
set A(int x) {}
}
Dart 2.0 tools incorrectly allowed this for setters (only). Dart 2.1 tools
will reject this code.
Issue link: #34225 <https://github.com/dart-lang/sdk/issues/34225>
*To fix:* This is unlikely to break anything, since it violates all style
guides anyway.
*Constant constructors cannot redirect to non-constant constructors.*
It is not allowed to have a constant constructor that redirects to a
non-constant constructor:
class A {
const A.foo() : this(); // Redirecting to A()
A() {}
}
Dart 2.0 tools incorrectly allowed this. Dart 2.1 tools will reject this
code.
Issue link: #34161 <https://github.com/dart-lang/sdk/issues/34161>
*To fix:* Make the target of the redirection a properly const constructor.
*Abstract methods may not unsoundly override a concrete method.*
Concrete methods must be valid implementations of their interfaces:
class A {
num get thing => 2.0;
}
abstract class B implements A {
int get thing;
}
class C extends A with B {} // 'thing' from 'A' is not a valid override of 'thing' from 'B'.
main() {
print(new C().thing.isEven); // Expects an int but gets a double.
}
Dart 2.0 tools would in some cases allow unsound overrides like the above.
Dart 2.1 tools will reject this code.
Issue link: #32014 <https://github.com/dart-lang/sdk/issues/32014>
*To fix: * Relax the type of the invalid override, or tighten the type of
the overridden method.
*Classes can't implement FutureOr.*
Dart doesn't allow classes to implement the FutureOr type:
class A implements FutureOr<Object> {}
Dart 2.0 tools allowed classes to implement FutureOr. Dart 2.1 tools will
reject this code.
Issue link: #33744 <https://github.com/dart-lang/sdk/issues/33744>
*To fix: *Don't do this.
*Type arguments to generic typedefs must satisfy their bounds.*
If a parameterized typedef specifies a bound, actual arguments must be
checked against it:
class A<X extends int> {}
typedef F<Y extends int> = A<Y> Function();
F<num> f = null;
Dart 2.0 tools would allow bounds violations like F<num> above. Dart 2.1
tools will reject this.
Issue link: #33308 <https://github.com/dart-lang/sdk/issues/33308>
*To fix:* Either remove the bound on the typedef parameter, or pass a valid
argument to the typedef.
*Constructor invocations must use valid syntax, even with optional new.*
Type arguments to generic named constructors go after the class name, not
the constructor name, even when used without an explicit *new*:
class A<T> {
A.foo() {}
}
main() {
A.foo<String>(); // Incorrect syntax, was accepted in 2.0
A<String>.foo(); // Correct syntax
}
Dart 2.0 tools accepted the incorrect syntax when the *new* keyword was
left out. Dart 2.1 tools will correctly reject this code.
Issue link: #34403 <https://github.com/dart-lang/sdk/issues/34403>
*To fix: *Move the type argument to the correct position after the class
name.
*Instance members should shadow prefixes.*
If the same name is used as an import prefix and as a class member name,
then the class member name takes precedence in the class scope.
import 'dart:core';import 'dart:core' as core;
class A {
core.List get core => null; // core refers to the field, not the prefix
}
Dart 2.0 tools incorrectly resolved the use of core in core.List to the
prefix name. Dart 2.1 tools will correctly resolve this to the field name.
Issue link: #34498 <https://github.com/dart-lang/sdk/issues/34498>
*To fix:* Change the prefix name to something which does not clash with the
instance member.
*Implicit type arguments in extends clauses must satisfy the class bounds.*
Implicit type arguments for generic classes are computed if not are passed
explicitly, but when used in extends clause they must be checked for
validity:
class Foo<T> {}
class Bar<T extends Foo<T>> {}
class Baz extends Bar {} // Should be error here, because Bar completes to Bar<Foo>
Dart 2.0 tools would accept the broken code above. Dart 2.1 tools will
reject this code.
Issue link: #34532 <https://github.com/dart-lang/sdk/issues/34532>
*To fix:* Provide explicit type arguments to the superclass that satisfy
the bound for the superclass.
*Mixins must correctly override their superclasses.*
In some rare cases, combinations of uses of mixins could result in invalid
overrides not being caught:
class A {
num get thing => 2.0;
}
class M1 {
int get thing => 2;
}
class B = A with M1;
class M2 {
num get thing => 2.0;
}
class C extends B with M2 {} // 'thing' from 'M2' not a valid override.
main() {
M1 a = new C();
print(a.thing.isEven); // Expects an int but gets a double.
}
Dart 2.0 tools accepted the above example. Dart 2.1 tools will reject this
code.
Issue link: #34235 <https://github.com/dart-lang/sdk/issues/34235>
*To fix:* Ensure that overriding methods are correct overrides of their
superclasses, either by relaxing the superclass type, or tightening the
subclass/mixin type.
The Dart Team regrets the errors.
thanks,
-leaf
the tools accepted non spec-compliant code. These fixes have landed in
development versions of Dart and in the Flutter master branch, and we have
fixed any breakage that we have seen, but it is possible that apps or
packages that have not been tested on recent development versions could
break with the next stable release of Dart (2.1) or Flutter. See below for
a summary of the changes, or see this rollup issue
<https://github.com/dart-lang/sdk/issues/34611>. Please reach out here or
in the issue tracker if you need help resolving breakage caused by these
fixes. *
*Setters with the same name as the enclosing class aren't allowed.*
It is not allowed to have a class member with the same name as the
enclosing class:
class A {
set A(int x) {}
}
Dart 2.0 tools incorrectly allowed this for setters (only). Dart 2.1 tools
will reject this code.
Issue link: #34225 <https://github.com/dart-lang/sdk/issues/34225>
*To fix:* This is unlikely to break anything, since it violates all style
guides anyway.
*Constant constructors cannot redirect to non-constant constructors.*
It is not allowed to have a constant constructor that redirects to a
non-constant constructor:
class A {
const A.foo() : this(); // Redirecting to A()
A() {}
}
Dart 2.0 tools incorrectly allowed this. Dart 2.1 tools will reject this
code.
Issue link: #34161 <https://github.com/dart-lang/sdk/issues/34161>
*To fix:* Make the target of the redirection a properly const constructor.
*Abstract methods may not unsoundly override a concrete method.*
Concrete methods must be valid implementations of their interfaces:
class A {
num get thing => 2.0;
}
abstract class B implements A {
int get thing;
}
class C extends A with B {} // 'thing' from 'A' is not a valid override of 'thing' from 'B'.
main() {
print(new C().thing.isEven); // Expects an int but gets a double.
}
Dart 2.0 tools would in some cases allow unsound overrides like the above.
Dart 2.1 tools will reject this code.
Issue link: #32014 <https://github.com/dart-lang/sdk/issues/32014>
*To fix: * Relax the type of the invalid override, or tighten the type of
the overridden method.
*Classes can't implement FutureOr.*
Dart doesn't allow classes to implement the FutureOr type:
class A implements FutureOr<Object> {}
Dart 2.0 tools allowed classes to implement FutureOr. Dart 2.1 tools will
reject this code.
Issue link: #33744 <https://github.com/dart-lang/sdk/issues/33744>
*To fix: *Don't do this.
*Type arguments to generic typedefs must satisfy their bounds.*
If a parameterized typedef specifies a bound, actual arguments must be
checked against it:
class A<X extends int> {}
typedef F<Y extends int> = A<Y> Function();
F<num> f = null;
Dart 2.0 tools would allow bounds violations like F<num> above. Dart 2.1
tools will reject this.
Issue link: #33308 <https://github.com/dart-lang/sdk/issues/33308>
*To fix:* Either remove the bound on the typedef parameter, or pass a valid
argument to the typedef.
*Constructor invocations must use valid syntax, even with optional new.*
Type arguments to generic named constructors go after the class name, not
the constructor name, even when used without an explicit *new*:
class A<T> {
A.foo() {}
}
main() {
A.foo<String>(); // Incorrect syntax, was accepted in 2.0
A<String>.foo(); // Correct syntax
}
Dart 2.0 tools accepted the incorrect syntax when the *new* keyword was
left out. Dart 2.1 tools will correctly reject this code.
Issue link: #34403 <https://github.com/dart-lang/sdk/issues/34403>
*To fix: *Move the type argument to the correct position after the class
name.
*Instance members should shadow prefixes.*
If the same name is used as an import prefix and as a class member name,
then the class member name takes precedence in the class scope.
import 'dart:core';import 'dart:core' as core;
class A {
core.List get core => null; // core refers to the field, not the prefix
}
Dart 2.0 tools incorrectly resolved the use of core in core.List to the
prefix name. Dart 2.1 tools will correctly resolve this to the field name.
Issue link: #34498 <https://github.com/dart-lang/sdk/issues/34498>
*To fix:* Change the prefix name to something which does not clash with the
instance member.
*Implicit type arguments in extends clauses must satisfy the class bounds.*
Implicit type arguments for generic classes are computed if not are passed
explicitly, but when used in extends clause they must be checked for
validity:
class Foo<T> {}
class Bar<T extends Foo<T>> {}
class Baz extends Bar {} // Should be error here, because Bar completes to Bar<Foo>
Dart 2.0 tools would accept the broken code above. Dart 2.1 tools will
reject this code.
Issue link: #34532 <https://github.com/dart-lang/sdk/issues/34532>
*To fix:* Provide explicit type arguments to the superclass that satisfy
the bound for the superclass.
*Mixins must correctly override their superclasses.*
In some rare cases, combinations of uses of mixins could result in invalid
overrides not being caught:
class A {
num get thing => 2.0;
}
class M1 {
int get thing => 2;
}
class B = A with M1;
class M2 {
num get thing => 2.0;
}
class C extends B with M2 {} // 'thing' from 'M2' not a valid override.
main() {
M1 a = new C();
print(a.thing.isEven); // Expects an int but gets a double.
}
Dart 2.0 tools accepted the above example. Dart 2.1 tools will reject this
code.
Issue link: #34235 <https://github.com/dart-lang/sdk/issues/34235>
*To fix:* Ensure that overriding methods are correct overrides of their
superclasses, either by relaxing the superclass type, or tightening the
subclass/mixin type.
The Dart Team regrets the errors.
thanks,
-leaf
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/a420d31a-b043-439f-8751-4a8bf9186a51%40dartlang.org.
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/a420d31a-b043-439f-8751-4a8bf9186a51%40dartlang.org.