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