[tfa] Fix bug in TFA transformation of unused fields
When a TFA eliminates a field it moves it's initializer to a
`LocalInitializer` of the constructor. After [0] the
`VariableDeclaration` of the local initializer will get the type of the
field.
Though that CL didn't ensure TFA also visits the type of the
`VariableDeclaration`. This can lead to a situation where the type
refers to a class that TFA has tree shaken, which causes dangling
references in the AST.
[0] https://dart-review.googlesource.com/c/sdk/+/415201
Issue https://github.com/flutter/flutter/issues/166124
Issue b/406692736
TEST=pkg/vm/testcases/transformations/type_flow/transformer/write_only_field
Change-Id: Ieb8f5c4daedd314c613617218da898059bb6941a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/419542
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 1708212..f499a92 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -1850,7 +1850,7 @@
null,
initializer: node.value,
isSynthesized: true,
- type: field.type,
+ type: visitDartType(field.type, cannotRemoveSentinel),
),
);
} else {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart
index d7b90d8..3352443 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart
@@ -21,8 +21,11 @@
class C {
B? instanceField = new B();
+ UsedAsType<int>? Function() instanceField2 = () => null;
}
+class UsedAsType<T> {}
+
void main() {
field = null;
new C().instanceField = null;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect
index d2f151a..7de083a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect
@@ -12,12 +12,14 @@
}
class C extends core::Object {
synthetic constructor •() → self::C
- : self::B? #t1 = new self::B::•(), super core::Object::•()
+ : self::B? #t1 = new self::B::•(), () → self::UsedAsType<core::int>? #t2 = () → Null => null, super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1]
set instanceField(synthesized self::B? value) → void;
}
+abstract class UsedAsType<T extends core::Object? = dynamic> extends core::Object {
+}
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
static method main() → void {