diff --git a/dmd2/attrib.c b/dmd2/attrib.c index de5c92bb..776565d0 100644 --- a/dmd2/attrib.c +++ b/dmd2/attrib.c @@ -56,7 +56,7 @@ Dsymbols *AttribDeclaration::include(Scope *sc, ScopeDsymbol *sd) int AttribDeclaration::apply(Dsymbol_apply_ft_t fp, void *param) { - Dsymbols *d = include(NULL, NULL); + Dsymbols *d = include(scope, NULL); if (d) { @@ -1278,9 +1278,9 @@ void ConditionalDeclaration::emitComment(Scope *sc) Dsymbols *ConditionalDeclaration::include(Scope *sc, ScopeDsymbol *sd) { - //printf("ConditionalDeclaration::include()\n"); + //printf("ConditionalDeclaration::include(sc = %p) scope = %p\n", sc, scope); assert(condition); - return condition->include(sc, sd) ? decl : elsedecl; + return condition->include(scope ? scope : sc, sd) ? decl : elsedecl; } void ConditionalDeclaration::setScope(Scope *sc) @@ -1440,6 +1440,9 @@ void StaticIfDeclaration::importAll(Scope *sc) void StaticIfDeclaration::setScope(Scope *sc) { // do not evaluate condition before semantic pass + + // But do set the scope, in case we need it for forward referencing + Dsymbol::setScope(sc); } void StaticIfDeclaration::semantic(Scope *sc) @@ -1471,6 +1474,8 @@ const char *StaticIfDeclaration::kind() /***************************** CompileDeclaration *****************************/ +// These are mixin declarations, like mixin("int x"); + CompileDeclaration::CompileDeclaration(Loc loc, Expression *exp) : AttribDeclaration(NULL) { @@ -1544,3 +1549,10 @@ void CompileDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) buf->writestring(");"); buf->writenl(); } + +const char *CompileDeclaration::kind() +{ + return "mixin"; +} + + diff --git a/dmd2/attrib.h b/dmd2/attrib.h index e296677a..6762d338 100644 --- a/dmd2/attrib.h +++ b/dmd2/attrib.h @@ -200,6 +200,7 @@ struct CompileDeclaration : AttribDeclaration void compileIt(Scope *sc); void semantic(Scope *sc); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); + const char *kind(); }; #endif /* DMD_ATTRIB_H */ diff --git a/dmd2/cond.c b/dmd2/cond.c index a37f2738..afce513e 100644 --- a/dmd2/cond.c +++ b/dmd2/cond.c @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2011 by Digital Mars +// Copyright (c) 1999-2012 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -22,6 +22,7 @@ #include "lexer.h" #include "mtype.h" #include "scope.h" +#include "arraytypes.h" int findCondition(Strings *ids, Identifier *ident) { @@ -29,7 +30,7 @@ int findCondition(Strings *ids, Identifier *ident) { for (size_t i = 0; i < ids->dim; i++) { - const char *id = ids->tdata()[i]; + const char *id = (*ids)[i]; if (strcmp(id, ident->toChars()) == 0) return TRUE; @@ -224,6 +225,7 @@ StaticIfCondition::StaticIfCondition(Loc loc, Expression *exp) : Condition(loc) { this->exp = exp; + this->nest = 0; } Condition *StaticIfCondition::syntaxCopy() @@ -234,7 +236,7 @@ Condition *StaticIfCondition::syntaxCopy() int StaticIfCondition::include(Scope *sc, ScopeDsymbol *s) { #if 0 - printf("StaticIfCondition::include(sc = %p, s = %p)\n", sc, s); + printf("StaticIfCondition::include(sc = %p, s = %p) this=%p inc = %d\n", sc, s, this, inc); if (s) { printf("\ts = '%s', kind = %s\n", s->toChars(), s->kind()); @@ -242,6 +244,15 @@ int StaticIfCondition::include(Scope *sc, ScopeDsymbol *s) #endif if (inc == 0) { + if (exp->op == TOKerror || nest > 100) + { + error(loc, (nest > 1000) ? "unresolvable circular static if expression" + : "error evaluating static if expression"); + if (!global.gag) + inc = 2; // so we don't see the error message again + return 0; + } + if (!sc) { error(loc, "static if conditional cannot be at global scope"); @@ -249,13 +260,19 @@ int StaticIfCondition::include(Scope *sc, ScopeDsymbol *s) return 0; } + ++nest; sc = sc->push(sc->scopesym); sc->sd = s; // s gets any addMember() sc->flags |= SCOPEstaticif; Expression *e = exp->semantic(sc); sc->pop(); e = e->optimize(WANTvalue | WANTinterpret); - if (e->isBool(TRUE)) + --nest; + if (e->op == TOKerror) + { exp = e; + inc = 0; + } + else if (e->isBool(TRUE)) inc = 1; else if (e->isBool(FALSE)) inc = 2; @@ -327,7 +344,7 @@ int IftypeCondition::include(Scope *sc, ScopeDsymbol *sd) TemplateParameters parameters; parameters.setDim(1); - parameters.tdata()[0] = &tp; + parameters[0] = &tp; Objects dedtypes; dedtypes.setDim(1); @@ -339,7 +356,7 @@ int IftypeCondition::include(Scope *sc, ScopeDsymbol *sd) else { inc = 1; - Type *tded = (Type *)dedtypes.tdata()[0]; + Type *tded = (Type *)dedtypes[0]; if (!tded) tded = targ; Dsymbol *s = new AliasDeclaration(loc, id, tded); diff --git a/dmd2/cond.h b/dmd2/cond.h index 789503a4..71400314 100644 --- a/dmd2/cond.h +++ b/dmd2/cond.h @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2011 by Digital Mars +// Copyright (c) 1999-2012 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -79,6 +79,7 @@ struct VersionCondition : DVCondition struct StaticIfCondition : Condition { Expression *exp; + int nest; // limit circular dependencies StaticIfCondition(Loc loc, Expression *exp); Condition *syntaxCopy(); diff --git a/dmd2/declaration.c b/dmd2/declaration.c index 2d284b09..4da51432 100644 --- a/dmd2/declaration.c +++ b/dmd2/declaration.c @@ -796,6 +796,7 @@ void VarDeclaration::semantic(Scope *sc) if (!type) { inuse++; + //printf("inferring type for %s with init %s\n", toChars(), init->toChars()); ArrayInitializer *ai = init->isArrayInitializer(); if (ai) { Expression *e; @@ -816,7 +817,6 @@ void VarDeclaration::semantic(Scope *sc) else type = init->inferType(sc); -//printf("test2: %s, %s, %s\n", toChars(), type->toChars(), type->deco); // type = type->semantic(loc, sc); inuse--; @@ -883,7 +883,14 @@ void VarDeclaration::semantic(Scope *sc) Type *tb = type->toBasetype(); if (tb->ty == Tvoid && !(storage_class & STClazy)) - { error("voids have no value"); + { + if (inferred) + { + error("type %s is inferred from initializer %s, and variables cannot be of type void", + type->toChars(), init->toChars()); + } + else + error("variables cannot be of type void"); type = Type::terror; tb = type; } diff --git a/dmd2/expression.c b/dmd2/expression.c index 4363d935..1af2c2ed 100644 --- a/dmd2/expression.c +++ b/dmd2/expression.c @@ -338,7 +338,15 @@ void checkPropertyCall(Expression *e, Expression *emsg) { CallExp *ce = (CallExp *)e; TypeFunction *tf; if (ce->f) + { tf = (TypeFunction *)ce->f->type; + /* If a forward reference to ce->f, try to resolve it + */ + if (!tf->deco && ce->f->scope) + { ce->f->semantic(ce->f->scope); + tf = (TypeFunction *)ce->f->type; + } + } else if (ce->e1->type->ty == Tfunction) tf = (TypeFunction *)ce->e1->type; else if (ce->e1->type->ty == Tdelegate) @@ -390,46 +398,54 @@ Expression *resolveUFCSProperties(Scope *sc, Expression *e1, Expression *e2 = NU else e = new DotIdExp(loc, e, ident); - Expressions *arguments = new Expressions(); - /* .f(e1, e2) - */ if (e2) { - arguments->setDim(2); - (*arguments)[0] = eleft; - (*arguments)[1] = e2; - + /* .f(e1) = e2 + */ Expression *ex = e->syntaxCopy(); - e = new CallExp(loc, e, arguments); - e = e->trySemantic(sc); - if (e) - { checkPropertyCall(e, e1); - return e->semantic(sc); - } - e = ex; - } + Expressions *a1 = new Expressions(); + a1->setDim(1); + (*a1)[0] = eleft; + ex = new CallExp(loc, ex, a1); + ex = ex->trySemantic(sc); - /* .f(e1) - * .f(e1) = e2 - */ + /* .f(e1, e2) + */ + Expressions *a2 = new Expressions(); + a2->setDim(2); + (*a2)[0] = eleft; + (*a2)[1] = e2; + e = new CallExp(loc, e, a2); + if (ex) + { // if fallback setter exists, gag errors + e = e->trySemantic(sc); + if (!e) + { checkPropertyCall(ex, e1); + ex = new AssignExp(loc, ex, e2); + return ex->semantic(sc); + } + } + else + { // strict setter prints errors if fails + e = e->semantic(sc); + } + checkPropertyCall(e, e1); + return e; + } + else { + /* .f(e1) + */ + Expressions *arguments = new Expressions(); arguments->setDim(1); (*arguments)[0] = eleft; e = new CallExp(loc, e, arguments); - e = e->trySemantic(sc); - if (!e) - goto Leprop; + e = e->semantic(sc); checkPropertyCall(e, e1); - if (e2) - e = new AssignExp(loc, e, e2); return e->semantic(sc); } } return e; - -Leprop: - e1->error("not a property %s", e1->toChars()); - return new ErrorExp(); } /****************************** @@ -1045,7 +1061,37 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf, } if (p->storageClass & STCref) { - arg = arg->toLvalue(sc, arg); + if (arg->op == TOKstructliteral) + { + Identifier *idtmp = Lexer::uniqueId("__tmpsl"); + VarDeclaration *tmp = new VarDeclaration(loc, arg->type, idtmp, new ExpInitializer(0, arg)); + tmp->storage_class |= STCctfe; + Expression *ae = new DeclarationExp(loc, tmp); + Expression *e = new CommaExp(loc, ae, new VarExp(loc, tmp)); + e = e->semantic(sc); + + arg = e; + } + else if (arg->op == TOKcall) + { + CallExp *ce = (CallExp *)arg; + if (ce->e1->op == TOKdotvar && + ((DotVarExp *)ce->e1)->var->isCtorDeclaration()) + { + DotVarExp *dve = (DotVarExp *)ce->e1; + assert(dve->e1->op == TOKcomma); + assert(((CommaExp *)dve->e1)->e2->op == TOKvar); + VarExp *ve = (VarExp *)((CommaExp *)dve->e1)->e2; + VarDeclaration *tmp = ve->var->isVarDeclaration(); + + arg = new CommaExp(arg->loc, arg, new VarExp(loc, tmp)); + arg = arg->semantic(sc); + } + else + arg = arg->toLvalue(sc, arg); + } + else + arg = arg->toLvalue(sc, arg); } else if (p->storageClass & STCout) { @@ -6753,9 +6799,29 @@ Expression *DotIdExp::semantic(Scope *sc, int flag) { goto L2; } - unsigned errors = global.startGagging(); + /* This would be much better if we added a "hasProperty" method to types, + * i.e. the gagging is a bad way. + */ + + if (t1b->ty == Taarray) + { + TypeAArray *taa = (TypeAArray *)t1b; + if (!taa->impl && + ident != Id::__sizeof && + ident != Id::__xalignof && + ident != Id::init && + ident != Id::mangleof && + ident != Id::stringof && + ident != Id::offsetof) + { + // Find out about these errors when not gagged + taa->getImpl(); + } + } + Type *t1 = e1->type; - e = e1->type->dotExp(sc, e1, ident); + unsigned errors = global.startGagging(); + e = t1->dotExp(sc, e1, ident); if (global.endGagging(errors)) // if failed to find the property { e1->type = t1; // kludge to restore type @@ -8841,6 +8907,8 @@ Expression *CastExp::semantic(Scope *sc) } else to = to->semantic(loc, sc); + if (to == Type::terror) + return new ErrorExp(); if (!to->equals(e1->type)) { @@ -9091,7 +9159,9 @@ Expression *SliceExp::syntaxCopy() if (this->upr) upr = this->upr->syntaxCopy(); - return new SliceExp(loc, e1->syntaxCopy(), lwr, upr); + SliceExp *se = new SliceExp(loc, e1->syntaxCopy(), lwr, upr); + se->lengthVar = this->lengthVar; // bug7871 + return se; } Expression *SliceExp::semantic(Scope *sc) @@ -9436,7 +9506,9 @@ ArrayExp::ArrayExp(Loc loc, Expression *e1, Expressions *args) Expression *ArrayExp::syntaxCopy() { - return new ArrayExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments)); + ArrayExp *ae = new ArrayExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments)); + ae->lengthVar = this->lengthVar; // bug7871 + return ae; } Expression *ArrayExp::semantic(Scope *sc) @@ -9603,6 +9675,13 @@ IndexExp::IndexExp(Loc loc, Expression *e1, Expression *e2) modifiable = 0; // assume it is an rvalue } +Expression *IndexExp::syntaxCopy() +{ + IndexExp *ie = new IndexExp(loc, e1->syntaxCopy(), e2->syntaxCopy()); + ie->lengthVar = this->lengthVar; // bug7871 + return ie; +} + Expression *IndexExp::semantic(Scope *sc) { Expression *e; Type *t1; diff --git a/dmd2/expression.h b/dmd2/expression.h index 14f3f235..762ff71c 100644 --- a/dmd2/expression.h +++ b/dmd2/expression.h @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2011 by Digital Mars +// Copyright (c) 1999-2012 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -1463,6 +1463,7 @@ struct IndexExp : BinExp int modifiable; IndexExp(Loc loc, Expression *e1, Expression *e2); + Expression *syntaxCopy(); Expression *semantic(Scope *sc); int isLvalue(); Expression *toLvalue(Scope *sc, Expression *e); diff --git a/dmd2/func.c b/dmd2/func.c index 81f2ace2..eb512522 100644 --- a/dmd2/func.c +++ b/dmd2/func.c @@ -190,6 +190,11 @@ void FuncDeclaration::semantic(Scope *sc) semanticRun = PASSsemantic; } + if (scope) + { sc = scope; + scope = NULL; + } + unsigned dprogress_save = Module::dprogress; foverrides.setDim(0); // reset in case semantic() is being retried for this function @@ -2895,6 +2900,9 @@ int FuncDeclaration::isImportedSymbol() int FuncDeclaration::isVirtual() { + if (toAliasFunc() != this) + return toAliasFunc()->isVirtual(); + Dsymbol *p = toParent(); #if 0 printf("FuncDeclaration::isVirtual(%s)\n", toChars()); @@ -2915,6 +2923,9 @@ int FuncDeclaration::isVirtual() int FuncDeclaration::isVirtualMethod() { + if (toAliasFunc() != this) + return toAliasFunc()->isVirtualMethod(); + //printf("FuncDeclaration::isVirtualMethod() %s\n", toChars()); if (!isVirtual()) return 0; @@ -2928,6 +2939,9 @@ int FuncDeclaration::isVirtualMethod() int FuncDeclaration::isFinal() { + if (toAliasFunc() != this) + return toAliasFunc()->isFinal(); + ClassDeclaration *cd; #if 0 printf("FuncDeclaration::isFinal(%s), %x\n", toChars(), Declaration::isFinal()); @@ -3444,6 +3458,11 @@ void CtorDeclaration::semantic(Scope *sc) TypeFunction *tf = (TypeFunction *)type; assert(tf && tf->ty == Tfunction); + if (scope) + { sc = scope; + scope = NULL; + } + sc = sc->push(); sc->stc &= ~STCstatic; // not a static constructor sc->flags |= SCOPEctor; @@ -3563,6 +3582,10 @@ void PostBlitDeclaration::semantic(Scope *sc) //printf("PostBlitDeclaration::semantic() %s\n", toChars()); //printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor); //printf("stc = x%llx\n", sc->stc); + if (scope) + { sc = scope; + scope = NULL; + } parent = sc->parent; Dsymbol *parent = toParent(); StructDeclaration *ad = parent->isStructDeclaration(); @@ -3636,6 +3659,10 @@ void DtorDeclaration::semantic(Scope *sc) { //printf("DtorDeclaration::semantic() %s\n", toChars()); //printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor); + if (scope) + { sc = scope; + scope = NULL; + } parent = sc->parent; Dsymbol *parent = toParent(); AggregateDeclaration *ad = parent->isAggregateDeclaration(); @@ -3728,6 +3755,11 @@ void StaticCtorDeclaration::semantic(Scope *sc) { //printf("StaticCtorDeclaration::semantic()\n"); + if (scope) + { sc = scope; + scope = NULL; + } + if (!type) type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); @@ -3856,6 +3888,11 @@ Dsymbol *StaticDtorDeclaration::syntaxCopy(Dsymbol *s) void StaticDtorDeclaration::semantic(Scope *sc) { + if (scope) + { sc = scope; + scope = NULL; + } + ClassDeclaration *cd = sc->scopesym->isClassDeclaration(); if (!type) @@ -3983,6 +4020,10 @@ Dsymbol *InvariantDeclaration::syntaxCopy(Dsymbol *s) void InvariantDeclaration::semantic(Scope *sc) { + if (scope) + { sc = scope; + scope = NULL; + } parent = sc->parent; Dsymbol *parent = toParent(); AggregateDeclaration *ad = parent->isAggregateDeclaration(); @@ -4063,6 +4104,10 @@ Dsymbol *UnitTestDeclaration::syntaxCopy(Dsymbol *s) void UnitTestDeclaration::semantic(Scope *sc) { + if (scope) + { sc = scope; + scope = NULL; + } #if IN_LLVM if (global.params.useUnitTests && sc->module->isRoot) #else @@ -4150,6 +4195,11 @@ void NewDeclaration::semantic(Scope *sc) { //printf("NewDeclaration::semantic()\n"); + if (scope) + { sc = scope; + scope = NULL; + } + parent = sc->parent; Dsymbol *parent = toParent(); ClassDeclaration *cd = parent->isClassDeclaration(); @@ -4234,6 +4284,11 @@ void DeleteDeclaration::semantic(Scope *sc) { //printf("DeleteDeclaration::semantic()\n"); + if (scope) + { sc = scope; + scope = NULL; + } + parent = sc->parent; Dsymbol *parent = toParent(); ClassDeclaration *cd = parent->isClassDeclaration(); diff --git a/dmd2/init.c b/dmd2/init.c index c5a834b7..5de6b114 100644 --- a/dmd2/init.c +++ b/dmd2/init.c @@ -21,6 +21,7 @@ #include "scope.h" #include "mtype.h" #include "hdrgen.h" +#include "template.h" /********************************** Initializer *******************************/ @@ -160,8 +161,18 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret) if (ad->ctor) error(loc, "%s %s has constructors, cannot use { initializers }, use %s( initializers ) instead", ad->kind(), ad->toChars(), ad->toChars()); - size_t nfields = ad->fields.dim; - if (((StructDeclaration *)ad)->isnested) nfields--; + StructDeclaration *sd = ad->isStructDeclaration(); + assert(sd); + sd->size(loc); + if (sd->sizeok != SIZEOKdone) + { + error(loc, "struct %s is forward referenced", sd->toChars()); + errors = 1; + goto Lerror; + } + size_t nfields = sd->fields.dim; + if (sd->isnested) + nfields--; for (size_t i = 0; i < field.dim; i++) { Identifier *id = field[i]; @@ -244,6 +255,7 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret) error(loc, "a struct is not a valid initializer for a %s", t->toChars()); errors = 1; } +Lerror: if (errors) { field.setDim(0); @@ -264,12 +276,11 @@ Expression *StructInitializer::toExpression() //printf("StructInitializer::toExpression() %s\n", toChars()); if (!ad) // if fwd referenced - { return NULL; - } StructDeclaration *sd = ad->isStructDeclaration(); if (!sd) return NULL; + Expressions *elements = new Expressions(); size_t nfields = ad->fields.dim; #if DMDV2 @@ -870,6 +881,15 @@ Type *ExpInitializer::inferType(Scope *sc) //printf("ExpInitializer::inferType() %s\n", toChars()); exp = exp->semantic(sc); exp = resolveProperties(sc, exp); + if (exp->op == TOKimport) + { ScopeExp *se = (ScopeExp *)exp; + TemplateInstance *ti = se->sds->isTemplateInstance(); + if (ti && ti->semanticRun == PASSsemantic && !ti->aliasdecl) + se->error("cannot infer type from %s %s, possible circular dependency", se->sds->kind(), se->toChars()); + else + se->error("cannot infer type from %s %s", se->sds->kind(), se->toChars()); + return Type::terror; + } // Give error for overloaded function addresses if (exp->op == TOKsymoff) diff --git a/dmd2/interpret.c b/dmd2/interpret.c index 1dcecd02..425a836d 100644 --- a/dmd2/interpret.c +++ b/dmd2/interpret.c @@ -6786,7 +6786,8 @@ Expression *TypeStruct::voidInitLiteral(VarDeclaration *var) exps->setDim(sym->fields.dim); for (size_t i = 0; i < sym->fields.dim; i++) { - (*exps)[i] = new VoidInitExp(var, sym->fields[i]->type); + //(*exps)[i] = new VoidInitExp(var, sym->fields[i]->type); + (*exps)[i] = sym->fields[i]->type->voidInitLiteral(var); } StructLiteralExp *se = new StructLiteralExp(var->loc, sym, exps); se->type = this; diff --git a/dmd2/module.c b/dmd2/module.c index 367ed43b..bd381808 100644 --- a/dmd2/module.c +++ b/dmd2/module.c @@ -1000,6 +1000,8 @@ void Module::semantic2(Scope* unused_sc) return; } //printf("Module::semantic2('%s'): parent = %p\n", toChars(), parent); + if (semanticRun == 0) // semantic() not completed yet - could be recursive call + return; if (semanticstarted >= 2) return; assert(semanticstarted == 1); diff --git a/dmd2/mtype.c b/dmd2/mtype.c index 1eaf106b..48d23e9a 100644 --- a/dmd2/mtype.c +++ b/dmd2/mtype.c @@ -6066,6 +6066,19 @@ int TypeFunction::callMatch(Expression *ethis, Expressions *args, int flag) new IntegerExp(0, ((StringExp *)arg)->len, Type::tindex)); } + else if (arg->op == TOKstructliteral) + match = MATCHconvert; + else if (arg->op == TOKcall) + { + CallExp *ce = (CallExp *)arg; + if (ce->e1->op == TOKdotvar && + ((DotVarExp *)ce->e1)->var->isCtorDeclaration()) + { + match = MATCHconvert; + } + else + goto Nomatch; + } else goto Nomatch; } @@ -7933,7 +7946,15 @@ Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident) L1: if (!s) { - return noMember(sc, e, ident); + if (sym->scope) // it's a fwd ref, maybe we can resolve it + { + sym->semantic(NULL); + s = sym->search(e->loc, ident, 0); + if (!s) + return noMember(sc, e, ident); + } + else + return noMember(sc, e, ident); } if (!s->isFuncDeclaration()) // because of overloading s->checkDeprecated(e->loc, sc); diff --git a/dmd2/struct.c b/dmd2/struct.c index b3c8cba3..51e6c3a7 100644 --- a/dmd2/struct.c +++ b/dmd2/struct.c @@ -465,7 +465,7 @@ void StructDeclaration::semantic(Scope *sc) */ //if (s->isEnumDeclaration() || (s->isAggregateDeclaration() && s->ident)) { - //printf("setScope %s %s\n", s->kind(), s->toChars()); + //printf("struct: setScope %s %s\n", s->kind(), s->toChars()); s->setScope(sc2); } } @@ -487,7 +487,9 @@ void StructDeclaration::semantic(Scope *sc) // Ungag errors when not speculative unsigned oldgag = global.gag; if (global.isSpeculativeGagging() && !isSpeculative()) + { global.gag = 0; + } s->semantic(sc2); global.gag = oldgag; } diff --git a/dmd2/template.c b/dmd2/template.c index 63f8ae54..6bf52076 100644 --- a/dmd2/template.c +++ b/dmd2/template.c @@ -1510,7 +1510,23 @@ Lretry: if (m && (fparam->storageClass & (STCref | STCauto)) == STCref) { if (!farg->isLvalue()) - goto Lnomatch; + { + if (farg->op == TOKstructliteral) + m = MATCHconvert; + else if (farg->op == TOKcall) + { + CallExp *ce = (CallExp *)farg; + if (ce->e1->op == TOKdotvar && + ((DotVarExp *)ce->e1)->var->isCtorDeclaration()) + { + m = MATCHconvert; + } + else + goto Lnomatch; + } + else + goto Lnomatch; + } } if (m && (fparam->storageClass & STCout)) { if (!farg->isLvalue()) @@ -2326,7 +2342,7 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, *wildmatch |= MODmutable; else *wildmatch |= (mod & ~MODshared); - tt = mutableOf(); + tt = mutableOf()->substWildTo(MODmutable); dedtypes->tdata()[i] = tt; goto Lconst; } diff --git a/dmd2/traits.c b/dmd2/traits.c index 911fc6fe..68f7b2a1 100644 --- a/dmd2/traits.c +++ b/dmd2/traits.c @@ -528,6 +528,11 @@ Expression *TraitsExp::semantic(Scope *sc) s1 = s1->toAlias(); s2 = s2->toAlias(); + if (s1->isFuncAliasDeclaration()) + s1 = ((FuncAliasDeclaration *)s1)->toAliasFunc(); + if (s2->isFuncAliasDeclaration()) + s2 = ((FuncAliasDeclaration *)s2)->toAliasFunc(); + if (s1 == s2) goto Ltrue; else diff --git a/runtime/druntime b/runtime/druntime index 946b499b..90a1a8ae 160000 --- a/runtime/druntime +++ b/runtime/druntime @@ -1 +1 @@ -Subproject commit 946b499bd64a7c1714baa5627a8b76b1a14859a3 +Subproject commit 90a1a8ae84a3d58ff8e8bb6e2358181f8a202bbc diff --git a/runtime/phobos b/runtime/phobos index d8574009..2bc3677a 160000 --- a/runtime/phobos +++ b/runtime/phobos @@ -1 +1 @@ -Subproject commit d857400952d9d9d33ac8768c400b61e2ee1abd83 +Subproject commit 2bc3677ac0446e1334c5f9397f69f9c05154cdd3