From a4246f0575534c17d58dc4d8913d2cdd925343d3 Mon Sep 17 00:00:00 2001 From: edgargonzalez Date: Mon, 5 May 2025 15:42:02 +0100 Subject: [PATCH 1/6] Add new rules --- src/Compiler/pars.fsy | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 7cac0ad0dc0..42f74f7649c 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -4416,6 +4416,16 @@ declExpr: { let trivia: SynExprYieldOrReturnTrivia = { YieldOrReturnKeyword = rhs parseState 1 } SynExpr.YieldOrReturn(($1, not $1), $2, (unionRanges (rhs parseState 1) $2.Range), trivia) } + | YIELD declExpr COLON typ + { let trivia: SynExprYieldOrReturnTrivia = { YieldOrReturnKeyword = rhs parseState 1 } + let typedExpr = SynExpr.Typed($2, $4, unionRanges $2.Range $4.Range) + SynExpr.YieldOrReturn(($1, not $1), typedExpr, (unionRanges (rhs parseState 1) $4.Range), trivia) } + + | YIELD_BANG declExpr COLON typ + { let trivia: SynExprYieldOrReturnFromTrivia = { YieldOrReturnFromKeyword = rhs parseState 1 } + let typedExpr = SynExpr.Typed($2, $4, unionRanges $2.Range $4.Range) + SynExpr.YieldOrReturnFrom(($1, not $1), typedExpr, (unionRanges (rhs parseState 1) $2.Range), trivia) } + | YIELD_BANG declExpr { let trivia: SynExprYieldOrReturnFromTrivia = { YieldOrReturnFromKeyword = rhs parseState 1 } SynExpr.YieldOrReturnFrom(($1, not $1), $2, (unionRanges (rhs parseState 1) $2.Range), trivia) } From 5fe09e08c6b2ccff02924d86ac9e59e9fe32151f Mon Sep 17 00:00:00 2001 From: edgargonzalez Date: Mon, 5 May 2025 15:42:19 +0100 Subject: [PATCH 2/6] Add syntax tree tests --- .../data/SyntaxTree/Expression/Return 01.fs | 7 ++++ .../SyntaxTree/Expression/Return 01.fs.bsl | 36 +++++++++++++++++ .../data/SyntaxTree/Expression/Return 02.fs | 7 ++++ .../SyntaxTree/Expression/Return 02.fs.bsl | 39 ++++++++++++++++++ .../data/SyntaxTree/Expression/Return 03.fs | 7 ++++ .../SyntaxTree/Expression/Return 03.fs.bsl | 36 +++++++++++++++++ .../data/SyntaxTree/Expression/Return 04.fs | 7 ++++ .../SyntaxTree/Expression/Return 04.fs.bsl | 39 ++++++++++++++++++ .../data/SyntaxTree/Expression/Return 05.fs | 7 ++++ .../SyntaxTree/Expression/Return 05.fs.bsl | 32 +++++++++++++++ .../data/SyntaxTree/Expression/Return 06.fs | 7 ++++ .../SyntaxTree/Expression/Return 06.fs.bsl | 34 ++++++++++++++++ .../SyntaxTree/Expression/ReturnBang 01.fs | 7 ++++ .../Expression/ReturnBang 01.fs.bsl | 37 +++++++++++++++++ .../SyntaxTree/Expression/ReturnBang 02.fs | 7 ++++ .../Expression/ReturnBang 02.fs.bsl | 40 +++++++++++++++++++ .../data/SyntaxTree/Expression/Yield 01.fs | 4 ++ .../SyntaxTree/Expression/Yield 01.fs.bsl | 24 +++++++++++ .../data/SyntaxTree/Expression/Yield 02.fs | 6 +++ .../SyntaxTree/Expression/Yield 02.fs.bsl | 31 ++++++++++++++ .../data/SyntaxTree/Expression/Yield 03.fs | 6 +++ .../SyntaxTree/Expression/Yield 03.fs.bsl | 34 ++++++++++++++++ .../data/SyntaxTree/Expression/Yield 04.fs | 4 ++ .../SyntaxTree/Expression/Yield 04.fs.bsl | 26 ++++++++++++ .../SyntaxTree/Expression/YieldBang 01.fs | 5 +++ .../SyntaxTree/Expression/YieldBang 01.fs.bsl | 25 ++++++++++++ .../SyntaxTree/Expression/YieldBang 02.fs | 4 ++ .../SyntaxTree/Expression/YieldBang 02.fs.bsl | 27 +++++++++++++ .../SyntaxTree/Expression/YieldBang 03.fs | 6 +++ .../SyntaxTree/Expression/YieldBang 03.fs.bsl | 32 +++++++++++++++ .../SyntaxTree/Expression/YieldBang 04.fs | 7 ++++ .../SyntaxTree/Expression/YieldBang 04.fs.bsl | 35 ++++++++++++++++ 32 files changed, 625 insertions(+) create mode 100644 tests/service/data/SyntaxTree/Expression/Return 01.fs create mode 100644 tests/service/data/SyntaxTree/Expression/Return 01.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/Return 02.fs create mode 100644 tests/service/data/SyntaxTree/Expression/Return 02.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/Return 03.fs create mode 100644 tests/service/data/SyntaxTree/Expression/Return 03.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/Return 04.fs create mode 100644 tests/service/data/SyntaxTree/Expression/Return 04.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/Return 05.fs create mode 100644 tests/service/data/SyntaxTree/Expression/Return 05.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/Return 06.fs create mode 100644 tests/service/data/SyntaxTree/Expression/Return 06.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/ReturnBang 01.fs create mode 100644 tests/service/data/SyntaxTree/Expression/ReturnBang 01.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/ReturnBang 02.fs create mode 100644 tests/service/data/SyntaxTree/Expression/ReturnBang 02.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/Yield 01.fs create mode 100644 tests/service/data/SyntaxTree/Expression/Yield 01.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/Yield 02.fs create mode 100644 tests/service/data/SyntaxTree/Expression/Yield 02.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/Yield 03.fs create mode 100644 tests/service/data/SyntaxTree/Expression/Yield 03.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/Yield 04.fs create mode 100644 tests/service/data/SyntaxTree/Expression/Yield 04.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/YieldBang 01.fs create mode 100644 tests/service/data/SyntaxTree/Expression/YieldBang 01.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/YieldBang 02.fs create mode 100644 tests/service/data/SyntaxTree/Expression/YieldBang 02.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/YieldBang 03.fs create mode 100644 tests/service/data/SyntaxTree/Expression/YieldBang 03.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/YieldBang 04.fs create mode 100644 tests/service/data/SyntaxTree/Expression/YieldBang 04.fs.bsl diff --git a/tests/service/data/SyntaxTree/Expression/Return 01.fs b/tests/service/data/SyntaxTree/Expression/Return 01.fs new file mode 100644 index 00000000000..51695776a55 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Return 01.fs @@ -0,0 +1,7 @@ +module Module + +let _ = + async { + return new MyType() : IDisposable + } + diff --git a/tests/service/data/SyntaxTree/Expression/Return 01.fs.bsl b/tests/service/data/SyntaxTree/Expression/Return 01.fs.bsl new file mode 100644 index 00000000000..2e14fc025c9 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Return 01.fs.bsl @@ -0,0 +1,36 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/Return 01.fs", false, QualifiedNameOfFile Module, [], [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Wild (3,4--3,5), None, + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturn + ((false, true), + Typed + (New + (false, + LongIdent (SynLongIdent ([MyType], [], [None])), + Const (Unit, (5,25--5,27)), (5,15--5,27)), + LongIdent + (SynLongIdent ([IDisposable], [], [None])), + (5,15--5,41)), (5,8--5,41), + { YieldOrReturnKeyword = (5,8--5,14) }), (4,10--6,5)), + (4,4--6,5)), (3,4--3,5), NoneAtLet, + { LeadingKeyword = Let (3,0--3,3) + InlineKeyword = None + EqualsRange = Some (3,6--3,7) })], (3,0--6,5))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,5), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/Return 02.fs b/tests/service/data/SyntaxTree/Expression/Return 02.fs new file mode 100644 index 00000000000..2bfa5ecf136 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Return 02.fs @@ -0,0 +1,7 @@ +module Module + +let _ = + async { + return (new MyType() : IDisposable) + } + diff --git a/tests/service/data/SyntaxTree/Expression/Return 02.fs.bsl b/tests/service/data/SyntaxTree/Expression/Return 02.fs.bsl new file mode 100644 index 00000000000..59ab0dac633 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Return 02.fs.bsl @@ -0,0 +1,39 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/Return 02.fs", false, QualifiedNameOfFile Module, [], [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Wild (3,4--3,5), None, + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturn + ((false, true), + Paren + (Typed + (New + (false, + LongIdent + (SynLongIdent ([MyType], [], [None])), + Const (Unit, (5,26--5,28)), (5,16--5,28)), + LongIdent + (SynLongIdent ([IDisposable], [], [None])), + (5,16--5,42)), (5,15--5,16), Some (5,42--5,43), + (5,15--5,43)), (5,8--5,43), + { YieldOrReturnKeyword = (5,8--5,14) }), (4,10--6,5)), + (4,4--6,5)), (3,4--3,5), NoneAtLet, + { LeadingKeyword = Let (3,0--3,3) + InlineKeyword = None + EqualsRange = Some (3,6--3,7) })], (3,0--6,5))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,5), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/Return 03.fs b/tests/service/data/SyntaxTree/Expression/Return 03.fs new file mode 100644 index 00000000000..ddf6e531468 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Return 03.fs @@ -0,0 +1,7 @@ +module Module + +let _ = + async { + return new MyType() :> IDisposable + } + diff --git a/tests/service/data/SyntaxTree/Expression/Return 03.fs.bsl b/tests/service/data/SyntaxTree/Expression/Return 03.fs.bsl new file mode 100644 index 00000000000..68d17129ef3 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Return 03.fs.bsl @@ -0,0 +1,36 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/Return 03.fs", false, QualifiedNameOfFile Module, [], [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Wild (3,4--3,5), None, + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturn + ((false, true), + Upcast + (New + (false, + LongIdent (SynLongIdent ([MyType], [], [None])), + Const (Unit, (5,25--5,27)), (5,15--5,27)), + LongIdent + (SynLongIdent ([IDisposable], [], [None])), + (5,15--5,42)), (5,8--5,42), + { YieldOrReturnKeyword = (5,8--5,14) }), (4,10--6,5)), + (4,4--6,5)), (3,4--3,5), NoneAtLet, + { LeadingKeyword = Let (3,0--3,3) + InlineKeyword = None + EqualsRange = Some (3,6--3,7) })], (3,0--6,5))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,5), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/Return 04.fs b/tests/service/data/SyntaxTree/Expression/Return 04.fs new file mode 100644 index 00000000000..933a72820cc --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Return 04.fs @@ -0,0 +1,7 @@ +module Module + +let _ = + async { + return (new MyType() :> IDisposable) + } + diff --git a/tests/service/data/SyntaxTree/Expression/Return 04.fs.bsl b/tests/service/data/SyntaxTree/Expression/Return 04.fs.bsl new file mode 100644 index 00000000000..00afeeaa092 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Return 04.fs.bsl @@ -0,0 +1,39 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/Return 04.fs", false, QualifiedNameOfFile Module, [], [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Wild (3,4--3,5), None, + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturn + ((false, true), + Paren + (Upcast + (New + (false, + LongIdent + (SynLongIdent ([MyType], [], [None])), + Const (Unit, (5,26--5,28)), (5,16--5,28)), + LongIdent + (SynLongIdent ([IDisposable], [], [None])), + (5,16--5,43)), (5,15--5,16), Some (5,43--5,44), + (5,15--5,44)), (5,8--5,44), + { YieldOrReturnKeyword = (5,8--5,14) }), (4,10--6,5)), + (4,4--6,5)), (3,4--3,5), NoneAtLet, + { LeadingKeyword = Let (3,0--3,3) + InlineKeyword = None + EqualsRange = Some (3,6--3,7) })], (3,0--6,5))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,5), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/Return 05.fs b/tests/service/data/SyntaxTree/Expression/Return 05.fs new file mode 100644 index 00000000000..bd1ef865815 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Return 05.fs @@ -0,0 +1,7 @@ +module Module + +let _ = + async { + return new MyType() + } + diff --git a/tests/service/data/SyntaxTree/Expression/Return 05.fs.bsl b/tests/service/data/SyntaxTree/Expression/Return 05.fs.bsl new file mode 100644 index 00000000000..06b83071496 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Return 05.fs.bsl @@ -0,0 +1,32 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/Return 05.fs", false, QualifiedNameOfFile Module, [], [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Wild (3,4--3,5), None, + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturn + ((false, true), + New + (false, + LongIdent (SynLongIdent ([MyType], [], [None])), + Const (Unit, (5,25--5,27)), (5,15--5,27)), + (5,8--5,27), { YieldOrReturnKeyword = (5,8--5,14) }), + (4,10--6,5)), (4,4--6,5)), (3,4--3,5), NoneAtLet, + { LeadingKeyword = Let (3,0--3,3) + InlineKeyword = None + EqualsRange = Some (3,6--3,7) })], (3,0--6,5))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,5), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/Return 06.fs b/tests/service/data/SyntaxTree/Expression/Return 06.fs new file mode 100644 index 00000000000..95941f09646 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Return 06.fs @@ -0,0 +1,7 @@ +module Module + +let _ = + async { + return (new MyType()) + } + diff --git a/tests/service/data/SyntaxTree/Expression/Return 06.fs.bsl b/tests/service/data/SyntaxTree/Expression/Return 06.fs.bsl new file mode 100644 index 00000000000..fc57c66f5db --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Return 06.fs.bsl @@ -0,0 +1,34 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/Return 06.fs", false, QualifiedNameOfFile Module, [], [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Wild (3,4--3,5), None, + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturn + ((false, true), + Paren + (New + (false, + LongIdent (SynLongIdent ([MyType], [], [None])), + Const (Unit, (5,26--5,28)), (5,16--5,28)), + (5,15--5,16), Some (5,28--5,29), (5,15--5,29)), + (5,8--5,29), { YieldOrReturnKeyword = (5,8--5,14) }), + (4,10--6,5)), (4,4--6,5)), (3,4--3,5), NoneAtLet, + { LeadingKeyword = Let (3,0--3,3) + InlineKeyword = None + EqualsRange = Some (3,6--3,7) })], (3,0--6,5))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,5), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/ReturnBang 01.fs b/tests/service/data/SyntaxTree/Expression/ReturnBang 01.fs new file mode 100644 index 00000000000..009a45b4c08 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/ReturnBang 01.fs @@ -0,0 +1,7 @@ +module Module + +let _ = + async { + return! new MyType() : IDisposable + } + diff --git a/tests/service/data/SyntaxTree/Expression/ReturnBang 01.fs.bsl b/tests/service/data/SyntaxTree/Expression/ReturnBang 01.fs.bsl new file mode 100644 index 00000000000..537dde46f62 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/ReturnBang 01.fs.bsl @@ -0,0 +1,37 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/ReturnBang 01.fs", false, QualifiedNameOfFile Module, [], + [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Wild (3,4--3,5), None, + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturnFrom + ((false, true), + Typed + (New + (false, + LongIdent (SynLongIdent ([MyType], [], [None])), + Const (Unit, (5,26--5,28)), (5,16--5,28)), + LongIdent + (SynLongIdent ([IDisposable], [], [None])), + (5,16--5,42)), (5,8--5,28), + { YieldOrReturnFromKeyword = (5,8--5,15) }), + (4,10--6,5)), (4,4--6,5)), (3,4--3,5), NoneAtLet, + { LeadingKeyword = Let (3,0--3,3) + InlineKeyword = None + EqualsRange = Some (3,6--3,7) })], (3,0--6,5))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,5), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/ReturnBang 02.fs b/tests/service/data/SyntaxTree/Expression/ReturnBang 02.fs new file mode 100644 index 00000000000..91fd750a01b --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/ReturnBang 02.fs @@ -0,0 +1,7 @@ +module Module + +let _ = + async { + return! (new MyType() : IDisposable) + } + diff --git a/tests/service/data/SyntaxTree/Expression/ReturnBang 02.fs.bsl b/tests/service/data/SyntaxTree/Expression/ReturnBang 02.fs.bsl new file mode 100644 index 00000000000..aa1df37ee9a --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/ReturnBang 02.fs.bsl @@ -0,0 +1,40 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/ReturnBang 02.fs", false, QualifiedNameOfFile Module, [], + [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Wild (3,4--3,5), None, + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturnFrom + ((false, true), + Paren + (Typed + (New + (false, + LongIdent + (SynLongIdent ([MyType], [], [None])), + Const (Unit, (5,27--5,29)), (5,17--5,29)), + LongIdent + (SynLongIdent ([IDisposable], [], [None])), + (5,17--5,43)), (5,16--5,17), Some (5,43--5,44), + (5,16--5,44)), (5,8--5,44), + { YieldOrReturnFromKeyword = (5,8--5,15) }), + (4,10--6,5)), (4,4--6,5)), (3,4--3,5), NoneAtLet, + { LeadingKeyword = Let (3,0--3,3) + InlineKeyword = None + EqualsRange = Some (3,6--3,7) })], (3,0--6,5))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,5), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/Yield 01.fs b/tests/service/data/SyntaxTree/Expression/Yield 01.fs new file mode 100644 index 00000000000..8f3656d8fcb --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Yield 01.fs @@ -0,0 +1,4 @@ +module Module + +yield [ 1 .. 10 ]: int list + diff --git a/tests/service/data/SyntaxTree/Expression/Yield 01.fs.bsl b/tests/service/data/SyntaxTree/Expression/Yield 01.fs.bsl new file mode 100644 index 00000000000..97efec2aec0 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Yield 01.fs.bsl @@ -0,0 +1,24 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/Yield 01.fs", false, QualifiedNameOfFile Module, [], [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (YieldOrReturn + ((true, false), + Typed + (ArrayOrListComputed + (false, + IndexRange + (Some (Const (Int32 1, (3,8--3,9))), (3,10--3,12), + Some (Const (Int32 10, (3,13--3,15))), (3,8--3,9), + (3,13--3,15), (3,8--3,15)), (3,6--3,17)), + App + (LongIdent (SynLongIdent ([list], [], [None])), None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], None, + true, (3,19--3,27)), (3,6--3,27)), (3,0--3,27), + { YieldOrReturnKeyword = (3,0--3,5) }), (3,0--3,27))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--3,27), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/Yield 02.fs b/tests/service/data/SyntaxTree/Expression/Yield 02.fs new file mode 100644 index 00000000000..0573f7af70a --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Yield 02.fs @@ -0,0 +1,6 @@ +module Module + +seq { + yield [ 1 .. 10 ]: int list +} + diff --git a/tests/service/data/SyntaxTree/Expression/Yield 02.fs.bsl b/tests/service/data/SyntaxTree/Expression/Yield 02.fs.bsl new file mode 100644 index 00000000000..a08ff30db77 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Yield 02.fs.bsl @@ -0,0 +1,31 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/Yield 02.fs", false, QualifiedNameOfFile Module, [], [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident seq, + ComputationExpr + (false, + YieldOrReturn + ((true, false), + Typed + (ArrayOrListComputed + (false, + IndexRange + (Some (Const (Int32 1, (4,12--4,13))), + (4,14--4,16), + Some (Const (Int32 10, (4,17--4,19))), + (4,12--4,13), (4,17--4,19), (4,12--4,19)), + (4,10--4,21)), + App + (LongIdent (SynLongIdent ([list], [], [None])), None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], + None, true, (4,23--4,31)), (4,10--4,31)), + (4,4--4,31), { YieldOrReturnKeyword = (4,4--4,9) }), + (3,4--5,1)), (3,0--5,1)), (3,0--5,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--5,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/Yield 03.fs b/tests/service/data/SyntaxTree/Expression/Yield 03.fs new file mode 100644 index 00000000000..d5c1f13e24f --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Yield 03.fs @@ -0,0 +1,6 @@ +module Module + +seq { + yield ([ 1 .. 10 ]: int list) +} + diff --git a/tests/service/data/SyntaxTree/Expression/Yield 03.fs.bsl b/tests/service/data/SyntaxTree/Expression/Yield 03.fs.bsl new file mode 100644 index 00000000000..a5710c8bb9c --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Yield 03.fs.bsl @@ -0,0 +1,34 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/Yield 03.fs", false, QualifiedNameOfFile Module, [], [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident seq, + ComputationExpr + (false, + YieldOrReturn + ((true, false), + Paren + (Typed + (ArrayOrListComputed + (false, + IndexRange + (Some (Const (Int32 1, (4,13--4,14))), + (4,15--4,17), + Some (Const (Int32 10, (4,18--4,20))), + (4,13--4,14), (4,18--4,20), (4,13--4,20)), + (4,11--4,22)), + App + (LongIdent (SynLongIdent ([list], [], [None])), + None, + [LongIdent (SynLongIdent ([int], [], [None]))], + [], None, true, (4,24--4,32)), (4,11--4,32)), + (4,10--4,11), Some (4,32--4,33), (4,10--4,33)), + (4,4--4,33), { YieldOrReturnKeyword = (4,4--4,9) }), + (3,4--5,1)), (3,0--5,1)), (3,0--5,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--5,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/Yield 04.fs b/tests/service/data/SyntaxTree/Expression/Yield 04.fs new file mode 100644 index 00000000000..e31740cb322 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Yield 04.fs @@ -0,0 +1,4 @@ +module Module + +yield ([ 1 .. 10 ]: int list) + diff --git a/tests/service/data/SyntaxTree/Expression/Yield 04.fs.bsl b/tests/service/data/SyntaxTree/Expression/Yield 04.fs.bsl new file mode 100644 index 00000000000..2363fe76684 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Yield 04.fs.bsl @@ -0,0 +1,26 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/Yield 04.fs", false, QualifiedNameOfFile Module, [], [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (YieldOrReturn + ((true, false), + Paren + (Typed + (ArrayOrListComputed + (false, + IndexRange + (Some (Const (Int32 1, (3,9--3,10))), (3,11--3,13), + Some (Const (Int32 10, (3,14--3,16))), (3,9--3,10), + (3,14--3,16), (3,9--3,16)), (3,7--3,18)), + App + (LongIdent (SynLongIdent ([list], [], [None])), None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], + None, true, (3,20--3,28)), (3,7--3,28)), (3,6--3,7), + Some (3,28--3,29), (3,6--3,29)), (3,0--3,29), + { YieldOrReturnKeyword = (3,0--3,5) }), (3,0--3,29))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--3,29), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/YieldBang 01.fs b/tests/service/data/SyntaxTree/Expression/YieldBang 01.fs new file mode 100644 index 00000000000..dbfd3f4beef --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/YieldBang 01.fs @@ -0,0 +1,5 @@ +module Module + +yield! [ 1 .. 10 ]: int list + + diff --git a/tests/service/data/SyntaxTree/Expression/YieldBang 01.fs.bsl b/tests/service/data/SyntaxTree/Expression/YieldBang 01.fs.bsl new file mode 100644 index 00000000000..a469799bff8 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/YieldBang 01.fs.bsl @@ -0,0 +1,25 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/YieldBang 01.fs", false, QualifiedNameOfFile Module, [], + [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (YieldOrReturnFrom + ((true, false), + Typed + (ArrayOrListComputed + (false, + IndexRange + (Some (Const (Int32 1, (3,9--3,10))), (3,11--3,13), + Some (Const (Int32 10, (3,14--3,16))), (3,9--3,10), + (3,14--3,16), (3,9--3,16)), (3,7--3,18)), + App + (LongIdent (SynLongIdent ([list], [], [None])), None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], None, + true, (3,20--3,28)), (3,7--3,28)), (3,0--3,18), + { YieldOrReturnFromKeyword = (3,0--3,6) }), (3,0--3,18))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--3,18), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/YieldBang 02.fs b/tests/service/data/SyntaxTree/Expression/YieldBang 02.fs new file mode 100644 index 00000000000..ed1bd0fea97 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/YieldBang 02.fs @@ -0,0 +1,4 @@ +module Module + +yield! ([ 1 .. 10 ]: int list) + diff --git a/tests/service/data/SyntaxTree/Expression/YieldBang 02.fs.bsl b/tests/service/data/SyntaxTree/Expression/YieldBang 02.fs.bsl new file mode 100644 index 00000000000..3f7d1e2526b --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/YieldBang 02.fs.bsl @@ -0,0 +1,27 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/YieldBang 02.fs", false, QualifiedNameOfFile Module, [], + [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (YieldOrReturnFrom + ((true, false), + Paren + (Typed + (ArrayOrListComputed + (false, + IndexRange + (Some (Const (Int32 1, (3,10--3,11))), (3,12--3,14), + Some (Const (Int32 10, (3,15--3,17))), (3,10--3,11), + (3,15--3,17), (3,10--3,17)), (3,8--3,19)), + App + (LongIdent (SynLongIdent ([list], [], [None])), None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], + None, true, (3,21--3,29)), (3,8--3,29)), (3,7--3,8), + Some (3,29--3,30), (3,7--3,30)), (3,0--3,30), + { YieldOrReturnFromKeyword = (3,0--3,6) }), (3,0--3,30))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--3,30), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/YieldBang 03.fs b/tests/service/data/SyntaxTree/Expression/YieldBang 03.fs new file mode 100644 index 00000000000..c80ceb053c5 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/YieldBang 03.fs @@ -0,0 +1,6 @@ +module Module + +seq { + yield! [ 1 .. 10 ]: int list +} + diff --git a/tests/service/data/SyntaxTree/Expression/YieldBang 03.fs.bsl b/tests/service/data/SyntaxTree/Expression/YieldBang 03.fs.bsl new file mode 100644 index 00000000000..431a5f04e38 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/YieldBang 03.fs.bsl @@ -0,0 +1,32 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/YieldBang 03.fs", false, QualifiedNameOfFile Module, [], + [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident seq, + ComputationExpr + (false, + YieldOrReturnFrom + ((true, false), + Typed + (ArrayOrListComputed + (false, + IndexRange + (Some (Const (Int32 1, (4,13--4,14))), + (4,15--4,17), + Some (Const (Int32 10, (4,18--4,20))), + (4,13--4,14), (4,18--4,20), (4,13--4,20)), + (4,11--4,22)), + App + (LongIdent (SynLongIdent ([list], [], [None])), None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], + None, true, (4,24--4,32)), (4,11--4,32)), + (4,4--4,22), { YieldOrReturnFromKeyword = (4,4--4,10) }), + (3,4--5,1)), (3,0--5,1)), (3,0--5,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--5,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/YieldBang 04.fs b/tests/service/data/SyntaxTree/Expression/YieldBang 04.fs new file mode 100644 index 00000000000..e80aee60891 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/YieldBang 04.fs @@ -0,0 +1,7 @@ +module Module + +seq { + yield! ([ 1 .. 10 ]: int list) +} + + diff --git a/tests/service/data/SyntaxTree/Expression/YieldBang 04.fs.bsl b/tests/service/data/SyntaxTree/Expression/YieldBang 04.fs.bsl new file mode 100644 index 00000000000..1a4dcede9c9 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/YieldBang 04.fs.bsl @@ -0,0 +1,35 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/YieldBang 04.fs", false, QualifiedNameOfFile Module, [], + [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident seq, + ComputationExpr + (false, + YieldOrReturnFrom + ((true, false), + Paren + (Typed + (ArrayOrListComputed + (false, + IndexRange + (Some (Const (Int32 1, (4,14--4,15))), + (4,16--4,18), + Some (Const (Int32 10, (4,19--4,21))), + (4,14--4,15), (4,19--4,21), (4,14--4,21)), + (4,12--4,23)), + App + (LongIdent (SynLongIdent ([list], [], [None])), + None, + [LongIdent (SynLongIdent ([int], [], [None]))], + [], None, true, (4,25--4,33)), (4,12--4,33)), + (4,11--4,12), Some (4,33--4,34), (4,11--4,34)), + (4,4--4,34), { YieldOrReturnFromKeyword = (4,4--4,10) }), + (3,4--5,1)), (3,0--5,1)), (3,0--5,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--5,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) From caeb72fdd50789c46a2f5d3592f8bd6e1b0c3aeb Mon Sep 17 00:00:00 2001 From: edgargonzalez Date: Mon, 5 May 2025 15:42:37 +0100 Subject: [PATCH 3/6] Add a component test --- .../Language/ComputationExpressionTests.fs | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs index 6b0a260a42f..b5ad5d638ab 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs @@ -23,6 +23,41 @@ let x = lb {1; 2;} |> shouldSucceed |> ignore + [] + let ``Allow CE return and type annotations to play well together without needing parentheses``() = + FSharp """ +module ComputationExpressionTests +open System + +type MyType() = + interface IDisposable with + member this.Dispose () = () + +let f () = + async { + return new MyType() : IDisposable + } + +let f1 () = + async { + return new MyType() :> IDisposable + } + +let f2 () : Async = + async { + return new MyType() + } + +let f3 () = + async { + return (new MyType() : IDisposable) + } + """ + |> asExe + |> withOptions ["--nowarn:988"] + |> compileAndRun + |> shouldSucceed + [] let ``A CE explicitly using Zero fails without a defined Zero``() = FSharp """ From 76e5921b6eb1ada87fc31c556d796cb07d335ddd Mon Sep 17 00:00:00 2001 From: edgargonzalez Date: Tue, 6 May 2025 20:07:34 +0100 Subject: [PATCH 4/6] ad recovery rules --- src/Compiler/pars.fsy | 18 +++++++++ .../data/SyntaxTree/Expression/Return 07.fs | 6 +++ .../SyntaxTree/Expression/Return 07.fs.bsl | 36 ++++++++++++++++++ .../SyntaxTree/Expression/ReturnBang 03.fs | 7 ++++ .../Expression/ReturnBang 03.fs.bsl | 38 +++++++++++++++++++ .../data/SyntaxTree/Expression/Yield 05.fs | 6 +++ .../SyntaxTree/Expression/Yield 05.fs.bsl | 30 +++++++++++++++ .../data/SyntaxTree/Expression/Yield 06.fs | 6 +++ .../SyntaxTree/Expression/Yield 06.fs.bsl | 30 +++++++++++++++ .../SyntaxTree/Expression/YieldBang 05.fs | 6 +++ .../SyntaxTree/Expression/YieldBang 05.fs.bsl | 31 +++++++++++++++ .../SyntaxTree/Expression/YieldBang 06.fs | 4 ++ .../SyntaxTree/Expression/YieldBang 06.fs.bsl | 24 ++++++++++++ 13 files changed, 242 insertions(+) create mode 100644 tests/service/data/SyntaxTree/Expression/Return 07.fs create mode 100644 tests/service/data/SyntaxTree/Expression/Return 07.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/ReturnBang 03.fs create mode 100644 tests/service/data/SyntaxTree/Expression/ReturnBang 03.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/Yield 05.fs create mode 100644 tests/service/data/SyntaxTree/Expression/Yield 05.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/Yield 06.fs create mode 100644 tests/service/data/SyntaxTree/Expression/Yield 06.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/YieldBang 05.fs create mode 100644 tests/service/data/SyntaxTree/Expression/YieldBang 05.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Expression/YieldBang 06.fs create mode 100644 tests/service/data/SyntaxTree/Expression/YieldBang 06.fs.bsl diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 42f74f7649c..a080bd9e529 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -4421,11 +4421,29 @@ declExpr: let typedExpr = SynExpr.Typed($2, $4, unionRanges $2.Range $4.Range) SynExpr.YieldOrReturn(($1, not $1), typedExpr, (unionRanges (rhs parseState 1) $4.Range), trivia) } + | YIELD declExpr opt_topReturnTypeWithTypeConstraints + { let trivia: SynExprYieldOrReturnTrivia = { YieldOrReturnKeyword = rhs parseState 1 } + let expr = + match $3 with + | None -> $2 + | Some(_, SynReturnInfo((ty, _), m)) -> + SynExpr.Typed($2, ty, unionRanges $2.Range m) + SynExpr.YieldOrReturn(($1, not $1), expr, (unionRanges (rhs parseState 1) expr.Range), trivia) } + | YIELD_BANG declExpr COLON typ { let trivia: SynExprYieldOrReturnFromTrivia = { YieldOrReturnFromKeyword = rhs parseState 1 } let typedExpr = SynExpr.Typed($2, $4, unionRanges $2.Range $4.Range) SynExpr.YieldOrReturnFrom(($1, not $1), typedExpr, (unionRanges (rhs parseState 1) $2.Range), trivia) } + | YIELD_BANG declExpr opt_topReturnTypeWithTypeConstraints + { let trivia: SynExprYieldOrReturnFromTrivia = { YieldOrReturnFromKeyword = rhs parseState 1 } + let expr = + match $3 with + | None -> $2 + | Some(_, SynReturnInfo((ty, _), m)) -> + SynExpr.Typed($2, ty, unionRanges $2.Range m) + SynExpr.YieldOrReturnFrom(($1, not $1), expr, (unionRanges (rhs parseState 1) $2.Range), trivia) } + | YIELD_BANG declExpr { let trivia: SynExprYieldOrReturnFromTrivia = { YieldOrReturnFromKeyword = rhs parseState 1 } SynExpr.YieldOrReturnFrom(($1, not $1), $2, (unionRanges (rhs parseState 1) $2.Range), trivia) } diff --git a/tests/service/data/SyntaxTree/Expression/Return 07.fs b/tests/service/data/SyntaxTree/Expression/Return 07.fs new file mode 100644 index 00000000000..19e68b27e5c --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Return 07.fs @@ -0,0 +1,6 @@ +module Module + +let _ = + async { + return new MyType() : + } diff --git a/tests/service/data/SyntaxTree/Expression/Return 07.fs.bsl b/tests/service/data/SyntaxTree/Expression/Return 07.fs.bsl new file mode 100644 index 00000000000..497892fd340 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Return 07.fs.bsl @@ -0,0 +1,36 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/Return 07.fs", false, QualifiedNameOfFile Module, [], [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Wild (3,4--3,5), None, + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturn + ((false, true), + Typed + (New + (false, + LongIdent (SynLongIdent ([MyType], [], [None])), + Const (Unit, (5,25--5,27)), (5,15--5,27)), + FromParseError (5,29--5,29), (5,15--5,29)), + (5,8--5,29), { YieldOrReturnKeyword = (5,8--5,14) }), + (4,10--6,5)), (4,4--6,5)), (3,4--3,5), NoneAtLet, + { LeadingKeyword = Let (3,0--3,3) + InlineKeyword = None + EqualsRange = Some (3,6--3,7) })], (3,0--6,5))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,5), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(6,4)-(6,5) parse error Unexpected symbol '}' in expression diff --git a/tests/service/data/SyntaxTree/Expression/ReturnBang 03.fs b/tests/service/data/SyntaxTree/Expression/ReturnBang 03.fs new file mode 100644 index 00000000000..dcb7b9c149a --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/ReturnBang 03.fs @@ -0,0 +1,7 @@ +module Module + +let _ = + async { + return! new MyType() : + } + diff --git a/tests/service/data/SyntaxTree/Expression/ReturnBang 03.fs.bsl b/tests/service/data/SyntaxTree/Expression/ReturnBang 03.fs.bsl new file mode 100644 index 00000000000..8958970b100 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/ReturnBang 03.fs.bsl @@ -0,0 +1,38 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/ReturnBang 03.fs", false, QualifiedNameOfFile Module, [], + [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Wild (3,4--3,5), None, + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + YieldOrReturnFrom + ((false, true), + Typed + (New + (false, + LongIdent (SynLongIdent ([MyType], [], [None])), + Const (Unit, (5,26--5,28)), (5,16--5,28)), + FromParseError (5,30--5,30), (5,16--5,30)), + (5,8--5,28), + { YieldOrReturnFromKeyword = (5,8--5,15) }), + (4,10--6,5)), (4,4--6,5)), (3,4--3,5), NoneAtLet, + { LeadingKeyword = Let (3,0--3,3) + InlineKeyword = None + EqualsRange = Some (3,6--3,7) })], (3,0--6,5))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,5), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(6,4)-(6,5) parse error Unexpected symbol '}' in expression diff --git a/tests/service/data/SyntaxTree/Expression/Yield 05.fs b/tests/service/data/SyntaxTree/Expression/Yield 05.fs new file mode 100644 index 00000000000..573d3b81cdc --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Yield 05.fs @@ -0,0 +1,6 @@ +module Module + +seq { + yield [ 1 .. 10 ] : +} + diff --git a/tests/service/data/SyntaxTree/Expression/Yield 05.fs.bsl b/tests/service/data/SyntaxTree/Expression/Yield 05.fs.bsl new file mode 100644 index 00000000000..2edd1561dda --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Yield 05.fs.bsl @@ -0,0 +1,30 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/Yield 05.fs", false, QualifiedNameOfFile Module, [], [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident seq, + ComputationExpr + (false, + YieldOrReturn + ((true, false), + Typed + (ArrayOrListComputed + (false, + IndexRange + (Some (Const (Int32 1, (4,12--4,13))), + (4,14--4,16), + Some (Const (Int32 10, (4,17--4,19))), + (4,12--4,13), (4,17--4,19), (4,12--4,19)), + (4,10--4,21)), FromParseError (4,23--4,23), + (4,10--4,23)), (4,4--4,23), + { YieldOrReturnKeyword = (4,4--4,9) }), (3,4--5,1)), + (3,0--5,1)), (3,0--5,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--5,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(5,0)-(5,1) parse error Unexpected symbol '}' in expression diff --git a/tests/service/data/SyntaxTree/Expression/Yield 06.fs b/tests/service/data/SyntaxTree/Expression/Yield 06.fs new file mode 100644 index 00000000000..bb699f40621 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Yield 06.fs @@ -0,0 +1,6 @@ +module Module + +seq { + yield [ 1 .. 10 ] : +} + diff --git a/tests/service/data/SyntaxTree/Expression/Yield 06.fs.bsl b/tests/service/data/SyntaxTree/Expression/Yield 06.fs.bsl new file mode 100644 index 00000000000..8f8900c7ba2 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/Yield 06.fs.bsl @@ -0,0 +1,30 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/Yield 06.fs", false, QualifiedNameOfFile Module, [], [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident seq, + ComputationExpr + (false, + YieldOrReturn + ((true, false), + Typed + (ArrayOrListComputed + (false, + IndexRange + (Some (Const (Int32 1, (4,12--4,13))), + (4,14--4,16), + Some (Const (Int32 10, (4,17--4,19))), + (4,12--4,13), (4,17--4,19), (4,12--4,19)), + (4,10--4,21)), FromParseError (4,23--4,23), + (4,10--4,23)), (4,4--4,23), + { YieldOrReturnKeyword = (4,4--4,9) }), (3,4--5,1)), + (3,0--5,1)), (3,0--5,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--5,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(5,0)-(5,1) parse error Unexpected symbol '}' in expression diff --git a/tests/service/data/SyntaxTree/Expression/YieldBang 05.fs b/tests/service/data/SyntaxTree/Expression/YieldBang 05.fs new file mode 100644 index 00000000000..5870293c0d1 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/YieldBang 05.fs @@ -0,0 +1,6 @@ +module Module + +seq { + yield! [ 1 .. 10 ] : +} + diff --git a/tests/service/data/SyntaxTree/Expression/YieldBang 05.fs.bsl b/tests/service/data/SyntaxTree/Expression/YieldBang 05.fs.bsl new file mode 100644 index 00000000000..ae0b6ad7f2b --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/YieldBang 05.fs.bsl @@ -0,0 +1,31 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/YieldBang 05.fs", false, QualifiedNameOfFile Module, [], + [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident seq, + ComputationExpr + (false, + YieldOrReturnFrom + ((true, false), + Typed + (ArrayOrListComputed + (false, + IndexRange + (Some (Const (Int32 1, (4,13--4,14))), + (4,15--4,17), + Some (Const (Int32 10, (4,18--4,20))), + (4,13--4,14), (4,18--4,20), (4,13--4,20)), + (4,11--4,22)), FromParseError (4,24--4,24), + (4,11--4,24)), (4,4--4,22), + { YieldOrReturnFromKeyword = (4,4--4,10) }), (3,4--5,1)), + (3,0--5,1)), (3,0--5,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--5,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(5,0)-(5,1) parse error Unexpected symbol '}' in expression diff --git a/tests/service/data/SyntaxTree/Expression/YieldBang 06.fs b/tests/service/data/SyntaxTree/Expression/YieldBang 06.fs new file mode 100644 index 00000000000..037f709a6e0 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/YieldBang 06.fs @@ -0,0 +1,4 @@ +module Module + +yield! [ 1 .. 10 ] : + diff --git a/tests/service/data/SyntaxTree/Expression/YieldBang 06.fs.bsl b/tests/service/data/SyntaxTree/Expression/YieldBang 06.fs.bsl new file mode 100644 index 00000000000..cc8d49d8071 --- /dev/null +++ b/tests/service/data/SyntaxTree/Expression/YieldBang 06.fs.bsl @@ -0,0 +1,24 @@ +ImplFile + (ParsedImplFileInput + ("/root/Expression/YieldBang 06.fs", false, QualifiedNameOfFile Module, [], + [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (YieldOrReturnFrom + ((true, false), + Typed + (ArrayOrListComputed + (false, + IndexRange + (Some (Const (Int32 1, (3,9--3,10))), (3,11--3,13), + Some (Const (Int32 10, (3,14--3,16))), (3,9--3,10), + (3,14--3,16), (3,9--3,16)), (3,7--3,18)), + FromParseError (3,20--3,20), (3,7--3,20)), (3,0--3,18), + { YieldOrReturnFromKeyword = (3,0--3,6) }), (3,0--3,18))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--3,18), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(5,0)-(5,0) parse error Incomplete structured construct at or before this point in expression From 9d53ca2199b660664eae02a5d8749911a9f76b38 Mon Sep 17 00:00:00 2001 From: edgargonzalez Date: Tue, 6 May 2025 20:09:38 +0100 Subject: [PATCH 5/6] release notes --- docs/release-notes/.FSharp.Compiler.Service/9.0.300.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md index e187f285d4b..b0b7b7de407 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md @@ -31,6 +31,7 @@ * Fix code completion considers types from own namespace non-imported ([PR #18518](https://github.com/dotnet/fsharp/issues/18518)) * Code completion: fix getting qualifier expression in do statements in type decls ([PR #18524](https://github.com/dotnet/fsharp/pull/18524)) * Fixed: [#18441](https://github.com/dotnet/fsharp/issues/18441) FSI multi-emit unstable. ([PR #18465](https://github.com/dotnet/fsharp/pull/18465)) +* Fixed: Allow `return`, `return!`, `yield`, `yield!` and type annotations without parentheses ([PR #18533](https://github.com/dotnet/fsharp/pull/18533)) ### Added * Added missing type constraints in FCS. ([PR #18241](https://github.com/dotnet/fsharp/pull/18241)) From 31d8b996cf3ab7729165a086fdac6446186d89f1 Mon Sep 17 00:00:00 2001 From: edgargonzalez Date: Tue, 6 May 2025 20:09:38 +0100 Subject: [PATCH 6/6] release notes --- docs/release-notes/.FSharp.Compiler.Service/9.0.300.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md index e187f285d4b..7c253f13df1 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md @@ -31,6 +31,7 @@ * Fix code completion considers types from own namespace non-imported ([PR #18518](https://github.com/dotnet/fsharp/issues/18518)) * Code completion: fix getting qualifier expression in do statements in type decls ([PR #18524](https://github.com/dotnet/fsharp/pull/18524)) * Fixed: [#18441](https://github.com/dotnet/fsharp/issues/18441) FSI multi-emit unstable. ([PR #18465](https://github.com/dotnet/fsharp/pull/18465)) +* Fixed: Allow `return`, `return!`, `yield`, `yield!` type annotations without parentheses ([PR #18533](https://github.com/dotnet/fsharp/pull/18533)) ### Added * Added missing type constraints in FCS. ([PR #18241](https://github.com/dotnet/fsharp/pull/18241))