Possibly a unification bug in the type checker
Nickolay Bukreyev
buknik95 at ya.ru
Fri Dec 29 19:50:35 UTC 2023
```d
struct A(T) { }
pragma(msg, is(const A!int == A!int)); // false
pragma(msg, is(const A!int == A!T, T)); // true
```
Intuitively, `const A!int` cannot be `== A!T` for any `T`, but
DMD insists it is. If you are curious, it infers `T` to be `int`.
The same happens with the implicit-convertibility check, though
we need an indirection to observe it:
```d
struct B(T) { int* p; }
pragma(msg, is(const B!int: B!int)); // false
pragma(msg, is(const B!int: B!T, T)); // true
```
So, if a *TemplateParameterList* is present, the type checker
ignores all qualifiers (even `shared`) on both LHS and RHS. The
spec does not mention such behavior in either [`is`
expressions][is] or [template-parameter deduction][deduction].
I wonder if it is a bug or a deliberate decision. If former,
fixing it can potentially break a lot of code dependent on the
buggy behavior (so yet another `-preview`?..). For example,
`std.sumtype` is [affected][is-sum-type]:
```d
enum bool isSumType(T) = is(T : SumType!Args, Args...);
```
(This should be `is(immutable T : immutable SumType!Args,
Args...)`: we use `immutable` to [erase][qualifiers] other
qualifiers.)
If it was intended to work this way, then IMO it’s a huge gotcha
that should be described in the docs. If so, could somebody
explain why it was designed such?
[Discovered][discovery] by Andrey Zherikov and me.
[is]: https://dlang.org/spec/expression.html#is-parameter-list
[deduction]:
https://dlang.org/spec/template.html#argument_deduction
[is-sum-type]:
https://github.com/dlang/phobos/blob/v2.106.0/std/sumtype.d#L1583
[qualifiers]:
https://dlang.org/spec/const3.html#combining_qualifiers
[discovery]:
https://github.com/andrey-zherikov/argparse/pull/143#discussion_r1434251705
More information about the Digitalmars-d
mailing list