Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Issue 9415 - delegate inference should make function literal impure #1572

Merged
merged 1 commit into from

2 participants

@WalterBright WalterBright commented on the diff
test/runnable/funclit.d
@@ -717,6 +717,16 @@ void test9153()
}
/***************************************************/
+// 9415
+
+void test9415()
+{
+ int z;
+ typeof((int a){return z;}) dg;
@WalterBright Owner

shouldn't this line be typed as pure, instead of line 726 as impure?

@9rnsr Collaborator
9rnsr added a note

In current, dg is declared as int delegate(int) pure nothrow @safe.
Because, inside typeof, pureness and safety inference is suppressed in temporary.

So this line is now pure, and line 726 is already impure. But it is a bug. This line should be impure.

Essentially, if a lambda literal contacts to the frame enclosing it, it should be impure.
But there is a few exceptions. In following, lambda literal is inferred to delegate but keeps its pureness.

Bar8751 foo8751b(const int x) pure
{
    return y => x > y; // pure delegate
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@WalterBright WalterBright merged commit a5ab2c3 into from
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 21 additions and 0 deletions.
  1. +10 −0 src/declaration.c
  2. +11 −0 test/runnable/funclit.d
View
10 src/declaration.c
@@ -1955,6 +1955,16 @@ void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration())
{
fld->tok = TOKdelegate;
+
+ /* This is necessary to avoid breaking tests for 8751 & 8793.
+ * See: compilable/testInference.d
+ */
+ if (type->isMutable() || // mutable variable
+ !type->implicitConvTo(type->invariantOf()) || // has any mutable indirections
+ !fdv->isPureBypassingInference()) // does not belong to pure function
+ {
+ fld->setImpure(); // Bugzilla 9415
+ }
}
}
View
11 test/runnable/funclit.d
@@ -717,6 +717,16 @@ void test9153()
}
/***************************************************/
+// 9415
+
+void test9415()
+{
+ int z;
+ typeof((int a){return z;}) dg;
@WalterBright Owner

shouldn't this line be typed as pure, instead of line 726 as impure?

@9rnsr Collaborator
9rnsr added a note

In current, dg is declared as int delegate(int) pure nothrow @safe.
Because, inside typeof, pureness and safety inference is suppressed in temporary.

So this line is now pure, and line 726 is already impure. But it is a bug. This line should be impure.

Essentially, if a lambda literal contacts to the frame enclosing it, it should be impure.
But there is a few exceptions. In following, lambda literal is inferred to delegate but keeps its pureness.

Bar8751 foo8751b(const int x) pure
{
    return y => x > y; // pure delegate
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ dg = (int a){return z;};
+}
+
+/***************************************************/
int main()
{
@@ -758,6 +768,7 @@ int main()
test8496();
test8575();
test9153();
+ test9415();
printf("Success\n");
return 0;
Something went wrong with that request. Please try again.