1 change: 1 addition & 0 deletions src/dmd/argtypes_x86.d
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ extern (C++) TypeTuple toArgTypes_x86(Type t)
Type t2 = null;
switch (t.ty)
{
case Ttype:
case Tvoid:
return;
case Tbool:
Expand Down
5 changes: 5 additions & 0 deletions src/dmd/astbase.d
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ struct ASTBase

Tdelegate,
Tnone,

Ttype,

Tvoid,
Tint8,
Tuns8,
Expand Down Expand Up @@ -2708,6 +2711,8 @@ struct ASTBase
extern (C++) __gshared Type terror; // for error recovery
extern (C++) __gshared Type tnull; // for null type

extern (C++) __gshared Type talias; // type of types

extern (C++) __gshared Type tsize_t; // matches size_t alias
extern (C++) __gshared Type tptrdiff_t; // matches ptrdiff_t alias
extern (C++) __gshared Type thash_t; // matches hash_t alias
Expand Down
9 changes: 9 additions & 0 deletions src/dmd/constfold.d
Original file line number Diff line number Diff line change
Expand Up @@ -1727,6 +1727,7 @@ UnionExp Cat(Type type, Expression e1, Expression e2)
}
else if ((e1.op == TOK.arrayLiteral || e1.op == TOK.null_) && e1.type.toBasetype().nextOf() && e1.type.toBasetype().nextOf().equals(e2.type))
{
L4:
auto elems = (e1.op == TOK.arrayLiteral)
? copyElements(e1) : new Expressions();
elems.push(e2);
Expand Down Expand Up @@ -1791,8 +1792,16 @@ UnionExp Cat(Type type, Expression e1, Expression e2)
e = ue.exp();
}
}
else if (e1.op == TOK.arrayLiteral && e2.op == TOK.type)
{
// when we have a type here we can just go the regular array cat
goto L4;
}
else
{
//printf("don't know how to deal with exps.ops: {%s, %s}\n", Token.toChars(e1.op), Token.toChars(e2.op));
cantExp(ue);
}
assert(ue.exp().type);
return ue;
}
Expand Down
23 changes: 22 additions & 1 deletion src/dmd/ctfeexpr.d
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,11 @@ UnionExp copyLiteral(Expression e)
emplaceExp!(UnionExp)(&ue, e);
return ue;
}
if (e.op == TOK.type)
{
emplaceExp!(TypeExp)(&ue, e.loc, e.type);
return ue;
}
e.error("CTFE internal error: literal `%s`", e.toChars());
assert(0);
}
Expand All @@ -438,6 +443,14 @@ Expression paintTypeOntoLiteral(Type type, Expression lit)

Expression paintTypeOntoLiteral(UnionExp* pue, Type type, Expression lit)
{
// painting to alias is a no-op
if (type.ty == Ttype)
{
auto nlit = lit.copy();
//nlit.type = Type.talias;
return nlit;
}

if (lit.type.equals(type))
return lit;
*pue = paintTypeOntoLiteralCopy(type, lit);
Expand Down Expand Up @@ -1574,6 +1587,11 @@ Expression ctfeCast(UnionExp* pue, const ref Loc loc, Type type, Type to, Expres
return paintTypeOntoLiteral(pue, to, e);
}

if (to.ty == Ttype)
{
return e;
}

if (e.op == TOK.null_)
return paint();

Expand All @@ -1600,7 +1618,7 @@ Expression ctfeCast(UnionExp* pue, const ref Loc loc, Type type, Type to, Expres
return paint();

Expression r;
if (e.type.equals(type) && type.equals(to))
if (((type is to && e.type is type) || (e.type.equals(type) && type.equals(to))))
{
// necessary not to change e's address for pointer comparisons
r = e;
Expand Down Expand Up @@ -1902,6 +1920,9 @@ bool isCtfeValueValid(Expression newval)

case TOK.void_:
return true; // uninitialized value
case TOK._type__:
case TOK.emptyType_:
return true;

default:
newval.error("CTFE internal error: illegal CTFE value `%s`", newval.toChars());
Expand Down
17 changes: 17 additions & 0 deletions src/dmd/dcast.d
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
{
//printf("Expression.implicitCastTo(%s of type %s) => %s\n", e.toChars(), e.type.toChars(), t.toChars());

if (t.ty == Ttype)
{
// casts to Ttype just create a new castExp.
result = new CastExp(e.loc, e, t);
result.type = t;
return ;
}

if (const match = e.implicitConvTo(t))
{
if (match == MATCH.constant && (e.type.constConv(t) || !e.isLvalue() && e.type.equivalent(t)))
Expand Down Expand Up @@ -1416,8 +1424,17 @@ MATCH implicitConvTo(Expression e, Type t)
if (tb.ty == Tpointer && e.e1.op == TOK.string_)
e.e1.accept(this);
}

override void visit(TypeExp e)
{
// TODO FIXME this should work
// MATCH match = e.type.implicitConvTo(t);
if (t.ty == Ttype)
result = MATCH.convert;
}
}


scope ImplicitConvTo v = new ImplicitConvTo(t);
e.accept(v);
return v.result;
Expand Down
4 changes: 2 additions & 2 deletions src/dmd/declaration.d
Original file line number Diff line number Diff line change
Expand Up @@ -1251,7 +1251,7 @@ extern (C++) class VarDeclaration : Declaration
const sz = t.size(loc);
assert(sz != SIZE_INVALID && sz < uint.max);
uint memsize = cast(uint)sz; // size of member
uint memalignsize = target.fieldalign(t); // size of member for alignment purposes
uint memalignsize = (t.ty == Ttype) ? 1 : target.fieldalign(t); // size of member for alignment purposes
offset = AggregateDeclaration.placeField(
poffset,
memsize, memalignsize, alignment,
Expand Down Expand Up @@ -1361,7 +1361,7 @@ extern (C++) class VarDeclaration : Declaration
*/
final bool isCTFE()
{
return (storage_class & STC.ctfe) != 0; // || !isDataseg();
return ((storage_class & STC.ctfe) != 0) || isTypeType(type);
}

final bool isOverlappedWith(VarDeclaration v)
Expand Down
Loading