www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Deduction regression or improvement?

reply Johan Engelen <j j.nl> writes:
Hi all,
   Should the following compile or not?

auto foo(T)(T start, T end) {}
void main() {
     const SomeStruct a;
     SomeStruct b;
     foo(a,b);
}
See http://dpaste.dzfl.pl/15581af64747

DMD 2.068.2 compiles and does not complain.
DMD 2.069.2 gives deduction error: "cannot deduce function from 
argument types !()(const(SomeStruct), SomeStruct),   candidates 
are:  foo(T)(T start, T end)"

Is this a regression or intended?  I did not find something about 
it in the release notes.

Thanks,
   Johan
Mar 08 2016
next sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
On Tuesday, 8 March 2016 at 21:22:35 UTC, Johan Engelen wrote:
 Hi all,
   Should the following compile or not?

 auto foo(T)(T start, T end) {}
 void main() {
     const SomeStruct a;
     SomeStruct b;
     foo(a,b);
 }
 See http://dpaste.dzfl.pl/15581af64747

 DMD 2.068.2 compiles and does not complain.
 DMD 2.069.2 gives deduction error: "cannot deduce function from 
 argument types !()(const(SomeStruct), SomeStruct),   candidates 
 are:  foo(T)(T start, T end)"

 Is this a regression or intended?  I did not find something 
 about it in the release notes.

 Thanks,
   Johan
const T is not T Therefore this code shall not compile.
Mar 08 2016
prev sibling next sibling parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Tue, Mar 08, 2016 at 09:22:35PM +0000, Johan Engelen via Digitalmars-d wrote:
 Hi all,
   Should the following compile or not?
 
 auto foo(T)(T start, T end) {}
 void main() {
     const SomeStruct a;
     SomeStruct b;
     foo(a,b);
 }
 See http://dpaste.dzfl.pl/15581af64747
 
 DMD 2.068.2 compiles and does not complain.
 DMD 2.069.2 gives deduction error: "cannot deduce function from argument
 types !()(const(SomeStruct), SomeStruct),   candidates are:  foo(T)(T start,
 T end)"
 
 Is this a regression or intended?  I did not find something about it
 in the release notes.
[...] IMO, this *should* compile and infer T == const(SomeStruct) as the common type of a and b. But I'm not sure whether or not this is a regression. T -- If the comments and the code disagree, it's likely that *both* are wrong. -- Christopher
Mar 08 2016
next sibling parent reply Johan Engelen <j j.nl> writes:
On Tuesday, 8 March 2016 at 22:35:57 UTC, H. S. Teoh wrote:
 On Tue, Mar 08, 2016 at 09:22:35PM +0000, Johan Engelen via 
 Digitalmars-d wrote:
 Hi all,
   Should the following compile or not?
 
 auto foo(T)(T start, T end) {}
 void main() {
     const SomeStruct a;
     SomeStruct b;
     foo(a,b);
 }
 See http://dpaste.dzfl.pl/15581af64747
 
 DMD 2.068.2 compiles and does not complain.
 DMD 2.069.2 gives deduction error: "cannot deduce function 
 from argument
 types !()(const(SomeStruct), SomeStruct),   candidates are:  
 foo(T)(T start,
 T end)"
 
 Is this a regression or intended?  I did not find something 
 about it in the release notes.
[...] IMO, this *should* compile and infer T == const(SomeStruct) as the common type of a and b. But I'm not sure whether or not this is a regression.
What was surprising to me is that 2.068.2 deduces T = SomeStruct. But SomeStruct c = a; works fine, i.e. copying const(SomeStruct) to a SomeStruct is fine. Argument passing a struct is just copying, so should be fine to deduce T=SomeStruct? ( it may help to play a little with the linked code at dpaste.dzfl.pl )
Mar 08 2016
parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Tue, Mar 08, 2016 at 11:31:54PM +0000, Johan Engelen via Digitalmars-d wrote:
 On Tuesday, 8 March 2016 at 22:35:57 UTC, H. S. Teoh wrote:
