Skip to content
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

Fix a few AND operator parser bugs and regressions #17113

Merged
merged 6 commits into from May 15, 2024

Conversation

psfinaki
Copy link
Member

@psfinaki psfinaki commented May 2, 2024

Fixes #16447
Fixes #17134
Fixes #16309

The problem was introduced together with the constraint intersection support here. The parser no longer stops at the ampersand sign in the clause and tries to interpret :? as part of the type.

Checklist

  • Test cases added
  • Release notes entry updated

Copy link
Contributor

github-actions bot commented May 2, 2024

❗ Release notes required


✅ Found changes and release notes in following paths:

Change path Release notes path Description
src/Compiler docs/release-notes/.FSharp.Compiler.Service/8.0.400.md

@psfinaki psfinaki changed the title Fix constraint intersection parser regression Fix pattern matching parser regression May 2, 2024
@psfinaki
Copy link
Member Author

psfinaki commented May 2, 2024

Hey I am getting a bit desperate with this, whatever I do breaks either pattern matching (the original regression) or constraint intersection (the original feature). I feel I am somewhere close but missing something obvious since I haven't properly worked with the parser before.

The current version is the closest I've got so far - it fixes the regression but partially breaks the constraint intersection, in particular this fails to identify the first hash constraint out of multiple hash constraints.

E.g. for

let y (f: #I & #Task<int> & #seq<string>) = ()

this will identify #Task<int> and #seq<string> as a HashConstraint but #I is just LongIdent.

Any ideas, maybe @auduchinok or @kerams?

Copy link
Contributor

@brianrourkeboll brianrourkeboll left a comment

Choose a reason for hiding this comment

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

@psfinaki

Would it make sense to define something like this separately:

hashConstraint:
  | HASH atomType
     { SynType.HashConstraint($2, lhs parseState) }

and then use hashConstraint in place of HASH atomType here:

fsharp/src/Compiler/pars.fsy

Lines 6215 to 6217 in 32e2822

atomType:
| HASH atomType
{ SynType.HashConstraint($2, lhs parseState) }

and here:

fsharp/src/Compiler/pars.fsy

Lines 5995 to 6000 in 32e2822

intersectionType:
| typar AMP intersectionConstraints %prec prec_no_more_attr_bindings // todo precedence
{ let constraints, mAmpersands = $3
SynType.Intersection(Some $1, List.rev constraints, lhs parseState, { AmpersandRanges = rhs parseState 2 :: List.rev mAmpersands }) }
| HASH atomType AMP intersectionConstraints %prec prec_no_more_attr_bindings // todo precedence

and in place of atomType here (with the recovery/error-reporting adjusted accordingly):

fsharp/src/Compiler/pars.fsy

Lines 2581 to 2596 in 32e2822

intersectionConstraints:
| intersectionConstraints AMP atomType %prec prec_no_more_attr_bindings // todo precedence
{ let constraints, mAmpersands = $1
match $3 with
| SynType.HashConstraint _ -> ()
| ty -> errorR(Error(FSComp.SR.parsConstraintIntersectionSyntaxUsedWithNonFlexibleType(), ty.Range))
($3 :: constraints), (rhs parseState 2 :: mAmpersands) }
| atomType
{ match $1 with
| SynType.HashConstraint _ -> ()
| ty -> errorR(Error(FSComp.SR.parsConstraintIntersectionSyntaxUsedWithNonFlexibleType(), ty.Range))
[ $1 ], [] }

?

@psfinaki
Copy link
Member Author

psfinaki commented May 9, 2024

@brianrourkeboll first of all - thanks for jumping in :) (this was meant to be sent on Tuesday but somehow didn't post here)

Secondly, the approach you suggest seems to do the job!
I was mostly playing with precedences but that didn't satisfy all tests. So thanks for your fresh thoughts.

@psfinaki psfinaki marked this pull request as ready for review May 9, 2024 16:34
@psfinaki psfinaki requested a review from a team as a code owner May 9, 2024 16:34
@psfinaki
Copy link
Member Author

psfinaki commented May 9, 2024

Okay this is green finally :)

@psfinaki psfinaki requested a review from auduchinok May 9, 2024 16:52
@brianrourkeboll
Copy link
Contributor

I think this approach should work — as long as we never need to extend the intersection type syntax to allow anything other than flexible types.

@psfinaki psfinaki changed the title Fix pattern matching parser regression Fix a few AND operator parser regressions May 10, 2024
@psfinaki
Copy link
Member Author

/azp run

Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@edgarfgp
Copy link
Contributor

@psfinaki Out of curiosity would this help with #16309 ?

@brianrourkeboll
Copy link
Contributor

@edgarfgp

Out of curiosity would this help with #16309 ?

I would guess that the second change here, from atomType to hashConstraint, would address this, yes:

 intersectionType:
-  | typar AMP intersectionConstraints %prec prec_no_more_attr_bindings // todo precedence
+  | typar AMP intersectionConstraints %prec prec_no_more_attr_bindings
     { let constraints, mAmpersands = $3
       SynType.Intersection(Some $1, List.rev constraints, lhs parseState, { AmpersandRanges = rhs parseState 2 :: List.rev mAmpersands }) }

-  | atomType AMP intersectionConstraints %prec prec_no_more_attr_bindings // todo precedence
+  | hashConstraint AMP intersectionConstraints %prec prec_no_more_attr_bindings
     { let constraints, mAmpersands = $3
       SynType.Intersection(None, $1 :: List.rev constraints, lhs parseState, { AmpersandRanges = rhs parseState 2 :: List.rev mAmpersands }) }

@psfinaki
Copy link
Member Author

@edgarfgp looks like it does fix that one as well!

I will add more tests then, thanks for pointing out :)

@edgarfgp
Copy link
Contributor

@edgarfgp looks like it does fix that one as well!

I will add more tests then, thanks for pointing out :)

Awesome to finally tackle all of these issues.

@psfinaki psfinaki changed the title Fix a few AND operator parser regressions Fix a few AND operator parser bugs and regressions May 13, 2024
@psfinaki psfinaki requested a review from KevinRansom May 14, 2024 19:22
@T-Gro T-Gro disabled auto-merge May 15, 2024 08:49
@T-Gro T-Gro merged commit 3f7772a into dotnet:main May 15, 2024
32 checks passed
@T-Gro
Copy link
Member

T-Gro commented May 15, 2024

(auto merge had some error, merged manually)

@psfinaki psfinaki deleted the fix-16447 branch May 15, 2024 09:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
7 participants