digitalmars.D - Possibly a unification bug in the type checker
- Nickolay Bukreyev (41/41) Dec 29 2023 ```d
- Walter Bright (6/6) Dec 29 2023 I haven't looked deeply into this yet, but the pattern matching design a...
```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
Dec 29 2023
I haven't looked deeply into this yet, but the pattern matching design and implementation of IsExpressions was done for D1. D1 did not have const, shared, etc. The behavior of the pattern matcher probably remained the same through the transition to const, etc. There's been so much water under the bridge since it would be very risky to change its behavior now.
Dec 29 2023