[Issue 9148] 'pure' is broken

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Fri Apr 25 20:25:43 PDT 2014


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

Xinok <xinok at live.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |xinok at live.com

--- Comment #3 from Xinok <xinok at live.com> ---
'S.bar' is immutable, meaning it can only access immutable members of 'S', so
the error is correct.

's.bar' (note the s is lowercase) 

(In reply to timon.gehr from comment #0)
> - There is no way to specify that a delegate is strongly pure without
> resorting to type deduction, because
>   - Member functions/local functions are handled inconsistently.
>     - Delegate types legally obtained from certain member functions are
> illegal to declare.
>     - 'pure' means 'weakly pure' for member functions and 'strongly pure'
> for local functions. Therefore it means 'weakly pure' for delegates, as
> those can be obtained from both.

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.

> - Delegates may break the transitivity of immutable, and by extension,
> shared.
> 
> A good first step in fixing up immutable/shared would be to make everything
> that is annotated 'error' pass, and the line annotated 'ok' should fail:
> 
> import std.stdio;
> 
> struct S{
>     int x;
>     int foo()pure{
>         return x++;
>     }
>     int bar()immutable pure{
>         // return x++; // error
>         return 2;
>     }
> }

Immutable functions can only read immutable members, so this error is actually
correct.

> 
> 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.

> 
> 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


Other than some confusion with member functions vs local functions, I'm not
sure there's actually any bugs here.

--


More information about the Digitalmars-d-bugs mailing list