diff dmd/StructLiteralExp.d @ 72:2e2a5c3f943a

reduced warnings by adding override to the methods think this also normalizes different line endings used all over the place
author Trass3r
date Sat, 28 Aug 2010 16:19:48 +0200
parents f708f0452e81
children 43073c7c7769
line wrap: on
line diff
--- a/dmd/StructLiteralExp.d	Sat Aug 28 16:14:07 2010 +0200
+++ b/dmd/StructLiteralExp.d	Sat Aug 28 16:19:48 2010 +0200
@@ -1,158 +1,158 @@
-module dmd.StructLiteralExp;
-
-import dmd.Expression;
-import dmd.MOD;
-import dmd.TypeStruct;
-import dmd.TypeSArray;
-import dmd.expression.Util;
-import dmd.ErrorExp;
-import dmd.Dsymbol;
-import dmd.VarDeclaration;
-import dmd.StructDeclaration;
-import dmd.FuncDeclaration;
-import dmd.ThisDeclaration;
-import dmd.backend.elem;
-import dmd.InterState;
-import dmd.MATCH;
-import dmd.WANT;
-import dmd.TY;
-import dmd.Type;
-import dmd.OutBuffer;
-import dmd.Loc;
-import dmd.Scope;
-import dmd.InlineCostState;
-import dmd.IRState;
-import dmd.InlineDoState;
-import dmd.backend.Symbol;
-import dmd.HdrGenState;
-import dmd.backend.dt_t;
-import dmd.InlineScanState;
-import dmd.ArrayTypes;
-import dmd.TOK;
-
-import dmd.codegen.Util;
-import dmd.backend.Util;
-import dmd.backend.RTLSYM;
-import dmd.backend.TYM;
-import dmd.backend.mTY;
-import dmd.backend.OPER;
-
-
+module dmd.StructLiteralExp;
+
+import dmd.Expression;
+import dmd.MOD;
+import dmd.TypeStruct;
+import dmd.TypeSArray;
+import dmd.expression.Util;
+import dmd.ErrorExp;
+import dmd.Dsymbol;
+import dmd.VarDeclaration;
+import dmd.StructDeclaration;
+import dmd.FuncDeclaration;
+import dmd.ThisDeclaration;
+import dmd.backend.elem;
+import dmd.InterState;
+import dmd.MATCH;
+import dmd.WANT;
+import dmd.TY;
+import dmd.Type;
+import dmd.OutBuffer;
+import dmd.Loc;
+import dmd.Scope;
+import dmd.InlineCostState;
+import dmd.IRState;
+import dmd.InlineDoState;
+import dmd.backend.Symbol;
+import dmd.HdrGenState;
+import dmd.backend.dt_t;
+import dmd.InlineScanState;
+import dmd.ArrayTypes;
+import dmd.TOK;
+
+import dmd.codegen.Util;
+import dmd.backend.Util;
+import dmd.backend.RTLSYM;
+import dmd.backend.TYM;
+import dmd.backend.mTY;
+import dmd.backend.OPER;
+
+
 class StructLiteralExp : Expression
 {
-	StructDeclaration sd;		// which aggregate this is for
-    Expressions elements;	// parallels sd->fields[] with
-				// NULL entries for fields to skip
-
-    Symbol* sym;		// back end symbol to initialize with literal
-    size_t soffset;		// offset from start of s
+	StructDeclaration sd;		// which aggregate this is for
+    Expressions elements;	// parallels sd->fields[] with
+				// NULL entries for fields to skip
+
+    Symbol* sym;		// back end symbol to initialize with literal
+    size_t soffset;		// offset from start of s
     int fillHoles;		// fill alignment 'holes' with zero
 
 	this(Loc loc, StructDeclaration sd, Expressions elements)
 	{
-		super(loc, TOKstructliteral, StructLiteralExp.sizeof);
-		this.sd = sd;
-		this.elements = elements;
-		this.sym = null;
-		this.soffset = 0;
-		this.fillHoles = 1;
+		super(loc, TOKstructliteral, StructLiteralExp.sizeof);
+		this.sd = sd;
+		this.elements = elements;
+		this.sym = null;
+		this.soffset = 0;
+		this.fillHoles = 1;
 	}
 
-	Expression syntaxCopy()
+	override Expression syntaxCopy()
 	{
 		assert(false);
 	}
 
-	Expression semantic(Scope sc)
+	override Expression semantic(Scope sc)
 	{
-		Expression e;
-		int nfields = sd.fields.dim - sd.isnested;
-
-version (LOGSEMANTIC) {
-		printf("StructLiteralExp.semantic('%s')\n", toChars());
-}
-		if (type)
-			return this;
-
-		// Run semantic() on each element
-		for (size_t i = 0; i < elements.dim; i++)
-		{	
-			e = cast(Expression)elements.data[i];
-			if (!e)
-				continue;
-			e = e.semantic(sc);
-			elements.data[i] = cast(void*)e;
-		}
-		expandTuples(elements);
-		size_t offset = 0;
-		for (size_t i = 0; i < elements.dim; i++)
-		{	
-			e = cast(Expression)elements.data[i];
-			if (!e)
-				continue;
-
-			if (!e.type)
-				error("%s has no value", e.toChars());
-			e = resolveProperties(sc, e);
-			if (i >= nfields)
-			{   
-				error("more initializers than fields of %s", sd.toChars());
-				return new ErrorExp();
-			}
-			Dsymbol s = cast(Dsymbol)sd.fields.data[i];
-			VarDeclaration v = s.isVarDeclaration();
-			assert(v);
-			if (v.offset < offset)
-				error("overlapping initialization for %s", v.toChars());
-			offset = v.offset + cast(uint)v.type.size();
-
-			Type telem = v.type;
-			while (!e.implicitConvTo(telem) && telem.toBasetype().ty == Tsarray)
-			{   
-				/* Static array initialization, as in:
-				 *	T[3][5] = e;
-				 */
-				telem = telem.toBasetype().nextOf();
-			}
-
-			e = e.implicitCastTo(sc, telem);
-
-			elements.data[i] = cast(void*)e;
-		}
-
-		/* Fill out remainder of elements[] with default initializers for fields[]
-		 */
-		for (size_t i = elements.dim; i < nfields; i++)
-		{	
-			Dsymbol s = cast(Dsymbol)sd.fields.data[i];
-			VarDeclaration v = s.isVarDeclaration();
-			assert(v);
-			assert(!v.isThisDeclaration());
-
-			if (v.offset < offset)
-			{   
-				e = null;
-				sd.hasUnions = 1;
-			}
-			else
-			{
-				if (v.init)
-				{   
-					e = v.init.toExpression();
-					if (!e)
-						error("cannot make expression out of initializer for %s", v.toChars());
-				}
-				else
-				{	
-					e = v.type.defaultInit(Loc(0));
-					e.loc = loc;
-				}
-				offset = v.offset + cast(uint)v.type.size();
-			}
-			elements.push(cast(void*)e);
-		}
-
-		type = sd.type;
+		Expression e;
+		int nfields = sd.fields.dim - sd.isnested;
+
+version (LOGSEMANTIC) {
+		printf("StructLiteralExp.semantic('%s')\n", toChars());
+}
+		if (type)
+			return this;
+
+		// Run semantic() on each element
+		for (size_t i = 0; i < elements.dim; i++)
+		{	
+			e = cast(Expression)elements.data[i];
+			if (!e)
+				continue;
+			e = e.semantic(sc);
+			elements.data[i] = cast(void*)e;
+		}
+		expandTuples(elements);
+		size_t offset = 0;
+		for (size_t i = 0; i < elements.dim; i++)
+		{	
+			e = cast(Expression)elements.data[i];
+			if (!e)
+				continue;
+
+			if (!e.type)
+				error("%s has no value", e.toChars());
+			e = resolveProperties(sc, e);
+			if (i >= nfields)
+			{   
+				error("more initializers than fields of %s", sd.toChars());
+				return new ErrorExp();
+			}
+			Dsymbol s = cast(Dsymbol)sd.fields.data[i];
+			VarDeclaration v = s.isVarDeclaration();
+			assert(v);
+			if (v.offset < offset)
+				error("overlapping initialization for %s", v.toChars());
+			offset = v.offset + cast(uint)v.type.size();
+
+			Type telem = v.type;
+			while (!e.implicitConvTo(telem) && telem.toBasetype().ty == Tsarray)
+			{   
+				/* Static array initialization, as in:
+				 *	T[3][5] = e;
+				 */
+				telem = telem.toBasetype().nextOf();
+			}
+
+			e = e.implicitCastTo(sc, telem);
+
+			elements.data[i] = cast(void*)e;
+		}
+
+		/* Fill out remainder of elements[] with default initializers for fields[]
+		 */
+		for (size_t i = elements.dim; i < nfields; i++)
+		{	
+			Dsymbol s = cast(Dsymbol)sd.fields.data[i];
+			VarDeclaration v = s.isVarDeclaration();
+			assert(v);
+			assert(!v.isThisDeclaration());
+
+			if (v.offset < offset)
+			{   
+				e = null;
+				sd.hasUnions = 1;
+			}
+			else
+			{
+				if (v.init)
+				{   
+					e = v.init.toExpression();
+					if (!e)
+						error("cannot make expression out of initializer for %s", v.toChars());
+				}
+				else
+				{	
+					e = v.type.defaultInit(Loc(0));
+					e.loc = loc;
+				}
+				offset = v.offset + cast(uint)v.type.size();
+			}
+			elements.push(cast(void*)e);
+		}
+
+		type = sd.type;
 		return this;
 	}
 
@@ -166,277 +166,277 @@
 		assert(false);
 	}
 
-	elem* toElem(IRState* irs)
+	override elem* toElem(IRState* irs)
 	{
-		elem* e;
-		size_t dim;
-
-		//printf("StructLiteralExp.toElem() %s\n", toChars());
-
-		// struct symbol to initialize with the literal
-		Symbol* stmp = sym ? sym : symbol_genauto(sd.type.toCtype());
-
-		e = null;
-
-		if (fillHoles)
-		{
-			/* Initialize all alignment 'holes' to zero.
-			 * Do before initializing fields, as the hole filling process
-			 * can spill over into the fields.
-			 */
-			size_t offset = 0;
-			for (size_t i = 0; i < sd.fields.dim; i++)
-			{
-				Dsymbol s = cast(Dsymbol)sd.fields.data[i];
-				VarDeclaration v = s.isVarDeclaration();
-				assert(v);
-
-				e = el_combine(e, fillHole(stmp, &offset, v.offset, sd.structsize));
-				size_t vend = v.offset + cast(uint)v.type.size();
-				if (offset < vend)
-					offset = vend;
-			}
-			e = el_combine(e, fillHole(stmp, &offset, sd.structsize, sd.structsize));
-		}
-
-		if (elements)
-		{
-			dim = elements.dim;
-			assert(dim <= sd.fields.dim);
-			for (size_t i = 0; i < dim; i++)
-			{   
-				Expression el = cast(Expression)elements.data[i];
-				if (!el)
-					continue;
-
-				Dsymbol s = cast(Dsymbol)sd.fields.data[i];
-				VarDeclaration v = s.isVarDeclaration();
-				assert(v);
-				assert(!v.isThisDeclaration());
-
-				elem* e1;
-				if (tybasic(stmp.Stype.Tty) == TYnptr)
-				{	
-					e1 = el_var(stmp);
-					e1.EV.sp.Voffset = soffset;
-				}
-				else
-				{	
-					e1 = el_ptr(stmp);
-					if (soffset)
-						e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset));
-				}
-				e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset));
-				elem* ec = e1;			// pointer to destination
-
-				elem* ep = el.toElem(irs);
-
-				Type t1b = v.type.toBasetype();
-				Type t2b = el.type.toBasetype();
-				if (t1b.ty == Tsarray)
-				{
-					if (t2b.implicitConvTo(t1b))
-					{
-		///version (DMDV2) {
-						// Determine if postblit is needed
-						int postblit = 0;
-						if (needsPostblit(t1b))
-							postblit = 1;
-
-						if (postblit)
-						{
-							/* Generate:
-							 *	_d_arrayctor(ti, From: ep, To: e1)
-							 */
-							Expression ti = t1b.nextOf().toBasetype().getTypeInfo(null);
-							elem* esize = el_long(TYsize_t, (cast(TypeSArray)t1b).dim.toInteger());
-							e1 = el_pair(TYdarray, esize, e1);
-							ep = el_pair(TYdarray, el_copytree(esize), array_toPtr(el.type, ep));
-							ep = el_params(e1, ep, ti.toElem(irs), null);
-							int rtl = RTLSYM_ARRAYCTOR;
-							e1 = el_bin(OPcall, type.totym(), el_var(rtlsym[rtl]), ep);
-						}
-						else
-		///}
-						{
-							elem* esize = el_long(TYsize_t, t1b.size());
-							ep = array_toPtr(el.type, ep);
-							e1 = el_bin(OPmemcpy, TYnptr, e1, el_param(ep, esize));
-						}
-					}
-					else
-					{
-						elem* edim = el_long(TYsize_t, t1b.size() / t2b.size());
-						e1 = setArray(e1, edim, t2b, ep, irs, TOKconstruct);
-					}
-				}
-				else
-				{
-					tym_t ty = v.type.totym();
-					e1 = el_una(OPind, ty, e1);
-					if (tybasic(ty) == TYstruct)
-						e1.Enumbytes = cast(uint)v.type.size();
-					e1 = el_bin(OPeq, ty, e1, ep);
-					if (tybasic(ty) == TYstruct)
-					{   
-						e1.Eoper = OPstreq;
-						e1.Enumbytes = cast(uint)v.type.size();
-					}
-version (DMDV2) {
-					/* Call postblit() on e1
-					 */
-					StructDeclaration sd = needsPostblit(v.type);
-					if (sd)
-					{   
-						FuncDeclaration fd = sd.postblit;
-						ec = el_copytree(ec);
-						ec = callfunc(loc, irs, 1, Type.tvoid, ec, sd.type.pointerTo(), fd, fd.type, null, null);
-						e1 = el_bin(OPcomma, ec.Ety, e1, ec);
-					}
-}
-				}
-				e = el_combine(e, e1);
-			}
-		}
-
-version (DMDV2) {
-		if (sd.isnested)
-		{	// Initialize the hidden 'this' pointer
-			assert(sd.fields.dim);
-			Dsymbol s = cast(Dsymbol)sd.fields.data[sd.fields.dim - 1];
-			ThisDeclaration v = s.isThisDeclaration();
-			assert(v);
-
-			elem* e1;
-			if (tybasic(stmp.Stype.Tty) == TYnptr)
-			{   
-				e1 = el_var(stmp);
-				e1.EV.sp.Voffset = soffset;
-			}
-			else
-			{   
-				e1 = el_ptr(stmp);
-				if (soffset)
-					e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset));
-			}
-			e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset));
-			e1 = setEthis(loc, irs, e1, sd);
-
-			e = el_combine(e, e1);
-		}
-}
-
-		elem* ev = el_var(stmp);
-		ev.Enumbytes = sd.structsize;
-		e = el_combine(e, ev);
-		el_setLoc(e,loc);
+		elem* e;
+		size_t dim;
+
+		//printf("StructLiteralExp.toElem() %s\n", toChars());
+
+		// struct symbol to initialize with the literal
+		Symbol* stmp = sym ? sym : symbol_genauto(sd.type.toCtype());
+
+		e = null;
+
+		if (fillHoles)
+		{
+			/* Initialize all alignment 'holes' to zero.
+			 * Do before initializing fields, as the hole filling process
+			 * can spill over into the fields.
+			 */
+			size_t offset = 0;
+			for (size_t i = 0; i < sd.fields.dim; i++)
+			{
+				Dsymbol s = cast(Dsymbol)sd.fields.data[i];
+				VarDeclaration v = s.isVarDeclaration();
+				assert(v);
+
+				e = el_combine(e, fillHole(stmp, &offset, v.offset, sd.structsize));
+				size_t vend = v.offset + cast(uint)v.type.size();
+				if (offset < vend)
+					offset = vend;
+			}
+			e = el_combine(e, fillHole(stmp, &offset, sd.structsize, sd.structsize));
+		}
+
+		if (elements)
+		{
+			dim = elements.dim;
+			assert(dim <= sd.fields.dim);
+			for (size_t i = 0; i < dim; i++)
+			{   
+				Expression el = cast(Expression)elements.data[i];
+				if (!el)
+					continue;
+
+				Dsymbol s = cast(Dsymbol)sd.fields.data[i];
+				VarDeclaration v = s.isVarDeclaration();
+				assert(v);
+				assert(!v.isThisDeclaration());
+
+				elem* e1;
+				if (tybasic(stmp.Stype.Tty) == TYnptr)
+				{	
+					e1 = el_var(stmp);
+					e1.EV.sp.Voffset = soffset;
+				}
+				else
+				{	
+					e1 = el_ptr(stmp);
+					if (soffset)
+						e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset));
+				}
+				e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset));
+				elem* ec = e1;			// pointer to destination
+
+				elem* ep = el.toElem(irs);
+
+				Type t1b = v.type.toBasetype();
+				Type t2b = el.type.toBasetype();
+				if (t1b.ty == Tsarray)
+				{
+					if (t2b.implicitConvTo(t1b))
+					{
+		///version (DMDV2) {
+						// Determine if postblit is needed
+						int postblit = 0;
+						if (needsPostblit(t1b))
+							postblit = 1;
+
+						if (postblit)
+						{
+							/* Generate:
+							 *	_d_arrayctor(ti, From: ep, To: e1)
+							 */
+							Expression ti = t1b.nextOf().toBasetype().getTypeInfo(null);
+							elem* esize = el_long(TYsize_t, (cast(TypeSArray)t1b).dim.toInteger());
+							e1 = el_pair(TYdarray, esize, e1);
+							ep = el_pair(TYdarray, el_copytree(esize), array_toPtr(el.type, ep));
+							ep = el_params(e1, ep, ti.toElem(irs), null);
+							int rtl = RTLSYM_ARRAYCTOR;
+							e1 = el_bin(OPcall, type.totym(), el_var(rtlsym[rtl]), ep);
+						}
+						else
+		///}
+						{
+							elem* esize = el_long(TYsize_t, t1b.size());
+							ep = array_toPtr(el.type, ep);
+							e1 = el_bin(OPmemcpy, TYnptr, e1, el_param(ep, esize));
+						}
+					}
+					else
+					{
+						elem* edim = el_long(TYsize_t, t1b.size() / t2b.size());
+						e1 = setArray(e1, edim, t2b, ep, irs, TOKconstruct);
+					}
+				}
+				else
+				{
+					tym_t ty = v.type.totym();
+					e1 = el_una(OPind, ty, e1);
+					if (tybasic(ty) == TYstruct)
+						e1.Enumbytes = cast(uint)v.type.size();
+					e1 = el_bin(OPeq, ty, e1, ep);
+					if (tybasic(ty) == TYstruct)
+					{   
+						e1.Eoper = OPstreq;
+						e1.Enumbytes = cast(uint)v.type.size();
+					}
+version (DMDV2) {
+					/* Call postblit() on e1
+					 */
+					StructDeclaration sd = needsPostblit(v.type);
+					if (sd)
+					{   
+						FuncDeclaration fd = sd.postblit;
+						ec = el_copytree(ec);
+						ec = callfunc(loc, irs, 1, Type.tvoid, ec, sd.type.pointerTo(), fd, fd.type, null, null);
+						e1 = el_bin(OPcomma, ec.Ety, e1, ec);
+					}
+}
+				}
+				e = el_combine(e, e1);
+			}
+		}
+
+version (DMDV2) {
+		if (sd.isnested)
+		{	// Initialize the hidden 'this' pointer
+			assert(sd.fields.dim);
+			Dsymbol s = cast(Dsymbol)sd.fields.data[sd.fields.dim - 1];
+			ThisDeclaration v = s.isThisDeclaration();
+			assert(v);
+
+			elem* e1;
+			if (tybasic(stmp.Stype.Tty) == TYnptr)
+			{   
+				e1 = el_var(stmp);
+				e1.EV.sp.Voffset = soffset;
+			}
+			else
+			{   
+				e1 = el_ptr(stmp);
+				if (soffset)
+					e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset));
+			}
+			e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset));
+			e1 = setEthis(loc, irs, e1, sd);
+
+			e = el_combine(e, e1);
+		}
+}
+
+		elem* ev = el_var(stmp);
+		ev.Enumbytes = sd.structsize;
+		e = el_combine(e, ev);
+		el_setLoc(e,loc);
 		return e;
 	}
 
