Skip to content

Commit

Permalink
fix Issue 20956 - [DIP1000] @safe defeated by closure capturing ref p…
Browse files Browse the repository at this point in the history
…arameter
  • Loading branch information
WalterBright authored and dkorpel committed Apr 19, 2024
1 parent 56a0ea8 commit be0c9d0
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 5 deletions.
11 changes: 11 additions & 0 deletions compiler/src/dmd/func.d
Original file line number Diff line number Diff line change
Expand Up @@ -1534,6 +1534,17 @@ extern (C++) class FuncDeclaration : Declaration
}
else
{
foreach (v; closureVars)
{
if (v.isRef() &&
(global.params.useDIP1000 == FeatureState.enabled && isSafe()))
{
error("cannot close over `ref` variable `%s`", v.toChars());
if (global.gag) // need not report supplemental errors
return true;
}
}

printGCUsage(loc, "using closure causes GC allocation");
return false;
}
Expand Down
7 changes: 4 additions & 3 deletions compiler/test/fail_compilation/test15544.d
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
REQUIRED_ARGS: -preview=dip1000
TEST_OUTPUT:
---
fail_compilation/test15544.d(20): Error: reference to local `this` assigned to non-scope `_del` in @safe code
fail_compilation/test15544.d(22): Error: reference to local `this` assigned to non-scope `_del` in @safe code
fail_compilation/test15544.d(21): Error: reference to local `this` assigned to non-scope `_del` in @safe code
fail_compilation/test15544.d(23): Error: reference to local `this` assigned to non-scope `_del` in @safe code
fail_compilation/test15544.d(18): Error: function `test15544.S.test` cannot close over `ref` variable `this`
---
*/

Expand All @@ -26,7 +27,7 @@ struct S {
/*
TEST_OUTPUT:
---
fail_compilation/test15544.d(46): Error: reference to local `y` assigned to non-scope `dg` in @safe code
fail_compilation/test15544.d(47): Error: reference to local `y` assigned to non-scope `dg` in @safe code
---
*/

Expand Down
5 changes: 3 additions & 2 deletions compiler/test/fail_compilation/test17423.d
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* REQUIRED_ARGS: -preview=dip1000
TEST_OUTPUT:
---
fail_compilation/test17423.d(27): Error: reference to local `this` assigned to non-scope parameter `dlg` calling `opApply`
fail_compilation/test17423.d(16): which is not `scope` because of `this.myDlg = dlg`
fail_compilation/test17423.d(28): Error: reference to local `this` assigned to non-scope parameter `dlg` calling `opApply`
fail_compilation/test17423.d(17): which is not `scope` because of `this.myDlg = dlg`
fail_compilation/test17423.d(27): Error: constructor `test17423.Foo.this` cannot close over `ref` variable `this`
---
*/

Expand Down
19 changes: 19 additions & 0 deletions compiler/test/fail_compilation/test20956.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* REQUIRED_ARGS: -preview=dip1000
TEST_OUTPUT:
---
fail_compilation/test20956.d(105): Error: function `test20956.forwardDg` cannot close over `ref` variable `c`
---
*/

// https://issues.dlang.org/show_bug.cgi?id=20956

#line 100

@safe:

alias DG = void delegate() @safe;

DG forwardDg(ref int c)
{
return () {assert(c == 42);};
}

0 comments on commit be0c9d0

Please sign in to comment.