Skip to content

Commit

Permalink
allow ref on locals, globals, and statics
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed May 1, 2024
1 parent e60bfd1 commit 6e23bc0
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 4 deletions.
12 changes: 12 additions & 0 deletions changelog/dmd.reflocal.dd
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
`ref` can now be applied to local, static, extern, and global variables

For example, one can now write:
```
void main()
{
int i;
ref int r = i;
r = 3;
assert(i == 3);
}
```
4 changes: 2 additions & 2 deletions compiler/src/dmd/dsymbolsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -1001,9 +1001,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
}
}

if ((dsym.storage_class & (STC.ref_ | STC.parameter | STC.foreach_ | STC.temp | STC.result)) == STC.ref_ && dsym.ident != Id.This)
if ((dsym.storage_class & (STC.ref_ | STC.field)) == (STC.ref_ | STC.field) && dsym.ident != Id.This)
{
.error(dsym.loc, "%s `%s` - only parameters, functions and `foreach` declarations can be `ref`", dsym.kind, dsym.toPrettyChars);
.error(dsym.loc, "%s `%s` - field declarations cannot be `ref`", dsym.kind, dsym.toPrettyChars);

Check warning on line 1006 in compiler/src/dmd/dsymbolsem.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/dsymbolsem.d#L1006

Added line #L1006 was not covered by tests
}

if (dsym.type.hasWild())
Expand Down
37 changes: 35 additions & 2 deletions compiler/test/fail_compilation/diag9679.d
Original file line number Diff line number Diff line change
@@ -1,13 +1,46 @@
/*
TEST_OUTPUT:
---
fail_compilation/diag9679.d(11): Error: variable `diag9679.main.n` - only parameters, functions and `foreach` declarations can be `ref`
fail_compilation/diag9679.d(12): Error: variable `diag9679.main.n` - storage class `auto` has no effect if type is not inferred, did you mean `scope`?
fail_compilation/diag9679.d(15): Error: variable `diag9679.main.n` - storage class `auto` has no effect if type is not inferred, did you mean `scope`?
fail_compilation/diag9679.d(16): Error: variable `diag9679.main.S.a` - field declarations cannot be `ref`
fail_compilation/diag9679.d(23): Error: returning `r` escapes a reference to local variable `r`
fail_compilation/diag9679.d(30): Error: returning `r` escapes a reference to local variable `r`
---
*/


void main()
{
if (ref n = 1) {}
if (auto int n = 1) {}
struct S { ref int a; }
}

ref int test2()
{
int i;
ref r = i;
return r;
}

ref int test3()
{
extern int i;
ref r = i;
return r;
}

struct S { int a; }

void test4()
{
S s;
ref int r1 = s.a;
r1 = 3;
__gshared S t2;
ref int r2 = t2.a;
static S t3;
ref int r3 = t3.a;
extern S t4;
ref int r4 = t4.a;
}

0 comments on commit 6e23bc0

Please sign in to comment.