Bug 4413 – typeof(this) doesn't work in method template signature

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2010-07-01T14:27:00Z
Last change time
2012-04-23T17:04:51Z
Keywords
patch, rejects-valid
Assigned to
nobody
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2010-07-01T14:27:43Z
dmd v2.047 shows a compilation error on the call to bar4, but in my opinion the compiler has to compile all four those bar methods: struct Foo { alias typeof(this) typeof_this; void bar1(typeof_this other) {} void bar2()(typeof_this other) {} void bar3(typeof(this) other) {} void bar4()(typeof(this) other) {} } void main() { Foo f; f.bar1(f); // OK f.bar2(f); // OK f.bar3(f); // OK f.bar4(f); // ERR } The generated errors: test.d(13): Error: template test.Foo.bar4() does not match any function template declaration test.d(13): Error: template test.Foo.bar4() cannot deduce template function from argument types !()(Foo) The problem of bar4 has shown up in D2 code similar to this one, where I have used typeof(this) to follow the DRY strategy and avoid repeating the struct name more than one time: struct Vec2 { float x, y; auto opBinary(string op)(typeof(this) other) if (op == "+") { ... } } A workaround that can be used is: struct Vec2 { float x, y; alias typeof(this) typeof_this; auto opBinary(string op)(typeof_this other) if (op == "+") { ... } }
Comment #1 by ibuclaw — 2011-02-06T07:32:03Z
Calling semantic on the param type in ::deduceType seems to be simplest workaround without causing side effects. --- a/src/template.c +++ b/src/template.c @@ -2183,6 +2183,7 @@ MATCH TypeStruct::deduceType(Scope *sc, Type *tparam, TemplateParameters *parame * to a template instance, too, and try again. */ TemplateInstance *ti = sym->parent->isTemplateInstance(); + tparam = tparam->semantic(0, sc); if (tparam && tparam->ty == Tinstance) { @@ -2317,6 +2318,7 @@ MATCH TypeClass::deduceType(Scope *sc, Type *tparam, TemplateParameters *paramet * to a template instance, too, and try again. */ TemplateInstance *ti = sym->parent->isTemplateInstance(); + tparam = tparam->semantic(0, sc); if (tparam && tparam->ty == Tinstance) { Ideally though, all typeof()'s should have been expanded beforehand. Regards
Comment #2 by bearophile_hugs — 2011-02-06T11:58:12Z
*** Issue 5532 has been marked as a duplicate of this issue. ***
Comment #3 by code — 2011-03-30T17:53:08Z
The patch by Iain seems to break std.datetime: /usr/local/include/d2/std/datetime.d(9217): Error: template instance std.datetime.DTRebindable!(immutable(TimeZone)) error instantiating
Comment #4 by ibuclaw — 2011-03-31T05:43:42Z
(In reply to comment #3) > The patch by Iain seems to break std.datetime: > > /usr/local/include/d2/std/datetime.d(9217): Error: template instance > std.datetime.DTRebindable!(immutable(TimeZone)) error instantiating Yep, I was merely suggesting that things should ideally be worked out before this point (because they *can* be worked out).
Comment #5 by k.hara.pg — 2011-12-21T05:55:25Z
*** Issue 5801 has been marked as a duplicate of this issue. ***
Comment #6 by k.hara.pg — 2011-12-21T05:55:58Z
Comment #7 by bugzilla — 2011-12-26T18:26:35Z
Comment #8 by k.hara.pg — 2012-04-23T17:04:51Z
*** Issue 5903 has been marked as a duplicate of this issue. ***