From 8c4909aa8f001847ff1c21131bbfada1f9c0c2be Mon Sep 17 00:00:00 2001 From: Alexander Markov Date: Tue, 24 Mar 2020 22:22:57 +0000 Subject: [PATCH] [vm/nnbd] Mark static fields in opted-in libraries as late MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the NNBD feature specification, "a toplevel or static variable with an initializer is evaluated as if it was marked late". This change actually marks all static fields in opted-in libraries as late, in order to make sure that the rest of the VM handles such fields uniformly as late. Without this change implicit getters for such fields were generated as late, but type propagation didn't treat these fields as nullable, so field initialization checks were removed if field has a non-nullable type. Change-Id: I95bc096fb1d304b112369428dbb29d346964383f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/140767 Commit-Queue: Alexander Markov Reviewed-by: RĂ©gis Crelier Reviewed-by: Liam Appelbe --- pkg/vm/lib/bytecode/gen_bytecode.dart | 5 ++++- runtime/vm/kernel_loader.cc | 9 +++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart index 7109a1568ff..6e9b06304f4 100644 --- a/pkg/vm/lib/bytecode/gen_bytecode.dart +++ b/pkg/vm/lib/bytecode/gen_bytecode.dart @@ -632,7 +632,10 @@ class BytecodeGenerator extends RecursiveVisitor { if (field.isExtensionMember) { flags |= FieldDeclaration.isExtensionMemberFlag; } - if (field.isLate) { + // In NNBD libraries, static fields act like late fields + // regardless of whether they're marked late. + if (field.isLate || + (field.isStatic && field.enclosingLibrary.isNonNullableByDefault)) { flags |= FieldDeclaration.isLateFlag; } int position = TreeNode.noOffset; diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc index fd193c870a0..98e542151b1 100644 --- a/runtime/vm/kernel_loader.cc +++ b/runtime/vm/kernel_loader.cc @@ -1221,7 +1221,9 @@ void KernelLoader::FinishTopLevelClassLoading( // Only instance fields could be covariant. ASSERT(!field_helper.IsCovariant() && !field_helper.IsGenericCovariantImpl()); - const bool is_late = field_helper.IsLate(); + // In NNBD libraries, static fields act like late fields + // regardless of whether they're marked late. + const bool is_late = field_helper.IsLate() || library.is_nnbd(); const bool is_extension_member = field_helper.IsExtensionMember(); const Field& field = Field::Handle( Z, Field::NewTopLevel(name, is_final, field_helper.IsConst(), is_late, @@ -1577,7 +1579,10 @@ void KernelLoader::FinishClassLoading(const Class& klass, // In the VM all const fields are implicitly final whereas in Kernel they // are not final because they are not explicitly declared that way. const bool is_final = field_helper.IsConst() || field_helper.IsFinal(); - const bool is_late = field_helper.IsLate(); + // In NNBD libraries, static fields act like late fields + // regardless of whether they're marked late. + const bool is_late = field_helper.IsLate() || + (field_helper.IsStatic() && library.is_nnbd()); const bool is_extension_member = field_helper.IsExtensionMember(); Field& field = Field::Handle( Z, Field::New(name, field_helper.IsStatic(), is_final,