Declare the variance of iterator, generator and tagged template types
Why
The iterator family's type parameters were invariant, so a generator of [#A] could not be coerced to one of [#A | #B], and values of library types built on Generator.t were not generalised under the relaxed value restriction. Yields and return values only flow out of an iterator and resume values only flow in. Needed for generators (#8934).
modifiedTyping coercion
let g: Generator.t<[#A], int, [#X | #Y]> = gen()let h = (g :> Generator.t<[#A | #B], int, [#X]>)
rule
t<y, r, n> ≤ t<y', r', n'> only if y = y', r = r', n = n'
y ≤ y'r ≤ r'n' ≤ n
t<y, r, n> ≤ t<y', r', n'>
t ∈ {Iterator, AsyncIterator, Generator, AsyncGenerator, IterableIterator, AsyncIterableIterator, IteratorObject}
rawResult<+y, +r>arrayLike<+a>taggedTemplate<-param, +output>
Review
- Is
+'returnsound whenGenerator.returnValuetakes a'return? Only up to a contrived case: a generator shared under two types, resumed throughreturnValuewhile afinallyblock yields, hands the wider value to the narrower reference. TypeScript'sGeneratorhas the same hole.