Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assigning OptionalChain!X to an Optional!X compiles, but result is inconsistent between DMD versions #58

Open
SimonN opened this issue May 26, 2023 · 0 comments

Comments

@SimonN
Copy link
Contributor

SimonN commented May 26, 2023

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 x is of type Optional!X for a class X, and
  • the right-hand side x.oc.maybeIncrement() is of type OptionalChain!X.

What is the desired behavior?

  1. x = x.oc.maybeIncrement; fails to compile.
  2. x is now a some(new X(8)), which I expected in usercode.
  3. x is 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."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant