May 14, 2013
>
> I think that should be consistent with the deduction mechanism proposed
>> in the DIP: foo is struct not in scope until template foo(T) is
>> instantiated.
>>
>

>  No it is not. The DIP states "find all constructors".


it said  'Find all matching class/struct types in scope', isn't that enough or am I missing something?

To clarify, I've added 3 out of scope structs named A in the example section to clarify that they won't be included in the overload set. see the ones marked '//not in scope'


May 14, 2013
On Tuesday, 14 May 2013 at 07:28:57 UTC, Timothee Cour wrote:
>>
>> I think that should be consistent with the deduction mechanism proposed
>>> in the DIP: foo is struct not in scope until template foo(T) is
>>> instantiated.
>>>
>>
>
>>  No it is not. The DIP states "find all constructors".
>
>
> it said  'Find all matching class/struct types in scope', isn't that enough
> or am I missing something?
>
> To clarify, I've added 3 out of scope structs named A in the example
> section to clarify that they won't be included in the overload set.
> see the ones marked '//not in scope'

I think the best here is to specify that the rule is the same than eponymous funtion and IFTY. Otherwise we'll have 2 different specs with small difference here and there. And that sucks.
May 14, 2013
On 05/14/2013 10:04 AM, deadalnix wrote:
> On Tuesday, 14 May 2013 at 07:28:57 UTC, Timothee Cour wrote:
>>>
>>> I think that should be consistent with the deduction mechanism proposed
>>>> in the DIP: foo is struct not in scope until template foo(T) is
>>>> instantiated.
>>>>
>>>
>>
>>>  No it is not. The DIP states "find all constructors".
>>
>>
>> it said  'Find all matching class/struct types in scope', isn't that
>> enough
>> or am I missing something?
>>
>> To clarify, I've added 3 out of scope structs named A in the example
>> section to clarify that they won't be included in the overload set.
>> see the ones marked '//not in scope'
>
> I think the best here is to specify that the rule is the same than
> eponymous funtion and IFTY. Otherwise we'll have 2 different specs with
> small difference here and there. And that sucks.

There is no spec for the IFTI case. (i.e. what happens if the eponymous declaration inside the template is an overload set?)
May 14, 2013
On 05/14/2013 09:28 AM, Timothee Cour wrote:
>         I think that should be consistent with the deduction mechanism
>         proposed
>         in the DIP: foo is struct not in scope until template foo(T) is
>         instantiated.
>
>     No it is not. The DIP states "find all constructors".
>
>
> it said  'Find all matching class/struct types in scope', isn't that
> enough or am I missing something?
>

Apparently. The point is that it is not always possible to determine all constructors before the template is instantiated. The DIP must state when and how it works and what happens if it does not.

> To clarify, I've added 3 out of scope structs named A in the example
> section to clarify that they won't be included in the overload set.
> see the ones marked '//not in scope'
>

I don't get this. (Also, why is it relevant to the discussion?)

The following declaration:

template A(T1){
struct A{ //not in scope unless T1 is explicitly instantiated
    this()(T1 a) {}
}
}

Is the same declaration, modulo constraint, as the preceding

struct A(T1)
if (!isNumeric!T1)
{
    this()(T1 a) {}
}


May 14, 2013
On Tuesday, 14 May 2013 at 09:30:01 UTC, Timon Gehr wrote:
> There is no spec for the IFTI case. (i.e. what happens if the eponymous declaration inside the template is an overload set?)

I know, but solving one problem at a time usual lead to better result than all at once.
May 14, 2013
On 05/14/2013 11:30 AM, Timon Gehr wrote:
> On 05/14/2013 10:04 AM, deadalnix wrote:
>> On Tuesday, 14 May 2013 at 07:28:57 UTC, Timothee Cour wrote:
>>>>
>>>> I think that should be consistent with the deduction mechanism proposed
>>>>> in the DIP: foo is struct not in scope until template foo(T) is
>>>>> instantiated.
>>>>>
>>>>
>>>
>>>>  No it is not. The DIP states "find all constructors".
>>>
>>>
>>> it said  'Find all matching class/struct types in scope', isn't that
>>> enough
>>> or am I missing something?
>>>
>>> To clarify, I've added 3 out of scope structs named A in the example
>>> section to clarify that they won't be included in the overload set.
>>> see the ones marked '//not in scope'
>>
>> I think the best here is to specify that the rule is the same than
>> eponymous funtion and IFTY. Otherwise we'll have 2 different specs with
>> small difference here and there. And that sucks.
>
> There is no spec for the IFTI case. (i.e. what happens if the eponymous
> declaration inside the template is an overload set?)

DMD's strategy is roughly: use the first eponymous declaration that can be found without analysing the template body for IFTI, then use the first eponymous declaration in the analyzed template body to resolve the eponymous declaration after instantiation.

---
import std.stdio;
template fun(T){
	int fun(double arg){ return 1; }
	int fun(T arg){ return 0; }
}
void main(){ writeln(fun(2)); } // error

---
import std.stdio;
template fun(T){
	int fun(T arg){ return 0; }
	int fun(double arg){ return 1; }
}
void main(){ writeln(fun(2)); } // ok

---

This has funny implications, as the compiler may decide to resolve to a different declaration than was used for IFTI later, without doing any kind of overload resolution within the template body.

---
template fun(T){
	int fun(T arg){ return 0; }
	static if(true) int fun(double arg){ return 1; }
}
pragma(msg, fun(2)); // 0
---
template fun(T){
	static if(true) int fun(double arg){ return 1; }
	int fun(T arg){ return 0; }
}
pragma(msg, fun(2)); // 1
---

In the second case, instantiation is performed with the second function, so T is resolved to 'int', but in the end, the 'double' overload is called with an implicit conversion.


May 14, 2013
On Tuesday, 14 May 2013 at 09:56:14 UTC, Timon Gehr wrote:
> DMD's strategy is roughly: use the first eponymous declaration that can be found without analysing the template body for IFTI, then use the first eponymous declaration in the analyzed template body to resolve the eponymous declaration after instantiation.
>
> ---
> import std.stdio;
> template fun(T){
> 	int fun(double arg){ return 1; }
> 	int fun(T arg){ return 0; }
> }
> void main(){ writeln(fun(2)); } // error
>
> ---
> import std.stdio;
> template fun(T){
> 	int fun(T arg){ return 0; }
> 	int fun(double arg){ return 1; }
> }
> void main(){ writeln(fun(2)); } // ok
>
> ---
>
> This has funny implications, as the compiler may decide to resolve to a different declaration than was used for IFTI later, without doing any kind of overload resolution within the template body.
>
> ---
> template fun(T){
> 	int fun(T arg){ return 0; }
> 	static if(true) int fun(double arg){ return 1; }
> }
> pragma(msg, fun(2)); // 0
> ---
> template fun(T){
> 	static if(true) int fun(double arg){ return 1; }
> 	int fun(T arg){ return 0; }
> }
> pragma(msg, fun(2)); // 1
> ---
>
> In the second case, instantiation is performed with the second function, so T is resolved to 'int', but in the end, the 'double' overload is called with an implicit conversion.

That creative. But completely b0rken IMO
May 14, 2013
2013/5/14 Timon Gehr <timon.gehr@gmx.ch>

> On 05/14/2013 11:30 AM, Timon Gehr wrote:
>
>> On 05/14/2013 10:04 AM, deadalnix wrote:
>>
>>> On Tuesday, 14 May 2013 at 07:28:57 UTC, Timothee Cour wrote:
>>>
>>>>
>>>>> I think that should be consistent with the deduction mechanism proposed
>>>>>
>>>>>> in the DIP: foo is struct not in scope until template foo(T) is
>>>>>> instantiated.
>>>>>>
>>>>>>
>>>>>
>>>>   No it is not. The DIP states "find all constructors".
>>>>>
>>>>
>>>>
>>>> it said  'Find all matching class/struct types in scope', isn't that
>>>> enough
>>>> or am I missing something?
>>>>
>>>> To clarify, I've added 3 out of scope structs named A in the example section to clarify that they won't be included in the overload set. see the ones marked '//not in scope'
>>>>
>>>
>>> I think the best here is to specify that the rule is the same than eponymous funtion and IFTY. Otherwise we'll have 2 different specs with small difference here and there. And that sucks.
>>>
>>
>> There is no spec for the IFTI case. (i.e. what happens if the eponymous declaration inside the template is an overload set?)
>>
>
> DMD's strategy is roughly: use the first eponymous declaration that can be found without analysing the template body for IFTI, then use the first eponymous declaration in the analyzed template body to resolve the eponymous declaration after instantiation.
>
> ---
> import std.stdio;
> template fun(T){
>         int fun(double arg){ return 1; }
>         int fun(T arg){ return 0; }
> }
> void main(){ writeln(fun(2)); } // error
>
> ---
> import std.stdio;
> template fun(T){
>         int fun(T arg){ return 0; }
>         int fun(double arg){ return 1; }
> }
> void main(){ writeln(fun(2)); } // ok
>
> ---
>
> This has funny implications, as the compiler may decide to resolve to a different declaration than was used for IFTI later, without doing any kind of overload resolution within the template body.
>
> ---
> template fun(T){
>         int fun(T arg){ return 0; }
>         static if(true) int fun(double arg){ return 1; }
> }
> pragma(msg, fun(2)); // 0
> ---
> template fun(T){
>         static if(true) int fun(double arg){ return 1; }
>         int fun(T arg){ return 0; }
> }
> pragma(msg, fun(2)); // 1
> ---
>
> In the second case, instantiation is performed with the second function, so T is resolved to 'int', but in the end, the 'double' overload is called with an implicit conversion.
>

Current dmd behavior is definitely a bug. Could you please file it in bugzilla?

Kenji Hara


May 14, 2013
On 05/14/2013 05:08 PM, Kenji Hara wrote:
> ...
>
> Current dmd behavior is definitely a bug. Could you please file it in
> bugzilla?
> ...

http://d.puremagic.com/issues/show_bug.cgi?id=10083

May 16, 2013
ok Hara Kenji just fixed the bug, see https://github.com/D-Programming-Language/dmd/pull/2041

So what's left unspecified now wrt DIP40?

My proposal was to just address case C2 below, not C1 (at least initially):

case C1:
template A(T1) {struct A{  this()(T1 a) {} }}

case C2:
struct A(T1){     this()(T1 a) {}}

Even though struct A(T1) may internally be implemented as template A(T1), I
think the most useful / less problematic conversion is just case C2.
In other words, as i said before, the constructors inside a template (as in
case C1) would note be considered as part of the overload set for this
DIP40 (at least initially).


On Tue, May 14, 2013 at 12:02 PM, Timon Gehr <timon.gehr@gmx.ch> wrote:

> On 05/14/2013 05:08 PM, Kenji Hara wrote:
>
>> ...
>>
>>
>> Current dmd behavior is definitely a bug. Could you please file it in
>> bugzilla?
>> ...
>>
>
> http://d.puremagic.com/issues/**show_bug.cgi?id=10083<http://d.puremagic.com/issues/show_bug.cgi?id=10083>
>
>