9 changes: 6 additions & 3 deletions src/mtype.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,12 +673,15 @@ class TypeQualified : public Type
void addInst(TemplateInstance *inst);
void addIndex(RootObject *expr);
d_uns64 size(Loc loc);

void resolveTupleIndex(Loc loc, Scope *sc, Dsymbol *s,
Expression **pe, Type **pt, Dsymbol **ps, RootObject *oindex);
void resolveExprType(Loc loc, Scope *sc, Expression *e, size_t i,
Expression **pe, Type **pt);
void resolveHelper(Loc loc, Scope *sc, Dsymbol *s, Dsymbol *scopesym,
Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false);
void accept(Visitor *v) { v->visit(this); }

private:
bool resolveTypeTupleIndex(Loc loc, Scope *sc, Dsymbol **s, Type **pt, Dsymbol **ps, RootObject *id, Expression *indexExpr);
void accept(Visitor *v) { v->visit(this); }
};

class TypeIdentifier : public TypeQualified
Expand Down
40 changes: 30 additions & 10 deletions src/parse.d
Original file line number Diff line number Diff line change
Expand Up @@ -3146,7 +3146,7 @@ public:
return t;
}

Type parseBasicType()
Type parseBasicType(bool dontLookDotIdents = false)
{
Type t;
Loc loc;
Expand Down Expand Up @@ -3240,20 +3240,20 @@ public:
// ident!(template_arguments)
auto tempinst = new TemplateInstance(loc, id);
tempinst.tiargs = parseTemplateArguments();
t = parseBasicTypeStartingAt(new TypeInstance(loc, tempinst));
t = parseBasicTypeStartingAt(new TypeInstance(loc, tempinst), dontLookDotIdents);
}
else
{
t = parseBasicTypeStartingAt(new TypeIdentifier(loc, id));
t = parseBasicTypeStartingAt(new TypeIdentifier(loc, id), dontLookDotIdents);
}
break;
case TOKdot:
// Leading . as in .foo
t = parseBasicTypeStartingAt(new TypeIdentifier(token.loc, Id.empty));
t = parseBasicTypeStartingAt(new TypeIdentifier(token.loc, Id.empty), dontLookDotIdents);
break;
case TOKtypeof:
// typeof(expression)
t = parseBasicTypeStartingAt(parseTypeof());
t = parseBasicTypeStartingAt(parseTypeof(), dontLookDotIdents);
break;
case TOKvector:
t = parseVector();
Expand Down Expand Up @@ -3294,7 +3294,7 @@ public:
return t;
}

Type parseBasicTypeStartingAt(TypeQualified tid)
Type parseBasicTypeStartingAt(TypeQualified tid, bool dontLookDotIdents)
{
Type maybeArray = null;
// See https://issues.dlang.org/show_bug.cgi?id=1215
Expand Down Expand Up @@ -3368,6 +3368,8 @@ public:
}
case TOKlbracket:
{
if (dontLookDotIdents) // workaround for Bugzilla 14911
goto Lend;
nextToken();
Type t = maybeArray ? maybeArray : cast(Type)tid;
if (token.value == TOKrbracket)
Expand Down Expand Up @@ -5953,6 +5955,12 @@ public:
{
// It's an associative array declaration
t = peek(t);
// ...[type].ident
if (t.value == TOKdot && peek(t).value == TOKidentifier)
{
t = peek(t);
t = peek(t);
}
}
else
{
Expand All @@ -5965,10 +5973,22 @@ public:
t = peek(t);
if (!isExpression(&t))
return false;
if (t.value != TOKrbracket)
return false;
t = peek(t);
}
else
{
if (t.value != TOKrbracket)
return false;
t = peek(t);
// ...[index].ident
if (t.value == TOKdot && peek(t).value == TOKidentifier)
{
t = peek(t);
t = peek(t);
}
}
if (t.value != TOKrbracket)
return false;
t = peek(t);
}
continue;
case TOKidentifier:
Expand Down Expand Up @@ -7695,7 +7715,7 @@ public:
return e;
}
StorageClass stc = parseTypeCtor();
t = parseBasicType();
t = parseBasicType(true);
t = parseBasicType2(t);
t = t.addSTC(stc);
if (t.ty == Taarray)
Expand Down
4 changes: 2 additions & 2 deletions src/parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ class Parser : public Lexer
BaseClasses *parseBaseClasses();
Dsymbols *parseImport();
Type *parseType(Identifier **pident = NULL, TemplateParameters **ptpl = NULL);
Type *parseBasicType();
Type *parseBasicTypeStartingAt(TypeQualified *tid);
Type *parseBasicType(bool dontLookDotIdents = false);
Type *parseBasicTypeStartingAt(TypeQualified *tid, bool dontLookDotIdents);
Type *parseBasicType2(Type *t);
Type *parseDeclarator(Type *t, int *alt, Identifier **pident,
TemplateParameters **tpl = NULL, StorageClass storage_class = 0, int *pdisable = NULL, Expressions **pudas = NULL);
Expand Down
49 changes: 49 additions & 0 deletions test/compilable/b1215.d
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,52 @@ struct C(Args...)
}

alias Z = A!(B,B,C!(B,B));

/***************************************************/
// 14889

struct A14889(alias Exc)
{
alias ExceptionType = Exc;
}
alias TT14889(Args...) = Args;

alias X14889a = TT14889!(A14889!Throwable());
alias Y14889a = X14889a[0].ExceptionType;

alias X14889b = TT14889!(A14889!Throwable);
alias Y14889b = X14889b[0].ExceptionType;

/***************************************************/
// 14889

alias TypeTuple14900(T...) = T;

struct S14900
{
alias T = int;
alias U = TypeTuple14900!(long,string);
}

alias Types14900 = TypeTuple14900!(S14900, S14900);

Types14900[0].T a14900; // Types[0] == S, then typeof(a) == S.T == int
Types14900[0].U[1] b14900; // Types[0].U == S.U, then typeof(b) == S.U[1] == string

void test14900()
{
Types14900[0].T a; // Types[0] == S, then typeof(a) == S.T == int
Types14900[0].U[1] b; // Types[0].U == S.U, then typeof(b) == S.U[1] == string
}

/***************************************************/
// 14911

void test14911()
{
struct S {}

int* buf1 = new int[2].ptr; // OK
S* buf2 = (new S[2]).ptr; // OK
S* buf3 = new S[2].ptr; // OK <- broken
}
4 changes: 1 addition & 3 deletions test/fail_compilation/fail9.d
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail9.d(25): Error: no property 'Vector' for type 'fail9.Vector!int'
fail_compilation/fail9.d(25): Error: no property 'Vector' for type 'fail9.Vector!int'
fail_compilation/fail9.d(23): Error: no property 'Vector' for type 'fail9.Vector!int'
---
*/


template Vector(T)
{
int x;
Expand Down
4 changes: 2 additions & 2 deletions test/fail_compilation/ice9865.d
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
TEST_OUTPUT:
---
fail_compilation/ice9865.d(9): Error: struct ice9865.Foo no size yet for forward reference
fail_compilation/ice9865.d(8): Error: alias ice9865.Baz cannot resolve
fail_compilation/ice9865.d(8): Error: alias ice9865.Baz recursive alias declaration
---
*/
import imports.ice9865b : Baz;
import imports.ice9865b : Baz;
struct Foo { Baz f; }