[VM runtime] Remove unused UnresolvedClass VM class.

Type resolution will be simplified in a later CL.

Change-Id: Ia610a5d06d381511ca48993dcc1cafbf205ca997
Reviewed-on: https://dart-review.googlesource.com/c/84552
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Régis Crelier <regis@google.com>
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index a8b625e..86ed771 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -523,7 +523,7 @@
       return CreateFunctionTypeMirror(type);
     }
   }
-  if (type.HasResolvedTypeClass()) {
+  if (type.HasTypeClass()) {
     const Class& cls = Class::Handle(type.type_class());
     // Handle void and dynamic types.
     if (cls.IsVoidClass()) {
@@ -730,7 +730,7 @@
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
   PROPAGATE_IF_MALFORMED(type);
   ASSERT(type.IsFinalized());
-  ASSERT(type.HasResolvedTypeClass());
+  ASSERT(type.HasTypeClass());
   const Class& cls = Class::Handle(type.type_class());
   ASSERT(!cls.IsNull());
   if (cls.IsDynamicClass() || cls.IsVoidClass() || cls.IsTypedefClass()) {
@@ -751,7 +751,7 @@
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(1));
 
-  ASSERT(type.HasResolvedTypeClass());
+  ASSERT(type.HasTypeClass());
   const Class& clz = Class::Handle(type.type_class());
   if (!clz.IsGeneric()) {
     const Array& error_args = Array::Handle(Array::New(3));
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 04fb131..3d717b7 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -58,7 +58,7 @@
 
 void AddSuperType(const AbstractType& type,
                   GrowableArray<intptr_t>* finalized_super_classes) {
-  ASSERT(type.HasResolvedTypeClass());
+  ASSERT(type.HasTypeClass());
   ASSERT(!type.IsDynamicType());
   if (type.IsObjectType()) {
     return;
@@ -86,7 +86,7 @@
   AbstractType& super_type = Type::Handle();
   super_type = cls.super_type();
   if (!super_type.IsNull()) {
-    if (!super_type.IsMalformed() && super_type.HasResolvedTypeClass()) {
+    if (!super_type.IsMalformed() && super_type.HasTypeClass()) {
       cls ^= super_type.type_class();
       if (cls.is_finalized()) {
         AddSuperType(super_type, finalized_super_classes);
@@ -157,7 +157,7 @@
   for (intptr_t i = 0; i < interfaces.Length(); ++i) {
     type ^= interfaces.At(i);
     if (type.IsMalformed()) continue;
-    if (!type.HasResolvedTypeClass()) continue;
+    if (!type.HasTypeClass()) continue;
     ifc ^= type.type_class();
     for (intptr_t j = 0; j < cids->length(); ++j) {
       if ((*cids)[j] == ifc.id()) {
@@ -309,53 +309,12 @@
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-static bool IsLoaded(const Type& type) {
-  if (type.HasResolvedTypeClass()) {
-    return true;
-  }
-  const UnresolvedClass& unresolved_class =
-      UnresolvedClass::Handle(type.unresolved_class());
-  const Object& prefix =
-      Object::Handle(unresolved_class.library_or_library_prefix());
-  if (prefix.IsNull()) {
-    return true;
-  } else if (prefix.IsLibraryPrefix()) {
-    return LibraryPrefix::Cast(prefix).is_loaded();
-  } else {
-    return true;
-  }
-}
-
-// Resolve unresolved_class in the library of cls, or return null.
-RawClass* ClassFinalizer::ResolveClass(
-    const Class& cls,
-    const UnresolvedClass& unresolved_class) {
-  const String& class_name = String::Handle(unresolved_class.ident());
-  Library& lib = Library::Handle();
-  Class& resolved_class = Class::Handle();
-  if (unresolved_class.library_or_library_prefix() == Object::null()) {
-    lib = cls.library();
-    ASSERT(!lib.IsNull());
-    resolved_class = lib.LookupClass(class_name);
-  } else {
-    const Object& prefix =
-        Object::Handle(unresolved_class.library_or_library_prefix());
-
-    if (prefix.IsLibraryPrefix()) {
-      resolved_class = LibraryPrefix::Cast(prefix).LookupClass(class_name);
-    } else {
-      resolved_class = Library::Cast(prefix).LookupClass(class_name);
-    }
-  }
-  return resolved_class.raw();
-}
-
 void ClassFinalizer::ResolveRedirectingFactory(const Class& cls,
                                                const Function& factory) {
   const Function& target = Function::Handle(factory.RedirectionTarget());
   if (target.IsNull()) {
     Type& type = Type::Handle(factory.RedirectionType());
-    if (!type.IsMalformed() && IsLoaded(type)) {
+    if (!type.IsMalformed()) {
       const GrowableObjectArray& visited_factories =
           GrowableObjectArray::Handle(GrowableObjectArray::New());
       ResolveRedirectingFactoryTarget(cls, factory, visited_factories);
@@ -516,25 +475,7 @@
   // unresolved is the correct thing to do.
 
   // Lookup the type class if necessary.
-  Class& type_class = Class::Handle();
-  if (type.HasResolvedTypeClass()) {
-    type_class = type.type_class();
-  } else {
-    const UnresolvedClass& unresolved_class =
-        UnresolvedClass::Handle(type.unresolved_class());
-    type_class = ResolveClass(cls, unresolved_class);
-    if (type_class.IsNull()) {
-      // The type class could not be resolved. The type is malformed.
-      FinalizeMalformedType(Error::Handle(),  // No previous error.
-                            Script::Handle(cls.script()), type,
-                            "cannot resolve class '%s' from '%s'",
-                            String::Handle(unresolved_class.Name()).ToCString(),
-                            String::Handle(cls.Name()).ToCString());
-      return;
-    }
-    // Replace unresolved class with resolved type class.
-    type.set_type_class(type_class);
-  }
+  Class& type_class = Class::Handle(type.type_class());
   // Promote the type to a function type in case its type class is a typedef.
   // Note that the type may already be a function type if it was parsed as a
   // formal parameter function type.
@@ -1596,10 +1537,8 @@
         // If the redirection type is from a deferred library and is not
         // yet loaded, do not attempt to resolve.
         Type& type = Type::Handle(zone, function.RedirectionType());
-        if (IsLoaded(type)) {
-          type ^= FinalizeType(cls, type);
-          function.SetRedirectionType(type);
-        }
+        type ^= FinalizeType(cls, type);
+        function.SetRedirectionType(type);
       }
     }
   }
@@ -2072,7 +2011,7 @@
   }
   Type& mixin_type = Type::Handle(mixin_app_class.mixin());
   ASSERT(!mixin_type.IsNull());
-  ASSERT(mixin_type.HasResolvedTypeClass());
+  ASSERT(mixin_type.HasTypeClass());
   const Class& mixin_class = Class::Handle(mixin_type.type_class());
 
   if (FLAG_trace_class_finalization) {
@@ -2189,7 +2128,7 @@
   Zone* zone = Thread::Current()->zone();
   const Type& mixin_type = Type::Handle(zone, cls.mixin());
   ASSERT(!mixin_type.IsNull());
-  ASSERT(mixin_type.HasResolvedTypeClass());
+  ASSERT(mixin_type.HasTypeClass());
   const Class& mixin_cls = Class::Handle(zone, mixin_type.type_class());
   FinalizeClass(mixin_cls);
   // If the mixin is a mixin application alias class, there are no members to
@@ -2775,7 +2714,7 @@
     if (super_class.IsMixinApplication()) {
       const Type& mixin_type = Type::Handle(super_class.mixin());
       ASSERT(!mixin_type.IsNull());
-      ASSERT(mixin_type.HasResolvedTypeClass());
+      ASSERT(mixin_type.HasTypeClass());
       const Class& mixin_class = Class::Handle(mixin_type.type_class());
       if (!IsMixinCycleFree(mixin_class, visited)) {
         return false;
@@ -2791,7 +2730,7 @@
     const Class& cls,
     const Type& type,
     const GrowableObjectArray& collected_args) {
-  ASSERT(type.HasResolvedTypeClass());
+  ASSERT(type.HasTypeClass());
   Class& type_class = Class::Handle(type.type_class());
   TypeArguments& type_args = TypeArguments::Handle(type.arguments());
   const intptr_t num_type_parameters = type_class.NumTypeParameters();
@@ -2839,7 +2778,7 @@
   AbstractType& mixin_super_type =
       AbstractType::Handle(zone, mixin_app_type.super_type());
   ResolveType(cls, mixin_super_type);
-  ASSERT(mixin_super_type.HasResolvedTypeClass());  // Even if malformed.
+  ASSERT(mixin_super_type.HasTypeClass());  // Even if malformed.
   if (mixin_super_type.IsMalformedOrMalbounded()) {
     ReportError(Error::Handle(zone, mixin_super_type.error()));
   }
@@ -2867,7 +2806,7 @@
     mixin_type = mixin_app_type.MixinTypeAt(i);
     ASSERT(!mixin_type.IsNull());
     ResolveType(cls, mixin_type);
-    ASSERT(mixin_type.HasResolvedTypeClass());  // Even if malformed.
+    ASSERT(mixin_type.HasTypeClass());  // Even if malformed.
     ASSERT(mixin_type.IsType());
     if (mixin_type.IsMalformedOrMalbounded()) {
       ReportError(Error::Handle(zone, mixin_type.error()));
@@ -3302,11 +3241,10 @@
                                                    ...) {
   va_list args;
   va_start(args, format);
-  const UnresolvedClass& unresolved_class =
-      UnresolvedClass::Handle(UnresolvedClass::New(LibraryPrefix::Handle(),
-                                                   Symbols::Empty(), type_pos));
-  const Type& type = Type::Handle(
-      Type::New(unresolved_class, Object::null_type_arguments(), type_pos));
+  // TODO(regis): Are malformed types still used in strong mode? Probably not.
+  const Type& type =
+      Type::Handle(Type::New(Class::Handle(Object::dynamic_class()),
+                             Object::null_type_arguments(), type_pos));
   MarkTypeMalformed(prev_error, script, type, format, args);
   va_end(args);
   ASSERT(type.IsMalformed());
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index e8d70ac..3b36a23 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -118,8 +118,6 @@
   static bool IsMixinCycleFree(const Class& cls,
                                GrowableArray<intptr_t>* visited);
   static void CheckForLegalConstClass(const Class& cls);
-  static RawClass* ResolveClass(const Class& cls,
-                                const UnresolvedClass& unresolved_class);
   static void ResolveType(const Class& cls, const AbstractType& type);
   static void ResolveRedirectingFactoryTarget(
       const Class& cls,
diff --git a/runtime/vm/class_finalizer_test.cc b/runtime/vm/class_finalizer_test.cc
index 4ea8c25..42fee86 100644
--- a/runtime/vm/class_finalizer_test.cc
+++ b/runtime/vm/class_finalizer_test.cc
@@ -70,33 +70,4 @@
   EXPECT(!ClassFinalizer::ProcessPendingClasses());
 }
 
-static RawLibrary* NewLib(const char* url_chars) {
-  String& url = String::ZoneHandle(Symbols::New(Thread::Current(), url_chars));
-  return Library::New(url);
-}
-
-ISOLATE_UNIT_TEST_CASE(ClassFinalize_Resolve) {
-  Zone* zone = thread->zone();
-  Isolate* isolate = thread->isolate();
-  ObjectStore* object_store = isolate->object_store();
-  const GrowableObjectArray& pending_classes =
-      GrowableObjectArray::Handle(zone, object_store->pending_classes());
-  Class& rhb = Class::Handle(CreateTestClass("RhB"));
-  pending_classes.Add(rhb);
-  Class& sbb = Class::Handle(CreateTestClass("SBB"));
-  pending_classes.Add(sbb);
-  Library& lib = Library::Handle(NewLib("TestLib"));
-  lib.AddClass(rhb);
-  lib.AddClass(sbb);
-  const String& superclass_name = String::Handle(sbb.Name());
-  const UnresolvedClass& unresolved =
-      UnresolvedClass::Handle(UnresolvedClass::New(
-          LibraryPrefix::Handle(), superclass_name, TokenPosition::kNoSource));
-  const TypeArguments& type_arguments = TypeArguments::Handle();
-  rhb.set_super_type(
-      Type::Handle(Type::New(Object::Handle(unresolved.raw()), type_arguments,
-                             TokenPosition::kNoSource)));
-  EXPECT(ClassFinalizer::ProcessPendingClasses());
-}
-
 }  // namespace dart
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 1cd8950..f9f3441 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -280,87 +280,6 @@
 };
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-class UnresolvedClassSerializationCluster : public SerializationCluster {
- public:
-  UnresolvedClassSerializationCluster()
-      : SerializationCluster("UnresolvedClass") {}
-  ~UnresolvedClassSerializationCluster() {}
-
-  void Trace(Serializer* s, RawObject* object) {
-    RawUnresolvedClass* cls = UnresolvedClass::RawCast(object);
-    objects_.Add(cls);
-
-    RawObject** from = cls->from();
-    RawObject** to = cls->to();
-    for (RawObject** p = from; p <= to; p++) {
-      s->Push(*p);
-    }
-  }
-
-  void WriteAlloc(Serializer* s) {
-    s->WriteCid(kUnresolvedClassCid);
-    intptr_t count = objects_.length();
-    s->WriteUnsigned(count);
-    for (intptr_t i = 0; i < count; i++) {
-      RawUnresolvedClass* cls = objects_[i];
-      s->AssignRef(cls);
-    }
-  }
-
-  void WriteFill(Serializer* s) {
-    intptr_t count = objects_.length();
-    for (intptr_t i = 0; i < count; i++) {
-      RawUnresolvedClass* cls = objects_[i];
-      RawObject** from = cls->from();
-      RawObject** to = cls->to();
-      for (RawObject** p = from; p <= to; p++) {
-        s->WriteRef(*p);
-      }
-      s->WriteTokenPosition(cls->ptr()->token_pos_);
-    }
-  }
-
- private:
-  GrowableArray<RawUnresolvedClass*> objects_;
-};
-#endif  // !DART_PRECOMPILED_RUNTIME
-
-class UnresolvedClassDeserializationCluster : public DeserializationCluster {
- public:
-  UnresolvedClassDeserializationCluster() {}
-  ~UnresolvedClassDeserializationCluster() {}
-
-  void ReadAlloc(Deserializer* d) {
-    start_index_ = d->next_index();
-    PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->ReadUnsigned();
-    for (intptr_t i = 0; i < count; i++) {
-      d->AssignRef(
-          AllocateUninitialized(old_space, UnresolvedClass::InstanceSize()));
-    }
-    stop_index_ = d->next_index();
-  }
-
-  void ReadFill(Deserializer* d) {
-    bool is_vm_object = d->isolate() == Dart::vm_isolate();
-
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawUnresolvedClass* cls =
-          reinterpret_cast<RawUnresolvedClass*>(d->Ref(id));
-      Deserializer::InitializeHeader(cls, kUnresolvedClassCid,
-                                     UnresolvedClass::InstanceSize(),
-                                     is_vm_object);
-      RawObject** from = cls->from();
-      RawObject** to = cls->to();
-      for (RawObject** p = from; p <= to; p++) {
-        *p = d->ReadRef();
-      }
-      cls->ptr()->token_pos_ = d->ReadTokenPosition();
-    }
-  }
-};
-
-#if !defined(DART_PRECOMPILED_RUNTIME)
 class TypeArgumentsSerializationCluster : public SerializationCluster {
  public:
   TypeArgumentsSerializationCluster() : SerializationCluster("TypeArguments") {}
@@ -4644,8 +4563,6 @@
   switch (cid) {
     case kClassCid:
       return new (Z) ClassSerializationCluster(num_cids_);
-    case kUnresolvedClassCid:
-      return new (Z) UnresolvedClassSerializationCluster();
     case kTypeArgumentsCid:
       return new (Z) TypeArgumentsSerializationCluster();
     case kPatchClassCid:
@@ -5176,8 +5093,6 @@
   switch (cid) {
     case kClassCid:
       return new (Z) ClassDeserializationCluster();
-    case kUnresolvedClassCid:
-      return new (Z) UnresolvedClassDeserializationCluster();
     case kTypeArgumentsCid:
       return new (Z) TypeArgumentsDeserializationCluster();
     case kPatchClassCid:
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index cd8350c..de1c670 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -450,7 +450,7 @@
     // a null check rather than the more elaborate class check
     CompileType* type = receiver->Type();
     const AbstractType* atype = type->ToAbstractType();
-    if (atype->IsInstantiated() && atype->HasResolvedTypeClass() &&
+    if (atype->IsInstantiated() && atype->HasTypeClass() &&
         !atype->IsDynamicType()) {
       if (type->is_nullable()) {
         receiver_maybe_null = true;
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index e02adfc..3b082be 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -286,7 +286,7 @@
         AbstractType::ZoneHandle(zone(), type_arguments.TypeAt(0));
     ASSERT(!tp_argument.IsMalformed());
     if (tp_argument.IsType()) {
-      ASSERT(tp_argument.HasResolvedTypeClass());
+      ASSERT(tp_argument.HasTypeClass());
       // Check if type argument is dynamic, Object, or void.
       const Type& object_type = Type::Handle(zone(), Type::ObjectType());
       if (object_type.IsSubtypeOf(tp_argument, NULL, NULL, Heap::kOld)) {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index dde228a..c62d083 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -278,7 +278,6 @@
         AbstractType::ZoneHandle(zone(), type_arguments.TypeAt(0));
     ASSERT(!tp_argument.IsMalformed());
     if (tp_argument.IsType()) {
-      ASSERT(tp_argument.HasResolvedTypeClass());
       // Check if type argument is dynamic, Object, or void.
       const Type& object_type = Type::Handle(zone(), Type::ObjectType());
       if (object_type.IsSubtypeOf(tp_argument, NULL, NULL, Heap::kOld)) {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index c041be6..859e772 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -294,7 +294,6 @@
         AbstractType::ZoneHandle(zone(), type_arguments.TypeAt(0));
     ASSERT(!tp_argument.IsMalformed());
     if (tp_argument.IsType()) {
-      ASSERT(tp_argument.HasResolvedTypeClass());
       // Check if type argument is dynamic, Object, or void.
       const Type& object_type = Type::Handle(zone(), Type::ObjectType());
       if (object_type.IsSubtypeOf(tp_argument, NULL, NULL, Heap::kOld)) {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index cf0c978..fa8c99b 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -287,7 +287,7 @@
         AbstractType::ZoneHandle(zone(), type_arguments.TypeAt(0));
     ASSERT(!tp_argument.IsMalformed());
     if (tp_argument.IsType()) {
-      ASSERT(tp_argument.HasResolvedTypeClass());
+      ASSERT(tp_argument.HasTypeClass());
       // Check if type argument is dynamic, Object, or void.
       const Type& object_type = Type::Handle(zone(), Type::ObjectType());
       if (object_type.IsSubtypeOf(tp_argument, NULL, NULL, Heap::kOld)) {
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 2b5574f..23a4b47 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -4060,7 +4060,7 @@
     // static receiver type on the ICData.
     if (checked_argument_count() == 1) {
       if (static_receiver_type_ != nullptr &&
-          static_receiver_type_->HasResolvedTypeClass()) {
+          static_receiver_type_->HasTypeClass()) {
         const Class& cls =
             Class::Handle(zone, static_receiver_type_->type_class());
         if (cls.IsGeneric() && !cls.IsFutureOrClass()) {
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 47537ee..7133e1f 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -700,7 +700,7 @@
       cid_ = kNullCid;
     } else if (type_->IsFunctionType() || type_->IsDartFunctionType()) {
       cid_ = kClosureCid;
-    } else if (type_->HasResolvedTypeClass()) {
+    } else if (type_->type_class_id() != kIllegalCid) {
       const Class& type_class = Class::Handle(type_->type_class());
       Thread* thread = Thread::Current();
       CHA& cha = thread->compiler_state().cha();
@@ -973,7 +973,7 @@
     // Receiver can't be null but can be an instance of a subclass.
     intptr_t cid = kDynamicCid;
 
-    if (type.HasResolvedTypeClass()) {
+    if (type.type_class_id() != kIllegalCid) {
       Thread* thread = Thread::Current();
       const Class& type_class = Class::Handle(type.type_class());
       if (!CHA::HasSubclasses(type_class)) {
@@ -1332,7 +1332,7 @@
   const AbstractType* abstract_type = NULL;
   if (isolate->can_use_strong_mode_types() ||
       (isolate->type_checks() &&
-       (type().IsFunctionType() || type().HasResolvedTypeClass()))) {
+       (type().IsFunctionType() || type().HasTypeClass()))) {
     cid = kIllegalCid;  // Abstract type is known, calculate cid lazily.
     abstract_type = &type();
     TraceStrongModeType(this, *abstract_type);
diff --git a/runtime/vm/compiler/frontend/flow_graph_builder.cc b/runtime/vm/compiler/frontend/flow_graph_builder.cc
index 2f04698..3d14de6 100644
--- a/runtime/vm/compiler/frontend/flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/flow_graph_builder.cc
@@ -356,7 +356,7 @@
   // Bail if the type is a function or a Dart Function type.
   if (type.IsFunctionType() || type.IsDartFunctionType()) return false;
 
-  ASSERT(type.HasResolvedTypeClass());
+  ASSERT(type.HasTypeClass());
   const Class& type_class = Class::Handle(type.type_class());
   // Bail if the type has any type parameters.
   if (type_class.IsGeneric()) return false;
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 6b56dcc..4f8b6dd 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -3068,7 +3068,7 @@
   bool is_unchecked_call = false;
 #ifndef TARGET_ARCH_DBC
   if (call_site_attributes.receiver_type != nullptr &&
-      call_site_attributes.receiver_type->HasResolvedTypeClass() &&
+      call_site_attributes.receiver_type->HasTypeClass() &&
       !Class::Handle(call_site_attributes.receiver_type->type_class())
            .IsGeneric()) {
     is_unchecked_call = true;
@@ -3608,7 +3608,7 @@
       SkipExpression();  // skip receiver
       is_unchecked_closure_call =
           ReadNameAsMethodName().Equals(Symbols::Call());
-    } else if (call_site_attributes.receiver_type->HasResolvedTypeClass() &&
+    } else if (call_site_attributes.receiver_type->HasTypeClass() &&
                !Class::Handle(call_site_attributes.receiver_type->type_class())
                     .IsGeneric()) {
       is_unchecked_call = true;
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 7fe36e5..e3dd575 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -107,15 +107,15 @@
       // Verify that the result type of a function is canonical or a
       // TypeParameter.
       typeHandle_ ^= funcHandle_.result_type();
-      ASSERT(typeHandle_.IsMalformed() || !typeHandle_.IsResolved() ||
-             typeHandle_.IsTypeParameter() || typeHandle_.IsCanonical());
+      ASSERT(typeHandle_.IsMalformed() || typeHandle_.IsTypeParameter() ||
+             typeHandle_.IsCanonical());
       // Verify that the types in the function signature are all canonical or
       // a TypeParameter.
       const intptr_t num_parameters = funcHandle_.NumParameters();
       for (intptr_t i = 0; i < num_parameters; i++) {
         typeHandle_ = funcHandle_.ParameterTypeAt(i);
-        ASSERT(typeHandle_.IsMalformed() || !typeHandle_.IsResolved() ||
-               typeHandle_.IsTypeParameter() || typeHandle_.IsCanonical());
+        ASSERT(typeHandle_.IsMalformed() || typeHandle_.IsTypeParameter() ||
+               typeHandle_.IsCanonical());
       }
     }
   }
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index cd878c1..091451f 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -112,8 +112,6 @@
 RawClass* Object::class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::dynamic_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::void_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::unresolved_class_class_ =
-    reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::type_arguments_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::patch_class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::function_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
@@ -557,9 +555,6 @@
   }
 
   // Allocate the remaining VM internal classes.
-  cls = Class::New<UnresolvedClass>();
-  unresolved_class_class_ = cls.raw();
-
   cls = Class::New<TypeArguments>();
   type_arguments_class_ = cls.raw();
 
@@ -947,7 +942,6 @@
   class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
   dynamic_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
   void_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-  unresolved_class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
   type_arguments_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
   patch_class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
   function_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
@@ -1047,7 +1041,6 @@
   SET_CLASS_NAME(class, Class);
   SET_CLASS_NAME(dynamic, Dynamic);
   SET_CLASS_NAME(void, Void);
-  SET_CLASS_NAME(unresolved_class, UnresolvedClass);
   SET_CLASS_NAME(type_arguments, TypeArguments);
   SET_CLASS_NAME(patch_class, PatchClass);
   SET_CLASS_NAME(function, Function);
@@ -1413,7 +1406,7 @@
     // declared number of type parameters is still 0. It will become 1 after
     // patching. The array type allocated below represents the raw type _List
     // and not _List<E> as we could expect. Use with caution.
-    type ^= Type::New(Object::Handle(zone, cls.raw()),
+    type ^= Type::New(Class::Handle(zone, cls.raw()),
                       TypeArguments::Handle(zone), TokenPosition::kNoSource);
     type.SetIsFinalized();
     type ^= type.Canonicalize();
@@ -3911,8 +3904,6 @@
       return Symbols::Void().raw();
     case kClassCid:
       return Symbols::Class().raw();
-    case kUnresolvedClassCid:
-      return Symbols::UnresolvedClass().raw();
     case kTypeArgumentsCid:
       return Symbols::TypeArguments().raw();
     case kPatchClassCid:
@@ -4500,7 +4491,7 @@
         return true;
       }
     }
-    if (other_type_arg.HasResolvedTypeClass() &&
+    if (other_type_arg.HasTypeClass() &&
         TypeTest(Class::kIsSubtypeOf, type_arguments,
                  Class::Handle(zone, other_type_arg.type_class()),
                  TypeArguments::Handle(other_type_arg.arguments()), bound_error,
@@ -5103,64 +5094,6 @@
   set.Release();
 }
 
-RawUnresolvedClass* UnresolvedClass::New(const Object& library_prefix,
-                                         const String& ident,
-                                         TokenPosition token_pos) {
-  const UnresolvedClass& type = UnresolvedClass::Handle(UnresolvedClass::New());
-  type.set_library_or_library_prefix(library_prefix);
-  type.set_ident(ident);
-  type.set_token_pos(token_pos);
-  return type.raw();
-}
-
-RawUnresolvedClass* UnresolvedClass::New() {
-  ASSERT(Object::unresolved_class_class() != Class::null());
-  RawObject* raw = Object::Allocate(
-      UnresolvedClass::kClassId, UnresolvedClass::InstanceSize(), Heap::kOld);
-  return reinterpret_cast<RawUnresolvedClass*>(raw);
-}
-
-void UnresolvedClass::set_token_pos(TokenPosition token_pos) const {
-  ASSERT(!token_pos.IsClassifying());
-  StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
-}
-
-void UnresolvedClass::set_ident(const String& ident) const {
-  StorePointer(&raw_ptr()->ident_, ident.raw());
-}
-
-void UnresolvedClass::set_library_or_library_prefix(
-    const Object& library_prefix) const {
-  StorePointer(&raw_ptr()->library_or_library_prefix_, library_prefix.raw());
-}
-
-RawString* UnresolvedClass::Name() const {
-  if (library_or_library_prefix() != Object::null()) {
-    Thread* thread = Thread::Current();
-    Zone* zone = thread->zone();
-    const Object& lib_prefix =
-        Object::Handle(zone, library_or_library_prefix());
-    String& name = String::Handle(zone);  // Qualifier.
-    if (lib_prefix.IsLibraryPrefix()) {
-      name = LibraryPrefix::Cast(lib_prefix).name();
-    } else {
-      name = Library::Cast(lib_prefix).name();
-    }
-    GrowableHandlePtrArray<const String> strs(zone, 3);
-    strs.Add(name);
-    strs.Add(Symbols::Dot());
-    strs.Add(String::Handle(zone, ident()));
-    return Symbols::FromConcatAll(thread, strs);
-  } else {
-    return ident();
-  }
-}
-
-const char* UnresolvedClass::ToCString() const {
-  const char* cname = String::Handle(Name()).ToCString();
-  return OS::SCreate(Thread::Current()->zone(), "unresolved class '%s'", cname);
-}
-
 intptr_t TypeArguments::ComputeHash() const {
   if (IsNull()) return 0;
   const intptr_t num_types = Length();
@@ -5299,7 +5232,7 @@
     if (type.IsNull()) {
       return false;
     }
-    if (!type.HasResolvedTypeClass()) {
+    if (!type.HasTypeClass()) {
       if (raw_instantiated && type.IsTypeParameter()) {
         // An uninstantiated type parameter is equivalent to dynamic (even in
         // the presence of a malformed bound in checked mode).
@@ -16819,12 +16752,6 @@
   UNREACHABLE();
 }
 
-bool AbstractType::HasResolvedTypeClass() const {
-  // AbstractType is an abstract class.
-  UNREACHABLE();
-  return false;
-}
-
 classid_t AbstractType::type_class_id() const {
   // AbstractType is an abstract class.
   UNREACHABLE();
@@ -16837,12 +16764,6 @@
   return Class::null();
 }
 
-RawUnresolvedClass* AbstractType::unresolved_class() const {
-  // AbstractType is an abstract class.
-  UNREACHABLE();
-  return UnresolvedClass::null();
-}
-
 RawTypeArguments* AbstractType::arguments() const {
   // AbstractType is an abstract class.
   UNREACHABLE();
@@ -17131,9 +17052,8 @@
   String& class_name = String::Handle(zone);
   intptr_t first_type_param_index;
   intptr_t num_type_params;  // Number of type parameters to print.
-  Class& cls = Class::Handle(zone);
+  Class& cls = Class::Handle(zone, type_class());
   if (IsFunctionType()) {
-    cls = type_class();
     const Function& signature_function =
         Function::Handle(zone, Type::Cast(*this).signature());
     if (!cls.IsTypedefClass()) {
@@ -17148,10 +17068,7 @@
       return class_name.raw();
     }
     // Print the name of a typedef as a regular, possibly parameterized, class.
-  } else if (HasResolvedTypeClass()) {
-    cls = type_class();
   }
-  if (!cls.IsNull()) {
     if (IsResolved() || !cls.IsMixinApplication()) {
       // Do not print the full vector, but only the declared type parameters.
       num_type_params = cls.NumTypeParameters();
@@ -17188,11 +17105,6 @@
       } else {
         first_type_param_index = num_args - num_type_params;
       }
-    }
-  } else {
-    class_name = UnresolvedClass::Handle(zone, unresolved_class()).Name();
-    num_type_params = num_args;
-    first_type_param_index = 0;
   }
   GrowableHandlePtrArray<const String> pieces(zone, 4);
   pieces.Add(class_name);
@@ -17213,11 +17125,7 @@
 
 RawString* AbstractType::ClassName() const {
   ASSERT(!IsFunctionType());
-  if (HasResolvedTypeClass()) {
-    return Class::Handle(type_class()).Name();
-  } else {
-    return UnresolvedClass::Handle(unresolved_class()).Name();
-  }
+  return Class::Handle(type_class()).Name();
 }
 
 bool AbstractType::IsNullTypeRef() const {
@@ -17228,7 +17136,7 @@
   if (IsCanonical()) {
     return raw() == Object::dynamic_type().raw();
   }
-  return HasResolvedTypeClass() && (type_class_id() == kDynamicCid);
+  return type_class_id() == kDynamicCid;
 }
 
 bool AbstractType::IsVoidType() const {
@@ -17237,17 +17145,17 @@
 }
 
 bool AbstractType::IsObjectType() const {
-  return HasResolvedTypeClass() && (type_class_id() == kInstanceCid);
+  return type_class_id() == kInstanceCid;
 }
 
 bool AbstractType::IsTopType() const {
   if (IsVoidType()) {
     return true;
   }
-  if (!HasResolvedTypeClass()) {
+  const classid_t cid = type_class_id();
+  if (cid == kIllegalCid) {
     return false;
   }
-  classid_t cid = type_class_id();
   if ((cid == kDynamicCid) || (cid == kInstanceCid)) {
     return true;
   }
@@ -17272,64 +17180,63 @@
 }
 
 bool AbstractType::IsNullType() const {
-  return HasResolvedTypeClass() && (type_class_id() == kNullCid);
+  return type_class_id() == kNullCid;
 }
 
 bool AbstractType::IsBoolType() const {
-  return HasResolvedTypeClass() && (type_class_id() == kBoolCid);
+  return type_class_id() == kBoolCid;
 }
 
 bool AbstractType::IsIntType() const {
-  return HasResolvedTypeClass() &&
+  return HasTypeClass() &&
          (type_class() == Type::Handle(Type::IntType()).type_class());
 }
 
 bool AbstractType::IsDoubleType() const {
-  return HasResolvedTypeClass() &&
+  return HasTypeClass() &&
          (type_class() == Type::Handle(Type::Double()).type_class());
 }
 
 bool AbstractType::IsFloat32x4Type() const {
   // kFloat32x4Cid refers to the private class and cannot be used here.
-  return HasResolvedTypeClass() &&
+  return HasTypeClass() &&
          (type_class() == Type::Handle(Type::Float32x4()).type_class());
 }
 
 bool AbstractType::IsFloat64x2Type() const {
   // kFloat64x2Cid refers to the private class and cannot be used here.
-  return HasResolvedTypeClass() &&
+  return HasTypeClass() &&
          (type_class() == Type::Handle(Type::Float64x2()).type_class());
 }
 
 bool AbstractType::IsInt32x4Type() const {
   // kInt32x4Cid refers to the private class and cannot be used here.
-  return HasResolvedTypeClass() &&
+  return HasTypeClass() &&
          (type_class() == Type::Handle(Type::Int32x4()).type_class());
 }
 
 bool AbstractType::IsNumberType() const {
-  return HasResolvedTypeClass() && (type_class_id() == kNumberCid);
+  return type_class_id() == kNumberCid;
 }
 
 bool AbstractType::IsSmiType() const {
-  return HasResolvedTypeClass() && (type_class_id() == kSmiCid);
+  return type_class_id() == kSmiCid;
 }
 
 bool AbstractType::IsStringType() const {
-  return HasResolvedTypeClass() &&
+  return HasTypeClass() &&
          (type_class() == Type::Handle(Type::StringType()).type_class());
 }
 
 bool AbstractType::IsDartFunctionType() const {
-  return HasResolvedTypeClass() &&
+  return HasTypeClass() &&
          (type_class() == Type::Handle(Type::DartFunctionType()).type_class());
 }
 
 bool AbstractType::IsDartClosureType() const {
   // Non-typedef function types have '_Closure' class as type class, but are not
   // the Dart '_Closure' type.
-  return !IsFunctionType() && HasResolvedTypeClass() &&
-         (type_class_id() == kClosureCid);
+  return !IsFunctionType() && (type_class_id() == kClosureCid);
 }
 
 bool AbstractType::TypeTest(TypeTestKind test_kind,
@@ -17663,7 +17570,7 @@
   ASSERT(type_class.NumTypeArguments() == 0);
   Type& type = Type::Handle(type_class.CanonicalType());
   if (type.IsNull()) {
-    type ^= Type::New(Object::Handle(type_class.raw()),
+    type ^= Type::New(Class::Handle(type_class.raw()),
                       Object::null_type_arguments(), TokenPosition::kNoSource);
     type.SetIsFinalized();
     type ^= type.Canonicalize();
@@ -17675,7 +17582,6 @@
 void Type::SetIsFinalized() const {
   ASSERT(!IsFinalized());
   if (IsInstantiated()) {
-    ASSERT(HasResolvedTypeClass());
     set_type_state(RawType::kFinalizedInstantiated);
   } else {
     set_type_state(RawType::kFinalizedUninstantiated);
@@ -17767,33 +17673,14 @@
   set_type_state(RawType::kResolved);
 }
 
-bool Type::HasResolvedTypeClass() const {
-  return !raw_ptr()->type_class_id_->IsHeapObject();
-}
-
 classid_t Type::type_class_id() const {
-  ASSERT(HasResolvedTypeClass());
-  return Smi::Value(reinterpret_cast<RawSmi*>(raw_ptr()->type_class_id_));
+  return Smi::Value(raw_ptr()->type_class_id_);
 }
 
 RawClass* Type::type_class() const {
   return Isolate::Current()->class_table()->At(type_class_id());
 }
 
-RawUnresolvedClass* Type::unresolved_class() const {
-#ifdef DEBUG
-  ASSERT(!HasResolvedTypeClass());
-  UnresolvedClass& unresolved_class = UnresolvedClass::Handle();
-  unresolved_class ^= raw_ptr()->type_class_id_;
-  ASSERT(!unresolved_class.IsNull());
-  return unresolved_class.raw();
-#else
-  ASSERT(!Object::Handle(raw_ptr()->type_class_id_).IsNull());
-  ASSERT(Object::Handle(raw_ptr()->type_class_id_).IsUnresolvedClass());
-  return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_id_);
-#endif
-}
-
 bool Type::IsInstantiated(Genericity genericity,
                           intptr_t num_free_fun_type_params,
                           TrailPtr trail) const {
@@ -17822,19 +17709,13 @@
   intptr_t len = num_type_args;  // Check the full vector of type args.
   ASSERT(num_type_args > 0);
   // This type is not instantiated if it refers to type parameters.
-  // Although this type may still be unresolved, the type parameters it may
-  // refer to are resolved by definition. We can therefore return the correct
-  // result even for an unresolved type. We just need to look at all type
-  // arguments and not just at the type parameters.
-  if (HasResolvedTypeClass()) {
-    const Class& cls = Class::Handle(type_class());
-    len = cls.NumTypeParameters();  // Check the type parameters only.
-    if (len > num_type_args) {
-      // This type has the wrong number of arguments and is not finalized yet.
-      // Type arguments are reset to null when finalizing such a type.
-      ASSERT(!IsFinalized());
-      len = num_type_args;
-    }
+  const Class& cls = Class::Handle(type_class());
+  len = cls.NumTypeParameters();  // Check the type parameters only.
+  if (len > num_type_args) {
+    // This type has the wrong number of arguments and is not finalized yet.
+    // Type arguments are reset to null when finalizing such a type.
+    ASSERT(!IsFinalized());
+    len = num_type_args;
   }
   return (len == 0) ||
          args.IsSubvectorInstantiated(num_type_args - len, len, genericity,
@@ -18461,13 +18342,7 @@
 
 void Type::set_type_class(const Class& value) const {
   ASSERT(!value.IsNull());
-  StorePointer(&raw_ptr()->type_class_id_,
-               reinterpret_cast<RawObject*>(Smi::New(value.id())));
-}
-
-void Type::set_unresolved_class(const Object& value) const {
-  ASSERT(!value.IsNull() && value.IsUnresolvedClass());
-  StorePointer(&raw_ptr()->type_class_id_, value.raw());
+  StorePointer(&raw_ptr()->type_class_id_, Smi::New(value.id()));
 }
 
 void Type::set_arguments(const TypeArguments& value) const {
@@ -18481,17 +18356,13 @@
   return reinterpret_cast<RawType*>(raw);
 }
 
-RawType* Type::New(const Object& clazz,
+RawType* Type::New(const Class& clazz,
                    const TypeArguments& arguments,
                    TokenPosition token_pos,
                    Heap::Space space) {
   Zone* Z = Thread::Current()->zone();
   const Type& result = Type::Handle(Z, Type::New(space));
-  if (clazz.IsClass()) {
-    result.set_type_class(Class::Cast(clazz));
-  } else {
-    result.set_unresolved_class(clazz);
-  }
+  result.set_type_class(clazz);
   result.set_arguments(arguments);
   result.SetHash(0);
   result.set_token_pos(token_pos);
@@ -18518,38 +18389,31 @@
     return "Type: null";
   }
   Zone* zone = Thread::Current()->zone();
-  const char* unresolved = IsResolved() ? "" : "Unresolved ";
   const TypeArguments& type_args = TypeArguments::Handle(zone, arguments());
   const char* args_cstr = type_args.IsNull() ? "null" : type_args.ToCString();
-  Class& cls = Class::Handle(zone);
+  const Class& cls = Class::Handle(zone, type_class());
   const char* class_name;
-  if (HasResolvedTypeClass()) {
-    cls = type_class();
-    const String& name = String::Handle(zone, cls.Name());
-    class_name = name.IsNull() ? "<null>" : name.ToCString();
-  } else {
-    class_name = UnresolvedClass::Handle(zone, unresolved_class()).ToCString();
-  }
+  const String& name = String::Handle(zone, cls.Name());
+  class_name = name.IsNull() ? "<null>" : name.ToCString();
   if (IsFunctionType()) {
     const Function& sig_fun = Function::Handle(zone, signature());
     const String& sig = String::Handle(zone, sig_fun.Signature());
     if (cls.IsClosureClass()) {
       ASSERT(type_args.IsNull());
-      return OS::SCreate(zone, "%sFunction Type: %s", unresolved,
-                         sig.ToCString());
+      return OS::SCreate(zone, "Function Type: %s", sig.ToCString());
     }
-    return OS::SCreate(zone, "%s Function Type: %s (class: %s, args: %s)",
-                       unresolved, sig.ToCString(), class_name, args_cstr);
+    return OS::SCreate(zone, "Function Type: %s (class: %s, args: %s)",
+                       sig.ToCString(), class_name, args_cstr);
   }
   if (type_args.IsNull()) {
-    return OS::SCreate(zone, "%sType: class '%s'", unresolved, class_name);
-  } else if (IsResolved() && IsFinalized() && IsRecursive()) {
+    return OS::SCreate(zone, "Type: class '%s'", class_name);
+  } else if (IsFinalized() && IsRecursive()) {
     const intptr_t hash = Hash();
     return OS::SCreate(zone, "Type: (@%p H%" Px ") class '%s', args:[%s]",
                        raw(), hash, class_name, args_cstr);
   } else {
-    return OS::SCreate(zone, "%sType: class '%s', args:[%s]", unresolved,
-                       class_name, args_cstr);
+    return OS::SCreate(zone, "Type: class '%s', args:[%s]", class_name,
+                       args_cstr);
   }
 }
 
@@ -18636,7 +18500,7 @@
 }
 
 void TypeRef::set_type(const AbstractType& value) const {
-  ASSERT(value.IsFunctionType() || value.HasResolvedTypeClass());
+  ASSERT(value.IsFunctionType() || value.HasTypeClass());
   ASSERT(!value.IsTypeRef());
   StorePointer(&raw_ptr()->type_, value.raw());
 }
@@ -18885,7 +18749,7 @@
       // is not and its class is not compiled yet, i.e. we cannot look for
       // a call method yet.
       if (!bounded_type.IsFunctionType() && upper_bound.IsFunctionType() &&
-          bounded_type.HasResolvedTypeClass() &&
+          bounded_type.HasTypeClass() &&
           !Class::Handle(bounded_type.type_class()).is_finalized()) {
         return false;  // Not a subtype yet, but no bound error yet.
       }
@@ -19213,7 +19077,7 @@
                !instantiated_upper_bound.IsInstantiated() ||
                (!instantiated_bounded_type.IsFunctionType() &&
                 instantiated_upper_bound.IsFunctionType() &&
-                instantiated_bounded_type.HasResolvedTypeClass() &&
+                instantiated_bounded_type.HasTypeClass() &&
                 !Class::Handle(instantiated_bounded_type.type_class())
                      .is_finalized()));
         // Postpone bound check by returning a new BoundedType with unfinalized
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index cfa12c8..b58ee61 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -415,7 +415,6 @@
   static RawClass* class_class() { return class_class_; }
   static RawClass* dynamic_class() { return dynamic_class_; }
   static RawClass* void_class() { return void_class_; }
-  static RawClass* unresolved_class_class() { return unresolved_class_class_; }
   static RawClass* type_arguments_class() { return type_arguments_class_; }
   static RawClass* patch_class_class() { return patch_class_class_; }
   static RawClass* function_class() { return function_class_; }
@@ -666,7 +665,6 @@
   static RawClass* class_class_;             // Class of the Class vm object.
   static RawClass* dynamic_class_;           // Class of the 'dynamic' type.
   static RawClass* void_class_;              // Class of the 'void' type.
-  static RawClass* unresolved_class_class_;  // Class of UnresolvedClass.
   static RawClass* type_arguments_class_;  // Class of TypeArguments vm object.
   static RawClass* patch_class_class_;     // Class of the PatchClass vm object.
   static RawClass* function_class_;        // Class of the Function vm object.
@@ -1506,37 +1504,6 @@
   friend class ClassFunctionVisitor;
 };
 
-// Unresolved class is used for storing unresolved names which will be resolved
-// to a class after all classes have been loaded and finalized.
-class UnresolvedClass : public Object {
- public:
-  RawObject* library_or_library_prefix() const {
-    return raw_ptr()->library_or_library_prefix_;
-  }
-  RawString* ident() const { return raw_ptr()->ident_; }
-  TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
-
-  RawString* Name() const;
-
-  static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawUnresolvedClass));
-  }
-
-  static RawUnresolvedClass* New(const Object& library_prefix,
-                                 const String& ident,
-                                 TokenPosition token_pos);
-
- private:
-  void set_library_or_library_prefix(const Object& library_prefix) const;
-  void set_ident(const String& ident) const;
-  void set_token_pos(TokenPosition token_pos) const;
-
-  static RawUnresolvedClass* New();
-
-  FINAL_HEAP_OBJECT_IMPLEMENTATION(UnresolvedClass, Object);
-  friend class Class;
-};
-
 // Classification of type genericity according to type parameter owners.
 enum Genericity {
   kAny,           // Consider type params of current class and functions.
@@ -6287,10 +6254,9 @@
   virtual void set_error(const LanguageError& value) const;
   virtual bool IsResolved() const;
   virtual void SetIsResolved() const;
-  virtual bool HasResolvedTypeClass() const;
+  virtual bool HasTypeClass() const { return type_class_id() != kIllegalCid; }
   virtual classid_t type_class_id() const;
   virtual RawClass* type_class() const;
-  virtual RawUnresolvedClass* unresolved_class() const;
   virtual RawTypeArguments* arguments() const;
   virtual void set_arguments(const TypeArguments& value) const;
   virtual TokenPosition token_pos() const;
@@ -6526,7 +6492,6 @@
 
 // A Type consists of a class, possibly parameterized with type
 // arguments. Example: C<T1, T2>.
-// An unresolved class is a String specifying the class name.
 //
 // Caution: 'RawType*' denotes a 'raw' pointer to a VM object of class Type, as
 // opposed to 'Type' denoting a 'handle' to the same object. 'RawType' does not
@@ -6560,12 +6525,13 @@
     return raw_ptr()->type_state_ >= RawType::kResolved;
   }
   virtual void SetIsResolved() const;
-  virtual bool HasResolvedTypeClass() const;  // Own type class resolved.
+  virtual bool HasTypeClass() const {
+    ASSERT(type_class_id() != kIllegalCid);
+    return true;
+  }
   virtual classid_t type_class_id() const;
   virtual RawClass* type_class() const;
   void set_type_class(const Class& value) const;
-  void set_unresolved_class(const Object& value) const;
-  virtual RawUnresolvedClass* unresolved_class() const;
   virtual RawTypeArguments* arguments() const { return raw_ptr()->arguments_; }
   virtual void set_arguments(const TypeArguments& value) const;
   virtual TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
@@ -6664,7 +6630,7 @@
   // The finalized type of the given non-parameterized class.
   static RawType* NewNonParameterizedType(const Class& type_class);
 
-  static RawType* New(const Object& clazz,
+  static RawType* New(const Class& clazz,
                       const TypeArguments& arguments,
                       TokenPosition token_pos,
                       Heap::Space space = Heap::kOld);
@@ -6713,9 +6679,9 @@
     return AbstractType::Handle(type()).error();
   }
   virtual bool IsResolved() const { return true; }
-  virtual bool HasResolvedTypeClass() const {
+  virtual bool HasTypeClass() const {
     return (type() != AbstractType::null()) &&
-           AbstractType::Handle(type()).HasResolvedTypeClass();
+           AbstractType::Handle(type()).HasTypeClass();
   }
   RawAbstractType* type() const { return raw_ptr()->type_; }
   void set_type(const AbstractType& value) const;
@@ -6791,7 +6757,8 @@
   virtual bool IsMalbounded() const { return false; }
   virtual bool IsMalformedOrMalbounded() const { return false; }
   virtual bool IsResolved() const { return true; }
-  virtual bool HasResolvedTypeClass() const { return false; }
+  virtual bool HasTypeClass() const { return false; }
+  virtual classid_t type_class_id() const { return kIllegalCid; }
   classid_t parameterized_class_id() const;
   RawClass* parameterized_class() const;
   RawFunction* parameterized_function() const {
@@ -6894,8 +6861,8 @@
   virtual bool IsMalformedOrMalbounded() const;
   virtual RawLanguageError* error() const;
   virtual bool IsResolved() const { return true; }
-  virtual bool HasResolvedTypeClass() const {
-    return AbstractType::Handle(type()).HasResolvedTypeClass();
+  virtual bool HasTypeClass() const {
+    return AbstractType::Handle(type()).HasTypeClass();
   }
   virtual classid_t type_class_id() const {
     return AbstractType::Handle(type()).type_class_id();
@@ -6903,9 +6870,6 @@
   virtual RawClass* type_class() const {
     return AbstractType::Handle(type()).type_class();
   }
-  virtual RawUnresolvedClass* unresolved_class() const {
-    return AbstractType::Handle(type()).unresolved_class();
-  }
   virtual RawTypeArguments* arguments() const {
     return AbstractType::Handle(type()).arguments();
   }
@@ -6991,7 +6955,7 @@
   virtual bool IsMalbounded() const { return false; }
   virtual bool IsMalformedOrMalbounded() const { return false; }
   virtual bool IsResolved() const { return false; }
-  virtual bool HasResolvedTypeClass() const { return false; }
+  virtual bool HasTypeClass() const { return false; }
   virtual RawString* Name() const;
   virtual TokenPosition token_pos() const;
 
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 3080fe7..fe68a1b 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -173,10 +173,6 @@
   }
 }
 
-void UnresolvedClass::PrintJSONImpl(JSONStream* stream, bool ref) const {
-  Object::PrintJSONImpl(stream, ref);
-}
-
 void TypeArguments::PrintJSONImpl(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
   // The index in the canonical_type_arguments table cannot be used as part of
@@ -1106,18 +1102,14 @@
   JSONObject jsobj(stream);
   PrintSharedInstanceJSON(&jsobj, ref);
   jsobj.AddProperty("kind", "Type");
-  if (HasResolvedTypeClass()) {
-    const Class& type_cls = Class::Handle(type_class());
-    if (type_cls.CanonicalType() == raw()) {
-      intptr_t cid = type_cls.id();
-      jsobj.AddFixedServiceId("classes/%" Pd "/types/%d", cid, 0);
-    } else {
-      jsobj.AddServiceId(*this);
-    }
-    jsobj.AddProperty("typeClass", type_cls);
+  const Class& type_cls = Class::Handle(type_class());
+  if (type_cls.CanonicalType() == raw()) {
+    intptr_t cid = type_cls.id();
+    jsobj.AddFixedServiceId("classes/%" Pd "/types/%d", cid, 0);
   } else {
     jsobj.AddServiceId(*this);
   }
+  jsobj.AddProperty("typeClass", type_cls);
   const String& user_name = String::Handle(UserVisibleName());
   const String& vm_name = String::Handle(Name());
   AddNameProperties(&jsobj, user_name.ToCString(), vm_name.ToCString());
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index d423f89..3dbbd42 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -382,7 +382,6 @@
   }
 
 REGULAR_VISITOR(Class)
-REGULAR_VISITOR(UnresolvedClass)
 REGULAR_VISITOR(Bytecode)
 REGULAR_VISITOR(Type)
 REGULAR_VISITOR(TypeRef)
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 3e35ec4..a617d89 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -22,7 +22,6 @@
 // Macrobatics to define the Object hierarchy of VM implementation classes.
 #define CLASS_LIST_NO_OBJECT_NOR_STRING_NOR_ARRAY(V)                           \
   V(Class)                                                                     \
-  V(UnresolvedClass)                                                           \
   V(PatchClass)                                                                \
   V(Function)                                                                  \
   V(ClosureData)                                                               \
@@ -960,17 +959,6 @@
   friend class CidRewriteVisitor;
 };
 
-class RawUnresolvedClass : public RawObject {
-  RAW_HEAP_OBJECT_IMPLEMENTATION(UnresolvedClass);
-
-  VISIT_FROM(RawObject*, library_or_library_prefix_);
-  RawObject* library_or_library_prefix_;  // Library or library prefix qualifier
-                                          // for the ident.
-  RawString* ident_;                      // Name of the unresolved identifier.
-  VISIT_TO(RawObject*, ident_);
-  TokenPosition token_pos_;
-};
-
 class RawPatchClass : public RawObject {
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(PatchClass);
@@ -2026,8 +2014,7 @@
   RAW_HEAP_OBJECT_IMPLEMENTATION(Type);
 
   VISIT_FROM(RawObject*, type_class_id_)
-  // Either the id of the resolved class as a Smi or an UnresolvedClass.
-  RawObject* type_class_id_;
+  RawSmi* type_class_id_;
   RawTypeArguments* arguments_;
   RawSmi* hash_;
   // This type object represents a function type if its signature field is a
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 70bed6a..54806bf 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -72,50 +72,6 @@
   }
 }
 
-RawUnresolvedClass* UnresolvedClass::ReadFrom(SnapshotReader* reader,
-                                              intptr_t object_id,
-                                              intptr_t tags,
-                                              Snapshot::Kind kind,
-                                              bool as_reference) {
-  ASSERT(reader != NULL);
-
-  // Allocate unresolved class object.
-  UnresolvedClass& unresolved_class =
-      UnresolvedClass::ZoneHandle(reader->zone(), UnresolvedClass::New());
-  reader->AddBackRef(object_id, &unresolved_class, kIsDeserialized);
-
-  // Set all non object fields.
-  unresolved_class.set_token_pos(
-      TokenPosition::SnapshotDecode(reader->Read<int32_t>()));
-
-  // Set all the object fields.
-  READ_OBJECT_FIELDS(unresolved_class, unresolved_class.raw()->from(),
-                     unresolved_class.raw()->to(), kAsReference);
-
-  return unresolved_class.raw();
-}
-
-void RawUnresolvedClass::WriteTo(SnapshotWriter* writer,
-                                 intptr_t object_id,
-                                 Snapshot::Kind kind,
-                                 bool as_reference) {
-  ASSERT(writer != NULL);
-
-  // Write out the serialization header value for this object.
-  writer->WriteInlinedObjectHeader(object_id);
-
-  // Write out the class and tags information.
-  writer->WriteVMIsolateObject(kUnresolvedClassCid);
-  writer->WriteTags(writer->GetObjectTags(this));
-
-  // Write out all the non object pointer fields.
-  writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
-
-  // Write out all the object pointer fields.
-  SnapshotWriterVisitor visitor(writer, kAsReference);
-  visitor.VisitPointers(from(), to());
-}
-
 RawAbstractType* AbstractType::ReadFrom(SnapshotReader* reader,
                                         intptr_t object_id,
                                         intptr_t tags,
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index f7d4f4d..8bded02 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -90,7 +90,6 @@
 class RawTypeParameter;
 class RawTypeRef;
 class RawUnhandledException;
-class RawUnresolvedClass;
 class RawWeakProperty;
 class String;
 class TypeArguments;
@@ -479,7 +478,6 @@
   friend class TypeParameter;
   friend class TypeRef;
   friend class UnhandledException;
-  friend class UnresolvedClass;
   friend class WeakProperty;
   DISALLOW_COPY_AND_ASSIGN(SnapshotReader);
 };
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index dd25ceb..c818530 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -164,7 +164,6 @@
   V(Null, "Null")                                                              \
   V(null, "null")                                                              \
   V(Dynamic, "dynamic")                                                        \
-  V(UnresolvedClass, "UnresolvedClass")                                        \
   V(Type, "Type")                                                              \
   V(_Type, "_Type")                                                            \
   V(_TypeRef, "_TypeRef")                                                      \
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
index 2dc8029..a7a83b8 100644
--- a/runtime/vm/type_testing_stubs.cc
+++ b/runtime/vm/type_testing_stubs.cc
@@ -153,7 +153,6 @@
   }
 
   if (type.IsCanonical()) {
-    ASSERT(type.IsResolved());
     if (type.IsType()) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
       // Lazily create the type testing stubs array.
@@ -996,7 +995,7 @@
   if (type.IsTypeRef()) {
     dereferenced_type = &AbstractType::Handle(TypeRef::Cast(type).type());
   }
-  if (dereferenced_type->IsResolved() && dereferenced_type->IsFinalized()) {
+  if (dereferenced_type->IsFinalized()) {
     return assert_assignable_types_.HasKey(dereferenced_type);
   }
   return false;