//////////////////////////////////////////////////////////// //case 1 class A { abstract void foo(); } class B : A { static if( __traits(isAbstractClass, typeof(this) )) { } override void foo() { } } void main() { B b = new B(); } //Error: cannot create instance of abstract class B //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// //case 2 abstract class A { void foo(); } class B : A { static if( __traits(isAbstractClass, typeof(this) )) { } override void foo() { } } void main() { B b = new B(); } //Okay //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// //case 3 class A { abstract void foo(); } class B : A { override void foo() { } } void main() { B b = new B(); } //Okay ////////////////////////////////////////////////////////////
If others agree, please change the summary to something like __traits(isAbstractClass) uses the definition that it knows so far, not the whole definition of the class In any case, it would be a chicken and egg problem if static if tried to complete the definition of the class. Ali
(In reply to comment #1) > If others agree, please change the summary to something like > > __traits(isAbstractClass) uses the definition that it knows so far, not the > whole definition of the class > > > In any case, it would be a chicken and egg problem if static if tried to > complete the definition of the class. > > Ali How about follow the rules of checking recursive alias?
(In reply to comment #1) > If others agree, please change the summary to something like > > __traits(isAbstractClass) uses the definition that it knows so far, not the > whole definition of the class Internal note: The issue is that __traits(isAbstractClass) has side-effects. It will call `ClassDeclaration::isAbstract`, but this will not only return the result but also set the internal `isabstract` field for the class (damn getter functions with side-effects..). I guess semantic() wasn't called on the class at that point.
https://github.com/dlang/dmd/pull/5695 After my PR, the use of __traits(isAbstractClass) at the condition of static if in class member will be rejected, because of the unresolved forward reference. For example: class C { static if (__traits(isAbstractClass, C)) { abstract void foo(); } }
Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/6fd1005dff51380e7bcb11dbc71e2c8bbb46cfb6 fix Issue 11169 - __traits(isAbstractClass) prematurely sets a class to be abstract __traits(isAbstractClass) should resolve forward references of all class member functions, in order to return stable result. https://github.com/dlang/dmd/commit/1bc9bad46c0539b243cca683d38cb19677771870 Merge pull request #5695 from 9rnsr/fix11169 Issue 11169 - __traits(isAbstractClass) prematurely sets a class to be abstract
Commits pushed to stable at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/6fd1005dff51380e7bcb11dbc71e2c8bbb46cfb6 fix Issue 11169 - __traits(isAbstractClass) prematurely sets a class to be abstract https://github.com/dlang/dmd/commit/1bc9bad46c0539b243cca683d38cb19677771870 Merge pull request #5695 from 9rnsr/fix11169
Commit pushed to dmd-cxx at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/37c1edd25e261ac09aebfee28ed6890a01598d16 Issue 11169 - __traits(isAbstractClass) prematurely sets a class to be abstract