Index: src/ResolvExpr/AdjustExprType.cc
===================================================================
--- src/ResolvExpr/AdjustExprType.cc	(revision aefcc3b4bc74c06dfe70a46ab130a8295ab26c3c)
+++ src/ResolvExpr/AdjustExprType.cc	(revision 23b6643f5ea88fa1b0e11583e2f0ed9315a515de)
@@ -37,4 +37,6 @@
 		virtual Type* mutate( TupleType *tupleType );
 		virtual Type* mutate( VarArgsType *varArgsType );
+		virtual Type* mutate( ZeroType *zeroType );
+		virtual Type* mutate( OneType *oneType );
 
 		const TypeEnvironment &env;
@@ -117,4 +119,12 @@
 		return varArgsType;
 	}
+
+	Type *AdjustExprType::mutate( ZeroType *zeroType ) {
+		return zeroType;
+	}
+
+	Type *AdjustExprType::mutate( OneType *oneType ) {
+		return oneType;
+	}
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision aefcc3b4bc74c06dfe70a46ab130a8295ab26c3c)
+++ src/ResolvExpr/CommonType.cc	(revision 23b6643f5ea88fa1b0e11583e2f0ed9315a515de)
@@ -39,4 +39,6 @@
 		virtual void visit( TupleType *tupleType );
 		virtual void visit( VarArgsType *varArgsType );
+		virtual void visit( ZeroType *zeroType );
+		virtual void visit( OneType *oneType );
 
 		template< typename RefType > void handleRefType( RefType *inst, Type *other );
@@ -134,9 +136,9 @@
 				result = new BasicType( basicType->get_qualifiers() + otherBasic->get_qualifiers(), newType );
 			} // if
-		} else if ( EnumInstType *enumInstType = dynamic_cast< EnumInstType * > ( type2 ) ) {
-			// use signed int in lieu of the enum type
+		} else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {
+			// use signed int in lieu of the enum/zero/one type
 			BasicType::Kind newType = combinedType[ basicType->get_kind() ][ BasicType::SignedInt ];
-			if ( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= enumInstType->get_qualifiers() ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->get_qualifiers() <= enumInstType->get_qualifiers() ) || widenSecond ) ) {
-				result = new BasicType( basicType->get_qualifiers() + enumInstType->get_qualifiers(), newType );
+			if ( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= type2->get_qualifiers() ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->get_qualifiers() <= type2->get_qualifiers() ) || widenSecond ) ) {
+				result = new BasicType( basicType->get_qualifiers() + type2->get_qualifiers(), newType );
 			} // if
 		} // if
@@ -171,4 +173,7 @@
 				otherPointer->get_base()->get_qualifiers() = tq2;
 			} // if
+		} else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) {
+			result = pointerType->clone();
+			result->get_qualifiers() += type2->get_qualifiers();
 		} // if
 	}
@@ -190,5 +195,5 @@
 
 	void CommonType::visit( EnumInstType *enumInstType ) {
-		if ( dynamic_cast< BasicType * >( type2 ) ) {
+		if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {
 			// reuse BasicType, EnumInstType code by swapping type2 with enumInstType
 			Type * temp = type2;
@@ -230,4 +235,26 @@
 	void CommonType::visit( VarArgsType *varArgsType ) {
 	}
+
+	void CommonType::visit( ZeroType *zeroType ) {
+		if ( widenFirst ) {
+			if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< PointerType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {
+				if ( widenSecond || zeroType->get_qualifiers() <= type2->get_qualifiers() ) {
+					result = type2->clone();
+					result->get_qualifiers() += zeroType->get_qualifiers();
+				}
+			}
+		}
+	}
+
+	void CommonType::visit( OneType *oneType ) {
+		if ( widenFirst ) {
+			if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {
+				if ( widenSecond || oneType->get_qualifiers() <= type2->get_qualifiers() ) {
+					result = type2->clone();
+					result->get_qualifiers() += oneType->get_qualifiers();
+				}
+			}
+		}
+	}
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision aefcc3b4bc74c06dfe70a46ab130a8295ab26c3c)
+++ src/ResolvExpr/ConversionCost.cc	(revision 23b6643f5ea88fa1b0e11583e2f0ed9315a515de)
@@ -160,5 +160,7 @@
 			// xxx - not positive this is correct, but appears to allow casting int => enum
 			cost = Cost( 1, 0, 0 );
-    } // if
+		} else if ( dynamic_cast< ZeroType* >( dest ) != nullptr || dynamic_cast< OneType* >( dest ) != nullptr ) {
+			cost = Cost( 1, 0, 0 );
+		} // if
 	}
 
