[Issue 15231] New: opOpAssign allows assignment to rvalue

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Wed Oct 21 05:52:11 PDT 2015


https://issues.dlang.org/show_bug.cgi?id=15231

          Issue ID: 15231
           Summary: opOpAssign allows assignment to rvalue
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: dmd
          Assignee: nobody at puremagic.com
          Reporter: ryan at rcorre.net

unittest {
  struct MyInt {
    int _val;

    auto opBinary(string op)(int other) {
      return mixin("_val"~op~"other");
    }

    void opOpAssign(string op)(int other) {
      _val = mixin("_val"~op~"other");
    }
  }

  struct Foo {
    int _i;
    MyInt _mi;

    auto i()         { return _i; }
    auto mi()        { return _mi; }
    auto i(int val)  { return _i = val; }
    auto mi(int val) { return _mi = MyInt(val); }
  }

  auto f = Foo(1, MyInt(1));
  static assert(!__traits(compiles, f.i += 1));  // f.i is an rvalue
  static assert(!__traits(compiles, f.mi += 1)); // f.mi should be an rvalue
}

The final assert fails.f.mi is not an lvalue, and therefore f.mi += 1 should
not compile. It deceptively appears to increment `mi` while truly doing
nothing. The compiler disallows this for builtin types (e.g. int) but somehow
the use of opOpAssign bypasses this check.

Ideally, I'd love to have support for in-place property modification
(https://issues.dlang.org/show_bug.cgi?id=8006), but failing that, I think this
should be disallowed to avoid confusion.

P.S. not sure whether this belongs in DMD or druntime

--


More information about the Digitalmars-d-bugs mailing list