Permalink
Browse files

Issue 5081 - Pure functions as initializers for immutable structures

Allow an expression to be implicitly cast to immutable if 1) it is the return value of a call to a strongly pure function or 2) it is being returned from a strongly pure function
  • Loading branch information...
1 parent c98b611 commit 99e0f21d2a7a19b655d97fa08394a3bc623f10a0 @yebblies yebblies committed Aug 21, 2011
Showing with 48 additions and 1 deletion.
  1. +20 −0 src/cast.c
  2. +0 −1 src/expression.c
  3. +2 −0 src/expression.h
  4. +7 −0 src/statement.c
  5. +19 −0 test/runnable/xtest46.d
View
@@ -576,6 +576,26 @@ MATCH AssocArrayLiteralExp::implicitConvTo(Type *t)
return Expression::implicitConvTo(t);
}
+MATCH CallExp::implicitConvTo(Type *t)
+{
+#if 0
+ printf("CalLExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
+ toChars(), type->toChars(), t->toChars());
+#endif
+
+ MATCH m = Expression::implicitConvTo(t);
+ if (m)
+ return m;
+
+ /* Allow the result of strongly pure functions to
+ * convert to immutable
+ */
+ if (f && f->isPure() == PUREstrong)
+ return type->invariantOf()->implicitConvTo(t);
+
+ return MATCHnomatch;
+}
+
MATCH AddrExp::implicitConvTo(Type *t)
{
#if 0
View
@@ -6859,7 +6859,6 @@ Expression *CallExp::syntaxCopy()
Expression *CallExp::semantic(Scope *sc)
{
TypeFunction *tf;
- FuncDeclaration *f;
Type *t1;
int istemp;
Objects *targsi = NULL; // initial list of template arguments
View
@@ -935,6 +935,7 @@ struct DotTypeExp : UnaExp
struct CallExp : UnaExp
{
Expressions *arguments; // function arguments
+ FuncDeclaration *f; // symbol to call
CallExp(Loc loc, Expression *e, Expressions *exps);
CallExp(Loc loc, Expression *e);
@@ -954,6 +955,7 @@ struct CallExp : UnaExp
Expression *toLvalue(Scope *sc, Expression *e);
int canThrow(bool mustNotThrow);
Expression *addDtorHook(Scope *sc);
+ MATCH implicitConvTo(Type *t);
int inlineCost(InlineCostState *ics);
Expression *doInline(InlineDoState *ids);
View
@@ -3521,6 +3521,13 @@ Statement *ReturnStatement::semantic(Scope *sc)
}
else if (tbret->ty != Tvoid)
{
+ if (fd->isPureBypassingInference() == PUREstrong &&
+ !exp->type->implicitConvTo(tret) &&
+ exp->type->invariantOf()->implicitConvTo(tret))
+ {
+ exp = exp->castTo(sc, exp->type->invariantOf());
+ }
+
exp = exp->implicitCastTo(sc, tret);
if (!((TypeFunction *)fd->type)->isref)
exp = exp->optimize(WANTvalue);
@@ -1875,6 +1875,24 @@ void test99()
/***************************************************/
+void test5081()
+{
+ static pure immutable(int[]) x()
+ {
+ return new int[](10);
+ }
+
+ static pure int[] y()
+ {
+ return new int[](10);
+ }
+
+ immutable a = x();
+ immutable b = y();
+}
+
+/***************************************************/
+
void test100()
{
string s;
@@ -3617,6 +3635,7 @@ int main()
test116();
test117();
test118();
+ test5081();
test120();

0 comments on commit 99e0f21

Please sign in to comment.