Bug 21209 – scope attribute inference with does not work well with foreach

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2020-08-29T13:50:33Z
Last change time
2021-06-03T08:00:33Z
Keywords
pull, rejects-valid, safe
Assigned to
No Owner
Creator
ChloƩ
See also
https://issues.dlang.org/show_bug.cgi?id=20674, https://issues.dlang.org/show_bug.cgi?id=20150, https://issues.dlang.org/show_bug.cgi?id=21990

Comments

Comment #0 by chloekek — 2020-08-29T13:50:33Z
The following program does not compile: --- $ cat main.d void foo()(const(char)[] cs) { foreach (c; cs) bar(c); } @safe void bar(char c) { } @safe void main() { char[10] cs; foo(cs); // line 16 } $ dmd -dip1000 main.d main.d(16): Error: reference to local variable `cs` assigned to non-scope parameter `cs` calling example.foo!().foo --- By manually adding the scope attribute to the cs parameter, the program compiles. But it is expected that DMD infers this from the body of the foo function, as it is a template. Verified with DMD 2.092.0 and LDC 1.23.0.
Comment #1 by pro.mathias.lang — 2021-02-19T06:15:44Z
At first I thought it wasn't a bug because the type of `cs` is specified. However, after changing `foo` to: ``` void foo(T)(T cs) { foreach (c; cs) bar(c); } ``` The error persist. The strangest part is that not calling `bar` from the foreach makes the error go away.
Comment #2 by ag0aep6g — 2021-02-19T07:30:14Z
(In reply to Mathias LANG from comment #1) > The strangest part is that not calling `bar` from the > foreach makes the error go away. That's because `bar` is not `pure`. Without the `bar` call, `foo` becomes `pure` and you're hitting issue 20150 (DMD wrongly assumes that parameters of `pure` functions can always be `scope`). When not relying on issue 20150, inference of `scope` is very limited. See also issue 20674.
Comment #3 by dkorpel — 2021-06-01T12:50:59Z
Worth noting that scope inference also fails on foreach loops of alias sequences: ``` @safe: void foo(A...)(A args) { static int x; x++; // force impure for issue 20150 foreach(a; args) { // gets lowered to unrolled loop with `string a = _param_0;` } } void main() { scope string x = "hey"; foo(x); } ``` Error: scope variable `x` assigned to non-scope parameter `_param_0` calling foo!string.foo
Comment #4 by dlang-bot — 2021-06-01T16:05:24Z
@dkorpel created dlang/dmd pull request #12620 "Fix issue 21209 - scope attribute inference fails on foreach" fixing this issue: - fix issue 21209 - scope inference fails with foreach https://github.com/dlang/dmd/pull/12620
Comment #5 by dlang-bot — 2021-06-02T23:58:48Z
dlang/dmd pull request #12620 "Fix issue 21209 - scope attribute inference fails on foreach" was merged into master: - 8e9ea4ef3ae9eb2cad92eeb8d54189dfb108e8b7 by dkorpel: Fix issue 21209 - scope inference fails on foreach https://github.com/dlang/dmd/pull/12620