Skip to content

Invalidate cached noop typechecks during typealias instantiation - #1717

Merged
bioball merged 2 commits into
apple:mainfrom
HT154:invalidate-cached-noop-typechecks
Jul 2, 2026
Merged

Invalidate cached noop typechecks during typealias instantiation#1717
bioball merged 2 commits into
apple:mainfrom
HT154:invalidate-cached-noop-typechecks

Conversation

@HT154

@HT154 HT154 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

This also fixes TypeAliasTypeNode always performing lazy type checks even when they should be eager.

Resolves #1710
Resolves #1716

@HT154 HT154 changed the title Invalidate cached noop typechecks Invalidate cached noop typechecks during typealias instantiation Jun 29, 2026
@HT154
HT154 force-pushed the invalidate-cached-noop-typechecks branch 4 times, most recently from 9b7521d to 08bfcd0 Compare June 29, 2026 19:33
@HT154
HT154 force-pushed the invalidate-cached-noop-typechecks branch from 08bfcd0 to 96a58f7 Compare June 30, 2026 06:51

@stackoverflow stackoverflow left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nested unions still suffer from the same issue:

typealias Flat<A, B> = A | B
res_flat = new Dynamic {} is Flat<module, module>

typealias Nested<A, B> = (A | A) | (B | B)
res_nested = new Dynamic {} is Nested<module, module>

Results in

res_flat = false
res_nested = true

Children should be invalidated before parents. The truffle visitor does the opposite (goes from parent to children).

@HT154
HT154 force-pushed the invalidate-cached-noop-typechecks branch 2 times, most recently from 2d43f82 to 5880b9d Compare June 30, 2026 19:27
@HT154
HT154 force-pushed the invalidate-cached-noop-typechecks branch from 5880b9d to 3d3d68f Compare June 30, 2026 19:30
@HT154
HT154 requested review from bioball and stackoverflow June 30, 2026 19:31

@bioball bioball left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need an invalidate() method. Instead, we can just call if (elementTypeNode.isNoopTypeCheck()) inside the execute methods of these nodes.

invalidate() suggests that a type node has stale state. But, the core problem is that we don't know yet if this is a noop check yet when inside the constructor of ListTypeNode, SetTypeNode, etc.

We can probably also change the isNoopTypeCheck method in class TypeVariableNode to this:

    @Override
    public boolean isNoopTypeCheck() {
      CompilerDirectives.transferToInterpreter();
      throw exceptionBuilder().bug("isNoopTypeCheck called on an unreplaced type variable").build();
    }

@HT154

HT154 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

I don't think we need an invalidate() method. Instead, we can just call if (elementTypeNode.isNoopTypeCheck()) inside the execute methods of these nodes.

Are you suggesting removing the skip_TypeChecks fields from each class?

We can probably also change the isNoopTypeCheck method in class TypeVariableNode to this:

    @Override
    public boolean isNoopTypeCheck() {
      CompilerDirectives.transferToInterpreter();
      throw exceptionBuilder().bug("isNoopTypeCheck called on an unreplaced type variable").build();
    }

This particular change isn't safe since TypeVariableNode is not replaced in generic classes/methods.

@bioball

bioball commented Jul 1, 2026

Copy link
Copy Markdown
Member

This particular change isn't safe since TypeVariableNode is not replaced in generic classes/methods.

Ah, gotcha. Then, yeah, we should keep that impl as-is for now (it basically stands for Unknown).

Are you suggesting removing the skip_TypeChecks fields from each class?

Yup! Or, possibly, defer setting that field until execute gets called. But, it seems fine to just remove.

@stackoverflow stackoverflow left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@HT154

HT154 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

An alternate approach here is having TypeVariableNode.isNoopTypeCheck() return false (only when it's in a type alias body?). This would mean slightly less efficient type checks when type vars are replaced with no-ops, but would preserve the optimization in other cases (like when no typealiases are used). Thoughts?

@HT154

HT154 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

An alternate approach here is having TypeVariableNode.isNoopTypeCheck() return false only when it's in a type alias body.

#1722 implements this approach. I think this is probably preferable to this PR as it avoids losing the caching optimization in non-type-parameter scenarios.

@bioball bioball left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Merging this one; I'm not totally sold that #1722 semantically makes sense (TypeVariableNode is always meant to be replaced, I think)

@bioball
bioball merged commit 6a4d3ac into apple:main Jul 2, 2026
22 checks passed
@HT154
HT154 deleted the invalidate-cached-noop-typechecks branch July 2, 2026 22:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

4 participants