Fix a few AND operator parser regressions
Fixes #16447 Fixes #17134
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
- [x] Test cases added
- [x] Release notes entry updated
:heavy_exclamation_mark: Release notes required
:white_check_mark: Found changes and release notes in following paths:
Change path Release notes path Description src/Compilerdocs/release-notes/.FSharp.Compiler.Service/8.0.400.md
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?
@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.
Okay this is green finally :)
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.
/azp run
Azure Pipelines successfully started running 2 pipeline(s).
@psfinaki Out of curiosity would this help with https://github.com/dotnet/fsharp/issues/16309 ?
@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 }) }
@edgarfgp looks like it does fix that one as well!
I will add more tests then, thanks for pointing out :)
@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.
(auto merge had some error, merged manually)