DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

Neia Neutuladh neia at ikeran.org
Wed Nov 14 21:32:24 UTC 2018


On Wed, 14 Nov 2018 13:40:46 -0500, Steven Schveighoffer wrote:
> You don't think this is confusing?
> 
> enum A : int {
>      val
> }
> 
> A a;
> foo(a); // error: be more specific
> int x = a;
> foo(x); // Sure

I find this confusing:

    void foo(int i) {}
    void foo(ubyte b) {}
    enum A : int { val = 0 }
    foo(A.val);  // calls foo(ubyte)
    A a = A.val;
    foo(a);      // calls foo(int)

If it instead produced an error, the error would look like:

    Error: foo called with argument types (E) matches both:
    example.d(1): foo(int i)
    and:
    example.d(2): foo(ubyte i)

Or else:

    Error: none of the overloads of foo are callable using
    argument types (A), candidates are:
    example.d(1): foo(int i)
    example.d(2): foo(ubyte i)

These aren't the intuitively obvious thing to me, but they're not going to 
surprise me by calling the wrong function, and there are obvious ways to 
make the code work as I want. Of the two, I'd prefer the former.

The intuitively obvious thing for me is:

* Don't use VRP to select an overload. Only use it if there's only one 
candidate with the right number of arguments.
* Don't use VRP if the argument is a ctor, cast expression, or symbol 
expression referring to a non-builtin. Maybe disallow with builtins.
* Don't use VRP if the argument is a literal with explicitly indicated type 
(0UL shouldn't match to byte, for instance).

I think this would make things more as most people expect:

    foo(A.val);  // A -> int, but no A -> byte; calls foo(int)
    foo(0);      // errors (currently calls foo(int))
    foo(0L);     // errors (currently calls foo(ubyte))
    foo(cast(ulong)0);  // errors (currently calls foo(ubyte))

And when there's only one overload:

    void bar(byte b) {}
    bar(A.val);  // errors; can't convert A -> byte
    bar(0);      // type any-number and fits within byte, so should work
    bar(0UL);    // errors; explicit incorrect type
    bar(0UL & 0x1F);    // bitwise and expression can do VRP
    bar("foo".length);  // length is a builtin; maybe do VRP?
    bar(byte.sizeof);   // sizeof is a builtin; maybe do VRP?


More information about the Digitalmars-d-announce mailing list