Bug 1728 – alias hides mixin member func?

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2007-12-11T23:30:00Z
Last change time
2015-06-09T01:14:23Z
Keywords
patch, rejects-valid
Assigned to
bugzilla
Creator
davidl

Comments

Comment #0 by davidl — 2007-12-11T23:30:12Z
import std.stdio; interface mix { void print(char[]); } template mixtem() { void print(char[] t) { writefln(t); } } class A { void print() { writefln("A"); } void print(int a) { writefln(a); } } class B:A,mix { alias A.print print; mixin mixtem; void pr() { super.print(); super.print(18); print("OK"); // this should call mixin member func writefln("B"); } } kk.d(36): function kk.A.print () does not match parameter types (char[2u])
Comment #1 by davidl — 2008-06-25T23:18:24Z
a patch in template.c TemplateMixin::semantic // Declare each template parameter as an alias for the argument type declareParameters(scope); ++ ScopeDsymbol *parent = sc -> parent; // Add members to enclosing scope, as well as this scope for (unsigned i = 0; i < members->dim; i++) { Dsymbol *s; s = (Dsymbol *)members->data[i]; +++ // for fixing bug 1728 http://d.puremagic.com/issues/show_bug.cgi?id=1728 +++ // actually we provide the sugar of introducing the funcdeclaration transparently from this anonymous scope +++ if (s -> isFuncDeclaration()) +++ { +++ s->addMember(scope, parent, i); +++ s->parent = this; +++ } +++ else s->addMember(scope, this, i); //sc->insert(s); //printf("sc->parent = %p, sc->scopesym = %p\n", sc->parent, sc->scopesym); //printf("s->parent = %s\n", s->parent->toChars()); } and in dsymbol.c: Dsymbol::addMember s2 = sd->symtab->lookup(ident); +++ s2 = s2 -> toAlias(); if (!s2->overloadInsert(this)) { sd->multiplyDefined(0, this, s2); }
Comment #2 by davidl — 2008-07-07T08:36:58Z
in the patch +++ if (s -> isFuncDeclaration()) +++ { +++ s->addMember(scope, parent, i); +++ s->parent = this; +++ } +++ else should be +++ if (s -> isFuncDeclaration() && parent != NULL ) +++ { +++ s->addMember(scope, parent, i); +++ s->parent = this; +++ } +++ else
Comment #3 by bugzilla — 2008-12-09T05:13:33Z
This is not a bug. The mixin establishes its own scope that is nested inside B's scope. If there is no print in B's scope, it will look in the mixin. If there is a print in B's scope, it will not look in the mixin. This works exactly the same as imports and symbols at module scope. The solution is to bring the desired members of mixtem up into B's scope. An alias will accomplish this, so rewriting B as: class B:A,mix { alias A.print print; mixin mixtem M; // give scope the name 'M' alias M.print print; // and bring M's print into B's scope void pr() { super.print(); super.print(18); print("OK"); // this should call mixin member func writefln("B"); } } should work.
Comment #4 by jarrett.billingsley — 2008-12-09T07:18:54Z
(In reply to comment #3) > This is not a bug. > > The mixin establishes its own scope that is nested inside B's scope. If there > is no print in B's scope, it will look in the mixin. If there is a print in B's > scope, it will not look in the mixin. > > This works exactly the same as imports and symbols at module scope. > > The solution is to bring the desired members of mixtem up into B's scope. That works fine for normal methods, but how about ctors? I actually ran into this. template mixtem() { this(char[] t) { Stdout.formatln(t); } } class A { mixin mixtem; this() { this("OK"); // same error as the OP } } Except of course "mixin mixtem M; alias M.this this;" is not legal. (I also tried using the weird _ctor but that doesn't work either.)
Comment #5 by bugzilla — 2008-12-09T21:41:15Z
I suspect that trying to make this work would add a bunch of arcane rules with little benefit. Instead, try to remove what this(string) does to a separate function, then call that function from the other this().
Comment #6 by davidl — 2008-12-11T06:19:38Z
But I can't accept that: class B:A,mix { mixin mixtem; void pr() { print("OK"); // this should call mixin member func writefln("B"); } } works while: class B:A,mix { alias A.print print; mixin mixtem; void pr() { print("OK"); // this should call mixin member func writefln("B"); } } doesn't work. An alias shouldn't hide a func that I try to call.