@@ -175,4 +177,6 @@
 				} // if
 			} // if
+		} else if ( dynamic_cast< ZeroType* >( dest ) != nullptr || dynamic_cast< OneType* >( dest ) != nullptr ) {
+			cost = Cost( 1, 0, 0 );
 		} // if
 	}
@@ -256,4 +260,34 @@
 		}
 	}
+
+	void ConversionCost::visit(ZeroType *zeroType) {
+		if ( dynamic_cast< ZeroType* >( dest ) ) {
+			cost = Cost::zero;
+		} else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
+			// copied from visit(BasicType*) for signed int, but +1 for safe conversions
+			int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
+			if ( tableResult == -1 ) {
+				cost = Cost( 1, 0, 0 );
+			} else {
+				cost = Cost( 0, 0, tableResult + 1 );
+			}
+		} else if ( dynamic_cast< PointerType* >( dest ) ) {
+			cost = Cost( 0, 0, 1 );
+		}
+	}
+
+	void ConversionCost::visit(OneType *oneType) {
+		if ( dynamic_cast< OneType* >( dest ) ) {
+			cost = Cost::zero;
+		} else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
+			// copied from visit(BasicType*) for signed int, but +1 for safe conversions
+			int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
+			if ( tableResult == -1 ) {
+				cost = Cost( 1, 0, 0 );
+			} else {
+				cost = Cost( 0, 0, tableResult + 1 );
+			}
+		}
+	}
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/ConversionCost.h
===================================================================
--- src/ResolvExpr/ConversionCost.h	(revision aefcc3b4bc74c06dfe70a46ab130a8295ab26c3c)
+++ src/ResolvExpr/ConversionCost.h	(revision 23b6643f5ea88fa1b0e11583e2f0ed9315a515de)
@@ -41,4 +41,6 @@
 		virtual void visit(TupleType *tupleType);
 		virtual void visit(VarArgsType *varArgsType);
+		virtual void visit(ZeroType *zeroType);
+		virtual void visit(OneType *oneType);
 	  protected:
 		Type *dest;
Index: src/ResolvExpr/PtrsAssignable.cc
===================================================================
--- src/ResolvExpr/PtrsAssignable.cc	(revision aefcc3b4bc74c06dfe70a46ab130a8295ab26c3c)
+++ src/ResolvExpr/PtrsAssignable.cc	(revision 23b6643f5ea88fa1b0e11583e2f0ed9315a515de)
@@ -39,4 +39,6 @@
 		virtual void visit( TupleType *tupleType );
 		virtual void visit( VarArgsType *varArgsType );
+		virtual void visit( ZeroType *zeroType );
+		virtual void visit( OneType *oneType );
 	  private:
 		Type *dest;
@@ -141,4 +143,11 @@
 	void PtrsAssignable::visit( VarArgsType *varArgsType ) {
 	}
+
+	void PtrsAssignable::visit( ZeroType *zeroType ) {
+	}
+	
+	void PtrsAssignable::visit( OneType *oneType ) {
+	}
+	
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/PtrsCastable.cc
===================================================================
--- src/ResolvExpr/PtrsCastable.cc	(revision aefcc3b4bc74c06dfe70a46ab130a8295ab26c3c)
+++ src/ResolvExpr/PtrsCastable.cc	(revision 23b6643f5ea88fa1b0e11583e2f0ed9315a515de)
@@ -40,4 +40,6 @@
 		virtual void visit(TupleType *tupleType);
 		virtual void visit(VarArgsType *varArgsType);
