Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision a83044fb86cf36e20d6c0f6fbc995d0b814fe1d7)
+++ src/AST/Convert.cpp	(revision 514a79107bae98b4aa4636858232b2de8a8a0ee3)
@@ -50,6 +50,6 @@
 		ConverterNewToOld & visitor;
 
-		template<typename U>
-		T * accept1( const ast::ptr<U> & ptr ) {
+		template<typename U, enum ast::Node::ref_type R>
+		T * accept1( const ast::ptr_base<U, R> & ptr ) {
 			if ( ! ptr ) return nullptr;
 			ptr->accept( visitor );
@@ -95,9 +95,12 @@
 
 	template<typename NewT, typename OldT>
-	NewT * cached( OldT * old ) {
-		auto it = cache.find( old );
-		// doesn't update cache, that should be handled by the accept function
-		ast::Node * nw = it == cache.end() ? getAccept1< NewT >( old ) : it->second;
-		return strict_dynamic_cast< NewT * >( nw );
+	NewT * cached( const OldT & old ) {
+		auto it = cache.find( old.get() );
+		if ( it == cache.end() ) {
+			// doesn't update cache, that should be handled by the accept function
+			return get< NewT >().accept1( old );
+		} else {
+			return strict_dynamic_cast< NewT * >( it->second );
+		}
 	}
 
@@ -797,5 +800,5 @@
 		ty->parameters = get<DeclarationWithType>().acceptL( node->params );
 		ty->forall = get<TypeDecl>().acceptL( node->forall );
-		node = ty;
+		this->node = ty;
 		return nullptr;
 	}
@@ -1679,9 +1682,20 @@
 
 	virtual void visit( TypeInstType * old ) override final {
-		auto ty = new ast::TypeInstType{
-			cached< ast::TypeDecl >( old->baseStruct ),
-			cv( old ),
-			GET_ACCEPT_V( attributes, Attribute )
-		};
+		ast::TypeInstType * ty;
+		if ( old->baseType ) {
+			ty = new ast::TypeInstType{
+				old->name,
+				cached< ast::TypeDecl >( old->baseType ),
+				cv( old ),
+				GET_ACCEPT_V( attributes, Attribute )
+			};
+		} else {
+			ty = new ast::TypeInstType{
+				old->name,
+				old->isFtype ? ast::TypeVar::Ftype : ast::TypeVar::Dtype,
+				cv( old ),
+				GET_ACCEPT_V( attributes, Attribute )
+			};
+		}
 		postvisit( old, ty );
 		this->node = ty;
Index: src/AST/Type.cpp
===================================================================
--- src/AST/Type.cpp	(revision a83044fb86cf36e20d6c0f6fbc995d0b814fe1d7)
+++ src/AST/Type.cpp	(revision 514a79107bae98b4aa4636858232b2de8a8a0ee3)
@@ -141,4 +141,10 @@
 bool EnumInstType::isComplete() const { return base ? base->body : false; }
 
+// --- TraitInstType
+
+TraitInstType::TraitInstType( const TraitDecl * b, CV::Qualifiers q,
+	std::vector<ptr<Attribute>>&& as )
+: ReferenceToType( b->name, q, std::move(as) ), base( b ) {}
+
 // --- TypeInstType
 
