Bug 22027 – inout shouldn't imply return

Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-06-15T23:22:27Z
Last change time
2022-03-22T10:53:48Z
Keywords
pull, safe
Assigned to
No Owner
Creator
Dennis
See also
https://issues.dlang.org/show_bug.cgi?id=17927, https://issues.dlang.org/show_bug.cgi?id=20149

Comments

Comment #0 by dkorpel — 2021-06-15T23:22:27Z
Currently `inout` parameters imply the `return` attribute. It's a special case, adding complexity to the language and the compiler, and it doesn't make sense. The rationale of it is: > The idea is that the inout doesn't make sense if one is not returning > something based on the parameter marked with inout. https://github.com/dlang/dmd/pull/10390#issuecomment-528774351 However, as pointed out by Rainer Schuetze, it's possible to return something else that has the same qualifier as the parameter but different lifetime. ``` struct Large { void[4000] data; } struct SImpl { Large d; } struct S { SImpl* impl; // GC managed? ref inout(Large) getLarge() inout { return impl.d; } } ``` https://github.com/dlang/dmd/pull/10390#issuecomment-529177731 In fact, here are examples of valid uses of inout with every combination of ref/return/scope, showing that it doesn't ever imply the need for `return`: ``` struct Node { int x; Node* next; inout(int*) next_v0() return inout {return &this.x;} inout(int*) next_v1() return scope inout {return &this.next.x;} inout(int*) next_v2() scope inout {return &this.next.next.x;} inout(int*) next_v3() inout {return &this.next.x;} ref inout(int) next_r0() return inout {return this.next.x;} ref inout(int) next_r1() scope inout {return this.next.next.x;} ref inout(int) next_r2() return scope inout {return this.next.next.x;} ref inout(int) next_r3() inout {return this.next.x;} } inout(int*) next_v0(return inout Node this_) {return &this_.next.x;} inout(int*) next_v1(return scope inout Node this_) {return &this_.next.x;} inout(int*) next_v2( scope inout Node this_) {return &this_.next.next.x;} inout(int*) next_v3( inout Node this_) {return &this_.next.x;} ref inout(int) next_r0(return inout Node this_) {return this_.next.x;} ref inout(int) next_r1(return scope inout Node this_) {return this_.next.x;} ref inout(int) next_r2( scope inout Node this_) {return this_.next.next.x;} ref inout(int) next_r3( inout Node this_) {return this_.next.x;} ``` It's also worth noting that the current implementation has a bug that's trivially fixed by removing the special case: https://issues.dlang.org/show_bug.cgi?id=20149 ``` @safe: struct ScopeBuffer { char[4] buf; inout(char)[] getSlice() inout {return buf[];} } char[] fun() { char[4] buf = "abcd"; ScopeBuffer sb = ScopeBuffer(buf); return sb.getSlice; // dangling slice to stack memory is returned here } void main() { auto s = fun(); } ```
Comment #1 by dlang-bot — 2021-06-15T23:33:05Z
@dkorpel created dlang/dmd pull request #12689 "Fix issue 22027, 20149 - inout doesn't imply return" fixing this issue: - fix issue 22027, 20149 - inout doesn't imply return https://github.com/dlang/dmd/pull/12689
Comment #2 by bugzilla — 2021-06-16T09:52:02Z
Removing the implicit `return` from `inout` will likely break existing code, as the `return` may need to be added.
Comment #3 by destructionator — 2021-06-18T18:37:59Z
How can you break existing code that doesn't exist? The whole return thing is new.
Comment #4 by dlang-bot — 2022-03-22T09:35:34Z
@dkorpel created dlang/dlang.org pull request #3259 "Fix issue 22027 - `inout` doesn't imply return" fixing this issue: - Fix issue 22027 - Inout doesn't imply return https://github.com/dlang/dlang.org/pull/3259
Comment #5 by dlang-bot — 2022-03-22T10:44:22Z
dlang/dmd pull request #12689 "Fix issue 22027, 20149 - inout doesn't imply return" was merged into master: - 9082bb675362f06c7c50141ecebff960648546f1 by dkorpel: Fix issue 22027, 22840 - inout doesn't imply return https://github.com/dlang/dmd/pull/12689
Comment #6 by dlang-bot — 2022-03-22T10:53:48Z
dlang/dlang.org pull request #3259 "Fix issue 22027 - `inout` doesn't imply return" was merged into master: - c4edb10953b1d33ee36a59d40e24e5debd67da2e by dkorpel: Fix issue 22027 - Inout doesn't imply return https://github.com/dlang/dlang.org/pull/3259