diff dmd/Type.d @ 98:5c859d5fbe27

and more
author Trass3r
date Tue, 31 Aug 2010 03:53:49 +0200
parents ae5b11064a9a
children 12c0c84d13fd
line wrap: on
line diff
--- a/dmd/Type.d	Tue Aug 31 02:12:15 2010 +0200
+++ b/dmd/Type.d	Tue Aug 31 03:53:49 2010 +0200
@@ -397,6 +397,7 @@
     DYNCAST dyncast() { return DYNCAST.DYNCAST_TYPE; } // kludge for template.isType()
 
 	/*******************************
+	 * Covariant means that 'this' can substitute for 't'.
 	 * Returns:
 	 *	0	types are distinct
 	 *	1	this is covariant with t
@@ -446,6 +447,7 @@
 				{
 ///static if (false) {
 ///				// turn on this for contravariant argument types, see bugzilla 3075
+///				// BUG: cannot convert ref to const to ref to immutable
 ///				// We can add const, but not subtract it
 ///				if (arg2.type.implicitConvTo(arg1.type) < MATCH.MATCHconst)
 ///}
@@ -649,6 +651,7 @@
 		basic[TY.Terror] = basic[TY.Tint32];
 
 		tvoidptr = tvoid.pointerTo();
+		tstring = tchar.invariantOf().arrayOf();
 
 		if (global.params.isX86_64) {
 			PTRSIZE = 8;
@@ -946,21 +949,6 @@
 	 */
 	Type constOf()
 	{
-static if (false) {
-		//printf("Type.constOf() %p %s\n", this, toChars());
-		if (isConst())
-			return this;
-		if (cto)
-			return cto;
-		Type t = makeConst();
-		t = t.merge();
-		cto = t;
-		if (ito)
-			ito.cto = t;
-		//if (t.nextOf()) assert(t.nextOf().isConst());
-		//printf("-Type.constOf() %p %s\n", t, toChars());
-		return t;
-} else {
 		//printf("Type.constOf() %p %s\n", this, toChars());
 		if (mod == MOD.MODconst)
 			return this;
@@ -974,7 +962,6 @@
 		t.fixTo(this);
 		//printf("-Type.constOf() %p %s\n", t, toChars());
 		return t;
-}
 	}
 
 	/********************************
@@ -982,32 +969,6 @@
 	 */
     Type invariantOf()
 	{	
-static if (false) {
-		//printf("Type.invariantOf() %p %s\n", this, toChars());
-		if (isInvariant())
-		{
-			return this;
-		}
-		if (ito)
-		{
-			//if (!ito.isInvariant()) printf("\tito is %p %s\n", ito, ito.toChars());
-			assert(ito.isInvariant());
-			return ito;
-		}
-		Type t = makeInvariant();
-		t = t.merge();
-		ito = t;
-		if (cto)
-			cto.ito = t;
-static if (false) {// fails for function types
-		if (t.nextOf() && !t.nextOf().isInvariant())
-		{
-			assert(0);
-		}
-}
-		//printf("\t%p\n", t);
-		return t;
-} else {
 		//printf("Type.invariantOf() %p %s\n", this, toChars());
 		if (isInvariant())
 		{
@@ -1023,60 +984,10 @@
 		t.fixTo(this);
 		//printf("\t%p\n", t);
 		return t;
-}
 	}
 
     Type mutableOf()
 	{
-	static if (false) {
-		//printf("Type.mutableOf() %p, %s\n", this, toChars());
-		Type t = this;
-		if (isConst())
-		{	
-			t = cto;
-			assert(!t || t.isMutable());
-		}
-		else if (isInvariant())
-		{	
-			t = ito;
-			assert(!t || t.isMutable());
-		}
-		if (!t)
-		{
-			uint sz = this.classinfo.init.length;
-			t = cast(Type)GC.malloc(sz);
-			memcpy(cast(void*)t, cast(void*)this, sz);
-			t.mod = 0;
-			t.deco = null;
-			t.arrayof = null;
-			t.pto = null;
-			t.rto = null;
-			t.cto = null;
-			t.ito = null;
-			t.sto = null;
-			t.scto = null;
-			t.vtinfo = null;
-			if (ty == Tsarray)
-			{   
-				TypeSArray ta = cast(TypeSArray)t;
-				//ta.next = ta.next.mutableOf();
-			}
-			t = t.merge();
-			if (isConst())
-			{   cto = t;
-				t.cto = this;
-				if (ito)
-					ito.cto = this;
-			}
-			else if (isInvariant())
-			{   ito = t;
-				t.ito = this;
-				if (cto)
-					cto.ito = this;
-			}
-		}
-		return t;
-	} else {
 		//printf("Type.mutableOf() %p, %s\n", this, toChars());
 		Type t = this;
 		if (isConst())
@@ -1097,7 +1008,7 @@
 			uint sz = this.classinfo.init.length;
 			t = cast(Type)GC.malloc(sz);
 			memcpy(cast(void*)t, cast(void*)this, sz);
-			t.mod = MODundefined;
+			t.mod = mod & MODshared;
 			t.deco = null;
 			t.arrayof = null;
 			t.pto = null;
@@ -1121,10 +1032,6 @@
 					t.ito = this;
 					break;
 
-				case MODshared:
-					t.sto = this;
-					break;
-
 				case MODshared | MODconst:
 					t.scto = this;
 					break;
@@ -1135,7 +1042,6 @@
 		}
 		return t;
 	}
-	}
 
     Type sharedOf()
 	{
@@ -1178,7 +1084,61 @@
 
 		return t;
 	}
