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
51 changes: 38 additions & 13 deletions src/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -3028,7 +3028,7 @@ Type *Parser::parseType(Identifier **pident, TemplateParameters **ptpl)
return t;
}

Type *Parser::parseBasicType()
Type *Parser::parseBasicType(bool dontLookDotIdents)
{
Type *t;
Loc loc;
Expand Down Expand Up @@ -3076,22 +3076,22 @@ Type *Parser::parseBasicType()
// ident!(template_arguments)
TemplateInstance *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:
Expand Down Expand Up @@ -3138,7 +3138,7 @@ Type *Parser::parseBasicType()
return t;
}

Type *Parser::parseBasicTypeStartingAt(TypeQualified *tid)
Type *Parser::parseBasicTypeStartingAt(TypeQualified *tid, bool dontLookDotIdents)
{
Type *maybeArray = NULL;
// See https://issues.dlang.org/show_bug.cgi?id=1215
Expand Down Expand Up @@ -3212,6 +3212,9 @@ Type *Parser::parseBasicTypeStartingAt(TypeQualified *tid)
}
case TOKlbracket:
{
if (dontLookDotIdents) // workaround for Bugzilla 14911
goto Lend;

nextToken();
Type *t = maybeArray ? maybeArray : (Type *)tid;
if (token.value == TOKrbracket)
Expand Down Expand Up @@ -3266,7 +3269,7 @@ Type *Parser::parseBasicTypeStartingAt(TypeQualified *tid)
goto Lend;
}
}
Lend:
Lend:
return maybeArray ? maybeArray : (Type *)tid;
}

Expand Down Expand Up @@ -6014,8 +6017,16 @@ bool Parser::isDeclarator(Token **pt, int *haveId, int *haveTpl, TOK endtok)
t = peek(t);
}
else if (isDeclaration(t, 0, TOKrbracket, &t))
{ // It's an associative array declaration
{
// 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 @@ -6024,13 +6035,27 @@ bool Parser::isDeclarator(Token **pt, int *haveId, int *haveTpl, TOK endtok)
if (!isExpression(&t))
return false;
if (t->value == TOKslice)
{ t = peek(t);
{
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;

Expand Down Expand Up @@ -7754,7 +7779,7 @@ Expression *Parser::parseNewExp(Expression *thisexp)
}

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
2 changes: 1 addition & 1 deletion src/template.c
Original file line number Diff line number Diff line change
Expand Up @@ -3280,7 +3280,7 @@ MATCH deduceType(RootObject *o, Scope *sc, Type *tparam, TemplateParameters *par
{
if (!s || !s->parent)
goto Lnomatch;
Dsymbol *s2 = s->parent->searchX(Loc(), sc, id);
Dsymbol *s2 = s->parent->search(Loc(), (Identifier *)id);
if (!s2)
goto Lnomatch;
s2 = s2->toAlias();
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; }