www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 19615] New: alias this not taken when member is

https://issues.dlang.org/show_bug.cgi?id=19615

          Issue ID: 19615
           Summary: alias this not taken when member is
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: qs.il.paperinik gmail.com

When a class/struct has alias-this and a (different) member is accessed, but
accessing fails, e.g. the the member is a function (i.e. a method) with no
overload viable with the given argument types, the alias-this member is not
being tried.

struct Test1
{
    // Note: No arguments
    int member() { return 0; }
}

struct Test2
{
    Test1 field;
    alias field this;

    // Note: One argument
    int member(int n) { return n; }
}

void main()
{
    Test2 test;
    static assert(!__traits(compiles, {
        int i1 = test.member();
    }));
    int i2 = test.field.member();
}

Removing member from Test2 makes the static assert fail, i.e. the alias-this
access valid.

In this minimal example, it can be helped adding a trivial overload of member
to Test2. This is not always viable, e.g. if the alias-this references
something that cannot be returned by a function: An AliasSeq.

struct Test(bool hasIndex, Types...)
{
    Types fields;
    alias fields this;

    static if (hasIndex)
    {
        int[] opIndex()
        {
            return [ ];
        }
    }
}

void main()
{
    Test!(false, int) testF;
    int[] iF = testF[]; // fails: no opIndex (intended)
    testF[0] = 1; // ok: equivalent to `testF.fields[0] = 1` by alias this

    Test!(true, int) testT;
    int[] iT = testT[]; // ok: equivalent to `testT.opIndex()`
    testT[0] = 1; // fails: testT.opIndex not callable with one argument.
}

There is no way to have slice obj[] and type-safe access to the fields with
obj[index] at the same time.

This can be resolved, too, by letting the compiler not rewrite obj[0] to
obj.opIndex(0) if the call does not compile.

--
Jan 25 2019