+		virtual void visit(ZeroType *zeroType);
+		virtual void visit(OneType *oneType);
 	  private:
 		Type *dest;
@@ -144,4 +146,12 @@
 		result = objectCast( dest, env, indexer );
 	}
+
+	void PtrsCastable::visit(ZeroType *zeroType) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable::visit(OneType *oneType) {
+		result = objectCast( dest, env, indexer );
+	}
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/RenameVars.cc
===================================================================
--- src/ResolvExpr/RenameVars.cc	(revision aefcc3b4bc74c06dfe70a46ab130a8295ab26c3c)
+++ src/ResolvExpr/RenameVars.cc	(revision 23b6643f5ea88fa1b0e11583e2f0ed9315a515de)
@@ -110,4 +110,14 @@
 	}
 
+	void RenameVars::visit( ZeroType *zeroType ) {
+		typeBefore( zeroType );
+		typeAfter( zeroType );
+	}
+
+	void RenameVars::visit( OneType *oneType ) {
+		typeBefore( oneType );
+		typeAfter( oneType );
+	}
+
 	void RenameVars::typeBefore( Type *type ) {
 		if ( ! type->get_forall().empty() ) {
Index: src/ResolvExpr/RenameVars.h
===================================================================
--- src/ResolvExpr/RenameVars.h	(revision aefcc3b4bc74c06dfe70a46ab130a8295ab26c3c)
+++ src/ResolvExpr/RenameVars.h	(revision 23b6643f5ea88fa1b0e11583e2f0ed9315a515de)
@@ -44,4 +44,6 @@
 		virtual void visit( TupleType *tupleType );
 		virtual void visit( VarArgsType *varArgsType );
+		virtual void visit( ZeroType *zeroType );
+		virtual void visit( OneType *oneType );
 
 		void typeBefore( Type *type );
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision aefcc3b4bc74c06dfe70a46ab130a8295ab26c3c)
+++ src/ResolvExpr/Resolver.cc	(revision 23b6643f5ea88fa1b0e11583e2f0ed9315a515de)
@@ -134,4 +134,6 @@
 			} else if ( BasicType *bt = dynamic_cast< BasicType * >( type ) ) {
 				return bt->isInteger();
+			} else if ( dynamic_cast< ZeroType* >( type ) != nullptr || dynamic_cast< OneType* >( type ) != nullptr ) {
+				return true;
 			} else {
 				return false;
@@ -455,5 +457,6 @@
 			}
 		} else {
-			assert( dynamic_cast< BasicType * >( initContext ) || dynamic_cast< PointerType * >( initContext ) );
+			assert( dynamic_cast< BasicType * >( initContext ) || dynamic_cast< PointerType * >( initContext )
+			        || dynamic_cast< ZeroType * >( initContext ) || dynamic_cast< OneType * >( initContext ) );
 			// basic types are handled here
 			Visitor::visit( listInit );
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision aefcc3b4bc74c06dfe70a46ab130a8295ab26c3c)
+++ src/ResolvExpr/Unify.cc	(revision 23b6643f5ea88fa1b0e11583e2f0ed9315a515de)
@@ -60,4 +60,6 @@
 		virtual void visit(TupleType *tupleType);
 		virtual void visit(VarArgsType *varArgsType);
+		virtual void visit(ZeroType *zeroType);
+		virtual void visit(OneType *oneType);
 
 		template< typename RefType > void handleRefType( RefType *inst, Type *other );
@@ -588,4 +590,12 @@
 	}
 
+	void Unify::visit(ZeroType *zeroType) {
+		result = dynamic_cast< ZeroType* >( type2 );
+	}
+
+	void Unify::visit(OneType *oneType) {
+		result = dynamic_cast< OneType* >( type2 );
+	}
+
 	// xxx - compute once and store in the FunctionType?
 	Type * extractResultType( FunctionType * function ) {
@@ -602,5 +612,4 @@
 		}
 	}
-
 } // namespace ResolvExpr
 
