[Issue 21697] Absurd limitations when passing lambda as alias parameter and bad error message

d-bugmail at puremagic.com d-bugmail at puremagic.com
Wed Mar 10 13:37:22 UTC 2021


https://issues.dlang.org/show_bug.cgi?id=21697

John Colvin <john.loughran.colvin at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |john.loughran.colvin at gmail.
                   |                            |com

--- Comment #1 from John Colvin <john.loughran.colvin at gmail.com> ---
The problem is triggered by the lambda being a template, yes

I expanded this to cover a bunch of cases to make sure I understood what was
happening, maybe it will be useful to someone trying to solve it and/or as a
comprehensive test.

module test;
import std.stdio;

//@safe:

struct S {
  //@safe:
  void foo() { writeln(&this); }
  void foo2()() { writeln(&this); }
  void runInsideDirect(alias f)() {
    write("runInsideDirect!" ~ __traits(identifier, f) ~ ": ");
    f();
  }
  void runInsideIndirect(alias f)() {
    write("runInsideIndirect!" ~ __traits(identifier, f) ~ ": ");
    auto b = &f;
    b();
  }
  void runInsideTemplateDirect(alias f)() {
    write("runInsideTemplateDirect!" ~ __traits(identifier, f) ~ ": ");
    f!()();
  }
  void runInsideTemplateIndirect(alias f)() {
    write("runInsideTemplateIndirect!" ~ __traits(identifier, f) ~ ": ");
    auto b = &f!();
    b();
  }
  void bar() {
    runInsideDirect!foo();
    runInsideIndirect!foo();
    //runOutsideDirect!foo(); // Error: need this
    runOutsideIndirect!foo(); // wrong this, caught by @safe
    runInsideTemplateDirect!foo2();
    runInsideTemplateIndirect!foo2();
    //runOutsideTemplateDirect!foo2(); // Error: need this
    runOutsideTemplateIndirect!foo2(); // wrong this, caught by @safe

    runInsideDirect!(foo2!())();
    runInsideIndirect!(foo2!())();
    //runOutsideDirect!(foo2!())(); // Error: need this
    runOutsideIndirect!(foo2!())(); // wrong this, caught by @safe

    void bar() //@safe
    {
      foo();
    }
    void bar2()() //@safe
    {
      foo();
    }
    runInsideDirect!bar();
    runInsideIndirect!bar();
    runOutsideDirect!bar();
    runOutsideIndirect!bar();
    //runInsideTemplateDirect!bar2(); // Error: need this, but no "Error
instantiating" message??
    //runInsideTemplateIndirect!bar2(); // Error: need this, but no "Error
instantiating" message??
    //runOutsideTemplateDirect!bar2(); // Error: need this
    //runOutsideTemplateIndirect!bar2(); // Error: need this

    runInsideDirect!(bar2!())();
    runInsideIndirect!(bar2!())();
    runOutsideDirect!(bar2!())();
    runOutsideIndirect!(bar2!())();
  }
}

void runOutsideDirect(alias f)() {
  write("runOutsideDirect!" ~ __traits(identifier, f) ~ ": ");
  f();
}
void runOutsideIndirect(alias f)() {
  write("runOutsideIndirect!" ~ __traits(identifier, f) ~ ": ");
  auto b = &f;
  b();
}
void runOutsideTemplateDirect(alias f)() {
  write("runOutsideTemplateDirect!" ~ __traits(identifier, f) ~ ": ");
  f!()();
}
void runOutsideTemplateIndirect(alias f)() {
  write("runOutsideTemplateIndirect!" ~ __traits(identifier, f) ~ ": ");
  auto b = &f!();
  b();
}

void main() {
  S s;
  s.bar();
}

--


More information about the Digitalmars-d-bugs mailing list