Thread overview
[Issue 3546] Aliasing an element of a static array should be legal if the index is a compile time constant
Jun 14, 2020
Nick Treleaven
Jun 14, 2020
Nick Treleaven
Jun 14, 2020
Basile-z
Jun 15, 2020
Basile-z
Jun 16, 2020
Dlang Bot
Dec 17, 2022
Iain Buclaw
June 14, 2020
https://issues.dlang.org/show_bug.cgi?id=3546

Nick Treleaven <nick@geany.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |nick@geany.org

--- Comment #2 from Nick Treleaven <nick@geany.org> ---
> It works with tuples

I was a bit confused how that applied to runtime data until I thought of a type sequence instance:

auto f(T...)(T s)
{
    alias a = s[0];
    a = 3; // OK, s is an lvalue sequence
    return s[0];
}
static assert(f(1) == 3);

This is a bit surprising. So I suppose your example aliasing a compile-time known element of a static array of runtime data could also work. But I noticed aliasing a struct .tupleof doesn't work:

struct S {int i;}
auto f(){
    S s;
    s.tupleof[0] = 5; // OK, .tupleof appears to be an lvalue sequence
    alias seq = s.tupleof; // error
    alias a = s.tupleof[0]; // error
    alias a = s.i; // OK
    a = 4; // Error: need `this` for `i` of type `int`
    return s.i;
}
static assert(f(1) == 5);

--
June 14, 2020
https://issues.dlang.org/show_bug.cgi?id=3546

--- Comment #3 from Nick Treleaven <nick@geany.org> ---
> alias a = s.i; // OK

While this line compiles, even reading `a` triggers the same error:

> Error: need `this` for `i` of type `int`

--
June 14, 2020
https://issues.dlang.org/show_bug.cgi?id=3546

Basile-z <b2.temp@gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |b2.temp@gmx.com

--- Comment #4 from Basile-z <b2.temp@gmx.com> ---
The feature cannot be made using language tricks. What is requested here is really a function, i.e an expression to read or write from an offset. This is simply not supported by AliasDeclaration abd would require to add stuff in AliasDeclaration.

(while simply aliasing a ref getter will give good code gen with LDC2).

Technically the AST node for alias would require to store an additional IntegerExp, do some type check to see if building the IndexExp would work and then replace each use of the aliased symbol by an IndexExp.

When you alias an element of a compile time sequence, the element is solved at compile time and gives a symbol. For the ER, the element is not a symbol, it's an offset + a symbol.

Actually, I think this is feasible but not worth, just use a function. Also it is specified that alias cant give exp. supporting one special case could open the Pandora box...

more funny attempts to make it works with typecons/meta-like stuff:

1. try to turn elements as symbol and to index the new symbol...
---
int[2] sta = [0, 1];   // works for static immutable / enum  STC
auto staSeq = aliasSeqOf!sta;
alias sta1 = staSeq[1];
---

2. try to make explicit symbols as member of a union, in parallel of the static array.
---
struct AliasableStaticArray(T)
if (isStaticArray!T)
{
    alias E = ElementType!T;
    private static string getCodeForElements()
    {
        string result = "struct {";
        static foreach (i; 0 .. T.length)
        {
            result ~= E.stringof ~ " element" ~ i.to!string ~ "; ";
        }
        result ~= "} ";
        return result;
    }
    union
    {
        T array;
        mixin(getCodeForElements());
    }
    alias array this;
}

void main(string[] args)
{
    AliasableStaticArray!(int[2]) asa;
    alias e00 = asa.element0;
    alias e10 = asa.element1;
    alias e01 = __traits(getMember, asa, "element0");
    alias e11 = __traits(getMember, asa, "element1");
    e00 = 42;             // error, need this...
    e10 = 1337;           // error, need this...
    e01 = 42;             // error, need this...
    e11 = 1337;           // error, need this...
    assert(asa == [42, 1337]);
}
---

verdict: impossible.

--
June 15, 2020
https://issues.dlang.org/show_bug.cgi?id=3546

--- Comment #5 from Basile-z <b2.temp@gmx.com> ---
There's a draft PR for the feature, builtin the compiler

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

you can suggest more tests (or test the feature locally) as the author might be
biased toward the fact that this works perfectly ;)

--
June 16, 2020
https://issues.dlang.org/show_bug.cgi?id=3546

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #6 from Dlang Bot <dlang-bot@dlang.rocks> ---
@NilsLankila updated dlang/dmd pull request #11273 "fix issue 3546 - experiment aliasing a symbol with a constant indexer" fixing this issue:

- fix issue 3546 - experiment aliasing a symbol with a constant indexer

  An alias allows to reference a variable. When used this variable is then
turned into a `VarExp`.
  The idea is why not allowing an extra index, as long as the index is for a
variable and that it is a compile-time constant ?

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

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=3546

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P2                          |P4

--