Bug 16484 – regression(2.064) Overloaded empty funcs trigger AssertError: "Called `get' on null Nullable"

Status
RESOLVED
Resolution
WONTFIX
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2016-09-09T18:31:06Z
Last change time
2022-01-21T11:59:52Z
Assigned to
No Owner
Creator
Nick Sabalausky

Comments

Comment #0 by bus_dbugzilla — 2016-09-09T18:31:06Z
----------------------------------- $ cat test.d import std.typecons; void foo(T)(Nullable!T value) { } void foo()(int i) { } void main() { Nullable!int x; foo(x); } $ dmd -run test.d core.exception.AssertError@/home/nick/.dvm/compilers/dmd-2.071.1/linux/bin/../../src/phobos/std/typecons.d(2075): Called `get' on null Nullable!int. ----------------------------------- WTF?!?!? Removing the "int" overload makes the error go away.
Comment #1 by bus_dbugzilla — 2016-09-09T18:37:39Z
Problem appears to have been introduced in 2.064
Comment #2 by ag0aep6g — 2016-09-09T18:55:05Z
Without phobos: ---- struct Nullable(T) { T x; alias x this; } void foo(T)(Nullable!T value) {} void foo()(int i) { assert(false); /* hit */ } void main() { foo(Nullable!int()); } ---- The second overload being selected is surprising, because it involves an implicit conversion whereas the first overload would be an exact match. I can't find anything in the spec about how IFTI interacts with overloading.
Comment #3 by bugzilla — 2016-10-13T23:48:39Z
(In reply to ag0aep6g from comment #2) > void foo(T)(Nullable!T value) {} Considered: "match with conversion for initial template arguments" "exact match for inferred template arguments" > void foo()(int i) { assert(false); /* hit */ } Considered: "exact match for initial template arguments" "exact match for inferred template arguments" And so the second match is better. The relevant line in the source code is "matchTiargs = MATCHconvert;" at: https://github.com/dlang/dmd/blob/master/src/dtemplate.d#L1916 This is because the parameter 'T' is deduced from argument 'Nullable!int', rather than being supplied directly. Whether this is correct or not is debatable, I think the template rules are excessively complex, but they are the result of constant complaints and revision. I am extremely reluctant to change them further, because that will inevitably result in hard-to-explain breakage, like this one, which was apparently introduced in 2.064. If someone wants to find the specific PR that did it, I'd appreciate it.
Comment #4 by bugzilla — 2016-10-13T23:56:37Z
Comment #5 by ag0aep6g — 2016-10-14T05:25:55Z
(In reply to Walter Bright from comment #3) > (In reply to ag0aep6g from comment #2) > > void foo(T)(Nullable!T value) {} > > Considered: > "match with conversion for initial template arguments" Here "with conversion" means that it needs template argument inference, right? > "exact match for inferred template arguments" > > > void foo()(int i) { assert(false); /* hit */ } > > Considered: > "exact match for initial template arguments" > "exact match for inferred template arguments" But this one is not an exact match. It involves an `alias this` conversion from Nullable!int to int. As far as I can tell, it should be: "match with conversion for initial template arguments" "match with conversion for inferred template arguments" Or maybe just "match with conversion" since there are no template parameters. The empty template parentheses can actually be omitted without changing the behavior of the code.
Comment #6 by code — 2016-10-16T11:01:20Z
I think we still have a few weird orderings for the new function vs. template overloads, and also within the existing template overloads. Part of those are simply caused by the way the current ordering is implemented. Discussing this is quite tricky and doesn't make sense for single examples. If someone would want to spend the effort on a DIP to come up w/ a sound and simpler partial ordering, that is implementable in a backward compatible way, it would probably be a welcome effort. Don't think it's an urgent topic though.
Comment #7 by github-bugzilla — 2016-10-16T11:01:35Z
Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/daf387f065d4914cc868deb584ee8b6fb53774a5 add comment in reponse to Issue 16484 https://github.com/dlang/dmd/commit/bee58a21d15dc3bfc5c4e1c2d1691f85b51bdf90 Merge pull request #6194 from WalterBright/fix16484 add comment in response to Issue 16484
Comment #8 by github-bugzilla — 2016-11-04T09:05:30Z
Commits pushed to newCTFE at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/daf387f065d4914cc868deb584ee8b6fb53774a5 add comment in reponse to Issue 16484 https://github.com/dlang/dmd/commit/bee58a21d15dc3bfc5c4e1c2d1691f85b51bdf90 Merge pull request #6194 from WalterBright/fix16484
Comment #9 by github-bugzilla — 2017-01-07T03:02:24Z
Commits pushed to stable at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/daf387f065d4914cc868deb584ee8b6fb53774a5 add comment in reponse to Issue 16484 https://github.com/dlang/dmd/commit/bee58a21d15dc3bfc5c4e1c2d1691f85b51bdf90 Merge pull request #6194 from WalterBright/fix16484
Comment #10 by razvan.nitu1305 — 2022-01-21T11:59:52Z
*** Issue 20509 has been marked as a duplicate of this issue. ***