Thread overview
[Issue 23116] foreach with opApply infer ref when opApply delegate is templated
May 16, 2022
Dlang Bot
May 16, 2022
Dennis
May 16, 2022
Luís Ferreira
May 16, 2022
Luís Ferreira
May 16, 2022
Luís Ferreira
Dec 17, 2022
Iain Buclaw
Jun 26
Dlang Bot
May 16, 2022
https://issues.dlang.org/show_bug.cgi?id=23116

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #1 from Dlang Bot <dlang-bot@dlang.rocks> ---
@ljmf00 created dlang/dmd pull request #14132 "fix(statementsem): foreach shouldn't infer ref on templated opApply" fixing this issue:

- fix(statementsem): foreach shouldn't infer ref on templated opApply

  When a foreach with templated opApply, the compiler infers the
  following:

  ```d
  foreach(ref int i; S())
  ```

  Even if you explicitly type it as non-ref.

  Fix issue 23116.

  Reference: https://issues.dlang.org/show_bug.cgi?id=23116
  Signed-off-by: Luís Ferreira <contact@lsferreira.net>

https://github.com/dlang/dmd/pull/14132

--
May 16, 2022
https://issues.dlang.org/show_bug.cgi?id=23116

Dennis <dkorpel@live.nl> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dkorpel@live.nl

--- Comment #2 from Dennis <dkorpel@live.nl> ---
Does inferring ref result in actual behavioral problems?

--
May 16, 2022
https://issues.dlang.org/show_bug.cgi?id=23116

--- Comment #3 from Luís Ferreira <contact@lsferreira.net> ---
(In reply to Dennis from comment #2)
> Does inferring ref result in actual behavioral problems?

It is. It should use the available overload. In my case, I have something like:

```
[ParameterStorageClassTuple!Dg].all!(stc => !(stc & STC.ref_))
```

It should fall into the usable case, like it does without templating it.

--
May 16, 2022
https://issues.dlang.org/show_bug.cgi?id=23116

--- Comment #4 from Luís Ferreira <contact@lsferreira.net> ---
Doing fallback of the overload manually can be a workaround for this:

```
int opApply(Dg : int delegate(ref ubyte))(scope Dg dg)
{
    enum attrs = functionAttributes!Dg;
    alias nonRefDg = SetFunctionAttributes!(int delegate(ubyte),
functionLinkage!Dg, attrs);
    foreach(ubyte i; &this.opApply!(nonRefDg)) // use the correct overload
        if(auto ret = dg(i)) return ret;

    return 0;
}

int opApply(Dg : int delegate(ubyte))(scope Dg dg)
{
    // ...
}
```

--
May 16, 2022
https://issues.dlang.org/show_bug.cgi?id=23116

--- Comment #5 from Luís Ferreira <contact@lsferreira.net> ---
Ok, I found the problem. The compiler seem to choose right for function declarations, but there is no logic for template declarations: https://github.com/dlang/dmd/blob/master/src/dmd/opover.d#L1598

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=23116

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P3

--
June 26
https://issues.dlang.org/show_bug.cgi?id=23116

--- Comment #6 from Dlang Bot <dlang-bot@dlang.rocks> ---
@Bolpat created dlang/dlang.org pull request #3859 "Specify `opApply` as an alias to a function template instance" fixing this issue:

- Fix Bugzilla Issues 23666, 17953, 23116, and 24633

https://github.com/dlang/dlang.org/pull/3859

--