Bug 9361 – Nasty bug and/or error message for template constaints using this

Status
RESOLVED
Resolution
DUPLICATE
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-01-20T14:19:00Z
Last change time
2014-01-24T22:22:54Z
Keywords
ice, pull
Assigned to
nobody
Creator
maidenphil

Comments

Comment #0 by maidenphil — 2013-01-20T14:19:02Z
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.
Comment #1 by k.hara.pg — 2013-01-20T18:33:09Z
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(); }
Comment #2 by k.hara.pg — 2013-01-20T19:56:02Z
Comment #3 by maidenphil — 2013-01-21T06:19:00Z
(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 :)
Comment #4 by k.hara.pg — 2013-01-22T19:37:10Z
*** This issue has been marked as a duplicate of issue 6538 ***
Comment #5 by github-bugzilla — 2013-01-22T21:50:19Z
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
Comment #6 by github-bugzilla — 2014-01-23T23:22:28Z
Commit pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/f6d861b2bb083812f24b43d2d50c70222626b039 [Improve] Relax restrictions on issue 6538 and 9361 Now pseudo symbols are placed in emulated scopes, and taking them by alias parameter is allowed.
Comment #7 by github-bugzilla — 2014-01-24T22:22:54Z
Commit pushed to 2.065 at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/d88598d4168a16fac1afea6e7d4cb22be707d487 Revert "[Improve] Relax restrictions on issue 6538 and 9361" This reverts commit f6d861b2bb083812f24b43d2d50c70222626b039.