www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - inout auto ref escaping a reference to parameter, only errors with

reply aliak <something something.com> writes:
Hi,

I have an error that says "Error: returning `match1(opt)` escapes 
a reference to parameter `opt`, perhaps annotate with `return`".

The code is here: https://run.dlang.io/is/ESZDW4 (It's copied at 
the end of this post as well)

1) If you remove the inout from line 11. It works.
2) If you *do not* call match2 and call match1 instead, it also 
works.
3) If you return something other than vibe's Json type, it works 
(afaict)

Am I using inout wrong? Why is it only happen with Json type so 
far. If I return any other random struct it works fine. And why 
does it work if I don't go through the "match2" template? Any 
help would be much appreciated.

---

template match1(handlers...) {
     auto ref match1(T)(inout auto ref Optional!T opt) { // remove 
inout, it works
         if (opt.empty) {
             return  handlers[1]();
         } else {
             return  handlers[0](opt.front);
         }
     }
}

template match2(handlers...) {
     auto match2(T)(auto ref Optional!T opt) {
         return match1!handlers(opt);
     }
}

void main() {
     some(1)
         .match2!( // use match1, it works
             (int i) {return Json(1);}, // return anything else, 
it works
             () {return Json(1);}
         )
         .writeln;
}

Cheers,
- Ali
Mar 11 2019
next sibling parent aliak <something something.com> writes:
On Monday, 11 March 2019 at 22:29:05 UTC, aliak wrote:
 Hi,

 I have an error that says "Error: returning `match1(opt)` 
 escapes a reference to parameter `opt`, perhaps annotate with 
 `return`".

 [...]
Ok, I've found out something else. It only happens when you're returning a type that has an indirection. So instead of the Json type if we returned an S type where S was: struct S { void[2] data; } We get the same error.
Mar 12 2019
prev sibling parent aliak <something something.com> writes:
On Monday, 11 March 2019 at 22:29:05 UTC, aliak wrote:
 [...]
Here's a much reduces test case: struct W(T) {} struct S { int* data; } template match1(alias handler) { auto ref match1(T)(inout auto ref W!T w) { return handler(); } } template match2(alias handler) { auto match2(T)(auto ref W!T w) { return match1!handler(w); } } void main() { W!int() .match2!(() => S()); }
Mar 12 2019