Bug 22284 – [DIP1000] function templates cannot infer scope in instances with indirections when accessing the address of fields

Status
NEW
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-09-07T14:12:20Z
Last change time
2024-12-13T19:18:22Z
Assigned to
No Owner
Creator
João Lourenço
Moved to GitHub: dmd#19981 →

Comments

Comment #0 by jlourenco5691 — 2021-09-07T14:12:20Z
``` @safe: struct Foo { void canInfer()() { cast(void) &i; } int i; } struct Bar { void canInfer1()() { cast(void) arr.ptr; } void canInfer2()() { cast(void) &arr[0]; } void cannotInfer()() { cast(void) &i; } void cannotInfer1()() { () scope { cast(void) &i; }(); } void cannotInfer2(this This)() { cast(void) &i; } void cannotInfer3(this This)() { () scope { cast(void) &i; }(); } void canInfer3(this This)() { (This bar) scope { with(bar) cast(void) &i; }(this); } void canInfer4(this This)() { (This bar) { with(bar) cast(void) &i; }(this); } int[] arr = [0]; int i; } void main() { scope foo = Foo(); scope bar = Bar(); foo.canInfer; bar.canInfer1; bar.canInfer2; bar.cannotInfer; // fails bar.cannotInfer1; // fails bar.cannotInfer2; // fails bar.cannotInfer3; // fails bar.canInfer3; // great... bar.canInfer4; // wait what? } ```
Comment #1 by dkorpel — 2021-09-07T15:53:07Z
I'm not sure why your cannotInfer examples fail, but canInfer3 and canInfer4 succeed because the parameter (This bar) in the lambda is inferred scope since it's passed by value and the lambda is `pure` and returns `void`, so it can't escape `arr`. The `scope` annotation of canInfer3 doesn't do anything since it's not a `delegate` but a `function` since you pass `this` explicitly through parameter `bar`.
Comment #2 by jlourenco5691 — 2021-09-07T17:12:23Z
Yes the last 2 make sense to infer scope, the comments were because I'm specifying other templates with `(this This)` and they cannot infer scope. > but canInfer3 and canInfer4 succeed because the parameter (This bar) in the lambda is inferred scope since it's passed by value and the lambda is `pure` and returns `void`, so it can't escape `arr`. Ok, but I can make it a function and still escape its context: ``` @safe: struct Bar { void canInfer(this This)() { This other; (This bar) { other = bar; } (this); with(other) cast(void) &i; } int[] arr = [0]; int i; } void main() { scope bar = Bar(); bar.canInfer; } ```
Comment #3 by jlourenco5691 — 2021-09-07T17:15:02Z
I meant a delegate.
Comment #4 by robert.schadek — 2024-12-13T19:18:22Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19981 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB