Issue 15094 - __traits(getMember) fails when the source is a struct/class field
Summary: __traits(getMember) fails when the source is a struct/class field
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P1 normal
Assignee: No Owner
URL:
Keywords: industry, pull, rejects-valid
Depends on:
Blocks:
 
Reported: 2015-09-21 15:49 UTC by Alex Parrill
Modified: 2021-01-03 22:57 UTC (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Alex Parrill 2015-09-21 15:49:24 UTC
Attempting to use `__traits(getMember)` with a sub-struct/field fails with a `need 'this'` error.

Example code:


	import std.stdio;

	struct Foo {
		int i;
	}

	struct Bar {
		Foo foo;
	}

	void main() {
		Bar bar;
		writeln(__traits(getMember, bar.foo, "i"));
	}

Output:

	$ rdmd ~/test.d
	/home/col/test.d(14): Error: need 'this' for 'i' of type 'int'
	Failed: ["dmd", "-v", "-o-", "/home/col/test.d", "-I/home/col"]

It's possible, but annoying, to work around this by storing a local pointer to the field first.

	auto foo = &bar.foo;
	writeln(__traits(getMember, foo, "i"));
Comment 1 Vladimir Panteleev 2015-10-15 17:22:38 UTC
This appears to be a regression.

Introduced in https://github.com/D-Programming-Language/dmd/pull/1687
Comment 2 Kenji Hara 2015-10-21 01:25:45 UTC
(In reply to Vladimir Panteleev from comment #1)
> This appears to be a regression.
> 
> Introduced in https://github.com/D-Programming-Language/dmd/pull/1687

Not correct. With 2.062, compiling example code with `dmd -c` will make:

test.d(16): Error: need 'this' to access member foo

PR 1687 had moved many "need this" errors in glue layer to front-end, but such the field access is not yet supported. I think it's a reject-valid bug.
Comment 3 Vladimir Panteleev 2015-10-21 03:30:09 UTC
(In reply to Kenji Hara from comment #2)
> PR 1687 had moved many "need this" errors in glue layer to front-end, but
> such the field access is not yet supported. I think it's a reject-valid bug.

Oh, OK.
Comment 5 Eyal Lotem 2016-05-31 14:32:38 UTC
Even after applying the PR (https://github.com/D-Programming-Language/dmd/pull/5215):

```
struct S { int i; }
S s;

unittest {
    import std.meta : Alias;

    alias GetMember1 =
        Alias!(__traits(getMember, mixin(__MODULE__), "s"));
    alias GetMember2 =
        Alias!(__traits(getMember, GetMember1, "i"));
    alias GetMember3 =
        Alias!(__traits(getMember,
                        __traits(getMember, mixin(__MODULE__), "s"),
                        "i"));

    // Works:
    auto a1 = &GetMember1;
    // Fails:
    auto a2 = &GetMember2;
    // Fails:
    auto a3 = &GetMember3;
    // Works:
    auto a4 =
        &__traits(getMember,
                  __traits(getMember, mixin(__MODULE__), "s"),
                  "i");
}
```

fails (in a2, a3).
Comment 6 Eyal Lotem 2016-05-31 14:33:21 UTC
Even after applying the PR (https://github.com/D-Programming-Language/dmd/pull/5215):

```
struct S { int i; }
S s;

unittest {
    import std.meta : Alias;

    alias GetMember1 =
        Alias!(__traits(getMember, mixin(__MODULE__), "s"));
    alias GetMember2 =
        Alias!(__traits(getMember, GetMember1, "i"));
    alias GetMember3 =
        Alias!(__traits(getMember,
                        __traits(getMember, mixin(__MODULE__), "s"),
                        "i"));

    // Works:
    auto a1 = &GetMember1;
    // Fails:
    auto a2 = &GetMember2;
    // Fails:
    auto a3 = &GetMember3;
    // Works:
    auto a4 =
        &__traits(getMember,
                  __traits(getMember, mixin(__MODULE__), "s"),
                  "i");
}
```

fails (in a2, a3).
Comment 7 Eyal 2017-05-23 21:36:55 UTC
This bit us in several places in the weka codebase.
Comment 8 github-bugzilla 2017-11-26 14:41:32 UTC
Commits pushed to master at https://github.com/dlang/dmd

https://github.com/dlang/dmd/commit/89c900316c02d7e845b151e02a460d89631a9d07
Fix Issue 15094 - __traits(getMember) fails when the source is a struct/class field

https://github.com/dlang/dmd/commit/c9d988ebc0eca6137551eaacb961400acb2e7752
Merge pull request #7341 from JinShil/fix_15094

Fix Issue 15094 - __traits(getMember) fails when the source is a struct/class field
Comment 9 github-bugzilla 2017-12-18 22:57:33 UTC
Commits pushed to stable at https://github.com/dlang/dmd

https://github.com/dlang/dmd/commit/89c900316c02d7e845b151e02a460d89631a9d07
Fix Issue 15094 - __traits(getMember) fails when the source is a struct/class field

https://github.com/dlang/dmd/commit/c9d988ebc0eca6137551eaacb961400acb2e7752
Merge pull request #7341 from JinShil/fix_15094
Comment 10 Dlang Bot 2021-01-03 22:57:06 UTC
dlang/dmd pull request #12093 "[dmd-cxx] Backport more recent traits to the C++ port" was merged into dmd-cxx:

- 542f9a47d165eb27b2d3b937cadd119c779b07fe by JinShil:
  [dmd-cxx] Fix Issue 15094 - __traits(getMember) fails when the source is a struct/class field

https://github.com/dlang/dmd/pull/12093