Index: src/Virtual/ExpandCasts.cc
===================================================================
--- src/Virtual/ExpandCasts.cc	(revision 8e6214fd05b409573f38728c086bcfa67dcfb76f)
+++ src/Virtual/ExpandCasts.cc	(revision aabb8468c120ebc4454ffa322b8210f1bc72774b)
@@ -10,6 +10,6 @@
 // Created On       : Mon Jul 24 13:59:00 2017
 // Last Modified By : Andrew Beach
-// Last Modified On : Tus Aug  2 14:59:00 2017
-// Update Count     : 1
+// Last Modified On : Tue May 26 14:37:00 2020
+// Update Count     : 2
 //
 
@@ -111,4 +111,17 @@
 	}
 
+	// Better error locations for generated casts.
+	static CodeLocation castLocation( VirtualCastExpr * castExpr ) {
+		if ( castExpr->location.isSet() ) {
+			return castExpr->location;
+		} else if ( castExpr->arg->location.isSet() ) {
+			return castExpr->arg->location;
+		} else if ( castExpr->result->location.isSet() ) {
+			return castExpr->result->location;
+		} else {
+			return CodeLocation();
+		}
+	}
+
 	Expression * VirtualCastCore::postmutate( VirtualCastExpr * castExpr ) {
 		assertf( castExpr->get_result(), "Virtual Cast target not found before expansion." );
@@ -117,34 +130,32 @@
 		assert( pvt_decl );
 
-		// May only cast to a pointer or reference type.
-		// A earlier validation should give a syntax error, this is
-		// just to make sure errors don't creep during translation.
-		// Move to helper with more detailed error messages.
-		PointerType * target_type =
-			dynamic_cast<PointerType *>( castExpr->get_result() );
-		assert( target_type );
+		// Get the base type of the pointer/reference.
+		Type * base;
+		Type * result_type = castExpr->result;
+		if ( PointerType * target = dynamic_cast<PointerType *>( result_type ) ) {
+			base = target->base;
+		} else if ( ReferenceType * target = dynamic_cast<ReferenceType *>( result_type ) ) {
+			base = target->base;
+		} else {
+			SemanticError( castLocation( castExpr ),
+				"Virtual cast type must be a pointer or reference type." );
+		}
 
-		StructInstType * target_struct =
-			dynamic_cast<StructInstType *>( target_type->get_base() );
-		assert( target_struct );
-
+		StructInstType * target_struct = dynamic_cast<StructInstType *>( base );
+		if ( nullptr == target_struct ) {
+			SemanticError( castLocation( castExpr ),
+				"Virtual cast type must refer to a structure type." );
+		}
 		StructDecl * target_decl = target_struct->get_baseStruct();
 
 		std::map<std::string, ObjectDecl *>::iterator found =
-			vtable_instances.find(
-				get_vtable_inst_name( target_decl->get_name() ) );
+			vtable_instances.find( get_vtable_inst_name( target_decl->get_name() ) );
 		if ( vtable_instances.end() == found ) {
-			assertf( false, "virtual table instance not found." );
+			SemanticError( castLocation( castExpr ),
+				"Virtual cast type does not have a virtual table instance." );
 		}
 		ObjectDecl * table = found->second;
 
 		Expression * result = new CastExpr(
-			//new ApplicationExpr(
-				//new AddressExpr( new VariableExpr( vcast_decl ) ),
-				//new CastExpr( new VariableExpr( vcast_decl ),
-				//	new PointerType( noQualifiers,
-				//		vcast_decl->get_type()->clone()
-				//		)
-				//	),
 			new ApplicationExpr( VariableExpr::functionPointer( vcast_decl ), {
 					new CastExpr(
