digitalmars.D.learn - inout auto ref escaping a reference to parameter, only errors with
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
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
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