[Issue 18115] [REG2.078-b1] case where && is not shortcut anymore in CTFE

d-bugmail at puremagic.com d-bugmail at puremagic.com
Fri May 18 03:11:20 UTC 2018


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

--- Comment #15 from Walter Bright <bugzilla at digitalmars.com> ---
Tracing this through the compiler, the trouble is more subtle.

  int test()
  {
    if (test.stringof.length > 6 &&
        test.stringof[$-7..$] == "1234567") {}
    return 0;
  }
  enum a = test();

1. The enum declaration says evaluate test() at compile time.
2. test() has not had semantic run on it yet, so the CTFE runs semantic on it
before attempting to execute it.
3. semantic sees the == with arrays on both sides. So it attempts to
instantiate the object.__equals() template with the left and right operands of
the ==.
4. As part of argument matching to the template, the operands get constant
folded.
5. The error is generated by the constant folding.

object.__equals() was added fairly recently, hence the regression.

I don't see any obvious way out of this.

However, there is a simple workaround, as constant folding does not do any flow
analysis:

  int test()
  {
    auto i = test.stringof.length;
    if (test.stringof.length > 6 &&
        test.stringof[i-7..i] == "1234567") {}
    return 0;
  }

  enum a = test();

Here, the value of `i` is not propagated to the constant folder. The optimizer
will do that, but later. CTFE will do it, too, but CTFE respects short
circuits.

Note also that the following version:

  int test()
  {
    if (test.stringof.length > 6 &&
        test.stringof[$-7..$]) {}
    return 0;
  }

  enum a = test();

does not issue an error. That's because no template matching is attempted.

--


More information about the Digitalmars-d-bugs mailing list