Skip to content

Commit

Permalink
Merge pull request #219 from yebblies/issue1339
Browse files Browse the repository at this point in the history
Issue 1339 - Invariant/const-ness is broken by built-in array properties
  • Loading branch information
WalterBright committed Oct 3, 2011
2 parents 6f37208 + 184c710 commit f6fe4cc
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 9 deletions.
7 changes: 4 additions & 3 deletions src/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -6538,9 +6538,10 @@ Expression *DotIdExp::semantic(Scope *sc, int flag)
return e->type->dotExp(sc, e, ident);
}
#if DMDV2
else if (t1b->ty == Tarray ||
t1b->ty == Tsarray ||
t1b->ty == Taarray)
else if ((t1b->ty == Tarray || t1b->ty == Tsarray ||
t1b->ty == Taarray) &&
ident != Id::sort && ident != Id::reverse &&
ident != Id::dup && ident != Id::idup)
{ /* If ident is not a valid property, rewrite:
* e1.ident
* as:
Expand Down
17 changes: 16 additions & 1 deletion src/mtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -3178,6 +3178,11 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
#if LOGDOTEXP
printf("TypeArray::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars());
#endif

if (!n->isMutable())
if (ident == Id::sort || ident == Id::reverse)
error(e->loc, "can only %s a mutable array\n", ident->toChars());

if (ident == Id::reverse && (n->ty == Tchar || n->ty == Twchar))
{
Expression *ec;
Expand Down Expand Up @@ -3220,6 +3225,7 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
int size = next->size(e->loc);
int dup;

Expression *olde = e;
assert(size);
dup = (ident == Id::dup || ident == Id::idup);
fd = FuncDeclaration::genCfunc(Type::tindex, dup ? Id::adDup : Id::adReverse);
Expand All @@ -3235,9 +3241,18 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
if (ident == Id::idup)
{ Type *einv = next->invariantOf();
if (next->implicitConvTo(einv) < MATCHconst)
error(e->loc, "cannot implicitly convert element type %s to immutable", next->toChars());
error(e->loc, "cannot implicitly convert element type %s to immutable in %s.idup",
next->toChars(), olde->toChars());
e->type = einv->arrayOf();
}
else if (ident == Id::dup)
{
Type *emut = next->mutableOf();
if (next->implicitConvTo(emut) < MATCHconst)
error(e->loc, "cannot implicitly convert element type %s to mutable in %s.dup",
next->toChars(), olde->toChars());
e->type = emut->arrayOf();
}
else
e->type = next->mutableOf()->arrayOf();
}
Expand Down
6 changes: 3 additions & 3 deletions test/runnable/test12.d
Original file line number Diff line number Diff line change
Expand Up @@ -1157,19 +1157,19 @@ void test56()
string a = "abcd";
string r;

r = a.idup.reverse;
r = a.dup.reverse.idup;
writefln(r);
assert(r == "dcba");

a = "a\u1235\u1234c";
writefln(a);
r = a.idup.reverse;
r = a.dup.reverse.idup;
writefln(r);
assert(r == "c\u1234\u1235a");

a = "ab\u1234c";
writefln(a);
r = a.idup.reverse;
r = a.dup.reverse.idup;
writefln(r);
assert(r == "c\u1234ba");
}
Expand Down
4 changes: 2 additions & 2 deletions test/runnable/test8.d
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ void test18()
str.sort;

// This will crash the compiler
str[0].sort;
str[0] = str[0].dup.sort.idup;

// This will give sintax error
//str[0].sort();
Expand All @@ -367,7 +367,7 @@ void test19()
string array = "foobar";

array = array.idup;
array.sort;
array = array.dup.sort.idup;
assert(array == "abfoor");
}

Expand Down

0 comments on commit f6fe4cc

Please sign in to comment.