www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Possibly a unification bug in the type checker

reply Nickolay Bukreyev <buknik95 ya.ru> writes:
```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
parent Walter Bright <newshound2 digitalmars.com> writes:
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