Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Side by Side Diff: runtime/vm/object.cc

Issue 2822323002: More work on finalization of recursive types (fixes #29357). (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/object.h ('k') | tests/language/regress_29357_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/become.h" 10 #include "vm/become.h"
(...skipping 4683 matching lines...) Expand 10 before | Expand all | Expand 10 after
4694 } 4694 }
4695 const intptr_t num_types = Length(); 4695 const intptr_t num_types = Length();
4696 if (num_types != other.Length()) { 4696 if (num_types != other.Length()) {
4697 return false; 4697 return false;
4698 } 4698 }
4699 AbstractType& type = AbstractType::Handle(); 4699 AbstractType& type = AbstractType::Handle();
4700 AbstractType& other_type = AbstractType::Handle(); 4700 AbstractType& other_type = AbstractType::Handle();
4701 for (intptr_t i = from_index; i < from_index + len; i++) { 4701 for (intptr_t i = from_index; i < from_index + len; i++) {
4702 type = TypeAt(i); 4702 type = TypeAt(i);
4703 other_type = other.TypeAt(i); 4703 other_type = other.TypeAt(i);
4704 if (!type.IsEquivalent(other_type, trail)) { 4704 if (!type.IsNull() && !type.IsEquivalent(other_type, trail)) {
4705 return false; 4705 return false;
4706 } 4706 }
4707 } 4707 }
4708 return true; 4708 return true;
4709 } 4709 }
4710 4710
4711 4711
4712 bool TypeArguments::IsRecursive() const { 4712 bool TypeArguments::IsRecursive() const {
4713 if (IsNull()) return false; 4713 if (IsNull()) return false;
4714 const intptr_t num_types = Length(); 4714 const intptr_t num_types = Length();
(...skipping 13 matching lines...) Expand all
4728 4728
4729 4729
4730 bool TypeArguments::IsDynamicTypes(bool raw_instantiated, 4730 bool TypeArguments::IsDynamicTypes(bool raw_instantiated,
4731 intptr_t from_index, 4731 intptr_t from_index,
4732 intptr_t len) const { 4732 intptr_t len) const {
4733 ASSERT(Length() >= (from_index + len)); 4733 ASSERT(Length() >= (from_index + len));
4734 AbstractType& type = AbstractType::Handle(); 4734 AbstractType& type = AbstractType::Handle();
4735 Class& type_class = Class::Handle(); 4735 Class& type_class = Class::Handle();
4736 for (intptr_t i = 0; i < len; i++) { 4736 for (intptr_t i = 0; i < len; i++) {
4737 type = TypeAt(from_index + i); 4737 type = TypeAt(from_index + i);
4738 if (type.IsNull()) {
4739 return false;
4740 }
4738 if (!type.HasResolvedTypeClass()) { 4741 if (!type.HasResolvedTypeClass()) {
4739 if (raw_instantiated && type.IsTypeParameter()) { 4742 if (raw_instantiated && type.IsTypeParameter()) {
4740 // An uninstantiated type parameter is equivalent to dynamic (even in 4743 // An uninstantiated type parameter is equivalent to dynamic (even in
4741 // the presence of a malformed bound in checked mode). 4744 // the presence of a malformed bound in checked mode).
4742 continue; 4745 continue;
4743 } 4746 }
4744 return false; 4747 return false;
4745 } 4748 }
4746 type_class = type.type_class(); 4749 type_class = type.type_class();
4747 if (!type_class.IsDynamicClass()) { 4750 if (!type_class.IsDynamicClass()) {
(...skipping 11 matching lines...) Expand all
4759 Error* bound_error, 4762 Error* bound_error,
4760 TrailPtr bound_trail, 4763 TrailPtr bound_trail,
4761 Heap::Space space) const { 4764 Heap::Space space) const {
4762 ASSERT(Length() >= (from_index + len)); 4765 ASSERT(Length() >= (from_index + len));
4763 ASSERT(!other.IsNull()); 4766 ASSERT(!other.IsNull());
4764 ASSERT(other.Length() >= (from_index + len)); 4767 ASSERT(other.Length() >= (from_index + len));
4765 AbstractType& type = AbstractType::Handle(); 4768 AbstractType& type = AbstractType::Handle();
4766 AbstractType& other_type = AbstractType::Handle(); 4769 AbstractType& other_type = AbstractType::Handle();
4767 for (intptr_t i = 0; i < len; i++) { 4770 for (intptr_t i = 0; i < len; i++) {
4768 type = TypeAt(from_index + i); 4771 type = TypeAt(from_index + i);
4769 ASSERT(!type.IsNull());
4770 other_type = other.TypeAt(from_index + i); 4772 other_type = other.TypeAt(from_index + i);
4771 ASSERT(!other_type.IsNull()); 4773 if (type.IsNull() || other_type.IsNull() ||
4772 if (!type.TypeTest(test_kind, other_type, bound_error, bound_trail, 4774 !type.TypeTest(test_kind, other_type, bound_error, bound_trail,
4773 space)) { 4775 space)) {
4774 return false; 4776 return false;
4775 } 4777 }
4776 } 4778 }
4777 return true; 4779 return true;
4778 } 4780 }
4779 4781
4780 4782
4781 bool TypeArguments::HasInstantiations() const { 4783 bool TypeArguments::HasInstantiations() const {
4782 const Array& prior_instantiations = Array::Handle(instantiations()); 4784 const Array& prior_instantiations = Array::Handle(instantiations());
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
4855 // type before A is marked as finalized. 4857 // type before A is marked as finalized.
4856 if (!type.IsNull() && !type.IsInstantiated(genericity, trail)) { 4858 if (!type.IsNull() && !type.IsInstantiated(genericity, trail)) {
4857 return false; 4859 return false;
4858 } 4860 }
4859 } 4861 }
4860 return true; 4862 return true;
4861 } 4863 }
4862 4864
4863 4865
4864 bool TypeArguments::IsUninstantiatedIdentity() const { 4866 bool TypeArguments::IsUninstantiatedIdentity() const {
4865 ASSERT(!IsInstantiated());
4866 AbstractType& type = AbstractType::Handle(); 4867 AbstractType& type = AbstractType::Handle();
4867 const intptr_t num_types = Length(); 4868 const intptr_t num_types = Length();
4868 for (intptr_t i = 0; i < num_types; i++) { 4869 for (intptr_t i = 0; i < num_types; i++) {
4869 type = TypeAt(i); 4870 type = TypeAt(i);
4871 if (type.IsNull()) {
4872 continue;
4873 }
4870 if (!type.IsTypeParameter()) { 4874 if (!type.IsTypeParameter()) {
4871 return false; 4875 return false;
4872 } 4876 }
4873 const TypeParameter& type_param = TypeParameter::Cast(type); 4877 const TypeParameter& type_param = TypeParameter::Cast(type);
4874 ASSERT(type_param.IsFinalized()); 4878 ASSERT(type_param.IsFinalized());
4875 if ((type_param.index() != i) || type_param.IsFunctionTypeParameter()) { 4879 if ((type_param.index() != i) || type_param.IsFunctionTypeParameter()) {
4876 return false; 4880 return false;
4877 } 4881 }
4882 // TODO(regis): Do the bounds really matter, since they are checked at
4883 // finalization time (creating BoundedTypes where required)? Understand
4884 // why ignoring bounds here causes failures.
4878 // If this type parameter specifies an upper bound, then the type argument 4885 // If this type parameter specifies an upper bound, then the type argument
4879 // vector does not really represent the identity vector. It cannot be 4886 // vector does not really represent the identity vector. It cannot be
4880 // substituted by the instantiator's type argument vector without checking 4887 // substituted by the instantiator's type argument vector without checking
4881 // the upper bound. 4888 // the upper bound.
4882 const AbstractType& bound = AbstractType::Handle(type_param.bound()); 4889 const AbstractType& bound = AbstractType::Handle(type_param.bound());
4883 ASSERT(bound.IsResolved()); 4890 ASSERT(bound.IsResolved());
4884 if (!bound.IsObjectType() && !bound.IsDynamicType()) { 4891 if (!bound.IsObjectType() && !bound.IsDynamicType()) {
4885 return false; 4892 return false;
4886 } 4893 }
4887 } 4894 }
(...skipping 12771 matching lines...) Expand 10 before | Expand all | Expand 10 after
17659 return OS::SCreate(zone, "%sType: class '%s', args:[%s]", unresolved, 17666 return OS::SCreate(zone, "%sType: class '%s', args:[%s]", unresolved,
17660 class_name, args_cstr); 17667 class_name, args_cstr);
17661 } 17668 }
17662 } 17669 }
17663 17670
17664 17671
17665 bool TypeRef::IsInstantiated(Genericity genericity, TrailPtr trail) const { 17672 bool TypeRef::IsInstantiated(Genericity genericity, TrailPtr trail) const {
17666 if (TestAndAddToTrail(&trail)) { 17673 if (TestAndAddToTrail(&trail)) {
17667 return true; 17674 return true;
17668 } 17675 }
17669 return AbstractType::Handle(type()).IsInstantiated(genericity, trail); 17676 const AbstractType& ref_type = AbstractType::Handle(type());
17677 return !ref_type.IsNull() && ref_type.IsInstantiated(genericity, trail);
17670 } 17678 }
17671 17679
17672 17680
17673 bool TypeRef::IsEquivalent(const Instance& other, TrailPtr trail) const { 17681 bool TypeRef::IsEquivalent(const Instance& other, TrailPtr trail) const {
17674 if (raw() == other.raw()) { 17682 if (raw() == other.raw()) {
17675 return true; 17683 return true;
17676 } 17684 }
17677 if (!other.IsAbstractType()) { 17685 if (!other.IsAbstractType()) {
17678 return false; 17686 return false;
17679 } 17687 }
17680 if (TestAndAddBuddyToTrail(&trail, AbstractType::Cast(other))) { 17688 if (TestAndAddBuddyToTrail(&trail, AbstractType::Cast(other))) {
17681 return true; 17689 return true;
17682 } 17690 }
17683 return AbstractType::Handle(type()).IsEquivalent(other, trail); 17691 const AbstractType& ref_type = AbstractType::Handle(type());
17692 return !ref_type.IsNull() && ref_type.IsEquivalent(other, trail);
17684 } 17693 }
17685 17694
17686 17695
17687 RawTypeRef* TypeRef::InstantiateFrom( 17696 RawTypeRef* TypeRef::InstantiateFrom(
17688 const TypeArguments& instantiator_type_arguments, 17697 const TypeArguments& instantiator_type_arguments,
17689 const TypeArguments& function_type_arguments, 17698 const TypeArguments& function_type_arguments,
17690 Error* bound_error, 17699 Error* bound_error,
17691 TrailPtr instantiation_trail, 17700 TrailPtr instantiation_trail,
17692 TrailPtr bound_trail, 17701 TrailPtr bound_trail,
17693 Heap::Space space) const { 17702 Heap::Space space) const {
17694 TypeRef& instantiated_type_ref = TypeRef::Handle(); 17703 TypeRef& instantiated_type_ref = TypeRef::Handle();
17695 instantiated_type_ref ^= OnlyBuddyInTrail(instantiation_trail); 17704 instantiated_type_ref ^= OnlyBuddyInTrail(instantiation_trail);
17696 if (!instantiated_type_ref.IsNull()) { 17705 if (!instantiated_type_ref.IsNull()) {
17697 return instantiated_type_ref.raw(); 17706 return instantiated_type_ref.raw();
17698 } 17707 }
17699 instantiated_type_ref = TypeRef::New(); 17708 instantiated_type_ref = TypeRef::New();
17700 AddOnlyBuddyToTrail(&instantiation_trail, instantiated_type_ref); 17709 AddOnlyBuddyToTrail(&instantiation_trail, instantiated_type_ref);
17701 17710
17702 AbstractType& ref_type = AbstractType::Handle(type()); 17711 AbstractType& ref_type = AbstractType::Handle(type());
17703 ASSERT(!ref_type.IsTypeRef()); 17712 ASSERT(!ref_type.IsNull() && !ref_type.IsTypeRef());
17704 AbstractType& instantiated_ref_type = AbstractType::Handle(); 17713 AbstractType& instantiated_ref_type = AbstractType::Handle();
17705 instantiated_ref_type = ref_type.InstantiateFrom( 17714 instantiated_ref_type = ref_type.InstantiateFrom(
17706 instantiator_type_arguments, function_type_arguments, bound_error, 17715 instantiator_type_arguments, function_type_arguments, bound_error,
17707 instantiation_trail, bound_trail, space); 17716 instantiation_trail, bound_trail, space);
17708 ASSERT(!instantiated_ref_type.IsTypeRef()); 17717 ASSERT(!instantiated_ref_type.IsTypeRef());
17709 instantiated_type_ref.set_type(instantiated_ref_type); 17718 instantiated_type_ref.set_type(instantiated_ref_type);
17710 return instantiated_type_ref.raw(); 17719 return instantiated_type_ref.raw();
17711 } 17720 }
17712 17721
17713 17722
17714 RawTypeRef* TypeRef::CloneUninstantiated(const Class& new_owner, 17723 RawTypeRef* TypeRef::CloneUninstantiated(const Class& new_owner,
17715 TrailPtr trail) const { 17724 TrailPtr trail) const {
17716 TypeRef& cloned_type_ref = TypeRef::Handle(); 17725 TypeRef& cloned_type_ref = TypeRef::Handle();
17717 cloned_type_ref ^= OnlyBuddyInTrail(trail); 17726 cloned_type_ref ^= OnlyBuddyInTrail(trail);
17718 if (!cloned_type_ref.IsNull()) { 17727 if (!cloned_type_ref.IsNull()) {
17719 return cloned_type_ref.raw(); 17728 return cloned_type_ref.raw();
17720 } 17729 }
17721 cloned_type_ref = TypeRef::New(); 17730 cloned_type_ref = TypeRef::New();
17722 AddOnlyBuddyToTrail(&trail, cloned_type_ref); 17731 AddOnlyBuddyToTrail(&trail, cloned_type_ref);
17723 AbstractType& ref_type = AbstractType::Handle(type()); 17732 AbstractType& ref_type = AbstractType::Handle(type());
17724 ASSERT(!ref_type.IsTypeRef()); 17733 ASSERT(!ref_type.IsNull() && !ref_type.IsTypeRef());
17725 AbstractType& cloned_ref_type = AbstractType::Handle(); 17734 AbstractType& cloned_ref_type = AbstractType::Handle();
17726 cloned_ref_type = ref_type.CloneUninstantiated(new_owner, trail); 17735 cloned_ref_type = ref_type.CloneUninstantiated(new_owner, trail);
17727 ASSERT(!cloned_ref_type.IsTypeRef()); 17736 ASSERT(!cloned_ref_type.IsTypeRef());
17728 cloned_type_ref.set_type(cloned_ref_type); 17737 cloned_type_ref.set_type(cloned_ref_type);
17729 return cloned_type_ref.raw(); 17738 return cloned_type_ref.raw();
17730 } 17739 }
17731 17740
17732 17741
17733 void TypeRef::set_type(const AbstractType& value) const { 17742 void TypeRef::set_type(const AbstractType& value) const {
17734 ASSERT(value.IsFunctionType() || value.HasResolvedTypeClass()); 17743 ASSERT(value.IsFunctionType() || value.HasResolvedTypeClass());
17735 ASSERT(!value.IsTypeRef()); 17744 ASSERT(!value.IsTypeRef());
17736 StorePointer(&raw_ptr()->type_, value.raw()); 17745 StorePointer(&raw_ptr()->type_, value.raw());
17737 } 17746 }
17738 17747
17739 17748
17740 // A TypeRef cannot be canonical by definition. Only its referenced type can be. 17749 // A TypeRef cannot be canonical by definition. Only its referenced type can be.
17741 // Consider the type Derived, where class Derived extends Base<Derived>. 17750 // Consider the type Derived, where class Derived extends Base<Derived>.
17742 // The first type argument of its flattened type argument vector is Derived, 17751 // The first type argument of its flattened type argument vector is Derived,
17743 // represented by a TypeRef pointing to itself. 17752 // represented by a TypeRef pointing to itself.
17744 RawAbstractType* TypeRef::Canonicalize(TrailPtr trail) const { 17753 RawAbstractType* TypeRef::Canonicalize(TrailPtr trail) const {
17745 if (TestAndAddToTrail(&trail)) { 17754 if (TestAndAddToTrail(&trail)) {
17746 return raw(); 17755 return raw();
17747 } 17756 }
17748 // TODO(regis): Try to reduce the number of nodes required to represent the 17757 // TODO(regis): Try to reduce the number of nodes required to represent the
17749 // referenced recursive type. 17758 // referenced recursive type.
17750 AbstractType& ref_type = AbstractType::Handle(type()); 17759 AbstractType& ref_type = AbstractType::Handle(type());
17760 ASSERT(!ref_type.IsNull());
17751 ref_type = ref_type.Canonicalize(trail); 17761 ref_type = ref_type.Canonicalize(trail);
17752 set_type(ref_type); 17762 set_type(ref_type);
17753 return raw(); 17763 return raw();
17754 } 17764 }
17755 17765
17756 17766
17757 #if defined(DEBUG) 17767 #if defined(DEBUG)
17758 bool TypeRef::CheckIsCanonical(Thread* thread) const { 17768 bool TypeRef::CheckIsCanonical(Thread* thread) const {
17759 AbstractType& ref_type = AbstractType::Handle(type()); 17769 AbstractType& ref_type = AbstractType::Handle(type());
17770 ASSERT(!ref_type.IsNull());
17760 return ref_type.CheckIsCanonical(thread); 17771 return ref_type.CheckIsCanonical(thread);
17761 } 17772 }
17762 #endif // DEBUG 17773 #endif // DEBUG
17763 17774
17764 17775
17765 RawString* TypeRef::EnumerateURIs() const { 17776 RawString* TypeRef::EnumerateURIs() const {
17766 Thread* thread = Thread::Current(); 17777 Thread* thread = Thread::Current();
17767 Zone* zone = thread->zone(); 17778 Zone* zone = thread->zone();
17768 const AbstractType& ref_type = AbstractType::Handle(zone, type()); 17779 const AbstractType& ref_type = AbstractType::Handle(zone, type());
17769 ASSERT(!ref_type.IsDynamicType() && !ref_type.IsVoidType()); 17780 ASSERT(!ref_type.IsDynamicType() && !ref_type.IsVoidType());
17770 GrowableHandlePtrArray<const String> pieces(zone, 6); 17781 GrowableHandlePtrArray<const String> pieces(zone, 6);
17771 const Class& cls = Class::Handle(zone, ref_type.type_class()); 17782 const Class& cls = Class::Handle(zone, ref_type.type_class());
17772 pieces.Add(Symbols::TwoSpaces()); 17783 pieces.Add(Symbols::TwoSpaces());
17773 pieces.Add(String::Handle(zone, cls.UserVisibleName())); 17784 pieces.Add(String::Handle(zone, cls.UserVisibleName()));
17774 // Break cycle by not printing type arguments, but '<optimized out>' instead. 17785 // Break cycle by not printing type arguments, but '<optimized out>' instead.
17775 pieces.Add(Symbols::OptimizedOut()); 17786 pieces.Add(Symbols::OptimizedOut());
17776 pieces.Add(Symbols::SpaceIsFromSpace()); 17787 pieces.Add(Symbols::SpaceIsFromSpace());
17777 const Library& library = Library::Handle(zone, cls.library()); 17788 const Library& library = Library::Handle(zone, cls.library());
17778 pieces.Add(String::Handle(zone, library.url())); 17789 pieces.Add(String::Handle(zone, library.url()));
17779 pieces.Add(Symbols::NewLine()); 17790 pieces.Add(Symbols::NewLine());
17780 return Symbols::FromConcatAll(thread, pieces); 17791 return Symbols::FromConcatAll(thread, pieces);
17781 } 17792 }
17782 17793
17783 17794
17784 intptr_t TypeRef::Hash() const { 17795 intptr_t TypeRef::Hash() const {
17785 // Do not calculate the hash of the referenced type to avoid divergence. 17796 // Do not calculate the hash of the referenced type to avoid divergence.
17786 const uint32_t result = 17797 const AbstractType& ref_type = AbstractType::Handle(type());
17787 Class::Handle(AbstractType::Handle(type()).type_class()).id(); 17798 ASSERT(!ref_type.IsNull());
17799 const uint32_t result = Class::Handle(ref_type.type_class()).id();
17788 return FinalizeHash(result, kHashBits); 17800 return FinalizeHash(result, kHashBits);
17789 } 17801 }
17790 17802
17791 17803
17792 RawTypeRef* TypeRef::New() { 17804 RawTypeRef* TypeRef::New() {
17793 RawObject* raw = 17805 RawObject* raw =
17794 Object::Allocate(TypeRef::kClassId, TypeRef::InstanceSize(), Heap::kOld); 17806 Object::Allocate(TypeRef::kClassId, TypeRef::InstanceSize(), Heap::kOld);
17795 return reinterpret_cast<RawTypeRef*>(raw); 17807 return reinterpret_cast<RawTypeRef*>(raw);
17796 } 17808 }
17797 17809
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
18280 AbstractType::Handle(bounded_type.raw()); 18292 AbstractType::Handle(bounded_type.raw());
18281 if (!bounded_type.IsInstantiated()) { 18293 if (!bounded_type.IsInstantiated()) {
18282 instantiated_bounded_type = bounded_type.InstantiateFrom( 18294 instantiated_bounded_type = bounded_type.InstantiateFrom(
18283 instantiator_type_arguments, function_type_arguments, bound_error, 18295 instantiator_type_arguments, function_type_arguments, bound_error,
18284 instantiation_trail, bound_trail, space); 18296 instantiation_trail, bound_trail, space);
18285 // In case types of instantiator_type_arguments are not finalized 18297 // In case types of instantiator_type_arguments are not finalized
18286 // (or instantiated), then the instantiated_bounded_type is not finalized 18298 // (or instantiated), then the instantiated_bounded_type is not finalized
18287 // (or instantiated) either. 18299 // (or instantiated) either.
18288 // Note that instantiator_type_arguments must have the final length, though. 18300 // Note that instantiator_type_arguments must have the final length, though.
18289 } 18301 }
18302 // If instantiated_bounded_type is not finalized, it is too early to check
18303 // its upper bound. It will be checked in a second finalization phase.
18290 if ((Isolate::Current()->type_checks()) && (bound_error != NULL) && 18304 if ((Isolate::Current()->type_checks()) && (bound_error != NULL) &&
18291 bound_error->IsNull()) { 18305 bound_error->IsNull() && instantiated_bounded_type.IsFinalized()) {
18292 AbstractType& upper_bound = AbstractType::Handle(bound()); 18306 AbstractType& upper_bound = AbstractType::Handle(bound());
18293 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); 18307 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType());
18294 AbstractType& instantiated_upper_bound = 18308 AbstractType& instantiated_upper_bound =
18295 AbstractType::Handle(upper_bound.raw()); 18309 AbstractType::Handle(upper_bound.raw());
18296 if (upper_bound.IsFinalized() && !upper_bound.IsInstantiated()) { 18310 if (upper_bound.IsFinalized() && !upper_bound.IsInstantiated()) {
18297 instantiated_upper_bound = upper_bound.InstantiateFrom( 18311 instantiated_upper_bound = upper_bound.InstantiateFrom(
18298 instantiator_type_arguments, function_type_arguments, bound_error, 18312 instantiator_type_arguments, function_type_arguments, bound_error,
18299 instantiation_trail, bound_trail, space); 18313 instantiation_trail, bound_trail, space);
18300 // The instantiated_upper_bound may not be finalized or instantiated. 18314 // The instantiated_upper_bound may not be finalized or instantiated.
18301 // See comment above. 18315 // See comment above.
18302 } 18316 }
18303 if (bound_error->IsNull()) { 18317 if (bound_error->IsNull()) {
18304 // Shortcut the F-bounded case where we have reached a fixpoint. 18318 // Shortcut the F-bounded case where we have reached a fixpoint.
18305 if (instantiated_bounded_type.Equals(bounded_type) && 18319 if (instantiated_bounded_type.Equals(bounded_type) &&
18306 instantiated_upper_bound.Equals(upper_bound)) { 18320 instantiated_upper_bound.Equals(upper_bound)) {
18307 return bounded_type.raw(); 18321 return bounded_type.raw();
18308 } 18322 }
18309 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); 18323 const TypeParameter& type_param = TypeParameter::Handle(type_parameter());
18310 if (!instantiated_bounded_type.IsFinalized() || 18324 if (instantiated_upper_bound.IsFinalized() &&
18311 !instantiated_upper_bound.IsFinalized() ||
18312 (!type_param.CheckBound(instantiated_bounded_type, 18325 (!type_param.CheckBound(instantiated_bounded_type,
18313 instantiated_upper_bound, bound_error, 18326 instantiated_upper_bound, bound_error,
18314 bound_trail, space) && 18327 bound_trail, space) &&
18315 bound_error->IsNull())) { 18328 bound_error->IsNull())) {
18316 // We cannot determine yet whether the bounded_type is below the 18329 // We cannot determine yet whether the bounded_type is below the
18317 // upper_bound, because one or both of them is still being finalized or 18330 // upper_bound, because one or both of them is still being finalized or
18318 // uninstantiated. For example, instantiated_bounded_type may be the 18331 // uninstantiated. For example, instantiated_bounded_type may be the
18319 // still unfinalized cloned type parameter of a mixin application class. 18332 // still unfinalized cloned type parameter of a mixin application class.
18320 // There is another special case where we do not want to report a bound 18333 // There is another special case where we do not want to report a bound
18321 // error yet: if the upper bound is a function type, but the bounded 18334 // error yet: if the upper bound is a function type, but the bounded
18322 // type is not and its class is not compiled yet, i.e. we cannot look 18335 // type is not and its class is not compiled yet, i.e. we cannot look
18323 // for a call method yet. 18336 // for a call method yet.
18324 ASSERT(instantiated_bounded_type.IsBeingFinalized() || 18337 ASSERT(!instantiated_bounded_type.IsInstantiated() ||
18325 instantiated_upper_bound.IsBeingFinalized() ||
18326 !instantiated_bounded_type.IsInstantiated() ||
18327 !instantiated_upper_bound.IsInstantiated() || 18338 !instantiated_upper_bound.IsInstantiated() ||
18328 (!instantiated_bounded_type.IsFunctionType() && 18339 (!instantiated_bounded_type.IsFunctionType() &&
18329 instantiated_upper_bound.IsFunctionType() && 18340 instantiated_upper_bound.IsFunctionType() &&
18330 instantiated_bounded_type.HasResolvedTypeClass() && 18341 instantiated_bounded_type.HasResolvedTypeClass() &&
18331 !Class::Handle(instantiated_bounded_type.type_class()) 18342 !Class::Handle(instantiated_bounded_type.type_class())
18332 .is_finalized())); 18343 .is_finalized()));
18333 // Postpone bound check by returning a new BoundedType with unfinalized 18344 // Postpone bound check by returning a new BoundedType with unfinalized
18334 // or partially instantiated bounded_type and upper_bound, but keeping 18345 // or partially instantiated bounded_type and upper_bound, but keeping
18335 // type_param. 18346 // type_param.
18336 instantiated_bounded_type = BoundedType::New( 18347 instantiated_bounded_type = BoundedType::New(
(...skipping 4854 matching lines...) Expand 10 before | Expand all | Expand 10 after
23191 return UserTag::null(); 23202 return UserTag::null();
23192 } 23203 }
23193 23204
23194 23205
23195 const char* UserTag::ToCString() const { 23206 const char* UserTag::ToCString() const {
23196 const String& tag_label = String::Handle(label()); 23207 const String& tag_label = String::Handle(label());
23197 return tag_label.ToCString(); 23208 return tag_label.ToCString();
23198 } 23209 }
23199 23210
23200 } // namespace dart 23211 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | tests/language/regress_29357_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698