changeset 51:b7d29f613539

StaticAssertStatement.syntaxCopy IfStatement.syntaxCopy CompoundDeclarationStatement.syntaxCopy VoidInitializer.syntaxCopy TypeAArray.syntaxCopy TypeTypeof.syntaxCopy TypeAArray.resolve TypeSArray.deduceType TypeAArray.deduceType TypeAArray.implicitConvTo TemplateDeclaration.leastAsSpecialized TemplateTypeParameter.dummyArg TypeIdentifier.deduceType TemplateTypeParameter.syntaxCopy Lexer.hexStringConstant Lexer.delimitedStringConstant GotoDefaultStatement.ctor CaseRangeStatement.ctor Type.castMod StorageClassDeclaration.syntaxCopy TemplateDeclaration.syntaxCopy
author korDen
date Sat, 21 Aug 2010 11:17:42 +0400
parents adf6f7f216ea
children 69d078c417c6
files dmd/CaseRangeStatement.d dmd/CompoundDeclarationStatement.d dmd/GotoDefaultStatement.d dmd/IfStatement.d dmd/Lexer.d dmd/StaticAssertStatement.d dmd/StorageClassDeclaration.d dmd/StructInitializer.d dmd/TemplateDeclaration.d dmd/TemplateTypeParameter.d dmd/Type.d dmd/TypeAArray.d dmd/TypeIdentifier.d dmd/TypeSArray.d dmd/TypeTypeof.d dmd/VoidInitializer.d
diffstat 16 files changed, 601 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/CaseRangeStatement.d	Sat Aug 21 10:38:26 2010 +0400
+++ b/dmd/CaseRangeStatement.d	Sat Aug 21 11:17:42 2010 +0400
@@ -16,8 +16,10 @@
 
     this(Loc loc, Expression first, Expression last, Statement s)
 	{
-		assert(false);
 		super(loc);
+		this.first = first;
+		this.last = last;
+		this.statement = s;
 	}
 	
     Statement syntaxCopy()
--- a/dmd/CompoundDeclarationStatement.d	Sat Aug 21 10:38:26 2010 +0400
+++ b/dmd/CompoundDeclarationStatement.d	Sat Aug 21 11:17:42 2010 +0400
@@ -17,7 +17,17 @@
 	
     Statement syntaxCopy()
 	{
-		assert(false);
+		Statements a = new Statements();
+		a.setDim(statements.dim);
+		for (size_t i = 0; i < statements.dim; i++)
+		{	
+			Statement s = cast(Statement)statements.data[i];
+			if (s)
+				s = s.syntaxCopy();
+			a.data[i] = cast(void*)s;
+		}
+		CompoundDeclarationStatement cs = new CompoundDeclarationStatement(loc, a);
+		return cs;
 	}
 	
     void toCBuffer(OutBuffer buf, HdrGenState* hgs)
--- a/dmd/GotoDefaultStatement.d	Sat Aug 21 10:38:26 2010 +0400
+++ b/dmd/GotoDefaultStatement.d	Sat Aug 21 11:17:42 2010 +0400
@@ -17,8 +17,8 @@
 
     this(Loc loc)
 	{
-		assert(false);
 		super(loc);
+		sw = null;
 	}
 
     Statement syntaxCopy()
--- a/dmd/IfStatement.d	Sat Aug 21 10:38:26 2010 +0400
+++ b/dmd/IfStatement.d	Sat Aug 21 11:17:42 2010 +0400
@@ -49,7 +49,17 @@
 		
     Statement syntaxCopy()
 	{
-		assert(false);
+		Statement i = null;
+		if (ifbody)
+			i = ifbody.syntaxCopy();
+
+		Statement e = null;
+		if (elsebody)
+			e = elsebody.syntaxCopy();
+
+		Argument a = arg ? arg.syntaxCopy() : null;
+		IfStatement s = new IfStatement(loc, a, condition.syntaxCopy(), i, e);
+		return s;
 	}
 	
     Statement semantic(Scope sc)
