digitalmars.D - Potential issue with DMD where the template constrains are not
- Georgi D (51/51) May 13 2016 Hi,
- Timon Gehr (29/57) May 13 2016 It's tricky. The reason it fails to compile is that the template
- Georgi D (3/9) May 17 2016 Should I open a PR in bugzilla for this?
- Hara Kenji (5/16) May 18 2016 Done.
- Georgi D (2/20) May 18 2016 Thanks, Great work!
Hi, I have the following code which should compile in my opinion: struct Foo {} import std.range.primitives; import std.algorithm.iteration : map, joiner; auto toChars(R)(R r) if (isInputRange!R) { return r.map!(toChars).joiner(", "); } auto toChars(Foo f) { import std.range : chain; return chain("foo", "bar"); } void main() { import std.range : repeat; Foo f; auto r = f.repeat(3); auto chars = r.toChars(); } But fails to compile with the following error: Error: template instance std.algorithm.iteration.MapResult!(toChars, Take!(Repeat!(Foo))) forward reference of function toChars The reason it fails to compile in my opinion is that the template constraint fails to remove the generic toChars from the list possible matches early enough so the compiler thinks there is a recursive call and cannot deduce the return type. Just changing the name of the generic toChars to anything else makes the code compile: struct Foo {} import std.range.primitives; import std.algorithm.iteration : map, joiner; auto toCharsRange(R)(R r) if (isInputRange!R) { return r.map!(toChars).joiner(", "); } auto toChars(Foo f) { import std.range : chain; return chain("foo", "bar"); } void main() { import std.range : repeat; Foo f; auto r = f.repeat(3); auto chars = r.toCharsRange(); } Compiles just fine.
May 13 2016
On 13.05.2016 23:21, Georgi D wrote:Hi, I have the following code which should compile in my opinion: struct Foo {} import std.range.primitives; import std.algorithm.iteration : map, joiner; auto toChars(R)(R r) if (isInputRange!R) { return r.map!(toChars).joiner(", "); } auto toChars(Foo f) { import std.range : chain; return chain("foo", "bar"); } void main() { import std.range : repeat; Foo f; auto r = f.repeat(3); auto chars = r.toChars(); } But fails to compile with the following error: Error: template instance std.algorithm.iteration.MapResult!(toChars, Take!(Repeat!(Foo))) forward reference of function toChars The reason it fails to compile in my opinion is that the template constraint fails to remove the generic toChars from the list possible matches early enough so the compiler thinks there is a recursive call and cannot deduce the return type.It's tricky. The reason it fails to compile is that the template argument you are passing does not actually refer to the overload set. return r.map!(.toChars).joiner(", "); works. Consider: int foo()(){ pragma(msg, typeof(&foo)); // int function() return 2; } double foo(){ return foo!(); } The reason for this behavior is that the first declaration is syntactic sugar for: template foo(){ int foo(){ pragma(msg, typeof(&foo)); return 2; } } Since template foo() introduces a scope, the inner 'int foo()' shadows the outer 'double foo()'. There are special cases in the compiler that reverse eponymous lookup before overload resolution (i.e. go from foo!().foo back to foo) in case some identifier appears in the context ident() or ident!(), so one does not usually run into this. This is not done for alias parameters. The error message is bad though. Also, I think it is not unreasonable to expect the code to work. Maybe reversal of eponymous lookup should be done for alias parameters too.
May 13 2016
On Friday, 13 May 2016 at 23:31:00 UTC, Timon Gehr wrote:On 13.05.2016 23:21, Georgi D wrote:Should I open a PR in bugzilla for this? Thanks[...]It's tricky. The reason it fails to compile is that the template argument you are passing does not actually refer to the overload set. [...]
May 17 2016
On Tuesday, 17 May 2016 at 21:48:55 UTC, Georgi D wrote:On Friday, 13 May 2016 at 23:31:00 UTC, Timon Gehr wrote:Done. https://issues.dlang.org/show_bug.cgi?id=16042 https://github.com/dlang/dmd/pull/5794 Kenji HaraOn 13.05.2016 23:21, Georgi D wrote:Should I open a PR in bugzilla for this? Thanks[...]It's tricky. The reason it fails to compile is that the template argument you are passing does not actually refer to the overload set. [...]
May 18 2016
On Wednesday, 18 May 2016 at 12:02:13 UTC, Hara Kenji wrote:On Tuesday, 17 May 2016 at 21:48:55 UTC, Georgi D wrote:Thanks, Great work!On Friday, 13 May 2016 at 23:31:00 UTC, Timon Gehr wrote:Done. https://issues.dlang.org/show_bug.cgi?id=16042 https://github.com/dlang/dmd/pull/5794 Kenji HaraOn 13.05.2016 23:21, Georgi D wrote:Should I open a PR in bugzilla for this? Thanks[...]It's tricky. The reason it fails to compile is that the template argument you are passing does not actually refer to the overload set. [...]
May 18 2016