@@ -403,17 +403,38 @@ f(nothing, 2.0)
403
403
These examples are telling us something: when ` x ` is ` nothing::Nothing ` , there are no
404
404
extra constraints on ` y ` .
405
405
It is as if the method signature had ` y::Any ` .
406
- This means that whether a variable is diagonal is not a static property based on
407
- where it appears in a type.
408
- Rather, it depends on where a variable appears when the subtyping algorithm * uses* it.
409
- When ` x ` has type ` Nothing ` , we don't need to use the ` T ` in ` Union{Nothing,T} ` , so ` T `
410
- does not "occur".
411
406
Indeed, we have the following type equivalence:
412
407
413
408
``` julia
414
409
(Tuple{Union{Nothing,T},T} where T) == Union{Tuple{Nothing,Any}, Tuple{T,T} where T}
415
410
```
416
411
412
+ The general rule is: a concrete variable in covariant position acts like it's
413
+ not concrete if the subtyping algorithm only * uses* it once.
414
+ When ` x ` has type ` Nothing ` , we don't need to use the ` T ` in ` Union{Nothing,T} ` ;
415
+ we only use it in the second slot.
416
+ This arises naturally from the observation that in ` Tuple{T} where T ` restricting
417
+ ` T ` to concrete types makes no difference; the type is equal to ` Tuple{Any} ` either way.
418
+
419
+ However, appearing in * invariant* position disqualifies a variable from being concrete
420
+ whether that appearance of the variable is used or not.
421
+ Otherwise types can behave differently depending on which other types
422
+ they are compared to, making subtyping not transitive. For example, consider
423
+
424
+ Tuple{Int,Int8,Vector{Integer}} <: Tuple{T,T,Vector{Union{Integer,T}}} where T
425
+
426
+ If the ` T ` inside the Union is ignored, then ` T ` is concrete and the answer is "false"
427
+ since the first two types aren't the same.
428
+ But consider instead
429
+
430
+ Tuple{Int,Int8,Vector{Any}} <: Tuple{T,T,Vector{Union{Integer,T}}} where T
431
+
432
+ Now we cannot ignore the ` T ` in the Union (we must have T == Any), so ` T ` is not
433
+ concrete and the answer is "true".
434
+ That would make the concreteness of ` T ` depend on the other type, which is not
435
+ acceptable since a type must have a clear meaning on its own.
436
+ Therefore the appearance of ` T ` inside ` Vector ` is considered in both cases.
437
+
417
438
## Subtyping diagonal variables
418
439
419
440
The subtyping algorithm for diagonal variables has two components:
0 commit comments