-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Distribute indexed accesses when simplifying them #26281
Conversation
@typescript-bot test this |
Heya @weswigham, I've started to run the extended test suite on this PR at c881d97. You can monitor the build here. It should now contribute to this PR's status checks. |
Saw a pair of RWC breaks due to @typescript-bot test this again btw |
Heya @weswigham, I've started to run the extended test suite on this PR at 518046c. You can monitor the build here. It should now contribute to this PR's status checks. |
}; | ||
|
||
function f1(s: Source, t: Target) { | ||
t = s; |
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.
I'm pretty sure this assignment is actually unsafe. Like, callback variance checks should prevent this from succeeding because Target
's callbacks don't handle a wide enough range of things, but because we overwrite K
with any
for an erased comparison and WindowEventMap[any]
is any
it succeeds.
Last RWC break I saw had to do with flow control - we use @typescript-bot test this again, since now there should be no new breaks 🤞 |
Heya @weswigham, I've started to run the extended test suite on this PR at 17d37ec. You can monitor the build here. It should now contribute to this PR's status checks. |
@typescript-bot test this now that we've accepted RWC updates so hopefully they are passing now |
Heya @weswigham, I've started to run the extended test suite on this PR at 17d37ec. You can monitor the build here. It should now contribute to this PR's status checks. |
So, I've checked: This also fixes #25181, which was also due to an issue with reasoning over an index on an intersection! This seems way cleaner than my other candidate to fix that. |
We talked about this today a bit - we think this is good, but we wanna fix the generic assignability issue one of the tests shows ( |
ef9f6ee
to
5bf01b3
Compare
@typescript-bot test this again since I've fixed the constraint confusion issue |
Heya @weswigham, I've started to run the extended test suite on this PR at c68d37a. You can monitor the build here. It should now contribute to this PR's status checks. |
So I'm in the middle of running this on DT, and I've found a somewhat legitimate bug in a dt package I'm only 1/5th of the way done, so I can't say for certain just yet, but the DT changes have started off looking pretty good (given this is the only one thus far). |
Please add repro from #26608 if it's not already covered by something representative |
@RyanCavanaugh added and confirmed for fixing #26608, too. |
@typescript-bot test this once more for a good ol' checkmark |
Heya @weswigham, I've started to run the extended test suite on this PR at 82b8a4f. You can monitor the build here. It should now contribute to this PR's status checks. |
…redTypeRelatedTo to match the non-identity relations
@ahejlsberg I know in person I spoke about how the one crash I found in DT while working on this was due to the recursion guard not being triggered due to simplified indexed accesses bypassing the types we guard against - rather than modify simplification further, I realized the issue was really that @typescript-bot test this again now that I've fixed the redux crash from DT (there's a repro in the tests now), just in case. |
Heya @weswigham, I've started to run the extended test suite on this PR at 98e9b3e. You can monitor the build here. It should now contribute to this PR's status checks. |
src/compiler/checker.ts
Outdated
function getConstraintForLocation(type: Type, node: Node): Type | undefined { | ||
function getConstraintForLocation(type: Type, node?: Node): Type; | ||
function getConstraintForLocation(type: Type | undefined, node?: Node): Type | undefined; | ||
function getConstraintForLocation(type: Type, node?: Node): Type | undefined { |
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.
Shouldn't this be node: Node | undefined
, i.e. not an optional parameter? It seems pointless to make it optional since the function will never do anything if you don't pass an argument for it.
Also, when might node
be undefined
? Not clear to me what those changes are accomplishing.
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.
Didn't need to be undefine
'd-able at all. I probably factored the place where it may have been undefinable so it wouldn't be while I was working on it - fix't.
src/compiler/checker.ts
Outdated
function elaborateError(node: Expression | undefined, source: Type, target: Type): boolean { | ||
if (!node) return false; | ||
if (isOrHasGenericConditional(target)) return false; |
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.
Combine this with line above and have a single if statement.
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.
Done
return type.simplified = mapType(objectType, t => getSimplifiedType(getIndexedAccessType(t, indexType))); | ||
} | ||
if (objectType.flags & TypeFlags.Intersection) { | ||
return type.simplified = getIntersectionType(map((objectType as IntersectionType).types, t => getSimplifiedType(getIndexedAccessType(t, indexType)))); |
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.
I love how much simpler this is!
getInitialType(<VariableDeclaration | BindingElement>node) : | ||
getAssignedType(node); | ||
getAssignedType(node), reference); |
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.
reference is always defined, isn't it? Then why does getConstraintForLocation change to node?: Node
?
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.
It doesn't now. ;) I think a prior iteration needed it. It's unchanged now.
function getInitialOrAssignedType(node: VariableDeclaration | BindingElement | Expression) { | ||
return node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement ? | ||
function getInitialOrAssignedType(node: VariableDeclaration | BindingElement | Expression, reference: Node) { | ||
return getConstraintForLocation(node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement ? |
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.
I think this is the right thing, having poked at this during other bug fixes, but doesn't it cause a lot of type changes? Is that reflected in the baseline updates?
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.
It is in the baselines - or rather, not doing this made the better distribution change some baselines, and then doing this changed them to the expected result.
And use the
unknownType
instead of theerrorType
when checking for property types if there is no error node, so the types combine appropriately under intersection and union operations.Sketch of a fix for #26274 - I mostly want to investigate this change's impact on RWC, since the changes to, eg, index signature handling in intersections (it's more correct!) could be breaky. It's also likely correct to simply distribute on initial construction, rather than waiting for simplification - but I haven't looked much into that approach yet.
Fixes #26274
Fixes #25181
Fixes #26608