Error: variable 'xyz' has scoped destruction, cannot build closure

Jon Degenhardt jond at noreply.com
Fri Oct 5 03:27:17 UTC 2018


I got the compilation error in the subject line when trying to 
create a range via std.range.generate. Turns out this was caused 
by trying to create a closure for 'generate' where the closure 
was accessing a struct containing a destructor.

The fix was easy enough: write out the loop by hand rather than 
using 'generate' with a closure. What I'm wondering/asking is if 
there alternate way to do this that would enable the 'generate' 
approach. This is more curiosity/learning at this point.

Below is a stripped down version of what I was doing. I have a 
struct for output buffering. The destructor writes any data left 
in the buffer to the output stream. This gets passed to routines 
performing output. It was this context that I created a generator 
that wrote to it.

----example.d-----
struct BufferedStdout
{
     import std.array : appender;

     private auto _outputBuffer = appender!(char[]);

     ~this()
     {
         import std.stdio : write;
         write(_outputBuffer.data);
         _outputBuffer.clear;
     }

     void appendln(T)(T stuff)
     {
         import std.range : put;
         put(_outputBuffer, stuff);
         put(_outputBuffer, "\n");
     }
}

void foo(BufferedStdout output)
{
     import std.algorithm : each;
     import std.conv : to;
     import std.range: generate, takeExactly;
     import std.random: Random, uniform, unpredictableSeed;

     auto randomGenerator = Random(unpredictableSeed);
     auto randomNumbers = generate!(() => uniform(0, 1000, 
randomGenerator));
     auto tenRandomNumbers = randomNumbers.takeExactly(10);
     tenRandomNumbers.each!(n => output.appendln(n.to!string));
}

void main(string[] args)
{
     foo(BufferedStdout());
}
----End of  example.d-----

Compiling the above results in:

    $ dmd example.d
    example.d(22): Error: variable `example.foo.output` has scoped 
destruction, cannot build closure

As mentioned, using a loop rather than 'generate' works fine, but 
help with alternatives that would use generate would be 
appreciated.

The actual buffered output struct has more behind it than shown 
above, but not too much. For anyone interested it's here:  
https://github.com/eBay/tsv-utils/blob/master/common/src/tsvutil.d#L358


More information about the Digitalmars-d-learn mailing list