Bug 16343 – Incorrectly requiring this pointer for a free function

Status
NEW
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2016-08-01T03:24:09Z
Last change time
2024-12-13T18:49:17Z
Keywords
rejects-valid
Assigned to
No Owner
Creator
Jonathan M Davis
Moved to GitHub: dmd#19166 →

Comments

Comment #0 by issues.dlang — 2016-08-01T03:24:09Z
This is a much reduced example from some code I'm working on: void main() { foo!(S.tupleof)(); } struct S { int i; } bool foo(fields...)() { return true; } It fails to compile, giving the error q.d(3): Error: need 'this' for 'foo' of type 'pure nothrow @nogc @safe bool()' I see no reason why that code shouldn't compile, and the error message is definitely bogus, because free functions don't need this pointers, and tupleof doesn't require a this pointer, since it's operating on a type, not an actual object.
Comment #1 by dfj1esp02 — 2016-08-01T09:34:00Z
Looks like tupleof returns a tuple of struct field aliases instead of a tuple of their types. And a template with an alias parameter requires a context through which it can access the aliased field. The question is what tupleof should return.
Comment #2 by issues.dlang — 2016-08-01T10:21:51Z
Yes, tupleof gives an AliasSeq of the fields in the struct - which is exactly what I want. It would be a major problem if it did something else. Also, there is no alias parameter here. It's a variadic template parameter, not an alias parameter. And note that this code compiles just fine: void main() { auto result = foo!(S.tupleof); } struct S { int i; } template foo(fields...) { enum foo = true; } It's just that when foo is a templated function instead of an eponymous template, you get the compilation error. So, something about foo being a function makes the compiler choke.
Comment #3 by schveiguy — 2016-08-01T12:01:30Z
Accepting aliases that require 'this' shouldn't trigger an error either. It's when you try to use the alias that it should fail (if you fail to use the alias properly, that is).
Comment #4 by dfj1esp02 — 2016-08-02T09:16:39Z
Probably a duplicate of issue 13062. See also discussion in issue 11946 and its related issues. AFAIK there was a request to not require the context pointer for such templates, but can't find it now.
Comment #5 by issues.dlang — 2017-11-19T08:34:22Z
I just hit this issue again - with an alias parameter this time. This code ============ struct S { int i; } void main() { foreach(memberName; __traits(allMembers, S)) { func!(__traits(getMember, S, memberName))(); } } void func(alias member)() { auto protection = __traits(getProtection, member); alias Type = typeof(member); auto name = __traits(identifier, member); } ============ gives this error q.d(10): Error: need 'this' for 'func' of type 'pure nothrow @nogc @safe void()' whereas moving the contents of the free function into main works just fine. The lack of ability to pass the member to a template for introspection makes it a lot harder to avoid code duplication when writing code that does type introspection.
Comment #6 by b2.temp — 2019-06-20T11:41:34Z
In a way the message about "this" is not bogus. It has not been mentioned but if you set func "static" then the code works. === struct S { int i; } void main() { foreach(memberName; __traits(allMembers, S)) func!(__traits(getMember, S, memberName)); } static void func(alias member)() { auto protection = __traits(getProtection, member); alias Type = typeof(member); auto name = __traits(identifier, member); } === The real bug is that "func" seems to be injected in "S" (or considered as member of) for some reasons.
Comment #7 by b2.temp — 2019-06-20T14:28:56Z
A fix would be to infer "static"... but this is excessively hard since TemplateDeclaration and TemplateInstance are two different things and the real scope comes with the instance.
Comment #8 by robert.schadek — 2024-12-13T18:49:17Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19166 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB