On Saturday, 30 May 2015 at 14:10:35 UTC, IgorStepanov wrote:
    static Foo opImplicitConstructFrom(T)(T val) if(is(T : int))

I briefly mentioned this at the dconf and thinking about it a bit more, I think there's only two cases where we want implicit construction: function argument lists and function return values. (The syntax doesn't really matter, but I'd do it similar to C++ and just slap an @implicit on a regular constructor).


So:

struct Foo { @implicit this(typeof(null)) {} }

Foo test() {
   return null;
}

Right now, that return null would say "cannot implicitly convert null to Foo". But since it is on a return statement and we have an implicit constructor, it would automatically rewrite that to return Foo(null); and be happy with it.

Note that this does NOT change

Foo foo = null;

because that already works with a standard constructor today! Similarly, foo = null is handled with opAssign. So no change needed there.



Anyway, the trickier case is function calls:


void test(Foo) {}

test(null); // should do test(Foo(null));



How does that interact with operator overloading? (I'd note that C++ does this so we could always borrow their rules too.) My proposal would be that if something matches exactly without implicit conversion, use that. Otherwise, try the implicit construction and issue an error if more than one match.


This would work the same as arrays today:

void a(int[]) {}
void a(long[]) {}
void a(typeof(null)) {}

void main() { a(null); }


That compiles. Comment the third line though and get:

b.d(5): Error: b.a called with argument types (typeof(null)) matches both:
b.d(1):     b.a(int[] _param_0)
and:
b.d(2):     b.a(long[] _param_0)



So I think that's doable and shouldn't break any existing code as it is a new opt-in keyword. Just will have to watch for regression bugs...


But that'd take care of the null problem with library AAs.... and I could use it to make my var type all the more wild :P

Reply via email to