mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:27:17 +00:00
[ddc] Avoid null check on forwarding field setters
Overriding fields can change the type to remove nullability and can also be final so they override the getters only. For DDC that means there is an inherited setter that could still be nullable and a forwarding setter that should allow null even though the type of the overriding field is non-nullable. With enhanced null safety asserts enabled in weak mode there should be no failure when setting the inherited field to null. Fixes: https://github.com/dart-lang/sdk/issues/50569 Change-Id: Ie6af0d1e265a5f3b15469311fa1f7e2a184d95ca Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/272480 Reviewed-by: Leaf Petersen <leafp@google.com> Commit-Queue: Nicholas Shahan <nshahan@google.com> Reviewed-by: Mark Zhou <markzipan@google.com>
This commit is contained in:
parent
a9c11acd25
commit
2cbed01634
|
@ -2259,7 +2259,9 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
|
|||
|
||||
var body = <js_ast.Statement>[];
|
||||
var value = _emitIdentifier('value');
|
||||
if (_requiresExtraNullCheck(field.setterType, field.annotations)) {
|
||||
// Avoid adding a null checks on forwarding field setters.
|
||||
if (field.hasSetter &&
|
||||
_requiresExtraNullCheck(field.setterType, field.annotations)) {
|
||||
body.add(
|
||||
_nullSafetyParameterCheck(value, field.location, field.name.text));
|
||||
}
|
||||
|
|
|
@ -159,6 +159,9 @@ main() {
|
|||
|
||||
// Same class as above defined in and inherited from null safe library throw.
|
||||
var nullSafeB = null_safe.B();
|
||||
// Should not throw because the inherited setter does allow null even though
|
||||
// the getter has an override and is non-nullable.
|
||||
nullSafeB.nullableField = null;
|
||||
Expect.throws(() {
|
||||
nullSafeB.getterSetterPair = null;
|
||||
}, asserted('i'));
|
||||
|
@ -193,6 +196,10 @@ main() {
|
|||
|
||||
// Same class as above defined in null safe library throws.
|
||||
var nullSafeD = null_safe.D();
|
||||
// Should not throw because the inherited setters do allow null even though
|
||||
// the getter has an override and is non-nullable.
|
||||
nullSafeD.nullableField = null;
|
||||
nullSafeD.nullableGetterSetterPair = null;
|
||||
Expect.throws(() {
|
||||
nullSafeD.field = null;
|
||||
}, asserted('field'));
|
||||
|
|
|
@ -28,7 +28,10 @@ class A {
|
|||
int get getterSetterPair => 0;
|
||||
set getterSetterPair(int i) => null;
|
||||
set setterOnly(String s) => null;
|
||||
int? get nullableGetterSetterPair => 0;
|
||||
set nullableGetterSetterPair(int? i) => null;
|
||||
int field = 0;
|
||||
int? nullableField = 0;
|
||||
static bool staticField = false;
|
||||
static int get staticGetterSetterPair => 0;
|
||||
static set staticGetterSetterPair(int i) => null;
|
||||
|
@ -44,6 +47,9 @@ class B extends A {
|
|||
int get getterSetterPair => 999;
|
||||
@override
|
||||
int get field => 999;
|
||||
// Getter override makes the type non-nullable.
|
||||
@override
|
||||
int get nullableField => 999;
|
||||
}
|
||||
|
||||
/// Overrides the setters.
|
||||
|
@ -60,4 +66,10 @@ class C extends A {
|
|||
class D extends A {
|
||||
@override
|
||||
int field = 10;
|
||||
// Field override is final (getter only) and makes type non-nullable.
|
||||
@override
|
||||
final int nullableField = 999;
|
||||
// Getter has override to be non-nullable but nullable setter is inherited.
|
||||
@override
|
||||
int get nullableGetterSetterPair => 999;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue