digitalmars.D - Return value storage classes - `scope` as well as `ref`
- Nick Treleaven (54/54) May 29 2023 Recently we've discussed syntax solutions to `ref` not applying
- Dukc (12/22) May 30 2023 No, this is working just as it should. `lf` is not `scope`, so a
- Dukc (16/18) May 30 2023 Oh sorry, didn't read your whole post. You weren't claiming
- Nick Treleaven (6/10) May 31 2023 Yes, thanks I didn't know that. I'm not sure if that's documented
- Nick Treleaven (2/3) May 31 2023 https://github.com/dlang/dlang.org/pull/3619
- Quirin Schroll (5/8) May 30 2023 By “unimplemented feature” are you suggesting a new langue
Recently we've discussed syntax solutions to `ref` not applying to a variable/parameter when those are of function pointer type: https://issues.dlang.org/show_bug.cgi?id=2753 `ref` is a function attribute, so this problem is easier to solve. Also it is not allowed after the parameter list because conceptually it applies to the return value. However, there is another case of missing syntax for an unimplemented feature. `scope` would be useful to apply to the return value of a function. Currently `scope` is disallowed on functions except for methods or delegates, where it applies to `this` or the context. There are cases where it would be useful to apply to the return value - e.g. for `List.front` here: https://issues.dlang.org/show_bug.cgi?id=17934 ```d Elem elem; { auto l = list(); elem = l.front; // should error // destructor called } ``` And for `S.fp` here: https://forum.dlang.org/post/mqyqlieghqwsinbqiqbp forum.dlang.org ```d int* p; { auto lf = S(5); p = lf.fp; // should error // destructor called } ``` Syntax solutions proposed to fix the `ref` problem are: * Parenthesized type syntax - https://forum.dlang.org/post/fnfuczxfyjpyespactjt forum.dlang.org * leading function pointer type syntax - https://forum.dlang.org/post/qngjoxgihmcsvoprnanb forum.dlang.org * trailing return type syntax - https://forum.dlang.org/post/iveapbodjzgqfjkujsop forum.dlang.org The first two have PRs. I think only the latter fixes the `scope` problem. A simpler fix would be this ordering: ``` Type ReturnStorage? Identifier Parameters ``` Where *ReturnStorage* is `ref` or `scope`. ```d T scope ref func_name(); ``` Using parentheses just for the storage class(es) would work too: ```d (scope ref) T func_name(); ``` Also, solving the problem generally could be useful in the future if we want any other storage classes to apply to the return value rather than the function or the parameter.
May 29 2023
On Monday, 29 May 2023 at 10:08:38 UTC, Nick Treleaven wrote:And for `S.fp` here: https://forum.dlang.org/post/mqyqlieghqwsinbqiqbp forum.dlang.org ```d int* p; { auto lf = S(5); p = lf.fp; // should error // destructor called } ```No, this is working just as it should. `lf` is not `scope`, so a return value of a `return scope` function should be neither. Maybe you're confusing lifetime of struct itself with lifetime of what it's pointing to. `return scope` return value is `scope` only if the struct is `scope` - that is, potentially pointing to a local with one or more of it's fields. Whether the struct itself is in stack is irrelevant. On the other hand, `return` (without the trailing `scope`, `return ref` when applied to a parameter) means the return value is `scope` if the struct is in a stack. Maybe that's what you intended `S.fp` to be.
May 30 2023
On Tuesday, 30 May 2023 at 07:21:44 UTC, Dukc wrote:No, this is working just as it should. `lf` is not `scope`, so a return value of a `return scope` function should be neither.Oh sorry, didn't read your whole post. You weren't claiming there's a bug but suggesting a new design. That is, making `lf` be `scope` with this syntax. I still prefer the current solution, though. `scope` is an on/off attribute only from perspect of variables. Expression, though, have shortest possible lifetimes, meaning they figure out which local scope the result is guaranteed to last. `S(5)` is an expression, so the compiler needs to figure out it's shortest possible lifetime even if it isn't immediately assigned to a variable. What should it be? It isn't obvious. What does work, without language changes, is giving a sentinel pointer parameter to the constructor that is used to figure out the shortest possible lifetime. That is, the constructor is defined `this(int, return scope void* sentinel)` and is used `S(5, &localVariableIWontOutlive)`.
May 30 2023
On Tuesday, 30 May 2023 at 07:21:44 UTC, Dukc wrote:On the other hand, `return` (without the trailing `scope`, `return ref` when applied to a parameter) means the return value is `scope` if the struct is in a stack. Maybe that's what you intended `S.fp` to be.Yes, thanks I didn't know that. I'm not sure if that's documented anywhere in the spec. https://dlang.org/spec/function.html#return-scope-parameters This also resolves the bugzilla issue: https://issues.dlang.org/show_bug.cgi?id=17934#c12
May 31 2023
On Wednesday, 31 May 2023 at 10:29:06 UTC, Nick Treleaven wrote:I'm not sure if that's documented anywhere in the spec.https://github.com/dlang/dlang.org/pull/3619
May 31 2023
On Monday, 29 May 2023 at 10:08:38 UTC, Nick Treleaven wrote:However, there is another case of missing syntax for an unimplemented feature. `scope` would be useful to apply to the return value of a function.By “unimplemented feature” are you suggesting a new langue feature or is there something specified that is not implemented yet? If it’s already in the spec, please quote the relevant sections.
May 30 2023