-	bool checkSideEffect(int flag)
+	override bool checkSideEffect(int flag)
 	{
 		assert(false);
 	}
 
-	void toCBuffer(OutBuffer buf, HdrGenState* hgs)
+	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
 		assert(false);
 	}
 
-	void toMangleBuffer(OutBuffer buf)
+	override void toMangleBuffer(OutBuffer buf)
 	{
 		assert(false);
 	}
 
-	void scanForNestedRef(Scope sc)
+	override void scanForNestedRef(Scope sc)
 	{
 		assert(false);
 	}
 
-	Expression optimize(int result)
+	override Expression optimize(int result)
 	{
-		if (elements)
-		{
-			for (size_t i = 0; i < elements.dim; i++)
-			{   
-				Expression e = cast(Expression)elements.data[i];
-				if (!e)
-					continue;
-				e = e.optimize(WANTvalue | (result & WANTinterpret));
-				elements.data[i] = cast(void*)e;
-			}
-		}
+		if (elements)
+		{
+			for (size_t i = 0; i < elements.dim; i++)
+			{   
+				Expression e = cast(Expression)elements.data[i];
+				if (!e)
+					continue;
+				e = e.optimize(WANTvalue | (result & WANTinterpret));
+				elements.data[i] = cast(void*)e;
+			}
+		}
 		return this;
 	}
 
