June 05, 2023
https://issues.dlang.org/show_bug.cgi?id=23972

          Issue ID: 23972
           Summary: class identity check is broken
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: major
          Priority: P1
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: qs.il.paperinik@gmail.com

The [spec](https://dlang.org/spec/expression.html#identity_expressions) says
that:
> For class objects, identity is defined as the object references are for the same object.

In general, this requires dynamic type checks. A pointer comparison is not enough, e.g. the following doesn’t work:

```d
interface I { void g(); }
interface I1 : I { void g1(); }
interface I2 : I { void g2(); }
interface J : I1, I2 { void h(); }

class C : J
{
    override void g() { }
    override void g1() { }
    override void g2() { }
    override void h() { }
}

void main() @safe
{
    C c = new C;
    I i1 = cast(I1) c;
    I i2 = cast(I2) c;
    assert(cast(Object) i1 is cast(Object) i2); // good
    assert(i1 is i2); // fails
    assert(c is i2); // fails
    assert(c is cast(C) i2); // good
    assert(c is cast(Object) i2); // good
    assert(i1 is c); // good
}
```
Clearly, `i1` and `i2` refer to the same object, but an explicit dynamic cast
using `cast(Object)` is necessary.

This can be solved two ways:

Either do dynamic type checks (unless the compiler can prove them redundant) or make `is` comparisons with interface-type expressions an error, requiring an explicit cast.

--