www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 17692] New: Filtering a struct instance's .tupleof loses


          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: nobody puremagic.com
          Reporter: htvennik 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



The both calls to foo() work, and the program outputs:
0: 5
1: 6
2: 7
0: 5
1: 6


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'


I hit this while working on https://github.com/trishume/ddbus/pull/21,
specifically when trying to allow selective marshaling of struct fields. I
(which worked) from

buildIter(&sub, arg.tupleof);


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.

Jul 25 2017