d: Merge upstream dmd, druntime d29e3eca45
D front-end changes: - Error messages related to operator overloading have been improved. D runtime changes: - Import latest fixes from druntime. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd d29e3eca45. * d-codegen.cc (can_elide_copy_p): Update for new front-end interface. * d-lang.cc (d_handle_option): Likewise. * expr.cc (class ExprVisitor): Likewise. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime d29e3eca45.
This commit is contained in:
parent
e8c9f4ab8f
commit
df1f6b9857
82 changed files with 1204 additions and 1037 deletions
|
@ -637,7 +637,7 @@ static bool
|
|||
can_elide_copy_p (Expression *exp)
|
||||
{
|
||||
/* Explicit `__rvalue(exp)'. */
|
||||
if (exp->rvalue)
|
||||
if (exp->rvalue ())
|
||||
return true;
|
||||
|
||||
/* Look for variable expression. */
|
||||
|
|
|
@ -450,7 +450,7 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
|
|||
break;
|
||||
|
||||
case OPT_fdebug:
|
||||
global.params.debuglevel = value ? 1 : 0;
|
||||
global.params.debugEnabled = value ? true : false;
|
||||
break;
|
||||
|
||||
case OPT_fdebug_:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
b7e3b3b61711bf6c6cad27c7b5b73df0e570c215
|
||||
d29e3eca45edaeef63b31f78c9846fc6e2870c49
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the dlang/dmd repository.
|
||||
|
|
|
@ -142,7 +142,7 @@ private bool hasPackageAccess(Module mod, Dsymbol s)
|
|||
/****************************************
|
||||
* Determine if scope sc has protected level access to cd.
|
||||
*/
|
||||
private bool hasProtectedAccess(Scope *sc, Dsymbol s)
|
||||
private bool hasProtectedAccess(Scope* sc, Dsymbol s)
|
||||
{
|
||||
if (auto cd = s.isClassMember()) // also includes interfaces
|
||||
{
|
||||
|
@ -273,7 +273,7 @@ bool symbolIsVisible(Dsymbol origin, Dsymbol s)
|
|||
* s = symbol to check for visibility
|
||||
* Returns: true if s is visible by origin
|
||||
*/
|
||||
bool symbolIsVisible(Scope *sc, Dsymbol s)
|
||||
bool symbolIsVisible(Scope* sc, Dsymbol s)
|
||||
{
|
||||
s = mostVisibleOverload(s);
|
||||
return checkSymbolAccess(sc, s);
|
||||
|
@ -288,7 +288,7 @@ bool symbolIsVisible(Scope *sc, Dsymbol s)
|
|||
* s = symbol to check for visibility
|
||||
* Returns: true if s is visible by origin
|
||||
*/
|
||||
bool checkSymbolAccess(Scope *sc, Dsymbol s)
|
||||
bool checkSymbolAccess(Scope* sc, Dsymbol s)
|
||||
{
|
||||
final switch (s.visible().kind)
|
||||
{
|
||||
|
|
|
@ -447,7 +447,8 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
|
|||
s.isTemplateDeclaration() ||
|
||||
s.isOverloadSet()))
|
||||
{
|
||||
.error(s.loc, "%s `%s` is not a constructor; identifiers starting with `__` are reserved for the implementation", s.kind(), s.toPrettyChars());
|
||||
error(s.loc, "%s name `__ctor` is not allowed", s.kind);
|
||||
errorSupplemental(s.loc, "identifiers starting with `__` are reserved for internal use");
|
||||
errors = true;
|
||||
s = null;
|
||||
}
|
||||
|
|
|
@ -44,12 +44,12 @@ bool isArrayOpValid(Expression e)
|
|||
if (e.op == EXP.arrayLiteral)
|
||||
{
|
||||
Type t = e.type.toBasetype();
|
||||
while (t.ty == Tarray || t.ty == Tsarray)
|
||||
while (t.isStaticOrDynamicArray())
|
||||
t = t.nextOf().toBasetype();
|
||||
return (t.ty != Tvoid);
|
||||
}
|
||||
Type tb = e.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (isUnaArrayOp(e.op))
|
||||
{
|
||||
|
@ -80,7 +80,7 @@ bool isNonAssignmentArrayOp(Expression e)
|
|||
return isNonAssignmentArrayOp(e.isSliceExp().e1);
|
||||
|
||||
Type tb = e.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
return (isUnaArrayOp(e.op) || isBinArrayOp(e.op));
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ Expression arrayOp(BinExp e, Scope* sc)
|
|||
{
|
||||
//printf("BinExp.arrayOp() %s\n", e.toChars());
|
||||
Type tb = e.type.toBasetype();
|
||||
assert(tb.ty == Tarray || tb.ty == Tsarray);
|
||||
assert(tb.isStaticOrDynamicArray());
|
||||
Type tbn = tb.nextOf().toBasetype();
|
||||
if (tbn.ty == Tvoid)
|
||||
{
|
||||
|
@ -346,7 +346,7 @@ bool isArrayOpOperand(Expression e)
|
|||
if (e.op == EXP.arrayLiteral)
|
||||
{
|
||||
Type t = e.type.toBasetype();
|
||||
while (t.ty == Tarray || t.ty == Tsarray)
|
||||
while (t.isStaticOrDynamicArray())
|
||||
t = t.nextOf().toBasetype();
|
||||
return (t.ty != Tvoid);
|
||||
}
|
||||
|
|
|
@ -271,17 +271,6 @@ extern (C++) final class LinkDeclaration : AttribDeclaration
|
|||
return new LinkDeclaration(loc, linkage, Dsymbol.arraySyntaxCopy(decl));
|
||||
}
|
||||
|
||||
|
||||
override const(char)* toChars() const
|
||||
{
|
||||
return toString().ptr;
|
||||
}
|
||||
|
||||
extern(D) override const(char)[] toString() const
|
||||
{
|
||||
return "extern ()";
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
{
|
||||
v.visit(this);
|
||||
|
@ -313,16 +302,6 @@ extern (C++) final class CPPMangleDeclaration : AttribDeclaration
|
|||
return new CPPMangleDeclaration(loc, cppmangle, Dsymbol.arraySyntaxCopy(decl));
|
||||
}
|
||||
|
||||
override const(char)* toChars() const
|
||||
{
|
||||
return toString().ptr;
|
||||
}
|
||||
|
||||
extern(D) override const(char)[] toString() const
|
||||
{
|
||||
return "extern ()";
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
{
|
||||
v.visit(this);
|
||||
|
@ -383,16 +362,6 @@ extern (C++) final class CPPNamespaceDeclaration : AttribDeclaration
|
|||
this.loc, this.ident, this.exp, Dsymbol.arraySyntaxCopy(this.decl), this.cppnamespace);
|
||||
}
|
||||
|
||||
override const(char)* toChars() const
|
||||
{
|
||||
return toString().ptr;
|
||||
}
|
||||
|
||||
extern(D) override const(char)[] toString() const
|
||||
{
|
||||
return "extern (C++, `namespace`)";
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
{
|
||||
v.visit(this);
|
||||
|
|
|
@ -67,7 +67,6 @@ public:
|
|||
|
||||
static LinkDeclaration *create(const Loc &loc, LINK p, Dsymbols *decl);
|
||||
LinkDeclaration *syntaxCopy(Dsymbol *s) override;
|
||||
const char *toChars() const override;
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
};
|
||||
|
||||
|
@ -77,7 +76,6 @@ public:
|
|||
CPPMANGLE cppmangle;
|
||||
|
||||
CPPMangleDeclaration *syntaxCopy(Dsymbol *s) override;
|
||||
const char *toChars() const override;
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
};
|
||||
|
||||
|
@ -87,7 +85,6 @@ public:
|
|||
Expression *exp;
|
||||
|
||||
CPPNamespaceDeclaration *syntaxCopy(Dsymbol *s) override;
|
||||
const char *toChars() const override;
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
};
|
||||
|
||||
|
|
|
@ -166,7 +166,7 @@ extern (C++) final class StaticForeach : RootObject
|
|||
return;
|
||||
}
|
||||
|
||||
Expressions *es;
|
||||
Expressions* es;
|
||||
if (auto ale = aggr.isArrayLiteralExp())
|
||||
{
|
||||
// Directly use the elements of the array for the TupleExp creation
|
||||
|
@ -493,15 +493,13 @@ extern (C++) final class StaticForeach : RootObject
|
|||
*/
|
||||
extern (C++) class DVCondition : Condition
|
||||
{
|
||||
uint level;
|
||||
Identifier ident;
|
||||
Module mod;
|
||||
|
||||
extern (D) this(const ref Loc loc, Module mod, uint level, Identifier ident) @safe
|
||||
extern (D) this(const ref Loc loc, Module mod, Identifier ident) @safe
|
||||
{
|
||||
super(loc);
|
||||
this.mod = mod;
|
||||
this.level = level;
|
||||
this.ident = ident;
|
||||
}
|
||||
|
||||
|
@ -556,15 +554,13 @@ extern (C++) final class DebugCondition : DVCondition
|
|||
*
|
||||
* Params:
|
||||
* mod = Module this node belongs to
|
||||
* level = Minimum global level this condition needs to pass.
|
||||
* Only used if `ident` is `null`.
|
||||
* ident = Identifier required for this condition to pass.
|
||||
* If `null`, this conditiion will use an integer level.
|
||||
* loc = Location in the source file
|
||||
*/
|
||||
extern (D) this(const ref Loc loc, Module mod, uint level, Identifier ident) @safe
|
||||
extern (D) this(const ref Loc loc, Module mod, Identifier ident) @safe
|
||||
{
|
||||
super(loc, mod, level, ident);
|
||||
super(loc, mod, ident);
|
||||
}
|
||||
|
||||
override int include(Scope* sc)
|
||||
|
@ -592,8 +588,9 @@ extern (C++) final class DebugCondition : DVCondition
|
|||
mod.debugidsNot.push(ident);
|
||||
}
|
||||
}
|
||||
else if (level <= global.params.debuglevel || level <= mod.debuglevel)
|
||||
else if (global.params.debugEnabled)
|
||||
inc = Include.yes;
|
||||
|
||||
if (!definedInModule)
|
||||
printDepsConditional(sc, this, "depsDebug ");
|
||||
return (inc == Include.yes);
|
||||
|
@ -608,11 +605,6 @@ extern (C++) final class DebugCondition : DVCondition
|
|||
{
|
||||
v.visit(this);
|
||||
}
|
||||
|
||||
override const(char)* toChars() const
|
||||
{
|
||||
return ident ? ident.toChars() : "debug".ptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -837,15 +829,13 @@ extern (C++) final class VersionCondition : DVCondition
|
|||
*
|
||||
* Params:
|
||||
* mod = Module this node belongs to
|
||||
* level = Minimum global level this condition needs to pass.
|
||||
* Only used if `ident` is `null`.
|
||||
* ident = Identifier required for this condition to pass.
|
||||
* If `null`, this conditiion will use an integer level.
|
||||
* loc = Location in the source file
|
||||
*/
|
||||
extern (D) this(const ref Loc loc, Module mod, uint level, Identifier ident) @safe
|
||||
extern (D) this(const ref Loc loc, Module mod, Identifier ident) @safe
|
||||
{
|
||||
super(loc, mod, level, ident);
|
||||
super(loc, mod, ident);
|
||||
}
|
||||
|
||||
override int include(Scope* sc)
|
||||
|
@ -875,8 +865,6 @@ extern (C++) final class VersionCondition : DVCondition
|
|||
mod.versionidsNot.push(ident);
|
||||
}
|
||||
}
|
||||
else if (level <= global.params.versionlevel || level <= mod.versionlevel)
|
||||
inc = Include.yes;
|
||||
if (!definedInModule &&
|
||||
(!ident || (!isReserved(ident.toString()) && ident != Id._unittest && ident != Id._assert)))
|
||||
{
|
||||
|
@ -894,11 +882,6 @@ extern (C++) final class VersionCondition : DVCondition
|
|||
{
|
||||
v.visit(this);
|
||||
}
|
||||
|
||||
override const(char)* toChars() const
|
||||
{
|
||||
return ident ? ident.toChars() : "version".ptr;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
|
@ -968,11 +951,6 @@ extern (C++) final class StaticIfCondition : Condition
|
|||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
override const(char)* toChars() const
|
||||
{
|
||||
return exp ? exp.toChars() : "static if".ptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1010,7 +988,5 @@ private void printDepsConditional(Scope* sc, DVCondition condition, const(char)[
|
|||
ob.writestring(") : ");
|
||||
if (condition.ident)
|
||||
ob.writestring(condition.ident.toString());
|
||||
else
|
||||
ob.print(condition.level);
|
||||
ob.writeByte('\n');
|
||||
}
|
||||
|
|
|
@ -58,7 +58,6 @@ public:
|
|||
class DVCondition : public Condition
|
||||
{
|
||||
public:
|
||||
unsigned level;
|
||||
Identifier *ident;
|
||||
Module *mod;
|
||||
|
||||
|
|
|
@ -2990,7 +2990,7 @@ final class CParser(AST) : Parser!AST
|
|||
if (isStatic || mod)
|
||||
error("static or type qualifier used outside of function prototype");
|
||||
}
|
||||
if (ts.isTypeSArray() || ts.isTypeDArray())
|
||||
if (ts.isStaticOrDynamicArray())
|
||||
{
|
||||
/* C11 6.7.6.2-1: type qualifiers and 'static' shall only appear
|
||||
* in the outermost array type derivation.
|
||||
|
|
|
@ -48,7 +48,6 @@ class ThrownExceptionExp final : public Expression
|
|||
{
|
||||
public:
|
||||
ClassReferenceExp *thrown; // the thing being tossed
|
||||
const char *toChars() const override;
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
};
|
||||
|
||||
|
@ -58,6 +57,4 @@ public:
|
|||
|
||||
class CTFEExp final : public Expression
|
||||
{
|
||||
public:
|
||||
const char *toChars() const override;
|
||||
};
|
||||
|
|
|
@ -688,7 +688,7 @@ Expression getAggregateFromPointer(Expression e, dinteger_t* ofs)
|
|||
if (auto ie = e.isIndexExp())
|
||||
{
|
||||
// Note that each AA element is part of its own memory block
|
||||
if ((ie.e1.type.ty == Tarray || ie.e1.type.ty == Tsarray || ie.e1.op == EXP.string_ || ie.e1.op == EXP.arrayLiteral) && ie.e2.op == EXP.int64)
|
||||
if ((ie.e1.type.isStaticOrDynamicArray() || ie.e1.op == EXP.string_ || ie.e1.op == EXP.arrayLiteral) && ie.e2.op == EXP.int64)
|
||||
{
|
||||
*ofs = ie.e2.toInteger();
|
||||
return ie.e1;
|
||||
|
@ -697,7 +697,7 @@ Expression getAggregateFromPointer(Expression e, dinteger_t* ofs)
|
|||
if (auto se = e.isSliceExp())
|
||||
{
|
||||
if (se && e.type.toBasetype().ty == Tsarray &&
|
||||
(se.e1.type.ty == Tarray || se.e1.type.ty == Tsarray || se.e1.op == EXP.string_ || se.e1.op == EXP.arrayLiteral) && se.lwr.op == EXP.int64)
|
||||
(se.e1.type.isStaticOrDynamicArray() || se.e1.op == EXP.string_ || se.e1.op == EXP.arrayLiteral) && se.lwr.op == EXP.int64)
|
||||
{
|
||||
*ofs = se.lwr.toInteger();
|
||||
return se.e1;
|
||||
|
@ -1841,7 +1841,7 @@ bool isCtfeValueValid(Expression newval)
|
|||
const SliceExp se = newval.isSliceExp();
|
||||
assert(se.lwr && se.lwr.op == EXP.int64);
|
||||
assert(se.upr && se.upr.op == EXP.int64);
|
||||
return (tb.ty == Tarray || tb.ty == Tsarray) && (se.e1.op == EXP.string_ || se.e1.op == EXP.arrayLiteral);
|
||||
return tb.isStaticOrDynamicArray() && (se.e1.op == EXP.string_ || se.e1.op == EXP.arrayLiteral);
|
||||
}
|
||||
|
||||
case EXP.void_:
|
||||
|
|
|
@ -338,13 +338,13 @@ const(char)* parametersTypeToChars(ParameterList pl)
|
|||
/***********************************************************
|
||||
* iasm.d
|
||||
*/
|
||||
Statement asmSemantic(AsmStatement s, Scope *sc)
|
||||
Statement asmSemantic(AsmStatement s, Scope* sc)
|
||||
{
|
||||
import dmd.iasm;
|
||||
return dmd.iasm.asmSemantic(s, sc);
|
||||
}
|
||||
|
||||
void asmSemantic(CAsmDeclaration d, Scope *sc)
|
||||
void asmSemantic(CAsmDeclaration d, Scope* sc)
|
||||
{
|
||||
import dmd.iasm;
|
||||
return dmd.iasm.asmSemantic(d, sc);
|
||||
|
@ -353,13 +353,13 @@ void asmSemantic(CAsmDeclaration d, Scope *sc)
|
|||
/***********************************************************
|
||||
* iasmgcc.d
|
||||
*/
|
||||
Statement gccAsmSemantic(GccAsmStatement s, Scope *sc)
|
||||
Statement gccAsmSemantic(GccAsmStatement s, Scope* sc)
|
||||
{
|
||||
import dmd.iasmgcc;
|
||||
return dmd.iasmgcc.gccAsmSemantic(s, sc);
|
||||
}
|
||||
|
||||
void gccAsmSemantic(CAsmDeclaration d, Scope *sc)
|
||||
void gccAsmSemantic(CAsmDeclaration d, Scope* sc)
|
||||
{
|
||||
import dmd.iasmgcc;
|
||||
return dmd.iasmgcc.gccAsmSemantic(d, sc);
|
||||
|
|
|
@ -626,7 +626,7 @@ MATCH implicitConvTo(Expression e, Type t)
|
|||
if (!e.committed && t.ty == Tpointer && t.nextOf().ty == Tvoid)
|
||||
return MATCH.nomatch;
|
||||
|
||||
if (!(e.type.ty == Tsarray || e.type.ty == Tarray || e.type.ty == Tpointer))
|
||||
if (!(e.type.isStaticOrDynamicArray() || e.type.ty == Tpointer))
|
||||
return visit(e);
|
||||
|
||||
TY tyn = e.type.nextOf().ty;
|
||||
|
@ -758,8 +758,7 @@ MATCH implicitConvTo(Expression e, Type t)
|
|||
Type typeb = e.type.toBasetype();
|
||||
|
||||
auto result = MATCH.nomatch;
|
||||
if ((tb.ty == Tarray || tb.ty == Tsarray) &&
|
||||
(typeb.ty == Tarray || typeb.ty == Tsarray))
|
||||
if (tb.isStaticOrDynamicArray() && typeb.isStaticOrDynamicArray())
|
||||
{
|
||||
result = MATCH.exact;
|
||||
Type typen = typeb.nextOf().toBasetype();
|
||||
|
@ -802,7 +801,7 @@ MATCH implicitConvTo(Expression e, Type t)
|
|||
|
||||
return result;
|
||||
}
|
||||
else if (tb.ty == Tvector && (typeb.ty == Tarray || typeb.ty == Tsarray || typeb.ty == Tpointer))
|
||||
else if (tb.ty == Tvector && (typeb.isStaticOrDynamicArray() || typeb.ty == Tpointer))
|
||||
{ // Tpointer because ImportC eagerly converts Tsarray to Tpointer
|
||||
result = MATCH.exact;
|
||||
// Convert array literal to vector type
|
||||
|
@ -2724,8 +2723,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
|
|||
}
|
||||
Type typeb = e.type.toBasetype();
|
||||
|
||||
if ((tb.ty == Tarray || tb.ty == Tsarray) &&
|
||||
(typeb.ty == Tarray || typeb.ty == Tsarray))
|
||||
if (tb.isStaticOrDynamicArray() && typeb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (tb.nextOf().toBasetype().ty == Tvoid && typeb.nextOf().toBasetype().ty != Tvoid)
|
||||
{
|
||||
|
@ -2768,7 +2766,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
|
|||
ae.type = tp;
|
||||
}
|
||||
}
|
||||
else if (tb.ty == Tvector && (typeb.ty == Tarray || typeb.ty == Tsarray || typeb.ty == Tpointer))
|
||||
else if (tb.ty == Tvector && (typeb.isStaticOrDynamicArray() || typeb.ty == Tpointer))
|
||||
{
|
||||
// Convert array literal to vector type
|
||||
// The Tpointer case comes from C eagerly converting Tsarray to Tpointer
|
||||
|
@ -3140,7 +3138,7 @@ Expression inferType(Expression e, Type t, int flag = 0)
|
|||
Expression visitAle(ArrayLiteralExp ale)
|
||||
{
|
||||
Type tb = t.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
Type tn = tb.nextOf();
|
||||
if (ale.basis)
|
||||
|
@ -3284,7 +3282,7 @@ private bool isVoidArrayLiteral(Expression e, Type other)
|
|||
{
|
||||
auto ale = e.isArrayLiteralExp();
|
||||
e = ale[0];
|
||||
if (other.ty == Tsarray || other.ty == Tarray)
|
||||
if (other.isStaticOrDynamicArray())
|
||||
other = other.nextOf();
|
||||
else
|
||||
return false;
|
||||
|
@ -3550,7 +3548,7 @@ Lagain:
|
|||
return null;
|
||||
}
|
||||
|
||||
if ((t1.ty == Tsarray || t1.ty == Tarray) && (e2.op == EXP.null_ && t2.ty == Tpointer && t2.nextOf().ty == Tvoid || e2.op == EXP.arrayLiteral && t2.ty == Tsarray && t2.nextOf().ty == Tvoid && t2.isTypeSArray().dim.toInteger() == 0 || isVoidArrayLiteral(e2, t1)))
|
||||
if (t1.isStaticOrDynamicArray() && (e2.op == EXP.null_ && t2.ty == Tpointer && t2.nextOf().ty == Tvoid || e2.op == EXP.arrayLiteral && t2.ty == Tsarray && t2.nextOf().ty == Tvoid && t2.isTypeSArray().dim.toInteger() == 0 || isVoidArrayLiteral(e2, t1)))
|
||||
{
|
||||
/* (T[n] op void*) => T[]
|
||||
* (T[] op void*) => T[]
|
||||
|
@ -3562,7 +3560,9 @@ Lagain:
|
|||
return coerce(t1.nextOf().arrayOf());
|
||||
}
|
||||
|
||||
if ((t2.ty == Tsarray || t2.ty == Tarray) && (e1.op == EXP.null_ && t1.ty == Tpointer && t1.nextOf().ty == Tvoid || e1.op == EXP.arrayLiteral && t1.ty == Tsarray && t1.nextOf().ty == Tvoid && t1.isTypeSArray().dim.toInteger() == 0 || isVoidArrayLiteral(e1, t2)))
|
||||
if (t2.isStaticOrDynamicArray() &&
|
||||
(e1.op == EXP.null_ && t1.ty == Tpointer && t1.nextOf().ty == Tvoid || e1.op == EXP.arrayLiteral
|
||||
&& t1.ty == Tsarray && t1.nextOf().ty == Tvoid && t1.isTypeSArray().dim.toInteger() == 0 || isVoidArrayLiteral(e1, t2)))
|
||||
{
|
||||
/* (void* op T[n]) => T[]
|
||||
* (void* op T[]) => T[]
|
||||
|
@ -3574,7 +3574,7 @@ Lagain:
|
|||
return coerce(t2.nextOf().arrayOf());
|
||||
}
|
||||
|
||||
if ((t1.ty == Tsarray || t1.ty == Tarray) && (m = t1.implicitConvTo(t2)) != MATCH.nomatch)
|
||||
if (t1.isStaticOrDynamicArray() && (m = t1.implicitConvTo(t2)) != MATCH.nomatch)
|
||||
{
|
||||
// https://issues.dlang.org/show_bug.cgi?id=7285
|
||||
// Tsarray op [x, y, ...] should to be Tsarray
|
||||
|
@ -3590,7 +3590,7 @@ Lagain:
|
|||
return convert(e1, t2);
|
||||
}
|
||||
|
||||
if ((t2.ty == Tsarray || t2.ty == Tarray) && t2.implicitConvTo(t1))
|
||||
if (t2.isStaticOrDynamicArray() && t2.implicitConvTo(t1))
|
||||
{
|
||||
// https://issues.dlang.org/show_bug.cgi?id=7285
|
||||
// https://issues.dlang.org/show_bug.cgi?id=14737
|
||||
|
@ -3599,7 +3599,8 @@ Lagain:
|
|||
return convert(e2, t1);
|
||||
}
|
||||
|
||||
if ((t1.ty == Tsarray || t1.ty == Tarray || t1.ty == Tpointer) && (t2.ty == Tsarray || t2.ty == Tarray || t2.ty == Tpointer) && t1.nextOf().mod != t2.nextOf().mod)
|
||||
if ((t1.isStaticOrDynamicArray() || t1.ty == Tpointer) && (t2.isStaticOrDynamicArray() || t2.ty == Tpointer)
|
||||
&& t1.nextOf().mod != t2.nextOf().mod)
|
||||
{
|
||||
/* If one is mutable and the other immutable, then retry
|
||||
* with both of them as const
|
||||
|
@ -3919,7 +3920,7 @@ LmodCompare:
|
|||
return convert(e1, t2);
|
||||
|
||||
/// Covers array operations for user-defined types
|
||||
Type checkArrayOpType(Expression e1, Expression e2, EXP op, Scope *sc)
|
||||
Type checkArrayOpType(Expression e1, Expression e2, EXP op, Scope* sc)
|
||||
{
|
||||
// scalar op scalar - we shouldn't be here
|
||||
if (e1.type.ty != Tarray && e1.type.ty != Tsarray && e2.type.ty != Tarray && e2.type.ty != Tsarray)
|
||||
|
@ -4138,7 +4139,7 @@ Expression typeCombine(BinExp be, Scope* sc)
|
|||
{
|
||||
Expression errorReturn()
|
||||
{
|
||||
Expression ex = be.incompatibleTypes();
|
||||
Expression ex = be.incompatibleTypes(sc);
|
||||
if (ex.op == EXP.error)
|
||||
return ex;
|
||||
return ErrorExp.get();
|
||||
|
@ -4240,7 +4241,7 @@ extern (D) bool arrayTypeCompatibleWithoutCasting(Type t1, Type t2)
|
|||
t1 = t1.toBasetype();
|
||||
t2 = t2.toBasetype();
|
||||
|
||||
if ((t1.ty == Tarray || t1.ty == Tsarray || t1.ty == Tpointer) && t2.ty == t1.ty)
|
||||
if ((t1.isStaticOrDynamicArray() || t1.ty == Tpointer) && t2.ty == t1.ty)
|
||||
{
|
||||
if (t1.nextOf().implicitConvTo(t2.nextOf()) >= MATCH.constant || t2.nextOf().implicitConvTo(t1.nextOf()) >= MATCH.constant)
|
||||
return true;
|
||||
|
|
|
@ -1379,16 +1379,6 @@ extern (C++) class TypeInfoDeclaration : VarDeclaration
|
|||
assert(0); // should never be produced by syntax
|
||||
}
|
||||
|
||||
override final const(char)* toChars() const
|
||||
{
|
||||
//printf("TypeInfoDeclaration::toChars() tinfo = %s\n", tinfo.toChars());
|
||||
OutBuffer buf;
|
||||
buf.writestring("typeid(");
|
||||
buf.writestring(tinfo.toChars());
|
||||
buf.writeByte(')');
|
||||
return buf.extractChars();
|
||||
}
|
||||
|
||||
override final inout(TypeInfoDeclaration) isTypeInfoDeclaration() inout @nogc nothrow pure @safe
|
||||
{
|
||||
return this;
|
||||
|
|
|
@ -342,7 +342,6 @@ public:
|
|||
|
||||
static TypeInfoDeclaration *create(Type *tinfo);
|
||||
TypeInfoDeclaration *syntaxCopy(Dsymbol *) override final;
|
||||
const char *toChars() const override final;
|
||||
|
||||
TypeInfoDeclaration *isTypeInfoDeclaration() override final { return this; }
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
|
@ -787,7 +786,6 @@ public:
|
|||
d_bool isMoveCtor;
|
||||
CtorDeclaration *syntaxCopy(Dsymbol *) override;
|
||||
const char *kind() const override;
|
||||
const char *toChars() const override;
|
||||
bool isVirtual() const override;
|
||||
bool addPreInvariant() override;
|
||||
bool addPostInvariant() override;
|
||||
|
@ -814,7 +812,6 @@ class DtorDeclaration final : public FuncDeclaration
|
|||
public:
|
||||
DtorDeclaration *syntaxCopy(Dsymbol *) override;
|
||||
const char *kind() const override;
|
||||
const char *toChars() const override;
|
||||
bool isVirtual() const override;
|
||||
bool addPreInvariant() override;
|
||||
bool addPostInvariant() override;
|
||||
|
|
|
@ -1885,7 +1885,7 @@ public:
|
|||
// Check for taking an address of a shared variable.
|
||||
// If the shared variable is an array, the offset might not be zero.
|
||||
Type fromType = null;
|
||||
if (e.var.type.ty == Tarray || e.var.type.ty == Tsarray)
|
||||
if (e.var.type.isStaticOrDynamicArray())
|
||||
{
|
||||
fromType = (cast(TypeArray)e.var.type).next;
|
||||
}
|
||||
|
@ -1900,7 +1900,7 @@ public:
|
|||
Expression val = getVarExp(e.loc, istate, e.var, goal);
|
||||
if (exceptionOrCant(val))
|
||||
return;
|
||||
if (val.type.ty == Tarray || val.type.ty == Tsarray)
|
||||
if (val.type.isStaticOrDynamicArray())
|
||||
{
|
||||
// Check for unsupported type painting operations
|
||||
Type elemtype = (cast(TypeArray)val.type).next;
|
||||
|
@ -3354,7 +3354,7 @@ public:
|
|||
// a[] = e can have const e. So we compare the naked types.
|
||||
Type tdst = e1.type.toBasetype();
|
||||
Type tsrc = e.e2.type.toBasetype();
|
||||
while (tdst.ty == Tsarray || tdst.ty == Tarray)
|
||||
while (tdst.isStaticOrDynamicArray())
|
||||
{
|
||||
tdst = (cast(TypeArray)tdst).next.toBasetype();
|
||||
if (tsrc.equivalent(tdst))
|
||||
|
@ -4302,7 +4302,7 @@ public:
|
|||
Expression assignTo(ArrayLiteralExp ae, size_t lwr, size_t upr)
|
||||
{
|
||||
Expressions* w = ae.elements;
|
||||
assert(ae.type.ty == Tsarray || ae.type.ty == Tarray || ae.type.ty == Tpointer);
|
||||
assert(ae.type.isStaticOrDynamicArray() || ae.type.ty == Tpointer);
|
||||
bool directblk = (cast(TypeNext)ae.type).next.equivalent(newval.type);
|
||||
for (size_t k = lwr; k < upr; k++)
|
||||
{
|
||||
|
@ -5804,8 +5804,7 @@ public:
|
|||
auto expTb = exp.type.toBasetype();
|
||||
|
||||
if (exp.type.implicitConvTo(tbNext) >= MATCH.convert &&
|
||||
(tb.ty == Tarray || tb.ty == Tsarray) &&
|
||||
(expTb.ty == Tarray || expTb.ty == Tsarray))
|
||||
tb.isStaticOrDynamicArray() && expTb.isStaticOrDynamicArray())
|
||||
return new ArrayLiteralExp(exp.loc, e.type, exp);
|
||||
return exp;
|
||||
}
|
||||
|
@ -5921,7 +5920,7 @@ public:
|
|||
|
||||
bool castToSarrayPointer = false;
|
||||
bool castBackFromVoid = false;
|
||||
if (e1.type.ty == Tarray || e1.type.ty == Tsarray || e1.type.ty == Tpointer)
|
||||
if (e1.type.isStaticOrDynamicArray() || e1.type.ty == Tpointer)
|
||||
{
|
||||
// Check for unsupported type painting operations
|
||||
// For slices, we need the type being sliced,
|
||||
|
@ -6101,7 +6100,7 @@ public:
|
|||
|
||||
// Disallow array type painting, except for conversions between built-in
|
||||
// types of identical size.
|
||||
if ((e.to.ty == Tsarray || e.to.ty == Tarray) && (e1.type.ty == Tsarray || e1.type.ty == Tarray) && !isSafePointerCast(e1.type.nextOf(), e.to.nextOf()))
|
||||
if (e.to.isStaticOrDynamicArray() && e1.type.isStaticOrDynamicArray() && !isSafePointerCast(e1.type.nextOf(), e.to.nextOf()))
|
||||
{
|
||||
auto se = e1.isStringExp();
|
||||
// Allow casting a hex string literal to short[], int[] or long[]
|
||||
|
|
|
@ -430,11 +430,9 @@ extern (C++) final class Module : Package
|
|||
|
||||
Modules aimports; // all imported modules
|
||||
|
||||
uint debuglevel; // debug level
|
||||
Identifiers* debugids; // debug identifiers
|
||||
Identifiers* debugidsNot; // forward referenced debug identifiers
|
||||
|
||||
uint versionlevel; // version level
|
||||
Identifiers* versionids; // version identifiers
|
||||
Identifiers* versionidsNot; // forward referenced version identifiers
|
||||
|
||||
|
|
|
@ -433,10 +433,7 @@ void gendocfile(Module m, const char[] ddoctext, const char* datetime, ErrorSink
|
|||
OutBuffer buf;
|
||||
if (m.filetype == FileType.ddoc)
|
||||
{
|
||||
const ploc = m.md ? &m.md.loc : &m.loc;
|
||||
Loc loc = *ploc;
|
||||
if (!loc.filename)
|
||||
loc.filename = srcfilename.ptr;
|
||||
Loc loc = m.md ? m.md.loc : m.loc;
|
||||
|
||||
size_t commentlen = m.comment ? strlen(cast(char*)m.comment) : 0;
|
||||
Dsymbols a;
|
||||
|
@ -694,9 +691,7 @@ bool emitAnchorName(ref OutBuffer buf, Dsymbol s, Scope* sc, bool includeParent)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* We just want the identifier, not overloads like TemplateDeclaration::toChars.
|
||||
* We don't want the template parameter list and constraints. */
|
||||
buf.writestring(s.Dsymbol.toChars());
|
||||
buf.writestring(s.ident ? s.ident.toString : "__anonymous");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -799,7 +794,11 @@ void emitAnchor(ref OutBuffer buf, Dsymbol s, Scope* sc, bool forHeader = false)
|
|||
}
|
||||
else
|
||||
{
|
||||
auto symbolName = ident.toString();
|
||||
// buf.writestring("<<<");
|
||||
// buf.writestring(typeof(ident).stringof);
|
||||
// buf.writestring(">>>");
|
||||
// auto symbolName = ident.toString();
|
||||
auto symbolName = ident.toChars().toDString();
|
||||
buf.printf("$(%.*s %.*s", cast(int) macroName.length, macroName.ptr,
|
||||
cast(int) symbolName.length, symbolName.ptr);
|
||||
|
||||
|
@ -2624,7 +2623,7 @@ Parameter isFunctionParameter(Dsymbols* a, const(char)[] p) @safe
|
|||
|
||||
/****************************************************
|
||||
*/
|
||||
Parameter isEponymousFunctionParameter(Dsymbols *a, const(char)[] p) @safe
|
||||
Parameter isEponymousFunctionParameter(Dsymbols* a, const(char)[] p) @safe
|
||||
{
|
||||
foreach (Dsymbol dsym; *a)
|
||||
{
|
||||
|
@ -3603,7 +3602,7 @@ struct MarkdownLinkReferences
|
|||
auto id = Identifier.lookup(ids[0].ptr, ids[0].length);
|
||||
if (id)
|
||||
{
|
||||
auto loc = Loc();
|
||||
auto loc = Loc.initial;
|
||||
Dsymbol pscopesym;
|
||||
auto symbol = _scope.search(loc, id, pscopesym, SearchOpt.ignoreErrors);
|
||||
for (size_t i = 1; symbol && i < ids.length; ++i)
|
||||
|
@ -4096,9 +4095,8 @@ size_t endRowAndTable(ref OutBuffer buf, size_t iStart, size_t iEnd, ref Markdow
|
|||
*/
|
||||
void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, size_t offset)
|
||||
{
|
||||
const incrementLoc = loc.linnum == 0 ? 1 : 0;
|
||||
loc.linnum = loc.linnum + incrementLoc;
|
||||
loc.charnum = 0;
|
||||
loc.nextLine();
|
||||
|
||||
//printf("highlightText()\n");
|
||||
bool leadingBlank = true;
|
||||
size_t iParagraphStart = offset;
|
||||
|
@ -4202,7 +4200,7 @@ void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, size_t of
|
|||
lineQuoted = false;
|
||||
tableRowDetected = false;
|
||||
iLineStart = i + 1;
|
||||
loc.linnum = loc.linnum + incrementLoc;
|
||||
loc.nextLine();
|
||||
|
||||
// update the paragraph start if we just entered a macro
|
||||
if (previousMacroLevel < macroLevel && iParagraphStart < iLineStart)
|
||||
|
|
|
@ -55,7 +55,7 @@ import dmd.visitor;
|
|||
import dmd.common.outbuffer;
|
||||
|
||||
/***************************************
|
||||
* Calls dg(Dsymbol *sym) for each Dsymbol.
|
||||
* Calls dg(Dsymbol* sym) for each Dsymbol.
|
||||
* If dg returns !=0, stops and returns that value else returns 0.
|
||||
* Params:
|
||||
* symbols = Dsymbols
|
||||
|
@ -84,7 +84,7 @@ int foreachDsymbol(Dsymbols* symbols, scope int delegate(Dsymbol) dg)
|
|||
}
|
||||
|
||||
/***************************************
|
||||
* Calls dg(Dsymbol *sym) for each Dsymbol.
|
||||
* Calls dg(Dsymbol* sym) for each Dsymbol.
|
||||
* Params:
|
||||
* symbols = Dsymbols
|
||||
* dg = delegate to call for each Dsymbol
|
||||
|
@ -297,9 +297,10 @@ extern (C++) class Dsymbol : ASTNode
|
|||
return new Dsymbol(ident);
|
||||
}
|
||||
|
||||
override const(char)* toChars() const
|
||||
final override const(char)* toChars() const
|
||||
{
|
||||
return ident ? ident.toChars() : "__anonymous";
|
||||
import dmd.hdrgen : toChars;
|
||||
return toChars(this);
|
||||
}
|
||||
|
||||
// Getters / setters for fields stored in `DsymbolAttributes`
|
||||
|
|
|
@ -187,7 +187,7 @@ public:
|
|||
PASS semanticRun;
|
||||
unsigned short localNum; // perturb mangled name to avoid collisions with those in FuncDeclaration.localsymtab
|
||||
static Dsymbol *create(Identifier *);
|
||||
const char *toChars() const override;
|
||||
const char *toChars() const final override;
|
||||
DeprecatedDeclaration* depdecl();
|
||||
CPPNamespaceDeclaration* cppnamespace();
|
||||
UserAttributeDeclaration* userAttribDecl();
|
||||
|
|
|
@ -424,7 +424,7 @@ private bool checkDeprecatedAliasThis(AliasThis at, const ref Loc loc, Scope* sc
|
|||
}
|
||||
|
||||
// Save the scope and defer semantic analysis on the Dsymbol.
|
||||
void deferDsymbolSemantic(Scope* sc, Dsymbol s, Scope *scx)
|
||||
void deferDsymbolSemantic(Scope* sc, Dsymbol s, Scope* scx)
|
||||
{
|
||||
s._scope = scx ? scx : sc.copy();
|
||||
s._scope.setNoFree();
|
||||
|
@ -4352,34 +4352,21 @@ private extern(C++) class AddMemberVisitor : Visitor
|
|||
Module m = sds.isModule();
|
||||
// Do not add the member to the symbol table,
|
||||
// just make sure subsequent debug declarations work.
|
||||
if (ds.ident)
|
||||
if (!m)
|
||||
{
|
||||
if (!m)
|
||||
{
|
||||
.error(ds.loc, "%s `%s` declaration must be at module level", ds.kind, ds.toPrettyChars);
|
||||
ds.errors = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m.debugidsNot && findCondition(*m.debugidsNot, ds.ident))
|
||||
{
|
||||
.error(ds.loc, "%s `%s` defined after use", ds.kind, ds.toPrettyChars);
|
||||
ds.errors = true;
|
||||
}
|
||||
if (!m.debugids)
|
||||
m.debugids = new Identifiers();
|
||||
m.debugids.push(ds.ident);
|
||||
}
|
||||
.error(ds.loc, "%s `%s` declaration must be at module level", ds.kind, ds.toPrettyChars);
|
||||
ds.errors = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m)
|
||||
if (m.debugidsNot && findCondition(*m.debugidsNot, ds.ident))
|
||||
{
|
||||
.error(ds.loc, "%s `%s` level declaration must be at module level", ds.kind, ds.toPrettyChars);
|
||||
.error(ds.loc, "%s `%s` defined after use", ds.kind, ds.toPrettyChars);
|
||||
ds.errors = true;
|
||||
}
|
||||
else
|
||||
m.debuglevel = ds.level;
|
||||
if (!m.debugids)
|
||||
m.debugids = new Identifiers();
|
||||
m.debugids.push(ds.ident);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4389,36 +4376,24 @@ private extern(C++) class AddMemberVisitor : Visitor
|
|||
Module m = sds.isModule();
|
||||
// Do not add the member to the symbol table,
|
||||
// just make sure subsequent debug declarations work.
|
||||
if (vs.ident)
|
||||
VersionCondition.checkReserved(vs.loc, vs.ident.toString());
|
||||
if (!m)
|
||||
{
|
||||
VersionCondition.checkReserved(vs.loc, vs.ident.toString());
|
||||
if (!m)
|
||||
{
|
||||
.error(vs.loc, "%s `%s` declaration must be at module level", vs.kind, vs.toPrettyChars);
|
||||
vs.errors = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m.versionidsNot && findCondition(*m.versionidsNot, vs.ident))
|
||||
{
|
||||
.error(vs.loc, "%s `%s` defined after use", vs.kind, vs.toPrettyChars);
|
||||
vs.errors = true;
|
||||
}
|
||||
if (!m.versionids)
|
||||
m.versionids = new Identifiers();
|
||||
m.versionids.push(vs.ident);
|
||||
}
|
||||
.error(vs.loc, "%s `%s` declaration must be at module level", vs.kind, vs.toPrettyChars);
|
||||
vs.errors = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m)
|
||||
if (m.versionidsNot && findCondition(*m.versionidsNot, vs.ident))
|
||||
{
|
||||
.error(vs.loc, "%s `%s` level declaration must be at module level", vs.kind, vs.toPrettyChars);
|
||||
.error(vs.loc, "%s `%s` defined after use", vs.kind, vs.toPrettyChars);
|
||||
vs.errors = true;
|
||||
}
|
||||
else
|
||||
m.versionlevel = vs.level;
|
||||
if (!m.versionids)
|
||||
m.versionids = new Identifiers();
|
||||
m.versionids.push(vs.ident);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override void visit(Nspace ns)
|
||||
|
|
|
@ -57,7 +57,7 @@ import dmd.dsymbolsem : dsymbolSemantic, checkDeprecated, aliasSemantic, search,
|
|||
import dmd.errors;
|
||||
import dmd.errorsink;
|
||||
import dmd.expression;
|
||||
import dmd.expressionsem : resolveLoc, expressionSemantic, resolveProperties;
|
||||
import dmd.expressionsem : resolveLoc, expressionSemantic, resolveProperties, checkValue;
|
||||
import dmd.func;
|
||||
import dmd.funcsem : functionSemantic, leastAsSpecialized, overloadApply;
|
||||
import dmd.globals;
|
||||
|
@ -746,14 +746,6 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
|
|||
return (onemember && onemember.isAggregateDeclaration()) ? onemember.kind() : "template";
|
||||
}
|
||||
|
||||
override const(char)* toChars() const
|
||||
{
|
||||
HdrGenState hgs;
|
||||
OutBuffer buf;
|
||||
toCharsMaybeConstraints(this, buf, hgs);
|
||||
return buf.extractChars();
|
||||
}
|
||||
|
||||
/****************************
|
||||
* Similar to `toChars`, but does not print the template constraints
|
||||
*/
|
||||
|
@ -3830,13 +3822,6 @@ extern (C++) class TemplateInstance : ScopeDsymbol
|
|||
return true;
|
||||
}
|
||||
|
||||
override const(char)* toChars() const
|
||||
{
|
||||
OutBuffer buf;
|
||||
toCBufferInstance(this, buf);
|
||||
return buf.extractChars();
|
||||
}
|
||||
|
||||
override final const(char)* toPrettyCharsHelper()
|
||||
{
|
||||
OutBuffer buf;
|
||||
|
@ -5524,13 +5509,6 @@ extern (C++) final class TemplateMixin : TemplateInstance
|
|||
return members.foreachDsymbol( (s) { return s.hasPointers(); } ) != 0;
|
||||
}
|
||||
|
||||
override const(char)* toChars() const
|
||||
{
|
||||
OutBuffer buf;
|
||||
toCBufferInstance(this, buf);
|
||||
return buf.extractChars();
|
||||
}
|
||||
|
||||
extern (D) bool findTempDecl(Scope* sc)
|
||||
{
|
||||
// Follow qualifications to find the TemplateDeclaration
|
||||
|
|
|
@ -29,21 +29,17 @@ import dmd.visitor;
|
|||
/***********************************************************
|
||||
* DebugSymbol's happen for statements like:
|
||||
* debug = identifier;
|
||||
* debug = integer;
|
||||
*/
|
||||
extern (C++) final class DebugSymbol : Dsymbol
|
||||
{
|
||||
uint level;
|
||||
|
||||
extern (D) this(const ref Loc loc, Identifier ident) @safe
|
||||
{
|
||||
super(loc, ident);
|
||||
}
|
||||
|
||||
extern (D) this(const ref Loc loc, uint level) @safe
|
||||
extern (D) this(const ref Loc loc) @safe
|
||||
{
|
||||
super(loc, null);
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
override DebugSymbol syntaxCopy(Dsymbol s)
|
||||
|
@ -51,19 +47,9 @@ extern (C++) final class DebugSymbol : Dsymbol
|
|||
assert(!s);
|
||||
auto ds = new DebugSymbol(loc, ident);
|
||||
ds.comment = comment;
|
||||
ds.level = level;
|
||||
return ds;
|
||||
}
|
||||
|
||||
override const(char)* toChars() const nothrow
|
||||
{
|
||||
if (ident)
|
||||
return ident.toChars();
|
||||
OutBuffer buf;
|
||||
buf.print(level);
|
||||
return buf.extractChars();
|
||||
}
|
||||
|
||||
override const(char)* kind() const nothrow
|
||||
{
|
||||
return "debug";
|
||||
|
@ -83,41 +69,28 @@ extern (C++) final class DebugSymbol : Dsymbol
|
|||
/***********************************************************
|
||||
* VersionSymbol's happen for statements like:
|
||||
* version = identifier;
|
||||
* version = integer;
|
||||
*/
|
||||
extern (C++) final class VersionSymbol : Dsymbol
|
||||
{
|
||||
uint level;
|
||||
|
||||
extern (D) this(const ref Loc loc, Identifier ident) @safe
|
||||
{
|
||||
super(loc, ident);
|
||||
}
|
||||
|
||||
extern (D) this(const ref Loc loc, uint level) @safe
|
||||
extern (D) this(const ref Loc loc) @safe
|
||||
{
|
||||
super(loc, null);
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
override VersionSymbol syntaxCopy(Dsymbol s)
|
||||
{
|
||||
assert(!s);
|
||||
auto ds = ident ? new VersionSymbol(loc, ident)
|
||||
: new VersionSymbol(loc, level);
|
||||
auto ds = new VersionSymbol(loc, ident);
|
||||
ds.comment = comment;
|
||||
return ds;
|
||||
}
|
||||
|
||||
override const(char)* toChars() const nothrow
|
||||
{
|
||||
if (ident)
|
||||
return ident.toChars();
|
||||
OutBuffer buf;
|
||||
buf.print(level);
|
||||
return buf.extractChars();
|
||||
}
|
||||
|
||||
override const(char)* kind() const nothrow
|
||||
{
|
||||
return "version";
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
|
||||
module dmd.errors;
|
||||
|
||||
import core.stdc.stdarg;
|
||||
public import core.stdc.stdarg;
|
||||
public import dmd.root.string: fTuple;
|
||||
import dmd.errorsink;
|
||||
import dmd.globals;
|
||||
import dmd.location;
|
||||
|
@ -384,7 +385,7 @@ else
|
|||
* see verrorReport for arguments
|
||||
* Returns: true if error handling is done, false to continue printing to stderr
|
||||
*/
|
||||
alias DiagnosticHandler = bool delegate(const ref Loc location, Color headerColor, const(char)* header, const(char)* messageFormat, va_list args, const(char)* prefix1, const(char)* prefix2);
|
||||
alias DiagnosticHandler = bool delegate(const ref SourceLoc location, Color headerColor, const(char)* header, const(char)* messageFormat, va_list args, const(char)* prefix1, const(char)* prefix2);
|
||||
|
||||
/**
|
||||
* The diagnostic handler.
|
||||
|
|
|
@ -1607,7 +1607,7 @@ void escapeExp(Expression e, ref scope EscapeByResults er, int deref)
|
|||
void visitArrayLiteral(ArrayLiteralExp e)
|
||||
{
|
||||
Type tb = e.type.toBasetype();
|
||||
if (tb.isTypeSArray() || tb.isTypeDArray())
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (e.basis)
|
||||
escapeExp(e.basis, er, deref);
|
||||
|
@ -2245,7 +2245,7 @@ private bool isTypesafeVariadicArray(VarDeclaration v)
|
|||
if (v.storage_class & STC.variadic)
|
||||
{
|
||||
Type tb = v.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -301,8 +301,14 @@ extern (C++) abstract class Expression : ASTNode
|
|||
|
||||
Loc loc; // file location
|
||||
const EXP op; // to minimize use of dynamic_cast
|
||||
bool parens; // if this is a parenthesized expression
|
||||
bool rvalue; // true if this is considered to be an rvalue, even if it is an lvalue
|
||||
|
||||
static struct BitFields
|
||||
{
|
||||
bool parens; // if this is a parenthesized expression
|
||||
bool rvalue; // true if this is considered to be an rvalue, even if it is an lvalue
|
||||
}
|
||||
import dmd.common.bitfields;
|
||||
mixin(generateBitFields!(BitFields, ubyte));
|
||||
|
||||
extern (D) this(const ref Loc loc, EXP op) scope @safe
|
||||
{
|
||||
|
@ -375,8 +381,13 @@ extern (C++) abstract class Expression : ASTNode
|
|||
return DYNCAST.expression;
|
||||
}
|
||||
|
||||
override const(char)* toChars() const
|
||||
final override const(char)* toChars() const
|
||||
{
|
||||
// FIXME: Test suite relies on lambda's being printed as __lambdaXXX in errors and .stringof
|
||||
// Printing a (truncated) lambda body is more user friendly
|
||||
if (auto fe = isFuncExp())
|
||||
return fe.fd.toChars();
|
||||
|
||||
return .toChars(this);
|
||||
}
|
||||
|
||||
|
@ -516,25 +527,6 @@ extern (C++) abstract class Expression : ASTNode
|
|||
return false;
|
||||
}
|
||||
|
||||
/****************************************
|
||||
* Check that the expression has a valid value.
|
||||
* If not, generates an error "... has no value".
|
||||
* Returns:
|
||||
* true if the expression is not valid or has void type.
|
||||
*/
|
||||
bool checkValue()
|
||||
{
|
||||
if (type && type.toBasetype().ty == Tvoid)
|
||||
{
|
||||
error(loc, "expression `%s` is `void` and has no value", toChars());
|
||||
//print(); assert(0);
|
||||
if (!global.gag)
|
||||
type = Type.terror;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/******************************
|
||||
* Take address of expression.
|
||||
*/
|
||||
|
@ -2126,6 +2118,16 @@ extern (C++) final class AssocArrayLiteralExp : Expression
|
|||
*/
|
||||
extern (C++) final class StructLiteralExp : Expression
|
||||
{
|
||||
struct BitFields
|
||||
{
|
||||
bool useStaticInit; /// if this is true, use the StructDeclaration's init symbol
|
||||
bool isOriginal = false; /// used when moving instances to indicate `this is this.origin`
|
||||
OwnedBy ownedByCtfe = OwnedBy.code;
|
||||
}
|
||||
import dmd.common.bitfields;
|
||||
mixin(generateBitFields!(BitFields, ubyte));
|
||||
StageFlags stageflags;
|
||||
|
||||
StructDeclaration sd; /// which aggregate this is for
|
||||
Expressions* elements; /// parallels sd.fields[] with null entries for fields to skip
|
||||
Type stype; /// final type of result (can be different from sd's type)
|
||||
|
@ -2163,11 +2165,6 @@ extern (C++) final class StructLiteralExp : Expression
|
|||
inlineScan = 0x10, /// inlineScan is running
|
||||
toCBuffer = 0x20 /// toCBuffer is running
|
||||
}
|
||||
StageFlags stageflags;
|
||||
|
||||
bool useStaticInit; /// if this is true, use the StructDeclaration's init symbol
|
||||
bool isOriginal = false; /// used when moving instances to indicate `this is this.origin`
|
||||
OwnedBy ownedByCtfe = OwnedBy.code;
|
||||
|
||||
extern (D) this(const ref Loc loc, StructDeclaration sd, Expressions* elements, Type stype = null) @safe
|
||||
{
|
||||
|
@ -2349,12 +2346,6 @@ extern (C++) final class TypeExp : Expression
|
|||
return true;
|
||||
}
|
||||
|
||||
override bool checkValue()
|
||||
{
|
||||
error(loc, "type `%s` has no value", toChars());
|
||||
return true;
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
{
|
||||
v.visit(this);
|
||||
|
@ -2408,12 +2399,6 @@ extern (C++) final class ScopeExp : Expression
|
|||
return false;
|
||||
}
|
||||
|
||||
override bool checkValue()
|
||||
{
|
||||
error(loc, "%s `%s` has no value", sds.kind(), sds.toChars());
|
||||
return true;
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
{
|
||||
v.visit(this);
|
||||
|
@ -2447,12 +2432,6 @@ extern (C++) final class TemplateExp : Expression
|
|||
return true;
|
||||
}
|
||||
|
||||
override bool checkValue()
|
||||
{
|
||||
error(loc, "%s `%s` has no value", td.kind(), toChars());
|
||||
return true;
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
{
|
||||
v.visit(this);
|
||||
|
@ -2720,11 +2699,6 @@ extern (C++) final class FuncExp : Expression
|
|||
return new FuncExp(loc, fd);
|
||||
}
|
||||
|
||||
override const(char)* toChars() const
|
||||
{
|
||||
return fd.toChars();
|
||||
}
|
||||
|
||||
override bool checkType()
|
||||
{
|
||||
if (td)
|
||||
|
@ -2735,16 +2709,6 @@ extern (C++) final class FuncExp : Expression
|
|||
return false;
|
||||
}
|
||||
|
||||
override bool checkValue()
|
||||
{
|
||||
if (td)
|
||||
{
|
||||
error(loc, "template lambda has no value");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
{
|
||||
v.visit(this);
|
||||
|
@ -3168,12 +3132,6 @@ extern (C++) final class DotTemplateExp : UnaExp
|
|||
return true;
|
||||
}
|
||||
|
||||
override bool checkValue()
|
||||
{
|
||||
error(loc, "%s `%s` has no value", td.kind(), toChars());
|
||||
return true;
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
{
|
||||
v.visit(this);
|
||||
|
@ -3252,18 +3210,6 @@ extern (C++) final class DotTemplateInstanceExp : UnaExp
|
|||
return false;
|
||||
}
|
||||
|
||||
override bool checkValue()
|
||||
{
|
||||
if (ti.tempdecl &&
|
||||
ti.semantictiargsdone &&
|
||||
ti.semanticRun == PASS.initial)
|
||||
|
||||
error(loc, "partial %s `%s` has no value", ti.kind(), toChars());
|
||||
else
|
||||
error(loc, "%s `%s` has no value", ti.kind(), ti.toChars());
|
||||
return true;
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
{
|
||||
v.visit(this);
|
||||
|
@ -4180,10 +4126,6 @@ extern (C++) final class LoweredAssignExp : AssignExp
|
|||
this.lowering = lowering;
|
||||
}
|
||||
|
||||
override const(char)* toChars() const
|
||||
{
|
||||
return lowering.toChars();
|
||||
}
|
||||
override void accept(Visitor v)
|
||||
{
|
||||
v.visit(this);
|
||||
|
@ -5089,27 +5031,6 @@ extern (C++) final class CTFEExp : Expression
|
|||
type = Type.tvoid;
|
||||
}
|
||||
|
||||
override const(char)* toChars() const
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case EXP.cantExpression:
|
||||
return "<cant>";
|
||||
case EXP.voidExpression:
|
||||
return "cast(void)0";
|
||||
case EXP.showCtfeContext:
|
||||
return "<error>";
|
||||
case EXP.break_:
|
||||
return "<break>";
|
||||
case EXP.continue_:
|
||||
return "<continue>";
|
||||
case EXP.goto_:
|
||||
return "<goto>";
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
extern (D) __gshared CTFEExp cantexp;
|
||||
extern (D) __gshared CTFEExp voidexp;
|
||||
extern (D) __gshared CTFEExp breakexp;
|
||||
|
@ -5146,11 +5067,6 @@ extern (C++) final class ThrownExceptionExp : Expression
|
|||
this.type = victim.type;
|
||||
}
|
||||
|
||||
override const(char)* toChars() const
|
||||
{
|
||||
return "CTFE ThrownException";
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
{
|
||||
v.visit(this);
|
||||
|
|
|
@ -77,8 +77,12 @@ public:
|
|||
Type *type; // !=NULL means that semantic() has been run
|
||||
Loc loc; // file location
|
||||
EXP op; // to minimize use of dynamic_cast
|
||||
d_bool parens; // if this is a parenthesized expression
|
||||
d_bool rvalue; // consider this an rvalue, even if it is an lvalue
|
||||
uint8_t bitFields;
|
||||
|
||||
bool parens() const;
|
||||
bool parens(bool v);
|
||||
bool rvalue() const;
|
||||
bool rvalue(bool v);
|
||||
|
||||
size_t size() const;
|
||||
static void _init();
|
||||
|
@ -87,7 +91,7 @@ public:
|
|||
// kludge for template.isExpression()
|
||||
DYNCAST dyncast() const override final { return DYNCAST_EXPRESSION; }
|
||||
|
||||
const char *toChars() const override;
|
||||
const char* toChars() const final override;
|
||||
|
||||
virtual dinteger_t toInteger();
|
||||
virtual uinteger_t toUInteger();
|
||||
|
@ -97,7 +101,6 @@ public:
|
|||
virtual StringExp *toStringExp();
|
||||
virtual bool isLvalue();
|
||||
virtual bool checkType();
|
||||
virtual bool checkValue();
|
||||
Expression *addressOf();
|
||||
Expression *deref();
|
||||
|
||||
|
@ -431,6 +434,24 @@ public:
|
|||
class StructLiteralExp final : public Expression
|
||||
{
|
||||
public:
|
||||
uint8_t bitFields;
|
||||
|
||||
// if this is true, use the StructDeclaration's init symbol
|
||||
bool useStaticInit() const;
|
||||
bool useStaticInit(bool v);
|
||||
// used when moving instances to indicate `this is this.origin`
|
||||
bool isOriginal() const;
|
||||
bool isOriginal(bool v);
|
||||
OwnedBy ownedByCtfe() const;
|
||||
OwnedBy ownedByCtfe(OwnedBy v);
|
||||
|
||||
/** anytime when recursive function is calling, 'stageflags' marks with bit flag of
|
||||
* current stage and unmarks before return from this function.
|
||||
* 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline'
|
||||
* (with infinite recursion) of this expression.
|
||||
*/
|
||||
uint8_t stageflags;
|
||||
|
||||
StructDeclaration *sd; // which aggregate this is for
|
||||
Expressions *elements; // parallels sd->fields[] with NULL entries for fields to skip
|
||||
Type *stype; // final type of result (can be different from sd's type)
|
||||
|
@ -451,17 +472,6 @@ public:
|
|||
StructLiteralExp *origin;
|
||||
|
||||
|
||||
/** anytime when recursive function is calling, 'stageflags' marks with bit flag of
|
||||
* current stage and unmarks before return from this function.
|
||||
* 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline'
|
||||
* (with infinite recursion) of this expression.
|
||||
*/
|
||||
uint8_t stageflags;
|
||||
|
||||
d_bool useStaticInit; // if this is true, use the StructDeclaration's init symbol
|
||||
d_bool isOriginal; // used when moving instances to indicate `this is this.origin`
|
||||
OwnedBy ownedByCtfe;
|
||||
|
||||
static StructLiteralExp *create(const Loc &loc, StructDeclaration *sd, void *elements, Type *stype = nullptr);
|
||||
bool equals(const RootObject * const o) const override;
|
||||
StructLiteralExp *syntaxCopy() override;
|
||||
|
@ -474,7 +484,6 @@ class TypeExp final : public Expression
|
|||
public:
|
||||
TypeExp *syntaxCopy() override;
|
||||
bool checkType() override;
|
||||
bool checkValue() override;
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
};
|
||||
|
||||
|
@ -485,7 +494,6 @@ public:
|
|||
|
||||
ScopeExp *syntaxCopy() override;
|
||||
bool checkType() override;
|
||||
bool checkValue() override;
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
};
|
||||
|
||||
|
@ -497,7 +505,6 @@ public:
|
|||
|
||||
bool isLvalue() override;
|
||||
bool checkType() override;
|
||||
bool checkValue() override;
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
};
|
||||
|
||||
|
@ -595,9 +602,7 @@ public:
|
|||
|
||||
bool equals(const RootObject * const o) const override;
|
||||
FuncExp *syntaxCopy() override;
|
||||
const char *toChars() const override;
|
||||
bool checkType() override;
|
||||
bool checkValue() override;
|
||||
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
};
|
||||
|
@ -741,7 +746,6 @@ public:
|
|||
TemplateDeclaration *td;
|
||||
|
||||
bool checkType() override;
|
||||
bool checkValue() override;
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
};
|
||||
|
||||
|
@ -762,7 +766,6 @@ public:
|
|||
|
||||
DotTemplateInstanceExp *syntaxCopy() override;
|
||||
bool checkType() override;
|
||||
bool checkValue() override;
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
};
|
||||
|
||||
|
@ -1045,7 +1048,6 @@ class LoweredAssignExp final : public AssignExp
|
|||
public:
|
||||
Expression *lowering;
|
||||
|
||||
const char *toChars() const override;
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
};
|
||||
|
||||
|
|
|
@ -308,7 +308,7 @@ extern (D) bool findTempDecl(DotTemplateInstanceExp exp, Scope* sc)
|
|||
* Returns:
|
||||
* String literal, or `null` if error happens.
|
||||
*/
|
||||
StringExp semanticString(Scope *sc, Expression exp, const char* s)
|
||||
StringExp semanticString(Scope* sc, Expression exp, const char* s)
|
||||
{
|
||||
sc = sc.startCTFE();
|
||||
exp = exp.expressionSemantic(sc);
|
||||
|
@ -377,7 +377,7 @@ private Expression incompatibleTypes(UnaExp e)
|
|||
* Returns:
|
||||
* ErrorExp
|
||||
*/
|
||||
extern (D) Expression incompatibleTypes(BinExp e)
|
||||
extern (D) Expression incompatibleTypes(BinExp e, Scope* sc = null)
|
||||
{
|
||||
if (e.e1.type.toBasetype() == Type.terror)
|
||||
return e.e1;
|
||||
|
@ -386,6 +386,10 @@ extern (D) Expression incompatibleTypes(BinExp e)
|
|||
|
||||
// CondExp uses 'a ? b : c' but we're comparing 'b : c'
|
||||
const(char)* thisOp = (e.op == EXP.question) ? ":" : EXPtoString(e.op).ptr;
|
||||
|
||||
if (sc && suggestBinaryOverloads(e, sc))
|
||||
return ErrorExp.get();
|
||||
|
||||
if (e.e1.op == EXP.type || e.e2.op == EXP.type)
|
||||
{
|
||||
error(e.loc, "incompatible types for `(%s) %s (%s)`: cannot use `%s` with types",
|
||||
|
@ -658,10 +662,9 @@ TupleDeclaration isAliasThisTuple(Expression e)
|
|||
* Runs semantic on ae.arguments. Declares temporary variables
|
||||
* if '$' was used.
|
||||
*/
|
||||
Expression resolveOpDollar(Scope* sc, ArrayExp ae, Expression* pe0)
|
||||
Expression resolveOpDollar(Scope* sc, ArrayExp ae, out Expression pe0)
|
||||
{
|
||||
assert(!ae.lengthVar);
|
||||
*pe0 = null;
|
||||
AggregateDeclaration ad = isAggregate(ae.e1.type);
|
||||
Dsymbol slice = search_function(ad, Id.opSlice);
|
||||
//printf("slice = %s %s\n", slice.kind(), slice.toChars());
|
||||
|
@ -675,7 +678,7 @@ Expression resolveOpDollar(Scope* sc, ArrayExp ae, Expression* pe0)
|
|||
foreach (i, e; *ae.arguments)
|
||||
{
|
||||
if (i == 0)
|
||||
*pe0 = extractOpDollarSideEffect(sc, ae);
|
||||
pe0 = extractOpDollarSideEffect(sc, ae);
|
||||
|
||||
if (e.op == EXP.interval && !(slice && slice.isTemplateDeclaration()))
|
||||
{
|
||||
|
@ -698,7 +701,7 @@ Expression resolveOpDollar(Scope* sc, ArrayExp ae, Expression* pe0)
|
|||
// If $ was used, declare it now
|
||||
Expression de = new DeclarationExp(ae.loc, ae.lengthVar);
|
||||
de = de.expressionSemantic(sc);
|
||||
*pe0 = Expression.combine(*pe0, de);
|
||||
pe0 = Expression.combine(pe0, de);
|
||||
}
|
||||
sc = sc.pop();
|
||||
|
||||
|
@ -721,7 +724,7 @@ Expression resolveOpDollar(Scope* sc, ArrayExp ae, Expression* pe0)
|
|||
if (!fslice)
|
||||
return fallback();
|
||||
|
||||
e = new DotTemplateInstanceExp(ae.loc, ae.e1, slice.ident, tiargs);
|
||||
e = new DotTemplateInstanceExp(ae.loc, ae.e1, Id.opSlice, tiargs);
|
||||
e = new CallExp(ae.loc, e, fargs);
|
||||
e = e.expressionSemantic(sc);
|
||||
}
|
||||
|
@ -745,7 +748,7 @@ Expression resolveOpDollar(Scope* sc, ArrayExp ae, Expression* pe0)
|
|||
* Returns:
|
||||
* ae, or ErrorExp if errors occurred
|
||||
*/
|
||||
Expression resolveOpDollar(Scope* sc, ArrayExp ae, IntervalExp ie, Expression* pe0)
|
||||
Expression resolveOpDollar(Scope* sc, ArrayExp ae, IntervalExp ie, ref Expression pe0)
|
||||
{
|
||||
//assert(!ae.lengthVar);
|
||||
if (!ie)
|
||||
|
@ -782,7 +785,7 @@ Expression resolveOpDollar(Scope* sc, ArrayExp ae, IntervalExp ie, Expression* p
|
|||
// If $ was used, declare it now
|
||||
Expression de = new DeclarationExp(ae.loc, ae.lengthVar);
|
||||
de = de.expressionSemantic(sc);
|
||||
*pe0 = Expression.combine(*pe0, de);
|
||||
pe0 = Expression.combine(pe0, de);
|
||||
}
|
||||
|
||||
sc = sc.pop();
|
||||
|
@ -821,7 +824,7 @@ extern(D) bool arrayExpressionSemantic(
|
|||
* Returns:
|
||||
* The expression that copy constructs or moves the value.
|
||||
*/
|
||||
extern (D) Expression doCopyOrMove(Scope *sc, Expression e, Type t, bool nrvo, bool move = false)
|
||||
extern (D) Expression doCopyOrMove(Scope* sc, Expression e, Type t, bool nrvo, bool move = false)
|
||||
{
|
||||
//printf("doCopyOrMove() %s\n", toChars(e));
|
||||
StructDeclaration sd;
|
||||
|
@ -1203,7 +1206,7 @@ private Expression resolveUFCS(Scope* sc, CallExp ce)
|
|||
eleft = die.e1;
|
||||
|
||||
Type t = eleft.type.toBasetype();
|
||||
if (t.ty == Tarray || t.ty == Tsarray || t.ty == Tnull || (t.isTypeBasic() && t.ty != Tvoid))
|
||||
if (t.isStaticOrDynamicArray() || t.ty == Tnull || (t.isTypeBasic() && t.ty != Tvoid))
|
||||
{
|
||||
/* Built-in types and arrays have no callable properties, so do shortcut.
|
||||
* It is necessary in: e.init()
|
||||
|
@ -1561,7 +1564,7 @@ Expression resolvePropertiesOnly(Scope* sc, Expression e1)
|
|||
* Returns:
|
||||
* `s` turned into an expression, `ErrorExp` if an error occurred
|
||||
*/
|
||||
Expression symbolToExp(Dsymbol s, const ref Loc loc, Scope *sc, bool hasOverloads)
|
||||
Expression symbolToExp(Dsymbol s, const ref Loc loc, Scope* sc, bool hasOverloads)
|
||||
{
|
||||
static if (LOGSEMANTIC)
|
||||
{
|
||||
|
@ -2346,7 +2349,7 @@ private bool checkNogc(FuncDeclaration f, ref Loc loc, Scope* sc)
|
|||
if (isRootTraitsCompilesScope(sc) ? !sc.func.isNogcBypassingInference() : !sc.func.setGCCall(f))
|
||||
return false;
|
||||
|
||||
if (loc.linnum == 0) // e.g. implicitly generated dtor
|
||||
if (loc == Loc.initial) // e.g. implicitly generated dtor
|
||||
loc = sc.func.loc;
|
||||
|
||||
// Lowered non-@nogc'd hooks will print their own error message inside of nogc.d (NOGCVisitor.visit(CallExp e)),
|
||||
|
@ -2368,8 +2371,14 @@ private bool checkNogc(FuncDeclaration f, ref Loc loc, Scope* sc)
|
|||
}
|
||||
|
||||
/********************************************
|
||||
* Check that the postblit is callable if t is an array of structs.
|
||||
* Returns true if error happens.
|
||||
* Check that the postblit of `t` isn't @disabled and has the right
|
||||
* function attributes for this scope.
|
||||
*
|
||||
* Params:
|
||||
* t = struct type, or static array of struct type to check
|
||||
* loc = error message location
|
||||
* sc = scope in which attributes are checked
|
||||
* Returns: true if there's an error
|
||||
*/
|
||||
private bool checkPostblit(Type t, ref Loc loc, Scope* sc)
|
||||
{
|
||||
|
@ -2392,12 +2401,12 @@ private bool checkPostblit(Type t, ref Loc loc, Scope* sc)
|
|||
return true;
|
||||
|
||||
//checkDeprecated(sc, sd.postblit); // necessary?
|
||||
sd.postblit.checkPurity(loc, sc);
|
||||
sd.postblit.checkSafety(loc, sc);
|
||||
sd.postblit.checkNogc(loc, sc);
|
||||
//checkAccess(sd, loc, sc, sd.postblit); // necessary?
|
||||
return false;
|
||||
|
||||
bool result = false;
|
||||
result |= sd.postblit.checkPurity(loc, sc);
|
||||
result |= sd.postblit.checkSafety(loc, sc);
|
||||
result |= sd.postblit.checkNogc(loc, sc);
|
||||
return result;
|
||||
}
|
||||
|
||||
/***************************************
|
||||
|
@ -3815,6 +3824,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
// See tryAliasThisSemantic
|
||||
Type[2] aliasThisStop;
|
||||
|
||||
// (Optional) the expression this was lowered from, for better error messages
|
||||
Expression parent;
|
||||
|
||||
this(Scope* sc) scope @safe
|
||||
{
|
||||
this.sc = sc;
|
||||
|
@ -7550,7 +7562,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
result = e;
|
||||
return;
|
||||
}
|
||||
if (exp.e1.op == EXP.slice || exp.e1.type.ty == Tarray || exp.e1.type.ty == Tsarray)
|
||||
if (exp.e1.op == EXP.slice || exp.e1.type.isStaticOrDynamicArray())
|
||||
{
|
||||
if (checkNonAssignmentArrayOp(exp.e1))
|
||||
return setError();
|
||||
|
@ -7579,15 +7591,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
exp.e1 = exp.e1.optimize(WANTvalue, /*keepLvalue*/ true);
|
||||
exp.type = exp.e1.type;
|
||||
|
||||
if (auto ad = isAggregate(exp.e1.type))
|
||||
{
|
||||
if (const s = search_function(ad, Id.opOpAssign))
|
||||
{
|
||||
error(exp.loc, "none of the `opOpAssign` overloads of `%s` are callable for `%s` of type `%s`", ad.toChars(), exp.e1.toChars(), exp.e1.type.toChars());
|
||||
return setError();
|
||||
}
|
||||
}
|
||||
if (exp.e1.checkScalar() ||
|
||||
if (exp.suggestOpOpAssign(sc, parent) ||
|
||||
exp.e1.checkScalar() ||
|
||||
exp.e1.checkReadModifyWrite(exp.op, exp.e2) ||
|
||||
exp.e1.checkSharedAccess(sc))
|
||||
return setError();
|
||||
|
@ -7644,7 +7649,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
result = (cast(BinExp)e).reorderSettingAAElem(sc);
|
||||
}
|
||||
|
||||
private Expression compileIt(MixinExp exp, Scope *sc)
|
||||
private Expression compileIt(MixinExp exp, Scope* sc)
|
||||
{
|
||||
OutBuffer buf;
|
||||
if (expressionsToString(buf, sc, exp.exps, exp.loc, null, true))
|
||||
|
@ -8842,7 +8847,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
fix16997(sc, exp);
|
||||
exp.type = exp.e1.type;
|
||||
Type tb = exp.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (!isArrayOpValid(exp.e1))
|
||||
{
|
||||
|
@ -8857,9 +8862,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
result = exp.incompatibleTypes();
|
||||
return;
|
||||
}
|
||||
if (exp.e1.checkNoBool())
|
||||
return setError();
|
||||
if (exp.e1.checkArithmetic(exp.op) ||
|
||||
if (exp.e1.checkNoBool() ||
|
||||
exp.e1.checkArithmetic(exp.op) ||
|
||||
exp.e1.checkSharedAccess(sc))
|
||||
return setError();
|
||||
|
||||
|
@ -8885,11 +8889,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
result = exp.incompatibleTypes();
|
||||
return;
|
||||
}
|
||||
if (exp.e1.checkNoBool())
|
||||
return setError();
|
||||
if (exp.e1.checkArithmetic(exp.op))
|
||||
return setError();
|
||||
if (exp.e1.checkSharedAccess(sc))
|
||||
|
||||
if (exp.e1.checkNoBool() ||
|
||||
exp.e1.checkArithmetic(exp.op) ||
|
||||
exp.e1.checkSharedAccess(sc))
|
||||
return setError();
|
||||
|
||||
result = exp.e1;
|
||||
|
@ -8907,7 +8910,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
fix16997(sc, exp);
|
||||
exp.type = exp.e1.type;
|
||||
Type tb = exp.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (!isArrayOpValid(exp.e1))
|
||||
{
|
||||
|
@ -8922,9 +8925,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
result = exp.incompatibleTypes();
|
||||
return;
|
||||
}
|
||||
if (exp.e1.checkNoBool())
|
||||
return setError();
|
||||
if (exp.e1.checkIntegral() ||
|
||||
if (exp.e1.checkNoBool() ||
|
||||
exp.e1.checkIntegral() ||
|
||||
exp.e1.checkSharedAccess(sc))
|
||||
return setError();
|
||||
|
||||
|
@ -9189,7 +9191,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
}
|
||||
|
||||
if (!t1b.equals(tob) && (t1b.ty == Tarray || t1b.ty == Tsarray))
|
||||
if (!t1b.equals(tob) && t1b.isStaticOrDynamicArray())
|
||||
{
|
||||
if (checkNonAssignmentArrayOp(exp.e1))
|
||||
return setError();
|
||||
|
@ -9509,7 +9511,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
/* Run semantic on lwr and upr.
|
||||
*/
|
||||
Scope* scx = sc;
|
||||
if (t1b.ty == Tsarray || t1b.ty == Tarray || t1b.ty == Ttuple)
|
||||
if (t1b.isStaticOrDynamicArray() || t1b.ty == Ttuple)
|
||||
{
|
||||
// Create scope for 'length' variable
|
||||
ScopeDsymbol sym = new ArrayScopeSymbol(sc, exp);
|
||||
|
@ -9616,7 +9618,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
IntRange lwrRange = getIntRange(exp.lwr);
|
||||
IntRange uprRange = getIntRange(exp.upr);
|
||||
|
||||
if (t1b.ty == Tsarray || t1b.ty == Tarray)
|
||||
if (t1b.isStaticOrDynamicArray())
|
||||
{
|
||||
Expression el = new ArrayLengthExp(exp.loc, exp.e1);
|
||||
el = el.expressionSemantic(sc);
|
||||
|
@ -9702,8 +9704,39 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
|
||||
if (auto ad = isAggregate(exp.e1.type))
|
||||
{
|
||||
error(exp.loc, "no `[]` operator overload for type `%s`", exp.e1.type.toChars());
|
||||
errorSupplemental(ad.loc, "`%s` declared here", ad.toPrettyChars());
|
||||
if (exp.arguments.length == 0)
|
||||
{
|
||||
error(exp.loc, "no `[]` operator overload for type `%s`", exp.e1.type.toChars());
|
||||
errorSupplemental(ad.loc, "perhaps define `auto opIndex() {}` for `%s`", ad.toPrettyChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
const(char)* typeString(Expression exp)
|
||||
{
|
||||
if (auto e = exp.trySemantic(sc))
|
||||
return e.type.toChars();
|
||||
else
|
||||
return "__error__";
|
||||
}
|
||||
|
||||
if (auto ie = (*exp.arguments)[0].isIntervalExp())
|
||||
{
|
||||
error(exp.loc, "no `[%s]` operator overload for type `%s`", ie.toChars(), exp.e1.type.toChars());
|
||||
errorSupplemental(ad.loc, "perhaps define `auto opSlice(%s lower, %s upper) {}` for `%s`",
|
||||
typeString(ie.lwr), typeString(ie.upr), ad.toPrettyChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
OutBuffer buf;
|
||||
buf.printf("%s", typeString((*exp.arguments)[0]));
|
||||
foreach (e; (*exp.arguments)[1 .. $])
|
||||
buf.printf(", %s", typeString(e));
|
||||
|
||||
error(exp.loc, "no `[]` operator overload for type `%s`", exp.e1.type.toChars());
|
||||
errorSupplemental(ad.loc, "perhaps define `auto opIndex(%s) {}` for `%s`",
|
||||
buf.extractChars, ad.toPrettyChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (exp.e1.op == EXP.type && exp.e1.type.ty != Ttuple)
|
||||
error(exp.loc, "static array of `%s` with multiple lengths not allowed", exp.e1.type.toChars());
|
||||
|
@ -9906,7 +9939,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
t1b = t1b.castMod(tv1.mod);
|
||||
exp.e1 = exp.e1.castTo(sc, t1b);
|
||||
}
|
||||
if (t1b.ty == Tsarray || t1b.ty == Tarray)
|
||||
if (t1b.isStaticOrDynamicArray())
|
||||
{
|
||||
if (!checkAddressable(exp, sc))
|
||||
return setError();
|
||||
|
@ -9915,7 +9948,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
/* Run semantic on e2
|
||||
*/
|
||||
Scope* scx = sc;
|
||||
if (t1b.ty == Tsarray || t1b.ty == Tarray || t1b.ty == Ttuple)
|
||||
if (t1b.isStaticOrDynamicArray() || t1b.ty == Ttuple)
|
||||
{
|
||||
// Create scope for 'length' variable
|
||||
ScopeDsymbol sym = new ArrayScopeSymbol(sc, exp);
|
||||
|
@ -10051,7 +10084,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
// We might know $ now
|
||||
setLengthVarIfKnown(exp.lengthVar, t1b);
|
||||
|
||||
if (t1b.ty == Tsarray || t1b.ty == Tarray)
|
||||
if (t1b.isStaticOrDynamicArray())
|
||||
{
|
||||
Expression el = new ArrayLengthExp(exp.loc, exp.e1);
|
||||
el = el.expressionSemantic(sc);
|
||||
|
@ -10198,7 +10231,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
e = new AddAssignExp(exp.loc, exp.e1, IntegerExp.literal!1);
|
||||
else
|
||||
e = new MinAssignExp(exp.loc, exp.e1, IntegerExp.literal!1);
|
||||
result = e.expressionSemantic(sc);
|
||||
result = e.expressionSemanticWithParent(sc, exp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -10307,7 +10340,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
if (search_function(ad, Id.opIndexAssign))
|
||||
{
|
||||
// Deal with $
|
||||
res = resolveOpDollar(sc, ae, &e0);
|
||||
res = resolveOpDollar(sc, ae, e0);
|
||||
if (!res) // a[i..j] = e2 might be: a.opSliceAssign(e2, i, j)
|
||||
goto Lfallback;
|
||||
if (res.op == EXP.error)
|
||||
|
@ -10337,7 +10370,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
if (maybeSlice && search_function(ad, Id.opSliceAssign))
|
||||
{
|
||||
// Deal with $
|
||||
res = resolveOpDollar(sc, ae, ie, &e0);
|
||||
res = resolveOpDollar(sc, ae, ie, e0);
|
||||
if (res.op == EXP.error)
|
||||
return setResult(res);
|
||||
|
||||
|
@ -11317,7 +11350,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return setError();
|
||||
}
|
||||
else if (exp.e1.op == EXP.slice &&
|
||||
(t2.ty == Tarray || t2.ty == Tsarray) &&
|
||||
t2.isStaticOrDynamicArray() &&
|
||||
t2.nextOf().implicitConvTo(t1.nextOf()))
|
||||
{
|
||||
// Check element-wise assignment.
|
||||
|
@ -11426,7 +11459,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
|
||||
if (exp.e1.op == EXP.slice &&
|
||||
(t1.ty == Tarray || t1.ty == Tsarray) &&
|
||||
t1.isStaticOrDynamicArray() &&
|
||||
t1.nextOf().toBasetype().ty == Tvoid)
|
||||
{
|
||||
if (t2.nextOf().implicitConvTo(t1.nextOf()))
|
||||
|
@ -11461,7 +11494,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
|
||||
/* Look for array operations
|
||||
*/
|
||||
if ((t2.ty == Tarray || t2.ty == Tsarray) && isArrayOpValid(exp.e2))
|
||||
if (t2.isStaticOrDynamicArray() && isArrayOpValid(exp.e2))
|
||||
{
|
||||
// Look for valid array operations
|
||||
if (exp.memset != MemorySet.blockAssign &&
|
||||
|
@ -11638,7 +11671,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return ae;
|
||||
|
||||
const isArrayAssign = (ae.e1.isSliceExp() || ae.e1.type.ty == Tsarray) &&
|
||||
(ae.e2.type.ty == Tsarray || ae.e2.type.ty == Tarray) &&
|
||||
(ae.e2.type.isStaticOrDynamicArray()) &&
|
||||
(ae.e1.type.nextOf() && ae.e2.type.nextOf() && ae.e1.type.nextOf.mutableOf.equals(ae.e2.type.nextOf.mutableOf()));
|
||||
|
||||
const isArraySetAssign = (ae.e1.isSliceExp() || ae.e1.type.ty == Tsarray) &&
|
||||
|
@ -11710,11 +11743,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return;
|
||||
}
|
||||
|
||||
if (exp.e1.checkReadModifyWrite(exp.op, exp.e2))
|
||||
if (exp.suggestOpOpAssign(sc, parent) ||
|
||||
exp.e1.checkReadModifyWrite(exp.op, exp.e2))
|
||||
return setError();
|
||||
|
||||
assert(exp.e1.type && exp.e2.type);
|
||||
if (exp.e1.op == EXP.slice || exp.e1.type.ty == Tarray || exp.e1.type.ty == Tsarray)
|
||||
if (exp.e1.op == EXP.slice || exp.e1.type.isStaticOrDynamicArray())
|
||||
{
|
||||
if (checkNonAssignmentArrayOp(exp.e1))
|
||||
return setError();
|
||||
|
@ -11734,7 +11768,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
// Check element types are arithmetic
|
||||
Type tb1 = exp.e1.type.nextOf().toBasetype();
|
||||
Type tb2 = exp.e2.type.toBasetype();
|
||||
if (tb2.ty == Tarray || tb2.ty == Tsarray)
|
||||
if (tb2.isStaticOrDynamicArray())
|
||||
tb2 = tb2.nextOf().toBasetype();
|
||||
if ((tb1.isIntegral() || tb1.isFloating()) && (tb2.isIntegral() || tb2.isFloating()))
|
||||
{
|
||||
|
@ -11789,6 +11823,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return;
|
||||
}
|
||||
|
||||
if (exp.suggestOpOpAssign(sc, parent))
|
||||
return setError();
|
||||
|
||||
if (SliceExp se = exp.e1.isSliceExp())
|
||||
{
|
||||
if (se.e1.type.toBasetype().ty == Tsarray)
|
||||
|
@ -11823,7 +11860,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
* EXP.concatenateDcharAssign: appending dchar to T[]
|
||||
*/
|
||||
if ((tb1.ty == Tarray) &&
|
||||
(tb2.ty == Tarray || tb2.ty == Tsarray) &&
|
||||
tb2.isStaticOrDynamicArray() &&
|
||||
(exp.e2.implicitConvTo(exp.e1.type) ||
|
||||
(tb2.nextOf().implicitConvTo(tb1next) &&
|
||||
// Do not strip const(void)[]
|
||||
|
@ -12081,7 +12118,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
|
||||
Type tb = exp.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (!isArrayOpValid(exp))
|
||||
{
|
||||
|
@ -12092,7 +12129,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return;
|
||||
}
|
||||
|
||||
if (exp.checkArithmeticBin())
|
||||
if (exp.suggestBinaryOverloads(sc) || exp.checkArithmeticBin())
|
||||
return setError();
|
||||
|
||||
tb1 = exp.e1.type.toBasetype();
|
||||
|
@ -12234,7 +12271,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
|
||||
Type tb = exp.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (!isArrayOpValid(exp))
|
||||
{
|
||||
|
@ -12245,7 +12282,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return;
|
||||
}
|
||||
|
||||
if (exp.checkArithmeticBin())
|
||||
if (exp.suggestBinaryOverloads(sc) || exp.checkArithmeticBin())
|
||||
return setError();
|
||||
|
||||
t1 = exp.e1.type.toBasetype();
|
||||
|
@ -12308,7 +12345,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return result;
|
||||
}
|
||||
|
||||
void handleCatArgument(Expressions *arguments, Expression e, Type catType, bool isRightArg)
|
||||
void handleCatArgument(Expressions* arguments, Expression e, Type catType, bool isRightArg)
|
||||
{
|
||||
auto tb = e.type.toBasetype();
|
||||
|
||||
|
@ -12416,7 +12453,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
|
||||
// Check for: array ~ element
|
||||
if ((tb1.ty == Tsarray || tb1.ty == Tarray) && tb2.ty != Tvoid)
|
||||
if (tb1.isStaticOrDynamicArray() && tb2.ty != Tvoid)
|
||||
{
|
||||
if (exp.e1.op == EXP.arrayLiteral)
|
||||
{
|
||||
|
@ -12455,7 +12492,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
}
|
||||
// Check for: element ~ array
|
||||
if ((tb2.ty == Tsarray || tb2.ty == Tarray) && tb1.ty != Tvoid)
|
||||
if (tb2.isStaticOrDynamicArray() && tb1.ty != Tvoid)
|
||||
{
|
||||
if (exp.e2.op == EXP.arrayLiteral)
|
||||
{
|
||||
|
@ -12490,7 +12527,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
|
||||
Lpeer:
|
||||
if ((tb1.ty == Tsarray || tb1.ty == Tarray) && (tb2.ty == Tsarray || tb2.ty == Tarray) && (tb1next.mod || tb2next.mod) && (tb1next.mod != tb2next.mod))
|
||||
if (tb1.isStaticOrDynamicArray() && tb2.isStaticOrDynamicArray() &&
|
||||
(tb1next.mod || tb2next.mod) && (tb1next.mod != tb2next.mod))
|
||||
{
|
||||
Type t1 = tb1next.mutableOf().constOf().arrayOf();
|
||||
Type t2 = tb2next.mutableOf().constOf().arrayOf();
|
||||
|
@ -12529,8 +12567,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
Type t1 = exp.e1.type.toBasetype();
|
||||
Type t2 = exp.e2.type.toBasetype();
|
||||
Expression e;
|
||||
if ((t1.ty == Tarray || t1.ty == Tsarray) &&
|
||||
(t2.ty == Tarray || t2.ty == Tsarray))
|
||||
if (t1.isStaticOrDynamicArray() && t2.isStaticOrDynamicArray())
|
||||
{
|
||||
// Normalize to ArrayLiteralExp or StringExp as far as possible
|
||||
e = exp.optimize(WANTvalue);
|
||||
|
@ -12546,7 +12583,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
trySetCatExpLowering(result);
|
||||
}
|
||||
|
||||
bool commonBinOpSemantic(BinExp exp)
|
||||
bool commonArithBinOpSemantic(BinExp exp)
|
||||
{
|
||||
if (Expression e = exp.opOverloadBinary(sc, aliasThisStop))
|
||||
{
|
||||
|
@ -12559,15 +12596,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
result = ex;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool commonArithBinOpSemantic(BinExp exp)
|
||||
{
|
||||
if (commonBinOpSemantic(exp))
|
||||
return true;
|
||||
|
||||
Type tb = exp.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (!isArrayOpValid(exp))
|
||||
{
|
||||
|
@ -12578,7 +12609,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return true;
|
||||
}
|
||||
|
||||
if (exp.checkArithmeticBin() || exp.checkSharedAccessBin(sc))
|
||||
if (exp.suggestBinaryOverloads(sc) || exp.checkArithmeticBin() || exp.checkSharedAccessBin(sc))
|
||||
{
|
||||
setError();
|
||||
return true;
|
||||
|
@ -12792,7 +12823,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return;
|
||||
}
|
||||
|
||||
if (exp.checkIntegralBin() || exp.checkSharedAccessBin(sc))
|
||||
if (exp.suggestBinaryOverloads(sc) || exp.checkIntegralBin() || exp.checkSharedAccessBin(sc))
|
||||
return setError();
|
||||
|
||||
if (!target.isVectorOpSupported(exp.e1.type.toBasetype(), exp.op, exp.e2.type.toBasetype()))
|
||||
|
@ -12847,7 +12878,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
}
|
||||
|
||||
Type tb = exp.type.toBasetype();
|
||||
if (tb.ty == Tarray || tb.ty == Tsarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (!isArrayOpValid(exp))
|
||||
{
|
||||
|
@ -12862,7 +12893,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
result = exp.incompatibleTypes();
|
||||
return;
|
||||
}
|
||||
if (exp.checkIntegralBin() || exp.checkSharedAccessBin(sc))
|
||||
|
||||
if (exp.suggestBinaryOverloads(sc) || exp.checkIntegralBin() || exp.checkSharedAccessBin(sc))
|
||||
return setError();
|
||||
|
||||
result = exp;
|
||||
|
@ -13008,7 +13040,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
Expression arrayLowering = null;
|
||||
t1 = exp.e1.type.toBasetype();
|
||||
t2 = exp.e2.type.toBasetype();
|
||||
if ((t1.ty == Tarray || t1.ty == Tsarray || t1.ty == Tpointer) && (t2.ty == Tarray || t2.ty == Tsarray || t2.ty == Tpointer))
|
||||
if ((t1.isStaticOrDynamicArray() || t1.ty == Tpointer) && (t2.isStaticOrDynamicArray() || t2.ty == Tpointer))
|
||||
{
|
||||
Type t1next = t1.nextOf();
|
||||
Type t2next = t2.nextOf();
|
||||
|
@ -13018,8 +13050,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return setError();
|
||||
}
|
||||
|
||||
if ((t1.ty == Tarray || t1.ty == Tsarray) &&
|
||||
(t2.ty == Tarray || t2.ty == Tsarray))
|
||||
if (t1.isStaticOrDynamicArray() && t2.isStaticOrDynamicArray())
|
||||
{
|
||||
if (!verifyHookExist(exp.loc, *sc, Id.__cmp, "comparing arrays"))
|
||||
return setError();
|
||||
|
@ -13040,12 +13071,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
arrayLowering = al;
|
||||
}
|
||||
}
|
||||
else if (t1.ty == Tstruct || t2.ty == Tstruct || (t1.ty == Tclass && t2.ty == Tclass))
|
||||
else if (t1.isTypeClass() && t2.isTypeClass())
|
||||
{
|
||||
if (t2.ty == Tstruct)
|
||||
error(exp.loc, "need member function `opCmp()` for %s `%s` to compare", t2.toDsymbol(sc).kind(), t2.toChars());
|
||||
else
|
||||
error(exp.loc, "need member function `opCmp()` for %s `%s` to compare", t1.toDsymbol(sc).kind(), t1.toChars());
|
||||
error(exp.loc, "need member function `opCmp()` for %s `%s` to compare", t1.toDsymbol(sc).kind(), t1.toChars());
|
||||
return setError();
|
||||
}
|
||||
else if (t1.isComplex() || t2.isComplex())
|
||||
|
@ -13119,7 +13147,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return setError();
|
||||
|
||||
case Tarray, Tsarray:
|
||||
result = exp.incompatibleTypes();
|
||||
result = exp.incompatibleTypes(sc);
|
||||
errorSupplemental(exp.loc, "`in` is only allowed on associative arrays");
|
||||
const(char)* slice = (t2b.ty == Tsarray) ? "[]" : "";
|
||||
errorSupplemental(exp.loc, "perhaps use `std.algorithm.find(%s, %s%s)` instead",
|
||||
|
@ -13127,7 +13155,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return;
|
||||
|
||||
default:
|
||||
result = exp.incompatibleTypes();
|
||||
result = exp.incompatibleTypes(sc);
|
||||
return;
|
||||
}
|
||||
result = exp;
|
||||
|
@ -13258,8 +13286,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return;
|
||||
}
|
||||
|
||||
const isArrayComparison = (t1.ty == Tarray || t1.ty == Tsarray) &&
|
||||
(t2.ty == Tarray || t2.ty == Tsarray);
|
||||
const isArrayComparison = t1.isStaticOrDynamicArray() && t2.isStaticOrDynamicArray();
|
||||
const needsArrayLowering = isArrayComparison && needsDirectEq(t1, t2, sc);
|
||||
|
||||
if (!needsArrayLowering)
|
||||
|
@ -13849,6 +13876,20 @@ private Expression expressionSemantic(Expression e, Scope* sc, Type[2] aliasThis
|
|||
return v.result;
|
||||
}
|
||||
|
||||
// ditto, but with `parent` parameter that represents the expression before rewriting.
|
||||
// This way, when lowering an expression (e.g. i++ to i+=1), error messages can still
|
||||
// refer to the original expression.
|
||||
private Expression expressionSemanticWithParent(Expression e, Scope* sc, Expression parent)
|
||||
{
|
||||
if (e.expressionSemanticDone)
|
||||
return e;
|
||||
|
||||
scope v = new ExpressionSemanticVisitor(sc);
|
||||
v.parent = parent;
|
||||
e.accept(v);
|
||||
return v.result;
|
||||
}
|
||||
|
||||
private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc)
|
||||
{
|
||||
//printf("dotIdSemanticPropX() %s\n", toChars(exp));
|
||||
|
@ -14371,7 +14412,7 @@ Expression dotTemplateSemanticProp(DotTemplateInstanceExp exp, Scope* sc, bool g
|
|||
{
|
||||
exp.e1 = die.e1; // take back
|
||||
Type t1b = exp.e1.type.toBasetype();
|
||||
if (t1b.ty == Tarray || t1b.ty == Tsarray || t1b.ty == Taarray || t1b.ty == Tnull || (t1b.isTypeBasic() && t1b.ty != Tvoid))
|
||||
if (t1b.isStaticOrDynamicArray() || t1b.ty == Taarray || t1b.ty == Tnull || (t1b.isTypeBasic() && t1b.ty != Tvoid))
|
||||
{
|
||||
/* No built-in type has templatized properties, so do shortcut.
|
||||
* It is necessary in: 1024.max!"a < b"
|
||||
|
@ -14741,11 +14782,16 @@ private bool checkArithmetic(Expression e, EXP op)
|
|||
return true;
|
||||
}
|
||||
|
||||
// FIXME: Existing code relies on adding / subtracting types in typeof() expressions:
|
||||
// alias I = ulong; alias U = typeof(I + 1u);
|
||||
// https://github.com/dlang/dmd/issues/20763
|
||||
if (op == EXP.add || op == EXP.min)
|
||||
if ((op == EXP.add || op == EXP.min) && e.isTypeExp())
|
||||
{
|
||||
// @@@DEPRECATED_2.121@@@
|
||||
// Deprecated in 2.111
|
||||
// In 2.121, remove this branch to let `checkValue` raise the error
|
||||
deprecation(e.loc, "type `%s` has no value", e.toChars);
|
||||
if (!e.type.isOpaqueType)
|
||||
deprecationSupplemental(e.loc, "perhaps use `%s.init`", e.toChars);
|
||||
return false;
|
||||
}
|
||||
|
||||
return e.checkValue();
|
||||
}
|
||||
|
@ -14801,6 +14847,77 @@ private bool checkArithmeticBin(BinExp e)
|
|||
return (e.e1.checkArithmetic(e.op) || e.e2.checkArithmetic(e.op));
|
||||
}
|
||||
|
||||
/****************************************
|
||||
* Check that the expression has a valid value.
|
||||
* If not, generates an error "... has no value".`
|
||||
*
|
||||
* Params:
|
||||
* e = expression to check
|
||||
*
|
||||
* Returns:
|
||||
* `true` if the expression is not valid or has `void` type.
|
||||
*/
|
||||
bool checkValue(Expression e)
|
||||
{
|
||||
if (auto te = e.isTypeExp())
|
||||
{
|
||||
error(e.loc, "type `%s` has no value", e.toChars());
|
||||
if (!e.type.isOpaqueType)
|
||||
errorSupplemental(e.loc, "perhaps use `%s.init`", e.toChars());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto dtie = e.isDotTemplateInstanceExp())
|
||||
{
|
||||
if (dtie.ti.tempdecl &&
|
||||
dtie.ti.semantictiargsdone &&
|
||||
dtie.ti.semanticRun == PASS.initial)
|
||||
|
||||
error(e.loc, "partial %s `%s` has no value", dtie.ti.kind(), e.toChars());
|
||||
else
|
||||
error(e.loc, "%s `%s` has no value", dtie.ti.kind(), dtie.ti.toChars());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto se = e.isScopeExp())
|
||||
{
|
||||
error(e.loc, "%s `%s` has no value", se.sds.kind(), se.sds.toChars());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto te = e.isTemplateExp())
|
||||
{
|
||||
error(e.loc, "%s `%s` has no value", te.td.kind(), te.toChars());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto fe = e.isFuncExp())
|
||||
{
|
||||
if (fe.td)
|
||||
{
|
||||
error(e.loc, "template lambda has no value");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (auto dte = e.isDotTemplateExp())
|
||||
{
|
||||
error(e.loc, "%s `%s` has no value", dte.td.kind(), e.toChars());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (e.type && e.type.toBasetype().ty == Tvoid)
|
||||
{
|
||||
error(e.loc, "expression `%s` is `void` and has no value", e.toChars());
|
||||
//print(); assert(0);
|
||||
if (!global.gag)
|
||||
e.type = Type.terror;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/***************************************
|
||||
* If expression is shared, check that we can access it.
|
||||
* Give error message if not.
|
||||
|
@ -16251,7 +16368,7 @@ private bool fit(StructDeclaration sd, const ref Loc loc, Scope* sc, Expressions
|
|||
Type typeb = se.type.toBasetype();
|
||||
TY tynto = tb.nextOf().ty;
|
||||
if (!se.committed &&
|
||||
(typeb.ty == Tarray || typeb.ty == Tsarray) && tynto.isSomeChar &&
|
||||
typeb.isStaticOrDynamicArray() && tynto.isSomeChar &&
|
||||
se.numberOfCodeUnits(tynto) < (cast(TypeSArray)tb).dim.toInteger())
|
||||
{
|
||||
e = se.castTo(sc, t);
|
||||
|
@ -16623,7 +16740,7 @@ private Modifiable checkModify(Declaration d, Loc loc, Scope* sc, Expression e1,
|
|||
if (scx.func == vthis.parent && scx.contract != Contract.none)
|
||||
{
|
||||
if (!(flag & ModifyFlags.noError))
|
||||
error(loc, "%s `%s` cannot modify parameter `this` in contract", d.kind, d.toPrettyChars);
|
||||
error(loc, "cannot modify member variable `%s` in contract", d.toPrettyChars());
|
||||
return Modifiable.initialization; // do not report type related errors
|
||||
}
|
||||
}
|
||||
|
|
|
@ -277,7 +277,7 @@ extern (C++) class FuncDeclaration : Declaration
|
|||
/// Sibling nested functions which called this one
|
||||
FuncDeclarations siblingCallers;
|
||||
|
||||
FuncDeclarations *inlinedNestedCallees;
|
||||
FuncDeclarations* inlinedNestedCallees;
|
||||
|
||||
/// In case of failed `@safe` inference, store the error that made the function `@system` for
|
||||
/// better diagnostics
|
||||
|
@ -1390,11 +1390,6 @@ extern (C++) final class CtorDeclaration : FuncDeclaration
|
|||
return isCpCtor ? "copy constructor" : "constructor";
|
||||
}
|
||||
|
||||
override const(char)* toChars() const
|
||||
{
|
||||
return "this";
|
||||
}
|
||||
|
||||
override bool isVirtual() const
|
||||
{
|
||||
return false;
|
||||
|
@ -1496,11 +1491,6 @@ extern (C++) final class DtorDeclaration : FuncDeclaration
|
|||
return "destructor";
|
||||
}
|
||||
|
||||
override const(char)* toChars() const
|
||||
{
|
||||
return "~this";
|
||||
}
|
||||
|
||||
override bool isVirtual() const
|
||||
{
|
||||
// D dtor's don't get put into the vtbl[]
|
||||
|
|
|
@ -242,8 +242,7 @@ extern (C++) struct Param
|
|||
Output mixinOut; // write expanded mixins for debugging
|
||||
Output moduleDeps; // Generate `.deps` module dependencies
|
||||
|
||||
uint debuglevel; // debug level
|
||||
uint versionlevel; // version level
|
||||
bool debugEnabled; // Global -debug flag (no -debug=XXX) is active
|
||||
|
||||
bool run; // run resulting executable
|
||||
Strings runargs; // arguments for executable
|
||||
|
|
|
@ -250,8 +250,7 @@ struct Param
|
|||
Output mixinOut; // write expanded mixins for debugging
|
||||
Output moduleDeps; // Generate `.deps` module dependencies
|
||||
|
||||
unsigned debuglevel; // debug level
|
||||
unsigned versionlevel; // version level
|
||||
d_bool debugEnabled; // -debug flag is passed
|
||||
|
||||
d_bool run; // run resulting executable
|
||||
Strings runargs; // arguments for executable
|
||||
|
|
|
@ -140,6 +140,42 @@ public const(char)* toChars(const Type t)
|
|||
return buf.extractChars();
|
||||
}
|
||||
|
||||
public const(char)* toChars(const Dsymbol d)
|
||||
{
|
||||
if (auto td = d.isTemplateDeclaration())
|
||||
{
|
||||
HdrGenState hgs;
|
||||
OutBuffer buf;
|
||||
toCharsMaybeConstraints(td, buf, hgs);
|
||||
return buf.extractChars();
|
||||
}
|
||||
|
||||
if (auto ti = d.isTemplateInstance())
|
||||
{
|
||||
OutBuffer buf;
|
||||
toCBufferInstance(ti, buf);
|
||||
return buf.extractChars();
|
||||
}
|
||||
|
||||
if (auto tm = d.isTemplateMixin())
|
||||
{
|
||||
OutBuffer buf;
|
||||
toCBufferInstance(tm, buf);
|
||||
return buf.extractChars();
|
||||
}
|
||||
|
||||
if (auto tid = d.isTypeInfoDeclaration())
|
||||
{
|
||||
OutBuffer buf;
|
||||
buf.writestring("typeid(");
|
||||
buf.writestring(tid.tinfo.toChars());
|
||||
buf.writeByte(')');
|
||||
return buf.extractChars();
|
||||
}
|
||||
|
||||
return d.ident ? d.ident.toHChars2() : "__anonymous";
|
||||
}
|
||||
|
||||
public const(char)[] toString(const Initializer i)
|
||||
{
|
||||
OutBuffer buf;
|
||||
|
@ -880,10 +916,7 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs)
|
|||
void visitDebugSymbol(DebugSymbol s)
|
||||
{
|
||||
buf.writestring("debug = ");
|
||||
if (s.ident)
|
||||
buf.writestring(s.ident.toString());
|
||||
else
|
||||
buf.print(s.level);
|
||||
buf.writestring(s.ident.toString());
|
||||
buf.writeByte(';');
|
||||
buf.writenl();
|
||||
}
|
||||
|
@ -891,10 +924,7 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs)
|
|||
void visitVersionSymbol(VersionSymbol s)
|
||||
{
|
||||
buf.writestring("version = ");
|
||||
if (s.ident)
|
||||
buf.writestring(s.ident.toString());
|
||||
else
|
||||
buf.print(s.level);
|
||||
buf.writestring(s.ident.toString());
|
||||
buf.writeByte(';');
|
||||
buf.writenl();
|
||||
}
|
||||
|
@ -2237,9 +2267,20 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, ref HdrGenSt
|
|||
buf.writestring(e.ident.toString());
|
||||
}
|
||||
|
||||
void visitDsymbol(DsymbolExp e)
|
||||
void visitDsymbol(Dsymbol s)
|
||||
{
|
||||
buf.writestring(e.s.toChars());
|
||||
// For -vcg-ast, print internal names such as __invariant, __ctor etc.
|
||||
// This condition is a bit kludge, and can be cleaned up if the
|
||||
// mutual dependency `AST.toChars <> hdrgen.d` gets refactored
|
||||
if (hgs.vcg_ast && s.ident && !s.isTemplateInstance() && !s.isTemplateDeclaration())
|
||||
buf.writestring(s.ident.toChars());
|
||||
else
|
||||
buf.writestring(s.toChars());
|
||||
}
|
||||
|
||||
void visitDsymbolExp(DsymbolExp e)
|
||||
{
|
||||
visitDsymbol(e.s);
|
||||
}
|
||||
|
||||
void visitThis(ThisExp e)
|
||||
|
@ -2444,7 +2485,7 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, ref HdrGenSt
|
|||
|
||||
void visitVar(VarExp e)
|
||||
{
|
||||
buf.writestring(e.var.toChars());
|
||||
visitDsymbol(e.var);
|
||||
}
|
||||
|
||||
void visitOver(OverExp e)
|
||||
|
@ -2678,7 +2719,7 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, ref HdrGenSt
|
|||
{
|
||||
expToBuffer(e.e1, PREC.primary, buf, hgs);
|
||||
buf.writeByte('.');
|
||||
buf.writestring(e.var.toChars());
|
||||
visitDsymbol(e.var);
|
||||
}
|
||||
|
||||
void visitDotTemplateInstance(DotTemplateInstanceExp e)
|
||||
|
@ -2893,7 +2934,7 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, ref HdrGenSt
|
|||
case EXP.float64: return visitReal(e.isRealExp());
|
||||
case EXP.complex80: return visitComplex(e.isComplexExp());
|
||||
case EXP.identifier: return visitIdentifier(e.isIdentifierExp());
|
||||
case EXP.dSymbol: return visitDsymbol(e.isDsymbolExp());
|
||||
case EXP.dSymbol: return visitDsymbolExp(e.isDsymbolExp());
|
||||
case EXP.this_: return visitThis(e.isThisExp());
|
||||
case EXP.super_: return visitSuper(e.isSuperExp());
|
||||
case EXP.null_: return visitNull(e.isNullExp());
|
||||
|
@ -3112,20 +3153,14 @@ public:
|
|||
override void visit(DebugCondition c)
|
||||
{
|
||||
buf.writestring("debug (");
|
||||
if (c.ident)
|
||||
buf.writestring(c.ident.toString());
|
||||
else
|
||||
buf.print(c.level);
|
||||
buf.writestring(c.ident.toString());
|
||||
buf.writeByte(')');
|
||||
}
|
||||
|
||||
override void visit(VersionCondition c)
|
||||
{
|
||||
buf.writestring("version (");
|
||||
if (c.ident)
|
||||
buf.writestring(c.ident.toString());
|
||||
else
|
||||
buf.print(c.level);
|
||||
buf.writestring(c.ident.toString());
|
||||
buf.writeByte(')');
|
||||
}
|
||||
|
||||
|
@ -4505,7 +4540,15 @@ string EXPtoString(EXP op)
|
|||
EXP.declaration : "declaration",
|
||||
|
||||
EXP.interval : "interval",
|
||||
EXP.loweredAssignExp : "="
|
||||
EXP.loweredAssignExp : "=",
|
||||
|
||||
EXP.thrownException : "CTFE ThrownException",
|
||||
EXP.cantExpression : "<cant>",
|
||||
EXP.voidExpression : "cast(void)0",
|
||||
EXP.showCtfeContext : "<error>",
|
||||
EXP.break_ : "<break>",
|
||||
EXP.continue_ : "<continue>",
|
||||
EXP.goto_ : "<goto>",
|
||||
];
|
||||
const p = strings[op];
|
||||
if (!p)
|
||||
|
|
|
@ -39,7 +39,7 @@ else
|
|||
|
||||
/************************ AsmStatement ***************************************/
|
||||
|
||||
Statement asmSemantic(AsmStatement s, Scope *sc)
|
||||
Statement asmSemantic(AsmStatement s, Scope* sc)
|
||||
{
|
||||
//printf("AsmStatement.semantic()\n");
|
||||
|
||||
|
@ -89,7 +89,7 @@ Statement asmSemantic(AsmStatement s, Scope *sc)
|
|||
|
||||
/************************ CAsmDeclaration ************************************/
|
||||
|
||||
void asmSemantic(CAsmDeclaration ad, Scope *sc)
|
||||
void asmSemantic(CAsmDeclaration ad, Scope* sc)
|
||||
{
|
||||
version (NoBackend)
|
||||
{
|
||||
|
|
|
@ -37,17 +37,17 @@ import dmd.statementsem;
|
|||
* Returns:
|
||||
* the completed gcc asm statement, or null if errors occurred
|
||||
*/
|
||||
public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc)
|
||||
public Statement gccAsmSemantic(GccAsmStatement s, Scope* sc)
|
||||
{
|
||||
//printf("GccAsmStatement.semantic()\n");
|
||||
const bool doUnittests = global.params.parsingUnittestsRequired();
|
||||
scope p = new Parser!ASTCodegen(sc._module, ";", false, global.errorSink, &global.compileEnv, doUnittests);
|
||||
|
||||
// Make a safe copy of the token list before parsing.
|
||||
Token *toklist = null;
|
||||
Token* toklist = null;
|
||||
Token **ptoklist = &toklist;
|
||||
|
||||
for (Token *token = s.tokens; token; token = token.next)
|
||||
for (Token* token = s.tokens; token; token = token.next)
|
||||
{
|
||||
*ptoklist = p.allocateToken();
|
||||
memcpy(*ptoklist, token, Token.sizeof);
|
||||
|
@ -126,7 +126,7 @@ public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc)
|
|||
* ad = asm declaration
|
||||
* sc = the scope where the asm declaration is located
|
||||
*/
|
||||
public void gccAsmSemantic(CAsmDeclaration ad, Scope *sc)
|
||||
public void gccAsmSemantic(CAsmDeclaration ad, Scope* sc)
|
||||
{
|
||||
import dmd.typesem : pointerTo;
|
||||
ad.code = semanticString(sc, ad.code, "asm definition");
|
||||
|
@ -254,9 +254,9 @@ Lerror:
|
|||
* Returns:
|
||||
* array of parsed clobber expressions
|
||||
*/
|
||||
Expressions *parseExtAsmClobbers(Parser)(Parser p)
|
||||
Expressions* parseExtAsmClobbers(Parser)(Parser p)
|
||||
{
|
||||
Expressions *clobbers;
|
||||
Expressions* clobbers;
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
@ -305,9 +305,9 @@ Lerror:
|
|||
* Returns:
|
||||
* array of parsed goto labels
|
||||
*/
|
||||
Identifiers *parseExtAsmGotoLabels(Parser)(Parser p)
|
||||
Identifiers* parseExtAsmGotoLabels(Parser)(Parser p)
|
||||
{
|
||||
Identifiers *labels;
|
||||
Identifiers* labels;
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
|
|
@ -108,7 +108,8 @@ nothrow:
|
|||
const(char)* p = null;
|
||||
if (this == Id.ctor)
|
||||
p = "this";
|
||||
else if (this == Id.dtor)
|
||||
else if (this == Id.dtor || this == Id.__xdtor || this == Id.__fieldDtor ||
|
||||
this == Id.__aggrDtor || this == Id.cppdtor || this == Id.ticppdtor)
|
||||
p = "~this";
|
||||
else if (this == Id.unitTest)
|
||||
p = "unittest";
|
||||
|
@ -120,6 +121,8 @@ nothrow:
|
|||
p = "result";
|
||||
else if (this == Id.returnLabel)
|
||||
p = "return";
|
||||
else if (this == Id.postblit)
|
||||
p = "this(this)";
|
||||
else
|
||||
{
|
||||
p = toChars();
|
||||
|
|
|
@ -166,7 +166,7 @@ Expression carraySemantic(ArrayExp ae, Scope* sc)
|
|||
* So, rewrite as an IndexExp if we can.
|
||||
*/
|
||||
auto t1 = e1.type.toBasetype();
|
||||
if (t1.isTypeDArray() || t1.isTypeSArray())
|
||||
if (t1.isStaticOrDynamicArray())
|
||||
{
|
||||
e2 = e2.expressionSemantic(sc).arrayFuncConv(sc);
|
||||
// C doesn't do array bounds checking, so `true` turns it off
|
||||
|
@ -176,7 +176,7 @@ Expression carraySemantic(ArrayExp ae, Scope* sc)
|
|||
e1 = e1.arrayFuncConv(sc); // e1 might still be a function call
|
||||
e2 = e2.expressionSemantic(sc);
|
||||
auto t2 = e2.type.toBasetype();
|
||||
if (t2.isTypeDArray() || t2.isTypeSArray())
|
||||
if (t2.isStaticOrDynamicArray())
|
||||
{
|
||||
return new IndexExp(ae.loc, e2, e1, true).expressionSemantic(sc); // swap operands
|
||||
}
|
||||
|
|
|
@ -439,7 +439,7 @@ Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedIn
|
|||
Type typeb = se.type.toBasetype();
|
||||
TY tynto = tb.nextOf().ty;
|
||||
if (!se.committed &&
|
||||
(typeb.ty == Tarray || typeb.ty == Tsarray) && tynto.isSomeChar &&
|
||||
typeb.isStaticOrDynamicArray() && tynto.isSomeChar &&
|
||||
se.numberOfCodeUnits(tynto) < tb.isTypeSArray().dim.toInteger())
|
||||
{
|
||||
i.exp = se.castTo(sc, t);
|
||||
|
|
|
@ -141,7 +141,7 @@ struct SignExtendedNumber
|
|||
|
||||
SignExtendedNumber opBinary(string op : "*")(SignExtendedNumber rhs)
|
||||
{
|
||||
// perform *saturated* multiplication, otherwise we may get bogus ranges
|
||||
// perform* saturated* multiplication, otherwise we may get bogus ranges
|
||||
// like 0x10 * 0x10 == 0x100 == 0.
|
||||
|
||||
/* Special handling for zeros:
|
||||
|
|
|
@ -351,19 +351,18 @@ public:
|
|||
{
|
||||
if (loc.isValid())
|
||||
{
|
||||
if (auto filename = loc.filename.toDString)
|
||||
SourceLoc sl = SourceLoc(loc);
|
||||
if (sl.filename.length > 0 && sl.filename != this.filename)
|
||||
{
|
||||
if (filename != this.filename)
|
||||
{
|
||||
this.filename = filename;
|
||||
property("file", filename);
|
||||
}
|
||||
this.filename = sl.filename;
|
||||
property("file", sl.filename);
|
||||
}
|
||||
if (loc.linnum)
|
||||
|
||||
if (sl.linnum)
|
||||
{
|
||||
property(linename, loc.linnum);
|
||||
if (loc.charnum)
|
||||
property(charname, loc.charnum);
|
||||
property(linename, sl.linnum);
|
||||
if (sl.charnum)
|
||||
property(charname, sl.charnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,6 +96,16 @@ nothrow:
|
|||
return _linnum = num;
|
||||
}
|
||||
|
||||
/// Advance this location to the first column of the next line
|
||||
void nextLine()
|
||||
{
|
||||
if (this._linnum)
|
||||
{
|
||||
this._linnum++;
|
||||
this.charnum = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* Returns: filename for this location, null if none
|
||||
*/
|
||||
|
@ -126,9 +136,7 @@ nothrow:
|
|||
bool showColumns = Loc.showColumns,
|
||||
MessageStyle messageStyle = Loc.messageStyle) const nothrow
|
||||
{
|
||||
OutBuffer buf;
|
||||
writeSourceLoc(buf, SourceLoc(this), showColumns, messageStyle);
|
||||
return buf.extractChars();
|
||||
return SourceLoc(this).toChars(showColumns, messageStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -140,9 +148,11 @@ nothrow:
|
|||
*/
|
||||
extern (C++) bool equals(ref const(Loc) loc) const
|
||||
{
|
||||
return (!showColumns || charnum == loc.charnum) &&
|
||||
linnum == loc.linnum &&
|
||||
FileName.equals(filename, loc.filename);
|
||||
SourceLoc lhs = SourceLoc(this);
|
||||
SourceLoc rhs = SourceLoc(loc);
|
||||
return (!showColumns || lhs.column == rhs.column) &&
|
||||
lhs.line == rhs.line &&
|
||||
FileName.equals(lhs.filename, rhs.filename);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,6 +208,8 @@ void writeSourceLoc(ref OutBuffer buf,
|
|||
bool showColumns,
|
||||
MessageStyle messageStyle) nothrow
|
||||
{
|
||||
if (loc.filename.length == 0)
|
||||
return;
|
||||
buf.writestring(loc.filename);
|
||||
if (loc.line == 0)
|
||||
return;
|
||||
|
@ -258,4 +270,18 @@ struct SourceLoc
|
|||
this.line = loc.linnum;
|
||||
this.column = loc.charnum;
|
||||
}
|
||||
|
||||
extern (C++) const(char)* toChars(
|
||||
bool showColumns = Loc.showColumns,
|
||||
MessageStyle messageStyle = Loc.messageStyle) const nothrow
|
||||
{
|
||||
OutBuffer buf;
|
||||
writeSourceLoc(buf, this, showColumns, messageStyle);
|
||||
return buf.extractChars();
|
||||
}
|
||||
|
||||
bool opEquals(SourceLoc other) const nothrow
|
||||
{
|
||||
return this.filename == other.filename && this.line == other.line && this.column == other.column;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,11 +109,9 @@ public:
|
|||
|
||||
Modules aimports; // all imported modules
|
||||
|
||||
unsigned debuglevel; // debug level
|
||||
Identifiers *debugids; // debug identifiers
|
||||
Identifiers *debugidsNot; // forward referenced debug identifiers
|
||||
|
||||
unsigned versionlevel; // version level
|
||||
Identifiers *versionids; // version identifiers
|
||||
Identifiers *versionidsNot; // forward referenced version identifiers
|
||||
|
||||
|
|
|
@ -1521,6 +1521,8 @@ extern (C++) abstract class Type : ASTNode
|
|||
inout(TypeTraits) isTypeTraits() { return ty == Ttraits ? cast(typeof(return))this : null; }
|
||||
inout(TypeNoreturn) isTypeNoreturn() { return ty == Tnoreturn ? cast(typeof(return))this : null; }
|
||||
inout(TypeTag) isTypeTag() { return ty == Ttag ? cast(typeof(return))this : null; }
|
||||
|
||||
extern (D) bool isStaticOrDynamicArray() const { return ty == Tarray || ty == Tsarray; }
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
|
@ -3947,7 +3949,7 @@ extern (C++) final class Parameter : ASTNode
|
|||
Type isLazyArray()
|
||||
{
|
||||
Type tb = type.toBasetype();
|
||||
if (tb.ty == Tsarray || tb.ty == Tarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
Type tel = (cast(TypeArray)tb).next.toBasetype();
|
||||
if (auto td = tel.isTypeDelegate())
|
||||
|
@ -4057,7 +4059,7 @@ extern (C++) final class Parameter : ASTNode
|
|||
|
||||
/***************************************
|
||||
* Expands tuples in args in depth first order. Calls
|
||||
* dg(void *ctx, size_t argidx, Parameter *arg) for each Parameter.
|
||||
* dg(void* ctx, size_t argidx, Parameter* arg) for each Parameter.
|
||||
* If dg returns !=0, stops and returns that value else returns 0.
|
||||
* Use this function to avoid the O(N + N^2/2) complexity of
|
||||
* calculating dim and calling N times getNth.
|
||||
|
@ -4316,10 +4318,10 @@ void attributesApply(const TypeFunction tf, void delegate(string) dg, TRUSTforma
|
|||
AggregateDeclaration isAggregate(Type t)
|
||||
{
|
||||
t = t.toBasetype();
|
||||
if (t.ty == Tclass)
|
||||
return (cast(TypeClass)t).sym;
|
||||
if (t.ty == Tstruct)
|
||||
return (cast(TypeStruct)t).sym;
|
||||
if (auto tc = t.isTypeClass())
|
||||
return tc.sym;
|
||||
if (auto ts = t.isTypeStruct())
|
||||
return ts.sym;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -4334,7 +4336,7 @@ AggregateDeclaration isAggregate(Type t)
|
|||
bool isIndexableNonAggregate(Type t)
|
||||
{
|
||||
t = t.toBasetype();
|
||||
return (t.ty == Tpointer || t.ty == Tsarray || t.ty == Tarray || t.ty == Taarray ||
|
||||
return (t.ty == Tpointer || t.isStaticOrDynamicArray() || t.ty == Taarray ||
|
||||
t.ty == Ttuple || t.ty == Tvector);
|
||||
}
|
||||
|
||||
|
|
|
@ -1683,7 +1683,7 @@ void genKill(ref ObState obstate, ObNode* ob)
|
|||
override void visit(ArrayLiteralExp e)
|
||||
{
|
||||
Type tb = e.type.toBasetype();
|
||||
if (tb.ty == Tsarray || tb.ty == Tarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (e.basis)
|
||||
e.basis.accept(this);
|
||||
|
@ -2424,7 +2424,7 @@ void checkObErrors(ref ObState obstate)
|
|||
override void visit(ArrayLiteralExp e)
|
||||
{
|
||||
Type tb = e.type.toBasetype();
|
||||
if (tb.ty == Tsarray || tb.ty == Tarray)
|
||||
if (tb.isStaticOrDynamicArray())
|
||||
{
|
||||
if (e.basis)
|
||||
e.basis.accept(this);
|
||||
|
|
|
@ -71,58 +71,63 @@ bool isCommutative(EXP op) @safe
|
|||
return false;
|
||||
}
|
||||
|
||||
/// Returns: whether `op` can be overloaded with `opBinary`
|
||||
private bool hasOpBinary(EXP op) pure @safe
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case EXP.add: return true;
|
||||
case EXP.min: return true;
|
||||
case EXP.mul: return true;
|
||||
case EXP.div: return true;
|
||||
case EXP.mod: return true;
|
||||
case EXP.and: return true;
|
||||
case EXP.or: return true;
|
||||
case EXP.xor: return true;
|
||||
case EXP.leftShift: return true;
|
||||
case EXP.rightShift: return true;
|
||||
case EXP.unsignedRightShift: return true;
|
||||
case EXP.concatenate: return true;
|
||||
case EXP.pow: return true;
|
||||
case EXP.in_: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the = from op=, e.g. += becomes +
|
||||
*
|
||||
* Params:
|
||||
* op = tag for a binary assign operator
|
||||
* Returns: the corresponding binary operator, or `op` if it wasn't an assign operator
|
||||
*/
|
||||
private EXP stripAssignOp(EXP op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case EXP.addAssign: return EXP.add;
|
||||
case EXP.minAssign: return EXP.min;
|
||||
case EXP.mulAssign: return EXP.mul;
|
||||
case EXP.divAssign: return EXP.div;
|
||||
case EXP.modAssign: return EXP.mod;
|
||||
case EXP.andAssign: return EXP.and;
|
||||
case EXP.orAssign: return EXP.or;
|
||||
case EXP.xorAssign: return EXP.xor;
|
||||
case EXP.leftShiftAssign: return EXP.leftShift;
|
||||
case EXP.rightShiftAssign: return EXP.rightShift;
|
||||
case EXP.unsignedRightShiftAssign: return EXP.unsignedRightShift;
|
||||
case EXP.concatenateAssign: return EXP.concatenate;
|
||||
case EXP.powAssign: return EXP.pow;
|
||||
default: return op;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
* Helper function to turn operator into template argument list
|
||||
*/
|
||||
Objects* opToArg(Scope* sc, EXP op)
|
||||
{
|
||||
/* Remove the = from op=
|
||||
*/
|
||||
switch (op)
|
||||
{
|
||||
case EXP.addAssign:
|
||||
op = EXP.add;
|
||||
break;
|
||||
case EXP.minAssign:
|
||||
op = EXP.min;
|
||||
break;
|
||||
case EXP.mulAssign:
|
||||
op = EXP.mul;
|
||||
break;
|
||||
case EXP.divAssign:
|
||||
op = EXP.div;
|
||||
break;
|
||||
case EXP.modAssign:
|
||||
op = EXP.mod;
|
||||
break;
|
||||
case EXP.andAssign:
|
||||
op = EXP.and;
|
||||
break;
|
||||
case EXP.orAssign:
|
||||
op = EXP.or;
|
||||
break;
|
||||
case EXP.xorAssign:
|
||||
op = EXP.xor;
|
||||
break;
|
||||
case EXP.leftShiftAssign:
|
||||
op = EXP.leftShift;
|
||||
break;
|
||||
case EXP.rightShiftAssign:
|
||||
op = EXP.rightShift;
|
||||
break;
|
||||
case EXP.unsignedRightShiftAssign:
|
||||
op = EXP.unsignedRightShift;
|
||||
break;
|
||||
case EXP.concatenateAssign:
|
||||
op = EXP.concatenate;
|
||||
break;
|
||||
case EXP.powAssign:
|
||||
op = EXP.pow;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Expression e = new StringExp(Loc.initial, EXPtoString(op));
|
||||
Expression e = new StringExp(Loc.initial, EXPtoString(stripAssignOp(op)));
|
||||
e = e.expressionSemantic(sc);
|
||||
auto tiargs = new Objects();
|
||||
tiargs.push(e);
|
||||
|
@ -144,7 +149,7 @@ Expression checkAliasThisForLhs(AggregateDeclaration ad, Scope* sc, BinExp e, Ty
|
|||
BinExp be = cast(BinExp)e.copy();
|
||||
// Resolve 'alias this' but in case of assigment don't resolve properties yet
|
||||
// because 'e1 = e2' could mean 'e1(e2)' or 'e1() = e2'
|
||||
bool findOnly = (e.op == EXP.assign);
|
||||
bool findOnly = e.isAssignExp() !is null;
|
||||
be.e1 = resolveAliasThis(sc, e.e1, true, findOnly);
|
||||
if (!be.e1)
|
||||
return null;
|
||||
|
@ -173,13 +178,12 @@ Expression checkAliasThisForRhs(AggregateDeclaration ad, Scope* sc, BinExp e, Ty
|
|||
|
||||
Expression opOverloadUnary(UnaExp e, Scope* sc)
|
||||
{
|
||||
Expression result;
|
||||
if (auto ae = e.e1.isArrayExp())
|
||||
{
|
||||
ae.e1 = ae.e1.expressionSemantic(sc);
|
||||
ae.e1 = resolveProperties(sc, ae.e1);
|
||||
Expression ae1old = ae.e1;
|
||||
const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
|
||||
const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].isIntervalExp());
|
||||
IntervalExp ie = null;
|
||||
if (maybeSlice && ae.arguments.length)
|
||||
{
|
||||
|
@ -188,70 +192,61 @@ Expression opOverloadUnary(UnaExp e, Scope* sc)
|
|||
Type att = null; // first cyclic `alias this` type
|
||||
while (true)
|
||||
{
|
||||
if (ae.e1.op == EXP.error)
|
||||
if (ae.e1.isErrorExp())
|
||||
{
|
||||
return ae.e1;
|
||||
}
|
||||
Expression e0 = null;
|
||||
Expression ae1save = ae.e1;
|
||||
ae.lengthVar = null;
|
||||
Type t1b = ae.e1.type.toBasetype();
|
||||
AggregateDeclaration ad = isAggregate(t1b);
|
||||
|
||||
AggregateDeclaration ad = isAggregate(ae.e1.type);
|
||||
if (!ad)
|
||||
break;
|
||||
|
||||
if (search_function(ad, Id.opIndexUnary))
|
||||
{
|
||||
Expression e0;
|
||||
// Deal with $
|
||||
result = resolveOpDollar(sc, ae, &e0);
|
||||
if (!result) // op(a[i..j]) might be: a.opSliceUnary!(op)(i, j)
|
||||
Expression ae2 = resolveOpDollar(sc, ae, e0);
|
||||
if (!ae2) // op(a[i..j]) might be: a.opSliceUnary!(op)(i, j)
|
||||
goto Lfallback;
|
||||
if (result.op == EXP.error)
|
||||
return result;
|
||||
if (ae2.isErrorExp())
|
||||
return ae2;
|
||||
/* Rewrite op(a[arguments]) as:
|
||||
* a.opIndexUnary!(op)(arguments)
|
||||
*/
|
||||
Expressions* a = ae.arguments.copy();
|
||||
Objects* tiargs = opToArg(sc, e.op);
|
||||
result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opIndexUnary, tiargs);
|
||||
result = new CallExp(e.loc, result, a);
|
||||
* a.opIndexUnary!(op)(arguments)
|
||||
*/
|
||||
Expression result = dotTemplateCall(ae.e1, Id.opIndexUnary, opToArg(sc, e.op), (*ae.arguments)[]);
|
||||
if (maybeSlice) // op(a[]) might be: a.opSliceUnary!(op)()
|
||||
result = result.trySemantic(sc);
|
||||
else
|
||||
result = result.expressionSemantic(sc);
|
||||
|
||||
if (result)
|
||||
{
|
||||
return Expression.combine(e0, result);
|
||||
}
|
||||
}
|
||||
Lfallback:
|
||||
if (maybeSlice && search_function(ad, Id.opSliceUnary))
|
||||
{
|
||||
// Deal with $
|
||||
result = resolveOpDollar(sc, ae, ie, &e0);
|
||||
if (result.op == EXP.error)
|
||||
return result;
|
||||
Expression e0;
|
||||
auto ae2 = resolveOpDollar(sc, ae, ie, e0);
|
||||
if (ae2.isErrorExp())
|
||||
return ae2;
|
||||
/* Rewrite op(a[i..j]) as:
|
||||
* a.opSliceUnary!(op)(i, j)
|
||||
*/
|
||||
auto a = new Expressions();
|
||||
if (ie)
|
||||
{
|
||||
a.push(ie.lwr);
|
||||
a.push(ie.upr);
|
||||
}
|
||||
Objects* tiargs = opToArg(sc, e.op);
|
||||
result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opSliceUnary, tiargs);
|
||||
result = new CallExp(e.loc, result, a);
|
||||
result = result.expressionSemantic(sc);
|
||||
result = Expression.combine(e0, result);
|
||||
return result;
|
||||
* a.opSliceUnary!(op)(i, j)
|
||||
*/
|
||||
Expression result = ie ?
|
||||
dotTemplateCall(ae.e1, Id.opSliceUnary, opToArg(sc, e.op), ie.lwr, ie.upr) :
|
||||
dotTemplateCall(ae.e1, Id.opSliceUnary, opToArg(sc, e.op));
|
||||
|
||||
return Expression.combine(e0, result.expressionSemantic(sc));
|
||||
}
|
||||
// Didn't find it. Forward to aliasthis
|
||||
if (ad.aliasthis && !isRecursiveAliasThis(att, ae.e1.type))
|
||||
{
|
||||
/* Rewrite op(a[arguments]) as:
|
||||
* op(a.aliasthis[arguments])
|
||||
*/
|
||||
* op(a.aliasthis[arguments])
|
||||
*/
|
||||
ae.e1 = resolveAliasThis(sc, ae1save, true);
|
||||
if (ae.e1)
|
||||
continue;
|
||||
|
@ -266,7 +261,7 @@ Expression opOverloadUnary(UnaExp e, Scope* sc)
|
|||
Type att = null; // first cyclic `alias this` type
|
||||
while (1)
|
||||
{
|
||||
if (e.e1.op == EXP.error)
|
||||
if (e.e1.isErrorExp())
|
||||
{
|
||||
return e.e1;
|
||||
}
|
||||
|
@ -275,19 +270,11 @@ Expression opOverloadUnary(UnaExp e, Scope* sc)
|
|||
if (!ad)
|
||||
break;
|
||||
|
||||
Dsymbol fd = null;
|
||||
/* Rewrite as:
|
||||
* e1.opUnary!(op)()
|
||||
*/
|
||||
fd = search_function(ad, Id.opUnary);
|
||||
if (fd)
|
||||
{
|
||||
Objects* tiargs = opToArg(sc, e.op);
|
||||
result = new DotTemplateInstanceExp(e.loc, e.e1, fd.ident, tiargs);
|
||||
result = new CallExp(e.loc, result);
|
||||
result = result.expressionSemantic(sc);
|
||||
return result;
|
||||
}
|
||||
if (Dsymbol fd = search_function(ad, Id.opUnary))
|
||||
return dotTemplateCall(e.e1, Id.opUnary, opToArg(sc, e.op)).expressionSemantic(sc);
|
||||
|
||||
// Didn't find it. Forward to aliasthis
|
||||
if (ad.aliasthis && !isRecursiveAliasThis(att, e.e1.type))
|
||||
|
@ -303,9 +290,19 @@ Expression opOverloadUnary(UnaExp e, Scope* sc)
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// For ++ and --, rewrites to += and -= are also tried, so don't error yet
|
||||
if (!e.isPreExp())
|
||||
{
|
||||
error(e.loc, "operator `%s` is not defined for `%s`", EXPtoString(e.op).ptr, ad.toChars());
|
||||
errorSupplemental(ad.loc, "perhaps overload the operator with `auto opUnary(string op : \"%s\")() {}`",
|
||||
EXPtoString(e.op).ptr);
|
||||
return ErrorExp.get();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
return null;
|
||||
}
|
||||
|
||||
Expression opOverloadArray(ArrayExp ae, Scope* sc)
|
||||
|
@ -313,17 +310,16 @@ Expression opOverloadArray(ArrayExp ae, Scope* sc)
|
|||
ae.e1 = ae.e1.expressionSemantic(sc);
|
||||
ae.e1 = resolveProperties(sc, ae.e1);
|
||||
Expression ae1old = ae.e1;
|
||||
const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
|
||||
const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].isIntervalExp());
|
||||
IntervalExp ie = null;
|
||||
if (maybeSlice && ae.arguments.length)
|
||||
{
|
||||
ie = (*ae.arguments)[0].isIntervalExp();
|
||||
}
|
||||
Expression result;
|
||||
Type att = null; // first cyclic `alias this` type
|
||||
while (true)
|
||||
{
|
||||
if (ae.e1.op == EXP.error)
|
||||
if (ae.e1.isErrorExp())
|
||||
{
|
||||
return ae.e1;
|
||||
}
|
||||
|
@ -336,67 +332,58 @@ Expression opOverloadArray(ArrayExp ae, Scope* sc)
|
|||
{
|
||||
// If the non-aggregate expression ae.e1 is indexable or sliceable,
|
||||
// convert it to the corresponding concrete expression.
|
||||
if (isIndexableNonAggregate(t1b) || ae.e1.op == EXP.type)
|
||||
if (isIndexableNonAggregate(t1b) || ae.e1.isTypeExp())
|
||||
{
|
||||
// Convert to SliceExp
|
||||
if (maybeSlice)
|
||||
{
|
||||
result = new SliceExp(ae.loc, ae.e1, ie);
|
||||
result = result.expressionSemantic(sc);
|
||||
return result;
|
||||
}
|
||||
return new SliceExp(ae.loc, ae.e1, ie).expressionSemantic(sc);
|
||||
|
||||
// Convert to IndexExp
|
||||
if (ae.arguments.length == 1)
|
||||
{
|
||||
result = new IndexExp(ae.loc, ae.e1, (*ae.arguments)[0]);
|
||||
result = result.expressionSemantic(sc);
|
||||
return result;
|
||||
}
|
||||
return new IndexExp(ae.loc, ae.e1, (*ae.arguments)[0]).expressionSemantic(sc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (search_function(ad, Id.opIndex))
|
||||
{
|
||||
// Deal with $
|
||||
result = resolveOpDollar(sc, ae, &e0);
|
||||
if (!result) // a[i..j] might be: a.opSlice(i, j)
|
||||
auto ae2 = resolveOpDollar(sc, ae, e0);
|
||||
if (!ae2) // a[i..j] might be: a.opSlice(i, j)
|
||||
goto Lfallback;
|
||||
if (result.op == EXP.error)
|
||||
return result;
|
||||
if (ae2.isErrorExp())
|
||||
return ae2;
|
||||
/* Rewrite e1[arguments] as:
|
||||
* e1.opIndex(arguments)
|
||||
*/
|
||||
Expressions* a = ae.arguments.copy();
|
||||
result = new DotIdExp(ae.loc, ae.e1, Id.opIndex);
|
||||
Expression result = new DotIdExp(ae.loc, ae.e1, Id.opIndex);
|
||||
result = new CallExp(ae.loc, result, a);
|
||||
if (maybeSlice) // a[] might be: a.opSlice()
|
||||
result = result.trySemantic(sc);
|
||||
else
|
||||
result = result.expressionSemantic(sc);
|
||||
|
||||
if (result)
|
||||
{
|
||||
return Expression.combine(e0, result);
|
||||
}
|
||||
}
|
||||
Lfallback:
|
||||
if (maybeSlice && ae.e1.op == EXP.type)
|
||||
if (maybeSlice && ae.e1.isTypeExp())
|
||||
{
|
||||
result = new SliceExp(ae.loc, ae.e1, ie);
|
||||
Expression result = new SliceExp(ae.loc, ae.e1, ie);
|
||||
result = result.expressionSemantic(sc);
|
||||
result = Expression.combine(e0, result);
|
||||
return result;
|
||||
return Expression.combine(e0, result);
|
||||
}
|
||||
if (maybeSlice && search_function(ad, Id.opSlice))
|
||||
{
|
||||
// Deal with $
|
||||
result = resolveOpDollar(sc, ae, ie, &e0);
|
||||
auto ae2 = resolveOpDollar(sc, ae, ie, e0);
|
||||
|
||||
if (result.op == EXP.error)
|
||||
if (ae2.isErrorExp())
|
||||
{
|
||||
if (!e0 && !search_function(ad, Id.dollar)) {
|
||||
ae.loc.errorSupplemental("Aggregate declaration '%s' does not define 'opDollar'", ae.e1.toChars());
|
||||
}
|
||||
return result;
|
||||
if (!e0 && !search_function(ad, Id.dollar))
|
||||
ad.loc.errorSupplemental("perhaps define `opDollar` for `%s`", ad.toChars());
|
||||
|
||||
return ae2;
|
||||
}
|
||||
/* Rewrite a[i..j] as:
|
||||
* a.opSlice(i, j)
|
||||
|
@ -407,11 +394,10 @@ Expression opOverloadArray(ArrayExp ae, Scope* sc)
|
|||
a.push(ie.lwr);
|
||||
a.push(ie.upr);
|
||||
}
|
||||
result = new DotIdExp(ae.loc, ae.e1, Id.opSlice);
|
||||
Expression result = new DotIdExp(ae.loc, ae.e1, Id.opSlice);
|
||||
result = new CallExp(ae.loc, result, a);
|
||||
result = result.expressionSemantic(sc);
|
||||
result = Expression.combine(e0, result);
|
||||
return result;
|
||||
return Expression.combine(e0, result);
|
||||
}
|
||||
// Didn't find it. Forward to aliasthis
|
||||
if (ad.aliasthis && !isRecursiveAliasThis(att, ae.e1.type))
|
||||
|
@ -428,7 +414,7 @@ Expression opOverloadArray(ArrayExp ae, Scope* sc)
|
|||
}
|
||||
ae.e1 = ae1old; // recovery
|
||||
ae.lengthVar = null;
|
||||
return result;
|
||||
return null;
|
||||
}
|
||||
|
||||
/***********************************************
|
||||
|
@ -437,48 +423,38 @@ Expression opOverloadArray(ArrayExp ae, Scope* sc)
|
|||
*/
|
||||
Expression opOverloadCast(CastExp e, Scope* sc, Type att = null)
|
||||
{
|
||||
Expression result;
|
||||
if (AggregateDeclaration ad = isAggregate(e.e1.type))
|
||||
AggregateDeclaration ad = isAggregate(e.e1.type);
|
||||
if (!ad)
|
||||
return null;
|
||||
|
||||
// Rewrite as: e1.opCast!(T)()
|
||||
if (Dsymbol fd = search_function(ad, Id.opCast))
|
||||
{
|
||||
Dsymbol fd = null;
|
||||
/* Rewrite as:
|
||||
* e1.opCast!(T)()
|
||||
*/
|
||||
fd = search_function(ad, Id.opCast);
|
||||
if (fd)
|
||||
version (all)
|
||||
{
|
||||
version (all)
|
||||
// Backwards compatibility with D1 if opCast is a function, not a template
|
||||
if (fd.isFuncDeclaration())
|
||||
{
|
||||
// Backwards compatibility with D1 if opCast is a function, not a template
|
||||
if (fd.isFuncDeclaration())
|
||||
{
|
||||
// Rewrite as: e1.opCast()
|
||||
return build_overload(e.loc, sc, e.e1, null, fd);
|
||||
}
|
||||
// Rewrite as: e1.opCast()
|
||||
return build_overload(e.loc, sc, e.e1, null, fd);
|
||||
}
|
||||
auto tiargs = new Objects();
|
||||
tiargs.push(e.to);
|
||||
result = new DotTemplateInstanceExp(e.loc, e.e1, fd.ident, tiargs);
|
||||
result = new CallExp(e.loc, result);
|
||||
result = result.expressionSemantic(sc);
|
||||
return result;
|
||||
}
|
||||
// Didn't find it. Forward to aliasthis
|
||||
if (ad.aliasthis && !isRecursiveAliasThis(att, e.e1.type))
|
||||
auto tiargs = new Objects();
|
||||
tiargs.push(e.to);
|
||||
return dotTemplateCall(e.e1, Id.opCast, tiargs).expressionSemantic(sc);
|
||||
}
|
||||
// Didn't find it. Forward to aliasthis
|
||||
if (ad.aliasthis && !isRecursiveAliasThis(att, e.e1.type))
|
||||
{
|
||||
// Rewrite `e1.opCast()` as `e1.aliasthis.opCast()`
|
||||
if (auto e1 = resolveAliasThis(sc, e.e1, true))
|
||||
{
|
||||
/* Rewrite op(e1) as:
|
||||
* op(e1.aliasthis)
|
||||
*/
|
||||
if (auto e1 = resolveAliasThis(sc, e.e1, true))
|
||||
{
|
||||
result = e.copy();
|
||||
(cast(UnaExp)result).e1 = e1;
|
||||
result = opOverloadCast(result.isCastExp(), sc, att);
|
||||
return result;
|
||||
}
|
||||
CastExp result = e.copy().isCastExp();
|
||||
result.e1 = e1;
|
||||
return result.opOverloadCast(sc, att);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return null;
|
||||
}
|
||||
|
||||
// When no operator overload functions are found for `e`, recursively try with `alias this`
|
||||
|
@ -488,7 +464,7 @@ Expression binAliasThis(BinExp e, Scope* sc, Type[2] aliasThisStop)
|
|||
AggregateDeclaration ad1 = isAggregate(e.e1.type);
|
||||
AggregateDeclaration ad2 = isAggregate(e.e2.type);
|
||||
Expression rewrittenLhs;
|
||||
if (!(e.op == EXP.assign && ad2 && ad1 == ad2)) // https://issues.dlang.org/show_bug.cgi?id=2943
|
||||
if (!(e.isAssignExp && ad2 && ad1 == ad2)) // https://issues.dlang.org/show_bug.cgi?id=2943
|
||||
{
|
||||
if (Expression result = checkAliasThisForLhs(ad1, sc, e, aliasThisStop))
|
||||
{
|
||||
|
@ -503,14 +479,14 @@ Expression binAliasThis(BinExp e, Scope* sc, Type[2] aliasThisStop)
|
|||
* one of the members, hence the `ad1.fields.length == 2 && ad1.vthis`
|
||||
* condition.
|
||||
*/
|
||||
if (result.op != EXP.assign)
|
||||
auto ae = result.isAssignExp();
|
||||
if (!ae)
|
||||
return result; // i.e: Rewrote `e1 = e2` -> `e1(e2)`
|
||||
|
||||
auto ae = result.isAssignExp();
|
||||
if (ae.e1.op != EXP.dotVariable)
|
||||
auto dve = ae.e1.isDotVarExp();
|
||||
if (!dve)
|
||||
return result; // i.e: Rewrote `e1 = e2` -> `e1() = e2`
|
||||
|
||||
auto dve = ae.e1.isDotVarExp();
|
||||
if (auto ad = dve.var.isMember2())
|
||||
{
|
||||
// i.e: Rewrote `e1 = e2` -> `e1.some.var = e2`
|
||||
|
@ -524,7 +500,7 @@ Expression binAliasThis(BinExp e, Scope* sc, Type[2] aliasThisStop)
|
|||
rewrittenLhs = ae.e1;
|
||||
}
|
||||
}
|
||||
if (!(e.op == EXP.assign && ad1 && ad1 == ad2)) // https://issues.dlang.org/show_bug.cgi?id=2943
|
||||
if (!(e.isAssignExp && ad1 && ad1 == ad2)) // https://issues.dlang.org/show_bug.cgi?id=2943
|
||||
{
|
||||
if (Expression result = checkAliasThisForRhs(ad2, sc, e, aliasThisStop))
|
||||
return result;
|
||||
|
@ -591,12 +567,104 @@ Expression opOverloadBinary(BinExp e, Scope* sc, Type[2] aliasThisStop)
|
|||
s_r = null;
|
||||
|
||||
bool choseReverse;
|
||||
if (auto res = pickBestBinaryOverload(sc, opToArg(sc, e.op), s, s_r, e, choseReverse))
|
||||
return res;
|
||||
if (auto result = pickBestBinaryOverload(sc, opToArg(sc, e.op), s, s_r, e, choseReverse))
|
||||
return result;
|
||||
|
||||
return binAliasThis(e, sc, aliasThisStop);
|
||||
}
|
||||
|
||||
/**
|
||||
* If applicable, print an error relating to implementing / fixing `opBinary` functions.
|
||||
* Params:
|
||||
* e = binary operation
|
||||
* sc = scope to try `opBinary!""` semantic in for error messages
|
||||
* Returns: `true` when an error related to `opBinary` was printed
|
||||
*/
|
||||
bool suggestBinaryOverloads(BinExp e, Scope* sc)
|
||||
{
|
||||
if (!e.op.hasOpBinary)
|
||||
return false;
|
||||
|
||||
AggregateDeclaration ad1 = isAggregate(e.e1.type);
|
||||
AggregateDeclaration ad2 = isAggregate(e.e2.type);
|
||||
|
||||
if (ad1)
|
||||
{
|
||||
if (Dsymbol s = search_function(ad1, Id.opBinary))
|
||||
{
|
||||
// This expressionSemantic will fail, otherwise operator overloading would have succeeded before
|
||||
dotTemplateCall(e.e1, Id.opBinary, opToArg(sc, e.op), e.e2).expressionSemantic(sc);
|
||||
errorSupplemental(s.loc, "`opBinary` defined here");
|
||||
return true;
|
||||
}
|
||||
error(e.loc, "operator `%s` is not defined for type `%s`", EXPtoString(e.op).ptr, e.e1.type.toChars);
|
||||
errorSupplemental(ad1.loc, "perhaps overload the operator with `auto opBinary(string op : \"%s\")(%s rhs) {}`", EXPtoString(e.op).ptr, e.e2.type.toChars);
|
||||
return true;
|
||||
}
|
||||
else if (ad2)
|
||||
{
|
||||
if (Dsymbol s_r = search_function(ad1, Id.opBinaryRight))
|
||||
{
|
||||
dotTemplateCall(e.e2, Id.opBinaryRight, opToArg(sc, e.op), e.e1).expressionSemantic(sc);
|
||||
errorSupplemental(s_r.loc, "`opBinaryRight` defined here");
|
||||
return true;
|
||||
}
|
||||
error(e.loc, "operator `%s` is not defined for type `%s`", EXPtoString(e.op).ptr, e.e2.type.toChars);
|
||||
errorSupplemental(ad2.loc, "perhaps overload the operator with `auto opBinaryRight(string op : \"%s\")(%s rhs) {}`", EXPtoString(e.op).ptr, e.e1.type.toChars);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If applicable, print an error relating to implementing / fixing `opOpAssign` or `opUnary` functions.
|
||||
* Params:
|
||||
* exp = binary operation
|
||||
* sc = scope to try `opOpAssign!""` semantic in for error messages
|
||||
* parent = if `exp` was lowered from this `PreExp` or `PostExp`, mention `opUnary` as well
|
||||
* Returns: `true` when an error related to `opOpAssign` was printed
|
||||
*/
|
||||
bool suggestOpOpAssign(BinAssignExp exp, Scope* sc, Expression parent)
|
||||
{
|
||||
auto ad = isAggregate(exp.e1.type);
|
||||
if (!ad)
|
||||
return false;
|
||||
|
||||
if (parent && (parent.isPreExp() || parent.isPostExp()))
|
||||
{
|
||||
error(exp.loc, "operator `%s` not supported for `%s` of type `%s`", EXPtoString(parent.op).ptr, exp.e1.toChars(), ad.toChars());
|
||||
errorSupplemental(ad.loc,
|
||||
"perhaps implement `auto opUnary(string op : \"%s\")() {}`"~
|
||||
" or `auto opOpAssign(string op : \"%s\")(int) {}`",
|
||||
EXPtoString(stripAssignOp(parent.op)).ptr,
|
||||
EXPtoString(stripAssignOp(exp.op)).ptr
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (const s = search_function(ad, Id.opOpAssign))
|
||||
{
|
||||
// This expressionSemantic will fail, otherwise operator overloading would have succeeded before
|
||||
dotTemplateCall(exp.e1, Id.opOpAssign, opToArg(sc, exp.op), exp.e2).expressionSemantic(sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
error(exp.loc, "operator `%s` not supported for `%s` of type `%s`", EXPtoString(exp.op).ptr, exp.e1.toChars(), ad.toChars());
|
||||
errorSupplemental(ad.loc, "perhaps implement `auto opOpAssign(string op : \"%s\")(%s) {}`",
|
||||
EXPtoString(stripAssignOp(exp.op)).ptr, exp.e2.type.toChars());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Helper to construct e.id!tiargs(args), e.g. `lhs.opBinary!"+"(rhs)`
|
||||
private Expression dotTemplateCall(Expression e, Identifier id, Objects* tiargs, Expression[] args...)
|
||||
{
|
||||
auto ti = new DotTemplateInstanceExp(e.loc, e, id, tiargs);
|
||||
auto expressions = new Expressions();
|
||||
expressions.pushSlice(args);
|
||||
return new CallExp(e.loc, ti, expressions);
|
||||
}
|
||||
|
||||
Expression opOverloadEqual(EqualExp e, Scope* sc, Type[2] aliasThisStop)
|
||||
{
|
||||
Type t1 = e.e1.type.toBasetype();
|
||||
|
@ -606,24 +674,23 @@ Expression opOverloadEqual(EqualExp e, Scope* sc, Type[2] aliasThisStop)
|
|||
* lowering to object.__equals(), which takes care of overloaded
|
||||
* operators for the element types.
|
||||
*/
|
||||
if ((t1.ty == Tarray || t1.ty == Tsarray) &&
|
||||
(t2.ty == Tarray || t2.ty == Tsarray))
|
||||
if (t1.isStaticOrDynamicArray() && t2.isStaticOrDynamicArray())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/* Check for class equality with null literal or typeof(null).
|
||||
*/
|
||||
if (t1.ty == Tclass && e.e2.op == EXP.null_ ||
|
||||
t2.ty == Tclass && e.e1.op == EXP.null_)
|
||||
if (t1.isTypeClass() && e.e2.isNullExp() ||
|
||||
t2.isTypeClass() && e.e1.isNullExp())
|
||||
{
|
||||
error(e.loc, "use `%s` instead of `%s` when comparing with `null`",
|
||||
EXPtoString(e.op == EXP.equal ? EXP.identity : EXP.notIdentity).ptr,
|
||||
EXPtoString(e.op).ptr);
|
||||
return ErrorExp.get();
|
||||
}
|
||||
if (t1.ty == Tclass && t2.ty == Tnull ||
|
||||
t1.ty == Tnull && t2.ty == Tclass)
|
||||
if (t1.isTypeClass() && t2.isTypeNull() ||
|
||||
t1.isTypeNull() && t2.isTypeClass())
|
||||
{
|
||||
// Comparing a class with typeof(null) should not call opEquals
|
||||
return null;
|
||||
|
@ -631,7 +698,7 @@ Expression opOverloadEqual(EqualExp e, Scope* sc, Type[2] aliasThisStop)
|
|||
|
||||
/* Check for class equality.
|
||||
*/
|
||||
if (t1.ty == Tclass && t2.ty == Tclass)
|
||||
if (t1.isTypeClass() && t2.isTypeClass())
|
||||
{
|
||||
ClassDeclaration cd1 = t1.isClassHandle();
|
||||
ClassDeclaration cd2 = t2.isClassHandle();
|
||||
|
@ -672,7 +739,7 @@ Expression opOverloadEqual(EqualExp e, Scope* sc, Type[2] aliasThisStop)
|
|||
EXP cmpOp;
|
||||
if (Expression result = compare_overload(e, sc, Id.opEquals, cmpOp, aliasThisStop))
|
||||
{
|
||||
if (lastComma(result).op == EXP.call && e.op == EXP.notEqual)
|
||||
if (lastComma(result).isCallExp() && e.op == EXP.notEqual)
|
||||
{
|
||||
result = new NotExp(result.loc, result);
|
||||
result = result.expressionSemantic(sc);
|
||||
|
@ -682,7 +749,7 @@ Expression opOverloadEqual(EqualExp e, Scope* sc, Type[2] aliasThisStop)
|
|||
|
||||
/* Check for pointer equality.
|
||||
*/
|
||||
if (t1.ty == Tpointer || t2.ty == Tpointer)
|
||||
if (t1.isTypePointer() || t2.isTypePointer())
|
||||
{
|
||||
/* Rewrite:
|
||||
* ptr1 == ptr2
|
||||
|
@ -699,7 +766,7 @@ Expression opOverloadEqual(EqualExp e, Scope* sc, Type[2] aliasThisStop)
|
|||
|
||||
/* Check for struct equality without opEquals.
|
||||
*/
|
||||
if (t1.ty == Tstruct && t2.ty == Tstruct)
|
||||
if (t1.isTypeStruct() && t2.isTypeStruct())
|
||||
{
|
||||
auto sd = t1.isTypeStruct().sym;
|
||||
if (sd != t2.isTypeStruct().sym)
|
||||
|
@ -738,10 +805,10 @@ Expression opOverloadEqual(EqualExp e, Scope* sc, Type[2] aliasThisStop)
|
|||
|
||||
/* Check for tuple equality.
|
||||
*/
|
||||
if (e.e1.op == EXP.tuple && e.e2.op == EXP.tuple)
|
||||
auto tup1 = e.e1.isTupleExp();
|
||||
auto tup2 = e.e2.isTupleExp();
|
||||
if (tup1 && tup2)
|
||||
{
|
||||
auto tup1 = e.e1.isTupleExp();
|
||||
auto tup2 = e.e2.isTupleExp();
|
||||
size_t dim = tup1.exps.length;
|
||||
if (dim != tup2.exps.length)
|
||||
{
|
||||
|
@ -794,12 +861,12 @@ Expression opOverloadCmp(CmpExp exp, Scope* sc, Type[2] aliasThisStop)
|
|||
error(e.loc, "recursive `opCmp` expansion");
|
||||
return ErrorExp.get();
|
||||
}
|
||||
if (e.op != EXP.call)
|
||||
if (!e.isCallExp())
|
||||
return e;
|
||||
|
||||
Type t1 = exp.e1.type.toBasetype();
|
||||
Type t2 = exp.e2.type.toBasetype();
|
||||
if (t1.ty != Tclass || t2.ty != Tclass)
|
||||
if (!t1.isTypeClass() || !t2.isTypeClass())
|
||||
{
|
||||
return new CmpExp(cmpOp, exp.loc, e, IntegerExp.literal!0).expressionSemantic(sc);
|
||||
}
|
||||
|
@ -842,7 +909,7 @@ Expression opOverloadBinaryAssign(BinAssignExp e, Scope* sc, Type[2] aliasThisSt
|
|||
ae.e1 = ae.e1.expressionSemantic(sc);
|
||||
ae.e1 = resolveProperties(sc, ae.e1);
|
||||
Expression ae1old = ae.e1;
|
||||
const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
|
||||
const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].isIntervalExp());
|
||||
IntervalExp ie = null;
|
||||
if (maybeSlice && ae.arguments.length)
|
||||
{
|
||||
|
@ -851,73 +918,61 @@ Expression opOverloadBinaryAssign(BinAssignExp e, Scope* sc, Type[2] aliasThisSt
|
|||
Type att = null; // first cyclic `alias this` type
|
||||
while (true)
|
||||
{
|
||||
if (ae.e1.op == EXP.error)
|
||||
{
|
||||
if (ae.e1.isErrorExp())
|
||||
return ae.e1;
|
||||
}
|
||||
|
||||
Expression e0 = null;
|
||||
Expression ae1save = ae.e1;
|
||||
ae.lengthVar = null;
|
||||
Type t1b = ae.e1.type.toBasetype();
|
||||
AggregateDeclaration ad = isAggregate(t1b);
|
||||
AggregateDeclaration ad = isAggregate(ae.e1.type);
|
||||
if (!ad)
|
||||
break;
|
||||
if (search_function(ad, Id.opIndexOpAssign))
|
||||
{
|
||||
// Deal with $
|
||||
Expression result = resolveOpDollar(sc, ae, &e0);
|
||||
if (!result) // (a[i..j] op= e2) might be: a.opSliceOpAssign!(op)(e2, i, j)
|
||||
Expression ae2 = resolveOpDollar(sc, ae, e0);
|
||||
if (!ae2) // (a[i..j] op= e2) might be: a.opSliceOpAssign!(op)(e2, i, j)
|
||||
goto Lfallback;
|
||||
if (result.op == EXP.error)
|
||||
return result;
|
||||
result = e.e2.expressionSemantic(sc);
|
||||
if (result.op == EXP.error)
|
||||
return result;
|
||||
e.e2 = result;
|
||||
if (ae2.isErrorExp())
|
||||
return ae2;
|
||||
e.e2 = e.e2.expressionSemantic(sc);
|
||||
if (e.e2.isErrorExp())
|
||||
return e.e2;
|
||||
|
||||
/* Rewrite a[arguments] op= e2 as:
|
||||
* a.opIndexOpAssign!(op)(e2, arguments)
|
||||
*/
|
||||
Expressions* a = ae.arguments.copy();
|
||||
a.insert(0, e.e2);
|
||||
Objects* tiargs = opToArg(sc, e.op);
|
||||
result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opIndexOpAssign, tiargs);
|
||||
result = new CallExp(e.loc, result, a);
|
||||
Expression result = dotTemplateCall(ae.e1, Id.opIndexOpAssign, opToArg(sc, e.op), (*a)[]);
|
||||
if (maybeSlice) // (a[] op= e2) might be: a.opSliceOpAssign!(op)(e2)
|
||||
result = result.trySemantic(sc);
|
||||
else
|
||||
result = result.expressionSemantic(sc);
|
||||
|
||||
if (result)
|
||||
{
|
||||
return Expression.combine(e0, result);
|
||||
}
|
||||
}
|
||||
Lfallback:
|
||||
if (maybeSlice && search_function(ad, Id.opSliceOpAssign))
|
||||
{
|
||||
// Deal with $
|
||||
Expression result = resolveOpDollar(sc, ae, ie, &e0);
|
||||
if (result.op == EXP.error)
|
||||
return result;
|
||||
result = e.e2.expressionSemantic(sc);
|
||||
if (result.op == EXP.error)
|
||||
return result;
|
||||
e.e2 = result;
|
||||
Expression ae2 = resolveOpDollar(sc, ae, ie, e0);
|
||||
if (ae2.isErrorExp())
|
||||
return ae2;
|
||||
|
||||
e.e2 = e.e2.expressionSemantic(sc);
|
||||
if (e.e2.isErrorExp())
|
||||
return e.e2;
|
||||
|
||||
/* Rewrite (a[i..j] op= e2) as:
|
||||
* a.opSliceOpAssign!(op)(e2, i, j)
|
||||
*/
|
||||
auto a = new Expressions();
|
||||
a.push(e.e2);
|
||||
if (ie)
|
||||
{
|
||||
a.push(ie.lwr);
|
||||
a.push(ie.upr);
|
||||
}
|
||||
Objects* tiargs = opToArg(sc, e.op);
|
||||
result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opSliceOpAssign, tiargs);
|
||||
result = new CallExp(e.loc, result, a);
|
||||
result = result.expressionSemantic(sc);
|
||||
result = Expression.combine(e0, result);
|
||||
return result;
|
||||
auto result = ie ?
|
||||
dotTemplateCall(ae.e1, Id.opSliceOpAssign, opToArg(sc, e.op), e.e2, ie.lwr, ie.upr) :
|
||||
dotTemplateCall(ae.e1, Id.opSliceOpAssign, opToArg(sc, e.op), e.e2);
|
||||
|
||||
return Expression.combine(e0, result.expressionSemantic(sc));
|
||||
}
|
||||
// Didn't find it. Forward to aliasthis
|
||||
if (ad.aliasthis && !isRecursiveAliasThis(att, ae.e1.type))
|
||||
|
@ -934,14 +989,14 @@ Expression opOverloadBinaryAssign(BinAssignExp e, Scope* sc, Type[2] aliasThisSt
|
|||
ae.e1 = ae1old; // recovery
|
||||
ae.lengthVar = null;
|
||||
}
|
||||
Expression result = e.binSemanticProp(sc);
|
||||
if (result)
|
||||
|
||||
if (Expression result = e.binSemanticProp(sc))
|
||||
return result;
|
||||
|
||||
// Don't attempt 'alias this' if an error occurred
|
||||
if (e.e1.type.ty == Terror || e.e2.type.ty == Terror)
|
||||
{
|
||||
if (e.e1.type.isTypeError() || e.e2.type.isTypeError())
|
||||
return ErrorExp.get();
|
||||
}
|
||||
|
||||
AggregateDeclaration ad1 = isAggregate(e.e1.type);
|
||||
Dsymbol s = search_function(ad1, Id.opOpAssign);
|
||||
if (s && !s.isTemplateDeclaration())
|
||||
|
@ -954,7 +1009,7 @@ Expression opOverloadBinaryAssign(BinAssignExp e, Scope* sc, Type[2] aliasThisSt
|
|||
if (auto res = pickBestBinaryOverload(sc, opToArg(sc, e.op), s, null, e, choseReverse))
|
||||
return res;
|
||||
|
||||
result = checkAliasThisForLhs(ad1, sc, e, aliasThisStop);
|
||||
Expression result = checkAliasThisForLhs(ad1, sc, e, aliasThisStop);
|
||||
if (result || !s) // no point in trying Rhs alias-this if there's no overload of any kind in lhs
|
||||
return result;
|
||||
|
||||
|
@ -990,7 +1045,7 @@ private Expression pickBestBinaryOverload(Scope* sc, Objects* tiargs, Dsymbol s,
|
|||
|
||||
if (s)
|
||||
{
|
||||
functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2));
|
||||
functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2), null);
|
||||
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
|
||||
return ErrorExp.get();
|
||||
}
|
||||
|
@ -998,7 +1053,7 @@ private Expression pickBestBinaryOverload(Scope* sc, Objects* tiargs, Dsymbol s,
|
|||
int count = m.count;
|
||||
if (s_r)
|
||||
{
|
||||
functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1));
|
||||
functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1), null);
|
||||
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
|
||||
return ErrorExp.get();
|
||||
}
|
||||
|
@ -1069,10 +1124,34 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, ref EXP
|
|||
* at this point, no matching opEquals was found for structs,
|
||||
* so we should not follow the alias this comparison code.
|
||||
*/
|
||||
if ((e.op == EXP.equal || e.op == EXP.notEqual) && ad1 == ad2)
|
||||
if (e.isEqualExp() && ad1 == ad2)
|
||||
return null;
|
||||
Expression result = checkAliasThisForLhs(ad1, sc, e, aliasThisStop);
|
||||
return result ? result : checkAliasThisForRhs(isAggregate(e.e2.type), sc, e, aliasThisStop);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
result = checkAliasThisForRhs(isAggregate(e.e2.type), sc, e, aliasThisStop);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
if (s || s_r)
|
||||
return null;
|
||||
|
||||
Expression suggestOverloading(Expression other, AggregateDeclaration ad)
|
||||
{
|
||||
error(e.loc, "no operator `%s` for type `%s`", EXPtoString(e.op).ptr, ad.toChars);
|
||||
string op = e.isEqualExp() ? "bool" : "int";
|
||||
errorSupplemental(ad.loc, "perhaps overload it with `%.*s %s(%s other) const {}`", op.fTuple.expand, id.toChars, other.type.toChars);
|
||||
return ErrorExp.get();
|
||||
}
|
||||
|
||||
// Classes have opCmp and opEquals defined in `Object` to fall back on already
|
||||
if (ad1 && ad1.isStructDeclaration)
|
||||
return suggestOverloading(e.e2, ad1);
|
||||
if (ad2 && ad2.isStructDeclaration)
|
||||
return suggestOverloading(e.e1, ad2);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/***********************************
|
||||
|
@ -1104,7 +1183,7 @@ Dsymbol search_function(ScopeDsymbol ad, Identifier funcid)
|
|||
Dsymbol s2 = s.toAlias();
|
||||
//printf("search_function: s2 = '%s'\n", s2.kind());
|
||||
FuncDeclaration fd = s2.isFuncDeclaration();
|
||||
if (fd && fd.type.ty == Tfunction)
|
||||
if (fd && fd.type.isTypeFunction())
|
||||
return fd;
|
||||
if (TemplateDeclaration td = s2.isTemplateDeclaration())
|
||||
return td;
|
||||
|
@ -1135,7 +1214,7 @@ bool inferForeachAggregate(Scope* sc, bool isForeach, ref Expression feaggr, out
|
|||
aggr = aggr.expressionSemantic(sc);
|
||||
aggr = resolveProperties(sc, aggr);
|
||||
aggr = aggr.optimize(WANTvalue);
|
||||
if (!aggr.type || aggr.op == EXP.error)
|
||||
if (!aggr.type || aggr.isErrorExp())
|
||||
return false;
|
||||
Type tab = aggr.type.toBasetype();
|
||||
switch (tab.ty)
|
||||
|
@ -1149,8 +1228,7 @@ bool inferForeachAggregate(Scope* sc, bool isForeach, ref Expression feaggr, out
|
|||
case Tclass:
|
||||
case Tstruct:
|
||||
{
|
||||
AggregateDeclaration ad = (tab.ty == Tclass) ? tab.isTypeClass().sym
|
||||
: tab.isTypeStruct().sym;
|
||||
AggregateDeclaration ad = isAggregate(tab);
|
||||
if (!sliced)
|
||||
{
|
||||
sapply = search_function(ad, isForeach ? Id.apply : Id.applyReverse);
|
||||
|
@ -1240,11 +1318,11 @@ bool inferApplyArgTypes(ForeachStatement fes, Scope* sc, ref Dsymbol sapply)
|
|||
// Determine ethis for sapply
|
||||
Expression ethis;
|
||||
Type tab = fes.aggr.type.toBasetype();
|
||||
if (tab.ty == Tclass || tab.ty == Tstruct)
|
||||
if (tab.isTypeClass() || tab.isTypeStruct())
|
||||
ethis = fes.aggr;
|
||||
else
|
||||
{
|
||||
assert(tab.ty == Tdelegate && fes.aggr.op == EXP.delegate_);
|
||||
assert(tab.isTypeDelegate() && fes.aggr.isDelegateExp());
|
||||
ethis = fes.aggr.isDelegateExp().e1;
|
||||
}
|
||||
|
||||
|
@ -1284,7 +1362,7 @@ bool inferApplyArgTypes(ForeachStatement fes, Scope* sc, ref Dsymbol sapply)
|
|||
}
|
||||
p = (*fes.parameters)[1];
|
||||
}
|
||||
if (!p.type && tab.ty != Ttuple)
|
||||
if (!p.type && !tab.isTypeTuple())
|
||||
{
|
||||
p.type = tab.nextOf(); // value type
|
||||
p.type = p.type.addStorageClass(p.storageClass);
|
||||
|
@ -1316,8 +1394,7 @@ bool inferApplyArgTypes(ForeachStatement fes, Scope* sc, ref Dsymbol sapply)
|
|||
case Tclass:
|
||||
case Tstruct:
|
||||
{
|
||||
AggregateDeclaration ad = (tab.ty == Tclass) ? tab.isTypeClass().sym
|
||||
: tab.isTypeStruct().sym;
|
||||
AggregateDeclaration ad = isAggregate(tab);
|
||||
if (fes.parameters.length == 1)
|
||||
{
|
||||
if (!p.type)
|
||||
|
|
|
@ -2274,7 +2274,6 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
*/
|
||||
private AST.Condition parseDebugCondition()
|
||||
{
|
||||
uint level = 1;
|
||||
Identifier id = null;
|
||||
Loc loc = token.loc;
|
||||
|
||||
|
@ -2290,7 +2289,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
nextToken();
|
||||
check(TOK.rightParenthesis);
|
||||
}
|
||||
return new AST.DebugCondition(loc, mod, level, id);
|
||||
return new AST.DebugCondition(loc, mod, id);
|
||||
}
|
||||
|
||||
/**************************************
|
||||
|
@ -2319,7 +2318,6 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
*/
|
||||
private AST.Condition parseVersionCondition()
|
||||
{
|
||||
uint level = 1;
|
||||
Identifier id = null;
|
||||
Loc loc;
|
||||
|
||||
|
@ -2345,7 +2343,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
}
|
||||
else
|
||||
error("(condition) expected following `version`");
|
||||
return new AST.VersionCondition(loc, mod, level, id);
|
||||
return new AST.VersionCondition(loc, mod, id);
|
||||
}
|
||||
|
||||
/***********************************************
|
||||
|
@ -5379,7 +5377,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
*/
|
||||
private void checkDanglingElse(Loc elseloc)
|
||||
{
|
||||
if (token.value != TOK.else_ && token.value != TOK.catch_ && token.value != TOK.finally_ && lookingForElse.linnum != 0)
|
||||
if (token.value != TOK.else_ && token.value != TOK.catch_ && token.value != TOK.finally_ && lookingForElse.isValid)
|
||||
{
|
||||
eSink.warning(elseloc, "else is dangling, add { } after condition at %s", lookingForElse.toChars());
|
||||
}
|
||||
|
@ -6255,12 +6253,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
if (token.value == TOK.assign)
|
||||
{
|
||||
if (auto ds = parseDebugSpecification())
|
||||
{
|
||||
if (ds.ident)
|
||||
eSink.error(ds.loc, "%s `%s` declaration must be at module level", ds.kind, ds.toPrettyChars);
|
||||
else
|
||||
eSink.error(ds.loc, "%s `%s` level declaration must be at module level", ds.kind, ds.toPrettyChars);
|
||||
}
|
||||
eSink.error(ds.loc, "%s `%s` declaration must be at module level", ds.kind, ds.toPrettyChars);
|
||||
|
||||
break;
|
||||
}
|
||||
cond = parseDebugCondition();
|
||||
|
@ -6271,12 +6265,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
if (token.value == TOK.assign)
|
||||
{
|
||||
if (auto vs = parseVersionSpecification())
|
||||
{
|
||||
if (vs.ident)
|
||||
eSink.error(vs.loc, "%s `%s` declaration must be at module level", vs.kind, vs.toPrettyChars);
|
||||
else
|
||||
eSink.error(vs.loc, "%s `%s` level declaration must be at module level", vs.kind, vs.toPrettyChars);
|
||||
}
|
||||
eSink.error(vs.loc, "%s `%s` declaration must be at module level", vs.kind, vs.toPrettyChars);
|
||||
|
||||
break;
|
||||
}
|
||||
cond = parseVersionCondition();
|
||||
|
|
|
@ -2089,7 +2089,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
|
|||
|
||||
// Make a copy of all the cases so that qsort doesn't scramble the actual
|
||||
// data we pass to codegen (the order of the cases in the switch).
|
||||
CaseStatements *csCopy = (*ss.cases).copy();
|
||||
CaseStatements* csCopy = (*ss.cases).copy();
|
||||
|
||||
if (numcases)
|
||||
{
|
||||
|
|
|
@ -79,7 +79,6 @@ public:
|
|||
bool overloadInsert(Dsymbol *s) override;
|
||||
bool hasStaticCtorOrDtor() override;
|
||||
const char *kind() const override;
|
||||
const char *toChars() const override;
|
||||
|
||||
Visibility visible() override;
|
||||
|
||||
|
@ -272,7 +271,6 @@ public:
|
|||
Dsymbol *toAlias() override final; // resolve real symbol
|
||||
const char *kind() const override;
|
||||
bool oneMember(Dsymbol *&ps, Identifier *ident) override;
|
||||
const char *toChars() const override;
|
||||
const char* toPrettyCharsHelper() override final;
|
||||
Identifier *getIdent() override final;
|
||||
|
||||
|
@ -292,7 +290,6 @@ public:
|
|||
const char *kind() const override;
|
||||
bool oneMember(Dsymbol *&ps, Identifier *ident) override;
|
||||
bool hasPointers() override;
|
||||
const char *toChars() const override;
|
||||
|
||||
TemplateMixin *isTemplateMixin() override { return this; }
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
|
|
|
@ -1425,7 +1425,7 @@ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, Templat
|
|||
Expression e;
|
||||
Type t;
|
||||
Dsymbol s;
|
||||
Scope *sco;
|
||||
Scope* sco;
|
||||
|
||||
const errors = global.startGagging();
|
||||
/* ref: https://issues.dlang.org/show_bug.cgi?id=11118
|
||||
|
|
|
@ -3128,7 +3128,7 @@ Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
|
|||
else
|
||||
{
|
||||
/* struct S { int a; };
|
||||
* struct S *s;
|
||||
* struct S* s;
|
||||
*/
|
||||
}
|
||||
mtype.resolved = sd.type;
|
||||
|
@ -3159,14 +3159,14 @@ Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
|
|||
mtype.tok == TOK.struct_ && s.isStructDeclaration())
|
||||
{
|
||||
/* struct S;
|
||||
* { struct S *s; }
|
||||
* { struct S* s; }
|
||||
*/
|
||||
mtype.resolved = s.isStructDeclaration().type;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* union S;
|
||||
* { struct S *s; }
|
||||
* { struct S* s; }
|
||||
*/
|
||||
.error(mtype.loc, "redeclaring `%s %s` as `%s %s`",
|
||||
s.kind(), s.toChars(), Token.toChars(mtype.tok), mtype.id.toChars());
|
||||
|
@ -7609,6 +7609,18 @@ bool checkRetType(TypeFunction tf, const ref Loc loc)
|
|||
return false;
|
||||
}
|
||||
|
||||
/// Returns: whether `t` is a struct/class/enum without a body
|
||||
bool isOpaqueType(Type t)
|
||||
{
|
||||
if (auto te = t.isTypeEnum())
|
||||
return te.sym.members is null;
|
||||
if (auto ts = t.isTypeStruct())
|
||||
return ts.sym.members is null;
|
||||
if (auto tc = t.isTypeClass())
|
||||
return tc.sym.members is null;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/******************************* Private *****************************************/
|
||||
|
||||
|
|
|
@ -15,11 +15,8 @@
|
|||
class DebugSymbol final : public Dsymbol
|
||||
{
|
||||
public:
|
||||
unsigned level;
|
||||
|
||||
DebugSymbol *syntaxCopy(Dsymbol *) override;
|
||||
|
||||
const char *toChars() const override;
|
||||
const char *kind() const override;
|
||||
DebugSymbol *isDebugSymbol() override;
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
|
@ -28,11 +25,8 @@ public:
|
|||
class VersionSymbol final : public Dsymbol
|
||||
{
|
||||
public:
|
||||
unsigned level;
|
||||
|
||||
VersionSymbol *syntaxCopy(Dsymbol *) override;
|
||||
|
||||
const char *toChars() const override;
|
||||
const char *kind() const override;
|
||||
VersionSymbol *isVersionSymbol() override;
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
|
|
|
@ -1622,7 +1622,7 @@ public:
|
|||
if (dve->e1->op == EXP::structLiteral)
|
||||
{
|
||||
StructLiteralExp *sle = dve->e1->isStructLiteralExp ();
|
||||
sle->useStaticInit = false;
|
||||
sle->useStaticInit (false);
|
||||
}
|
||||
|
||||
FuncDeclaration *fd = dve->var->isFuncDeclaration ();
|
||||
|
@ -2773,7 +2773,7 @@ public:
|
|||
|
||||
/* Building sinit trees are delayed until after frontend semantic
|
||||
processing has complete. Build the static initializer now. */
|
||||
if (e->useStaticInit && !this->constp_ && !e->sd->isCsymbol ())
|
||||
if (e->useStaticInit () && !this->constp_ && !e->sd->isCsymbol ())
|
||||
{
|
||||
tree init = aggregate_initializer_decl (e->sd);
|
||||
|
||||
|
@ -2841,7 +2841,7 @@ public:
|
|||
tree field = get_symbol_decl (e->sd->vthis);
|
||||
tree value = build_vthis (e->sd);
|
||||
CONSTRUCTOR_APPEND_ELT (ve, field, value);
|
||||
gcc_assert (e->useStaticInit == false);
|
||||
gcc_assert (e->useStaticInit () == false);
|
||||
}
|
||||
|
||||
/* Build a constructor in the correct shape of the aggregate type. */
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/b17285.d(14): Error: type `ONE` has no value
|
||||
fail_compilation/b17285.d(14): Error: type `TWO` has no value
|
||||
fail_compilation/b17285.d(14): Error: cannot implicitly convert expression `ONE` of type `b17285.ONE` to `int`
|
||||
fail_compilation/b17285.d(15): Error: type `ONE` has no value
|
||||
fail_compilation/b17285.d(15): perhaps use `ONE.init`
|
||||
fail_compilation/b17285.d(15): Error: type `TWO` has no value
|
||||
fail_compilation/b17285.d(15): Error: cannot implicitly convert expression `ONE` of type `b17285.ONE` to `int`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -19,11 +19,11 @@ void main()
|
|||
{
|
||||
T2!().F x = T1!().F();
|
||||
}
|
||||
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/bug9631.d(41): Error: incompatible types for `(x) == (y)`: `bug9631.S` and `bug9631.tem!().S`
|
||||
fail_compilation/bug9631.d(41): Error: no operator `==` for type `S`
|
||||
fail_compilation/bug9631.d(30): perhaps overload it with `bool opEquals(S other) const {}`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,89 +2,172 @@
|
|||
REQUIRED_ARGS:
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/dep_d1_ops.d(198): Error: incompatible types for `(s) + (1)`: `S` and `int`
|
||||
fail_compilation/dep_d1_ops.d(199): Error: incompatible types for `(1) + (s)`: `int` and `S`
|
||||
fail_compilation/dep_d1_ops.d(200): Error: incompatible types for `(s) - (1)`: `S` and `int`
|
||||
fail_compilation/dep_d1_ops.d(201): Error: incompatible types for `(1) - (s)`: `int` and `S`
|
||||
fail_compilation/dep_d1_ops.d(202): Error: incompatible types for `(s) * (1)`: `S` and `int`
|
||||
fail_compilation/dep_d1_ops.d(203): Error: incompatible types for `(1) * (s)`: `int` and `S`
|
||||
fail_compilation/dep_d1_ops.d(204): Error: incompatible types for `(s) / (1)`: `S` and `int`
|
||||
fail_compilation/dep_d1_ops.d(205): Error: incompatible types for `(1) / (s)`: `int` and `S`
|
||||
fail_compilation/dep_d1_ops.d(206): Error: incompatible types for `(s) % (1)`: `S` and `int`
|
||||
fail_compilation/dep_d1_ops.d(207): Error: incompatible types for `(1) % (s)`: `int` and `S`
|
||||
fail_compilation/dep_d1_ops.d(209): Error: incompatible types for `(s) & (1)`: `S` and `int`
|
||||
fail_compilation/dep_d1_ops.d(210): Error: incompatible types for `(s) | (1)`: `S` and `int`
|
||||
fail_compilation/dep_d1_ops.d(211): Error: incompatible types for `(s) ^ (1)`: `S` and `int`
|
||||
fail_compilation/dep_d1_ops.d(213): Error: `s` is not of integral type, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(214): Error: `s` is not of integral type, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(215): Error: `s` is not of integral type, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(216): Error: `s` is not of integral type, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(217): Error: `s` is not of integral type, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(218): Error: `s` is not of integral type, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(220): Error: incompatible types for `(s) ~ (1)`: `S` and `int`
|
||||
fail_compilation/dep_d1_ops.d(221): Error: incompatible types for `(1) ~ (s)`: `int` and `S`
|
||||
fail_compilation/dep_d1_ops.d(223): Error: operator `+` is not defined for `s` of type `S`
|
||||
fail_compilation/dep_d1_ops.d(224): Error: operator `-` is not defined for `s` of type `S`
|
||||
fail_compilation/dep_d1_ops.d(225): Error: `s` is not of integral type, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(226): Error: `s` is not a scalar, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(227): Error: `s` is not a scalar, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(228): Error: can only `*` a pointer, not a `S`
|
||||
fail_compilation/dep_d1_ops.d(230): Error: incompatible types for `(s) in (1)`: `S` and `int`
|
||||
fail_compilation/dep_d1_ops.d(231): Error: incompatible types for `(1) in (s)`: `int` and `S`
|
||||
fail_compilation/dep_d1_ops.d(233): Error: `s` is not a scalar, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(234): Error: `s` is not a scalar, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(235): Error: `s` is not a scalar, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(236): Error: `s` is not a scalar, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(237): Error: `s` is not a scalar, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(238): Error: `s` is not a scalar, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(239): Error: `s` is not a scalar, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(240): Error: `s` is not a scalar, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(241): Error: `s` is not a scalar, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(242): Error: `s` is not a scalar, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(243): Error: `s` is not a scalar, it is a `S`
|
||||
fail_compilation/dep_d1_ops.d(244): Error: cannot append type `int` to type `S`
|
||||
fail_compilation/dep_d1_ops.d(248): Error: incompatible types for `(c) + (1)`: `dep_d1_ops.C` and `int`
|
||||
fail_compilation/dep_d1_ops.d(249): Error: incompatible types for `(1) + (c)`: `int` and `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(250): Error: incompatible types for `(c) - (1)`: `dep_d1_ops.C` and `int`
|
||||
fail_compilation/dep_d1_ops.d(251): Error: incompatible types for `(1) - (c)`: `int` and `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(252): Error: incompatible types for `(c) * (1)`: `dep_d1_ops.C` and `int`
|
||||
fail_compilation/dep_d1_ops.d(253): Error: incompatible types for `(1) * (c)`: `int` and `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(254): Error: incompatible types for `(c) / (1)`: `dep_d1_ops.C` and `int`
|
||||
fail_compilation/dep_d1_ops.d(255): Error: incompatible types for `(1) / (c)`: `int` and `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(256): Error: incompatible types for `(c) % (1)`: `dep_d1_ops.C` and `int`
|
||||
fail_compilation/dep_d1_ops.d(257): Error: incompatible types for `(1) % (c)`: `int` and `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(259): Error: incompatible types for `(c) & (1)`: `dep_d1_ops.C` and `int`
|
||||
fail_compilation/dep_d1_ops.d(260): Error: incompatible types for `(c) | (1)`: `dep_d1_ops.C` and `int`
|
||||
fail_compilation/dep_d1_ops.d(261): Error: incompatible types for `(c) ^ (1)`: `dep_d1_ops.C` and `int`
|
||||
fail_compilation/dep_d1_ops.d(263): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(264): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(265): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(266): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(267): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(268): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(270): Error: incompatible types for `(c) ~ (1)`: `dep_d1_ops.C` and `int`
|
||||
fail_compilation/dep_d1_ops.d(271): Error: incompatible types for `(1) ~ (c)`: `int` and `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(273): Error: operator `+` is not defined for `c` of type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(274): Error: operator `-` is not defined for `c` of type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(275): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(276): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(277): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(278): Error: can only `*` a pointer, not a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(280): Error: incompatible types for `(c) in (1)`: `dep_d1_ops.C` and `int`
|
||||
fail_compilation/dep_d1_ops.d(281): Error: incompatible types for `(1) in (c)`: `int` and `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(283): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(284): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(285): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(286): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(287): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(288): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(289): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(290): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(291): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(292): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(293): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(294): Error: cannot append type `int` to type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(303): Error: `nd` is not of integral type, it is a `dep_d1_ops.NoDeprecation`
|
||||
fail_compilation/dep_d1_ops.d(281): Error: operator `+` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "+")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(282): Error: operator `+` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : "+")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(283): Error: operator `-` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "-")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(284): Error: operator `-` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : "-")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(285): Error: operator `*` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "*")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(286): Error: operator `*` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : "*")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(287): Error: operator `/` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "/")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(288): Error: operator `/` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : "/")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(289): Error: operator `%` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "%")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(290): Error: operator `%` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : "%")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(292): Error: operator `&` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "&")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(293): Error: operator `|` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "|")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(294): Error: operator `^` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "^")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(296): Error: operator `<<` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "<<")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(297): Error: operator `<<` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : "<<")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(298): Error: operator `>>` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : ">>")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(299): Error: operator `>>` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : ">>")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(300): Error: operator `>>>` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : ">>>")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(301): Error: operator `>>>` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : ">>>")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(303): Error: operator `~` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "~")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(304): Error: operator `~` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : "~")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(306): Error: operator `+` is not defined for `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opUnary(string op : "+")() {}`
|
||||
fail_compilation/dep_d1_ops.d(307): Error: operator `-` is not defined for `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opUnary(string op : "-")() {}`
|
||||
fail_compilation/dep_d1_ops.d(308): Error: operator `~` is not defined for `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opUnary(string op : "~")() {}`
|
||||
fail_compilation/dep_d1_ops.d(309): Error: operator `++` not supported for `s` of type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opUnary(string op : "++")() {}` or `auto opOpAssign(string op : "+")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(310): Error: operator `--` not supported for `s` of type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opUnary(string op : "--")() {}` or `auto opOpAssign(string op : "-")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(311): Error: operator `*` is not defined for `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opUnary(string op : "*")() {}`
|
||||
fail_compilation/dep_d1_ops.d(313): Error: operator `in` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : "in")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(314): Error: operator `in` is not defined for type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : "in")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(316): Error: operator `+=` not supported for `s` of type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "+")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(317): Error: operator `-=` not supported for `s` of type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "-")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(318): Error: operator `*=` not supported for `s` of type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "*")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(319): Error: operator `/=` not supported for `s` of type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "/")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(320): Error: operator `%=` not supported for `s` of type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "%")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(321): Error: operator `&=` not supported for `s` of type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "&")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(322): Error: operator `|=` not supported for `s` of type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "|")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(323): Error: operator `^=` not supported for `s` of type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "^")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(324): Error: operator `<<=` not supported for `s` of type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "<<")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(325): Error: operator `>>=` not supported for `s` of type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : ">>")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(326): Error: operator `>>>=` not supported for `s` of type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : ">>>")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(327): Error: operator `~=` not supported for `s` of type `S`
|
||||
fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : "~")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(331): Error: operator `+` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "+")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(332): Error: operator `+` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : "+")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(333): Error: operator `-` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "-")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(334): Error: operator `-` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : "-")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(335): Error: operator `*` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "*")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(336): Error: operator `*` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : "*")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(337): Error: operator `/` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "/")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(338): Error: operator `/` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : "/")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(339): Error: operator `%` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "%")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(340): Error: operator `%` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : "%")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(342): Error: operator `&` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "&")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(343): Error: operator `|` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "|")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(344): Error: operator `^` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "^")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(346): Error: operator `<<` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "<<")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(347): Error: operator `<<` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : "<<")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(348): Error: operator `>>` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : ">>")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(349): Error: operator `>>` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : ">>")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(350): Error: operator `>>>` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : ">>>")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(351): Error: operator `>>>` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : ">>>")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(353): Error: operator `~` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "~")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(354): Error: operator `~` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : "~")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(356): Error: operator `+` is not defined for `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opUnary(string op : "+")() {}`
|
||||
fail_compilation/dep_d1_ops.d(357): Error: operator `-` is not defined for `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opUnary(string op : "-")() {}`
|
||||
fail_compilation/dep_d1_ops.d(358): Error: operator `~` is not defined for `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opUnary(string op : "~")() {}`
|
||||
fail_compilation/dep_d1_ops.d(359): Error: operator `++` not supported for `c` of type `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opUnary(string op : "++")() {}` or `auto opOpAssign(string op : "+")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(360): Error: operator `--` not supported for `c` of type `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opUnary(string op : "--")() {}` or `auto opOpAssign(string op : "-")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(361): Error: operator `*` is not defined for `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opUnary(string op : "*")() {}`
|
||||
fail_compilation/dep_d1_ops.d(363): Error: operator `in` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : "in")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(364): Error: operator `in` is not defined for type `dep_d1_ops.C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : "in")(int rhs) {}`
|
||||
fail_compilation/dep_d1_ops.d(366): Error: operator `+=` not supported for `c` of type `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "+")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(367): Error: operator `-=` not supported for `c` of type `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "-")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(368): Error: operator `*=` not supported for `c` of type `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "*")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(369): Error: operator `/=` not supported for `c` of type `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "/")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(370): Error: operator `%=` not supported for `c` of type `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "%")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(371): Error: operator `&=` not supported for `c` of type `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "&")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(372): Error: operator `|=` not supported for `c` of type `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "|")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(373): Error: operator `^=` not supported for `c` of type `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "^")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(374): Error: operator `<<=` not supported for `c` of type `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "<<")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(375): Error: operator `>>=` not supported for `c` of type `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : ">>")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(376): Error: operator `>>>=` not supported for `c` of type `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : ">>>")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(377): Error: operator `~=` not supported for `c` of type `C`
|
||||
fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : "~")(int) {}`
|
||||
fail_compilation/dep_d1_ops.d(386): Error: operator `~` is not defined for `NoDeprecation`
|
||||
fail_compilation/dep_d1_ops.d(390): perhaps overload the operator with `auto opUnary(string op : "~")() {}`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/diag12063.d(19): Error: cannot check `diag12063.Bar.b` value for overflow
|
||||
fail_compilation/diag12063.d(16): Error: no property `max` for type `Foo`, perhaps `import std.algorithm;` is needed?
|
||||
fail_compilation/diag12063.d(19): Error: cannot generate value for `diag12063.Bar.b`
|
||||
fail_compilation/diag12063.d(19): Error: incompatible types for `(Foo()) + (1)`: `Bar` and `int`
|
||||
fail_compilation/diag12063.d(29): Error: cannot check `diag12063.b` value for overflow
|
||||
fail_compilation/diag12063.d(29): Error: incompatible types for `(S()) == (1)`: `S` and `int`
|
||||
fail_compilation/diag12063.d(38): Error: enum member `diag12063.d` initialization with `__anonymous.c+1` causes overflow for type `Q`
|
||||
fail_compilation/diag12063.d(21): Error: cannot check `diag12063.Bar.b` value for overflow
|
||||
fail_compilation/diag12063.d(18): Error: no property `max` for type `Foo`, perhaps `import std.algorithm;` is needed?
|
||||
fail_compilation/diag12063.d(21): Error: cannot generate value for `diag12063.Bar.b`
|
||||
fail_compilation/diag12063.d(21): Error: operator `+` is not defined for type `Bar`
|
||||
fail_compilation/diag12063.d(16): perhaps overload the operator with `auto opBinary(string op : "+")(int rhs) {}`
|
||||
fail_compilation/diag12063.d(31): Error: cannot check `diag12063.b` value for overflow
|
||||
fail_compilation/diag12063.d(31): Error: no operator `==` for type `S`
|
||||
fail_compilation/diag12063.d(24): perhaps overload it with `bool opEquals(int other) const {}`
|
||||
fail_compilation/diag12063.d(40): Error: enum member `diag12063.d` initialization with `__anonymous.c+1` causes overflow for type `Q`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/diag13320.d(13): Error: `f` is not a scalar, it is a `Foo`
|
||||
fail_compilation/diag13320.d(14): Error: operator `++` not supported for `f` of type `Foo`
|
||||
fail_compilation/diag13320.d(9): perhaps implement `auto opUnary(string op : "++")() {}` or `auto opOpAssign(string op : "+")(int) {}`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/diag16499.d(22): Error: incompatible types for `(2) in (foo)`: `int` and `A`
|
||||
fail_compilation/diag16499.d(24): Error: incompatible types for `(1.0) in (bar)`: `double` and `B`
|
||||
fail_compilation/diag16499.d(24): Error: operator `in` is not defined for type `A`
|
||||
fail_compilation/diag16499.d(11): perhaps overload the operator with `auto opBinaryRight(string op : "in")(int rhs) {}`
|
||||
fail_compilation/diag16499.d(26): Error: operator `in` is not defined for type `B`
|
||||
fail_compilation/diag16499.d(12): perhaps overload the operator with `auto opBinaryRight(string op : "in")(double rhs) {}`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail10964.d(28): Error: function `fail10964.S.__postblit` is not `nothrow`
|
||||
fail_compilation/fail10964.d(29): Error: function `fail10964.S.__postblit` is not `nothrow`
|
||||
fail_compilation/fail10964.d(30): Error: function `fail10964.S.__postblit` is not `nothrow`
|
||||
fail_compilation/fail10964.d(33): Error: function `fail10964.S.__postblit` is not `nothrow`
|
||||
fail_compilation/fail10964.d(34): Error: function `fail10964.S.__postblit` is not `nothrow`
|
||||
fail_compilation/fail10964.d(35): Error: function `fail10964.S.__postblit` is not `nothrow`
|
||||
fail_compilation/fail10964.d(28): Error: function `fail10964.S.this(this)` is not `nothrow`
|
||||
fail_compilation/fail10964.d(29): Error: function `fail10964.S.this(this)` is not `nothrow`
|
||||
fail_compilation/fail10964.d(30): Error: function `fail10964.S.this(this)` is not `nothrow`
|
||||
fail_compilation/fail10964.d(33): Error: function `fail10964.S.this(this)` is not `nothrow`
|
||||
fail_compilation/fail10964.d(34): Error: function `fail10964.S.this(this)` is not `nothrow`
|
||||
fail_compilation/fail10964.d(35): Error: function `fail10964.S.this(this)` is not `nothrow`
|
||||
fail_compilation/fail10964.d(22): Error: function `fail10964.foo` may throw but is marked as `nothrow`
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -1,36 +1,24 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail10968.d(43): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
|
||||
fail_compilation/fail10968.d(43): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
|
||||
fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
|
||||
fail_compilation/fail10968.d(44): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
|
||||
fail_compilation/fail10968.d(44): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
|
||||
fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
|
||||
fail_compilation/fail10968.d(44): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.arrayassign._d_arraysetassign!(SA[], SA)._d_arraysetassign`
|
||||
$p:druntime/import/core/internal/array/arrayassign.d$($n$): which calls `core.lifetime.copyEmplace!(SA, SA).copyEmplace`
|
||||
$p:druntime/import/core/lifetime.d$($n$): which calls `fail10968.SA.__postblit`
|
||||
fail_compilation/fail10968.d(45): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
|
||||
fail_compilation/fail10968.d(45): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
|
||||
fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
|
||||
fail_compilation/fail10968.d(45): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.arrayassign._d_arrayassign_l!(SA[], SA)._d_arrayassign_l`
|
||||
$p:druntime/import/core/internal/array/arrayassign.d$-mixin-$n$($n$): which calls `core.lifetime.copyEmplace!(SA, SA).copyEmplace`
|
||||
$p:druntime/import/core/lifetime.d$($n$): which calls `fail10968.SA.__postblit`
|
||||
fail_compilation/fail10968.d(48): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
|
||||
fail_compilation/fail10968.d(48): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
|
||||
fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
|
||||
fail_compilation/fail10968.d(49): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
|
||||
fail_compilation/fail10968.d(49): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
|
||||
fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
|
||||
fail_compilation/fail10968.d(49): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.construction._d_arraysetctor!(SA[], SA)._d_arraysetctor`
|
||||
$p:druntime/import/core/internal/array/construction.d$($n$): which calls `core.lifetime.copyEmplace!(SA, SA).copyEmplace`
|
||||
$p:druntime/import/core/lifetime.d$($n$): which calls `fail10968.SA.__postblit`
|
||||
fail_compilation/fail10968.d(50): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
|
||||
fail_compilation/fail10968.d(50): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
|
||||
fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
|
||||
fail_compilation/fail10968.d(50): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.construction._d_arrayctor!(SA[], SA)._d_arrayctor`
|
||||
$p:druntime/import/core/internal/array/construction.d$($n$): which calls `core.lifetime.copyEmplace!(SA, SA).copyEmplace`
|
||||
$p:druntime/import/core/lifetime.d$($n$): which calls `fail10968.SA.__postblit`
|
||||
fail_compilation/fail10968.d(43): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.this(this)`
|
||||
fail_compilation/fail10968.d(43): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.this(this)`
|
||||
fail_compilation/fail10968.d(31): `fail10968.SA.this(this)` is declared here
|
||||
fail_compilation/fail10968.d(44): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.this(this)`
|
||||
fail_compilation/fail10968.d(44): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.this(this)`
|
||||
fail_compilation/fail10968.d(31): `fail10968.SA.this(this)` is declared here
|
||||
fail_compilation/fail10968.d(45): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.this(this)`
|
||||
fail_compilation/fail10968.d(45): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.this(this)`
|
||||
fail_compilation/fail10968.d(31): `fail10968.SA.this(this)` is declared here
|
||||
fail_compilation/fail10968.d(48): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.this(this)`
|
||||
fail_compilation/fail10968.d(48): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.this(this)`
|
||||
fail_compilation/fail10968.d(31): `fail10968.SA.this(this)` is declared here
|
||||
fail_compilation/fail10968.d(49): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.this(this)`
|
||||
fail_compilation/fail10968.d(49): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.this(this)`
|
||||
fail_compilation/fail10968.d(31): `fail10968.SA.this(this)` is declared here
|
||||
fail_compilation/fail10968.d(50): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.this(this)`
|
||||
fail_compilation/fail10968.d(50): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.this(this)`
|
||||
fail_compilation/fail10968.d(31): `fail10968.SA.this(this)` is declared here
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail18143.d(20): Error: variable `fail18143.S.a` cannot modify parameter `this` in contract
|
||||
fail_compilation/fail18143.d(21): Error: variable `fail18143.S.a` cannot modify parameter `this` in contract
|
||||
fail_compilation/fail18143.d(25): Error: variable `fail18143.S.a` cannot modify parameter `this` in contract
|
||||
fail_compilation/fail18143.d(26): Error: variable `fail18143.S.a` cannot modify parameter `this` in contract
|
||||
fail_compilation/fail18143.d(35): Error: variable `fail18143.C.a` cannot modify parameter `this` in contract
|
||||
fail_compilation/fail18143.d(36): Error: variable `fail18143.C.a` cannot modify parameter `this` in contract
|
||||
fail_compilation/fail18143.d(40): Error: variable `fail18143.C.a` cannot modify parameter `this` in contract
|
||||
fail_compilation/fail18143.d(41): Error: variable `fail18143.C.a` cannot modify parameter `this` in contract
|
||||
fail_compilation/fail18143.d(20): Error: cannot modify member variable `fail18143.S.a` in contract
|
||||
fail_compilation/fail18143.d(21): Error: cannot modify member variable `fail18143.S.a` in contract
|
||||
fail_compilation/fail18143.d(25): Error: cannot modify member variable `fail18143.S.a` in contract
|
||||
fail_compilation/fail18143.d(26): Error: cannot modify member variable `fail18143.S.a` in contract
|
||||
fail_compilation/fail18143.d(35): Error: cannot modify member variable `fail18143.C.a` in contract
|
||||
fail_compilation/fail18143.d(36): Error: cannot modify member variable `fail18143.C.a` in contract
|
||||
fail_compilation/fail18143.d(40): Error: cannot modify member variable `fail18143.C.a` in contract
|
||||
fail_compilation/fail18143.d(41): Error: cannot modify member variable `fail18143.C.a` in contract
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail18985.d(16): Error: `foo` is not a scalar, it is a `object.Object`
|
||||
fail_compilation/fail18985.d(17): Error: `bar` is not a scalar, it is a `shared(Object)`
|
||||
fail_compilation/fail18985.d(20): Error: operator `+=` not supported for `foo` of type `C`
|
||||
fail_compilation/fail18985.d(13): perhaps implement `auto opOpAssign(string op : "+")(int) {}`
|
||||
fail_compilation/fail18985.d(21): Error: operator `+=` not supported for `bar` of type `C`
|
||||
fail_compilation/fail18985.d(13): perhaps implement `auto opOpAssign(string op : "+")(int) {}`
|
||||
---
|
||||
*/
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=18985
|
||||
|
||||
Object foo;
|
||||
shared Object bar;
|
||||
class C {}
|
||||
|
||||
C foo;
|
||||
shared C bar;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail20.d(16): Error: need member function `opCmp()` for struct `FOO` to compare
|
||||
fail_compilation/fail20.d(17): Error: no operator `<` for type `FOO`
|
||||
fail_compilation/fail20.d(11): perhaps overload it with `int opCmp(FOO other) const {}`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail20616.d(16): Error: undefined identifier `$`
|
||||
fail_compilation/fail20616.d(16): Aggregate declaration 'X()' does not define 'opDollar'
|
||||
fail_compilation/fail20616.d(13): perhaps define `opDollar` for `X`
|
||||
fail_compilation/fail20616.d(18): Error: undefined identifier `$`
|
||||
fail_compilation/fail20616.d(18): Aggregate declaration 'b' does not define 'opDollar'
|
||||
fail_compilation/fail20616.d(13): perhaps define `opDollar` for `X`
|
||||
---
|
||||
*/
|
||||
module fail20616;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail297.d(30): Error: operator `+` is not defined for `Bar()` of type `Bar`
|
||||
fail_compilation/fail297.d(31): Error: operator `+` is not defined for type `Bar`
|
||||
fail_compilation/fail297.d(25): perhaps overload the operator with `auto opBinary(string op : "+")(const(Bar) rhs) {}`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail3.d(41): Error: operator `+` is not defined for `a` of type `vec2`
|
||||
fail_compilation/fail3.d(42): Error: operator `+` is not defined for type `vec2`
|
||||
fail_compilation/fail3.d(13): perhaps overload the operator with `auto opBinary(string op : "+")(vec2 rhs) {}`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail3672.d(28): Error: read-modify-write operations are not allowed for `shared` variables
|
||||
fail_compilation/fail3672.d(28): Use `core.atomic.atomicOp!"+="(*p, 1)` instead
|
||||
fail_compilation/fail3672.d(32): Error: none of the `opOpAssign` overloads of `SF` are callable for `*sfp` of type `shared(SF)`
|
||||
fail_compilation/fail3672.d(29): Error: read-modify-write operations are not allowed for `shared` variables
|
||||
fail_compilation/fail3672.d(29): Use `core.atomic.atomicOp!"+="(*p, 1)` instead
|
||||
fail_compilation/fail3672.d(33): Error: template `opOpAssign` is not callable using argument types `!("+")(int) shared`
|
||||
fail_compilation/fail3672.d(13): Candidate is: `opOpAssign(string op, T)(T rhs)`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail4421.d(16): Error: function `fail4421.U1.__postblit` destructors, postblits and invariants are not allowed in union `U1`
|
||||
fail_compilation/fail4421.d(16): Error: function `fail4421.U1.this(this)` destructors, postblits and invariants are not allowed in union `U1`
|
||||
fail_compilation/fail4421.d(17): Error: destructor `fail4421.U1.~this` destructors, postblits and invariants are not allowed in union `U1`
|
||||
fail_compilation/fail4421.d(18): Error: function `fail4421.U1.__invariant1` destructors, postblits and invariants are not allowed in union `U1`
|
||||
fail_compilation/fail4421.d(18): Error: function `fail4421.U1.invariant` destructors, postblits and invariants are not allowed in union `U1`
|
||||
---
|
||||
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail6107.d(10): Error: variable `fail6107.Foo.__ctor` is not a constructor; identifiers starting with `__` are reserved for the implementation
|
||||
fail_compilation/fail6107.d(14): Error: variable `fail6107.Bar.__ctor` is not a constructor; identifiers starting with `__` are reserved for the implementation
|
||||
fail_compilation/fail6107.d(12): Error: variable name `__ctor` is not allowed
|
||||
fail_compilation/fail6107.d(12): identifiers starting with `__` are reserved for internal use
|
||||
fail_compilation/fail6107.d(16): Error: variable name `__ctor` is not allowed
|
||||
fail_compilation/fail6107.d(16): identifiers starting with `__` are reserved for internal use
|
||||
---
|
||||
*/
|
||||
struct Foo
|
||||
|
|
|
@ -9,12 +9,12 @@ fail_compilation/fail7848.d(21): `fail7848.func` is declared here
|
|||
fail_compilation/fail7848.d(27): Error: `@nogc` function `fail7848.C.__unittest_L25_C30` cannot call non-@nogc function `fail7848.func`
|
||||
fail_compilation/fail7848.d(27): Error: function `fail7848.func` is not `nothrow`
|
||||
fail_compilation/fail7848.d(25): Error: function `fail7848.C.__unittest_L25_C30` may throw but is marked as `nothrow`
|
||||
fail_compilation/fail7848.d(32): Error: `pure` function `fail7848.C.__invariant0` cannot call impure function `fail7848.func`
|
||||
fail_compilation/fail7848.d(32): Error: `@safe` function `fail7848.C.__invariant0` cannot call `@system` function `fail7848.func`
|
||||
fail_compilation/fail7848.d(32): Error: `pure` function `fail7848.C.invariant` cannot call impure function `fail7848.func`
|
||||
fail_compilation/fail7848.d(32): Error: `@safe` function `fail7848.C.invariant` cannot call `@system` function `fail7848.func`
|
||||
fail_compilation/fail7848.d(21): `fail7848.func` is declared here
|
||||
fail_compilation/fail7848.d(32): Error: `@nogc` function `fail7848.C.__invariant0` cannot call non-@nogc function `fail7848.func`
|
||||
fail_compilation/fail7848.d(32): Error: `@nogc` function `fail7848.C.invariant` cannot call non-@nogc function `fail7848.func`
|
||||
fail_compilation/fail7848.d(32): Error: function `fail7848.func` is not `nothrow`
|
||||
fail_compilation/fail7848.d(30): Error: function `fail7848.C.__invariant0` may throw but is marked as `nothrow`
|
||||
fail_compilation/fail7848.d(30): Error: function `fail7848.C.invariant` may throw but is marked as `nothrow`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ fail_compilation/fail_arrayexp.d(25): Error: cannot use `[]` operator on express
|
|||
fail_compilation/fail_arrayexp.d(26): Error: static array of `const(int)[]` with multiple lengths not allowed
|
||||
fail_compilation/fail_arrayexp.d(27): Error: only one index allowed to index `string`
|
||||
fail_compilation/fail_arrayexp.d(28): Error: no `[]` operator overload for type `U`
|
||||
fail_compilation/fail_arrayexp.d(16): `fail_arrayexp.U` declared here
|
||||
fail_compilation/fail_arrayexp.d(16): perhaps define `auto opIndex() {}` for `fail_arrayexp.U`
|
||||
fail_compilation/fail_arrayexp.d(29): Error: only one index allowed to index `(int, string)`
|
||||
---
|
||||
*/
|
||||
|
@ -29,3 +29,24 @@ void test19534() // https://issues.dlang.org/show_bug.cgi?id=19534
|
|||
auto t = agg[];
|
||||
auto u = getTuple!(int, string)[1, 2];
|
||||
}
|
||||
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail_arrayexp.d(49): Error: no `[3.."4"]` operator overload for type `S`
|
||||
fail_compilation/fail_arrayexp.d(42): perhaps define `auto opSlice(int lower, string upper) {}` for `fail_arrayexp.S`
|
||||
fail_compilation/fail_arrayexp.d(50): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_arrayexp.d(42): perhaps define `auto opIndex(int, string, char) {}` for `fail_arrayexp.S`
|
||||
---
|
||||
*/
|
||||
|
||||
struct S
|
||||
{
|
||||
}
|
||||
|
||||
void testSlice()
|
||||
{
|
||||
S s;
|
||||
const b = s[3 .. "4"];
|
||||
const c = s[3, "4", 'c'];
|
||||
}
|
||||
|
|
|
@ -4,33 +4,33 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail_opover.d(39): Error: no `[]` operator overload for type `object.Object`
|
||||
$p:object.d$(110): `object.Object` declared here
|
||||
$p:object.d$(110): perhaps define `auto opIndex() {}` for `object.Object`
|
||||
fail_compilation/fail_opover.d(43): Error: no `[]` operator overload for type `TestS`
|
||||
fail_compilation/fail_opover.d(41): `fail_opover.test1.TestS` declared here
|
||||
fail_compilation/fail_opover.d(41): perhaps define `auto opIndex() {}` for `fail_opover.test1.TestS`
|
||||
fail_compilation/fail_opover.d(55): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opIndex() {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(56): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(57): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opIndex(int) {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(57): Error: no `[1..2]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opSlice(int lower, int upper) {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(58): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opIndex() {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(59): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(60): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opIndex(int) {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(60): Error: no `[1..2]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opSlice(int lower, int upper) {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(61): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opIndex() {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(62): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(63): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opIndex(int) {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(63): Error: no `[1..2]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opSlice(int lower, int upper) {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(64): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opIndex() {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(65): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(66): Error: no `[]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): `fail_opover.test2.S` declared here
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opIndex(int) {}` for `fail_opover.test2.S`
|
||||
fail_compilation/fail_opover.d(66): Error: no `[1..2]` operator overload for type `S`
|
||||
fail_compilation/fail_opover.d(48): perhaps define `auto opSlice(int lower, int upper) {}` for `fail_opover.test2.S`
|
||||
---
|
||||
*/
|
||||
void test1()
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/ice10624.d(38): Error: need member function `opCmp()` for struct `Tuple!(Msg)` to compare
|
||||
fail_compilation/ice10624.d(48): Error: template instance `ice10624.Variant.handler!(Tuple!(Msg))` error instantiating
|
||||
fail_compilation/ice10624.d(21): instantiated from here: `opAssign!(Tuple!(Msg))`
|
||||
fail_compilation/ice10624.d(39): Error: no operator `<` for type `Tuple`
|
||||
fail_compilation/ice10624.d(13): perhaps overload it with `int opCmp(Tuple!(Msg) other) const {}`
|
||||
fail_compilation/ice10624.d(49): Error: template instance `ice10624.Variant.handler!(Tuple!(Msg))` error instantiating
|
||||
fail_compilation/ice10624.d(22): instantiated from here: `opAssign!(Tuple!(Msg))`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/ice12902.d(20): Error: variable `ice12902.main.__dollar` - type `void` is inferred from initializer `s.opDollar()`, and variables cannot be of type `void`
|
||||
fail_compilation/ice12902.d(20): Error: variable `ice12902.main.$` - type `void` is inferred from initializer `s.opDollar()`, and variables cannot be of type `void`
|
||||
fail_compilation/ice12902.d(20): Error: expression `s.opDollar()` is `void` and has no value
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
----
|
||||
fail_compilation/ice9545.d(13): Error: type `int` has no value
|
||||
fail_compilation/ice9545.d(14): Error: type `int` has no value
|
||||
fail_compilation/ice9545.d(14): perhaps use `int.init`
|
||||
----
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/operator_undefined.d(19): Error: operator `-` is not defined for `toJson(2)` of type `Json`
|
||||
fail_compilation/operator_undefined.d(20): Error: operator `-` is not defined for `Json`
|
||||
fail_compilation/operator_undefined.d(11): perhaps overload the operator with `auto opUnary(string op : "-")() {}`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
31
gcc/testsuite/gdc.test/fail_compilation/test20763.d
Normal file
31
gcc/testsuite/gdc.test/fail_compilation/test20763.d
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
REQUIRED_ARGS: -de
|
||||
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/test20763.d(25): Deprecation: type `ulong` has no value
|
||||
fail_compilation/test20763.d(25): perhaps use `ulong.init`
|
||||
fail_compilation/test20763.d(26): Deprecation: type `ulong` has no value
|
||||
fail_compilation/test20763.d(26): perhaps use `ulong.init`
|
||||
fail_compilation/test20763.d(27): Error: type `ulong` has no value
|
||||
fail_compilation/test20763.d(27): perhaps use `ulong.init`
|
||||
fail_compilation/test20763.d(28): Error: type `ulong` has no value
|
||||
fail_compilation/test20763.d(28): perhaps use `ulong.init`
|
||||
fail_compilation/test20763.d(29): Error: type `ulong` has no value
|
||||
fail_compilation/test20763.d(29): perhaps use `ulong.init`
|
||||
fail_compilation/test20763.d(30): Error: type `ulong` has no value
|
||||
fail_compilation/test20763.d(30): perhaps use `ulong.init`
|
||||
---
|
||||
*/
|
||||
|
||||
// https://github.com/dlang/dmd/issues/20763
|
||||
void test()
|
||||
{
|
||||
alias I = ulong;
|
||||
alias U0 = typeof(I + 1u);
|
||||
alias U1 = typeof(1 - I);
|
||||
alias U2 = typeof(+I);
|
||||
alias U3 = typeof(I * 1);
|
||||
alias U4 = typeof(I << 1);
|
||||
alias U5 = typeof(I | 1);
|
||||
}
|
|
@ -4,9 +4,10 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/imports/imp22329.d(3): Error: no property `values` for type `test22329.Foo`
|
||||
fail_compilation/test22329.d(13): struct `Foo` defined here
|
||||
fail_compilation/imports/imp22329.d(3): Error: incompatible types for `(arg) + (1)`: `Foo` and `int`
|
||||
fail_compilation/test22329.d(21): Error: template instance `imp22329.func!(Foo)` error instantiating
|
||||
fail_compilation/test22329.d(14): struct `Foo` defined here
|
||||
fail_compilation/imports/imp22329.d(3): Error: operator `+` is not defined for type `Foo`
|
||||
fail_compilation/test22329.d(14): perhaps overload the operator with `auto opBinary(string op : "+")(int rhs) {}`
|
||||
fail_compilation/test22329.d(22): Error: template instance `imp22329.func!(Foo)` error instantiating
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
b7e3b3b61711bf6c6cad27c7b5b73df0e570c215
|
||||
d29e3eca45edaeef63b31f78c9846fc6e2870c49
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the dlang/dmd repository.
|
||||
|
|
|
@ -704,6 +704,11 @@ private int softPopcnt(N)(N x) pure
|
|||
return cast(int) x;
|
||||
}
|
||||
|
||||
version (DigitalMars) version (AArch64)
|
||||
{
|
||||
int _popcnt(ulong x) pure;
|
||||
}
|
||||
|
||||
version (DigitalMars) version (AnyX86)
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -33,7 +33,12 @@ void InitializeObjectAttributes(OBJECT_ATTRIBUTES* p, UNICODE_STRING* n,
|
|||
}
|
||||
}
|
||||
|
||||
bool NT_SUCCESS(int x) { return x >= 0; }
|
||||
pragma(inline, true) @safe pure nothrow @nogc {
|
||||
bool NT_SUCCESS(NTSTATUS Status) { return Status >= 0; }
|
||||
bool NT_INFORMATION(NTSTATUS Status) { return ((cast(ULONG) Status) >> 30) == 1; }
|
||||
bool NT_WARNING(NTSTATUS Status) { return ((cast(ULONG) Status) >> 30) == 2; }
|
||||
bool NT_ERROR(NTSTATUS Status) { return ((cast(ULONG) Status) >> 30) == 3; }
|
||||
}
|
||||
|
||||
/* In MinGW, NTSTATUS, UNICODE_STRING, STRING and their associated pointer
|
||||
* type aliases are defined in ntdef.h, ntsecapi.h and subauth.h, each of
|
||||
|
|
Loading…
Add table
Reference in a new issue