On Friday, 13 October 2017 at 13:01:48 UTC, Steven Schveighoffer
wrote:
On 10/12/17 7:57 PM, Q. Schroll wrote:
We have some sort of implicit construction already. Weirdly,
it's reserved for classes. Just look at this:
class C { this(int x) { } }
void foo(C c ...) { }
void main() { foo(0); }
If you put @nogc in front of ctor and functions, the compiler
tells you not to use 'new' in main while you actually don't.
Merely the compiler inserts it for you to complain about it.
Not sure where you put the @nogc.
class C { this(int x) @nogc { } }
void foo(C c ...) @nogc { }
void main() @nogc { foo(0); }
It tells you not to use 'new' while you don't (explicitly, at
least).
What is likely happening is that the call to foo is lowered to
foo(new C(0)). Indeed, using -vcg-ast proves it.
Probably. I don't care -- the compiler should not give me this
error message. I've filed a bug report, but I cannot find it
anymore.
The spec says it can put the class on the stack, but is not
required to.
Exactly. It shouldn't work and doesn't. That's not the problem.
One could propose to extend the three-dots notation to
structs. I don't.
The fact that this is not supported (it isn't, I tried it)
doesn't make any sense.
It tried once, too.
It's likely this hails from a time where classes had ctors and
structs did not, and is just not a feature that anyone cared
about or used.
IMO, it should be extended for structs just in terms of
consistency. But I don't think it would be a high priority.
That would be another consistent solution. Even if we had this
for structs, there is the @nogc argument not to allow it for
classes (the compiler inserts nontrivial things: the heap
allocation).
I'd vote for deprecating the three-dots for classes. Did you
know it exists? Did you use it - like ever? Does anyone depend
on it?
I'm mixed on it. I wouldn't care personally if it was removed,
but it's a feature that may be used somewhere, and there's no
harm in keeping it.
Even extending this to structs does not give you implicit ctor
calls. You can use ... only for the last parameter for obvious
reasons. It's completely different from implicit ctor calls. I
only mentioned that as it is the closest thing in D to implicit
ctor calls.
[snip]
It's a neat idea. I don't see why we would need to remove the
typesafe variadics to allow this to work.
You don't. I mentioned it as it is somehow implicit ctor call.
It *really* would be nice though, to allow annotations on
parameters. The @implicit(1) stinks. Would look much better as:
proto_goo(int v, @implicit S s, bool b);
I tried that, too, and failed because of that. (I'd even assume
anyone would, because it'd be the obvious way to want it.) This
is another reason to allow that.
Where you may run into trouble is if there is ambiguity (for
instance 2 implicit parameters could match the potential
arguments in different ways).
How? I only accept *one* parameter. Ctors with more than one
parameter are disallowed. One could allow those which can be
called with one parameter because they fill the rest with default
values. I didn't for the sake of an easier implementation. It's a
first sketch, a proof of concept.
Another option is to not worry about tagging which parameters
would be implicit, and go only on the fact that types in the
parameter list have @implicit constructors when you call
implicitOverloads.
There are two reasons against it.
1. implicitOverloads would search much more for nothing.
2. You'd add implicit overloads the author of the function
maybe wouldn't want.
You can think of my system as offer and acceptance. You need
both. @implicit ctors do nothing for themselves the same way
@implicit(1) does nothing if the targeted type has nothing to
offer. That's on purpose to make implicit ctor calls as
transparent as possible. Walter didn't want implicit construction
because it is non-transparent. Under these circumstances, it has
good chances to be accepted for Phobos.