Thread overview
[Issue 21889] __traits(isSame, Object, const Object) yields true
May 03, 2021
Dlang Bot
Dec 17, 2022
Iain Buclaw
May 03, 2021
https://issues.dlang.org/show_bug.cgi?id=21889

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #1 from Dlang Bot <dlang-bot@dlang.rocks> ---
@BorisCarvajal created dlang/dmd pull request #12497 "Fix Issue 21889 - __traits(isSame, Object, const Object) yields true" fixing this issue:

- Fix Issue 21889 - __traits(isSame, Object, const Object) yields true

https://github.com/dlang/dmd/pull/12497

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=21889

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P2

--
March 26
https://issues.dlang.org/show_bug.cgi?id=21889

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |bugzilla@digitalmars.com
         Resolution|---                         |WONTFIX

--- Comment #2 from Walter Bright <bugzilla@digitalmars.com> ---
The documentation says:

"The result is true if the two arguments are the same symbol (once aliases are
resolved)."

  -- https://dlang.org/spec/traits.html#isSame

The code is behaving as specified, as Object and const(Object) are indeed the
same symbol.

But they are different types. To compare types, use

```
is(Object == const(Object))
```
or:
```
is(Object : const(Object))
```

There isn't a need to change anything. Use `is` if comparing types, `traits(isSame)` for comparing symbols.

--
March 26
https://issues.dlang.org/show_bug.cgi?id=21889

Jonathan M Davis <issues.dlang@jmdavisProg.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |issues.dlang@jmdavisProg.co
                   |                            |m

--- Comment #3 from Jonathan M Davis <issues.dlang@jmdavisProg.com> ---
(In reply to Walter Bright from comment #2)
> The code is behaving as specified, as Object and const(Object) are indeed
> the same symbol.

Are they? What is the exact definition of a symbol? Obviously, depending on the exact language/terminology being used Object and const Object could be considered different types, or they could be considered the same type with different type qualifiers. So, there's certainly some ambiguity with what "type" means, and it's arguably the same with "symbol". Personally, I find it very surprising that __traits(isSame, ...) would compare what would typically considered two different types and consider them to be the same.

And note that

    static assert(!__traits(isSame, double, const double));

compiles, which would imply that double and const double are considered different symbols, and certainly, it means that the scalar types behave different from classes or structs, which seems like a bad thing.

So, the behavior of __traits(isSame, ...) with regards to types definitely looks inconsistent and therefore error-prone, which potentially makes it problematic for generic code in particular. Certainly, I agree that if you specifically want to be comparing types, then is expressions are what you should be using, not __traits(isSame, ...), but when dealing with AliasSeqs in generic code, there are going to be times that __traits(isSame, ...) is going to be used on types when the idea is to compare symbols.

Of course, changing the current behavior risks breaking code (though likely most - if not all - code that depends on the current behavior does so by accident), so we'd arguably need to make the change with an edition, but I don't see how the current behavior is at all desirable - especially the fact that scalar types are treated differently with regards to type qualifiers from user-defined types.

Ultimately, "wontfix" may be correct in the sense that we decide that we can't fix it because of concerns with breaking existing code, but the inconsistencies here definitely seem like a problem, and if we could fix it with a future edition at some point, then I would think that that would be better than "wontfix."

--