Jump to page: 1 2
Thread overview
[Issue 8204] Can't instantiate auto ref template explicitly
[Issue 8204] Alias causes error: "auto can only be used for template function parameters"
Jul 18, 2017
Vladimir Panteleev
Jun 06, 2019
Simen Kjaeraas
Jun 07, 2019
anonymous4
Jun 07, 2019
Simen Kjaeraas
Aug 17, 2020
Simen Kjaeraas
Sep 04, 2020
Basile-z
Sep 04, 2020
Basile-z
Apr 27, 2022
Basile-z
Apr 28, 2022
vitamin
Jul 27, 2022
Nick Treleaven
Jul 27, 2022
Nick Treleaven
Dec 17, 2022
Iain Buclaw
August 18, 2014
https://issues.dlang.org/show_bug.cgi?id=8204

hsteoh@quickfur.ath.cx changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hsteoh@quickfur.ath.cx

--- Comment #1 from hsteoh@quickfur.ath.cx ---
Still happens on git HEAD.

--
July 18, 2017
https://issues.dlang.org/show_bug.cgi?id=8204

--- Comment #2 from Vladimir Panteleev <dlang-bugzilla@thecybershadow.net> ---
(In reply to dlang+issues from comment #0)
> void foo(T)(ref auto T v) { }
> alias foo!int bar; // Error: auto can only be used for template function
> parameters

What is the expected type of "bar" here? The compiler can't know whether the instantiated function should take its parameter by ref or not, so I'm not sure whether this issue is valid. What is the expected behaviour?

As a workaround, you can move the type to a separate outer template using the eponymous template pattern:

template foo(T)
{
    void foo()(auto ref T v) { }
}
alias foo!int bar;

Unfortunately, this breaks calling foo (as in `foo(5)`). The type will need to
be indicated explicitly (e.g. `foo!int(5)`).

--
June 06, 2019
https://issues.dlang.org/show_bug.cgi?id=8204

Simen Kjaeraas <simen.kjaras@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |simen.kjaras@gmail.com

--- Comment #3 from Simen Kjaeraas <simen.kjaras@gmail.com> ---
It's perfectly possible to get aliases to overload sets in D, so that's what bar should be.

--
June 07, 2019
https://issues.dlang.org/show_bug.cgi?id=8204

--- Comment #4 from anonymous4 <dfj1esp02@sneakemail.com> ---
auto ref is IFTI, not an overload set though

--
June 07, 2019
https://issues.dlang.org/show_bug.cgi?id=8204

--- Comment #5 from Simen Kjaeraas <simen.kjaras@gmail.com> ---
That was my point. Instead of resolving to a single instantiation of the template, we could instantiate all possible ref/non-ref permutations and alias bar to the resultant overload set. Of course, when I think a bit more about that, the number of possible instantiations may well be too damn high.

The correct solution here is to issue a better error message.

--
August 17, 2020
https://issues.dlang.org/show_bug.cgi?id=8204

Simen Kjaeraas <simen.kjaras@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Alias causes error: "auto   |Can't instantiate auto ref
                   |can only be used for        |template explicitly
                   |template function           |
                   |parameters"                 |

--- Comment #6 from Simen Kjaeraas <simen.kjaras@gmail.com> ---
We could argue that foo!int should alias to the non-ref version, and foo!(ref
int) (or, in valid D, foo!(Parameters!((ref int){}))) give the ref version. So
far, so good.

However, auto ref functions are a strange breed, and this is perfectly valid:

    void fun()(auto ref int){}

In this case there's no template argument to carry the information about refness, so no explicit instantiation can be made. In some cases we can add extra parameters and simply extract the refness from those, so the definition as seen by the compiler is more like this:

    void fun(__Hidden)(transferRefness!(__Hidden, int)) {}

This, however, breaks for variadic templates, so is also not a real solution. All in all, there's no provision in the language today for explicitly instantiating auto ref functions, and no obvious point to extend to give this ability. A solution to this issue will likely require a DIP.

--
September 04, 2020
https://issues.dlang.org/show_bug.cgi?id=8204

Basile-z <b2.temp@gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |diagnostic
                 CC|                            |b2.temp@gmx.com

--- Comment #7 from Basile-z <b2.temp@gmx.com> ---
There are tricks to generate the ref version or not:

---
void foo(T)(ref auto T v)
{
    pragma(msg,__PRETTY_FUNCTION__);
}

alias intByVal = typeof(foo(0));
alias intByRef = typeof(foo(*new int));

struct S{}

alias sByVal = typeof(foo(S()));
alias sByRef = typeof(foo(*new S()));
---

> void runnable.foo!int.foo(int v)
> void runnable.foo!int.foo(ref int v)
> void runnable.foo!(S).foo(S v)
> void runnable.foo!(S).foo(ref S v)

But the error message is not encouraging.

--
September 04, 2020
https://issues.dlang.org/show_bug.cgi?id=8204

--- Comment #8 from Basile-z <b2.temp@gmx.com> ---
ignore my previous comment. Obviously the `typeof()` dont instanciate the
functions at all.

--
April 27, 2022
https://issues.dlang.org/show_bug.cgi?id=8204

--- Comment #9 from Basile-z <b2.temp@gmx.com> ---
why not just instantiate all possible permutations of by value / by ref in an overload set ?

--
April 28, 2022
https://issues.dlang.org/show_bug.cgi?id=8204

vitamin <submada@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |submada@gmail.com

--- Comment #10 from vitamin <submada@gmail.com> ---
This problem has become worst.

`auto ref` inference is no longer only problem. `scope` and `return` parameter storage classes inference has similar problem.

Example how inference differ from manual template instantion:
```d
void foo(T)(T* ptr){
}

ref T bar(T)(ref T val){
    static if(is(T == long))
        return *new T(val);
    else
        return val;
}


static long* global_ptr;

void main()@safe{

    {
        //void function(int* ptr) pure nothrow @nogc @safe:
        pragma(msg, typeof(&foo!int));

        //void function(int* ptr) pure nothrow @nogc @safe:
        foo(new int);
    }

    {
        //void function(int* ptr) pure nothrow @nogc @safe:
        pragma(msg, typeof(&foo!int));

        //void function(scope int* ptr) pure nothrow @nogc @safe:
        scope int* i;
        foo(i);
    }

    {
        //int function(ref int val) pure nothrow @nogc ref @safe:
        pragma(msg, typeof(&bar!int));

        //int function(return ref int val) pure nothrow @nogc ref @safe:
        scope int x;
        scope int* ptr = &bar(x);
    }
    {
        //long function(ref long val) pure nothrow ref @safe:
        pragma(msg, typeof(&bar!long));

        //long function(scope ref long val) pure nothrow ref @safe:
        scope long x;
        global_ptr = &bar(x);
    }
}
```

--
« First   ‹ Prev
1 2