First Draft: Implicit Conversion of Template Instantiations

Timon Gehr timon.gehr at gmx.ch
Mon Mar 18 01:11:55 UTC 2024


On 3/16/24 16:50, Walter Bright wrote:
> https://github.com/WalterBright/documents/blob/9dba63a4c2887bdb2b988c354ebb0d6bb44c4968/templatecast.md
> 
> DConf: https://dconf.org/2024/online/index.html#walterb

Idea: Explicit variance annotations.

Benefits:

- Makes it easy to determine a common type.
- I expect overall faster compilation, because subtyping can be refuted 
without analyzing all fields.
- Solves question of how to annotate in an opt-in solution. (I think 
opt-in is absolutely required for this feature.)
- Very easy to implement by simple additions on top of the existing 
prototype.
- Principled.

Drawbacks:

- Slightly more expensive to determine that subtyping holds. (First, you 
check the arguments according to the variance annotations, if that 
succeeds, you still have to perform the member-wise check.)

- This particular proposal would disallow a template type with variance 
of one template parameter varying based on one of the other template 
parameters.


E.g.

```d
struct S(+T){
     T payload;
}
```

This annotation means that `S` is _covariant_ in `T`. Intuitively, this 
means that an rvalue of type `S!T` can produce values of type `T`.

Other examples:

```d
struct S(+T){
     T foo();
}
```

```d
struct S(+T){
     void foo(void delegate(T) callback){}
}
```

The common type of `S!T1` and `S!T2` is `S!T3`, where `T3` is the common 
type of `T1` and `T2`.


``d
struct S(-T){
     void delegate(T) payload;
}
```

This annotation means that `S` is _contravariant_ in `T`. Intuitively, 
this means that an rvalue of type `S!T` can consume values of type `T`.

The common type of `S!T1` and `S!T2` is `S!T3`, where `T3` is the shared 
type of `T1` and `T2`.



The implementation currently also supports a case like this one:

```d
struct S(T){
     T[] payload;
}
```

Here, `S` is covariant in `T` only if converting to a non-mutable type.

This would require a different annotation, I suggest `+const`.

```d
struct S(+const T){
     T[] payload;
}
```

In principle we could also have `-const`, but currently I do not see a 
case where that would be helpful.




More information about the dip.development mailing list