Bug 3416 – Non-compilable template instantiation in is(typeof()) fails compilation
Status
RESOLVED
Resolution
DUPLICATE
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2009-10-18T11:25:00Z
Last change time
2015-06-09T01:26:56Z
Assigned to
nobody
Creator
samukha
Comments
Comment #0 by samukha — 2009-10-18T11:25:00Z
template bar()
{
void bar()
{
a b; // invalid code
}
}
template foo()
{
enum foo = is(typeof(bar!()));
}
enum c = foo!();
test.d(19): Error: identifier 'a' is not defined
test.d(19): Error: a is used as a type
test.d(19): Error: variable Test.bar!().bar.b voids have no value
Comment #1 by samukha — 2009-10-18T11:56:17Z
Looks like a blocker for QtD
Comment #2 by braddr — 2009-10-18T14:26:25Z
How can invalid code be considered a blocker for anything?
Blockers are for problems that have no work around. The work around for invalid code is obvious.
Am I missing something?
Comment #3 by samukha — 2009-10-19T02:00:52Z
That is just a minimal test case. We should be able to check if a template can be instantiated with given template arguments. Here is a better test case:
template bar(T)
{
void baz()
{
T a;
a = null; // this may or may not be valid code, depending on T
}
}
enum foo = is(typeof(bar!int)); // this should evaluate to false
----
test.d(22): Error: cannot implicitly convert expression (null) of type void* to int
May be a regression.
Note that the following compiles as expected:
template bar(T)
{
T a = null; // this may or may not be valid code, depending on T
}
static assert(!is(typeof(bar!int)));
static assert(is(typeof(bar!(void*))));
Comment #4 by samukha — 2009-10-19T05:09:11Z
Interestingly, if 'foo' is instantiated in 'static assert', is incorrectly evaluated to true.
template bar(T)
{
private void baz()
{
T a = null;
}
}
template foo(T)
{
enum foo = is(typeof(bar!T));
}
static assert(!foo!int);
----
Error: static assert (!true) is false
Comment #5 by clugdbug — 2009-10-19T05:29:45Z
I don't think this is a bug. You're assuming that is(typeof(X)) is a test for whether X compiles. But it isn't. is(typeof(X)) only checks if the X has a semantically valid type. And in this case it does, because it's declared as void.
There's a larger issue, in that is(typeof(X)) is ugly, and it's very common to want to see if something compiles. In fact it's arguably the ugliest thing in the language right now. But it's not a bug.
Comment #6 by samukha — 2009-10-19T06:24:50Z
Ok, but there is no other way to determine if some syntactically correct code is also correct semantically. And without that, D's metaprogramming system is of little use.
Anyway, I'm not sure whether semantically incorrect code should produce a valid type, which void is. Should it?
And the current compiler seems to treat __traits(compiles, X) and is(typeof(X)) identically...
I think this bug should remain open until is(typeof(X)) is fixed or a different/better mechanism is introduced. And it is definitely a blocker.
Thanks
Comment #7 by clugdbug — 2009-10-19T07:19:54Z
(In reply to comment #6)
> Ok, but there is no other way to determine if some syntactically correct code
> is also correct semantically. And without that, D's metaprogramming system is
> of little use.
I think you're overstating the problem. Certainly it's an annoyance. But in my experience it is quite easy to work around it.
> Anyway, I'm not sure whether semantically incorrect code should produce a valid
> type, which void is. Should it?
Dunno. To avoid that, it would have to instantiate the body of every template, recursively.
> And the current compiler seems to treat __traits(compiles, X) and is(typeof(X))
> identically...
THAT is definitely a bug.
> I think this bug should remain open until is(typeof(X)) is fixed or a
> different/better mechanism is introduced. And it is definitely a blocker.
A comment: 30% of the blockers in Bugzilla are from you. None of them have any votes, not even from you. You might want to change that.
Comment #8 by samukha — 2009-10-21T07:52:43Z
(In reply to comment #7)
> (In reply to comment #6)
> > Ok, but there is no other way to determine if some syntactically correct code
> > is also correct semantically. And without that, D's metaprogramming system is
> > of little use.
>
> I think you're overstating the problem. Certainly it's an annoyance. But in my
> experience it is quite easy to work around it.
>
I don't think so. I intend to base a design on a feature that seems to work:
template bar(T)
{
T a = null;
}
template foo(T)
{
enum foo = is(typeof(bar!(T)));
}
static assert(!foo!(int));
static assert(foo!(void*));
The above looks logical, regardless of the syntax. By extension, I conclude that it will work in more complex cases. I squeal with delight. Then it appears that the feature doesn't work and is not supposed to work at all. Now I have to introduce hacks (if we stop calling them workarounds, the world may change for the better) or rethink the design. It is not just an annoyance but another massive WTF. I wouldn't be whining here if those annoyances weren't so frequent.
> > Anyway, I'm not sure whether semantically incorrect code should produce a valid
> > type, which void is. Should it?
>
> Dunno. To avoid that, it would have to instantiate the body of every template,
> recursively.
>
> > And the current compiler seems to treat __traits(compiles, X) and is(typeof(X))
> > identically...
>
> THAT is definitely a bug.
Should I post another report? And what about D1 that does not have __traits?
>
> > I think this bug should remain open until is(typeof(X)) is fixed or a
> > different/better mechanism is introduced. And it is definitely a blocker.
>
> A comment: 30% of the blockers in Bugzilla are from you. None of them have any
> votes, not even from you. You might want to change that.
Thanks for the comment. I came from C# that had a very stable toolchain and clear specification even in those dark times. I was green and it took me a while to get used to the D way (more powerful language at a price of buggy toolchain and incomplete specification).
Anyway, only 3 of the blockers has remained open. One was a blocker for a design I eventually gave up on because of it and other bugs. Another I've changed to normal. The third is this one.
Comment #9 by clugdbug — 2009-10-28T05:01:20Z
This seems to be a duplicate of bug 965. My comments were based on Walter's
comment in that bug.
Comment #10 by samukha — 2009-10-28T06:58:04Z
I think, you are right. No point in further analysis if the type can be determined without it. Sorry for the rant.
I'll post a bug concerning __traits(compiles), then.
*** This issue has been marked as a duplicate of issue 965 ***