Lets have this code:
import core.lifetime : forward;
import core.stdc.stdio;
import std.algorithm : move;
struct Value(T) {
private T storage;
this()(auto ref T val) {
storage = forward!val;
}
ref inout(T) get() inout {
return storage;
}
}
Value!T value(T)(auto ref T val) {
return Value!T(forward!val);
}
auto ref unwrap(EX)(auto ref EX res) {
return res.get();
}
struct Foo {
int n;
@disable this(this);
~this() { printf("~this(%d)\n", n); }
}
auto gen() {
Foo f;
f.n = 42;
return value(f.move());
}
void main() {
Foo f;
f = gen().unwrap.move;
}
As I understand it unwrap in f = gen().unwrap.move
can't be called by ref (as gen() returns rvalue) so it would force the Value
to be copied but as it holds non copyable struct, it can't be and so it should end up with a compiler error.
But the code outputs:
~this(0)
~this(0)
~this(0)
~this(42) <- this is a copy (that shouldn't exist) being destroyed
~this(0)
~this(42)
This could cause unwanted resource cleanup on a seemingly non copyable structs.
Bug or feature? :)