@@ -1585,7 +1585,9 @@ RawError* Object::Init(Isolate* isolate,
15851585 // patching. The array type allocated below represents the raw type _List
15861586 // and not _List<E> as we could expect. Use with caution.
15871587 type = Type::New(Class::Handle(zone, cls.raw()),
1588- TypeArguments::Handle(zone), TokenPosition::kNoSource);
1588+ TypeArguments::Handle(zone), TokenPosition::kNoSource,
1589+ Dart::non_nullable_flag() ? Nullability::kNonNullable
1590+ : Nullability::kLegacy);
15891591 type.SetIsFinalized();
15901592 type ^= type.Canonicalize();
15911593 object_store->set_array_type(type);
@@ -2456,8 +2458,10 @@ RawAbstractType* Class::RareType() const {
24562458 return DeclarationType();
24572459 }
24582460 ASSERT(is_declaration_loaded());
2459- const Type& type = Type::Handle(Type::New(
2460- *this, Object::null_type_arguments(), TokenPosition::kNoSource));
2461+ const Type& type = Type::Handle(
2462+ Type::New(*this, Object::null_type_arguments(), TokenPosition::kNoSource,
2463+ Dart::non_nullable_flag() ? Nullability::kNonNullable
2464+ : Nullability::kLegacy));
24612465 return ClassFinalizer::FinalizeType(*this, type);
24622466}
24632467
@@ -4354,19 +4358,19 @@ void Class::set_declaration_type(const Type& value) const {
43544358 ASSERT(!value.IsNull() && value.IsCanonical() && value.IsOld());
43554359 ASSERT((declaration_type() == Object::null()) ||
43564360 (declaration_type() == value.raw())); // Set during own finalization.
4357- // TODO(regis): Since declaration type is used as the runtime type of
4358- // instances of a non-generic class, the nullability should be set to
4359- // kNonNullable instead of kLegacy.
4360- // For now, we accept any except for Null (kNullable).
4361+ // Since declaration type is used as the runtime type of instances of a
4362+ // non-generic class, the nullability is set to kNonNullable instead of
4363+ // kLegacy when the non-nullable experiment is enabled.
43614364 ASSERT(!value.IsNullType() || value.IsNullable());
4362- ASSERT(value.IsNullType() || value.IsLegacy());
4365+ ASSERT(
4366+ value.IsNullType() ||
4367+ (Dart::non_nullable_flag() ? value.IsNonNullable() : value.IsLegacy()));
43634368 StorePointer(&raw_ptr()->declaration_type_, value.raw());
43644369}
43654370
4366- RawType* Class::DeclarationType(Nullability nullability ) const {
4371+ RawType* Class::DeclarationType() const {
43674372 ASSERT(is_declaration_loaded());
43684373 if (IsNullClass()) {
4369- // Ignore requested nullability (e.g. by mirrors).
43704374 return Type::NullType();
43714375 }
43724376 if (IsDynamicClass()) {
@@ -4378,23 +4382,21 @@ RawType* Class::DeclarationType(Nullability nullability) const {
43784382 if (IsNeverClass()) {
43794383 return Type::NeverType();
43804384 }
4381- Type& type = Type::Handle(declaration_type());
4382- if (!type.IsNull()) {
4383- return type.ToNullability(nullability, Heap::kOld);
4385+ if (declaration_type() != Type::null()) {
4386+ return declaration_type();
43844387 }
4385- // TODO(regis): We should pass nullabiity to Type::New to avoid having to
4386- // clone the type to the desired nullability. This however causes issues with
4387- // the runtimeType intrinsic grabbing DeclarationType without checking its
4388- // nullability. Indeed, when the CFE provides a non-nullable version of the
4389- // type first, this non-nullable version gets cached as the declaration type.
4390- // We consistenly cache the kLegacy version of a type, unless the non-nullable
4388+ // For efficiency, the runtimeType intrinsic returns the type cached by
4389+ // DeclarationType without checking its nullability. Therefore, we
4390+ // consistently cache the kLegacy version of a type, unless the non-nullable
43914391 // experiment is enabled, in which case we store the kNonNullable version.
43924392 // In either cases, the exception is type Null which is stored as kNullable.
4393- type = Type::New(*this, TypeArguments::Handle(type_parameters()), token_pos(),
4394- Nullability::kLegacy);
4393+ Type& type = Type::Handle(
4394+ Type::New(*this, TypeArguments::Handle(type_parameters()), token_pos(),
4395+ Dart::non_nullable_flag() ? Nullability::kNonNullable
4396+ : Nullability::kLegacy));
43954397 type ^= ClassFinalizer::FinalizeType(*this, type);
43964398 set_declaration_type(type);
4397- return type.ToNullability(nullability, Heap::kOld );
4399+ return type.raw( );
43984400}
43994401
44004402void Class::set_allocation_stub(const Code& value) const {
@@ -16745,10 +16747,10 @@ RawAbstractType* Instance::GetType(Heap::Space space) const {
1674516747 if (cls.NumTypeArguments() > 0) {
1674616748 type_arguments = GetTypeArguments();
1674716749 }
16748- // TODO(regis): The runtime type of a non-null instance should be
16749- // non-nullable instead of legacy. Revisit.
1675016750 type = Type::New(cls, type_arguments, TokenPosition::kNoSource,
16751- Nullability::kLegacy, space);
16751+ Dart::non_nullable_flag() ? Nullability::kNonNullable
16752+ : Nullability::kLegacy,
16753+ space);
1675216754 type.SetIsFinalized();
1675316755 type ^= type.Canonicalize();
1675416756 }
@@ -17783,11 +17785,9 @@ RawType* Type::DartTypeType() {
1778317785 return Isolate::Current()->object_store()->type_type();
1778417786}
1778517787
17786- RawType* Type::NewNonParameterizedType(const Class& type_class,
17787- Nullability nullability) {
17788+ RawType* Type::NewNonParameterizedType(const Class& type_class) {
1778817789 ASSERT(type_class.NumTypeArguments() == 0);
1778917790 if (type_class.IsNullClass()) {
17790- // Ignore requested nullability (e.g. by mirrors).
1779117791 return Type::NullType();
1779217792 }
1779317793 if (type_class.IsDynamicClass()) {
@@ -17805,13 +17805,14 @@ RawType* Type::NewNonParameterizedType(const Class& type_class,
1780517805 if (type.IsNull()) {
1780617806 type = Type::New(Class::Handle(type_class.raw()),
1780717807 Object::null_type_arguments(), TokenPosition::kNoSource,
17808- Nullability::kLegacy);
17808+ Dart::non_nullable_flag() ? Nullability::kNonNullable
17809+ : Nullability::kLegacy);
1780917810 type.SetIsFinalized();
1781017811 type ^= type.Canonicalize();
1781117812 type_class.set_declaration_type(type);
1781217813 }
1781317814 ASSERT(type.IsFinalized());
17814- return type.ToNullability(nullability, Heap::kOld );
17815+ return type.raw( );
1781517816}
1781617817
1781717818void Type::SetIsFinalized() const {
@@ -17840,6 +17841,7 @@ RawType* Type::ToNullability(Nullability value, Heap::Space space) const {
1784017841 }
1784117842 // Clone type and set new nullability.
1784217843 Type& type = Type::Handle();
17844+ // TODO(regis): Should we always clone in old space and remove space param?
1784317845 type ^= Object::Clone(*this, space);
1784417846 type.set_nullability(value);
1784517847 type.SetHash(0);
@@ -18154,6 +18156,20 @@ bool Type::IsRecursive() const {
1815418156 return TypeArguments::Handle(arguments()).IsRecursive();
1815518157}
1815618158
18159+ bool Type::IsDeclarationTypeOf(const Class& cls) const {
18160+ ASSERT(type_class() == cls.raw());
18161+ if (IsNullType()) {
18162+ return true;
18163+ }
18164+ if (cls.IsGeneric() || cls.IsClosureClass() || cls.IsTypedefClass()) {
18165+ return false;
18166+ }
18167+ const Nullability declaration_nullability = Dart::non_nullable_flag()
18168+ ? Nullability::kNonNullable
18169+ : Nullability::kLegacy;
18170+ return nullability() == declaration_nullability;
18171+ }
18172+
1815718173RawAbstractType* Type::Canonicalize(TrailPtr trail) const {
1815818174 ASSERT(IsFinalized());
1815918175 if (IsCanonical()) {
@@ -18183,8 +18199,7 @@ RawAbstractType* Type::Canonicalize(TrailPtr trail) const {
1818318199 const Class& cls = Class::Handle(zone, type_class());
1818418200
1818518201 // Fast canonical lookup/registry for simple types.
18186- if ((IsNullType() || IsLegacy()) && !cls.IsGeneric() &&
18187- !cls.IsClosureClass() && !cls.IsTypedefClass()) {
18202+ if (IsDeclarationTypeOf(cls)) {
1818818203 ASSERT(!IsFunctionType());
1818918204 ASSERT(!IsNullType() || IsNullable());
1819018205 Type& type = Type::Handle(zone, cls.declaration_type());
@@ -18317,8 +18332,7 @@ bool Type::CheckIsCanonical(Thread* thread) const {
1831718332 const Class& cls = Class::Handle(zone, type_class());
1831818333
1831918334 // Fast canonical lookup/registry for simple types.
18320- if ((IsNullType() || IsLegacy()) && !cls.IsGeneric() &&
18321- !cls.IsClosureClass() && !cls.IsTypedefClass()) {
18335+ if (IsDeclarationTypeOf(cls)) {
1832218336 ASSERT(!IsFunctionType());
1832318337 type = cls.declaration_type();
1832418338 ASSERT(type.IsCanonical());
@@ -18652,6 +18666,7 @@ RawTypeParameter* TypeParameter::ToNullability(Nullability value,
1865218666 }
1865318667 // Clone type and set new nullability.
1865418668 TypeParameter& type_parameter = TypeParameter::Handle();
18669+ // TODO(regis): Should we always clone in old space and remove space param?
1865518670 type_parameter ^= Object::Clone(*this, space);
1865618671 type_parameter.set_nullability(value);
1865718672 type_parameter.SetHash(0);
0 commit comments