diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index dde1ee4031f..65c684ab550 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -16,6 +16,7 @@ * Enforce AttributeTargets on let values and functions. ([PR #16692](https://github.com/dotnet/fsharp/pull/16692)) * Enforce AttributeTargets on union case declarations. ([PR #16764](https://github.com/dotnet/fsharp/pull/16764)) * Disallow using base to invoke an abstract base method. ([Issue #13926](https://github.com/dotnet/fsharp/issues/13926), [PR #16773](https://github.com/dotnet/fsharp/pull/16773)) +* Parser: more unfinished member recovery ([PR #16835](https://github.com/dotnet/fsharp/pull/16835)) * Enforce AttributeTargets on implicit constructors. ([PR #16845](https://github.com/dotnet/fsharp/pull/16845/)) * Enforce AttributeTargets on structs and classes ([PR #16790](https://github.com/dotnet/fsharp/pull/16790)) * Parser: fix pattern range for idents with trivia ([PR #16824](https://github.com/dotnet/fsharp/pull/16824)) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 73fcdaf17e6..b1b4f43a473 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -1910,7 +1910,7 @@ memberCore: let memberRange = unionRanges rangeStart mEnd |> unionRangeWithXmlDoc xmlDoc [ SynMemberDefn.Member (binding, memberRange) ] } - | opt_inline bindingPattern opt_topReturnTypeWithTypeConstraints recover + | opt_inline bindingPattern opt_topReturnTypeWithTypeConstraints ends_coming_soon_or_recover { let optReturnType = $3 let bindingPat, mBindLhs = $2 let mEnd = @@ -1918,6 +1918,7 @@ memberCore: | Some(_, ty) -> ty.Range.EndRange | _ -> bindingPat.Range.EndRange let expr = arbExpr ("memberCore2", mEnd) + errorR (Error(FSComp.SR.parsMissingMemberBody(), rhs parseState 4)) fun vis flagsBuilderAndLeadingKeyword attrs rangeStart -> let xmlDoc = grabXmlDocAtRangeStart(parseState, attrs, rangeStart) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/AccessibilityAnnotations/OnTypeMembers/OnTypeMembers.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/AccessibilityAnnotations/OnTypeMembers/OnTypeMembers.fs index 0fbbe44a903..49c79c2600d 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/AccessibilityAnnotations/OnTypeMembers/OnTypeMembers.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/AccessibilityAnnotations/OnTypeMembers/OnTypeMembers.fs @@ -90,6 +90,7 @@ module AccessibilityAnnotations_OnTypeMembers = (Error 10, Line 20, Col 49, Line 20, Col 50, "Unexpected identifier in pattern") (Error 1244, Line 20, Col 48, Line 20, Col 57, "Attempted to parse this as an operator name, but failed") (Error 10, Line 23, Col 36, Line 23, Col 42, "Unexpected keyword 'public' in member definition") + (Error 3567, Line 23, Col 36, Line 23, Col 42, "Expecting member body") ] // SOURCE=OnProperty01.fs # OnProperty01.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/ImportDeclarations.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/ImportDeclarations.fs index 851746df35c..449fb5bd9d3 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/ImportDeclarations.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/ImportDeclarations.fs @@ -73,6 +73,7 @@ module ImportDeclarations = (Error 10, Line 9, Col 5, Line 9, Col 9, "Unexpected keyword 'open' in binding. Expected incomplete structured construct at or before this point or other token.") (Error 10, Line 17, Col 9, Line 17, Col 13, "Unexpected keyword 'open' in binding") (Error 10, Line 23, Col 9, Line 23, Col 13, "Unexpected keyword 'open' in expression") + (Error 3567, Line 23, Col 9, Line 23, Col 13, "Expecting member body") ] // SOURCE=OpenNestedModule01.fs # OpenNestedModule01.fs diff --git a/tests/fsharpqa/Source/Diagnostics/General/E_IncompleteConstruct01.fs b/tests/fsharpqa/Source/Diagnostics/General/E_IncompleteConstruct01.fs index e6d2ee6c084..63bbad5d811 100644 --- a/tests/fsharpqa/Source/Diagnostics/General/E_IncompleteConstruct01.fs +++ b/tests/fsharpqa/Source/Diagnostics/General/E_IncompleteConstruct01.fs @@ -1,6 +1,6 @@ // #Regression #Diagnostics // Regression test for FSHARP1.0:1181 -//Incomplete structured construct at or before this point in member definition\. Expected 'with', '=' or other token\. +//Expecting member body type INumericNorm<'T,'Measure> = interface INumeric<'T> diff --git a/tests/fsharpqa/Source/Diagnostics/General/E_IncompleteConstruct01b.fs b/tests/fsharpqa/Source/Diagnostics/General/E_IncompleteConstruct01b.fs index e3fb451018e..b029157e52b 100644 --- a/tests/fsharpqa/Source/Diagnostics/General/E_IncompleteConstruct01b.fs +++ b/tests/fsharpqa/Source/Diagnostics/General/E_IncompleteConstruct01b.fs @@ -1,7 +1,7 @@ // #Regression #Diagnostics // Regression test for FSHARP1.0:1181 //syntax error -// +// diff --git a/tests/service/data/SyntaxTree/Expression/Object - Class 07.fs.bsl b/tests/service/data/SyntaxTree/Expression/Object - Class 07.fs.bsl index 02f2b2c4bb5..eeaef3fd16a 100644 --- a/tests/service/data/SyntaxTree/Expression/Object - Class 07.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/Object - Class 07.fs.bsl @@ -35,4 +35,4 @@ ImplFile { ConditionalDirectives = [] CodeComments = [] }, set [])) -(4,17)-(4,18) parse error Incomplete structured construct at or before this point in object expression. Expected 'with', '=' or other token. +(4,17)-(4,18) parse error Expecting member body diff --git a/tests/service/data/SyntaxTree/Expression/Object - Class 08.fs.bsl b/tests/service/data/SyntaxTree/Expression/Object - Class 08.fs.bsl index da2aa3f44bc..f7c76b0b8fb 100644 --- a/tests/service/data/SyntaxTree/Expression/Object - Class 08.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/Object - Class 08.fs.bsl @@ -36,4 +36,4 @@ ImplFile CodeComments = [] }, set [])) (4,18)-(4,19) parse error Identifier expected -(4,18)-(4,19) parse error Incomplete structured construct at or before this point in object expression. Expected 'with', '=' or other token. +(4,18)-(4,19) parse error Expecting member body diff --git a/tests/service/data/SyntaxTree/Expression/Object - Class 09.fs.bsl b/tests/service/data/SyntaxTree/Expression/Object - Class 09.fs.bsl index 5fc68741000..831deffbeac 100644 --- a/tests/service/data/SyntaxTree/Expression/Object - Class 09.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/Object - Class 09.fs.bsl @@ -38,4 +38,4 @@ ImplFile { ConditionalDirectives = [] CodeComments = [] }, set [])) -(4,19)-(4,20) parse error Incomplete structured construct at or before this point in object expression. Expected 'with', '=' or other token. +(4,19)-(4,20) parse error Expecting member body diff --git a/tests/service/data/SyntaxTree/Member/Member 08.fs.bsl b/tests/service/data/SyntaxTree/Member/Member 08.fs.bsl index d7a7eda73ea..b2e10558c6a 100644 --- a/tests/service/data/SyntaxTree/Member/Member 08.fs.bsl +++ b/tests/service/data/SyntaxTree/Member/Member 08.fs.bsl @@ -76,4 +76,4 @@ ImplFile { ConditionalDirectives = [] CodeComments = [] }, set [])) -(5,0)-(5,0) parse error Incomplete structured construct at or before this point in member definition. Expected 'with', '=' or other token. +(5,0)-(5,0) parse error Expecting member body diff --git a/tests/service/data/SyntaxTree/Member/Member 10.fs.bsl b/tests/service/data/SyntaxTree/Member/Member 10.fs.bsl index 5749df6a18b..e0e6936d612 100644 --- a/tests/service/data/SyntaxTree/Member/Member 10.fs.bsl +++ b/tests/service/data/SyntaxTree/Member/Member 10.fs.bsl @@ -45,4 +45,4 @@ ImplFile { ConditionalDirectives = [] CodeComments = [] }, set [])) -(7,0)-(7,0) parse error Incomplete structured construct at or before this point in member definition. Expected 'with', '=' or other token. +(7,0)-(7,0) parse error Expecting member body diff --git a/tests/service/data/SyntaxTree/Member/Member 12.fs.bsl b/tests/service/data/SyntaxTree/Member/Member 12.fs.bsl index 94ece410c41..44e361be813 100644 --- a/tests/service/data/SyntaxTree/Member/Member 12.fs.bsl +++ b/tests/service/data/SyntaxTree/Member/Member 12.fs.bsl @@ -43,4 +43,4 @@ ImplFile CodeComments = [] }, set [])) (6,0)-(6,1) parse error Identifier expected -(6,0)-(6,1) parse error Incomplete structured construct at or before this point in member definition. Expected 'with', '=' or other token. +(6,0)-(6,1) parse error Expecting member body diff --git a/tests/service/data/SyntaxTree/Member/Member 13.fs b/tests/service/data/SyntaxTree/Member/Member 13.fs new file mode 100644 index 00000000000..98b5bc08640 --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Member 13.fs @@ -0,0 +1,9 @@ +module Module + +type A = + static member P: + +type B = + | A of int + +() diff --git a/tests/service/data/SyntaxTree/Member/Member 13.fs.bsl b/tests/service/data/SyntaxTree/Member/Member 13.fs.bsl new file mode 100644 index 00000000000..129c9f529ce --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Member 13.fs.bsl @@ -0,0 +1,77 @@ +ImplFile + (ParsedImplFileInput + ("/root/Member/Member 13.fs", false, QualifiedNameOfFile Module, [], [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [A], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (3,5--3,6)), + ObjectModel + (Unspecified, + [Member + (SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (Some { IsInstance = false + IsDispatchSlot = false + IsOverrideOrExplicitImpl = false + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = Member }, + SynValInfo ([[]], SynArgInfo ([], false, None)), + None), + LongIdent + (SynLongIdent ([P], [], [None]), None, None, + Pats [], None, (4,18--4,19)), + Some + (SynBindingReturnInfo + (FromParseError (4,20--4,20), (4,20--4,20), [], + { ColonRange = Some (4,19--4,20) })), + Typed + (ArbitraryAfterError ("memberCore2", (4,20--4,20)), + FromParseError (4,20--4,20), (4,20--4,20)), + (4,18--4,19), NoneAtInvisible, + { LeadingKeyword = + StaticMember ((4,4--4,10), (4,11--4,17)) + InlineKeyword = None + EqualsRange = None }), (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)); + Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [B], + PreXmlDoc ((6,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (6,5--6,6)), + Simple + (Union + (None, + [SynUnionCase + ([], SynIdent (A, None), + Fields + [SynField + ([], false, None, + LongIdent (SynLongIdent ([int], [], [None])), + false, + PreXmlDoc ((7,11), FSharp.Compiler.Xml.XmlDocCollector), + None, (7,11--7,14), { LeadingKeyword = None + MutableKeyword = None })], + PreXmlDoc ((7,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (7,6--7,14), { BarRange = Some (7,4--7,5) })], + (7,4--7,14)), (7,4--7,14)), [], None, (6,5--7,14), + { LeadingKeyword = Type (6,0--6,4) + EqualsRange = Some (6,7--6,8) + WithKeyword = None })], (6,0--7,14)); + Expr (Const (Unit, (9,0--9,2)), (9,0--9,2))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--9,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(6,0)-(6,4) parse error Incomplete structured construct at or before this point in member definition +(6,0)-(6,4) parse error Expecting member body