-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Tuple rest sandwich prop #49106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tuple rest sandwich prop #49106
Conversation
Rest tuple sandwich implementation Changes to be committed: modified: src/compiler/checker.ts new file: tests/baselines/reference/variadicTupleRestSandwich.errors.txt new file: tests/baselines/reference/variadicTupleRestSandwich.js new file: tests/baselines/reference/variadicTupleRestSandwich.symbols new file: tests/baselines/reference/variadicTupleRestSandwich.types new file: tests/cases/conformance/types/tuple/variadicTupleRestSandwich.ts
Changes to be committed: modified: tests/baselines/reference/variadicTuples1.errors.txt modified: tests/baselines/reference/variadicTuples1.types modified: tests/baselines/reference/variadicTuples2.types Update basline
The code is functionally correct with respect to the baselines tests. However, the following two kinds of contextualType currently exist in the baseline examples, and end up being passed to
Here's how length gets handled for those cases:
Certainly (I think) at least we could make a test with a TupleLikeType that requires the birectional search. But because we're not currently returning a real length, that kind of test could fail. Also, as for Unions, I haven't fully analyzed those cases but it is definitely the case a imposing a lenght of 1 causes the some baseline tests to return different type results. (However, in limited testing, didn't notice any actual error yes/no differences.) We also need to consider whether those kinds of tests would need bidirectional search - by default I think the answer should be yes. |
Changes to be committed: modified: tests/baselines/reference/variadicTupleRestSandwich.errors.txt modified: tests/baselines/reference/variadicTupleRestSandwich.js modified: tests/baselines/reference/variadicTupleRestSandwich.symbols modified: tests/baselines/reference/variadicTupleRestSandwich.types modified: tests/cases/conformance/types/tuple/variadicTupleRestSandwich.ts Improve test file variadicTupleRestSandwich.ts documentation Update baseline
Changes to be committed: modified: src/compiler/checker.ts Completed unification of old and new code. These functions exable the compatibility: getContextualTypeForElementExpression_altTypeAndFlag getContextualTypeForElementExpression_altLength getContextualTypeForElementExpression_altFlags Still there is no real length for some types which are not isTupleType. See getContextualTypeForElementExpression_altFlags for how that works now by returning a large number instead of a real length. However, that won't in case of bidirectional search. So it's just lucky that the baseline tests don't contain a comnbination of a type that has no defined length and the need for a bidirection search.
// arrayContextualType, | ||
// t => getIteratedTypeOrElementType(IterationUse.Element, t, undefinedType, /*errorNode*/ undefined, /*checkAssignability*/ false), | ||
// /*noReductions*/ true)); | ||
const getContextualTypeForElementExpression_altTypeAndFlag=(arrayContextualType: Readonly<Type>, index: number): [Type, ElementFlags] => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getContextualTypeForElementExpression_altTypeAndFlag
getContextualTypeForElementExpression_altLength
getContextualTypeForElementExpression_altFlags
are workarounds for getContextualTypeForElementExpression
which fails when accessing indices beyond the first
index corresponding to a rest index. getContextualTypeForElementExpression
returns the value at the first rest index for any index value >= the first rest index. That doesn't work when there are real values beyond the first rest index, which are actually allowed in the current code from createNormalizedTupleType:
(checker.ts
: function createNormalizedTupleType
), see the code corresponding to comments:
// Turn optional elements preceding the last required element into required elements
// Turn elements between first rest and last optional/rest into a single rest element
Proposal: IF an abstract representation is necessary (is it necessary?)
then modify getContextualTypeForElementExpression
to accept negeative indices, where -n refers to the nth element from the end, starting at -1. (Same numbering convention as slice).
NOTE!!!
The condition (contextualType.target.elementFlags.length < getTypeArguments(contextualType).length)
does occur. It has been observed tp happen when there is tuple type which an unknow generic type in, e.g., [...T]
followed by an instantiation of that type, e.g. [...T] = ["hello"]
. (There may or may not be other examples), Then the types contained in getTypeArguments(contextualType)
are [string, T]
(length 2) but contextualType.target.elementFlags
is [ElementFlags.Required]
(length 1).
Conformance in length is required when reading from the ends of the arrays.
} | ||
|
||
{ | ||
// Type T12 IS a rest sandwich format - this example shows results that improvably differ between before and after. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Type T12 IS a rest sandwich format - this example shows results that improvably differ between before and after. | |
// Type T12 IS a rest sandwich format - this example shows results that improbably differ between before and after. |
The bug for this PR was fixed in 5.0, so I'm going to close it. Please let me know if it needs to be re-opened. |
This is for analytic use with issue #49105 (reopened in short form as #49138).
The analysis is complete and the results are written below. The code is no longer being worked on. It remains as a "pull draft" merely fpr analysis purposes.
To summarize the analysis, the way the code is currently written (4.7) there is assumption that array context types
don't necessarily need to expose a length for use in matching. However that won't necessarily work when
trying to match with a bidirectional search. Might be able to get away with negative indices
(distance from the end) and still avoid length. But stretching a rest element to infinite length won't work when a bidirectional search is required.