www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 9361] New: Nasty bug and/or error message for template constaints using this

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9361

           Summary: Nasty bug and/or error message for template constaints
                    using this
           Product: D
           Version: D2
          Platform: x86
        OS/Version: Windows
            Status: NEW
          Severity: major
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: maidenphil hotmail.com


--- Comment #0 from Phil Lavoie <maidenphil hotmail.com> 2013-01-20 14:19:02
PST ---
I tried to make the code as brief as possible:
module rettypeinfer;

import std.stdio;

struct Unit( A ) {

  void useMe() {
    writeln( isUnit!this );
    writeln( is( unitType!this == int ) );
    writeln( ( unitType!this ).stringof );
  }

  void useMoreOfMe( T )( T t ) if( is( atomType!T == unitType!( typeof( this )
) ) ) {
    writeln( "We're ok, but borderline" );
  }

  void butPleaseDontUseMe( T )( T t ) if( is( atomType!T == unitType!( ( this )
) ) ) {
    writeln( "Look at the error message" );
  }

}

template isUnit( alias T ) if( is( T ) ) {
  static if( is( T _: Unit!Args, Args... ) ) {
    enum isUnit = true;
  } else {
    enum isUnit = false;
  }
}
template isUnit( alias T ) if( !is( T ) ) {
  enum isUnit = isUnit!( typeof( T ) );
}
template unitType( alias T ) if( isUnit!T ) {
  static if( is( T _: Unit!Args, Args... ) ) {
    alias unitType = Args[ 0 ];
  } else {
    alias unitType = unitType!( typeof( T ) );
  }
}

struct Atom( A ) {

}

template isAtom( alias A ) if( is( A ) ) {
  static if( is( A _: Atom!Args, Args... ) ) {
    enum isAtom = true;
  } else {
    enum isAtom = false;
  }
}
template isAtom( alias A ) if( !is( A ) ) {
  enum isAtom = isAtom!( typeof( A ) );
}
template atomType( alias T ) if( isAtom!T ) {
  static if( is( T _: Atom!Args, Args... ) ) {
    alias atomType = Args[ 0 ];
  } else {
    alias atomType = atomType!( typeof( T ) );
  }
}

void main( string[] args ) {
  Unit!int u;

  assert( isUnit!u );
  assert( isUnit!( typeof( u ) ) );
  assert( is( unitType!u == int ) );
  assert( is( unitType!( typeof( u ) ) == int ) );

  u.useMe();

  Atom!int a;

  assert( isAtom!a );
  assert( isAtom!( typeof( a ) ) );
  assert( is( atomType!a == int ) );
  assert( is( atomType!( typeof( a ) ) == int ) );

  u.useMoreOfMe( a );

  //Crashes, with nasty error message.
  u.butPleaseDontUseMe( a );
}

Run this and it outputs:
Assertion failure: 'fd && fd->inferRetType' on line 81 in file 'mangle.c'

abnormal program termination

The last function crashes the program. If you replace unitType!this with
unitType( typeof( this ) ) the function works properly, as in the previous
member declaration.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 20 2013
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9361



--- Comment #1 from Kenji Hara <k.hara.pg gmail.com> 2013-01-20 18:33:09 PST ---
Reduced test case:

struct Unit(A)
{
    void butPleaseDontUseMe()()
    if (is(unitType!((this))))  // !
    {}

}
template isUnit(alias T) if ( is(T)) {}
template isUnit(alias T) if (!is(T)) {}
template unitType(alias T) if (isUnit!T) {}
void main()
{
    Unit!int u;
    u.butPleaseDontUseMe();     // crashes
}

====

I think the instantiation unitType!((this)) in the template constraint for
butPleaseDontUseMe template function should always fail, because the 'this'
symbol yet not has an actual entity while the constraint evaluation.

That means, the invocation of s.foo() should fail in following.

template Sym(alias A) { enum Sym = true; }
struct S {
    void foo()() if (Sym!(this)) {}
    // Sym!(this) always make an error, because
    // Sym template never be able to access
    // valid 'this' symbol.
}
void main() { S s; s.foo(); }

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 20 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9361


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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |ice, pull
           Platform|x86                         |All
         OS/Version|Windows                     |All


--- Comment #2 from Kenji Hara <k.hara.pg gmail.com> 2013-01-20 19:56:02 PST ---
https://github.com/D-Programming-Language/dmd/pull/1525

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 20 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9361



--- Comment #3 from Phil Lavoie <maidenphil hotmail.com> 2013-01-21 06:19:00
PST ---
(In reply to comment #1)
 Reduced test case:
 
 struct Unit(A)
 {
     void butPleaseDontUseMe()()
     if (is(unitType!((this))))  // !
     {}
 
 }
 template isUnit(alias T) if ( is(T)) {}
 template isUnit(alias T) if (!is(T)) {}
 template unitType(alias T) if (isUnit!T) {}
 void main()
 {
     Unit!int u;
     u.butPleaseDontUseMe();     // crashes
 }
 
 ====
 
 I think the instantiation unitType!((this)) in the template constraint for
 butPleaseDontUseMe template function should always fail, because the 'this'
 symbol yet not has an actual entity while the constraint evaluation.
 
 That means, the invocation of s.foo() should fail in following.
 
 template Sym(alias A) { enum Sym = true; }
 struct S {
     void foo()() if (Sym!(this)) {}
     // Sym!(this) always make an error, because
     // Sym template never be able to access
     // valid 'this' symbol.
 }
 void main() { S s; s.foo(); }

Yes it makes sense, however the error message is clearly not appropriate! Something like: dmd: Error: If you use this in template constraint again I will hate you. Should do :) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 21 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9361


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

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


--- Comment #4 from Kenji Hara <k.hara.pg gmail.com> 2013-01-22 19:37:10 PST ---
*** This issue has been marked as a duplicate of issue 6538 ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 22 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9361



--- Comment #5 from github-bugzilla puremagic.com 2013-01-22 21:50:19 PST ---
Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/d31dd28886a832b077b013c62a885fb02a6ed124
fix Issue 9361 - Nasty bug and/or error message for template constaints using
this

Add test cases

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