Skip to content

Fix SubMatch wrapped in Typed node by ensureNoLocalRefs#25778

Open
zielinsky wants to merge 3 commits intoscala:mainfrom
zielinsky:i25746
Open

Fix SubMatch wrapped in Typed node by ensureNoLocalRefs#25778
zielinsky wants to merge 3 commits intoscala:mainfrom
zielinsky:i25746

Conversation

@zielinsky
Copy link
Copy Markdown
Member

@zielinsky zielinsky commented Apr 14, 2026

Fixes #25746

ensureNoLocalRefs in the typer wrapped SubMatch node in Typed(SubMatch, String). This caused PatternMatcher to miss the SubMatch and emit it as a raw ResultPlan, which after a few steps crashed BCodeBodyBuilder.

How much have you relied on LLM-based tools in this contribution?

To help me identify the error.

How was the solution tested?

Tests are included.

Additional notes

My first attempt was to handle Typed(t: SubMatch, _) in caseDefPlan in PatternMatcher, but I was afraid of silent errors by just stripping Typed.

@zielinsky zielinsky changed the title Fix SubMatch wrapped in Typed node by ensureNoLocalRefs FixSubMatch wrapped in Typed node by ensureNoLocalRefs Apr 14, 2026
@zielinsky zielinsky changed the title FixSubMatch wrapped in Typed node by ensureNoLocalRefs Fix SubMatch wrapped in Typed node by ensureNoLocalRefs Apr 14, 2026
@zielinsky zielinsky requested a review from noti0na1 April 14, 2026 09:24
@noti0na1
Copy link
Copy Markdown
Member

@EugeneFlesselle Can you take a look of this PR? thanks!

case block @ Block(stats, expr) if !expr.isInstanceOf[Closure] =>
val expr1 = ascribeType(expr, pt)
cpy.Block(block)(stats, expr1).withType(expr1.tpe) // no assignType here because avoid is redundant
case m @ Match(selector, cases) if m.isSubMatch =>
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'm not sure why we only need to handle SubMatch here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It's because of how transformMatch handles a simple Match vs SubMatch. For the first one, wrapping it in Typed is not a problem

Copy link
Copy Markdown
Contributor

@EugeneFlesselle EugeneFlesselle left a comment

Choose a reason for hiding this comment

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

This caused PatternMatcher to miss the SubMatch and emit it as a raw ResultPlan, which after a few steps crashed BCodeBodyBuilder.

In that case it might be best to have the fix be in the PattenMatcher for SubCases specifically, rather than in the avoidance logic

case block @ Block(stats, expr) if !expr.isInstanceOf[Closure] =>
val expr1 = ascribeType(expr, pt)
cpy.Block(block)(stats, expr1).withType(expr1.tpe) // no assignType here because avoid is redundant
case m @ Match(selector, cases) if m.isSubMatch =>
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.

IIUC this case is added to avoid the Typed wrapper?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Exactly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RuntimeException: Invalid pattern in Match node using subCases

3 participants