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