https://issues.dlang.org/show_bug.cgi?id=17692
Issue ID: 17692 Summary: Filtering a struct instance's .tupleof loses contained this reference Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Severity: enhancement Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: htven...@gmail.com Okay, let's start with the code to reproduce, to put things in context: ----- import std.meta : Filter; import std.typecons : No; import std.traits : hasUDA; struct S { int a; int b; @(No.Wanted) int c; } private template isWanted(alias field) { enum isWanted = !hasUDA!(field, No.Wanted); } void foo(TS...)(TS args) { import std.conv : to; import std.stdio : writefln; foreach (index, arg; args) { writefln("%d: %s", index, arg.to!string); } } void main() { S s = S(5, 6, 7); foo(s.tupleof); // works, passes all struct fields as arguments foo(Filter!(isWanted, s.tupleof)); // error } ----- EXPECTED BEHAVIOR The both calls to foo() work, and the program outputs: 0: 5 1: 6 2: 7 0: 5 1: 6 ACTUAL BEHAVIOR Compilation fails with the following errors: tupleof_filter.d(31): Error: need 'this' for 'a' of type 'int' tupleof_filter.d(31): Error: need 'this' for 'b' of type 'int' REAL WORLD CASE I hit this while working on https://github.com/trishume/ddbus/pull/21, specifically when trying to allow selective marshaling of struct fields. I changed https://github.com/thaven/ddbus/blob/6bce6cf6490ce819f048b7ea8f1458ec66fbf1c8/source/ddbus/conv.d#L119 (which worked) from buildIter(&sub, arg.tupleof); to buildIter(&sub, Filter!(isAllowedField, arg.tupleof)); and added the isAllowedField predicate template and then got the 'no this for member' errors. I needed to rewrite this nice compact line of code into ugly `foreach` + `static if` to work around the issue. --