On Tue, Mar 08, 2016 at 09:22:35PM +0000, Johan Engelen via Digitalmars-d
wrote:
Hi all,
  Should the following compile or not?

auto foo(T)(T start, T end) {}
void main() {
    const SomeStruct a;
    SomeStruct b;
    foo(a,b);
}
[...]
IMO, this *should* compile and infer T == const(SomeStruct) as the
common type of a and b.  But I'm not sure whether or not this is a
regression.
What was surprising to me is that 2.068.2 deduces T = SomeStruct. But SomeStruct c = a; works fine, i.e. copying const(SomeStruct) to a SomeStruct is fine. Argument passing a struct is just copying, so should be fine to deduce T=SomeStruct?
[...] Hmm. I guess it makes sense if SomeStruct has no indirections, since structs are value types so you can always copy a const value to a mutable variable / parameter. T -- It is of the new things that men tire --- of fashions and proposals and improvements and change. It is the old things that startle and intoxicate. It is the old things that are young. -- G.K. Chesterton
Mar 08 2016
prev sibling next sibling parent reply Meta <jared771 gmail.com> writes:
On Tuesday, 8 March 2016 at 22:35:57 UTC, H. S. Teoh wrote:
 IMO, this *should* compile and infer T == const(SomeStruct) as 
 the common type of a and b.  But I'm not sure whether or not 
 this is a regression.
Does template type inference do implicit conversion? I thought it did not, and thus would expect this example to not compile.
Mar 09 2016
parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Wed, Mar 09, 2016 at 02:42:51PM +0000, Meta via Digitalmars-d wrote:
 On Tuesday, 8 March 2016 at 22:35:57 UTC, H. S. Teoh wrote:
