Thread overview
[Issue 1728] New: alias hides mixin member func?
Dec 12, 2007
d-bugmail
Jun 26, 2008
d-bugmail
Jul 07, 2008
d-bugmail
Dec 09, 2008
d-bugmail
Dec 09, 2008
d-bugmail
Dec 10, 2008
d-bugmail
Dec 11, 2008
d-bugmail
December 12, 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1728

           Summary: alias hides mixin member func?
           Product: D
           Version: 2.008
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Keywords: rejects-valid
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: davidl@126.com


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])


-- 

June 26, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1728


davidl@126.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch




------- Comment #1 from davidl@126.com  2008-06-25 23:18 -------
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);
            }


-- 

July 07, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1728





------- Comment #2 from davidl@126.com  2008-07-07 08:36 -------
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


-- 

December 09, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1728


bugzilla@digitalmars.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID




------- Comment #3 from bugzilla@digitalmars.com  2008-12-09 05:13 -------
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.


-- 

December 09, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1728





------- Comment #4 from jarrett.billingsley@gmail.com  2008-12-09 07:18 -------
(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.)


-- 

December 10, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1728





------- Comment #5 from bugzilla@digitalmars.com  2008-12-09 21:41 -------
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().


-- 

December 11, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1728





------- Comment #6 from davidl@126.com  2008-12-11 06:19 -------
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.


--