`alias x = v.x;` not working in struct bodies?

Steven Schveighoffer schveiguy at gmail.com
Sat Jan 20 22:16:35 UTC 2024


On Saturday, 20 January 2024 at 09:00:22 UTC, Danilo wrote:

> Can't `alias` targets be used in method bodies?
>
> In the method/constructor parameters it's working as expected. 
> But not inside the bodies?

alias is always about a *symbol*. It is not about an 
*expression*. Yes, in some cases (such as template parameters) 
you can alias an expression. This is not the same thing.

So when you do:

```d
alias x = v.x;
```

What you are doing is saying `x` is an alias to `Vec2.x`, the 
symbol. The `v` plays no part in it except to be a namespace -- 
it does not help clarify which x you are talking about.

Why does it work for normal members? To be clear, I'm talking 
about:

```d
struct S
{
    int x;
    alias x2 = x;
}

```

It's actually the same thing thing as your `v.x` example! `x2` is 
an alias to the *symbol* `S.x`, not to the instance variable 
`this.x`. It works because when you access it, you are accessing 
it *through* the instance variable, and the compiler says "aha! 
the symbol `x` on the instance, I know how to access that". But 
when you access the symbol `Vec2.x` on a `Vec3`, it doesn't know 
how to resolve that without a (proper) instance (remember, the 
`v` is just used for namespacing, not directing how to access the 
alias).

So how do you do it?

```d
struct Vec3
{
    Vec2 v;
    ref x() => v.x;
    ref y() => v.y;
}
```

It's not perfect, as taking the address of `x` will yield a 
delegate, and not a pointer to the member, but it's the best you 
can do.

Now, you might wonder, why does alias work when passed to a 
template function? Because the compiler adds a *hidden context* 
parameter, which then tells it how to access the variable. This 
is a feature which does not apply everywhere alias is used -- you 
are not always calling a function where a context parameter can 
be passed.

-Steve


More information about the Digitalmars-d mailing list