https://issues.dlang.org/show_bug.cgi?id=21868
Dennis <dkor...@live.nl> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |dkor...@live.nl --- Comment #1 from Dennis <dkor...@live.nl> --- Here's it reduced some more: ``` struct S { int buf; int* ptr; // <= required } int* getPtr(ref return scope S this_) { return &this_.buf; } ``` Since getPtr does not return by `ref`, the `return scope` applies to the members of `S` and not the `ref this_` itself. The compiler checks whether `&this_.buf;` is escaped by value. In `visit(AddrExp e)` of escape.d, it reduces this to checking whether `this_.x` escapes by ref, which reduces to checking whether `this_` escapes by ref. Then it looks at the parameter's storage classes, and sees `return`, so it allows it. This is wrong, the `return` does not apply to `&this_.x`, only to `this_.buf`; Without the `buf` member, S has no pointers, so the `return scope` attribute is meaningless, so it is stripped away at some earlier stage. This way the compiler can't mistake it for a `ref return`, so it raises an error. I'm still trying to grasp the incredibly difficult logic in escape.d so I'm not sure how to fix this yet. --