Currently, you can alias a member of your struct no problem:
struct S
{
int x;
alias y = x;
}
If I want to alias a member of a member, it does not work:
struct T
{
S s;
alias y = s.x; // note, this compiles just fine, you need to use it to flag the error.
}
void main()
{
T t;
t.s.y = 5; // ok
t.y = 5; // Error: need 'this' for 'x' of type 'int'
}
To me, this doesn't make sense. The requirements shouldn't be any different, if I can alias a member, I should be able to alias a member's member, especially if the member is a field.
I'm not sure if this is an enhancement or a bug. Flagging as bug, change if necessary.
Note, in older versions of the compiler (2.069 and earlier), I get an additional error:
Error: struct testalias.T 'x' is not a member
Comment #1 by dfj1esp02 — 2016-06-06T14:56:24Z
I guess, you can alias a symbol, but then the compiler doesn't know what S's symbol in T struct means.
struct S
{
int x;
alias y = x;
}
actually means
struct S
{
int x;
alias y = S.x;
}
struct T
{
S s;
alias y = S.x; // what this means?
}
Comment #2 by schveiguy — 2016-06-06T15:11:17Z
(In reply to Sobirari Muhomori from comment #1)
> struct T
> {
> S s;
> alias y = S.x; // what this means?
> }
Right, but I said s.x, not S.x. It means alias to the member x of the instance of S called s, which resides in this instance of T.
Maybe it's more helpful if I say:
alias y = T.s.x;
In any case, I see no technical limitation of why this shouldn't work. If there's already a way to do it, please close and let me know how to!
Note, I've worked around in my code by doing essentially:
private ref y() { return s.x; }
But I much prefer the alias mechanism.
Comment #3 by maxsamukha — 2016-06-06T16:59:22Z
(In reply to Steven Schveighoffer from comment #2)
> (In reply to Sobirari Muhomori from comment #1)
>
> > struct T
> > {
> > S s;
> > alias y = S.x; // what this means?
> > }
>
> Right, but I said s.x, not S.x. It means alias to the member x of the
> instance of S called s, which resides in this instance of T.
In 'alias', they are just two equivalent ways of referencing 'x', that is:
__traits(isSame, S.x, T.s.x) == true
And it kind of makes sense if you think of 'alias' as little more than a means of creating synonyms for a symbol. With 's.x' in the 'alias' declaration, you are simply importing 'x' to the namespace of 'T'. Not that I care much now, but some code I wrote actually relied on this semantics.
Comment #4 by schveiguy — 2016-06-06T17:28:44Z
I'm having trouble seeing how this logically is different. Access to t.s.x is done by adding some offset to &t, just like access to s.x is done by adding some offset to &s.
I get that the "symbol" I'm trying to alias is really a compound symbol, but I can alias it just fine in other places.
This reminds me of the whole inability to alias keywords. It's an implementation detail that I shouldn't have to care about!
Comment #5 by maxsamukha — 2016-06-06T18:08:15Z
(In reply to Steven Schveighoffer from comment #4)
> I'm having trouble seeing how this logically is different. Access to t.s.x
> is done by adding some offset to &t, just like access to s.x is done by
> adding some offset to &s.
>
> I get that the "symbol" I'm trying to alias is really a compound symbol, but
> I can alias it just fine in other places.
I just say that what you are trying is not how 'alias' works, and the current semantics does make sense. Whether it is good is a different issue.
>
> This reminds me of the whole inability to alias keywords. It's an
> implementation detail that I shouldn't have to care about!
Inability to alias keywords is a different issue.
Comment #6 by schveiguy — 2016-06-06T18:22:47Z
(In reply to Max Samukha from comment #5)
> (In reply to Steven Schveighoffer from comment #4)
> > I'm having trouble seeing how this logically is different. Access to t.s.x
> > is done by adding some offset to &t, just like access to s.x is done by
> > adding some offset to &s.
> >
> > I get that the "symbol" I'm trying to alias is really a compound symbol, but
> > I can alias it just fine in other places.
>
> I just say that what you are trying is not how 'alias' works, and the
> current semantics does make sense. Whether it is good is a different issue.
I would understand if s was a property and not a field, because you need to execute code to compute the actual access. I get that alias is not as powerful as a mixin, but this doesn't seem like a reasonable limitation.
Note: it's kind of weird that the compiler would allow this kind of alias to compile when it's fully unusable.
> > This reminds me of the whole inability to alias keywords. It's an
> > implementation detail that I shouldn't have to care about!
>
> Inability to alias keywords is a different issue.
To the user, it's not much different. Granted, two different implementation issues, but it looks the same -- compiler cannot do what should be obviously doable.
Comment #7 by schveiguy — 2016-06-06T18:37:04Z
(In reply to Max Samukha from comment #5)
> I just say that what you are trying is not how 'alias' works, and the
> current semantics does make sense. Whether it is good is a different issue.
However, I get your point that this is intended behavior and working as designed. I'm changing to enhancement.