Thread overview
strage heisenbug (has scoped destruction, cannot build closure)
Mar 03, 2015
ketmar
Mar 03, 2015
ketmar
Mar 03, 2015
ketmar
Mar 03, 2015
anonymous
March 03, 2015
hi.

the following (manually "dustmited" ;-)) code gives the error from subj on git HEAD:

=== ztest.d ===
  module ztest;

  auto streamAsRange(STP) (STP st) {
    static struct StreamRange(ST) {
    private:
      ST strm;
    public:
      void put (const(ubyte)[] data) { strm.rawWrite(data); }
    }
    return StreamRange!STP();
  }

  void zcompress(RO) (RO ro) {
    ubyte[1] obuf;

    void writeOBuf () {
      static if (is(typeof(() {
        ubyte[2] b;
        ro.put(b);
      }))) {
        ro.put(obuf);
      }
    }

    writeOBuf();
  }

  void test () {
    import std.stdio;
    auto fo = File();
    zcompress(streamAsRange(fo));
  }

  void main () {
  }
======

the strange thing is that this is heisenbug. if i comment out `static if` the module successfully compiles. i.e. changing `zcompress()` to this allows me to compile the code:

===
  void zcompress(RO) (RO ro) {
    ubyte[1] obuf;

    void writeOBuf () {
      ro.put(obuf);
    }

    writeOBuf();
  }
===

so the offending line is `ro.put(b);` (comment it out, and everything is working again).

am i doing something very wrong here, or this is really a compiler bug?

March 03, 2015
p.s. well, it's not a heisenbug, 'cause it reproducible. let's say that it's a... very strange bug. ;-)

March 03, 2015
p.p.s. sure, i can see where i'm creating a closure. but i can't see how that closure got to IR generator, as it is never executes, there is no need to generate code for it, and it should be removed after checking `static if` condition.

March 03, 2015
On Tuesday, 3 March 2015 at 07:26:13 UTC, ketmar wrote:
> hi.
>
> the following (manually "dustmited" ;-)) code gives the error from subj
> on git HEAD:
>
> === ztest.d ===
>   module ztest;
>
>   auto streamAsRange(STP) (STP st) {
>     static struct StreamRange(ST) {
>     private:
>       ST strm;
>     public:
>       void put (const(ubyte)[] data) { strm.rawWrite(data); }
>     }
>     return StreamRange!STP();
>   }
>
>   void zcompress(RO) (RO ro) {
>     ubyte[1] obuf;
>
>     void writeOBuf () {
>       static if (is(typeof(() {
>         ubyte[2] b;
>         ro.put(b);
>       }))) {
>         ro.put(obuf);
>       }
>     }
>
>     writeOBuf();
>   }
>
>   void test () {
>     import std.stdio;
>     auto fo = File();
>     zcompress(streamAsRange(fo));
>   }
>
>   void main () {
>   }
> ======

Reduced further:

----
module ztest;

struct StreamRange {
  ~this() {}
  void put() {}
}

void zcompress(StreamRange ro) {
  void writeOBuf() {
    enum e = is(typeof({ro.put();}));
    ro.put();
  }
  writeOBuf();
}

void main() {
  zcompress(StreamRange());
}
----

Looks like a compiler bug to me.