Thread overview
[Issue 17036] Template default parameter does not works correctly
[Issue 17036] Template default parametr does not works correctly
Dec 27, 2016
Daniel Kozak
Jan 04, 2017
Daniel Kozak
Jan 28, 2018
Seb
Dec 17, 2022
Iain Buclaw
December 27, 2016
https://issues.dlang.org/show_bug.cgi?id=17036

Daniel Kozak <kozzi11@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                URL|                            |http://stackoverflow.com/qu
                   |                            |estions/41346661/creating-n
                   |                            |ew-types-using-typedef-on-v
                   |                            |ibe-data-json-json-implicit
                   |                            |-conversion-err

--
January 04, 2017
https://issues.dlang.org/show_bug.cgi?id=17036

bitter.taste@gmx.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bitter.taste@gmx.com

--- Comment #1 from bitter.taste@gmx.com ---
---
struct S0
{
    void x[1];
}
pragma(msg, S0.init);
---

As you can see this outputs `S0([cast(ubyte)0u]`, let's assume that the
compiler is right and try using that value as initializer

---
auto x = S0([cast(ubyte)0u]; // and I thought you couldn't cast a ubyte into a
void
---

gives a fairly explicative error, which is what one would rightfully expect

---
cannot implicitly convert expression ([cast(ubyte)0u]) of type ubyte[] to
void[1]
---

on the other hand using the `.init` directly works perfectly..isn't that weird ?

---
auto x = S0.init; // works
---

Let's take a step back, where's the initializer coming from? Here it is [1],
you sneaky bastard! So what happens here is that a zero-initialized TypeSArray
is created with a void[1] type bolted on, the trick falls short when the struct
initializer (the aforementioned `S0([cast(ubyte)0u]` that now has a S0(void[1])
type) is run trough dtemplate `matchArg` and trough the CTFE engine where
nothing is done beside losing our bolted-on type.
What happens next is where the error originates, the new initializer gets
trough the semantic phase

---
ArrayLiteralExp::semantic('[cast(ubyte)0u]')
---

if you're familiar with the inner workings I'll also add that `type` is null right now and the deduced type is `ubyte[]` which is the technically right answer but the wrong one in this context. ugh.

Here's where the shit hits the fan

---
ArrayLiteralExp::implicitConvTo(this=[cast(ubyte)0u], type=ubyte[], t=void[1])
TypeDArray::implicitConvTo(to = void[1]) this = ubyte[]
---

What to do? One could try not to lose the hacked-up type of the array, relax the rules for casts to `void[N]`, emit a `void` initializer instead of a zeroing the array (which is what one would expect since void has no default initializer), hope for the best, use another lang^Hthat's it!

[1] https://github.com/dlang/dmd/blob/master/src/mtype.d#L5040

--
January 04, 2017
https://issues.dlang.org/show_bug.cgi?id=17036

--- Comment #2 from Daniel Kozak <kozzi11@gmail.com> ---
yeah I am aware of all of this, but in all other cases(context) it is legal to do this cast. It is even legal by language specification if I remember it correctly.

I would fix it by myself but thera are many ways to fix this and i am not sure which way is the best, so I hope someone with more skill try to fix it or propose some solution or direction

--
January 28, 2018
https://issues.dlang.org/show_bug.cgi?id=17036

Seb <greensunny12@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |greensunny12@gmail.com
            Summary|Template default parametr   |Template default parameter
                   |does not works correctly    |does not works correctly

--- Comment #3 from Seb <greensunny12@gmail.com> ---
Here's another example:


```
struct Foo {}
struct Bar {}

Foo foo;

void myFun(D)(D d = foo){}

void bar()
{
    myFun(); // works
    myFun(Bar()); // error
}
```

--
January 28, 2018
https://issues.dlang.org/show_bug.cgi?id=17036

hsteoh@quickfur.ath.cx changed:

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

--- Comment #4 from hsteoh@quickfur.ath.cx ---
Related:
https://issues.dlang.org/show_bug.cgi?id=16467
https://issues.dlang.org/show_bug.cgi?id=17186

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

Iain Buclaw <ibuclaw@gdcproject.org> changed:

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

--
December 13
https://issues.dlang.org/show_bug.cgi?id=17036

--- Comment #5 from dlangBugzillaToGithub <robert.schadek@posteo.de> ---
THIS ISSUE HAS BEEN MOVED TO GITHUB

https://github.com/dlang/dmd/issues/19220

DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB

--