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:
Iain Buclaw 2021-06-11 19:33:07 +02:00
parent b13f297f01
commit 68f46862d3
32 changed files with 388 additions and 80 deletions

View File

@ -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.

View File

@ -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,7 +199,8 @@ 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;
r->vtinfo = TypeInfoStructDeclaration::create(r); // prevent typeinfo from going to object file
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();
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)));
// 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)

View File

@ -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 */

View File

@ -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);

View File

@ -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;
}

View File

@ -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,22 +643,23 @@ 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());
return false;
}
}
else
{
fs->error("foreach: key type must be int or uint, not %s", p->type->toChars());
return false;
}
fs->error("foreach: key cannot be of non-integral type `%s`",
p->type->toChars());
return false;
}
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("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);
@ -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());

View File

@ -0,0 +1 @@
module object;

View File

@ -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
}
}

View File

@ -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)) { }
}

View File

@ -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) { }
}

View File

@ -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));

View File

@ -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]) {}
}
}

View File

@ -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) {}
}
}

View File

@ -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) {}
}

View File

@ -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
---
*/

View File

@ -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]) {}
}
}

View File

@ -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))`
---
*/

View File

@ -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))`
---
*/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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
---
*/

View File

@ -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
}
}

View File

@ -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) {}

View File

@ -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.

View File

@ -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;