www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Bug in D type inferencing

reply Hiemlick Hiemlicker <HH reign.com> writes:
public struct Foo
{
	public void Create(T)(uint delegate(T) c, T param)
	{	
	}
}

Foo f;

f.Create((x) { }, "asdf");

cannot deduce arguments compiler error.

Surely D can figure out that T is a string?

If one simply changes this to

public struct Foo(T)
{
	public void Create(uint delegate(T) c, T param)
	{	
	}
}

and

Foo!string f;

everything works.

The second parameter is a string so why not infer that T is a 
string?

Also, if one does

f.Create((string x) { }, "asdf");

Then it works. Seems like a blatant limitation in D's type 
inferencing system.
Jul 01 2016
next sibling parent Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Saturday, 2 July 2016 at 01:20:35 UTC, Hiemlick Hiemlicker 
wrote:
 public struct Foo
 {
 	public void Create(T)(uint delegate(T) c, T param)
 	{	
 	}
 }

 Foo f;

 f.Create((x) { }, "asdf");
I'm a D noob so take it with a very big grain of salt, but I think that expression is wrong already on the level of the syntax. In your expression x doesn't have any type, neither explicit nor deduced. I suppose that something like that could work: f.Create((auto x) { }, "asdf"); // verbose syntax
 cannot deduce arguments compiler error.

 Surely D can figure out that T is a string?

 If one simply changes this to

 public struct Foo(T)
 {
 	public void Create(uint delegate(T) c, T param)
 	{	
 	}
 }

 and

 Foo!string f;

 everything works.

 The second parameter is a string so why not infer that T is a 
 string?

 Also, if one does

 f.Create((string x) { }, "asdf");
Here x has a type and the definition is syntactically correct.
 Then it works. Seems like a blatant limitation in D's type 
 inferencing system.
Jul 02 2016
prev sibling parent reply John Colvin <john.loughran.colvin gmail.com> writes:
On Saturday, 2 July 2016 at 01:20:35 UTC, Hiemlick Hiemlicker 
wrote:
 public struct Foo
 {
 	public void Create(T)(uint delegate(T) c, T param)
 	{	
 	}
 }

 Foo f;

 f.Create((x) { }, "asdf");

 cannot deduce arguments compiler error.

 Surely D can figure out that T is a string?

 If one simply changes this to

 public struct Foo(T)
 {
 	public void Create(uint delegate(T) c, T param)
 	{	
 	}
 }

 and

 Foo!string f;

 everything works.

 The second parameter is a string so why not infer that T is a 
 string?

 Also, if one does

 f.Create((string x) { }, "asdf");

 Then it works. Seems like a blatant limitation in D's type 
 inferencing system.
Those lambdas don't return uint, they return void, so they could never match anyway. Here's a simple example showing the problem I think you are getting at: void create(T)(void delegate(T) c, T param) {} void main() { // create((x){}, "fdsa"); // can't deduce create!string((x){},"fdsa"); // OK create((string x){},"fdsa"); // OK } I don't know how difficult it would be to make this work, but you could definitely file an enhancement request for it at issues.dlang.org
Jul 02 2016
parent Hiemlick Hiemlicker <HH reign.com> writes:
On Saturday, 2 July 2016 at 08:02:30 UTC, John Colvin wrote:
 On Saturday, 2 July 2016 at 01:20:35 UTC, Hiemlick Hiemlicker 
 wrote:
 public struct Foo
 {
 	public void Create(T)(uint delegate(T) c, T param)
 	{	
 	}
 }

 Foo f;

 f.Create((x) { }, "asdf");

 cannot deduce arguments compiler error.

 Surely D can figure out that T is a string?

 If one simply changes this to

 public struct Foo(T)
 {
 	public void Create(uint delegate(T) c, T param)
 	{	
 	}
 }

 and

 Foo!string f;

 everything works.

 The second parameter is a string so why not infer that T is a 
 string?

 Also, if one does

 f.Create((string x) { }, "asdf");

 Then it works. Seems like a blatant limitation in D's type 
 inferencing system.
Those lambdas don't return uint, they return void, so they could never match anyway. Here's a simple example showing the problem I think you are getting at: void create(T)(void delegate(T) c, T param) {} void main() { // create((x){}, "fdsa"); // can't deduce create!string((x){},"fdsa"); // OK create((string x){},"fdsa"); // OK } I don't know how difficult it would be to make this work, but you could definitely file an enhancement request for it at issues.dlang.org
Well, I guess I should have put a return in the code on the mock up so it wouldn't be taken literal. The point is, the second argument is definitely a string, is it not? So the compiler should be able to deduce that T is a string, should it not? Regardless of what the delegate does.
Jul 02 2016