--- a/dmd/Lexer.d	Sat Aug 21 10:38:26 2010 +0400
+++ b/dmd/Lexer.d	Sat Aug 21 11:17:42 2010 +0400
@@ -1622,15 +1622,256 @@
 		assert(false);
 	}
 
+	/**************************************
+	 * Lex hex strings:
+	 *	x"0A ae 34FE BD"
+	 */
     TOK hexStringConstant(Token* t)
 	{
-		assert(false);
+		uint c;
+		Loc start = loc;
+		uint n = 0;
+		uint v;
+
+		p++;
+		stringbuffer.reset();
+		while (1)
+			{
+			c = *p++;
+			switch (c)
+			{
+				case ' ':
+				case '\t':
+				case '\v':
+				case '\f':
+					continue;			// skip white space
+
+				case '\r':
+					if (*p == '\n')
+						continue;			// ignore
+				// Treat isolated '\r' as if it were a '\n'
+				case '\n':
+					loc.linnum++;
+					continue;
+
+				case 0:
+				case 0x1A:
+					error("unterminated string constant starting at %s", start.toChars());
+					t.ustring = "".ptr;
+					t.len = 0;
+					t.postfix = 0;
+					return TOKstring;
+
+				case '"':
+					if (n & 1)
+					{   
+						error("odd number (%d) of hex characters in hex string", n);
+						stringbuffer.writeByte(v);
+					}
+					t.len = stringbuffer.offset;
+					stringbuffer.writeByte(0);
+					void* mem = malloc(stringbuffer.offset);
+					memcpy(mem, stringbuffer.data, stringbuffer.offset);
+					t.ustring = cast(const(char)*)mem;
+					stringPostfix(t);
+					return TOKstring;
+
+			default:
+				if (c >= '0' && c <= '9')
+					c -= '0';
+				else if (c >= 'a' && c <= 'f')
+					c -= 'a' - 10;
+				else if (c >= 'A' && c <= 'F')
+					c -= 'A' - 10;
+				else if (c & 0x80)
+				{   p--;
+					uint u = decodeUTF();
+					p++;
+					if (u == PS || u == LS)
+					loc.linnum++;
+					else
+					error("non-hex character \\u%x", u);
+				}
+				else
+					error("non-hex character '%c'", c);
+				if (n & 1)
+				{   v = (v << 4) | c;
+					stringbuffer.writeByte(v);
+				}
+				else
+					v = c;
+				n++;
+				break;
+			}
+		}
 	}
 
 version (DMDV2) {
+	/**************************************
+	 * Lex delimited strings:
+	 *	q"(foo(xxx))"   // "foo(xxx)"
+	 *	q"[foo(]"       // "foo("
+	 *	q"/foo]/"       // "foo]"
+	 *	q"HERE
+	 *	foo
+	 *	HERE"		// "foo\n"
+	 * Input:
+	 *	p is on the "
+	 */
     TOK delimitedStringConstant(Token* t)
 	{
-		assert(false);
+		uint c;
+		Loc start = loc;
+		uint delimleft = 0;
+		uint delimright = 0;
+		uint nest = 1;
+		uint nestcount;
+		Identifier hereid = null;
+		uint blankrol = 0;
+		uint startline = 0;
+
+		p++;
+		stringbuffer.reset();
+		while (1)
+		{
+			c = *p++;
+			//printf("c = '%c'\n", c);
+			switch (c)
+			{
+				case '\n':
+					Lnextline:
+					loc.linnum++;
+					startline = 1;
+					if (blankrol)
+					{   blankrol = 0;
+						continue;
+					}
+					if (hereid)
+					{
+						stringbuffer.writeUTF8(c);
+						continue;
+					}
+					break;
+
+				case '\r':
+					if (*p == '\n')
+						continue;	// ignore
+					c = '\n';	// treat EndOfLine as \n character
+					goto Lnextline;
+
+				case 0:
+				case 0x1A:
+					goto Lerror;
+
+				default:
+					if (c & 0x80)
+					{   p--;
+						c = decodeUTF();
+						p++;
+						if (c == PS || c == LS)
+						goto Lnextline;
+					}
+					break;
+			}
+			if (delimleft == 0)
+			{   
+				delimleft = c;
+				nest = 1;
+				nestcount = 1;
+				if (c == '(')
+					delimright = ')';
+				else if (c == '{')
+					delimright = '}';
+				else if (c == '[')
+					delimright = ']';
+				else if (c == '<')
+					delimright = '>';
+				else if (isalpha(c) || c == '_' || (c >= 0x80 && isUniAlpha(c)))
+				{	
+					// Start of identifier; must be a heredoc
+					Token t2;
+					p--;
+					scan(&t2);		// read in heredoc identifier
+					if (t2.value != TOKidentifier)
+					{   
+						error("identifier expected for heredoc, not %s", t2.toChars());
+						delimright = c;
+					}
+					else
+					{   
+						hereid = t2.ident;
+						//printf("hereid = '%s'\n", hereid.toChars());
+						blankrol = 1;
+					}
+					nest = 0;
+				}
+				else
+				{	
+					delimright = c;
+					nest = 0;
+					if (isspace(c))
+						error("delimiter cannot be whitespace");
+				}
+			}
+			else
+			{
+				if (blankrol)
+				{	
+					error("heredoc rest of line should be blank");
+					blankrol = 0;
+					continue;
+				}
+				if (nest == 1)
+				{
+					if (c == delimleft)
+						nestcount++;
+					else if (c == delimright)
+					{   nestcount--;
+						if (nestcount == 0)
+						goto Ldone;
+					}
+				}
+				else if (c == delimright)
+					goto Ldone;
+				if (startline && isalpha(c) && hereid)
+				{	
+					Token t2;
+					ubyte* psave = p;
+					p--;
+					scan(&t2);		// read in possible heredoc identifier
+					//printf("endid = '%s'\n", t2.ident.toChars());
+					if (t2.value == TOKidentifier && t2.ident.equals(hereid))
+					{   
+						/* should check that rest of line is blank
+						 */
+						goto Ldone;
+					}
+					p = psave;
+				}
+				stringbuffer.writeUTF8(c);
+				startline = 0;
+			}
+		}
+
+	Ldone:
+		if (*p == '"')
+			p++;
+		else
+			error("delimited string must end in %c\"", delimright);
+		t.len = stringbuffer.offset;
+		stringbuffer.writeByte(0);
+		void* mem = malloc(stringbuffer.offset);
+		memcpy(mem, stringbuffer.data, stringbuffer.offset);
+		t.ustring = cast(const(char)*)mem;
+		stringPostfix(t);
+		return TOKstring;
+
+	Lerror:
+		error("unterminated string constant starting at %s", start.toChars());
+		t.ustring = "".ptr;
+		t.len = 0;
+		t.postfix = 0;
+		return TOKstring;
 	}
 
 	/**************************************
--- a/dmd/StaticAssertStatement.d	Sat Aug 21 10:38:26 2010 +0400
+++ b/dmd/StaticAssertStatement.d	Sat Aug 21 11:17:42 2010 +0400
@@ -19,7 +19,8 @@
 	
     Statement syntaxCopy()
 	{
-		assert(false);
+		StaticAssertStatement s = new StaticAssertStatement(cast(StaticAssert)sa.syntaxCopy(null));
+		return s;
 	}
 	
     Statement semantic(Scope sc)
--- a/dmd/StorageClassDeclaration.d	Sat Aug 21 10:38:26 2010 +0400
+++ b/dmd/StorageClassDeclaration.d	Sat Aug 21 11:17:42 2010 +0400
@@ -23,7 +23,11 @@
 	
     Dsymbol syntaxCopy(Dsymbol s)
 	{
-		assert(false);
+		StorageClassDeclaration scd;
+
+		assert(!s);
+		scd = new StorageClassDeclaration(stc, Dsymbol.arraySyntaxCopy(decl));
+		return scd;
 	}
 	
     void setScope(Scope sc)
--- a/dmd/StructInitializer.d	Sat Aug 21 10:38:26 2010 +0400
+++ b/dmd/StructInitializer.d	Sat Aug 21 11:17:42 2010 +0400
@@ -41,6 +41,8 @@
 		
 		field = new Identifiers();
 		value = new Initializers();
+		
+		vars = new Array();
 	}
 	
     Initializer syntaxCopy()
--- a/dmd/TemplateDeclaration.d	Sat Aug 21 10:38:26 2010 +0400
+++ b/dmd/TemplateDeclaration.d	Sat Aug 21 11:17:42 2010 +0400
@@ -151,7 +151,29 @@
 
     Dsymbol syntaxCopy(Dsymbol)
 	{
-		assert(false);
+		//printf("TemplateDeclaration.syntaxCopy()\n");
+		TemplateDeclaration td;
+		TemplateParameters p;
+		Array d;
+
+		p = null;
+		if (parameters)
+		{
+			p = new TemplateParameters();
+			p.setDim(parameters.dim);
+			for (int i = 0; i < p.dim; i++)
+			{   
+				TemplateParameter tp = cast(TemplateParameter)parameters.data[i];
+				p.data[i] = cast(void*)tp.syntaxCopy();
+			}
+		}
+		
+		Expression e = null;
+		if (constraint)
+			e = constraint.syntaxCopy();
+		d = Dsymbol.arraySyntaxCopy(members);
+		td = new TemplateDeclaration(loc, ident, p, e, d);
+		return td;
 	}
 
     void semantic(Scope sc)
@@ -514,9 +536,67 @@
 		return m;
 	}
 	
+	/********************************************
+	 * Determine partial specialization order of 'this' vs td2.
+	 * Returns:
+	 *	match	this is at least as specialized as td2
+	 *	0	td2 is more specialized than this
+	 */
     MATCH leastAsSpecialized(TemplateDeclaration td2)
 	{
-		assert(false);
+	    /* This works by taking the template parameters to this template
+		 * declaration and feeding them to td2 as if it were a template
+		 * instance.
+		 * If it works, then this template is at least as specialized
+		 * as td2.
+		 */
+
+		scope TemplateInstance ti = new TemplateInstance(Loc(0), ident);	// create dummy template instance
+		scope Objects dedtypes = new Objects();
+
+version (LOG_LEASTAS) {
+		printf("%s.leastAsSpecialized(%s)\n", toChars(), td2.toChars());
+}
+
+		// Set type arguments to dummy template instance to be types
+		// generated from the parameters to this template declaration
+		ti.tiargs = new Objects();
+		ti.tiargs.setDim(parameters.dim);
+		for (int i = 0; i < ti.tiargs.dim; i++)
+		{
+			TemplateParameter tp = cast(TemplateParameter)parameters.data[i];
+
+			void* p = tp.dummyArg();
+			if (p)
+				ti.tiargs.data[i] = p;
+			else
+				ti.tiargs.setDim(i);
+		}
+
+		// Temporary Array to hold deduced types
+		//dedtypes.setDim(parameters.dim);
+		dedtypes.setDim(td2.parameters.dim);
+
+		// Attempt a type deduction
+		MATCH m = td2.matchWithInstance(ti, dedtypes, 1);
+		if (m)
+		{
+			/* A non-variadic template is more specialized than a
+			 * variadic one.
+			 */
+			if (isVariadic() && !td2.isVariadic())
+				goto L1;
+
+version (LOG_LEASTAS) {
+			printf("  matches %d, so is least as specialized\n", m);
+}
+			return m;
+		}
+	  L1:
+version (LOG_LEASTAS) {
+		printf("  doesn't match, so is not as specialized\n");
+}
+		return MATCHnomatch;
 	}
 
 	/*************************************************
--- a/dmd/TemplateTypeParameter.d	Sat Aug 21 10:38:26 2010 +0400
+++ b/dmd/TemplateTypeParameter.d	Sat Aug 21 11:17:42 2010 +0400
@@ -38,7 +38,12 @@
 	
     TemplateParameter syntaxCopy()
 	{
-		assert(false);
+		TemplateTypeParameter tp = new TemplateTypeParameter(loc, ident, specType, defaultType);
+		if (tp.specType)
+			tp.specType = specType.syntaxCopy();
+		if (defaultType)
+			tp.defaultType = defaultType.syntaxCopy();
+		return tp;
 	}
 	
     void declareParameter(Scope sc)
@@ -210,6 +215,15 @@
 	
     void* dummyArg()
 	{
-		assert(false);
+		Type t;
+
+		if (specType)
+			t = specType;
+		else
+		{   
+			// Use this for alias-parameter's too (?)
+			t = new TypeIdentifier(loc, ident);
+		}
+		return cast(void *)t;
 	}
 }
\ No newline at end of file
--- a/dmd/Type.d	Sat Aug 21 10:38:26 2010 +0400
+++ b/dmd/Type.d	Sat Aug 21 11:17:42 2010 +0400
@@ -1373,9 +1373,39 @@
 		}
 	}
 
+	/************************************
+	 * Apply MODxxxx bits to existing type.
+	 */
     Type castMod(uint mod)
 	{
-		assert(false);
+		Type t;
+
+		switch (mod)
+		{
+		case 0:
+			t = mutableOf();
+			break;
+
+		case MODconst:
+			t = constOf();
+			break;
+
+		case MODinvariant:
+			t = invariantOf();
+			break;
+
+		case MODshared:
+			t = sharedOf();
+			break;
+
+		case MODshared | MODconst:
+			t = sharedConstOf();
+			break;
+
+		default:
+			assert(0);
+		}
+		return t;
 	}
 	
 	/************************************
--- a/dmd/TypeAArray.d	Sat Aug 21 10:38:26 2010 +0400
+++ b/dmd/TypeAArray.d	Sat Aug 21 11:17:42 2010 +0400
@@ -49,7 +49,16 @@
 	
     Type syntaxCopy()
 	{
-		assert(false);
+		Type t = next.syntaxCopy();
+		Type ti = index.syntaxCopy();
+		if (t == next && ti == index)
+			t = this;
+		else
+		{	
+			t = new TypeAArray(t, ti);
+			t.mod = mod;
+		}
+		return t;
 	}
 
 version (DumbClone) {
@@ -137,7 +146,30 @@
 	
     void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps)
 	{
-		assert(false);
+		//printf("TypeAArray.resolve() %s\n", toChars());
+
+		// Deal with the case where we thought the index was a type, but
+		// in reality it was an expression.
+		if (index.ty == Tident || index.ty == Tinstance || index.ty == Tsarray)
+		{
+			Expression e;
+			Type t;
+			Dsymbol s;
+
+			index.resolve(loc, sc, &e, &t, &s);
+			if (e)
+			{   // It was an expression -
+				// Rewrite as a static array
+
+				TypeSArray tsa = new TypeSArray(next, e);
+				return tsa.resolve(loc, sc, pe, pt, ps);
+			}
+			else if (t)
+				index = t;
+			else
+				index.error(loc, "index is not a type or an expression");
+		}
+		Type.resolve(loc, sc, pe, pt, ps);
 	}
 	
     void toDecoBuffer(OutBuffer buf, int flag)
@@ -236,7 +268,22 @@
 	
     MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes)
 	{
-		assert(false);
+static if (false) {
+		printf("TypeAArray.deduceType()\n");
+		printf("\tthis   = %d, ", ty); print();
+		printf("\ttparam = %d, ", tparam.ty); tparam.print();
+}
+
+		// Extra check that index type must match
+		if (tparam && tparam.ty == Taarray)
+		{
+			TypeAArray tp = cast(TypeAArray)tparam;
+			if (!index.deduceType(sc, tp.index, parameters, dedtypes))
+			{
+				return MATCHnomatch;
+			}
+		}
+		return Type.deduceType(sc, tparam, parameters, dedtypes);
 	}
 	
     bool isZeroInit(Loc loc)
@@ -261,7 +308,32 @@
 	
     MATCH implicitConvTo(Type to)
 	{
-		assert(false);
+		//printf("TypeAArray.implicitConvTo(to = %s) this = %s\n", to.toChars(), toChars());
+		if (equals(to))
+			return MATCHexact;
+
+		if (to.ty == Taarray)
+		{	
+			TypeAArray ta = cast(TypeAArray)to;
+
+			if (!(next.mod == ta.next.mod || ta.next.mod == MODconst))
+				return MATCHnomatch;	// not const-compatible
+
+			if (!(index.mod == ta.index.mod || ta.index.mod == MODconst))
+				return MATCHnomatch;	// not const-compatible
+
+			MATCH m = next.constConv(ta.next);
+			MATCH mi = index.constConv(ta.index);
+			if (m != MATCHnomatch && mi != MATCHnomatch)
+			{
+				if (m == MATCHexact && mod != to.mod)
+					m = MATCHconst;
+				if (mi < m)
+					m = mi;
+				return m;
+			}
+		}
+		return Type.implicitConvTo(to);
 	}
 	
     MATCH constConv(Type to)
--- a/dmd/TypeIdentifier.d	Sat Aug 21 10:38:26 2010 +0400
+++ b/dmd/TypeIdentifier.d	Sat Aug 21 11:17:42 2010 +0400
@@ -158,7 +158,21 @@
 	
     MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes)
 	{
-		assert(false);
+	    // Extra check
+		if (tparam && tparam.ty == Tident)
+		{
+			TypeIdentifier tp = cast(TypeIdentifier)tparam;
+
+			for (int i = 0; i < idents.dim; i++)
+			{
+				Identifier id1 = cast(Identifier)idents.data[i];
+				Identifier id2 = cast(Identifier)tp.idents.data[i];
+
+				if (!id1.equals(id2))
+					return MATCHnomatch;
+			}
+		}
+		return Type.deduceType(sc, tparam, parameters, dedtypes);
 	}
 	
     Type reliesOnTident()
--- a/dmd/TypeSArray.d	Sat Aug 21 10:38:26 2010 +0400
+++ b/dmd/TypeSArray.d	Sat Aug 21 11:17:42 2010 +0400
@@ -1,8 +1,12 @@
 module dmd.TypeSArray;
 
 import dmd.TypeArray;
+import dmd.TypeAArray;
 import dmd.MOD;
 import dmd.Argument;
+import dmd.TypeIdentifier;
+import dmd.TemplateParameter;
+import dmd.TemplateValueParameter;
 import dmd.TypeStruct;
 import dmd.TypeTuple;
 import dmd.VarExp;
@@ -476,7 +480,97 @@
 	
     MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes)
 	{
-		assert(false);
+static if (false) {
+		printf("TypeSArray.deduceType()\n");
+		printf("\tthis   = %d, ", ty); print();
+		printf("\ttparam = %d, ", tparam.ty); tparam.print();
+}
+
+		// Extra check that array dimensions must match
+		if (tparam)
+		{
+			if (tparam.ty == Tsarray)
+			{
+				TypeSArray tp = cast(TypeSArray)tparam;
+
+				if (tp.dim.op == TOKvar && (cast(VarExp)tp.dim).var.storage_class & STCtemplateparameter)
+				{	
+					int i = templateIdentifierLookup((cast(VarExp)tp.dim).var.ident, parameters);
+				// This code matches code in TypeInstance.deduceType()
+					if (i == -1)
+						goto Lnomatch;
+					TemplateParameter tp2 = cast(TemplateParameter)parameters.data[i];
+					TemplateValueParameter tvp = tp2.isTemplateValueParameter();
+					if (!tvp)
+						goto Lnomatch;
+					Expression e = cast(Expression)dedtypes.data[i];
+					if (e)
+					{
+						if (!dim.equals(e))
+						goto Lnomatch;
+					}
+					else
+					{   
+						Type vt = tvp.valType.semantic(Loc(0), sc);
+						MATCH m = cast(MATCH)dim.implicitConvTo(vt);
+						if (!m)
+							goto Lnomatch;
+						dedtypes.data[i] = cast(void*)dim;
+					}
+				}
+				else if (dim.toInteger() != tp.dim.toInteger())
+					return MATCHnomatch;
+			}
+			else if (tparam.ty == Taarray)
+			{
+				TypeAArray tp = cast(TypeAArray)tparam;
+				if (tp.index.ty == Tident)
+				{	
+					TypeIdentifier tident = cast(TypeIdentifier)tp.index;
+
+					if (tident.idents.dim == 0)
+					{   
+						Identifier id = tident.ident;
+
+						for (size_t i = 0; i < parameters.dim; i++)
+						{
+							TemplateParameter tp2 = cast(TemplateParameter)parameters.data[i];
+
+							if (tp2.ident.equals(id))
+							{   
+								// Found the corresponding template parameter
+								TemplateValueParameter tvp = tp2.isTemplateValueParameter();
+								if (!tvp || !tvp.valType.isintegral())
+								goto Lnomatch;
+
+								if (dedtypes.data[i])
+								{
+									if (!dim.equals(cast(Object)dedtypes.data[i]))
+										goto Lnomatch;
+								}
+								else
+								{	dedtypes.data[i] = cast(void*)dim;
+								}
+								return next.deduceType(sc, tparam.nextOf(), parameters, dedtypes);
+							}
+						}
+					}
+				}
+			}
+			else if (tparam.ty == Tarray)
+			{   
+				MATCH m;
+
+				m = next.deduceType(sc, tparam.nextOf(), parameters, dedtypes);
+				if (m == MATCHexact)
+					m = MATCHconvert;
+				return m;
+			}
+		}
+		return Type.deduceType(sc, tparam, parameters, dedtypes);
+
+	  Lnomatch:
+		return MATCHnomatch;
 	}
 	
     TypeInfoDeclaration getTypeInfoDeclaration()
--- a/dmd/TypeTypeof.d	Sat Aug 21 10:38:26 2010 +0400
+++ b/dmd/TypeTypeof.d	Sat Aug 21 11:17:42 2010 +0400
@@ -34,7 +34,13 @@
 	
     Type syntaxCopy()
 	{
-		assert(false);
+		//printf("TypeTypeof.syntaxCopy() %s\n", toChars());
+		TypeTypeof t;
+
+		t = new TypeTypeof(loc, exp.syntaxCopy());
+		t.syntaxCopyHelper(this);
+		t.mod = mod;
+		return t;
 	}
 	
     Dsymbol toDsymbol(Scope sc)
--- a/dmd/VoidInitializer.d	Sat Aug 21 10:38:26 2010 +0400
+++ b/dmd/VoidInitializer.d	Sat Aug 21 11:17:42 2010 +0400
@@ -21,7 +21,7 @@
 	
     Initializer syntaxCopy()
 	{
-		assert(false);
+		return new VoidInitializer(loc);
 	}
 	
     Initializer semantic(Scope sc, Type t)