Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision 42f1279c182e0cf2f329749d809a250ef38193f3)
+++ src/SymTab/Indexer.cc	(revision d908563f67f11148f27b808eadf9cdd55d2df4e3)
@@ -74,92 +74,4 @@
 	}
 
-	void Indexer::removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const {
-		// only need to perform this step for constructors, destructors, and assignment functions
-		if ( ! CodeGen::isCtorDtorAssign( id ) ) return;
-
-		// helpful data structure to organize properties for a type
-		struct ValueType {
-			struct DeclBall { // properties for this particular decl
-				IdData decl;
-				bool isUserDefinedFunc;
-				bool isCopyFunc;
-			};
-			// properties for this type
-			bool existsUserDefinedCopyFunc = false;    // user-defined copy ctor found
-			BaseSyntaxNode * deleteStmt = nullptr;     // non-null if a user-defined function is found
-			std::list< DeclBall > decls;
-
-			// another FunctionDecl for the current type was found - determine
-			// if it has special properties and update data structure accordingly
-			ValueType & operator+=( IdData data ) {
-				DeclarationWithType * function = data.id;
-				bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->linkage );
-				bool isCopyFunc = InitTweak::isCopyFunction( function, function->name );
-				decls.push_back( DeclBall{ data, isUserDefinedFunc, isCopyFunc } );
-				existsUserDefinedCopyFunc |= (isUserDefinedFunc && isCopyFunc);
-				if ( isUserDefinedFunc && ! deleteStmt ) {
-					// any user-defined function can act as an implicit delete statement for generated constructors.
-					// a delete stmt should not act as an implicit delete statement.
-					deleteStmt = data.id;
-				}
-				return *this;
-			}
-		}; // ValueType
-
-		std::list< IdData > copy;
-		copy.splice( copy.end(), out );
-
-		// organize discovered declarations by type
-		std::unordered_map< std::string, ValueType > funcMap;
-		for ( auto decl : copy ) {
-			if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl.id ) ) {
-				std::list< DeclarationWithType * > & params = function->type->parameters;
-				assert( ! params.empty() );
-				// use base type of pointer, so that qualifiers on the pointer type aren't considered.
-				Type * base = InitTweak::getPointerBase( params.front()->get_type() );
-				assert( base );
-				funcMap[ Mangler::mangle( base ) ] += decl;
-			} else {
-				out.push_back( decl );
-			}
-		}
-
-		// if a type contains user defined ctor/dtor/assign, then special rules trigger, which 
-		// determinethe set of ctor/dtor/assign that can be used  by the requester. In particular, 
-		// if the user defines a default ctor, then the generated default ctor is unavailable, 
-		// likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 
-		// field ctors are available. If the user defines any ctor then the generated default ctor 
-		// is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 
-		// anything that looks like a copy constructor, then the generated copy constructor is 
-		// unavailable, and likewise for the assignment operator.
-		for ( std::pair< const std::string, ValueType > & pair : funcMap ) {
-			ValueType & val = pair.second;
-			for ( ValueType::DeclBall ball : val.decls ) {
-				bool isNotUserDefinedFunc = ! ball.isUserDefinedFunc && ball.decl.id->linkage != LinkageSpec::Intrinsic;
-				bool isCopyFunc = ball.isCopyFunc;
-				bool existsUserDefinedCopyFunc = val.existsUserDefinedCopyFunc;
-
-				// only implicitly delete non-user defined functions that are not intrinsic, and are
-				// not copy functions (assignment or copy constructor). If a  user-defined copy 
-				// function exists, do not pass along the non-user-defined copy functions since 
-				// signatures do not have to match, and the generated functions will often be 
-				// cheaper.
-				if ( isNotUserDefinedFunc ) {
-					if ( isCopyFunc ) {
-						// Skip over non-user-defined copy functions when there is a user-defined 
-						// copy function. Since their signatures do not have to be exact, deleting 
-						// them is the wrong choice.
-						if ( existsUserDefinedCopyFunc ) continue;
-					} else {
-						// delete non-user-defined non-copy functions if applicable.
-						// deleteStmt will be non-null only if a user-defined function is found.
-						ball.decl.deleteStmt = val.deleteStmt;
-					}
-				}
-				out.push_back( ball.decl );
-			}
-		}
-	}
-
 	Indexer::Indexer() 
 	: idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 
@@ -208,9 +120,4 @@
 			out.push_back( decl.second );
 		}
-		
-		// some special functions, e.g. constructors and destructors
-		// remove autogenerated functions when they are defined so that
-		// they can never be matched
-		removeSpecialOverrides( id, out );
 	}
 
@@ -461,7 +368,9 @@
 			// perform removals from mangle table, and deletions if necessary
 			for ( const auto& key : removed ) {
+				++*stats().map_mutations;
 				mangleTable = mangleTable->erase( key );
 			}
 			if ( ! alreadyUserDefinedFunc ) for ( const auto& entry : deleted ) {
+				++*stats().map_mutations;
 				mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } );
 			}
@@ -493,4 +402,5 @@
 			// this needs to be a separate loop because of iterator invalidation
 			for ( const auto& entry : deleted ) {
+				++*stats().map_mutations;
 				mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } );
 			}
@@ -592,4 +502,5 @@
 		lazyInitScope();
 		IdData data{ decl, baseExpr, deleteStmt, scope };
+		// Ensure that auto-generated ctor/dtor/assignment are deleted if necessary
 		if ( ! removeSpecialOverrides( data, mangleTable ) ) return;
 		*stats().map_mutations += 2;
