Issue 16123 - alias member of member
Summary: alias member of member
Status: NEW
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P4 enhancement
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-06-05 01:54 UTC by Steven Schveighoffer
Modified: 2024-08-26 11:21 UTC (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Steven Schveighoffer 2016-06-05 01:54:26 UTC
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 anonymous4 2016-06-06 14:56:24 UTC
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 Steven Schveighoffer 2016-06-06 15:11:17 UTC
(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 Max Samukha 2016-06-06 16:59:22 UTC
(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 Steven Schveighoffer 2016-06-06 17:28:44 UTC
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 Max Samukha 2016-06-06 18:08:15 UTC
(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 Steven Schveighoffer 2016-06-06 18:22:47 UTC
(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 Steven Schveighoffer 2016-06-06 18:37:04 UTC
(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.
Comment 8 Andrei Alexandrescu 2020-09-17 15:41:01 UTC
subscribe
Comment 9 Nick Treleaven 2024-08-26 11:21:01 UTC
>   S s;
>   alias y = s.x; // note, this compiles just fine, you need to use it to flag the error.

This is an error in the next edition:
https://dlang.org/spec/legacy#alias-instance-member

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