August 25
Please post complete examples of the cases, instead of just the line with the error message. The missing lines are critical to understanding the bug report.
August 26
On Monday, 26 August 2024 at 05:25:00 UTC, Walter Bright wrote:
> Please post complete examples of the cases, instead of just the line with the error message. The missing lines are critical to understanding the bug report.

I must be trolling.
August 26
On 8/26/24 07:21, Walter Bright wrote:
> On 8/24/2024 9:36 AM, Manu wrote:
>> alias x = s.tupleof; // this works
>> alias y = s.tupleof[0]; // this is a compile error?!
> 
> 
> Can you please repost with the missing declarations from your example? Thanks!

This suffices to reproduce:

```d
struct S{ int x; }
S s;
alias x = s.tupleof; // this works
alias y = s.tupleof[0]; // this is a compile error?!
```

The underlying issue is that `.tupleof` has some magic that is not accessible to aliases.

Consider:

```d
struct S{ int x; }
void main(){
    S s;
    alias x = s.tupleof;
    x[0] = 2; // ok
    alias y = s.x;
    y = 2; // error
}
```

So `x[0]` is an alias to the field of an instance.

I think all of these examples should just work.

When template parameters get involved however, local instantiation can get a bit tricky. So making it work without breakage probably also comes down to the issue that local instantiation works with only one context, which had a fix in DMD but was never ported to GDC and LDC, and was then reverted via deprecation in DMD as well. This is one of the most annoying and long-standing issues in D.
August 27
On Mon, 26 Aug 2024 at 18:45, Timon Gehr via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On 8/26/24 07:21, Walter Bright wrote:
> > On 8/24/2024 9:36 AM, Manu wrote:
> >> alias x = s.tupleof; // this works
> >> alias y = s.tupleof[0]; // this is a compile error?!
> >
> >
> > Can you please repost with the missing declarations from your example? Thanks!
>
> This suffices to reproduce:
>
> ```d
> struct S{ int x; }
> S s;
> alias x = s.tupleof; // this works
> alias y = s.tupleof[0]; // this is a compile error?!
> ```
>
> The underlying issue is that `.tupleof` has some magic that is not accessible to aliases.
>
> Consider:
>
> ```d
> struct S{ int x; }
> void main(){
>      S s;
>      alias x = s.tupleof;
>      x[0] = 2; // ok
>      alias y = s.x;
>      y = 2; // error
> }
> ```
>
> So `x[0]` is an alias to the field of an instance.
>
> I think all of these examples should just work.
>
> When template parameters get involved however, local instantiation can get a bit tricky. So making it work without breakage probably also comes down to the issue that local instantiation works with only one context, which had a fix in DMD but was never ported to GDC and LDC, and was then reverted via deprecation in DMD as well. This is one of the most annoying and long-standing issues in D.
>

I endorse every word of this post.


August 27
On 8/26/2024 1:40 AM, Timon Gehr wrote:
> When template parameters get involved however, local instantiation can get a bit tricky. So making it work without breakage probably also comes down to the issue that local instantiation works with only one context, which had a fix in DMD but was never ported to GDC and LDC, and was then reverted via deprecation in DMD as well. This is one of the most annoying and long-standing issues in D.

Was that the multiple context pointer thing?

Multiple inheritance again :-/
August 28

On Monday, 26 August 2024 at 05:25:00 UTC, Walter Bright wrote:

>

Please post complete examples of the cases, instead of just the line with the error message. The missing lines are critical to understanding the bug report.

struct T
{
  void myFun(int) {}
}
T instance;
enum funName = "myFun";

void main()
{
    int args = 0;
    alias fun = __traits(getMember, instance, funName);
    return fun(args);   // error : calling non-static function `myFun` requires an instance of type `T`
}

-Steve

August 28
On Sunday, 25 August 2024 at 19:42:08 UTC, Timon Gehr wrote:
> On 8/25/24 21:35, user1234 wrote:
>> 
>> Just in case, the kind of alias you are debating about is to be deprecated, see https://dlang.org/spec/legacy.html#alias-instance-member.
>
> Well, first it should be deprecated,

I did that first, Walter said it shouldn't be a deprecation:
https://github.com/dlang/dmd/pull/15863#issuecomment-1902711081

The problem is that if someone understood what it actually does (alias a member of a type), then deprecating that will deprecate correct code. But I think the confusion justifies a deprecation.

So it was made a next edition error. Possibly it could be a warning in the current edition with -w.

I did refine the error so it only happens for members of an instance that need `this` - https://github.com/dlang/dmd/pull/16813, merged yesterday.
August 28

On Sunday, 25 August 2024 at 05:07:43 UTC, Manu wrote:

>

Like, from my example above, what even IS s.tupleof? It's some kind of
list of what kind of thing? Direct symbol references to members of a live
instance?

