D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 11169 - __traits(isAbstractClass) prematurely sets a class to be abstract
Summary: __traits(isAbstractClass) prematurely sets a class to be abstract
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 normal
Assignee: No Owner
URL:
Keywords: pull, rejects-valid
Depends on:
Blocks:
 
Reported: 2013-10-03 22:19 UTC by Elvis Zhou
Modified: 2020-03-21 03:56 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Elvis Zhou 2013-10-03 22:19:23 UTC
////////////////////////////////////////////////////////////
//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 Ali Cehreli 2013-10-03 23:27:26 UTC
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 Elvis Zhou 2013-10-03 23:48:02 UTC
(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 Andrej Mitrovic 2013-10-04 04:32:31 UTC
(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 Kenji Hara 2016-04-23 15:46:59 UTC
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 github-bugzilla 2016-04-27 10:18:18 UTC
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
Comment 6 github-bugzilla 2016-10-01 11:46:35 UTC
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
Comment 7 github-bugzilla 2017-08-02 08:07:06 UTC
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