diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md index 476df124084..82892d11db9 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -129,6 +129,7 @@ * Fix dot-completion after indexed expressions (`a.[0].Data.`, `a[0].Data.`, `[1;2].Length.`) returning unrelated global completions instead of expression-typings members. ([Issue #4966](https://github.com/dotnet/fsharp/issues/4966), [PR #19934](https://github.com/dotnet/fsharp/pull/19934)) * Quotations of `match s with "" -> _` no longer leak the `s <> null && s.Length = 0` lowering; the empty-string optimization moved from pattern-match compilation to the optimizer so quoted expressions keep `op_Equality(s, "")`. ([Issue #19873](https://github.com/dotnet/fsharp/issues/19873)) * Fix #5795: Allow attributes defined in a `module rec` / `namespace rec` scope to be used on union cases, record fields, and generic type parameters of types in the same recursive scope. ([Issue #5795](https://github.com/dotnet/fsharp/issues/5795), [PR #19744](https://github.com/dotnet/fsharp/pull/19744)) +* Parser: recover on missing interface members ([PR #20105](https://github.com/dotnet/fsharp/pull/20105)) ### Added diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 01120123a36..2483d757502 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -2313,6 +2313,10 @@ opt_interfaceImplDefn: { let mWithKwd = rhs parseState 1 Some(mWithKwd, [], mWithKwd) } + | OWITH recover + { let mWithKwd = rhs parseState 1 + Some(mWithKwd, [], mWithKwd) } + | /* EMPTY */ { None } diff --git a/tests/service/data/SyntaxTree/Member/Interface 11.fs b/tests/service/data/SyntaxTree/Member/Interface 11.fs new file mode 100644 index 00000000000..96bbda25a76 --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Interface 11.fs @@ -0,0 +1,6 @@ +module Module + +type T = + interface I with [] + +let f () = () diff --git a/tests/service/data/SyntaxTree/Member/Interface 11.fs.bsl b/tests/service/data/SyntaxTree/Member/Interface 11.fs.bsl new file mode 100644 index 00000000000..a609f789285 --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Interface 11.fs.bsl @@ -0,0 +1,42 @@ +ImplFile + (ParsedImplFileInput + ("/root/Member/Interface 11.fs", false, QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [T], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (3,5--3,6)), + ObjectModel + (Unspecified, + [Interface + (LongIdent (SynLongIdent ([I], [], [None])), + Some (4,16--4,20), Some [], (4,4--4,20))], (4,4--4,20)), + [], None, (3,5--4,20), { LeadingKeyword = Type (3,0--3,4) + EqualsRange = Some (3,7--3,8) + WithKeyword = None })], (3,0--4,20)); + Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((6,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([[]], SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent ([f], [], [None]), None, None, + Pats [Paren (Const (Unit, (6,6--6,8)), (6,6--6,8))], None, + (6,4--6,8)), None, Const (Unit, (6,11--6,13)), (6,4--6,8), + NoneAtLet, { LeadingKeyword = Let (6,0--6,3) + InlineKeyword = None + EqualsRange = Some (6,9--6,10) })], (6,0--6,13), + { InKeyword = None })], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,13), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(4,21)-(4,23) parse error Unexpected symbol '[<' in member definition +(6,0)-(6,3) parse error Incomplete structured construct at or before this point in member definition