-	Expression interpret(InterState istate)
+	override Expression interpret(InterState istate)
 	{
 		assert(false);
 	}
 
-	dt_t** toDt(dt_t** pdt)
+	override dt_t** toDt(dt_t** pdt)
 	{
 		assert(false);
 	}
 
-	int isLvalue()
+	override int isLvalue()
 	{
 		assert(false);
 	}
 
-	Expression toLvalue(Scope sc, Expression e)
+	override Expression toLvalue(Scope sc, Expression e)
 	{
 		assert(false);
 	}
 
-	bool canThrow()
+	override bool canThrow()
 	{
 		return arrayExpressionCanThrow(elements);
 	}
 
-	MATCH implicitConvTo(Type t)
+	override MATCH implicitConvTo(Type t)
 	{
-static if (false) {
-		printf("StructLiteralExp.implicitConvTo(this=%.*s, type=%.*s, t=%.*s)\n",
-			toChars(), type.toChars(), t.toChars());
-}
-		MATCH m = Expression.implicitConvTo(t);
-		if (m != MATCHnomatch)
-			return m;
-		if (type.ty == t.ty && type.ty == Tstruct && (cast(TypeStruct)type).sym == (cast(TypeStruct)t).sym)
-		{
-			m = MATCHconst;
-			for (int i = 0; i < elements.dim; i++)
-			{   
-				Expression e = cast(Expression)elements.data[i];
-				Type te = e.type;
-				if (t.mod == 0)
-					te = te.mutableOf();
-				else
-				{	
-					assert(t.mod == MODinvariant);
-					te = te.invariantOf();
-				}
-				MATCH m2 = e.implicitConvTo(te);
-				//printf("\t%s => %s, match = %d\n", e.toChars(), te.toChars(), m2);
-				if (m2 < m)
-					m = m2;
-			}
-		}
+static if (false) {
+		printf("StructLiteralExp.implicitConvTo(this=%.*s, type=%.*s, t=%.*s)\n",
+			toChars(), type.toChars(), t.toChars());
+}
+		MATCH m = Expression.implicitConvTo(t);
+		if (m != MATCHnomatch)
+			return m;
+		if (type.ty == t.ty && type.ty == Tstruct && (cast(TypeStruct)type).sym == (cast(TypeStruct)t).sym)
+		{
+			m = MATCHconst;
+			for (int i = 0; i < elements.dim; i++)
+			{   
+				Expression e = cast(Expression)elements.data[i];
+				Type te = e.type;
+				if (t.mod == 0)
+					te = te.mutableOf();
+				else
+				{	
+					assert(t.mod == MODinvariant);
+					te = te.invariantOf();
+				}
+				MATCH m2 = e.implicitConvTo(te);
+				//printf("\t%s => %s, match = %d\n", e.toChars(), te.toChars(), m2);
+				if (m2 < m)
+					m = m2;
+			}
+		}
 		return m;
 	}
 
-	int inlineCost(InlineCostState* ics)
+	override int inlineCost(InlineCostState* ics)
 	{
 		assert(false);
 	}
 
-	Expression doInline(InlineDoState ids)
+	override Expression doInline(InlineDoState ids)
 	{
 		assert(false);
 	}
 
-	Expression inlineScan(InlineScanState* iss)
+	override Expression inlineScan(InlineScanState* iss)
 	{
 		assert(false);
 	}