Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision 0b3b2ae5a0f1b9ef532505a8bdba40cf680091db)
+++ src/SymTab/Indexer.cc	(revision ed34540b9dafc248ba846075be2285b7a964866a)
@@ -272,4 +272,8 @@
 	}
 
+	NamedTypeDecl *Indexer::globalLookupType( const std::string &id ) const {
+		return lookupTypeAtScope( id, 0 );
+	}
+
 	StructDecl *Indexer::globalLookupStruct( const std::string &id ) const {
 		return lookupStructAtScope( id, 0 );
@@ -503,11 +507,17 @@
 
 	bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) {
-		if ( existing->get_base() == 0 ) {
+		if ( existing->base == nullptr ) {
 			return false;
-		} else if ( added->get_base() == 0 ) {
+		} else if ( added->base == nullptr ) {
 			return true;
 		} else {
-			SemanticError( added, "redeclaration of " );
-		}
+			assert( existing->base && added->base );
+			// typedef redeclarations are errors only if types are different
+			if ( ! ResolvExpr::typesCompatible( existing->base, added->base, Indexer() ) ) {
+				SemanticError( added->location, "redeclaration of " + added->name );
+			}
+		}
+		// does not need to be added to the table if both existing and added have a base that are the same
+		return true;
 	}
 
Index: src/SymTab/Indexer.h
===================================================================
--- src/SymTab/Indexer.h	(revision 0b3b2ae5a0f1b9ef532505a8bdba40cf680091db)
+++ src/SymTab/Indexer.h	(revision ed34540b9dafc248ba846075be2285b7a964866a)
@@ -71,4 +71,6 @@
 		TraitDecl *lookupTrait( const std::string &id ) const;
 
+		/// Gets the type declaration with the given ID at global scope
+		NamedTypeDecl *globalLookupType( const std::string &id ) const;
 		/// Gets the struct declaration with the given ID at global scope
 		StructDecl *globalLookupStruct( const std::string &id ) const;
