Bug 18282 – [Scope][DIP1000]Assignment of local variable to `scope` variable not recognized by compiler

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2018-01-23T01:50:21Z
Last change time
2018-03-18T23:23:19Z
Keywords
safe
Assigned to
No Owner
Creator
Mike Franklin

Comments

Comment #0 by slavo5150 — 2018-01-23T01:50:21Z
void main() @safe { string foo = "foo"; scope string*[] ls; ls ~= &foo; } Compile with `-dip1000` onlineapp.d(5): Error: reference to local variable foo assigned to non-scope ls https://run.dlang.io/is/ecYAKZ The compiler doesn't seem to recognize that ls is attributed with `scope`. However due to the way D's attributes are parsed, I'm not sure if it should actually be `scope string*[]`, `scope(string*)[]`, or `scope(string*[])`. Anyway, if you use `scope()` (i.e. with parens) the compiler confuses it with `scope(exit)` and friends. void main() @safe { string foo = "foo"; scope(string*[]) ls; ls ~= &foo; } Compile with `-dip1000` onlineapp.d(4): Error: valid scope identifiers are exit, failure, or success, not string https://run.dlang.io/is/ecYAKZ
Comment #1 by bugzilla — 2018-03-12T03:32:22Z
(In reply to Mike Franklin from comment #0) > void main() @safe > { > string foo = "foo"; > scope string*[] ls; > ls ~= &foo; > } > > Compile with `-dip1000` > > onlineapp.d(5): Error: reference to local variable foo assigned to non-scope > ls While ls is scope, ls[] is not scope. Scope is not transitive, hence the compiler error. > The compiler doesn't seem to recognize that ls is attributed with `scope`. > However due to the way D's attributes are parsed, I'm not sure if it should > actually be `scope string*[]`, `scope(string*)[]`, or `scope(string*[])`. > Anyway, if you use `scope()` (i.e. with parens) the compiler confuses it > with `scope(exit)` and friends. > > > void main() @safe > { > string foo = "foo"; > scope(string*[]) ls; > ls ~= &foo; > } > > Compile with `-dip1000` > > onlineapp.d(4): Error: valid scope identifiers are exit, failure, or > success, not string Scope is a storage class, not a type constructor. (`const`, for example, is a type constructor, and `static` is a storage class.)
Comment #2 by ag0aep6g — 2018-03-12T11:20:25Z
(In reply to Walter Bright from comment #1) > (In reply to Mike Franklin from comment #0) > > void main() @safe > > { > > string foo = "foo"; > > scope string*[] ls; > > ls ~= &foo; > > } > > > > Compile with `-dip1000` > > > > onlineapp.d(5): Error: reference to local variable foo assigned to non-scope > > ls > > While ls is scope, ls[] is not scope. Scope is not transitive, hence the > compiler error. I assume that you don't mean `ls[]` literally, but rather that the elements of `ls` aren't `scope`, right? That means, it should be okay to return `ls[0]` because that's not `scope`, right? But that doesn't work: ---- string* f() @safe { scope string*[] ls; return ls[0]; /* Error: scope variable ls may not be returned */ } ---- On the other hand, this works: ---- void main() @safe { string foo = "foo"; scope string*[] ls; ls = ls ~ &foo; } ---- The only difference from the original code is `ls ~= &foo;` -> `ls = ls ~ &foo;`. Those two assignments should be equivalent [1], no? Either both should be accepted, or both should be rejected. [1] https://dlang.org/spec/expression.html#assignment_operator_expressions
Comment #3 by bugzilla — 2018-03-13T06:22:37Z
I'll reopen it and look at it again.
Comment #4 by bugzilla — 2018-03-13T22:52:52Z
Comment #5 by github-bugzilla — 2018-03-16T04:43:01Z
Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/ac0224287fd16d293081059acef7c23b94212a7b fix Issue 18282 - [Scope][DIP1000]Assignment of local variable to variable not recognized by compiler https://github.com/dlang/dmd/commit/718350da81d5c2d1f18e0eb7b6e6ec69d1e69c34 Merge pull request #8030 from WalterBright/fix18282 fix Issue 18282 - [Scope][DIP1000]Assignment of local variable to va… merged-on-behalf-of: Mike Franklin <[email protected]>
Comment #6 by ag0aep6g — 2018-03-16T10:23:28Z
(In reply to Walter Bright from comment #4) > https://github.com/dlang/dmd/pull/8030 That seems to have fixed this snippet from comment #2: ---- string* f() @safe { scope string*[] ls; return ls[0]; } ---- But the original test case still fails: ---- void main() @safe { string foo = "foo"; scope string*[] ls; ls ~= &foo; /* Error. But this works: ls = ls ~ &foo; */ } ---- Looks like the actual issue hasn't been fixed. Reopening.
Comment #7 by bugzilla — 2018-03-17T04:08:40Z
Comment #8 by github-bugzilla — 2018-03-18T23:23:18Z
Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/2dbc2bd85d5e5a55a3bcbf362c60cb0648102a73 fix Issue 18282 part 2 https://github.com/dlang/dmd/commit/bbe466b97fe5d2fa9f2914937f42079a987579d2 Merge pull request #8045 from WalterBright/fix18282-2 fix Issue 18282 part 2 merged-on-behalf-of: Walter Bright <[email protected]>