Bug 22541 – DIP1000: Resolve ambiguity of ref-return-scope parameters
Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-11-24T05:46:42Z
Last change time
2022-02-17T05:58:38Z
Keywords
pull, safe
Assigned to
No Owner
Creator
Walter Bright
Comments
Comment #0 by bugzilla — 2021-11-24T05:46:42Z
When a function parameter is declared as `ref return scope`, is it `return ref`, or `return scope`?
Consider the following types:
P contains indirections
I does not contain indirections
X may or may not contain indirections
Currently, the ambiguity is resolved:
a. P foo(ref return scope P p) => ref returnScope
b. I foo(ref return scope P p) => returnRef scope
c. ref X foo(ref return scope P p) => returnRef scope
d. X foo(ref return scope I) => returnRef
e. ref X foo(ref return scope I) => returnRef
d,e are explained in terms of `scope` being dropped because it makes no sense if I contains no indirections. The trouble comes into play when a generic type T is used, and the `return` attribute moves surprisingly back and forth between the `ref` and the `scope`. b is explained because since a pointer is not being returned, there's no reason for `scope` to be `return`. Again, generic code can have surprising behavior. a,c cause problems because converting a pointer to/from a ref is legitimate in @system code.
`ref` `return` and `scope` can appear in any order, and intermingled with other attributes like `const`. They cannot appear more than once.
This proposal is that if `return` and `ref` appear adjacent to each other, in this order, then the result is returnRef. Similarly, `return` and `scope` become returnScope. If neither of these two patterns appear, the behavior remains the same as in a..e.
Having `returnRef` and `returnScope` remains illegal.
Comment #1 by bugzilla — 2021-11-24T05:54:43Z
For struct member functions:
struct S {
T foo() return scope { ... }
}
the first parameter is `ref S`. But the ambiguity is resolved by allowing `ref` to appear after the `foo()`, as in:
T foo() return ref scope { ... } // returnRef scope
T foo() ref return scope { ... } // ref returnScope
Comment #2 by dkorpel — 2021-11-24T23:04:48Z
I do like the idea of looking for adjacent `return scope`.
I don't like the complexity behind rules a..e, I'd rather simplify it than add on top of that, so how about an alternative proposal:
When adjacent keywords `return scope` are present, the result is `ref returnScope`. Everything else results in `returnRef scope`.
You can make returnRef member functions with `scope return`, no new grammar needed. It also covers issue 20881.
Comment #3 by dlang-bot — 2021-11-25T08:03:31Z
@WalterBright created dlang/dmd pull request #13357 "fix Issue 22541 - DIP1000: Resolve ambiguity of ref-return-scope para…" fixing this issue:
- fix Issue 22541 - DIP1000: Resolve ambiguity of ref-return-scope parameters
https://github.com/dlang/dmd/pull/13357
Comment #4 by bugzilla — 2021-11-30T06:42:59Z
Where I'd like to go is only allow "return ref" or "return scope". In the meantime, backwards compatibility will do for the first iteration.
Comment #5 by dkorpel — 2021-11-30T11:01:21Z
(In reply to Walter Bright from comment #4)
> Where I'd like to go is only allow "return ref" or "return scope". In the
> meantime, backwards compatibility will do for the first iteration.
Yes, let's do that!
Comment #6 by dlang-bot — 2022-01-24T11:55:44Z
dlang/dmd pull request #13357 "fix Issue 22541 - DIP1000: Resolve ambiguity of ref-return-scope para…" was merged into master:
- 7754800627f4f37bc16e49d123cd6db6597e7c3a by Walter Bright:
fix Issue 22541 - DIP1000: Resolve ambiguity of ref-return-scope parameters
https://github.com/dlang/dmd/pull/13357
Comment #7 by dkorpel — 2022-02-16T13:25:55Z
As mentioned in the PR, that was only a partial fix, this still fails:
```
struct S
{
int i;
int* ptr;
int* wannabeReturnRef() scope return
{
return &i;
}
}
```
Error: returning `&this.i` escapes a reference to parameter `this`
perhaps remove `scope` parameter annotation so `return` applies to `ref`
Comment #8 by dlang-bot — 2022-02-17T03:22:14Z
@WalterBright created dlang/dmd pull request #13677 "fix Issue 22541 - DIP1000: Resolve ambiguity of ref-return-scope para…" fixing this issue:
- fix Issue 22541 - DIP1000: Resolve ambiguity of ref-return-scope parameters
https://github.com/dlang/dmd/pull/13677
Comment #9 by dlang-bot — 2022-02-17T05:58:38Z
dlang/dmd pull request #13677 "fix Issue 22541 - DIP1000: Resolve ambiguity of ref-return-scope para…" was merged into master:
- a435fa4a2cd64b47f234bdc2b3843d9624582731 by Walter Bright:
fix Issue 22541 - DIP1000: Resolve ambiguity of ref-return-scope parameters
https://github.com/dlang/dmd/pull/13677