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