Skip to content

Conversation

@AnsonYeung
Copy link

Allow Match to be inverted, which will be used to create non null checks during handler lowering.

Copy link
Contributor

@LPTK LPTK left a comment

Choose a reason for hiding this comment

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

LGTM, but it's missing at least one test where this is actually used.

AnsonYeung and others added 2 commits January 8, 2026 19:01
Co-authored-by: Lionel Parreaux <lionel.parreaux@gmail.com>
@AnsonYeung
Copy link
Author

It's probably better to change the JSBuilder and not the IR, as this change make little sense with multiple branch. I will implement the change to JSBuilder directly in the handler branch as it is small enough. So we do not need to change the IR to allow inverted match then.

@AnsonYeung AnsonYeung closed this Jan 8, 2026
@LPTK
Copy link
Contributor

LPTK commented Jan 8, 2026

But I don't think there's a compact/convenient way of representing that in the IR? Ideally we'd want to have such compact representation to facilitate analyses and optimizations.

Now that I think of it, though, it seems that we should allow negative match cases regardless of the pattern, not just for literal patterns.

@AnsonYeung
Copy link
Author

Right now, I express it as Match(..., Case.Lit(...) -> End(), S(...), rst), I'm not sure how to add it so that it would be available for all patterns

@LPTK
Copy link
Contributor

LPTK commented Jan 8, 2026

We would associate a Bool with each Case in the Match.

Using default branches technically works but isn't compact (can't merge several into the same match). Not sure it's that important, though.

@AnsonYeung
Copy link
Author

For a negative match, I think it's typically not used in multiple branches as the only useful scenario I can think of is for early exit, where you expect the match to sucess and return if it's not matched.

@LPTK
Copy link
Contributor

LPTK commented Jan 8, 2026

Users can write things with negated patterns, eg

fun test(x) = if x is
  0 then "0"
  ~2 & ~3 then "not 2 and not 3"
  ~3 then "not 3"
  _ then "other"

test(0)
//│ = "0"
test(1)
//│ = "not 2 and not 3"
test(2)
//│ = "not 3"
test(3)
//│ = "other"

Though currently, it seems UCS lowering already does a good job producing a negation-free result:

//│ JS (unsanitized):
//│ let test;
//│ test = function test(x2) {
//│   switch (x2) {
//│     case 0:
//│       return "0";
//│       break;
//│     case 2:
//│       return "not 3";
//│       break;
//│     case 3:
//│       return "other";
//│       break;
//│     default:
//│       return "not 2 and not 3";
//│       break;
//│   }
//│ };

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.

2 participants