Bug 10413 – .init incorrectly accepts any expression

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-06-19T03:04:04Z
Last change time
2019-11-03T05:10:35Z
Keywords
accepts-invalid
Assigned to
No Owner
Creator
Don

Comments

Comment #0 by clugdbug — 2013-06-19T03:04:04Z
According to the spec, only variables, fields, and types support the .init property. But all kinds of other things compile: int foo() { return 1; } static assert(foo.init == 0); This gets changed into typeof(foo()).init. --- diff --git a/src/mtype.c b/src/mtype.c index 1c83eb9..8217e8d 100644 --- a/src/mtype.c +++ b/src/mtype.c @@ -2051,6 +2051,11 @@ Expression *Type::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) char *s = e->toChars(); e = new StringExp(e->loc, s, strlen(s), 'c'); } + else if (ident == Id::init && ex->op != TOKtype) + { + error(e->loc, ".init can only be applied to variables, fields, and types. Did you mean typeof(%s).init ?", e->toChars()); + e = new ErrorExp(); + } else e = getProperty(e->loc, ident, flag);
Comment #1 by clugdbug — 2013-06-25T23:57:58Z
Pull request: https://github.com/D-Programming-Language/dmd/pull/2240 This fails Phobos unit tests in multiple places, for example: std/traits.d(3654): Error: static assert (is(void == double)) is false With constructions like: template Foo(T...) T[0].init is OK if T[0] is a type, but if it is a value, it won't compile. It is in fact pretty bizarre that 2.init == 0, so this should probably be changed.
Comment #2 by monarchdodra — 2014-04-08T08:10:53Z
(In reply to comment #1) > With constructions like: > template Foo(T...) > > T[0].init > is OK if T[0] is a type, but if it is a value, it won't compile. If the template code doesn't make sense, then it doesn't compile. Seems fine to me. > It is in fact pretty bizarre that 2.init == 0, so this should probably be > changed. ".init" is a static property, and as such, can be called on either type or instance, just the same way you can write "assert(1.max == 0x7FFFFFF)". As a matter of fact, I'm pretty sure I've seen this used before, instance of having to pulling out the "typeof". I'm not sure changing this would be correct.
Comment #3 by monarchdodra — 2014-04-08T08:12:41Z
(In reply to comment #2) > instance of having > to pulling out the "typeof". I mean "instead of having to pull out the "typeof"."
Comment #4 by andrej.mitrovich — 2014-04-21T09:39:09Z
According to Walter it's ok if a UDT defines its own .init, which would make value.init valid: https://issues.dlang.org/show_bug.cgi?id=7066 I don't agree with him though, especially since the whole argument against allowing user-defined default ctors is the compile-time known .init property.
Comment #5 by iamthewilsonator — 2019-11-03T05:10:35Z
int foo() { return 1; } static assert(foo.init == 0); is a case of optional parentheses, as char foo() { return 1; } static assert(foo.init == 255); passes, but int foo(int) { return 1; } static assert(foo.init == 0); fails with onlineapp.d(3): Error: function onlineapp.foo(int) is not callable using argument types () onlineapp.d(3): missing argument for parameter #1: int onlineapp.d(3): while evaluating: static assert((__error).init == 0) closing as invalid