Thread overview
[Issue 19877] [dip1000] std.container.rbtree is unsafely accessing private data
[Issue 19877] [dip1000] 'private' makes toHash un-@safe
Mar 12, 2020
Walter Bright
Mar 12, 2020
Walter Bright
Apr 03, 2022
Dennis
May 15, 2019
https://issues.dlang.org/show_bug.cgi?id=19877

hsteoh@quickfur.ath.cx changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |rejects-valid
            Summary|'private' makes toHash      |[dip1000] 'private' makes
                   |un-@safe in                 |toHash un-@safe
                   |-preview=dip1000            |

--
May 16, 2019
https://issues.dlang.org/show_bug.cgi?id=19877

--- Comment #1 from hsteoh@quickfur.ath.cx ---
Here's a much more reduced case:
------
struct S {
        private int _x;
}
struct RedBlackTree
{
    size_t toHash() nothrow @safe
    {
        return .hashOf(S.init);
    }
}
void main() { }
------

--
March 12, 2020
https://issues.dlang.org/show_bug.cgi?id=19877

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com
          Component|dmd                         |phobos

--- Comment #2 from Walter Bright <bugzilla@digitalmars.com> ---
The cause of this is core.internal.hash.hashOf() is getting its attributes inferred. Having it access private members of a struct causes it to be inferred as @system, and @safe RedBlackTree.toHash() is not allowed to call an @system function.

The problem is in std.container.rbtree, where the call to .toHash() should be put in an @trusted block.

--
March 12, 2020
https://issues.dlang.org/show_bug.cgi?id=19877

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|[dip1000] 'private' makes   |[dip1000]
                   |toHash un-@safe             |std.container.rbtree is
                   |                            |unsafely accessing private
                   |                            |data

--
June 07, 2021
https://issues.dlang.org/show_bug.cgi?id=19877

Ajieskola@gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |Ajieskola@gmail.com
          Component|phobos                      |druntime

--- Comment #3 from Ajieskola@gmail.com ---
I'd argue it behaves correctly now. Private state should be private. If `.hashOf`, or any other external funtion, needs to access it directly, it ought to fail. The correct thing to do is to add `toHash` member function to the element `struct`.

Current `-dip1000` prevents errors like this:

```
struct Ternary
{ private ubyte state;
  @safe auto opEquals(const Ternary rhs) const
  { if (state >= 2) return rhs.state >= 2;
    else return state == rhs.state;
  }
}

@safe void main()
{ Ternary a = void, b = void;
  //fails with high likelihood
  if(a == b) assert(.hashOf(a) == .hashOf(b), "WAT?");
}
```

Perhaps the error message should suggest adding the `toHash` function, though.

--
April 03, 2022
https://issues.dlang.org/show_bug.cgi?id=19877

Dennis <dkorpel@live.nl> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |dkorpel@live.nl
         Resolution|---                         |FIXED

--- Comment #4 from Dennis <dkorpel@live.nl> ---
Fixed by https://github.com/dlang/dmd/pull/13522

--