d: foreach over a tuple doesn't work on 16-bit targets (PR100999)
Improves semantic passes in the front-end around the `foreach' and `static foreach' statements to be more resilient to compiling in a minimal D runtime environment. Checking of the index type has been improved as well so now there won't be needless compiler errors when using 8 or 16-bit integers as index types when the size fits the expected loop range. gcc/d/ChangeLog: PR d/100999 * dmd/MERGE: Merge upstream dmd 7a3808254. libphobos/ChangeLog: PR d/100999 * src/MERGE: Merge upstream phobos 55bb17543.
This commit is contained in:
parent
b13f297f01
commit
68f46862d3
|
@ -1,4 +1,4 @@
|
|||
4a4e46a6f304a667e0c05d4455706ec2056ffddc
|
||||
7a3808254878df8cb70a055bea58afc79187b778
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the dlang/dmd repository.
|
||||
|
|
|
@ -112,6 +112,7 @@ static void lowerArrayAggregate(StaticForeach *sfe, Scope *sc)
|
|||
sfe->aggrfe->aggr = new TupleExp(aggr->loc, es);
|
||||
sfe->aggrfe->aggr = expressionSemantic(sfe->aggrfe->aggr, sc);
|
||||
sfe->aggrfe->aggr = sfe->aggrfe->aggr->optimize(WANTvalue);
|
||||
sfe->aggrfe->aggr = sfe->aggrfe->aggr->ctfeInterpret();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -198,6 +199,7 @@ static TypeStruct *createTupleType(Loc loc, Expressions *e)
|
|||
Type *ty = new TypeTypeof(loc, new TupleExp(loc, e));
|
||||
sdecl->members->push(new VarDeclaration(loc, ty, fid, NULL));
|
||||
TypeStruct *r = (TypeStruct *)sdecl->type;
|
||||
if (global.params.useTypeInfo && Type::dtypeinfo)
|
||||
r->vtinfo = TypeInfoStructDeclaration::create(r); // prevent typeinfo from going to object file
|
||||
return r;
|
||||
}
|
||||
|
@ -312,15 +314,25 @@ static void lowerNonArrayAggregate(StaticForeach *sfe, Scope *sc)
|
|||
Identifier *idres = Identifier::generateId("__res");
|
||||
VarDeclaration *vard = new VarDeclaration(aloc, aty, idres, NULL);
|
||||
Statements *s2 = new Statements();
|
||||
|
||||
// Run 'typeof' gagged to avoid duplicate errors and if it fails just create
|
||||
// an empty foreach to expose them.
|
||||
unsigned olderrors = global.startGagging();
|
||||
ety = typeSemantic(ety, aloc, sc);
|
||||
if (global.endGagging(olderrors))
|
||||
s2->push(createForeach(sfe, aloc, pparams[1], NULL));
|
||||
else
|
||||
{
|
||||
s2->push(new ExpStatement(aloc, vard));
|
||||
Expression *catass = new CatAssignExp(aloc, new IdentifierExp(aloc, idres), res[1]);
|
||||
s2->push(createForeach(sfe, aloc, pparams[1], new ExpStatement(aloc, catass)));
|
||||
s2->push(new ReturnStatement(aloc, new IdentifierExp(aloc, idres)));
|
||||
}
|
||||
|
||||
Expression *aggr;
|
||||
Type *indexty;
|
||||
|
||||
if (sfe->rangefe && (indexty = typeSemantic(ety, aloc, sc))->isintegral())
|
||||
if (sfe->rangefe && (indexty = ety)->isintegral())
|
||||
{
|
||||
sfe->rangefe->lwr->type = indexty;
|
||||
sfe->rangefe->upr->type = indexty;
|
||||
|
@ -384,11 +396,6 @@ void staticForeachPrepare(StaticForeach *sfe, Scope *sc)
|
|||
sfe->aggrfe->aggr = expressionSemantic(sfe->aggrfe->aggr, sc);
|
||||
sc = sc->endCTFE();
|
||||
sfe->aggrfe->aggr = sfe->aggrfe->aggr->optimize(WANTvalue);
|
||||
Type *tab = sfe->aggrfe->aggr->type->toBasetype();
|
||||
if (tab->ty != Ttuple)
|
||||
{
|
||||
sfe->aggrfe->aggr = sfe->aggrfe->aggr->ctfeInterpret();
|
||||
}
|
||||
}
|
||||
|
||||
if (sfe->aggrfe && sfe->aggrfe->aggr->type->toBasetype()->ty == Terror)
|
||||
|
|
|
@ -643,7 +643,16 @@ Expression *ctfeInterpret(Expression *e)
|
|||
case TOKfloat64:
|
||||
case TOKcomplex80:
|
||||
case TOKnull:
|
||||
case TOKvoid:
|
||||
case TOKstring:
|
||||
case TOKthis:
|
||||
case TOKsuper:
|
||||
case TOKtype:
|
||||
case TOKtypeid:
|
||||
case TOKtemplate: // non-eponymous template/instance
|
||||
case TOKscope: // ditto
|
||||
case TOKdottd: // ditto, e.e1 doesn't matter here
|
||||
case TOKdot: // ditto
|
||||
if (e->type->ty == Terror)
|
||||
return new ErrorExp();
|
||||
/* fall through */
|
||||
|
|
|
@ -1044,7 +1044,7 @@ bool Expression::checkPostblit(Scope *sc, Type *t)
|
|||
t = t->baseElemOf();
|
||||
if (t->ty == Tstruct)
|
||||
{
|
||||
if (global.params.useTypeInfo)
|
||||
if (global.params.useTypeInfo && Type::dtypeinfo)
|
||||
{
|
||||
// Bugzilla 11395: Require TypeInfo generation for array concatenation
|
||||
semanticTypeInfo(sc, t);
|
||||
|
|
|
@ -1082,11 +1082,6 @@ static Expression *resolvePropertiesX(Scope *sc, Expression *e1, Expression *e2
|
|||
if (checkUnsafeAccess(sc, e1, true, true))
|
||||
return new ErrorExp();
|
||||
}
|
||||
else if (e1->op == TOKdot)
|
||||
{
|
||||
e1->error("expression has no value");
|
||||
return new ErrorExp();
|
||||
}
|
||||
else if (e1->op == TOKcall)
|
||||
{
|
||||
CallExp *ce = (CallExp *)e1;
|
||||
|
@ -4513,11 +4508,18 @@ public:
|
|||
|
||||
void visit(DotTemplateExp *e)
|
||||
{
|
||||
if (e->type)
|
||||
{
|
||||
result = e;
|
||||
return;
|
||||
}
|
||||
if (Expression *ex = unaSemantic(e, sc))
|
||||
{
|
||||
result = ex;
|
||||
return;
|
||||
}
|
||||
// 'void' like TemplateExp
|
||||
e->type = Type::tvoid;
|
||||
result = e;
|
||||
}
|
||||
|
||||
|
|
|
@ -563,9 +563,6 @@ public:
|
|||
else
|
||||
{
|
||||
e = resolveProperties(sc, e);
|
||||
type = e->type;
|
||||
if (paramtype)
|
||||
type = paramtype;
|
||||
Initializer *ie = new ExpInitializer(Loc(), e);
|
||||
VarDeclaration *v = new VarDeclaration(loc, type, ident, ie);
|
||||
if (storageClass & STCref)
|
||||
|
@ -646,23 +643,24 @@ public:
|
|||
}
|
||||
}
|
||||
p->type = typeSemantic(p->type, loc, sc);
|
||||
TY keyty = p->type->ty;
|
||||
if (keyty != Tint32 && keyty != Tuns32)
|
||||
|
||||
if (!p->type->isintegral())
|
||||
{
|
||||
if (global.params.isLP64)
|
||||
{
|
||||
if (keyty != Tint64 && keyty != Tuns64)
|
||||
{
|
||||
fs->error("foreach: key type must be int or uint, long or ulong, not %s", p->type->toChars());
|
||||
fs->error("foreach: key cannot be of non-integral type `%s`",
|
||||
p->type->toChars());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
unsigned length = te ? te->exps->length : tuple->arguments->length;
|
||||
IntRange dimrange = IntRange(SignExtendedNumber(length)).cast(Type::tsize_t);
|
||||
// https://issues.dlang.org/show_bug.cgi?id=12504
|
||||
dimrange.imax = SignExtendedNumber(dimrange.imax.value-1);
|
||||
if (!IntRange::fromType(p->type).contains(dimrange))
|
||||
{
|
||||
fs->error("foreach: key type must be int or uint, not %s", p->type->toChars());
|
||||
fs->error("index type `%s` cannot cover index range 0..%llu",
|
||||
p->type->toChars(), (ulonglong)length);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Initializer *ie = new ExpInitializer(Loc(), new IntegerExp(k));
|
||||
VarDeclaration *var = new VarDeclaration(loc, p->type, p->ident, ie);
|
||||
var->storage_class |= STCmanifest;
|
||||
|
@ -1073,6 +1071,8 @@ public:
|
|||
{
|
||||
TypeSArray *ta = (TypeSArray *)tab;
|
||||
IntRange dimrange = getIntRange(ta->dim);
|
||||
// https://issues.dlang.org/show_bug.cgi?id=12504
|
||||
dimrange.imax = SignExtendedNumber(dimrange.imax.value-1);
|
||||
if (!IntRange::fromType(var->type).contains(dimrange))
|
||||
{
|
||||
fs->error("index type `%s` cannot cover index range 0..%llu", p->type->toChars(), ta->dim->toInteger());
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
module object;
|
|
@ -0,0 +1,30 @@
|
|||
// https://issues.dlang.org/show_bug.cgi?id=21927
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
T1(Args...)
|
||||
T1!()
|
||||
T2(Args2...)
|
||||
T2!()
|
||||
this.T2(Args2...)
|
||||
this.T2!()
|
||||
---
|
||||
*/
|
||||
template T1(Args...) {}
|
||||
|
||||
pragma(msg, T1); // TOK.template_
|
||||
pragma(msg, T1!()); // TOK.scope_
|
||||
|
||||
struct S
|
||||
{
|
||||
template T2(Args2...) {}
|
||||
|
||||
pragma(msg, S.T2); // TOK.template_
|
||||
pragma(msg, S.T2!()); // TOK.scope_
|
||||
|
||||
void fun()
|
||||
{
|
||||
pragma(msg, this.T2); // TOK.dotTemplateDeclaration
|
||||
pragma(msg, this.T2!()); // TOK.dot
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// DFLAGS:
|
||||
// REQUIRED_ARGS: -defaultlib=
|
||||
// EXTRA_SOURCES: extra-files/minimal/object.d
|
||||
|
||||
/**********************************************/
|
||||
// https://issues.dlang.org/show_bug.cgi?id=19234
|
||||
void issue19234()
|
||||
{
|
||||
static struct A {}
|
||||
A[10] a;
|
||||
A[10] b;
|
||||
b[] = a[];
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
// https://issues.dlang.org/show_bug.cgi?id=22005
|
||||
void issue22005()
|
||||
{
|
||||
enum int[4] foo = [1,2,3,4];
|
||||
static foreach (i, e; foo)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
// https://issues.dlang.org/show_bug.cgi?id=22006
|
||||
void issue22006()
|
||||
{
|
||||
alias size_t = typeof(int.sizeof);
|
||||
alias AliasSeq(T...) = T;
|
||||
|
||||
foreach (size_t i, e; [0, 1, 2, 3]) { }
|
||||
static foreach (size_t i, e; [0, 1, 2, 3]) { }
|
||||
foreach (size_t i, e; AliasSeq!(0, 1, 2, 3)) { }
|
||||
static foreach (size_t i, e; AliasSeq!(0, 1, 2, 3)) { }
|
||||
}
|
|
@ -115,6 +115,8 @@ bug17688
|
|||
T
|
||||
foo2
|
||||
T2
|
||||
TestStaticForeach2
|
||||
issue22007
|
||||
1 2 '3'
|
||||
2 3 '4'
|
||||
0 1
|
||||
|
@ -840,3 +842,39 @@ struct T2{
|
|||
struct S{}
|
||||
}
|
||||
static assert(is(__traits(parent,T2.S)==T2));
|
||||
|
||||
struct TestStaticForeach2
|
||||
{
|
||||
static:
|
||||
// StringExp
|
||||
char[] test(string str)()
|
||||
{
|
||||
char[] s;
|
||||
static foreach (c; str)
|
||||
{
|
||||
s ~= c;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
static assert(test!"tёstñ" == ['t', '\xd1', '\x91', 's', 't', '\xc3', '\xb1']);
|
||||
|
||||
static foreach (c; "")
|
||||
{
|
||||
static assert(0);
|
||||
}
|
||||
|
||||
// NullExp
|
||||
enum int[] a = null;
|
||||
static foreach (c; a)
|
||||
{
|
||||
static assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
//https://issues.dlang.org/show_bug.cgi?id=22007
|
||||
void issue22007()
|
||||
{
|
||||
immutable int[32] array = 1;
|
||||
foreach (size_t a, int b; array) {}
|
||||
static foreach (size_t a, int b; array) { }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// https://issues.dlang.org/show_bug.cgi?id=21742
|
||||
|
||||
int foo()() { return 0; }
|
||||
|
||||
struct B
|
||||
{
|
||||
int foo()() { return 0; }
|
||||
}
|
||||
|
||||
static assert(is(typeof(foo) == void));
|
||||
|
||||
// failed, gagged error: expression B().foo()() has no type
|
||||
static assert(is(typeof(B().foo) == void));
|
|
@ -0,0 +1,14 @@
|
|||
// https://issues.dlang.org/show_bug.cgi?id=22006
|
||||
void test22006()
|
||||
{
|
||||
alias AliasSeq(TList...) = TList;
|
||||
{
|
||||
alias aseq = AliasSeq!(0, 1, 2, 3);
|
||||
static foreach (ubyte i; 0 .. aseq.length) {}
|
||||
static foreach (ubyte i, x; aseq) {}
|
||||
}
|
||||
{
|
||||
static foreach (ubyte i; 0 .. [0, 1, 2, 3].length) {}
|
||||
static foreach (ubyte i, x; [0, 1, 2, 3]) {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/b12504.d(26): Error: cannot implicitly convert expression `257$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `ubyte`
|
||||
fail_compilation/b12504.d(27): Error: index type `ubyte` cannot cover index range 0..257
|
||||
fail_compilation/b12504.d(31): Error: cannot implicitly convert expression `129$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `byte`
|
||||
fail_compilation/b12504.d(32): Error: index type `byte` cannot cover index range 0..129
|
||||
fail_compilation/b12504.d(36): Error: cannot implicitly convert expression `65537$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `ushort`
|
||||
fail_compilation/b12504.d(37): Error: index type `ushort` cannot cover index range 0..65537
|
||||
fail_compilation/b12504.d(41): Error: cannot implicitly convert expression `32769$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `short`
|
||||
fail_compilation/b12504.d(42): Error: index type `short` cannot cover index range 0..32769
|
||||
fail_compilation/b12504.d(46): Error: cannot implicitly convert expression `257$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `ubyte`
|
||||
fail_compilation/b12504.d(47): Error: index type `ubyte` cannot cover index range 0..257
|
||||
fail_compilation/b12504.d(51): Error: cannot implicitly convert expression `129$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `byte`
|
||||
fail_compilation/b12504.d(52): Error: index type `byte` cannot cover index range 0..129
|
||||
fail_compilation/b12504.d(56): Error: cannot implicitly convert expression `65537$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `ushort`
|
||||
fail_compilation/b12504.d(57): Error: index type `ushort` cannot cover index range 0..65537
|
||||
fail_compilation/b12504.d(61): Error: cannot implicitly convert expression `32769$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `short`
|
||||
fail_compilation/b12504.d(62): Error: index type `short` cannot cover index range 0..32769
|
||||
---
|
||||
*/
|
||||
void main()
|
||||
{
|
||||
{
|
||||
int[0xFF + 2] sta;
|
||||
foreach (ubyte i; 0 .. sta.length) {}
|
||||
foreach (ubyte i, x; sta) {}
|
||||
}
|
||||
{
|
||||
int[0x7F + 2] sta;
|
||||
foreach (byte i; 0 .. sta.length) {}
|
||||
foreach (byte i, x; sta) {}
|
||||
}
|
||||
{
|
||||
int[0xFFFF + 2] sta;
|
||||
foreach (ushort i; 0 .. sta.length) {}
|
||||
foreach (ushort i, x; sta) {}
|
||||
}
|
||||
{
|
||||
int[0x7FFF + 2] sta;
|
||||
foreach (short i; 0 .. sta.length) {}
|
||||
foreach (short i, x; sta) {}
|
||||
}
|
||||
{
|
||||
immutable int[0xFF + 2] sta;
|
||||
static foreach (ubyte i; 0 .. sta.length) {}
|
||||
static foreach (ubyte i, x; sta) {}
|
||||
}
|
||||
{
|
||||
immutable int[0x7F + 2] sta;
|
||||
static foreach (byte i; 0 .. sta.length) {}
|
||||
static foreach (byte i, x; sta) {}
|
||||
}
|
||||
{
|
||||
immutable int[0xFFFF + 2] sta;
|
||||
static foreach (ushort i; 0 .. sta.length) {}
|
||||
static foreach (ushort i, x; sta) {}
|
||||
}
|
||||
{
|
||||
immutable int[0x7FFF + 2] sta;
|
||||
static foreach (short i; 0 .. sta.length) {}
|
||||
static foreach (short i, x; sta) {}
|
||||
}
|
||||
}
|
|
@ -1,21 +1,37 @@
|
|||
/* TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/diag16976.d(28): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(29): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(30): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(31): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(32): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(33): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(34): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(35): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(36): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(37): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(38): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(39): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(40): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(41): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(42): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(43): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(44): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(45): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(46): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(47): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(48): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(49): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(50): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(51): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(52): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(53): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(54): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(55): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(56): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(57): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(58): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(59): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(65): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(66): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(67): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(68): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(69): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(70): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(71): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(72): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(73): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(74): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(75): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(76): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(77): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(78): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(79): Error: foreach: key cannot be of non-integral type `float`
|
||||
fail_compilation/diag16976.d(80): Error: foreach: key cannot be of non-integral type `float`
|
||||
---
|
||||
*/
|
||||
|
||||
|
@ -41,4 +57,25 @@ void main()
|
|||
foreach_reverse(float f, dchar i; sta) {}
|
||||
foreach_reverse(float f, dchar i; str) {}
|
||||
foreach_reverse(float f, dchar i; chr) {}
|
||||
|
||||
immutable int[] idyn = [1,2,3,4,5];
|
||||
immutable int[5] ista = [1,2,3,4,5];
|
||||
immutable char[] istr = ['1','2','3','4','5'];
|
||||
immutable char[5] ichr = ['1','2','3','4','5'];
|
||||
static foreach(float f, i; idyn) {}
|
||||
static foreach(float f, i; ista) {}
|
||||
static foreach(float f, i; istr) {}
|
||||
static foreach(float f, i; ichr) {}
|
||||
static foreach(float f, dchar i; idyn) {}
|
||||
static foreach(float f, dchar i; ista) {}
|
||||
static foreach(float f, dchar i; istr) {}
|
||||
static foreach(float f, dchar i; ichr) {}
|
||||
static foreach_reverse(float f, i; idyn) {}
|
||||
static foreach_reverse(float f, i; ista) {}
|
||||
static foreach_reverse(float f, i; istr) {}
|
||||
static foreach_reverse(float f, i; ichr) {}
|
||||
static foreach_reverse(float f, dchar i; idyn) {}
|
||||
static foreach_reverse(float f, dchar i; ista) {}
|
||||
static foreach_reverse(float f, dchar i; istr) {}
|
||||
static foreach_reverse(float f, dchar i; ichr) {}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail117.d(35): Error: expression has no value
|
||||
fail_compilation/fail117.d(36): Error: expression has no value
|
||||
fail_compilation/fail117.d(37): Error: expression `foo.mixin MGettor!(a) geta;
|
||||
` is `void` and has no value
|
||||
fail_compilation/fail117.d(38): Error: expression `foo.mixin MGettor!(b) getb;
|
||||
` is `void` and has no value
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail22006.d(15): Error: cannot implicitly convert expression `4$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `bool`
|
||||
fail_compilation/fail22006.d(16): Error: index type `bool` cannot cover index range 0..4
|
||||
fail_compilation/fail22006.d(19): Error: cannot implicitly convert expression `4$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `bool`
|
||||
fail_compilation/fail22006.d(20): Error: index type `bool` cannot cover index range 0..4
|
||||
---
|
||||
*/
|
||||
void test22006()
|
||||
{
|
||||
alias AliasSeq(TList...) = TList;
|
||||
{
|
||||
alias aseq = AliasSeq!(0, 1, 2, 3);
|
||||
static foreach (bool i; 0 .. aseq.length) {}
|
||||
static foreach (bool i, x; aseq) {}
|
||||
}
|
||||
{
|
||||
static foreach (bool i; 0 .. [0, 1, 2, 3].length) {}
|
||||
static foreach (bool i, x; [0, 1, 2, 3]) {}
|
||||
}
|
||||
}
|
|
@ -3,10 +3,10 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail238_m32.d(21): Error: cannot implicitly convert expression `"a"` of type `string` to `uint`
|
||||
fail_compilation/fail238_m32.d(24): Error: cannot interpret X!() at compile time
|
||||
fail_compilation/fail238_m32.d(29): Error: template instance fail238_m32.A!"a" error instantiating
|
||||
fail_compilation/fail238_m32.d(35): instantiated from here: M!(q)
|
||||
fail_compilation/fail238_m32.d(35): while evaluating pragma(msg, M!(q))
|
||||
fail_compilation/fail238_m32.d(24): Error: cannot implicitly convert expression `X!()` of type `void` to `const(string)`
|
||||
fail_compilation/fail238_m32.d(29): Error: template instance `fail238_m32.A!"a"` error instantiating
|
||||
fail_compilation/fail238_m32.d(35): instantiated from here: `M!(q)`
|
||||
fail_compilation/fail238_m32.d(35): while evaluating `pragma(msg, M!(q))`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail238_m64.d(21): Error: cannot implicitly convert expression `"a"` of type `string` to `ulong`
|
||||
fail_compilation/fail238_m64.d(24): Error: cannot interpret X!() at compile time
|
||||
fail_compilation/fail238_m64.d(29): Error: template instance fail238_m64.A!"a" error instantiating
|
||||
fail_compilation/fail238_m64.d(35): instantiated from here: M!(q)
|
||||
fail_compilation/fail238_m64.d(35): while evaluating pragma(msg, M!(q))
|
||||
fail_compilation/fail238_m64.d(24): Error: cannot implicitly convert expression `X!()` of type `void` to `const(string)`
|
||||
fail_compilation/fail238_m64.d(29): Error: template instance `fail238_m64.A!"a"` error instantiating
|
||||
fail_compilation/fail238_m64.d(35): instantiated from here: `M!(q)`
|
||||
fail_compilation/fail238_m64.d(35): while evaluating `pragma(msg, M!(q))`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail7424b.d(10): Error: cannot resolve type for this.g()()
|
||||
fail_compilation/fail7424b.d(10): Error: expression `this.g()()` is `void` and has no value
|
||||
---
|
||||
*/
|
||||
struct S7424b
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail7424c.d(10): Error: cannot resolve type for this.g()()
|
||||
fail_compilation/fail7424c.d(10): Error: expression `this.g()()` is `void` and has no value
|
||||
---
|
||||
*/
|
||||
struct S7424c
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail7424d.d(10): Error: cannot resolve type for this.g()()
|
||||
fail_compilation/fail7424d.d(10): Error: expression `this.g()()` is `void` and has no value
|
||||
---
|
||||
*/
|
||||
struct S7424d
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail7424e.d(10): Error: cannot resolve type for this.g()()
|
||||
fail_compilation/fail7424e.d(10): Error: expression `this.g()()` is `void` and has no value
|
||||
---
|
||||
*/
|
||||
struct S7424e
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail7424f.d(10): Error: cannot resolve type for this.g()()
|
||||
fail_compilation/fail7424f.d(10): Error: expression `this.g()()` is `void` and has no value
|
||||
---
|
||||
*/
|
||||
struct S7424f
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail7424g.d(10): Error: cannot resolve type for this.g()()
|
||||
fail_compilation/fail7424g.d(10): Error: expression `this.g()()` is `void` and has no value
|
||||
---
|
||||
*/
|
||||
struct S7424g
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail7424h.d(10): Error: cannot resolve type for this.g()()
|
||||
fail_compilation/fail7424h.d(10): Error: expression `this.g()()` is `void` and has no value
|
||||
---
|
||||
*/
|
||||
struct S7424g
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail7424i.d(10): Error: cannot resolve type for this.g()()
|
||||
fail_compilation/fail7424i.d(10): Error: expression `this.g()()` is `void` and has no value
|
||||
---
|
||||
*/
|
||||
struct S7424g
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail9766.d(14): Error: cannot interpret Foo!int at compile time
|
||||
fail_compilation/fail9766.d(14): Error: integer constant expression expected instead of `Foo!int`
|
||||
fail_compilation/fail9766.d(14): Error: alignment must be an integer positive power of 2, not Foo!int
|
||||
fail_compilation/fail9766.d(17): Error: alignment must be an integer positive power of 2, not -1
|
||||
fail_compilation/fail9766.d(20): Error: alignment must be an integer positive power of 2, not 0
|
||||
fail_compilation/fail9766.d(23): Error: alignment must be an integer positive power of 2, not 3
|
||||
|
@ -9,6 +10,7 @@ fail_compilation/fail9766.d(26): Error: alignment must be an integer positive po
|
|||
---
|
||||
*/
|
||||
|
||||
#line 12
|
||||
template Foo(T) {}
|
||||
|
||||
align(Foo!int)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/ice9406.d(21): Error: expression has no value
|
||||
fail_compilation/ice9406.d(22): Error: `s1.mixin Mixin!() t1;
|
||||
` has no effect
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
// https://issues.dlang.org/show_bug.cgi?id=21927
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/test21927.d(17): Error: invalid `foreach` aggregate `this.T2(Args2...)`
|
||||
fail_compilation/test21927.d(18): Error: invalid `foreach` aggregate `this.T2!()`
|
||||
---
|
||||
*/
|
||||
|
||||
struct S
|
||||
{
|
||||
template T2(Args2...) {}
|
||||
|
||||
void fun()
|
||||
{
|
||||
// original test case
|
||||
static foreach (p; this.T2) {} // ICE
|
||||
static foreach (p; this.T2!()) {} // ICE
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
// https://issues.dlang.org/show_bug.cgi?id=21939
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/test21939.d(9): Error: invalid `foreach` aggregate `Object`, define `opApply()`, range primitives, or use `.tupleof`
|
||||
---
|
||||
*/
|
||||
|
||||
static foreach (a; Object) {}
|
|
@ -1,4 +1,4 @@
|
|||
63f4caa900e17c541042617b2fa187059b86bf88
|
||||
55bb17543138a87c376a84745f2a30ec00bdecd9
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the dlang/phobos repository.
|
||||
|
|
|
@ -5935,13 +5935,7 @@ mixin template Proxy(alias a)
|
|||
// built-in type field, manifest constant, and static non-mutable field
|
||||
enum opDispatch = mixin("a."~name);
|
||||
}
|
||||
else static if (is(typeof(mixin("a."~name))) || __traits(getOverloads, a, name).length != 0)
|
||||
{
|
||||
// field or property function
|
||||
@property auto ref opDispatch(this X)() { return mixin("a."~name); }
|
||||
@property auto ref opDispatch(this X, V)(auto ref V v) { return mixin("a."~name~" = v"); }
|
||||
}
|
||||
else
|
||||
else static if (__traits(isTemplate, mixin("a."~name)))
|
||||
{
|
||||
// member template
|
||||
template opDispatch(T...)
|
||||
|
@ -5950,6 +5944,13 @@ mixin template Proxy(alias a)
|
|||
auto ref opDispatch(this X, Args...)(auto ref Args args){ return mixin("a."~name~targs~"(args)"); }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// field or property function
|
||||
@property auto ref opDispatch(this X)() { return mixin("a."~name); }
|
||||
@property auto ref opDispatch(this X, V)(auto ref V v) { return mixin("a."~name~" = v"); }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
import std.traits : isArray;
|
||||
|
|
Loading…
Reference in New Issue