Repository navigation
Prefer the function reading of a return-annotated let binding head - #248
Open
pcshrosbree wants to merge 1 commit into
Open
pcshrosbree wants to merge 1 commit into
pcshrosbree wants to merge 1 commit into
Conversation
Fixes the let case of ionide#244 (members are still open). `let h (g: int -> int) : int = g 42` also parses as a value binding whose pattern swallows the return type (`h (g ...) : int` as a typed constructor pattern). Both GLR versions survive to the `=`, and the static precedences of function_declaration_left (3) and value_declaration_left (2) cannot rank them there, so the winner depended on what followed the binding: a value_declaration_left as the last binding in a file, a function_declaration_left otherwise. A dynamic precedence on function_declaration_left makes the function reading win whenever both survive, as every unannotated head already parses. The parse tables are unchanged in size, and no corpus file parses differently by error count. This changes the expected tree of one existing test, "multidimensional array types" (`let f (x: float[,]) : float[,,,] = x`), which recorded the value-binding shape for exactly this case.
Author
|
This PR is one of a set; #255 maps them all, with their dependencies and merge order. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the
letcase of #244. The member case is still open; see below.let h (g: int -> int) : int = g 42has two readings in this grammar:function_declaration_left(hwithargument_patterns) followed by the return type;value_declaration_leftwhose pattern swallows the return type:h (g …) : intas an identifier pattern with a typed argument.FSC's parser produces one
SynPat.LongIdenthead either way and lets the checker decide. This grammar, though, prefers the function reading: every head without a return annotation, and evenlet Some x = …, parses asfunction_declaration_left. With the annotation, both GLR versions survive to the=, and the static precedences (3 and 2) cannot rank them there. The winner depended on what followed: the value reading when the binding was last in the file, the function reading otherwise.Change
prec.dynamic(1, …)onfunction_declaration_left, so the function reading wins whenever both versions survive. The parse tables are the same size, since dynamic precedence only breaks GLR ties.Tests
New tests in
test/corpus/function_defn.txtcover a return-annotated function as the last binding in the file: with one parameter (the issue's example), with two, and withprivate. All fail onmainand parse cleanly with FCS (Fantomas.FCS7.0.5).One existing test changes its expected tree.
multidimensional array types(let f (x: float[,]) : float[,,,] =/x) recorded the value reading for exactly this case. It now has the function head, withx: float[,]inargument_patternsandfloat[,,,]as the return type.Not fixed here: members
member _.H (f: int -> int) : int = f 21still folds the return type into the last argument, astyped_pattern (paren_pattern …) int._method_defnhas no return-type slot: itsargsarerepeat1($._pattern), and a trailing: Tparses as a typed pattern statically, not as a GLR tie that dynamic precedence could break. Adding an optional return type there changes nothing for the same reason. FSC's member arguments are atomic patterns, so the principled fix is atomicargs. In this grammar, though,_atomic_patternhas other node shapes: a barelong_identifier, and parentheses without aparen_patternnode. That would rewrite the expected tree of nearly every member test, so I've left it for a separate change.Corpus
check:baseline: no file changes its error count.check:invalid: all recorded errors are still found.