Bug 9633 – compiles trait wrongly returns true even when object method call actually does not compile
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-03-02T08:37:00Z
Last change time
2014-03-02T08:08:33Z
Keywords
pull
Assigned to
nobody
Creator
puneet
Comments
Comment #0 by puneet — 2013-03-02T08:37:46Z
The following code prints "baz compiles in global scope" with version 2.063. No message is printed with version 2.062.
baz is an object method and does not compile in module scope since no (this pointer) object has been provided as argument. So compiles trait on line 11 should return false, as is done by DMD version 2.062.
class Foo { // 1
void baz() {} // 2
void bar() { // 3
static if(compilesWithoutThis!baz) { // 4
import std.stdio; // 5
writeln("baz compiles in global scope"); // 6
} // 7
} // 8
} // 9
template compilesWithoutThis (alias F) { // 10
static if(__traits(compiles, F())) // 11
enum bool compilesWithoutThis = true; // 12
else // 13
enum bool compilesWithoutThis = false; // 14
} // 15
void main() { // 16
Foo foo = new Foo; // 17
foo.bar(); // 18
} // 19
Comment #3 by dlang-bugzilla — 2014-03-02T08:06:33Z
Why is it a requirement that F() should not compile?
I have filed issue 12230 which is an opposite of this pull request.
Some things to be aware of:
- Inside speculative blocks (in __traits(compiles) or typeof(exp)), we always pretend that we have an "is" pointer. This greatly simplifies writing template constraints for methods, among other things.
- The rules for fields and methods differ when they are passed as alias parameters (see issue 12230). When a field is passed as an alias parameter, the template becomes nested within the field's aggregate (struct/class). When a method is passed, this doesn't happen, which I think is an unwarranted inconsistence.
Comment #4 by dlang-bugzilla — 2014-03-02T08:08:33Z
(In reply to comment #3)
> I have filed issue 12230 which is an opposite of this pull request.
of this issue*
> we always pretend that we have an "is" pointer
"this" pointer*