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

[email protected] changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |[email protected]
         Resolution|---                         |INVALID

--- Comment #1 from [email protected] ---
(In reply to Atila Neves from comment #0)
> struct MockScope(T) {
>     this(T)(ref T oldFunc, T newFunc) {
>         _oldFuncPtr = &oldFunc;
[...]
>     }
[...]
> }
> 
> struct Mock(T) {
>     this(ref T func) {
[...]
>         _scope = MockScope!(T)(func, &inner);
>     }
[...]
> }
> 
> auto mock(T)(T f) {
>     return Mock!T(f);
> }
> 
> void main() {
>     //auto m = Mock!(typeof(dg))(dg); //this works
>     auto m = mock(dg); // this should be equivalent but crashes
[...]
> }

mock's parameter f is not ref. So it's constructing a Mock/MockScope that
references its local f. Once mock returns, the local f ceases to exists.
Dereferencing the pointer to it is bound to fail then.

When you change mock's parameter to ref, it no longer crashes in that way. But
it doesn't work either. It then boils down to this:

----
struct Mock {
    this(ref int delegate() func) {
        func = {return _return;};
    }
    int _return = 41;
}

Mock mock(ref int delegate() f) {
    return Mock(f);
}

void main() {
    int delegate() dg;
    version (good) auto m = Mock(dg); // works
    else auto m = mock(dg); // fails
    assert(dg() == 41);
    m._return = 42;
    assert(dg() == 42);
}
----

I think I can see the problem here, and it's similar to be above: When mock
returns, the Mock is copied. But the delegate that's created in the constructor
references the old, temporary location. When mock returns, the delegate gets
invalidated. It references garbage from then on.

As far as I see, everything works as expected here, so I'm closing this as
invalid. Please reopen if I have missed something, or if you think that
something should work differently.

--

Reply via email to