Thread overview
[Issue 9100] New: Weird behavior on template instance argument
Dec 01, 2012
Kenji Hara
Dec 01, 2012
Kenji Hara
Dec 01, 2012
Kenji Hara
Dec 01, 2012
Kenji Hara
Dec 01, 2012
Kenji Hara
Dec 09, 2012
timon.gehr@gmx.ch
Dec 09, 2012
Walter Bright
December 01, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9100

           Summary: Weird behavior on template instance argument
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: k.hara.pg@gmail.com


--- Comment #0 from Kenji Hara <k.hara.pg@gmail.com> 2012-11-30 19:09:03 PST ---
On template instance argument, a template arguments *sometimes* is treated just
as a symbol.
That looks weird and inconsistent behavior.

----
template Id(alias A) { alias Id = A; }  // L1
template ErrId(alias A) { static assert(0); }
template TypeTuple(TL...) { alias TypeTuple = TL; }
class C {
  void fun(){}
  void tfun(T)(){}
  TypeTuple!(int, long) field;  // L7

  void test()
  {
    auto c = this;
    alias t1a = Id!(c.fun);         // OK
    alias t1b = Id!(this.fun);      // Weird error, bad
    // test1.d(1): Error: variable test1.A type void is inferred
    //   from initializer this.fun(), and variables cannot be of type void
    // -> internally given DotVarExp

    alias t2a = Id!(c.tfun);        // OK
    alias t2b = ErrId!(this.tfun);  // No error occurs, why?
    // -> internally given DotTemplateExp

    alias t3a = Id!(foo);           // OK
    alias t3b = Id!(mixin("foo"));  // Prints weird error, bad
    // test1.d(1): Error: variable test1.A type void is inferred
    //   from initializer foo(), and variables cannot be of type void
    // -> internally given TemplateExp

    alias t4b = TypeTuple!(field);      // L28, NG
    // test1.d(7): Error: expression this._field_field_0 is not a valid
template value argument
    // test1.d(7): Error: expression this._field_field_1 is not a valid
template value argument
    // test1.d(28): Error: template instance
test1.TypeTuple!(this._field_field_0, this._field_field_1) error instantiating
    alias t4a = TypeTuple!(GetField!0); // L32, NG
    // test1.d(42): Error: alias test1.GetField!(0).GetField cannot alias an
expression _field_field_0
    // test1.d(42): Error: alias test1.GetField!(0).GetField cannot alias an
expression _field_field_0
    // test1.d(32): Error: template instance test1.GetField!(0) error
instantiating
    // test1.d(42): Error: alias test1.GetField!(0).GetField cannot alias an
expression _field_field_0
    // test1.d(32): Error: C.field[0u] is not a type
  }
}

void foo()(){}
template GetField(size_t i) { alias GetField = C.field[i]; }  // L42

void main(){ (new C()).test(); }
----

From the internal of dmd implementation, if failure to give just as a symbol, the argument has been semantically analysed as an expression which refers a symbol - DotVarExp, TemplateExp, and DotTemplteExp.

D does not support an aliasing of expression, so I think these *expression template arguments* should be deduced to just a symbol. In such deduction, the *context* expression for the symbol (e1, in DotVarExp or DotTemplateExp) should be just removed.

It will increase consistency and will relax some limitations.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 01, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9100



--- Comment #1 from Kenji Hara <k.hara.pg@gmail.com> 2012-11-30 19:24:41 PST ---
This is a root cause of some 2.061head regressions - bug 9091, bug 8972, and bug 8971.

If you use __traits() to get member symbol inside class/struct member function,
the found member symbol will have the implicit 'this'.
Passing the __traits result to the template argument will caught the *bug*
which I explained here.

class C {
  int var;
  void test() {
    __traits(getMember, C, "var");  // same as this.var -> DotVarExp
    alias t = Id!(__traits(getMember, C, "var")); // same as Id!(this.var),
hit!
  }
}
void main() {
  __traits(getMember, C, "var")  // same as C.var == Just a symbol
  alias t = Id!(__traits(getMember, C, "var")); // same as Id!(C.var), no
problem
}

Therefore, I think this is an important semantic analysis bug which should be fixed.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 01, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9100



--- Comment #2 from Kenji Hara <k.hara.pg@gmail.com> 2012-11-30 19:36:04 PST ---
As a related note, this program runs successfully with no error in current
compiler.
It looks weird, but is expected from the view of language consistency.

void main(){ (new C(1)).test(); }
template Id(alias A) { alias Id = A; }
class C
{
  int n;
  this(int x){ n = x; }
  int fun(){ return n; }

  void test()
  {
    auto c = new C(2);
    assert(c.fun() == 2);
    alias f = Id!(c.fun);
    assert(f() == 1);  // calls this.fun, not c.fun
  }
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 01, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9100


Kenji Hara <k.hara.pg@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull, rejects-valid
             Blocks|                            |9091, 9083
           Severity|normal                      |major


--- Comment #3 from Kenji Hara <k.hara.pg@gmail.com> 2012-11-30 21:14:14 PST ---
https://github.com/D-Programming-Language/dmd/pull/1340

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 01, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9100


Kenji Hara <k.hara.pg@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Blocks|                            |8972, 8971


--- Comment #4 from Kenji Hara <k.hara.pg@gmail.com> 2012-11-30 21:22:12 PST ---
The following bugs that were already fixed are fundamentally dependent on this.

Issue 8971 - __traits(getOverloads) fails in a member function Issue 8972 - __traits fails in a struct member function

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 09, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9100



--- Comment #5 from github-bugzilla@puremagic.com 2012-12-09 12:52:07 PST ---
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/1ba96f16d5c0300f4de8f4d2d851d65cf269dd15 fix Issue 9100 - Weird behavior on template instance argument

https://github.com/D-Programming-Language/dmd/commit/2f043f66b50a5f7d505cf9776a8ca2bfd632cabd Merge pull request #1340 from 9rnsr/fix9100

Issue 9100 - Weird behavior on template instance argument

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 09, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9100


timon.gehr@gmx.ch changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |timon.gehr@gmx.ch


--- Comment #6 from timon.gehr@gmx.ch 2012-12-09 13:20:55 PST ---
(In reply to comment #2)
> As a related note, this program runs successfully with no error in current
> compiler.
> It looks weird, but is expected from the view of language consistency.
> 
> void main(){ (new C(1)).test(); }
> template Id(alias A) { alias Id = A; }
> class C
> {
>   int n;
>   this(int x){ n = x; }
>   int fun(){ return n; }
> 
>   void test()
>   {
>     auto c = new C(2);
>     assert(c.fun() == 2);
>     alias f = Id!(c.fun);
>     assert(f() == 1);  // calls this.fun, not c.fun
>   }
> }

Language _sanity_ is what is important. It should call c.fun or be a compile time error. Deliberately assigning unsupported code strange semantics in order to be consistent with existing buggy compiler behaviour just makes it harder to lift restrictions later.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 09, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9100


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |bugzilla@digitalmars.com
         Resolution|                            |FIXED


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------