-
Notifications
You must be signed in to change notification settings - Fork 8
Description
Tested with the current package optional 1.3.0, I haven't tested with older versions of package optional.
Reduced code example:
import std.stdio;
import optional;
class X {
int number = 0;
this(in int n) {
number = n;
}
Optional!X maybeIncrement() {
return Optional!X(new X(number + 1));
}
}
void main() {
Optional!X x = new X(7);
x = x.oc.maybeIncrement();
if (x.empty) {
writeln("x is now empty.");
} else {
writeln("x now holds ", x.front.number, ".");
}
}This code behaves differently between DMD versions.
- On DMD 2.100 and older (at least another year back from that), it prints: "x now holds 8."
- On DMD 2.102.1 and newer (e.g., in the current DMD 2.103.1), it prints: "x is now empty."
I haven't used digger or manual reduction for DMD versions to pin it down further in between 2.100 and 2.102.1. I could reduce it further in theory, but I'd rather like to know if I should rely on this behavior in usercode at all -- I got bugs from it after a compiler upgrade after all.
The critical line is x = x.oc.maybeIncrement(); where
- the left-hand side
xis of typeOptional!Xfor a classX, and - the right-hand side
x.oc.maybeIncrement()is of typeOptionalChain!X.
What is the desired behavior?
x = x.oc.maybeIncrement;fails to compile.xis now asome(new X(8)), which I expected in usercode.xis now empty, which is the current behavior in DMD 2.102.1.
In the example, I've also tried x = x.oc.maybeIncrement().toOptional(); explicitly. This doesn't change the behavior at all: It still gives the exact same inconsistent result, i.e., some(new X(8)) on the older DMD versions, and empty on newer DMD versions.
Workaround: I've replaced lines such as x = x.oc.maybeIncrement(); with:
x = x.empty ? Optional!X() : x.front.maybeIncrement();
This behaves the same across all DMD versions, and would print in our example: "x now holds 8."