From 64d260f6473a45c8756af00620169c071fb1e563 Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Wed, 1 May 2024 20:08:25 -0700 Subject: [PATCH] Fix ref on function param --- changelog/dmd.reflocal.dd | 8 +++++--- compiler/src/dmd/dsymbolsem.d | 4 ++-- compiler/src/dmd/escape.d | 4 ++-- compiler/test/fail_compilation/diag9679.d | 5 ++--- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/changelog/dmd.reflocal.dd b/changelog/dmd.reflocal.dd index c3ce216c45..9732ef0d19 100644 --- a/changelog/dmd.reflocal.dd +++ b/changelog/dmd.reflocal.dd @@ -2,11 +2,13 @@ For example, one can now write: ``` +struct S { int a; } + void main() { - int i; - ref int r = i; + S s; + ref int r = s.a; r = 3; - assert(i == 3); + assert(s.a == 3); } ``` diff --git a/compiler/src/dmd/dsymbolsem.d b/compiler/src/dmd/dsymbolsem.d index b2a7e1153e..90b01cdbf9 100644 --- a/compiler/src/dmd/dsymbolsem.d +++ b/compiler/src/dmd/dsymbolsem.d @@ -1105,8 +1105,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } } - if ((dsym.storage_class & (STC.ref_ | STC.field)) == STC.ref_ && !dsym._init) - .error(dsym.loc, "%s `%s` - initializer is required for `ref` variable", dsym.kind, dsym.toPrettyChars, dsym.type.toChars()); + if ((dsym.storage_class & (STC.ref_ | STC.field | STC.parameter | STC.temp | STC.foreach_)) == STC.ref_ && !dsym._init && dsym.ident != Id.This) + .error(dsym.loc, "%s `%s` - initializer is required for `ref` variable", dsym.kind, dsym.toPrettyChars); FuncDeclaration fd = parent.isFuncDeclaration(); if (dsym.type.isscope() && !(dsym.storage_class & STC.nodtor)) diff --git a/compiler/src/dmd/escape.d b/compiler/src/dmd/escape.d index 1631602952..672b70baa6 100644 --- a/compiler/src/dmd/escape.d +++ b/compiler/src/dmd/escape.d @@ -1956,9 +1956,9 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retR auto v = e.var.isVarDeclaration(); if (v) { - if (v.storage_class & STC.ref_ && v.storage_class & (STC.foreach_ | STC.temp) && v._init) + if (v.storage_class & STC.ref_ && v._init) { - /* If compiler generated ref temporary + /* If ref * (ref v = ex; ex) * look at the initializer instead */ diff --git a/compiler/test/fail_compilation/diag9679.d b/compiler/test/fail_compilation/diag9679.d index e2614a7306..fb0dd8aa92 100644 --- a/compiler/test/fail_compilation/diag9679.d +++ b/compiler/test/fail_compilation/diag9679.d @@ -3,12 +3,12 @@ TEST_OUTPUT: --- 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` +fail_compilation/diag9679.d(23): Error: returning `r` escapes a reference to local variable `i` --- */ + void main() { if (ref n = 1) {} @@ -54,4 +54,3 @@ void test5() { ref int r5; } -