IMO, this *should* compile and infer T == const(SomeStruct) as the
common type of a and b.  But I'm not sure whether or not this is a
regression.
Does template type inference do implicit conversion? I thought it did not, and thus would expect this example to not compile.
[...] Hmm. I tried a little test, which revealed something interesting: class A {} class B : A {} class C : A {} void func(T)(T a, T b) {} void main() { auto x = new A; auto y = new B; auto z = new C; func(x,y); // OK func(x,z); // OK func(y,z); // compile error func(y,x); // OK func(z,x); // OK func(z,y); // compile error } It seems like *some* kind of implicit conversion is happening, because the compiler is able to figure out, in the case where one of the arguments is the base class, that it should convert the other argument to the base class. However, it doesn't seem to be able to figure out the case where neither argument is the base class, even though both does share the same base class. Arguably, this could be construed to be a bug / enhancement request? It does seem to imply that IFTI does include some form of implicit conversion check, though. T -- If you think you are too small to make a difference, try sleeping in a closed room with a mosquito. -- Jan van Steenbergen
Mar 09 2016
prev sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Tuesday, 8 March 2016 at 22:35:57 UTC, H. S. Teoh wrote:
 On Tue, Mar 08, 2016 at 09:22:35PM +0000, Johan Engelen via 
 Digitalmars-d wrote:
 Hi all,
   Should the following compile or not?
 
 auto foo(T)(T start, T end) {}
 void main() {
     const SomeStruct a;
     SomeStruct b;
     foo(a,b);
 }
 See http://dpaste.dzfl.pl/15581af64747
 
 DMD 2.068.2 compiles and does not complain.
 DMD 2.069.2 gives deduction error: "cannot deduce function 
 from argument
 types !()(const(SomeStruct), SomeStruct),   candidates are:  
 foo(T)(T start,
 T end)"
 
 Is this a regression or intended?  I did not find something 
 about it in the release notes.
[...] IMO, this *should* compile and infer T == const(SomeStruct) as the common type of a and b. But I'm not sure whether or not this is a regression. T
More tricky actually. If T has indirection, then that is the correct answer. If not, the T == SomeStruct.
Mar 11 2016
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 12.03.2016 08:58, deadalnix wrote:
 IMO, this *should* compile and infer T == const(SomeStruct) as the
 common type of a and b.  But I'm not sure whether or not this is a
 regression.


 T
More tricky actually. If T has indirection, then that is the correct answer. If not, the T == SomeStruct.
Actually the documentation currently special-cases pointers and arrays: "The deduced type parameter for dynamic array and pointer arguments has an unqualified head:" http://dlang.org/spec/template.html#function-templates
Mar 12 2016
prev sibling parent reply Dicebot <public dicebot.lv> writes:
On 03/08/2016 11:22 PM, Johan Engelen wrote:
 Hi all,
   Should the following compile or not?
 
 auto foo(T)(T start, T end) {}
 void main() {
     const SomeStruct a;
     SomeStruct b;
     foo(a,b);
 }
 See http://dpaste.dzfl.pl/15581af64747
 
 DMD 2.068.2 compiles and does not complain.
 DMD 2.069.2 gives deduction error: "cannot deduce function from argument
 types !()(const(SomeStruct), SomeStruct),   candidates are:  foo(T)(T
 start, T end)"
 
 Is this a regression or intended?  I did not find something about it in
 the release notes.
 
 Thanks,
   Johan
 
 
 
Looks like regression to me. If SomeStruct contains indirections, it should be able to deduce T as const(SomeStruct). It SomeStruct is strict value type, deducing T as both SomeStruct and const(SomeStruct) would be fine.
Mar 08 2016
next sibling parent Johan Engelen <j j.nl> writes:
I've reported it here:
https://issues.dlang.org/show_bug.cgi?id=15781
Mar 09 2016
prev sibling parent reply Hara Kenji <k.hara.pg gmail.com> writes:
On Wednesday, 9 March 2016 at 01:27:41 UTC, Dicebot wrote:
 Looks like regression to me.

 If SomeStruct contains indirections, it should be able to 
 deduce T as
 const(SomeStruct).

 It SomeStruct is strict value type, deducing T as both 
 SomeStruct and const(SomeStruct) would be fine.
But the behavior with 2.068 was bug-prone. struct S { int value; } auto foo(T)(T start, T end) { pragma(msg, "In foo, T = ", T); } void main() { const S cs; S ms; foo(cs, ms); // [a] NG with 2.069.2, but T == S with 2.068! foo(ms, cs); // [b] NG with 2.069.2, but T == const(S) with 2.068!! } The both cases are disabled in the bugfix PR: https://github.com/D-Programming-Language/dmd/pull/4818 I think that T should be deduced to the typeof(true ? cs : ms) at line [a] and typeof(true ? ms : cs) at line [b], then the two lines will get consistent deduction result T == const(S). Kenji Hara
Mar 11 2016
next sibling parent Johan Engelen <j j.nl> writes:
On Friday, 11 March 2016 at 13:28:22 UTC, Hara Kenji wrote:
 I think that T should be deduced to the typeof(true ? cs : ms) 
 at line [a] and typeof(true ? ms : cs) at line [b], then the 
 two lines will get consistent deduction result T == const(S).
I also thought it should deduce T == const(S), and was surprised 2.068.2 deduced it without const.
Mar 11 2016
prev sibling parent Dicebot <public dicebot.lv> writes:
On Friday, 11 March 2016 at 13:28:22 UTC, Hara Kenji wrote:
 On Wednesday, 9 March 2016 at 01:27:41 UTC, Dicebot wrote:

 The both cases are disabled in the bugfix PR:
 https://github.com/D-Programming-Language/dmd/pull/4818

 I think that T should be deduced to the typeof(true ? cs : ms) 
 at line [a] and typeof(true ? ms : cs) at line [b], then the 
 two lines will get consistent deduction result T == const(S).

 Kenji Hara
Sorry, but to me this "fix" looks like harmful regression that needs to be reverted. Bug prone or not it breaks valid good code without deprecation process.
Mar 11 2016