May 15, 2019
On Wednesday, 15 May 2019 at 07:56:48 UTC, Walter Bright wrote:
> Maybe the clock is not synchronized somewhere.

It's off by one hour.
May 15, 2019
On Wed, May 15, 2019 at 12:39:05AM -0700, Walter Bright via Digitalmars-d-announce wrote:
> https://github.com/dlang/phobos/pull/6931
> 
> This is a major milestone in improving the memory safety of D programming.  Thanks to everyone who helped with this!
> 
> Time to start compiling your projects with DIP1000, too!

My very first attempt to compile my code with -preview=dip1000 led to a regression. :-(

Reduced code:
------
import std.container.rbtree;
alias Grid = RedBlackTree!(GridPoint);
struct GridPoint
{
    private string _srcStr;
    int opCmp(in GridPoint p) const { return 0; }
}
------

Compiler output (with -preview=dip1000):
------
/usr/src/d/phobos/std/container/rbtree.d(1111): Error: `@safe` function `std.container.rbtree.RedBlackTree!(GridPoint, "a < b", false).RedBlackTree.toHash` cannot call `@system` function `core.internal.hash.hashOf!(GridPoint).hashOf`
/usr/src/d/druntime/import/core/internal/hash.d(510):        `core.internal.hash.hashOf!(GridPoint).hashOf` is declared here
numid.d(3): Error: template instance `std.container.rbtree.RedBlackTree!(GridPoint, "a < b", false)` error instantiating
------

The culprit is the 'private' in GridPoint.  Removing 'private' gets rid of the problem.

*Why* putting 'private' on a field member makes toHash unsafe, is beyond my ability to comprehend.


T

-- 
Windows: the ultimate triumph of marketing over technology. -- Adrian von Bidder
May 15, 2019
On Wed, May 15, 2019 at 11:09:01AM -0700, H. S. Teoh via Digitalmars-d-announce wrote:
> On Wed, May 15, 2019 at 12:39:05AM -0700, Walter Bright via Digitalmars-d-announce wrote:
> > https://github.com/dlang/phobos/pull/6931
> > 
> > This is a major milestone in improving the memory safety of D programming.  Thanks to everyone who helped with this!
> > 
> > Time to start compiling your projects with DIP1000, too!
> 
> My very first attempt to compile my code with -preview=dip1000 led to a regression. :-(
[...]

Bugzilla issue:

	https://issues.dlang.org/show_bug.cgi?id=19877


T

-- 
To err is human; to forgive is not our policy. -- Samuel Adler
May 15, 2019
On 5/15/2019 11:09 AM, H. S. Teoh wrote:
> *Why* putting 'private' on a field member makes toHash unsafe, is beyond
> my ability to comprehend.

That's because the reduced version isn't a reduced version. It imports a vast amount of other code.
May 15, 2019
On Wed, May 15, 2019 at 11:34:44AM -0700, Walter Bright via Digitalmars-d-announce wrote:
> On 5/15/2019 11:09 AM, H. S. Teoh wrote:
> > *Why* putting 'private' on a field member makes toHash unsafe, is beyond my ability to comprehend.
> 
> That's because the reduced version isn't a reduced version. It imports a vast amount of other code.

Alright, here's a TRULY reduced version:

----
struct S {
	private int _x;
}
struct RedBlackTree
{
    size_t toHash() nothrow @safe
    {
	return .hashOf(S.init);
    }
}
void main() { }
----

Compiling with -preview=dip1000 causes a compile error complaining that toHash() is not @safe.  Removing 'private' makes it go away. Compiling without -preview=dip1000 also makes it go away.

Now explain this one. :-D


T

-- 
A linguistics professor was lecturing to his class one day. "In English," he said, "A double negative forms a positive. In some languages, though, such as Russian, a double negative is still a negative. However, there is no language wherein a double positive can form a negative." A voice from the back of the room piped up, "Yeah, yeah."
May 15, 2019
On Wed, May 15, 2019 at 05:53:17PM -0700, H. S. Teoh via Digitalmars-d-announce wrote:
> On Wed, May 15, 2019 at 11:34:44AM -0700, Walter Bright via Digitalmars-d-announce wrote:
> > On 5/15/2019 11:09 AM, H. S. Teoh wrote:
> > > *Why* putting 'private' on a field member makes toHash unsafe, is beyond my ability to comprehend.
> > 
> > That's because the reduced version isn't a reduced version. It imports a vast amount of other code.
> 
> Alright, here's a TRULY reduced version:

Gah, so apparently .hashOf is a gigantic overload set of *21* different overloads, so this is not really "truly" reduced. =-O

Anybody up for figuring out which overload(s) is/are getting called? Betcha the problem is that -preview=dip1000 causes one of the overloads to fail to compile, thus shuffling to a different overload that isn't @safe.  I hate SFINAE.


T

-- 
Just because you survived after you did it, doesn't mean it wasn't stupid!
May 16, 2019
On Thursday, 16 May 2019 at 01:05:53 UTC, H. S. Teoh wrote:
>  ...
>  I hate SFINAE.
>

But.. But D doesn't have it!11 NOOO!!1!


May 16, 2019
On Thursday, 16 May 2019 at 01:05:53 UTC, H. S. Teoh wrote:
> Gah, so apparently .hashOf is a gigantic overload set of *21* different overloads, so this is not really "truly" reduced. =-O
>
> Anybody up for figuring out which overload(s) is/are getting called?

https://github.com/dlang/druntime/blob/master/src/core/internal/hash.d#L393

static if (hasCallableToHash!(typeof(val))){ ... } // false
else
{
    static if (__traits(hasMember, T, "toHash") && is(typeof(T.toHash) == function)) { ... } // false
    else static if (T.tupleof.length == 0) { ... } // false
    else static if ((is(T == struct) && !canBitwiseHash!T) || T.tupleof.length == 1)//true
    {
        static foreach (i, F; typeof(val.tupleof))
        {
            static if (__traits(isStaticArray, F)) { ... } // false
            else static if (is(F == struct) || is(F == union)) { ... } // false
            else
            {
                    // Nothing special happening.
                    static if (i == 0 && !isChained)
                        size_t h = hashOf(val.tupleof[i]);
                    else
                        h = hashOf(val.tupleof[i], h);
            }
    }
}

> Betcha the problem is that -preview=dip1000 causes one of the overloads to fail to compile, thus shuffling to a different overload that isn't @safe.  I hate SFINAE.

My money's on access to a private member through .tupleof.
May 16, 2019
On Thursday, 16 May 2019 at 05:14:39 UTC, Nicholas Wilson wrote:
> [...]

Yes that sounds like the culprit. Btw as mentioned on DConf, the dip1000 switch contains a few other breaking changes which will make it even harder to adopt too.
May 16, 2019
On Thursday, 16 May 2019 at 04:29:10 UTC, evilrat wrote:
> On Thursday, 16 May 2019 at 01:05:53 UTC, H. S. Teoh wrote:
>>  ...
>>  I hate SFINAE.
>>
>
> But.. But D doesn't have it!11 NOOO!!1!

Not in the same sense as C++. But if the template constrains rely of is() statements, that is still a kind of explicitly-activated SFINAE.

If that's the case here, it's probably the template constraint that's badly designed.