[Issue 9148] 'pure' is broken

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Sat Apr 26 03:15:45 PDT 2014


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

--- Comment #4 from timon.gehr at gmx.ch ---
(In reply to Xinok from comment #3)
> 'S.bar' is immutable, meaning it can only access immutable members of 'S',
> so the error is correct.
> ...
> 
> Immutable functions can only read immutable members, so this error is
> actually correct.
> 

(Indeed. I already noted this.)

> I think the trouble of member functions vs local functions may be a
> technicality: The struct object is seen as a hidden argument passed to the 
> member function, whereas it's not seen this way with local functions. Because > pure functions can take mutable arguments, it will work for member functions. > But because the context pointer is not seen as an argument for local 
> functions, it fails.

But obviously it is a hidden argument. There are no distinctions to be made
between local functions and member functions in this respect, and this is
especially important since delegates can be formed from both and their types
need to have a consistent interpretation.

> > 
> > int delegate()pure s(){
> >     int x;
> >     int foo()pure{
> >         // return x++; // error
> >         return 2;
> >     }
> >     /+int bar()immutable pure{ // error
> >         return 2;
> >     }+/
> >     return &foo;
> > }
> 
> Function 'bar' actually compiles fine for me, no errors.
> ...

This is a change in behaviour since the bug was reported.

> > 
> > void main(){
> >     S s;
> >     int delegate()pure dg = &s.foo;
> >     // int delegate()pure immutable dg2 = &s.bar; // error
> >     writeln(dg(), dg(), dg(), dg()); // 0123
> >     immutable int delegate()pure dg3 = dg; // ok
> >     writeln(dg3(), dg3(), dg3(), dg3()); // 4567
> >     // static assert(is(typeof(cast()dg3)==int delegate() immutable pure));
> > // error
> >     auto bar = &s.bar;
> >     pragma(msg, typeof(bar)); // "int delegate() immutable pure"
> > }
> 
> immutable int delegate()pure == immutable(int delegate()pure) != int
> delegate() immutable pure
> ...

Sure. Why is this relevant? The first 'error' appears to be fine now. The line
annotated 'ok' absolutely must fail. In case this is not obvious consider the
following code, which compiles and runs fine now:

class C{}

C foo(immutable C delegate()@safe pure dg)pure @safe{
    return dg();
}

void main()@safe{
    C c = new C();
    struct S{
        C c;
        C foo()pure{ return c; }
    }
    S s=S(c);
    immutable(C) d=foo(&s.foo);
    assert(c is d);    
}

I.e. this 'ok' is a loophole that allows unsafe type coercion.

The static assertion should pass. If top-level immutable is stripped using the
cast(), this should not affect the qualification of the context pointer
(because this way, it is @safe).

This is analogous to 

immutable(int*) x;
static assert(is(typeof(cast()x)==immutable(int)*));

> 
> Other than some confusion with member functions vs local functions,

(This confusion is actually the main part of the bug report and all the other
problems seem to be quite related to it.)

> I'm not sure there's actually any bugs here.

Some parser limitations appear to have been fixed since this issue was reported
but there are still plenty bugs as demonstrated above.

--


More information about the Digitalmars-d-bugs mailing list