Thread overview
[Issue 12000] New: Forward reference issue with RefCounted
Jan 26, 2014
Walter Bright
Jan 26, 2014
Walter Bright
Jan 26, 2014
Walter Bright
Jan 27, 2014
Kenji Hara
Jan 27, 2014
Kenji Hara
January 26, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=12000

           Summary: Forward reference issue with RefCounted
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: andrei@erdani.com


--- Comment #0 from Andrei Alexandrescu <andrei@erdani.com> 2014-01-25 18:37:19 PST ---
Consider:

import std.typecons;

struct GroupBy(R)
{
    struct SharedInput
    {
        Group unused;
    }

    struct Group
    {
        private RefCounted!SharedInput _allGroups;
    }
}

unittest
{
    GroupBy!(int[]) g1;
}

This came about while I was working on #5968. The intent here is to have each group have a backreference to the mother hen of all groups. However, the code does not compile due to protests about forward reference issues (specifically not knowing the size). It should, seeing as RefCounted is just a pointer so the size is not needed to define Group's layout.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 26, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=12000


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com


--- Comment #1 from Walter Bright <bugzilla@digitalmars.com> 2014-01-25 20:48:39 PST ---
Eliminating the dependency on Phobos:
--------------------------------------------
struct RefCounted(T)
{
    struct RefCountedStore
    {
        private struct Impl
        {
            SharedInput _payload;
        }

        private void initialize(A...)(auto ref A args)
        {
            import core.memory;
        }

        void ensureInitialized()
        {
            initialize();
        }

    }
    RefCountedStore _refCounted;

    void opAssign(SharedInput rhs)
    {
    }

    int refCountedPayload()
    {
        _refCounted.ensureInitialized();
        return 0;
    }

    int refCountedPayload() inout;

    alias refCountedPayload this;
}

struct SharedInput
{
    Group unused;
}

struct Group
{
    RefCounted!SharedInput _allGroups;
}
------------------------------------------------
foo.d(6): Error: struct
foo.RefCounted!(SharedInput).RefCounted.RefCountedStore.Impl unable to resol
ve forward reference in definition
foo.d(46): Error: template instance foo.RefCounted!(SharedInput) error
instantiating

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 26, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=12000


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |regression


--- Comment #2 from Walter Bright <bugzilla@digitalmars.com> 2014-01-25 21:08:42 PST ---
Just noticed this compiles with 2.064, marking as regression

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 26, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=12000



--- Comment #3 from Walter Bright <bugzilla@digitalmars.com> 2014-01-25 21:10:37 PST ---
Actually, example 1 still fails with 2.064, while example 2 succeeds.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 27, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=12000


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

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|DMD                         |Phobos
         Depends on|                            |12008
           Severity|regression                  |normal


--- Comment #4 from Kenji Hara <k.hara.pg@gmail.com> 2014-01-27 01:27:41 PST ---
(In reply to comment #1)
> Eliminating the dependency on Phobos:
[snip]

I separated compiler regression into issue 12008.

(In reply to comment #0)
> Consider:
> 
> import std.typecons;
> 
> struct GroupBy(R)
> {
>     struct SharedInput
>     {
>         Group unused;
>     }
> 
>     struct Group
>     {
>         private RefCounted!SharedInput _allGroups;
>     }
> }
> 
> unittest
> {
>     GroupBy!(int[]) g1;
> }
> 
> This came about while I was working on #5968. The intent here is to have each group have a backreference to the mother hen of all groups. However, the code does not compile due to protests about forward reference issues (specifically not knowing the size). It should, seeing as RefCounted is just a pointer so the size is not needed to define Group's layout.

The root cause is in the implementation of RefCounted.


import std.traits : hasIndirections;

struct RefCounted(T)
{
    ~this()
    {
        static if (hasIndirections!T) { /* ... */ }
    }
}

hasIndirections!T requires the full representation of T to calculate result. Therefore, contrary to the Andrei's thought, current RefCounted does not become just a pointer to T.

To fix the issue, following fix would be necessary.

struct RefCounted(T)
{
    ~this()
    {
        static if (!__traits(compiles, hasIndirections!T) || hasIndirections!T)
        { /* ... */ }
    }
}

It means that, if hasIndirections!T fails, assume T has forward reference to RefCounted!T.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 27, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=12000


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

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Depends on|                            |12009


--- Comment #5 from Kenji Hara <k.hara.pg@gmail.com> 2014-01-27 01:47:30 PST ---
I found one more compiler issue.
Issue 12009 - local import and "unable to resolve forward reference" error

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 05, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=12000


monarchdodra@gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |monarchdodra@gmail.com


--- Comment #6 from monarchdodra@gmail.com 2014-04-05 04:24:32 PDT ---
See also: http://forum.dlang.org/thread/wokatnixzkulvmfujamr@forum.dlang.org

Reduced to:
//----
struct S(T)
{
    static assert(hasIndirections!T);
}

class A(T)
{
    S!A a;
}

A!int dummy;
//----

In this case, it should work, since you don't need to know about A to know that it's a class, and as such, is an indirection.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 05, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=12000



--- Comment #7 from monarchdodra@gmail.com 2014-04-05 04:39:34 PDT ---
https://github.com/D-Programming-Language/phobos/pull/2070

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