DIP1000: 'return scope' ambiguity and why you can't make opIndex work

ag0aep6g anonymous at example.com
Fri Jun 18 17:04:02 UTC 2021


On Friday, 18 June 2021 at 15:44:02 UTC, Dennis wrote:
> **Does the `return` attribute apply to the parameter's `ref` or 
> the pointer value?**
> |                                  | `scope`   | no `scope` |
> |----------------------------------|-----------|------------|
> | `ref` return type / `ref` param  | **`ref`** | **`ref`**  |
> | value return type / `ref` param  | **value** | **`ref`**  |
> | `ref` return type / value param  | **value** | **value**  |
> | value return type / value param  | **value** | **value**  |
[...]
> Here's the reduced code:
> ```D
> struct Vector {
>     float[] _elements;
>     ref float opIndex(size_t i) scope return {
>         return this._elements[i];
>     }
> }
> ```
>
> With the patch I made, the error becomes:
> ```
> source/automem/vector.d(212,25): Error: scope parameter `this` 
> may not be returned
> source/automem/vector.d(212,25):        note that `return` 
> applies to `ref`, not the value
> ```

Geez, this isn't easy. I had to go step by step to make sense of 
that error, so maybe this can help others understand:

`opIndex` has a half-hidden parameter: `return ref scope this`. 
Depending on the `opIndex`'s return type, the `return` part of 
the `this` parameter can either bind to its `ref` part or to its 
`scope` part. In pseudo code, it can be either `(return ref) 
(not-return scope) this` or `(not-return ref) (return scope) 
this`.

`opIndex` has a `ref` return type. According to the table above, 
that means `return` binds to the `ref` part of `ref scope this`. 
I.e., it's `(return ref) (not-return scope) this`.

`(return ref) this` means `opIndex` may return a `ref` to `this` 
or `this._elements` (same address).

`(not-return scope) this` means it cannot return a `ref` to the 
elements of `this._elements`, because that would be returning a 
`scope` pointer which hasn't been annotated with `return`.

As far as I understand, `opIndex` could return 
`&this._elements[i]` by value. Then the `return` would bind to 
the `scope` part of `ref scope this`, making `&this._elements[i]` 
a `return scope` pointer. But `float*` would be an awkward return 
type for `opIndex`.

Geez, this isn't easy.



More information about the Digitalmars-d mailing list