+
+	/********************************
+	 * Make type unshared.
+	 */
+	Type unSharedOf()
+	{
+		//writef("Type::unSharedOf() %p, %s\n", this, toChars());
+		Type t = this;
+
+		if (isShared())
+		{
+			if (isConst())
+				t = cto;	// shared const => const
+			else
+				t = sto;
+			assert(!t || !t.isShared());
+		}
+
+		if (!t)
+		{
+			uint sz = this.classinfo.init.length;
+			t = cast(Type)GC.malloc(sz);
+			memcpy(cast(void*)t, cast(void*)this, sz);
+			t.mod = mod & ~MODshared;
+			t.deco = null;
+			t.arrayof = null;
+			t.pto = null;
+			t.rto = null;
+			t.cto = null;
+			t.ito = null;
+			t.sto = null;
+			t.scto = null;
+			t.vtinfo = null;
+			t = t.merge();
 	
+			t.fixTo(this);
+	
+			switch (mod)
+			{
+				case MODshared:
+				t.sto = this;
+				break;
+	
+				case MODshared | MODconst:
+				t.scto = this;
+				break;
+	
+				default:
+				assert(0);
+			}
+		}
+		assert(!t.isShared());
+		return t;
+	}
+
 	static uint X(MOD m, MOD n)
 	{
 		return (((m) << 3) | (n));
@@ -1906,7 +1866,8 @@
 	 */
     MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes)
 	{
-	static if (false) {
+	static if (false)
+	{
 		printf("Type.deduceType()\n");
 		printf("\tthis   = %d, ", ty); print();
 		printf("\ttparam = %d, ", tparam.ty); tparam.print();
@@ -1951,42 +1912,94 @@
 			Type tt = this;
 			Type at = cast(Type)dedtypes.data[i];
 
-			// 3*3 == 9 cases
-			if (tparam.isMutable())
-			{   // foo(U:U) T            => T
-				// foo(U:U) const(T)     => const(T)
-				// foo(U:U) invariant(T) => invariant(T)
+			// 5*5 == 25 cases
+			static pure int X(int U, int T) { return ((U << 3) | T); }
+			
+			switch (X(tparam.mod, mod))
+			{
+				case X(0, 0):
+				case X(0, MODconst):
+				case X(0, MODinvariant):
+				case X(0, MODshared):
+				case X(0, MODconst | MODshared):
+				// foo(U:U) T  							=> T
+				// foo(U:U) const(T)					=> const(T)
+				// foo(U:U) immutable(T)				=> immutable(T)
+				// foo(U:U) shared(T)					=> shared(T)
+				// foo(U:U) const(shared(T))			=> const(shared(T))
 				if (!at)
-				{   
-					dedtypes.data[i] = cast(void*)this;
+				{   dedtypes.data[i] = cast(void *)tt;
 					goto Lexact;
 				}
-			}
-			else if (mod == tparam.mod)
-			{   // foo(U:const(U))     const(T)     => T
-				// foo(U:invariant(U)) invariant(T) => T
+				break;
+
+				case X(MODconst, MODconst):
+				case X(MODinvariant, MODinvariant):
+				case X(MODshared, MODshared):
+				case X(MODconst | MODshared, MODconst | MODshared):
+				// foo(U:const(U))			const(T)		=> T
+				// foo(U:immutable(U))		immutable(T)	=> T
+				// foo(U:shared(U))			shared(T)		=> T
+				// foo(U:const(shared(U))	const(shared(T))=> T
+				tt = mutableOf().unSharedOf();
+				if (!at)
+				{   dedtypes.data[i] = cast(void *)tt;
+					goto Lexact;
+				}
+				break;
+
+				case X(MODconst, 0):
+				case X(MODconst, MODimmutable):
+				case X(MODconst, MODconst | MODshared):
+				case X(MODconst | MODshared, MODimmutable):
+				// foo(U:const(U))			T					=> T
+				// foo(U:const(U))			immutable(T)		=> T
+				// foo(U:const(U))			const(shared(T))	=> shared(T)
+				// foo(U:const(shared(U))	immutable(T)		=> T
 				tt = mutableOf();
 				if (!at)
-				{   
-					dedtypes.data[i] = cast(void*)tt;
-					goto Lexact;
+				{   dedtypes.data[i] = cast(void *)tt;
+					goto Lconst;
 				}
-			}
-			else if (tparam.isConst())
-			{   // foo(U:const(U)) T            => T
-				// foo(U:const(U)) invariant(T) => T
-				tt = mutableOf();
+				break;
+
+				case X(MODshared, MODconst | MODshared):
+				case X(MODconst | MODshared, MODshared):
+				// foo(U:shared(U))			const(shared(T))	=> const(T)
+				// foo(U:const(shared(U))	shared(T)			=> T
+				tt = unSharedOf();
 				if (!at)
-				{   
-					dedtypes.data[i] = cast(void*)tt;
+				{   dedtypes.data[i] = cast(void *)tt;
 					goto Lconst;
 				}
-			}
-			else
-			{   // foo(U:invariant(U)) T        => nomatch
-				// foo(U:invariant(U)) const(T) => nomatch
-				if (!at)
+				break;
+
+				case X(MODimmutable,		 0):
+				case X(MODimmutable,		 MODconst):
+				case X(MODimmutable,		 MODshared):
+				case X(MODimmutable,		 MODconst | MODshared):
+				case X(MODconst,			 MODshared):
+				case X(MODshared,			0):
+				case X(MODshared,			MODconst):
+				case X(MODshared,			MODimmutable):
+				case X(MODconst | MODshared, 0):
+				case X(MODconst | MODshared, MODconst):
+				// foo(U:immutable(U)) T				   => nomatch
+				// foo(U:immutable(U)) const(T)			=> nomatch
+				// foo(U:immutable(U)) shared(T)		   => nomatch
+				// foo(U:immutable(U)) const(shared(T))	=> nomatch
+				// foo(U:const(U)) shared(T)			   => nomatch
+				// foo(U:shared(U)) T					  => nomatch
+				// foo(U:shared(U)) const(T)			   => nomatch
+				// foo(U:shared(U)) immutable(T)		   => nomatch
+				// foo(U:const(shared(U)) T				=> nomatch
+				// foo(U:const(shared(U)) const(T)		 => nomatch
+				//if (!at)
 					goto Lnomatch;
+				break;
+
+				default:
+				assert(0);
 			}
 
 			if (tt.equals(at))
@@ -2272,7 +2285,10 @@
 		case TY.Tpointer:	t = TYM.TYnptr;	break;
 		case TY.Tdelegate:	t = TYM.TYdelegate;	break;
 		case TY.Tarray:	t = TYM.TYdarray;	break;
-		case TY.Tsarray:	t = TYM.TYarray;	break;
+version(SARRAYVALUE)
+{		case TY.Tsarray:	t = TYstruct;	break;}
+else
+{		case TY.Tsarray:	t = TYM.TYarray;	break;}
 		case TY.Tstruct:	t = TYM.TYstruct;	break;
 
 		case TY.Tenum:
@@ -2485,7 +2501,8 @@
 	}
 	
     static Type tvoidptr;		// void*
-    
+    static Type tstring;		// immutable(char)[]
+
 	static Type terror()
 	{
 		return basic[TY.Terror];	// for error recovery