Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
* Allow object expression without overrides. ([Language suggestion #632](https://github.com/fsharp/fslang-suggestions/issues/632), [PR #17387](https://github.com/dotnet/fsharp/pull/17387))
* Enable FSharp 9.0 Language Version ([Issue #17497](https://github.com/dotnet/fsharp/issues/17438)), [PR](https://github.com/dotnet/fsharp/pull/17500)))
* Enable LanguageFeature.EnforceAttributeTargets in F# 9.0. ([Issue #17514](https://github.com/dotnet/fsharp/issues/17558), [PR #17516](https://github.com/dotnet/fsharp/pull/17558))
* Parser: better recovery for unfinished patterns ([PR #17231](https://github.com/dotnet/fsharp/pull/17231), [PR #17232](https://github.com/dotnet/fsharp/pull/17232)))

### Changed

Expand Down
23 changes: 21 additions & 2 deletions src/Compiler/pars.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) ->
%type <SynPat> headBindingPattern
%type <SynType> appTypeNullableInParens
%type <SynType> atomTypeNonAtomicDeprecated
%type <SynType> atomTypeOrAnonRecdType
%type <SynExpr> atomicExprAfterType
%type <SynExpr> typedSequentialExprBlock
%type <SynExpr * bool> atomicExpr
Expand Down Expand Up @@ -3550,7 +3551,7 @@ headBindingPattern:
{ let mColonColon = rhs parseState 2
SynPat.ListCons($1, $3, rhs2 parseState 1 3, { ColonColonRange = mColonColon }) }

| headBindingPattern COLON_COLON recover
| headBindingPattern COLON_COLON ends_coming_soon_or_recover
{ let mColonColon = rhs parseState 2
let pat2 = SynPat.Wild(mColonColon.EndRange)
SynPat.ListCons($1, pat2, rhs2 parseState 1 2, { ColonColonRange = mColonColon }) }
Expand Down Expand Up @@ -3679,7 +3680,21 @@ constrPattern:
SynPat.LongIdent(lid, None, None, args, vis, m) }

| COLON_QMARK atomTypeOrAnonRecdType %prec pat_isinst
{ SynPat.IsInst($2, lhs parseState) }
{ let m = unionRanges (rhs parseState 1) $2.Range
SynPat.IsInst($2, m) }

| COLON_QMARK recover %prec pat_isinst
{ let mColon = rhs parseState 1
if not $2 then
reportParseErrorAt mColon (FSComp.SR.parsExpectingPattern ())
let ty = SynType.FromParseError(mColon.EndRange)
SynPat.IsInst(ty, mColon) }

| COLON_QMARK %prec pat_isinst
{ let mColon = rhs parseState 1
let ty = SynType.FromParseError(mColon.EndRange)
reportParseErrorAt mColon (FSComp.SR.parsExpectingType ())
SynPat.IsInst(ty, mColon) }

| atomicPattern
{ $1 }
Expand Down Expand Up @@ -3856,6 +3871,8 @@ parenPattern:

| parenPattern COLON recover
{ let mColon = rhs parseState 2
if not $3 then
reportParseErrorAt mColon (FSComp.SR.parsExpectingPattern ())
let ty = SynType.FromParseError(mColon.EndRange)
SynPat.Typed($1, ty, unionRanges $1.Range mColon) }

Expand All @@ -3869,6 +3886,8 @@ parenPattern:

| parenPattern COLON_COLON recover
{ let mColonColon = rhs parseState 2
if not $3 then
reportParseErrorAt mColonColon (FSComp.SR.parsExpectingPattern ())
let pat2 = SynPat.Wild(mColonColon.EndRange)
SynPat.ListCons($1, pat2, rhs2 parseState 1 2, { ColonColonRange = mColonColon }) }

Expand Down
6 changes: 6 additions & 0 deletions tests/service/data/SyntaxTree/MatchClause/Missing pat 05.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Module

match () with
|

()
18 changes: 18 additions & 0 deletions tests/service/data/SyntaxTree/MatchClause/Missing pat 05.fs.bsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
ImplFile
(ParsedImplFileInput
("/root/MatchClause/Missing pat 05.fs", false, QualifiedNameOfFile Module,
[], [],
[SynModuleOrNamespace
([Module], false, NamedModule,
[Expr
(Match
(Yes (3,0--3,13), Const (Unit, (3,6--3,8)), [], (3,0--4,1),
{ MatchKeyword = (3,0--3,5)
WithKeyword = (3,9--3,13) }), (3,0--4,1));
Expr (Const (Unit, (6,0--6,2)), (6,0--6,2))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))

(6,0)-(6,1) parse error Incomplete structured construct at or before this point in expression
6 changes: 6 additions & 0 deletions tests/service/data/SyntaxTree/Pattern/IsInst 01.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Module

match () with
| :? T -> ()

()
21 changes: 21 additions & 0 deletions tests/service/data/SyntaxTree/Pattern/IsInst 01.fs.bsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
ImplFile
(ParsedImplFileInput
("/root/Pattern/IsInst 01.fs", false, QualifiedNameOfFile Module, [], [],
[SynModuleOrNamespace
([Module], false, NamedModule,
[Expr
(Match
(Yes (3,0--3,13), Const (Unit, (3,6--3,8)),
[SynMatchClause
(IsInst
(LongIdent (SynLongIdent ([T], [], [None])), (4,2--4,6)),
None, Const (Unit, (4,10--4,12)), (4,2--4,12), Yes,
{ ArrowRange = Some (4,7--4,9)
BarRange = Some (4,0--4,1) })], (3,0--4,12),
{ MatchKeyword = (3,0--3,5)
WithKeyword = (3,9--3,13) }), (3,0--4,12));
Expr (Const (Unit, (6,0--6,2)), (6,0--6,2))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))
6 changes: 6 additions & 0 deletions tests/service/data/SyntaxTree/Pattern/IsInst 02.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Module

match () with
| :? T

()
23 changes: 23 additions & 0 deletions tests/service/data/SyntaxTree/Pattern/IsInst 02.fs.bsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
ImplFile
(ParsedImplFileInput
("/root/Pattern/IsInst 02.fs", false, QualifiedNameOfFile Module, [], [],
[SynModuleOrNamespace
([Module], false, NamedModule,
[Expr
(Match
(Yes (3,0--3,13), Const (Unit, (3,6--3,8)),
[SynMatchClause
(IsInst
(LongIdent (SynLongIdent ([T], [], [None])), (4,2--4,6)),
None, ArbitraryAfterError ("patternClauses2", (4,6--4,6)),
(4,2--4,6), Yes, { ArrowRange = None
BarRange = Some (4,0--4,1) })],
(3,0--4,6), { MatchKeyword = (3,0--3,5)
WithKeyword = (3,9--3,13) }), (3,0--4,6));
Expr (Const (Unit, (6,0--6,2)), (6,0--6,2))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))

(6,0)-(6,1) parse error Incomplete structured construct at or before this point in pattern matching. Expected '->' or other token.
6 changes: 6 additions & 0 deletions tests/service/data/SyntaxTree/Pattern/IsInst 03.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Module

match () with
| :? -> ()

()
22 changes: 22 additions & 0 deletions tests/service/data/SyntaxTree/Pattern/IsInst 03.fs.bsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
ImplFile
(ParsedImplFileInput
("/root/Pattern/IsInst 03.fs", false, QualifiedNameOfFile Module, [], [],
[SynModuleOrNamespace
([Module], false, NamedModule,
[Expr
(Match
(Yes (3,0--3,13), Const (Unit, (3,6--3,8)),
[SynMatchClause
(IsInst (FromParseError (4,4--4,4), (4,2--4,4)), None,
Const (Unit, (4,8--4,10)), (4,2--4,10), Yes,
{ ArrowRange = Some (4,5--4,7)
BarRange = Some (4,0--4,1) })], (3,0--4,10),
{ MatchKeyword = (3,0--3,5)
WithKeyword = (3,9--3,13) }), (3,0--4,10));
Expr (Const (Unit, (6,0--6,2)), (6,0--6,2))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))

(4,2)-(4,4) parse error Expecting type
6 changes: 6 additions & 0 deletions tests/service/data/SyntaxTree/Pattern/IsInst 04.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Module

match () with
| :?

()
23 changes: 23 additions & 0 deletions tests/service/data/SyntaxTree/Pattern/IsInst 04.fs.bsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
ImplFile
(ParsedImplFileInput
("/root/Pattern/IsInst 04.fs", false, QualifiedNameOfFile Module, [], [],
[SynModuleOrNamespace
([Module], false, NamedModule,
[Expr
(Match
(Yes (3,0--3,13), Const (Unit, (3,6--3,8)),
[SynMatchClause
(IsInst (FromParseError (4,4--4,4), (4,2--4,4)), None,
ArbitraryAfterError ("patternClauses2", (4,4--4,4)),
(4,2--4,4), Yes, { ArrowRange = None
BarRange = Some (4,0--4,1) })],
(3,0--4,4), { MatchKeyword = (3,0--3,5)
WithKeyword = (3,9--3,13) }), (3,0--4,4));
Expr (Const (Unit, (6,0--6,2)), (6,0--6,2))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))

(4,2)-(4,4) parse error Expecting type
(6,0)-(6,1) parse error Incomplete structured construct at or before this point in pattern matching. Expected '->' or other token.
7 changes: 7 additions & 0 deletions tests/service/data/SyntaxTree/Pattern/IsInst 05.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module Module

match () with
| :?
| _ -> ()

()
24 changes: 24 additions & 0 deletions tests/service/data/SyntaxTree/Pattern/IsInst 05.fs.bsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
ImplFile
(ParsedImplFileInput
("/root/Pattern/IsInst 05.fs", false, QualifiedNameOfFile Module, [], [],
[SynModuleOrNamespace
([Module], false, NamedModule,
[Expr
(Match
(Yes (3,0--3,13), Const (Unit, (3,6--3,8)),
[SynMatchClause
(Or
(IsInst (FromParseError (4,4--4,4), (4,2--4,4)),
Wild (5,2--5,3), (4,2--5,3), { BarRange = (5,0--5,1) }),
None, Const (Unit, (5,7--5,9)), (4,2--5,9), Yes,
{ ArrowRange = Some (5,4--5,6)
BarRange = Some (4,0--4,1) })], (3,0--5,9),
{ MatchKeyword = (3,0--3,5)
WithKeyword = (3,9--3,13) }), (3,0--5,9));
Expr (Const (Unit, (7,0--7,2)), (7,0--7,2))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--7,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))

(4,2)-(4,4) parse error Expecting type