It's a symbol sequence of references to fields.

import std;

struct S
{
    int i;
    char c;
}

void main()
{
    S s = {2, 'c'};
    ref si = s.i;
    ref sc = s.c;
    alias tupleof = AliasSeq!(si, sc); // same as s.tupleof
    tupleof[0]++;
    s.writeln();
    assert(s.i == 3);

    // this actually works
    alias a = tupleof[0];
    a++;
    assert(s.i == 4);
}

So alias e = s.tupleof[0]; could be made to work.

See also: https://dlang.org/spec/template.html#lvalue-sequences.

BTW I'd like to make sequences a separate spec page from templates really.

>

If s.tupleof can populate a list with that kind of thing, why doesn't this
work:

struct S
{
int x, y;
}

struct T
{
S s;
int i;

alias a = i; // works
alias b = s.x; // Doesn't work? Why?
}

a is a symbol alias. b would be an expression if it did what you want. Instead it's the same as S.x, which needs an instance of S to use it at runtime.

However, you could now use ref b = s.x; instead inside a method of T.

...

>

alias b = s.tupleof[0]; // this emits a surprising error message:

error : alias b cannot alias an expression AliasSeq!(s.x, s.y)[0]
So, that 'list' I mention; does this error message imply that this list given by tupleof is an AliasSeq? What exactly IS an AliasSeq? What is the actual set of things that it can hold?

Symbols (declarations) and compile-time values. S.x is a declaration, s.x is a runtime value.

tupleof is a symbol sequence of implicit ref declarations.

August 28
On Wed, 28 Aug 2024 at 19:46, Nick Treleaven via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On Sunday, 25 August 2024 at 05:07:43 UTC, Manu wrote:
> > Like, from my example above, what even IS `s.tupleof`? It's
> > some kind of
> > list of what kind of thing? Direct symbol references to members
> > of a live
> > instance?
>
> It's a symbol sequence of references to fields.
>
> ```d
> import std;
>
> struct S
> {
>      int i;
>      char c;
> }
>
> void main()
> {
>      S s = {2, 'c'};
>      ref si = s.i;
>      ref sc = s.c;
>      alias tupleof = AliasSeq!(si, sc); // same as s.tupleof
>      tupleof[0]++;
>      s.writeln();
>      assert(s.i == 3);
>
>      // this actually works
>      alias a = tupleof[0];
>      a++;
>      assert(s.i == 4);
> }
> ```
>
> So `alias e = s.tupleof[0];` could be made to work.
>
> See also: https://dlang.org/spec/template.html#lvalue-sequences.
>
> BTW I'd like to make sequences a separate spec page from templates really.
>
> > If s.tupleof can populate a list with that kind of thing, why
> > doesn't this
> > work:
> >
> > struct S
> > {
> >   int x, y;
> > }
> >
> > struct T
> > {
> >   S s;
> >   int i;
> >
> >   alias a = i; // works
> >   alias b = s.x; // Doesn't work? Why?
> > }
>
> `a` is a symbol alias. `b` would be an expression if it did what you want. Instead it's the same as `S.x`, which needs an instance of S to use it at runtime.
>

Not necessarily; it doesn't need to carry around the expression; it could evaluate the resolve the expression on the spot.


> > alias b = s.tupleof[0]; // this emits a surprising error message:
> >
> > error : alias `b` cannot alias an expression `AliasSeq!(s.x,
> > s.y)[0]`
> > So, that 'list' I mention; does this error message imply that
> > this list given by `tupleof` is an AliasSeq? What exactly IS an
> > AliasSeq? What is the actual set of things that it can hold?
>
> Symbols (declarations) and compile-time values. S.x is a
> declaration, s.x is a runtime value.
>
> `tupleof` is a symbol sequence of implicit ref declarations.
>

What's a 'ref'?


August 28

On Wednesday, 28 August 2024 at 10:41:25 UTC, Manu wrote:

>

On Wed, 28 Aug 2024 at 19:46, Nick Treleaven via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> >

struct T
{
S s;
int i;

alias a = i; // works
alias b = s.x; // Doesn't work? Why?
}

a is a symbol alias. b would be an expression if it did what you want. Instead it's the same as S.x, which needs an instance of S to use it at runtime.

Not necessarily; it doesn't need to carry around the expression; it could evaluate the resolve the expression on the spot.

It resolves to the field declaration x, which knows nothing about s - because s.x is not a declaration. It might confuse the concept of aliases if you allow them to refer to some sub-part of a declaration.

You could instead write:

ref b() => s.x;
> >

tupleof is a symbol sequence of implicit ref declarations.

What's a 'ref'?

https://dlang.org/changelog/pending.html#dmd.reflocal