Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CTFE] AliasSeq in multi-level alias this fails in CTFE #19043

Open
dlangBugzillaToGithub opened this issue Sep 15, 2015 · 5 comments
Open

[CTFE] AliasSeq in multi-level alias this fails in CTFE #19043

dlangBugzillaToGithub opened this issue Sep 15, 2015 · 5 comments

Comments

@dlangBugzillaToGithub
Copy link

Jack Stouffer (@JackStouffer) reported this on 2015-09-15T20:22:58Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=15064

CC List

  • Paolo Invernizzi
  • Simen Kjaeraas

Description

@dlangBugzillaToGithub
Copy link
Author

k.hara.pg commented on 2015-09-16T00:27:43Z

Please add a test case, at least.

@dlangBugzillaToGithub
Copy link
Author

jack (@JackStouffer) commented on 2015-09-16T00:33:41Z

Sorry

int test()
{
    import std.range : enumerate;

    int[] a = [1];

    foreach (i, e; a.enumerate) {}

    return 0;
}

void main()
{
    enum res = test(); // fails
    int res = test(); // works fine
}

@dlangBugzillaToGithub
Copy link
Author

k.hara.pg commented on 2015-09-16T02:25:43Z

Thanks.

@dlangBugzillaToGithub
Copy link
Author

b2.temp commented on 2017-09-18T06:14:13Z

Remove the field names of the Tuple used in enumerate and it works i.e change the definition

"alias ElemType = Tuple!(Enumerator, "index", ElementType!Range, "value");"

to

"alias ElemType = Tuple!(Enumerator, ElementType!Range);"

(+ fix the unittests that use the field name by using indexers as postfix)

and it works, although No idea why. This is just a clue, not a fix. Removing the field names would break code.

@dlangBugzillaToGithub
Copy link
Author

simen.kjaras commented on 2017-09-18T12:03:30Z

Reduced test case:

import std.meta : AliasSeq;

struct Super {
    AliasSeq!(int, int) expand;
    alias expand this;
}

struct Tuple {
    Super inner;
    alias inner this;
}

struct Range {
    Tuple front;
    void popFront() {}
    bool empty = true;
}

int test1() {
    import std.algorithm : map;
    foreach (i, e; Range.init) {} // Fails
    foreach (i, e; [Tuple.init].map!(a=>a)) {} // Fails
    foreach (i, e; [Tuple.init]) {} // Works [line 23]
    return 3;
}

enum s1 = test1();

And even more reduced, I think:

struct Super2 {
    AliasSeq!int expand;
    alias expand this;
}

struct Tuple2 {
    Super2 inner;
    alias inner this;
}

int test2() {
    AliasSeq!int a = Tuple2.init; // Fails with same message
    int b = Tuple2.init[0]; // Works [line 41]
    
    return 3;
}

enum s2 = test2();

Since test2 gives the same error message, and the same kind of unpacking will happen in both cases, I assume that's the root problem.

So in summary: If an AliasSeq is used in alias this inside another alias this, some context goes missing in CTFE, possibly only during tuple assignment (see line 41). Strangely, it seems to work when the unpacking comes from an array instead of a range (line 23). Not sure why that is, but it seems tangential to the real problem here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant