diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fs b/src/Compiler/SyntaxTree/SyntaxTree.fs index e02559815a3..452d174c73c 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fs +++ b/src/Compiler/SyntaxTree/SyntaxTree.fs @@ -881,7 +881,7 @@ type SynSimplePats = type SynArgPats = | Pats of pats: SynPat list - | NamePatPairs of pats: (Ident * range * SynPat) list * range: range * trivia: SynArgPatsNamePatPairsTrivia + | NamePatPairs of pats: (Ident * range option * SynPat) list * range: range * trivia: SynArgPatsNamePatPairsTrivia member x.Patterns = match x with diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fsi b/src/Compiler/SyntaxTree/SyntaxTree.fsi index c9619454ded..575673804f5 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTree.fsi @@ -1025,7 +1025,7 @@ type SynSimplePats = type SynArgPats = | Pats of pats: SynPat list - | NamePatPairs of pats: (Ident * range * SynPat) list * range: range * trivia: SynArgPatsNamePatPairsTrivia + | NamePatPairs of pats: (Ident * range option * SynPat) list * range: range * trivia: SynArgPatsNamePatPairsTrivia member Patterns: SynPat list diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 64223ea75be..496d70bae62 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -3133,7 +3133,12 @@ namePatPairs: namePatPair: | ident EQUALS parenPattern { let mEquals = rhs parseState 2 - ($1, mEquals, $3) } + ($1, Some mEquals, $3) } + | ident EQUALS recover + { let mEquals = rhs parseState 2 + ($1, Some mEquals, patFromParseError (SynPat.Wild mEquals.EndRange)) } + | ident recover + { ($1, None, patFromParseError (SynPat.Wild $1.idRange.EndRange)) } constrPattern: | atomicPatternLongIdent explicitValTyparDecls diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl index 86a216e066b..af07cb1e4aa 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl @@ -5769,8 +5769,8 @@ FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: FSharp.Compiler.SyntaxTrivia.Syn FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia trivia FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: FSharp.Compiler.Text.Range get_range() FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: FSharp.Compiler.Text.Range range -FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Text.Range,FSharp.Compiler.Syntax.SynPat]] get_pats() -FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Text.Range,FSharp.Compiler.Syntax.SynPat]] pats +FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.Ident,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range],FSharp.Compiler.Syntax.SynPat]] get_pats() +FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.Ident,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range],FSharp.Compiler.Syntax.SynPat]] pats FSharp.Compiler.Syntax.SynArgPats+Pats: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat] get_pats() FSharp.Compiler.Syntax.SynArgPats+Pats: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat] pats FSharp.Compiler.Syntax.SynArgPats+Tags: Int32 NamePatPairs @@ -5779,7 +5779,7 @@ FSharp.Compiler.Syntax.SynArgPats: Boolean IsNamePatPairs FSharp.Compiler.Syntax.SynArgPats: Boolean IsPats FSharp.Compiler.Syntax.SynArgPats: Boolean get_IsNamePatPairs() FSharp.Compiler.Syntax.SynArgPats: Boolean get_IsPats() -FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats NewNamePatPairs(Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Text.Range,FSharp.Compiler.Syntax.SynPat]], FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia) +FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats NewNamePatPairs(Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.Ident,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range],FSharp.Compiler.Syntax.SynPat]], FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia) FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats NewPats(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat]) FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats+NamePatPairs FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats+Pats diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl index 86a216e066b..af07cb1e4aa 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl @@ -5769,8 +5769,8 @@ FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: FSharp.Compiler.SyntaxTrivia.Syn FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia trivia FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: FSharp.Compiler.Text.Range get_range() FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: FSharp.Compiler.Text.Range range -FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Text.Range,FSharp.Compiler.Syntax.SynPat]] get_pats() -FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Text.Range,FSharp.Compiler.Syntax.SynPat]] pats +FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.Ident,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range],FSharp.Compiler.Syntax.SynPat]] get_pats() +FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.Ident,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range],FSharp.Compiler.Syntax.SynPat]] pats FSharp.Compiler.Syntax.SynArgPats+Pats: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat] get_pats() FSharp.Compiler.Syntax.SynArgPats+Pats: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat] pats FSharp.Compiler.Syntax.SynArgPats+Tags: Int32 NamePatPairs @@ -5779,7 +5779,7 @@ FSharp.Compiler.Syntax.SynArgPats: Boolean IsNamePatPairs FSharp.Compiler.Syntax.SynArgPats: Boolean IsPats FSharp.Compiler.Syntax.SynArgPats: Boolean get_IsNamePatPairs() FSharp.Compiler.Syntax.SynArgPats: Boolean get_IsPats() -FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats NewNamePatPairs(Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Text.Range,FSharp.Compiler.Syntax.SynPat]], FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia) +FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats NewNamePatPairs(Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.Ident,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range],FSharp.Compiler.Syntax.SynPat]], FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia) FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats NewPats(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat]) FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats+NamePatPairs FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats+Pats diff --git a/tests/service/data/SyntaxTree/Pattern/NamedPatPairRecoverAfterEquals.fs b/tests/service/data/SyntaxTree/Pattern/NamedPatPairRecoverAfterEquals.fs new file mode 100644 index 00000000000..ad0c46afcfc --- /dev/null +++ b/tests/service/data/SyntaxTree/Pattern/NamedPatPairRecoverAfterEquals.fs @@ -0,0 +1,2 @@ +match x with +| Y(z = ) -> () diff --git a/tests/service/data/SyntaxTree/Pattern/NamedPatPairRecoverAfterEquals.fs.bsl b/tests/service/data/SyntaxTree/Pattern/NamedPatPairRecoverAfterEquals.fs.bsl new file mode 100644 index 00000000000..4549710dfd6 --- /dev/null +++ b/tests/service/data/SyntaxTree/Pattern/NamedPatPairRecoverAfterEquals.fs.bsl @@ -0,0 +1,26 @@ +ImplFile + (ParsedImplFileInput + ("/root/Pattern/NamedPatPairRecoverAfterEquals.fs", false, + QualifiedNameOfFile NamedPatPairRecoverAfterEquals, [], [], + [SynModuleOrNamespace + ([NamedPatPairRecoverAfterEquals], false, AnonModule, + [Expr + (Match + (Yes (1,0--1,12), Ident x, + [SynMatchClause + (LongIdent + (SynLongIdent ([Y], [], [None]), None, None, + NamePatPairs + ([(z, Some (2,6--2,7), + FromParseError (Wild (2,7--2,7), (2,7--2,7)))], + (2,4--2,9), { ParenRange = (2,3--2,9) }), None, + (2,2--2,9)), None, Const (Unit, (2,13--2,15)), + (2,2--2,15), Yes, { ArrowRange = Some (2,10--2,12) + BarRange = Some (2,0--2,1) })], + (1,0--2,15), { MatchKeyword = (1,0--1,5) + WithKeyword = (1,8--1,12) }), (1,0--2,15))], + PreXmlDocEmpty, [], None, (1,0--3,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(2,8)-(2,9) parse error Unexpected symbol ')' in pattern diff --git a/tests/service/data/SyntaxTree/Pattern/NamedPatPairRecoverAfterIdentifier.fs b/tests/service/data/SyntaxTree/Pattern/NamedPatPairRecoverAfterIdentifier.fs new file mode 100644 index 00000000000..9c207d700e3 --- /dev/null +++ b/tests/service/data/SyntaxTree/Pattern/NamedPatPairRecoverAfterIdentifier.fs @@ -0,0 +1,2 @@ +match x with +| Y(a = 1; b = 2; c) -> () diff --git a/tests/service/data/SyntaxTree/Pattern/NamedPatPairRecoverAfterIdentifier.fs.bsl b/tests/service/data/SyntaxTree/Pattern/NamedPatPairRecoverAfterIdentifier.fs.bsl new file mode 100644 index 00000000000..c288ee9ea72 --- /dev/null +++ b/tests/service/data/SyntaxTree/Pattern/NamedPatPairRecoverAfterIdentifier.fs.bsl @@ -0,0 +1,28 @@ +ImplFile + (ParsedImplFileInput + ("/root/Pattern/NamedPatPairRecoverAfterIdentifier.fs", false, + QualifiedNameOfFile NamedPatPairRecoverAfterIdentifier, [], [], + [SynModuleOrNamespace + ([NamedPatPairRecoverAfterIdentifier], false, AnonModule, + [Expr + (Match + (Yes (1,0--1,12), Ident x, + [SynMatchClause + (LongIdent + (SynLongIdent ([Y], [], [None]), None, None, + NamePatPairs + ([(a, Some (2,6--2,7), Const (Int32 1, (2,8--2,9))); + (b, Some (2,13--2,14), Const (Int32 2, (2,15--2,16))); + (c, None, + FromParseError (Wild (2,19--2,19), (2,19--2,19)))], + (2,4--2,20), { ParenRange = (2,3--2,20) }), None, + (2,2--2,20)), None, Const (Unit, (2,24--2,26)), + (2,2--2,26), Yes, { ArrowRange = Some (2,21--2,23) + BarRange = Some (2,0--2,1) })], + (1,0--2,26), { MatchKeyword = (1,0--1,5) + WithKeyword = (1,8--1,12) }), (1,0--2,26))], + PreXmlDocEmpty, [], None, (1,0--3,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(2,19)-(2,20) parse error Unexpected symbol ')' in pattern. Expected '=' or other token. diff --git a/tests/service/data/SyntaxTree/Pattern/ParenthesesOfSynArgPatsNamePatPairs.fs.bsl b/tests/service/data/SyntaxTree/Pattern/ParenthesesOfSynArgPatsNamePatPairs.fs.bsl index a875ebd4c57..e260f077c31 100644 --- a/tests/service/data/SyntaxTree/Pattern/ParenthesesOfSynArgPatsNamePatPairs.fs.bsl +++ b/tests/service/data/SyntaxTree/Pattern/ParenthesesOfSynArgPatsNamePatPairs.fs.bsl @@ -11,7 +11,7 @@ ImplFile (LongIdent (SynLongIdent ([OnePartData], [], [None]), None, None, NamePatPairs - ([(part1, (4,10--4,11), + ([(part1, Some (4,10--4,11), Named (SynIdent (p1, None), false, None, (4,12--4,14)))], (4,4--5,13), { ParenRange = (3,13--5,13) }), None, diff --git a/tests/service/data/SyntaxTree/Pattern/SynArgPatsNamePatPairsContainsTheRangeOfTheEqualsSign.fs.bsl b/tests/service/data/SyntaxTree/Pattern/SynArgPatsNamePatPairsContainsTheRangeOfTheEqualsSign.fs.bsl index b82db10dce3..61afba6c7a8 100644 --- a/tests/service/data/SyntaxTree/Pattern/SynArgPatsNamePatPairsContainsTheRangeOfTheEqualsSign.fs.bsl +++ b/tests/service/data/SyntaxTree/Pattern/SynArgPatsNamePatPairsContainsTheRangeOfTheEqualsSign.fs.bsl @@ -14,7 +14,7 @@ ImplFile (LongIdent (SynLongIdent ([X], [], [None]), None, None, NamePatPairs - ([(Y, (3,7--3,8), + ([(Y, Some (3,7--3,8), Named (SynIdent (y, None), false, None, (3,9--3,10)))], (3,4--3,11), { ParenRange = (3,3--3,11) }), None,