Bug 1536 – Literal '0' is improperly used to deduce an implicit template parameter

Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
All
OS
All
Creation time
2007-09-28T13:09:44Z
Last change time
2019-08-21T11:11:06Z
Assigned to
No Owner
Creator
Russ Lewis

Comments

Comment #0 by webmaster — 2007-09-28T13:09:44Z
EXAMPLE CODE void delegate() CurryAll(A...)(void delegate(A) dg, A args) { return null; // dummy function } struct S { void foo() { uint u = 0; int i = 0; // these work auto a = CurryAll (&this.baz, 0); auto b = CurryAll!(uint)(&this.bar, 0); auto c = CurryAll (&this.bar, u); auto d = CurryAll (&this.baz, i); auto e = CurryAll!(uint)(&this.bar, i); auto f = CurryAll!( int)(&this.baz, u); // these don't auto z = CurryAll (&this.bar, 0); } void bar(uint u) { return; } void baz( int i) { return; } } DMD OUTPUT implicit_instantiation_and_implicit_cast.d(21): function implicit_instantiation_and_implicit_cast.CurryAll!(int).CurryAll (void delegate(int i),(int _param_1)) does not match parameter types (void delegate((uint _param_1)),int) implicit_instantiation_and_implicit_cast.d(21): Error: cannot implicitly convert expression (&(*this).bar) of type void delegate((uint _param_1)) to void delegate(int i) ANALYSIS It appears that when DMD encounters the literal '0', it is jumping to the conclusion that that literal '0' *must* be of type int, even though it could be other types (uint, real, etc.). In the case of the example z from above, this is bad because the delegate argument quite clearly requires that the template be deduced to have parameter uint.
Comment #1 by regan — 2007-09-28T13:17:39Z
A decimal literal within the range of 0 .. 2_147_483_647 is assumed to be of type int, it's in the docs: http://www.digitalmars.com/d/lex.html#integerliteral "The type of the integer is resolved as follows: Decimal Literal Type 0 .. 2_147_483_647 int 2_147_483_648 .. 9_223_372_036_854_775_807L long Decimal Literal, L Suffix Type 0L .. 9_223_372_036_854_775_807L long Decimal Literal, U Suffix Type 0U .. 4_294_967_296U uint 4_294_967_296U .. 18_446_744_073_709_551_615UL ulong Decimal Literal, UL Suffix Type 0UL .. 18_446_744_073_709_551_615UL ulong "
Comment #2 by webmaster — 2007-09-28T13:25:42Z
Seems that I was wrong about what is written in the spec; I thought that the type of literal was considered ambiguous until it was forced, by context, to be something (such as assigning it to a variable, or passing it as a parameter). So, let's make this bug more of a question about the language itself: Perhaps we need to change integer literals to have their type inferred from context, just like string literals. IMHO, the code below looks pretty simple and seems like it *ought* to work. Is there a technical reason (other than just "it is easier") why integer literals *shouldn't* be polysemous?
Comment #3 by clugdbug — 2012-09-26T01:04:53Z
This example is unnecessarily complicated. void CurryAll(A)(A x, A y) { } void foo() { uint u = 0; CurryAll(u, 0); }
Comment #4 by razvan.nitu1305 — 2019-08-21T11:11:06Z
In the initial bug report there is an easy workaround: simply use `0u` and it will work; easy and obvious. Closing as invalid.