Skip to content

Commit 0263371

Browse files
alexmarkovCommit Queue
authored andcommitted
[cfe] Fix Field.isCovariantByClass for fields without implicit setters
TEST=pkg/vm/testcases/transformations/type_flow/transformer/regress_57084.dart Fixes #57084 Change-Id: Id2a411c3be22e60f8d1a24db0098f3d72369434c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/396300 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Alexander Markov <[email protected]>
1 parent eb81564 commit 0263371

File tree

10 files changed

+71
-10
lines changed

10 files changed

+71
-10
lines changed

pkg/front_end/lib/src/kernel/member_covariance.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class Covariance {
4141
if ((covariance & Covariant) != 0) {
4242
field.isCovariantByDeclaration = true;
4343
}
44-
if ((covariance & GenericCovariantImpl) != 0) {
44+
if (((covariance & GenericCovariantImpl) != 0) && field.hasSetter) {
4545
field.isCovariantByClass = true;
4646
}
4747
}

pkg/front_end/lib/src/source/source_field_builder.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,9 @@ class RegularFieldEncoding implements FieldEncoding {
814814

815815
@override
816816
void setGenericCovariantImpl() {
817-
_field.isCovariantByClass = true;
817+
if (_field.hasSetter) {
818+
_field.isCovariantByClass = true;
819+
}
818820
}
819821

820822
@override
@@ -1175,7 +1177,9 @@ abstract class AbstractLateFieldEncoding implements FieldEncoding {
11751177

11761178
@override
11771179
void setGenericCovariantImpl() {
1178-
_field.isCovariantByClass = true;
1180+
if (_field.hasSetter) {
1181+
_field.isCovariantByClass = true;
1182+
}
11791183
_lateSetter?.function.positionalParameters.single.isCovariantByClass = true;
11801184
}
11811185

pkg/front_end/testcases/nnbd/issue40600.dart.strong.expect

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class B<Y extends core::Object? = dynamic> extends core::Object {
1212
method bar(covariant-by-class FutureOr<self::B::Y%>y) → dynamic {}
1313
}
1414
class A<X extends core::Object? = dynamic> extends core::Object {
15-
covariant-by-class final field self::B<self::A::X%> b = new self::B::•<self::A::X%>();
15+
final field self::B<self::A::X%> b = new self::B::•<self::A::X%>();
1616
synthetic constructor •() → self::A<self::A::X%>
1717
: super core::Object::•()
1818
;

pkg/front_end/testcases/nnbd/issue40600.dart.strong.modular.expect

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class B<Y extends core::Object? = dynamic> extends core::Object {
1212
method bar(covariant-by-class FutureOr<self::B::Y%>y) → dynamic {}
1313
}
1414
class A<X extends core::Object? = dynamic> extends core::Object {
15-
covariant-by-class final field self::B<self::A::X%> b = new self::B::•<self::A::X%>();
15+
final field self::B<self::A::X%> b = new self::B::•<self::A::X%>();
1616
synthetic constructor •() → self::A<self::A::X%>
1717
: super core::Object::•()
1818
;

pkg/front_end/testcases/nnbd/issue40600.dart.strong.outline.expect

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class B<Y extends core::Object? = dynamic> extends core::Object {
1111
;
1212
}
1313
class A<X extends core::Object? = dynamic> extends core::Object {
14-
covariant-by-class final field self::B<self::A::X%> b;
14+
final field self::B<self::A::X%> b;
1515
synthetic constructor •() → self::A<self::A::X%>
1616
;
1717
method foo([covariant-by-class FutureOr<self::A::X%>? x = null]) → dynamic

pkg/front_end/testcases/nnbd/issue40600.dart.strong.transformed.expect

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class B<Y extends core::Object? = dynamic> extends core::Object {
1212
method bar(covariant-by-class FutureOr<self::B::Y%>y) → dynamic {}
1313
}
1414
class A<X extends core::Object? = dynamic> extends core::Object {
15-
covariant-by-class final field self::B<self::A::X%> b = new self::B::•<self::A::X%>();
15+
final field self::B<self::A::X%> b = new self::B::•<self::A::X%>();
1616
synthetic constructor •() → self::A<self::A::X%>
1717
: super core::Object::•()
1818
;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// Regression test for https://github.com/dart-lang/sdk/issues/57084.
6+
// Verifies that summmary collector is not called recursively
7+
// when recording a constant field which is incorrectly marked
8+
// as isCovariantByClass and needs type guard summary.
9+
10+
abstract class A<T> {
11+
T get field;
12+
void set field(T value);
13+
}
14+
15+
class C<T> implements A<T> {
16+
@override
17+
final T field;
18+
19+
const C(this.field);
20+
21+
@override
22+
set field(value) => throw '';
23+
}
24+
25+
const c = C<String>('');
26+
27+
void main() {
28+
print(c);
29+
() {
30+
print(c);
31+
}();
32+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
library #lib;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
abstract class A<T extends core::Object? = dynamic> extends core::Object {
6+
}
7+
class C<T extends core::Object? = dynamic> extends core::Object implements self::A<self::C::T%> /*hasConstConstructor*/ {
8+
9+
[@vm.inferred-type.metadata=dart.core::_OneByteString (value: "")]
10+
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]
11+
final field self::C::T% field;
12+
}
13+
14+
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
15+
[@vm.closure-id=1]
16+
static method main() → void {
17+
core::print(#C2);
18+
[@vm.direct-call.metadata=closure 1 in #lib::main] [@vm.inferred-type.metadata=!? (receiver not int)]([@vm.closure-id=1]() → Null {
19+
core::print(#C2);
20+
})(){() → Null};
21+
}
22+
constants {
23+
#C1 = ""
24+
#C2 = self::C<core::String> {field:#C1}
25+
}

pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter147239.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// for a field which has initializer with closure and captured receiver.
88

99
class Foo<T> {
10-
late final aField = () {
10+
late var aField = () {
1111
return <T>[];
1212
};
1313
}

pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter147239.dart.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import "dart:core" as core;
55
class Foo<T extends core::Object? = dynamic> extends core::Object {
66

77
[@vm.inferred-type.metadata=dart.core::_Closure (closure 1 in #lib::Foo.aField)]
8-
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]
8+
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]
99
[@vm.closure-id=1]
10-
late covariant-by-class final field () → core::List<self::Foo::T%> aField = [@vm.closure-id=1]() → core::List<self::Foo::T%> {
10+
late covariant-by-class field () → core::List<self::Foo::T%> aField = [@vm.closure-id=1]() → core::List<self::Foo::T%> {
1111
return [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::String>] core::_GrowableList::•<self::Foo::T%>(0);
1212
};
1313
synthetic constructor •() → self::Foo<self::Foo::T%>

0 commit comments

Comments
 (0)