www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Should this compile?

reply "tchaloupka" <chalucha gmail.com> writes:
import std.stdio;
import std.range : chain;

auto test(string a) {
     return test(a, "b");
}

auto test(string a, string b) {
     return chain(a, b);
}

void main() {
     writeln(test(a));
}

Ends with: Error: forward reference to inferred return type of 
function call 'test'

I know this exact sample is solvable by default parameter but 
there are cases where it is not possible. What to do then?
Aug 25 2015
parent reply "Vladimir Panteleev" <thecybershadow.lists gmail.com> writes:
On Tuesday, 25 August 2015 at 18:19:40 UTC, tchaloupka wrote:
 import std.stdio;
 import std.range : chain;

 auto test(string a) {
     return test(a, "b");
 }

 auto test(string a, string b) {
     return chain(a, b);
 }

 void main() {
     writeln(test(a));
 }

 Ends with: Error: forward reference to inferred return type of 
 function call 'test'

 I know this exact sample is solvable by default parameter but 
 there are cases where it is not possible. What to do then?
I think this is a bug, but is easily worked around with: auto test(string a) { return .test(a, "b"); } I suspect that the reason the error occurs, is that the auto return type automatically rewrites the function declaration into an eponymous template declaration. Since this creates a new naming scope, "test" by itself will only match the declaration inside the eponymous template. Forcing the compiler to look on the module level will force it to perform overload resolution.
Aug 25 2015
next sibling parent "tchaloupka" <chalucha gmail.com> writes:
On Tuesday, 25 August 2015 at 18:29:08 UTC, Vladimir Panteleev 
wrote:
 I think this is a bug, but is easily worked around with:

 auto test(string a) {
     return .test(a, "b");
 }
Thanks, this worked. Filled it: https://issues.dlang.org/show_bug.cgi?id=14965
Aug 26 2015
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/25/2015 08:29 PM, Vladimir Panteleev wrote:
 I think this is a bug, but is easily worked around with:

 auto test(string a) {
      return .test(a, "b");
 }

 I suspect that the reason the error occurs, is that the auto return type
 automatically rewrites the function declaration into an eponymous
 template declaration.  ...
No true. In fact, doing so manually works around the problem. :o) This compiles and runs: import std.stdio; import std.range : chain; auto test()(string a) { return test(a,"b"); } auto test(string a,string b) { return chain(a,b); } void main() { writeln(test("a")); }
Aug 26 2015
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/26/2015 09:55 PM, Timon Gehr wrote:
 On 08/25/2015 08:29 PM, Vladimir Panteleev wrote:
 I think this is a bug, but is easily worked around with:

 auto test(string a) {
      return .test(a, "b");
 }

 I suspect that the reason the error occurs, is that the auto return type
 automatically rewrites the function declaration into an eponymous
 template declaration.  ...
No true. In fact, doing so manually works around the problem. :o) This compiles and runs: import std.stdio; import std.range : chain; auto test()(string a) { return test(a,"b"); } auto test(string a,string b) { return chain(a,b); } void main() { writeln(test("a")); }
Another workaround is to order the declarations in the opposite way: import std.stdio; import std.range : chain; auto test(string a,string b) { return chain(a,b); } auto test(string a) { return test(a,"b"); } void main() { writeln(test("a")); }
Aug 26 2015
parent "Meta" <jared771 gmail.com> writes:
On Wednesday, 26 August 2015 at 20:02:35 UTC, Timon Gehr wrote:
 Another workaround is to order the declarations in the opposite 
 way:

 import std.stdio;
 import std.range : chain;

 auto test(string a,string b) {
     return chain(a,b);
 }
 auto test(string a) {
     return test(a,"b");
 }
 void main() {
     writeln(test("a"));
 }
It's definitely a bug if the code is dependent on order of declaration.
Aug 26 2015