Bug 11169 – __traits(isAbstractClass) prematurely sets a class to be abstract
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-10-03T22:19:23Z
Last change time
2020-03-21T03:56:37Z
Keywords
pull, rejects-valid
Assigned to
No Owner
Creator
Elvis Zhou
Comments
Comment #0 by elvis.x.zhou — 2013-10-03T22:19:23Z
////////////////////////////////////////////////////////////
//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
////////////////////////////////////////////////////////////
Comment #1 by acehreli — 2013-10-03T23:27:26Z
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
Comment #2 by elvis.x.zhou — 2013-10-03T23:48:02Z
(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?
Comment #3 by andrej.mitrovich — 2013-10-04T04:32:31Z
(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.
Comment #4 by k.hara.pg — 2016-04-23T15:46:59Z
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();
}
}
Comment #5 by github-bugzilla — 2016-04-27T10:18:18Z