digitalmars.D.bugs - [Issue 19096] New: [REG 2.061] Proper error messages are not shown
- d-bugmail puremagic.com (97/97) Jul 18 2018 https://issues.dlang.org/show_bug.cgi?id=19096
https://issues.dlang.org/show_bug.cgi?id=19096 Issue ID: 19096 Summary: [REG 2.061] Proper error messages are not shown for templates that go beyond two deep, wrongly says no template overload matches Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: regression Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: dbugz joakim.fea.st I ran into this when refactoring std.conv.parse in Phobos and mistakenly had a variable shadowing another. Suddenly, ldc started telling me that none of the 11 overloads matched anymore, with no clue what I'd done wrong. I resorted to cutting and pasting the parse() function into a test file and removing all template arguments and constraints, after which the compiler pointed out the shadowed variable. I reduced that down to this code that shows the ins and outs: ``` import std.range.primitives, std.traits; Target parse(Target, Source)(ref Source source) if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum) && isFloatingPoint!Target && !is(Target == enum)) { bool anydigits = false; version(broken) { if ( anydigits ) { bool anydigits = true; } } return 3.14; } template isExactSomeString(T) { enum isExactSomeString = isSomeString!T && !is(T == enum); } private T toImpl(T, S)(S value) if (isInputRange!S && isSomeChar!(ElementEncodingType!S) && !isExactSomeString!T && is(typeof(parse!T(value)))) { bool anydigits = false; version(proper) { if ( anydigits ) { bool anydigits = true; } } return parse!T(value); } void main() { string foo = "3.14"; version(correct) parse!real(foo); else toImpl!real(foo); } ``` Ignoring all the version statements, this compiles fine with no shadowed variables with dmd 2.081.1 for linux/x64. If there's a shadowed variable in the toImpl() template called from main, enabled with `dmd -version=proper shadow.d`, I get this useful error message: frontend.d(32): Error: variable anydigits is shadowing variable frontend.toImpl!(real, string).toImpl.anydigits frontend.d(42): Error: template instance `frontend.toImpl!(real, string)` error instantiating However, if the shadowing problem goes two templates deep, enabled with `dmd -version=broken shadow.d`, I get this weird error, it claims no overloads match anymore: frontend.d(42): Error: template frontend.toImpl cannot deduce function from argument types !(real)(string), candidates are: frontend.d(23): frontend.toImpl(T, S)(S value) if (isInputRange!S && isSomeChar!(ElementEncodingType!S) && !isExactSomeString!T && is(typeof(parse!T(value)))) If I call that broken parse() template directly, enabled with `dmd -version=correct -version=broken shadow.d`, now I get a useful error again: frontend.d(12): Error: variable anydigits is shadowing variable frontend.parse!(real, string).parse.anydigits frontend.d(41): Error: template instance `frontend.parse!(real, string)` error instantiating This demonstrates how the frontend is throwing away the right error messages once templates start getting nested, which can be seen in the similar bug 9179 and bug 13340 also. run.dlang.io says this actually used to work up till dmd 2.061: https://run.dlang.io/is/DpqFeg Working with templates gets very annoying if it starts to gag these error messages. I'm not sure why it would do this: are there actually template overloads where multiple functions might work, so it just chooses the one that compiles? In this case, I think only one overload should match, so I want the error message for that one. --
Jul 18 2018