On Wednesday, 3 May 2017 at 09:04:07 UTC, Jonathan M Davis wrote:
I believe that the core problem is that an alias declaration
just aliases a symbol - i.e. it just creates a new name for the
symbol. And as far as I can tell,
alias n2 = x2.n;
is actually equivalent to
alias n2 = member.n;
You get exactly the same error message if that change is made.
It's a bit like how you can call a static function with an
object rather than the struct/class(e.g. s.foo() instead of
S.foo()). Similarly, if you turn n into a member function, then
you get an error like
q.d(20): Error: this for n needs to be type member not type
outer
It's just aliasing the function, not creating a delegate or
doing a syntactic conversion. If it _were_ doing a syntactic
conversion and just making it so that everywhere you see n2, it
got changed to x.n, then I could see code like
outer o;
o.n2 = 5;
working. But that's not how alias declarations work. They just
create a new name for the symbol in the scope that they're
declared. So, the symbol isn't tied to a particular instance,
and you get the problem that you're having.
alias this is a bit different, because it isn't really aliasing
the symbol - rather it's telling the compiler about an implicit
conversion. So, that arguably confuses things a bit, but for
your example to work, normal alias declarations would need to
do more than create a new name for a symbol, and as I
understand it, they don't.
Now, I totally agree that it would be nice if your example
would work, and I think that I've run into this problem before
in my own code, but aliases would have to work a bit
differently than they curently do for it to work. It seems like
a reasonable enhancement request to me, but I'm not sure what
Walter's take on it would be. He has a tendancy to see things
how the compiler would in cases like this and not necessarily
how a typical programmer would, so it wouldn't surprise me if
he's reaction were that of course it wouldn't work, but I don't
know. It's often the case that what the programmer thinks is
intuitive doesn't really jive with how the language actually
works.
Thanks, that was enlightening. That said, if alias this really
did bring n into the outer scope in the specific case when it's a
variable in an embedded struct then `alias n2 = n` in the outer
scope would work in the ordinary way. After all,
struct fakeOuter
{
int n;
alias n2 = n;
}
void main()
{
fakeOuter o;
o.n2 = 5;
}
compiles and runs fine. And presumably as it's a struct being
embedded here
struct member
{
int n;
}
struct outer
{
member x;
alias x this;
//alias n2 = n;
}
the binary layouts of fakeOuter and outer are the same, so the
rename is harmless because it has a simple interpretation in
regular D without `alias this`.