From fb7487620f6488b09e234db09b4614d44fedf834 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Wed, 15 Oct 2025 17:02:49 +0300 Subject: [PATCH 1/8] wip --- src/Compiler/SyntaxTree/ParseHelpers.fs | 10 ++--- src/Compiler/SyntaxTree/ParseHelpers.fsi | 4 +- src/Compiler/pars.fsy | 57 ++++++++++-------------- 3 files changed, 31 insertions(+), 40 deletions(-) diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs index 572600f9ff9..7013ae560bf 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fs +++ b/src/Compiler/SyntaxTree/ParseHelpers.fs @@ -868,7 +868,7 @@ let mkClassMemberLocalBindings SynMemberDefn.LetBindings(decls, isStatic, isRec, mWhole) /// Creates a SynExprAndBang node for and! bindings in computation expressions -let mkAndBang (mKeyword: range, pat: SynPat, rhs: SynExpr, mWhole: range, mEquals: range, mIn: range option) = +let mkAndBang (mKeyword: range, pat: SynPat, returnInfo: SynBindingReturnInfo option, rhs: SynExpr, mWhole: range, mEquals: range, mIn: range option) = let spBind = DebugPointAtBinding.Yes(unionRanges mKeyword rhs.Range) let trivia: SynBindingTrivia = @@ -887,7 +887,7 @@ let mkAndBang (mKeyword: range, pat: SynPat, rhs: SynExpr, mWhole: range, mEqual xmlDoc = PreXmlDoc.Empty, valData = SynInfo.emptySynValData, headPat = pat, - returnInfo = None, + returnInfo = returnInfo, expr = rhs, range = mWhole, debugPoint = spBind, @@ -1075,11 +1075,11 @@ let mkLetExpression mWhole: range, body: SynExpr, bindingInfo: BindingSet option, - bangInfo: (SynPat * SynExpr * SynBinding list * range * range option * bool) option + bangInfo: (SynPat * SynBindingReturnInfo option * SynExpr * SynBinding list * range * range option * bool) option ) = if isBang then match bangInfo with - | Some(pat, rhs, andBangs, mKeyword, mEquals, isUse) -> + | Some(pat, returnInfo, rhs, andBangs, mKeyword, mEquals, isUse) -> let spBind = DebugPointAtBinding.Yes(unionRanges mKeyword rhs.Range) let trivia: SynBindingTrivia = @@ -1103,7 +1103,7 @@ let mkLetExpression xmlDoc = PreXmlDoc.Empty, valData = SynInfo.emptySynValData, headPat = pat, - returnInfo = None, + returnInfo = returnInfo, expr = rhs, range = unionRanges mKeyword rhs.Range, debugPoint = spBind, diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fsi b/src/Compiler/SyntaxTree/ParseHelpers.fsi index 301e72e0ed7..eed66a79b76 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fsi +++ b/src/Compiler/SyntaxTree/ParseHelpers.fsi @@ -205,11 +205,11 @@ val mkLetExpression: mWhole: range * body: SynExpr * bindingInfo: BindingSet option * - bangInfo: (SynPat * SynExpr * SynBinding list * range * range option * bool) option -> + bangInfo: (SynPat * SynBindingReturnInfo option * SynExpr * SynBinding list * range * range option * bool) option -> SynExpr val mkAndBang: - mKeyword: range * pat: SynPat * rhs: SynExpr * mWhole: range * mEquals: range * mIn: range option -> SynBinding + mKeyword: range * pat: SynPat * returnInfo: SynBindingReturnInfo option * rhs: SynExpr * mWhole: range * mEquals: range * mIn: range option -> SynBinding val mkDefnBindings: mWhole: range * BindingSet * attrs: SynAttributes * vis: SynAccess option * attrsm: range -> SynModuleDecl list diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 172bd9683e3..2a525e51410 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -3523,32 +3523,23 @@ bindingPattern: | headBindingPattern { $1, $1.Range } -// This rule unifies the pattern parsing for both regular 'let' bindings and (let!, use!, and!) -bindingPatternWithOptType: - | headBindingPattern opt_topReturnTypeWithTypeConstraints - { // Pattern with optional type annotation - match $2 with - | None -> - // No type annotation - $1, $1.Range, None - | Some(colonRangeOpt, SynReturnInfo((ty, _), _)) -> - // Pattern with type annotation (e.g., x: int) - let mWhole = unionRanges $1.Range ty.Range - let typedPat = SynPat.Typed($1, ty, mWhole) - typedPat, mWhole, Some ty } - -// Handles the pattern part of let!, use!, and! bindings +// Handles pattern and return type part of let!, use!, and! bindings ceBindingCore: - | opt_inline opt_mutable bindingPatternWithOptType - { let pat, mPat, tyOpt = $3 + | opt_inline opt_mutable bindingPattern opt_topReturnTypeWithTypeConstraints + { let pat, mPat = $3 + let tyOpt = $4 let isInline = Option.isSome $1 let isMutable = Option.isSome $2 - match tyOpt with - | Some ty -> - parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AllowTypedLetUseAndBang ty.Range - | None -> () - - pat, mPat, isInline, isMutable, tyOpt } + + let ty = + match tyOpt with + | Some(colonRangeOpt, SynReturnInfo((ty, _), tym)) -> + parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AllowTypedLetUseAndBang ty.Range + Some (SynBindingReturnInfo(ty, tym, [], { ColonRange = colonRangeOpt })) + | None -> + None + + pat, mPat, isInline, isMutable, ty } opt_simplePatterns: | simplePatterns @@ -4144,7 +4135,7 @@ recover: moreBinders: | AND_BANG ceBindingCore EQUALS typedSequentialExprBlock IN moreBinders %prec expr_let - { let pat, mPat, isInline, isMutable, tyOpt = $2 + { let pat, mPat, isInline, isMutable, returnInfo = $2 // and! bindings don't support inline or mutable modifiers if isInline then errorR(Error(FSComp.SR.parsInvalidDeclarationSyntax(), rhs parseState 2)) @@ -4155,11 +4146,11 @@ moreBinders: let m = unionRanges mKeyword $4.Range let mIn = Some(rhs parseState 5) - mkAndBang(mKeyword, pat, $4, m, mEquals, mIn) :: $6 } + mkAndBang(mKeyword, pat, returnInfo, $4, m, mEquals, mIn) :: $6 } | OAND_BANG ceBindingCore EQUALS typedSequentialExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP moreBinders %prec expr_let { // Offside-sensitive version of and! binding - let pat, mPat, isInline, isMutable, tyOpt = $2 + let pat, mPat, isInline, isMutable, returnInfo = $2 // and! bindings don't support inline or mutable modifiers if isInline then errorR(Error(FSComp.SR.parsInvalidDeclarationSyntax(), rhs parseState 2)) @@ -4171,7 +4162,7 @@ moreBinders: let mEquals = rhs parseState 3 let m = unionRanges mKeyword $4.Range - mkAndBang(mKeyword, pat, $4, m, mEquals, mIn) :: $7 } + mkAndBang(mKeyword, pat, returnInfo, $4, m, mEquals, mIn) :: $7 } | %prec prec_no_more_attr_bindings { [] } @@ -4536,7 +4527,7 @@ declExpr: | BINDER ceBindingCore EQUALS typedSequentialExprBlock IN opt_OBLOCKSEP moreBinders typedSequentialExprBlock %prec expr_let { // Handle let! and use! bindings with unified pattern parsing - let pat, mPat, isInline, isMutable, tyOpt = $2 + let pat, mPat, isInline, isMutable, returnInfo = $2 // let! and use! bindings don't support inline or mutable modifiers if isInline then errorR(Error(FSComp.SR.parsInvalidDeclarationSyntax(), rhs parseState 2)) @@ -4549,11 +4540,11 @@ declExpr: // $1 contains the actual keyword ("let" or "use") let isUse = ($1 = "use") - mkLetExpression(true, None, m, $8, None, Some(pat, $4, $7, mKeyword, mEquals, isUse)) } + mkLetExpression(true, None, m, $8, None, Some(pat, returnInfo, $4, $7, mKeyword, mEquals, isUse)) } | OBINDER ceBindingCore EQUALS typedSequentialExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP moreBinders typedSequentialExprBlock %prec expr_let { // Offside-sensitive version of let!/use! binding - let pat, mPat, isInline, isMutable, tyOpt = $2 + let pat, mPat, isInline, isMutable, returnInfo = $2 // let! and use! bindings don't support inline or mutable modifiers if isInline then errorR(Error(FSComp.SR.parsInvalidDeclarationSyntax(), rhs parseState 2)) @@ -4567,12 +4558,12 @@ declExpr: let isUse = ($1 = "use") - mkLetExpression(true, None, m, $8, None, Some(pat, $4, $7, mKeyword, mEquals, isUse)) } + mkLetExpression(true, None, m, $8, None, Some(pat, returnInfo, $4, $7, mKeyword, mEquals, isUse)) } | OBINDER ceBindingCore EQUALS typedSequentialExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP error %prec expr_let { // Error recovery for incomplete let!/use! bindings // Allows intellisense to work when writing incomplete computation expressions - let pat, mPat, isInline, isMutable, tyOpt = $2 + let pat, mPat, isInline, isMutable, returnInfo = $2 // Error checking for invalid modifiers if isInline then errorR(Error(FSComp.SR.parsInvalidDeclarationSyntax(), rhs parseState 2)) @@ -4586,7 +4577,7 @@ declExpr: let isUse = ($1 = "use") // Use ImplicitZero as the continuation expression for error recovery - mkLetExpression(true, None, mAll, SynExpr.ImplicitZero m, None, Some(pat, $4, [], mKeyword, mEquals, isUse)) } + mkLetExpression(true, None, mAll, SynExpr.ImplicitZero m, None, Some(pat, returnInfo, $4, [], mKeyword, mEquals, isUse)) } | DO_BANG typedSequentialExpr IN opt_OBLOCKSEP typedSequentialExprBlock %prec expr_let { let spBind = DebugPointAtBinding.NoneAtDo From 57deb9d09a6036f0507169fb8e2b604a48d28ff2 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Wed, 15 Oct 2025 17:17:15 +0300 Subject: [PATCH 2/8] wip --- .../SynType/Typed LetBang 01.fs.bsl | 12 +-- .../SynType/Typed LetBang 05.fs.bsl | 9 ++- .../SynType/Typed LetBang 06.fs.bsl | 10 +-- .../SynType/Typed LetBang 08.fs.bsl | 22 ++--- .../SynType/Typed LetBang 11.fs.bsl | 32 ++++---- .../SynType/Typed LetBang 12.fs.bsl | 29 ++++--- .../SynType/Typed LetBang 14.fs.bsl | 46 ++++++----- .../SynType/Typed LetBang 15.fs.bsl | 22 ++--- .../SynType/Typed LetBang 18.fs.bsl | 19 ++--- .../SynType/Typed LetBang 20.fs.bsl | 22 ++--- .../SyntaxTree/SynType/Typed LetBang 21.fs | 6 ++ .../SynType/Typed LetBang 21.fs.bsl | 49 ++++++++++++ .../SynType/Typed LetBang AndBang 01.fs.bsl | 24 +++--- .../SynType/Typed LetBang AndBang 04.fs.bsl | 58 +++++++------- .../SynType/Typed LetBang AndBang 05.fs.bsl | 22 ++--- .../SynType/Typed LetBang AndBang 08.fs.bsl | 64 ++++++++------- .../SynType/Typed LetBang AndBang 09.fs.bsl | 58 ++++++++------ .../SynType/Typed LetBang AndBang 10.fs.bsl | 48 ++++++----- .../SynType/Typed LetBang AndBang 11.fs.bsl | 40 +++++----- .../SynType/Typed LetBang AndBang 14.fs.bsl | 63 ++++++++------- .../SynType/Typed LetBang AndBang 15.fs.bsl | 40 +++++----- .../SynType/Typed LetBang AndBang 16.fs.bsl | 40 +++++----- .../SynType/Typed LetBang AndBang 17.fs.bsl | 80 ++++++++++--------- .../SynType/Typed LetBang AndBang 18.fs.bsl | 46 ++++++----- .../SynType/Typed UseBang 01.fs.bsl | 12 +-- .../SynType/Typed UseBang 03.fs.bsl | 9 ++- .../SynType/Typed UseBang 04.fs.bsl | 10 +-- .../SynType/Typed UseBang 05.fs.bsl | 10 ++- 28 files changed, 512 insertions(+), 390 deletions(-) create mode 100644 tests/service/data/SyntaxTree/SynType/Typed LetBang 21.fs create mode 100644 tests/service/data/SyntaxTree/SynType/Typed LetBang 21.fs.bsl diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 01.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 01.fs.bsl index d23a59f4b8f..b901dac5465 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang 01.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 01.fs.bsl @@ -16,11 +16,13 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Named - (SynIdent (res, None), false, None, (4,9--4,12)), - LongIdent (SynLongIdent ([int], [], [None])), - (4,9--4,17)), None, + Named + (SynIdent (res, None), false, None, (4,9--4,12)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([int], [], [None])), + (4,14--4,17), [], + { ColonRange = Some (4,12--4,13) })), App (NonAtomic, false, Ident async, ComputationExpr diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 05.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 05.fs.bsl index f2a845e439e..c25638c937b 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang 05.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 05.fs.bsl @@ -11,10 +11,11 @@ ImplFile SynValData (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Named (SynIdent (x, None), false, None, (2,5--2,6)), - LongIdent (SynLongIdent ([int], [], [None])), - (2,5--2,10)), None, + Named (SynIdent (x, None), false, None, (2,5--2,6)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([int], [], [None])), + (2,7--2,10), [], { ColonRange = Some (2,6--2,7) })), App (NonAtomic, false, Ident async, ComputationExpr diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 06.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 06.fs.bsl index a1cf34982f4..78a44c56d3a 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang 06.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 06.fs.bsl @@ -10,11 +10,11 @@ ImplFile (None, Normal, false, false, [], PreXmlDocEmpty, SynValData (None, SynValInfo ([], SynArgInfo ([], false, None)), - None), - Typed - (Wild (2,5--2,6), - LongIdent (SynLongIdent ([int], [], [None])), - (2,5--2,10)), None, + None), Wild (2,5--2,6), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([int], [], [None])), + (2,7--2,10), [], { ColonRange = Some (2,6--2,7) })), App (NonAtomic, false, Ident async, ComputationExpr diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 08.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 08.fs.bsl index 98891d11346..a8e603e6eaf 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang 08.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 08.fs.bsl @@ -16,16 +16,18 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Record - ([NamePatPairField - (SynLongIdent ([Name], [], [None]), - Some (3,16--3,17), (3,11--3,22), - Named - (SynIdent (name, None), false, None, - (3,18--3,22)), None)], (3,9--3,24)), - LongIdent (SynLongIdent ([Person], [], [None])), - (3,9--3,32)), None, + Record + ([NamePatPairField + (SynLongIdent ([Name], [], [None]), + Some (3,16--3,17), (3,11--3,22), + Named + (SynIdent (name, None), false, None, + (3,18--3,22)), None)], (3,9--3,24)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([Person], [], [None])), + (3,26--3,32), [], + { ColonRange = Some (3,24--3,25) })), App (Atomic, false, Ident asyncPerson, Const (Unit, (3,46--3,48)), (3,35--3,48)), diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 11.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 11.fs.bsl index 37e4b473fc8..91620f8a19d 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang 11.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 11.fs.bsl @@ -16,22 +16,24 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Paren - (LongIdent - (SynLongIdent ([Union], [], [None]), None, + Paren + (LongIdent + (SynLongIdent ([Union], [], [None]), None, None, + Pats + [Named + (SynIdent (value, None), false, None, + (3,16--3,21))], None, (3,10--3,21)), + (3,9--3,22)), + Some + (SynBindingReturnInfo + (App + (LongIdent + (SynLongIdent ([option], [], [None])), None, - Pats - [Named - (SynIdent (value, None), false, None, - (3,16--3,21))], None, (3,10--3,21)), - (3,9--3,22)), - App - (LongIdent (SynLongIdent ([option], [], [None])), - None, - [LongIdent (SynLongIdent ([int], [], [None]))], - [], None, true, (3,24--3,34)), (3,9--3,34)), - None, + [LongIdent + (SynLongIdent ([int], [], [None]))], [], + None, true, (3,24--3,34)), (3,24--3,34), [], + { ColonRange = Some (3,22--3,23) })), App (Atomic, false, Ident asyncOption, Const (Unit, (3,48--3,50)), (3,37--3,50)), diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 12.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 12.fs.bsl index bb9904fdb84..19b59f7f1da 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang 12.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 12.fs.bsl @@ -16,19 +16,22 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (LongIdent - (SynLongIdent ([Union], [], [None]), None, None, - Pats - [Named - (SynIdent (value, None), false, None, - (3,15--3,20))], None, (3,9--3,20)), - App - (LongIdent (SynLongIdent ([option], [], [None])), - None, - [LongIdent (SynLongIdent ([int], [], [None]))], - [], None, true, (3,22--3,32)), (3,9--3,32)), - None, + LongIdent + (SynLongIdent ([Union], [], [None]), None, None, + Pats + [Named + (SynIdent (value, None), false, None, + (3,15--3,20))], None, (3,9--3,20)), + Some + (SynBindingReturnInfo + (App + (LongIdent + (SynLongIdent ([option], [], [None])), + None, + [LongIdent + (SynLongIdent ([int], [], [None]))], [], + None, true, (3,22--3,32)), (3,22--3,32), [], + { ColonRange = Some (3,20--3,21) })), App (Atomic, false, Ident asyncOption, Const (Unit, (3,46--3,48)), (3,35--3,48)), diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 14.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 14.fs.bsl index 1f0ddcb4626..87485698a0d 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang 14.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 14.fs.bsl @@ -16,16 +16,18 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Paren - (As - (Named - (SynIdent (x, None), false, None, - (4,10--4,11)), - Named - (SynIdent (y, None), false, None, - (4,15--4,16)), (4,10--4,16)), (4,9--4,17)), - FromParseError (4,18--4,18), (4,9--4,18)), None, + Paren + (As + (Named + (SynIdent (x, None), false, None, + (4,10--4,11)), + Named + (SynIdent (y, None), false, None, + (4,15--4,16)), (4,10--4,16)), (4,9--4,17)), + Some + (SynBindingReturnInfo + (FromParseError (4,18--4,18), (4,18--4,18), [], + { ColonRange = Some (4,17--4,18) })), App (Atomic, false, Ident asyncInt, Const (Unit, (4,29--4,31)), (4,21--4,31)), @@ -39,17 +41,19 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Paren - (As - (Named - (SynIdent (a, None), false, None, - (5,10--5,11)), - Named - (SynIdent (b, None), false, None, - (5,15--5,16)), (5,10--5,16)), (5,9--5,17)), - LongIdent (SynLongIdent ([string], [], [None])), - (5,9--5,25)), None, + Paren + (As + (Named + (SynIdent (a, None), false, None, + (5,10--5,11)), + Named + (SynIdent (b, None), false, None, + (5,15--5,16)), (5,10--5,16)), (5,9--5,17)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([string], [], [None])), + (5,19--5,25), [], + { ColonRange = Some (5,17--5,18) })), App (Atomic, false, Ident asyncString, Const (Unit, (5,39--5,41)), (5,28--5,41)), diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 15.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 15.fs.bsl index 2d03ed11587..e252e9d6393 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang 15.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 15.fs.bsl @@ -16,16 +16,18 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Paren - (As - (Named - (SynIdent (x, None), false, None, - (4,10--4,11)), - Named - (SynIdent (y, None), false, None, - (4,15--4,16)), (4,10--4,16)), (4,9--4,17)), - FromParseError (4,18--4,18), (4,9--4,18)), None, + Paren + (As + (Named + (SynIdent (x, None), false, None, + (4,10--4,11)), + Named + (SynIdent (y, None), false, None, + (4,15--4,16)), (4,10--4,16)), (4,9--4,17)), + Some + (SynBindingReturnInfo + (FromParseError (4,18--4,18), (4,18--4,18), [], + { ColonRange = Some (4,17--4,18) })), App (Atomic, false, Ident asyncString, Const (Unit, (5,39--5,41)), (5,28--5,41)), diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 18.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 18.fs.bsl index 1acf38da849..0b62badd88e 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang 18.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 18.fs.bsl @@ -35,15 +35,16 @@ ImplFile SynValData (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (As - (LongIdent - (SynLongIdent ([Even], [], [None]), None, None, - Pats [], None, (5,5--5,9)), - Named (SynIdent (x, None), false, None, (5,13--5,14)), - (5,5--5,14)), - LongIdent (SynLongIdent ([int], [], [None])), - (5,5--5,19)), None, + As + (LongIdent + (SynLongIdent ([Even], [], [None]), None, None, + Pats [], None, (5,5--5,9)), + Named (SynIdent (x, None), false, None, (5,13--5,14)), + (5,5--5,14)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([int], [], [None])), + (5,16--5,19), [], { ColonRange = Some (5,14--5,15) })), App (NonAtomic, false, Ident async, ComputationExpr diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 20.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 20.fs.bsl index c755fa45c08..9177dc08cb8 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang 20.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 20.fs.bsl @@ -44,16 +44,18 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (As - (LongIdent - (SynLongIdent ([Even], [], [None]), None, - None, Pats [], None, (5,9--5,13)), - Named - (SynIdent (x, None), false, None, - (5,17--5,18)), (5,9--5,18)), - LongIdent (SynLongIdent ([int], [], [None])), - (5,9--5,23)), None, + As + (LongIdent + (SynLongIdent ([Even], [], [None]), None, + None, Pats [], None, (5,9--5,13)), + Named + (SynIdent (x, None), false, None, + (5,17--5,18)), (5,9--5,18)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([int], [], [None])), + (5,20--5,23), [], + { ColonRange = Some (5,18--5,19) })), App (NonAtomic, false, Ident async, ComputationExpr diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 21.fs b/tests/service/data/SyntaxTree/SynType/Typed LetBang 21.fs new file mode 100644 index 00000000000..9c5c61a8e58 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 21.fs @@ -0,0 +1,6 @@ +module Module + +async { + let (x: string): int = 2 + return x +} diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang 21.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang 21.fs.bsl new file mode 100644 index 00000000000..bfbbb3ea841 --- /dev/null +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang 21.fs.bsl @@ -0,0 +1,49 @@ +ImplFile + (ParsedImplFileInput + ("/root/SynType/Typed LetBang 21.fs", false, QualifiedNameOfFile Module, [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + LetOrUse + (false, false, true, false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, + SynValInfo ([], SynArgInfo ([], false, None)), + None), + Paren + (Typed + (Named + (SynIdent (x, None), false, None, (4,9--4,10)), + LongIdent (SynLongIdent ([string], [], [None])), + (4,9--4,18)), (4,8--4,19)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([int], [], [None])), + (4,21--4,24), [], + { ColonRange = Some (4,19--4,20) })), + Typed + (Const (Int32 2, (4,27--4,28)), + LongIdent (SynLongIdent ([int], [], [None])), + (4,27--4,28)), (4,8--4,19), Yes (4,4--4,28), + { LeadingKeyword = Let (4,4--4,7) + InlineKeyword = None + EqualsRange = Some (4,25--4,26) })], + YieldOrReturn + ((false, true), Ident x, (5,4--5,12), + { YieldOrReturnKeyword = (5,4--5,10) }), (4,4--5,12), + { LetOrUseKeyword = (4,4--4,7) + InKeyword = None + EqualsRange = Some (4,25--4,26) }), (3,6--6,1)), + (3,0--6,1)), (3,0--6,1))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 01.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 01.fs.bsl index 0bc048b73f5..17749b3e300 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 01.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 01.fs.bsl @@ -17,11 +17,13 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Named - (SynIdent (res, None), false, None, (4,9--4,12)), - LongIdent (SynLongIdent ([int], [], [None])), - (4,9--4,17)), None, + Named + (SynIdent (res, None), false, None, (4,9--4,12)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([int], [], [None])), + (4,14--4,17), [], + { ColonRange = Some (4,12--4,13) })), App (NonAtomic, false, Ident async, ComputationExpr @@ -40,11 +42,13 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Named - (SynIdent (res2, None), false, None, (5,9--5,13)), - LongIdent (SynLongIdent ([int], [], [None])), - (5,9--5,18)), None, + Named + (SynIdent (res2, None), false, None, (5,9--5,13)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([int], [], [None])), + (5,15--5,18), [], + { ColonRange = Some (5,13--5,14) })), App (NonAtomic, false, Ident async, ComputationExpr diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 04.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 04.fs.bsl index a018d95610d..c50f2a3c6ab 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 04.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 04.fs.bsl @@ -17,23 +17,25 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Record - ([NamePatPairField - (SynLongIdent ([Name], [], [None]), - Some (4,16--4,17), (4,11--4,22), - Named - (SynIdent (name, None), false, None, - (4,18--4,22)), - Some ((4,22--4,23), Some (4,23))); - NamePatPairField - (SynLongIdent ([Age], [], [None]), - Some (4,28--4,29), (4,24--4,33), - Named - (SynIdent (age, None), false, None, - (4,30--4,33)), None)], (4,9--4,35)), - LongIdent (SynLongIdent ([Person], [], [None])), - (4,9--4,43)), None, + Record + ([NamePatPairField + (SynLongIdent ([Name], [], [None]), + Some (4,16--4,17), (4,11--4,22), + Named + (SynIdent (name, None), false, None, + (4,18--4,22)), + Some ((4,22--4,23), Some (4,23))); + NamePatPairField + (SynLongIdent ([Age], [], [None]), + Some (4,28--4,29), (4,24--4,33), + Named + (SynIdent (age, None), false, None, + (4,30--4,33)), None)], (4,9--4,35)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([Person], [], [None])), + (4,37--4,43), [], + { ColonRange = Some (4,35--4,36) })), App (Atomic, false, Ident asyncPerson, Const (Unit, (4,57--4,59)), (4,46--4,59)), @@ -47,16 +49,18 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Record - ([NamePatPairField - (SynLongIdent ([Id], [], [None]), - Some (5,14--5,15), (5,11--5,18), - Named - (SynIdent (id, None), false, None, - (5,16--5,18)), None)], (5,9--5,20)), - LongIdent (SynLongIdent ([User], [], [None])), - (5,9--5,26)), None, + Record + ([NamePatPairField + (SynLongIdent ([Id], [], [None]), + Some (5,14--5,15), (5,11--5,18), + Named + (SynIdent (id, None), false, None, + (5,16--5,18)), None)], (5,9--5,20)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([User], [], [None])), + (5,22--5,26), [], + { ColonRange = Some (5,20--5,21) })), App (Atomic, false, Ident asyncUser, Const (Unit, (5,38--5,40)), (5,29--5,40)), diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 05.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 05.fs.bsl index a8bd98a1058..4a48b37dd02 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 05.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 05.fs.bsl @@ -48,16 +48,18 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Record - ([NamePatPairField - (SynLongIdent ([Id], [], [None]), - Some (5,14--5,15), (5,11--5,18), - Named - (SynIdent (id, None), false, None, - (5,16--5,18)), None)], (5,9--5,20)), - LongIdent (SynLongIdent ([User], [], [None])), - (5,9--5,26)), None, + Record + ([NamePatPairField + (SynLongIdent ([Id], [], [None]), + Some (5,14--5,15), (5,11--5,18), + Named + (SynIdent (id, None), false, None, + (5,16--5,18)), None)], (5,9--5,20)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([User], [], [None])), + (5,22--5,26), [], + { ColonRange = Some (5,20--5,21) })), App (Atomic, false, Ident asyncUser, Const (Unit, (5,38--5,40)), (5,29--5,40)), diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 08.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 08.fs.bsl index 6dc85a13777..6086dd750c9 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 08.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 08.fs.bsl @@ -17,22 +17,24 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Paren - (LongIdent - (SynLongIdent ([Union], [], [None]), None, + Paren + (LongIdent + (SynLongIdent ([Union], [], [None]), None, None, + Pats + [Named + (SynIdent (value, None), false, None, + (4,16--4,21))], None, (4,10--4,21)), + (4,9--4,22)), + Some + (SynBindingReturnInfo + (App + (LongIdent + (SynLongIdent ([option], [], [None])), None, - Pats - [Named - (SynIdent (value, None), false, None, - (4,16--4,21))], None, (4,10--4,21)), - (4,9--4,22)), - App - (LongIdent (SynLongIdent ([option], [], [None])), - None, - [LongIdent (SynLongIdent ([int], [], [None]))], - [], None, true, (4,24--4,34)), (4,9--4,34)), - None, + [LongIdent + (SynLongIdent ([int], [], [None]))], [], + None, true, (4,24--4,34)), (4,24--4,34), [], + { ColonRange = Some (4,22--4,23) })), App (Atomic, false, Ident asyncOption, Const (Unit, (4,48--4,50)), (4,37--4,50)), @@ -46,22 +48,24 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Paren - (LongIdent - (SynLongIdent ([Union], [], [None]), None, + Paren + (LongIdent + (SynLongIdent ([Union], [], [None]), None, None, + Pats + [Named + (SynIdent (value2, None), false, None, + (5,16--5,22))], None, (5,10--5,22)), + (5,9--5,23)), + Some + (SynBindingReturnInfo + (App + (LongIdent + (SynLongIdent ([option], [], [None])), None, - Pats - [Named - (SynIdent (value2, None), false, None, - (5,16--5,22))], None, (5,10--5,22)), - (5,9--5,23)), - App - (LongIdent (SynLongIdent ([option], [], [None])), - None, - [LongIdent (SynLongIdent ([int], [], [None]))], - [], None, true, (5,25--5,35)), (5,9--5,35)), - None, + [LongIdent + (SynLongIdent ([int], [], [None]))], [], + None, true, (5,25--5,35)), (5,25--5,35), [], + { ColonRange = Some (5,23--5,24) })), App (Atomic, false, Ident asyncOption, Const (Unit, (5,49--5,51)), (5,38--5,51)), diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 09.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 09.fs.bsl index 18392642b3d..688a32c991e 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 09.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 09.fs.bsl @@ -17,19 +17,22 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (LongIdent - (SynLongIdent ([Union], [], [None]), None, None, - Pats - [Named - (SynIdent (value, None), false, None, - (4,15--4,20))], None, (4,9--4,20)), - App - (LongIdent (SynLongIdent ([option], [], [None])), - None, - [LongIdent (SynLongIdent ([int], [], [None]))], - [], None, true, (4,22--4,32)), (4,9--4,32)), - None, + LongIdent + (SynLongIdent ([Union], [], [None]), None, None, + Pats + [Named + (SynIdent (value, None), false, None, + (4,15--4,20))], None, (4,9--4,20)), + Some + (SynBindingReturnInfo + (App + (LongIdent + (SynLongIdent ([option], [], [None])), + None, + [LongIdent + (SynLongIdent ([int], [], [None]))], [], + None, true, (4,22--4,32)), (4,22--4,32), [], + { ColonRange = Some (4,20--4,21) })), App (Atomic, false, Ident asyncOption, Const (Unit, (4,46--4,48)), (4,35--4,48)), @@ -43,19 +46,22 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (LongIdent - (SynLongIdent ([Union], [], [None]), None, None, - Pats - [Named - (SynIdent (value2, None), false, None, - (5,15--5,21))], None, (5,9--5,21)), - App - (LongIdent (SynLongIdent ([option], [], [None])), - None, - [LongIdent (SynLongIdent ([int], [], [None]))], - [], None, true, (5,23--5,33)), (5,9--5,33)), - None, + LongIdent + (SynLongIdent ([Union], [], [None]), None, None, + Pats + [Named + (SynIdent (value2, None), false, None, + (5,15--5,21))], None, (5,9--5,21)), + Some + (SynBindingReturnInfo + (App + (LongIdent + (SynLongIdent ([option], [], [None])), + None, + [LongIdent + (SynLongIdent ([int], [], [None]))], [], + None, true, (5,23--5,33)), (5,23--5,33), [], + { ColonRange = Some (5,21--5,22) })), App (Atomic, false, Ident asyncOption, Const (Unit, (5,47--5,49)), (5,36--5,49)), diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 10.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 10.fs.bsl index 420ef6d8ac7..27e96d1da50 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 10.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 10.fs.bsl @@ -17,17 +17,19 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Paren - (As - (Named - (SynIdent (x, None), false, None, - (4,10--4,11)), - Named - (SynIdent (y, None), false, None, - (4,15--4,16)), (4,10--4,16)), (4,9--4,17)), - LongIdent (SynLongIdent ([int], [], [None])), - (4,9--4,22)), None, + Paren + (As + (Named + (SynIdent (x, None), false, None, + (4,10--4,11)), + Named + (SynIdent (y, None), false, None, + (4,15--4,16)), (4,10--4,16)), (4,9--4,17)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([int], [], [None])), + (4,19--4,22), [], + { ColonRange = Some (4,17--4,18) })), App (Atomic, false, Ident asyncInt, Const (Unit, (4,33--4,35)), (4,25--4,35)), @@ -41,17 +43,19 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Paren - (As - (Named - (SynIdent (a, None), false, None, - (5,10--5,11)), - Named - (SynIdent (b, None), false, None, - (5,15--5,16)), (5,10--5,16)), (5,9--5,17)), - LongIdent (SynLongIdent ([string], [], [None])), - (5,9--5,25)), None, + Paren + (As + (Named + (SynIdent (a, None), false, None, + (5,10--5,11)), + Named + (SynIdent (b, None), false, None, + (5,15--5,16)), (5,10--5,16)), (5,9--5,17)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([string], [], [None])), + (5,19--5,25), [], + { ColonRange = Some (5,17--5,18) })), App (Atomic, false, Ident asyncString, Const (Unit, (5,39--5,41)), (5,28--5,41)), diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 11.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 11.fs.bsl index db188d2d345..f3d45337e72 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 11.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 11.fs.bsl @@ -17,15 +17,17 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (As - (Named - (SynIdent (x, None), false, None, (4,9--4,10)), - Named - (SynIdent (y, None), false, None, - (4,14--4,15)), (4,9--4,15)), - LongIdent (SynLongIdent ([int], [], [None])), - (4,9--4,20)), None, + As + (Named + (SynIdent (x, None), false, None, (4,9--4,10)), + Named + (SynIdent (y, None), false, None, (4,14--4,15)), + (4,9--4,15)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([int], [], [None])), + (4,17--4,20), [], + { ColonRange = Some (4,15--4,16) })), App (Atomic, false, Ident asyncInt, Const (Unit, (4,31--4,33)), (4,23--4,33)), @@ -39,15 +41,17 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (As - (Named - (SynIdent (a, None), false, None, (5,9--5,10)), - Named - (SynIdent (b, None), false, None, - (5,14--5,15)), (5,9--5,15)), - LongIdent (SynLongIdent ([string], [], [None])), - (5,9--5,23)), None, + As + (Named + (SynIdent (a, None), false, None, (5,9--5,10)), + Named + (SynIdent (b, None), false, None, (5,14--5,15)), + (5,9--5,15)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([string], [], [None])), + (5,17--5,23), [], + { ColonRange = Some (5,15--5,16) })), App (Atomic, false, Ident asyncString, Const (Unit, (5,37--5,39)), (5,26--5,39)), diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 14.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 14.fs.bsl index c49714f66a9..361bf9c9074 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 14.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 14.fs.bsl @@ -17,21 +17,23 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (ArrayOrList - (true, - [Named - (SynIdent (first, None), false, None, - (4,12--4,17)); - Named - (SynIdent (second, None), false, None, - (4,19--4,25))], (4,9--4,28)), - App - (LongIdent (SynLongIdent ([array], [], [None])), - None, - [LongIdent (SynLongIdent ([int], [], [None]))], - [], None, true, (4,30--4,39)), (4,9--4,39)), - None, + ArrayOrList + (true, + [Named + (SynIdent (first, None), false, None, + (4,12--4,17)); + Named + (SynIdent (second, None), false, None, + (4,19--4,25))], (4,9--4,28)), + Some + (SynBindingReturnInfo + (App + (LongIdent + (SynLongIdent ([array], [], [None])), None, + [LongIdent + (SynLongIdent ([int], [], [None]))], [], + None, true, (4,30--4,39)), (4,30--4,39), [], + { ColonRange = Some (4,28--4,29) })), App (Atomic, false, Ident asyncArray, Const (Unit, (4,52--4,54)), (4,42--4,54)), @@ -45,21 +47,22 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (ListCons - (Named - (SynIdent (head, None), false, None, - (5,9--5,13)), - Named - (SynIdent (tail, None), false, None, - (5,17--5,21)), (5,9--5,21), - { ColonColonRange = (5,14--5,16) }), - App - (LongIdent (SynLongIdent ([list], [], [None])), - None, - [LongIdent - (SynLongIdent ([string], [], [None]))], [], - None, true, (5,23--5,34)), (5,9--5,34)), None, + ListCons + (Named + (SynIdent (head, None), false, None, (5,9--5,13)), + Named + (SynIdent (tail, None), false, None, + (5,17--5,21)), (5,9--5,21), + { ColonColonRange = (5,14--5,16) }), + Some + (SynBindingReturnInfo + (App + (LongIdent + (SynLongIdent ([list], [], [None])), None, + [LongIdent + (SynLongIdent ([string], [], [None]))], + [], None, true, (5,23--5,34)), (5,23--5,34), + [], { ColonRange = Some (5,21--5,22) })), App (Atomic, false, Ident asyncList, Const (Unit, (5,46--5,48)), (5,37--5,48)), diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 15.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 15.fs.bsl index b92d2adb0bc..e3ab36d1f96 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 15.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 15.fs.bsl @@ -19,27 +19,29 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Paren + Paren + (Tuple + (false, + [Named + (SynIdent (x, None), false, None, + (4,10--4,11)); + Named + (SynIdent (y, None), false, None, + (4,13--4,14))], [(4,11--4,12)], + (4,10--4,14)), (4,9--4,15)), + Some + (SynBindingReturnInfo (Tuple (false, - [Named - (SynIdent (x, None), false, None, - (4,10--4,11)); - Named - (SynIdent (y, None), false, None, - (4,13--4,14))], [(4,11--4,12)], - (4,10--4,14)), (4,9--4,15)), - Tuple - (false, - [Type - (LongIdent - (SynLongIdent ([int], [], [None]))); - Star (4,21--4,22); - Type - (LongIdent - (SynLongIdent ([int], [], [None])))], - (4,17--4,26)), (4,9--4,26)), None, + [Type + (LongIdent + (SynLongIdent ([int], [], [None]))); + Star (4,21--4,22); + Type + (LongIdent + (SynLongIdent ([int], [], [None])))], + (4,17--4,26)), (4,17--4,26), [], + { ColonRange = Some (4,15--4,16) })), App (Atomic, false, Ident asyncInt, Const (Unit, (4,37--4,39)), (4,29--4,39)), diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 16.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 16.fs.bsl index ee99dcee6fb..074eaa322f6 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 16.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 16.fs.bsl @@ -17,27 +17,29 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Paren + Paren + (Tuple + (false, + [Named + (SynIdent (x, None), false, None, + (4,10--4,11)); + Named + (SynIdent (y, None), false, None, + (4,13--4,14))], [(4,11--4,12)], + (4,10--4,14)), (4,9--4,15)), + Some + (SynBindingReturnInfo (Tuple (false, - [Named - (SynIdent (x, None), false, None, - (4,10--4,11)); - Named - (SynIdent (y, None), false, None, - (4,13--4,14))], [(4,11--4,12)], - (4,10--4,14)), (4,9--4,15)), - Tuple - (false, - [Type - (LongIdent - (SynLongIdent ([int], [], [None]))); - Star (4,21--4,22); - Type - (LongIdent - (SynLongIdent ([int], [], [None])))], - (4,17--4,26)), (4,9--4,26)), None, + [Type + (LongIdent + (SynLongIdent ([int], [], [None]))); + Star (4,21--4,22); + Type + (LongIdent + (SynLongIdent ([int], [], [None])))], + (4,17--4,26)), (4,17--4,26), [], + { ColonRange = Some (4,15--4,16) })), App (Atomic, false, Ident asyncInt, Const (Unit, (4,37--4,39)), (4,29--4,39)), diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 17.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 17.fs.bsl index df7351df7f3..c8267cda094 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 17.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 17.fs.bsl @@ -17,27 +17,29 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Paren + Paren + (Tuple + (false, + [Named + (SynIdent (x, None), false, None, + (4,10--4,11)); + Named + (SynIdent (y, None), false, None, + (4,13--4,14))], [(4,11--4,12)], + (4,10--4,14)), (4,9--4,15)), + Some + (SynBindingReturnInfo (Tuple (false, - [Named - (SynIdent (x, None), false, None, - (4,10--4,11)); - Named - (SynIdent (y, None), false, None, - (4,13--4,14))], [(4,11--4,12)], - (4,10--4,14)), (4,9--4,15)), - Tuple - (false, - [Type - (LongIdent - (SynLongIdent ([int], [], [None]))); - Star (4,21--4,22); - Type - (LongIdent - (SynLongIdent ([int], [], [None])))], - (4,17--4,26)), (4,9--4,26)), None, + [Type + (LongIdent + (SynLongIdent ([int], [], [None]))); + Star (4,21--4,22); + Type + (LongIdent + (SynLongIdent ([int], [], [None])))], + (4,17--4,26)), (4,17--4,26), [], + { ColonRange = Some (4,15--4,16) })), App (Atomic, false, Ident asyncInt, Const (Unit, (4,37--4,39)), (4,29--4,39)), @@ -51,27 +53,29 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Paren + Paren + (Tuple + (false, + [Named + (SynIdent (x, None), false, None, + (5,10--5,11)); + Named + (SynIdent (y, None), false, None, + (5,13--5,14))], [(5,11--5,12)], + (5,10--5,14)), (5,9--5,15)), + Some + (SynBindingReturnInfo (Tuple (false, - [Named - (SynIdent (x, None), false, None, - (5,10--5,11)); - Named - (SynIdent (y, None), false, None, - (5,13--5,14))], [(5,11--5,12)], - (5,10--5,14)), (5,9--5,15)), - Tuple - (false, - [Type - (LongIdent - (SynLongIdent ([int], [], [None]))); - Star (5,21--5,22); - Type - (LongIdent - (SynLongIdent ([int], [], [None])))], - (5,17--5,26)), (5,9--5,26)), None, + [Type + (LongIdent + (SynLongIdent ([int], [], [None]))); + Star (5,21--5,22); + Type + (LongIdent + (SynLongIdent ([int], [], [None])))], + (5,17--5,26)), (5,17--5,26), [], + { ColonRange = Some (5,15--5,16) })), App (Atomic, false, Ident asyncInt, Const (Unit, (5,37--5,39)), (5,29--5,39)), diff --git a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 18.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 18.fs.bsl index c7706ac0f69..e6deb827d1a 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 18.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed LetBang AndBang 18.fs.bsl @@ -17,17 +17,19 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Paren - (As - (Named - (SynIdent (x, None), false, None, - (4,10--4,11)), - Named - (SynIdent (y, None), false, None, - (4,15--4,16)), (4,10--4,16)), (4,9--4,17)), - LongIdent (SynLongIdent ([int], [], [None])), - (4,9--4,22)), None, + Paren + (As + (Named + (SynIdent (x, None), false, None, + (4,10--4,11)), + Named + (SynIdent (y, None), false, None, + (4,15--4,16)), (4,10--4,16)), (4,9--4,17)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([int], [], [None])), + (4,19--4,22), [], + { ColonRange = Some (4,17--4,18) })), App (Atomic, false, Ident asyncInt, Const (Unit, (4,33--4,35)), (4,25--4,35)), @@ -41,16 +43,18 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Paren - (As - (Named - (SynIdent (a, None), false, None, - (5,10--5,11)), - Named - (SynIdent (b, None), false, None, - (5,15--5,16)), (5,10--5,16)), (5,9--5,17)), - FromParseError (5,18--5,18), (5,9--5,18)), None, + Paren + (As + (Named + (SynIdent (a, None), false, None, + (5,10--5,11)), + Named + (SynIdent (b, None), false, None, + (5,15--5,16)), (5,10--5,16)), (5,9--5,17)), + Some + (SynBindingReturnInfo + (FromParseError (5,18--5,18), (5,18--5,18), [], + { ColonRange = Some (5,17--5,18) })), App (Atomic, false, Ident asyncString, Const (Unit, (5,32--5,34)), (5,21--5,34)), diff --git a/tests/service/data/SyntaxTree/SynType/Typed UseBang 01.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed UseBang 01.fs.bsl index a5d9ba2d0b1..e37cc274965 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed UseBang 01.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed UseBang 01.fs.bsl @@ -16,11 +16,13 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Named - (SynIdent (res, None), false, None, (4,9--4,12)), - LongIdent (SynLongIdent ([int], [], [None])), - (4,9--4,17)), None, + Named + (SynIdent (res, None), false, None, (4,9--4,12)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([int], [], [None])), + (4,14--4,17), [], + { ColonRange = Some (4,12--4,13) })), App (NonAtomic, false, Ident async, ComputationExpr diff --git a/tests/service/data/SyntaxTree/SynType/Typed UseBang 03.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed UseBang 03.fs.bsl index 2b8f672600b..b60bc19b2ff 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed UseBang 03.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed UseBang 03.fs.bsl @@ -11,10 +11,11 @@ ImplFile SynValData (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Named (SynIdent (x, None), false, None, (3,5--3,6)), - LongIdent (SynLongIdent ([int], [], [None])), - (3,5--3,10)), None, + Named (SynIdent (x, None), false, None, (3,5--3,6)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([int], [], [None])), + (3,7--3,10), [], { ColonRange = Some (3,6--3,7) })), App (NonAtomic, false, Ident async, ComputationExpr diff --git a/tests/service/data/SyntaxTree/SynType/Typed UseBang 04.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed UseBang 04.fs.bsl index 18be0fbf4fb..c69ff41b570 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed UseBang 04.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed UseBang 04.fs.bsl @@ -10,11 +10,11 @@ ImplFile (None, Normal, false, false, [], PreXmlDocEmpty, SynValData (None, SynValInfo ([], SynArgInfo ([], false, None)), - None), - Typed - (Wild (3,5--3,6), - LongIdent (SynLongIdent ([int], [], [None])), - (3,5--3,10)), None, + None), Wild (3,5--3,6), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([int], [], [None])), + (3,7--3,10), [], { ColonRange = Some (3,6--3,7) })), App (NonAtomic, false, Ident async, ComputationExpr diff --git a/tests/service/data/SyntaxTree/SynType/Typed UseBang 05.fs.bsl b/tests/service/data/SyntaxTree/SynType/Typed UseBang 05.fs.bsl index 66092e7a006..945d32adab2 100644 --- a/tests/service/data/SyntaxTree/SynType/Typed UseBang 05.fs.bsl +++ b/tests/service/data/SyntaxTree/SynType/Typed UseBang 05.fs.bsl @@ -16,10 +16,12 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Typed - (Named - (SynIdent (res, None), false, None, (4,9--4,12)), - FromParseError (4,13--4,13), (4,9--4,13)), None, + Named + (SynIdent (res, None), false, None, (4,9--4,12)), + Some + (SynBindingReturnInfo + (FromParseError (4,13--4,13), (4,13--4,13), [], + { ColonRange = Some (4,12--4,13) })), App (NonAtomic, false, Ident async, ComputationExpr From 627275957023849e541975a7ea5ee7a733ec2736 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Wed, 15 Oct 2025 18:20:02 +0300 Subject: [PATCH 3/8] wip --- src/Compiler/SyntaxTree/ParseHelpers.fs | 4 +++- src/Compiler/SyntaxTree/ParseHelpers.fsi | 9 ++++++++- src/Compiler/pars.fsy | 4 ++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs index 7013ae560bf..de4e4387048 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fs +++ b/src/Compiler/SyntaxTree/ParseHelpers.fs @@ -868,7 +868,9 @@ let mkClassMemberLocalBindings SynMemberDefn.LetBindings(decls, isStatic, isRec, mWhole) /// Creates a SynExprAndBang node for and! bindings in computation expressions -let mkAndBang (mKeyword: range, pat: SynPat, returnInfo: SynBindingReturnInfo option, rhs: SynExpr, mWhole: range, mEquals: range, mIn: range option) = +let mkAndBang + (mKeyword: range, pat: SynPat, returnInfo: SynBindingReturnInfo option, rhs: SynExpr, mWhole: range, mEquals: range, mIn: range option) + = let spBind = DebugPointAtBinding.Yes(unionRanges mKeyword rhs.Range) let trivia: SynBindingTrivia = diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fsi b/src/Compiler/SyntaxTree/ParseHelpers.fsi index eed66a79b76..a4277ad06c8 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fsi +++ b/src/Compiler/SyntaxTree/ParseHelpers.fsi @@ -209,7 +209,14 @@ val mkLetExpression: SynExpr val mkAndBang: - mKeyword: range * pat: SynPat * returnInfo: SynBindingReturnInfo option * rhs: SynExpr * mWhole: range * mEquals: range * mIn: range option -> SynBinding + mKeyword: range * + pat: SynPat * + returnInfo: SynBindingReturnInfo option * + rhs: SynExpr * + mWhole: range * + mEquals: range * + mIn: range option -> + SynBinding val mkDefnBindings: mWhole: range * BindingSet * attrs: SynAttributes * vis: SynAccess option * attrsm: range -> SynModuleDecl list diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 2a525e51410..5abe2d82a07 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -3531,7 +3531,7 @@ ceBindingCore: let isInline = Option.isSome $1 let isMutable = Option.isSome $2 - let ty = + let returnInfo = match tyOpt with | Some(colonRangeOpt, SynReturnInfo((ty, _), tym)) -> parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AllowTypedLetUseAndBang ty.Range @@ -3539,7 +3539,7 @@ ceBindingCore: | None -> None - pat, mPat, isInline, isMutable, ty } + pat, mPat, isInline, isMutable, returnInfo } opt_simplePatterns: | simplePatterns From b7a3a82d681eac119c6edec2616600838e763e2f Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Wed, 15 Oct 2025 18:21:16 +0300 Subject: [PATCH 4/8] readme ^ Conflicts: ^ docs/release-notes/.FSharp.Compiler.Service/11.0.0.md --- docs/release-notes/.FSharp.Compiler.Service/11.0.0.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.0.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.0.md index 655ad02ad2a..e8c5494d02a 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.0.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.0.md @@ -4,6 +4,7 @@ * Fix excessive StackGuard thread jumping ([PR #18971](https://github.com/dotnet/fsharp/pull/18971)) * Checking: Fix checking nested fields for records and anonymous ([PR #18964](https://github.com/dotnet/fsharp/pull/18964)) * Fix name is bound multiple times is not reported in 'as' pattern ([PR #18984](https://github.com/dotnet/fsharp/pull/18984)) +* Syntax Tree: fix return type info for let! / and! / use! ([PR #19004](https://github.com/dotnet/fsharp/pull/19004)) * Fix: warn FS0049 on upper union case label. ([PR #19003](https://github.com/dotnet/fsharp/pull/19003)) * Type relations cache: handle potentially "infinite" types ([PR #19010](https://github.com/dotnet/fsharp/pull/19010)) From b12e35497bd7a789e021af66b992340ea75743f2 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Wed, 22 Oct 2025 00:30:43 +0300 Subject: [PATCH 5/8] wip --- .../CheckComputationExpressions.fs | 15 +- .../Language/ComputationExpressionTests.fs | 161 ++++++++++++++++++ 2 files changed, 172 insertions(+), 4 deletions(-) diff --git a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs index e21bfee2640..04e19b92fd0 100644 --- a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs @@ -4,7 +4,6 @@ /// with generalization at appropriate points. module internal FSharp.Compiler.CheckComputationExpressions -open FSharp.Compiler.TcGlobals open Internal.Utilities.Library open FSharp.Compiler.AccessibilityLogic open FSharp.Compiler.AttributeChecking @@ -854,6 +853,12 @@ let (|OptionalSequential|) e = | SynExpr.Sequential(debugPoint = _sp; isTrueSeq = true; expr1 = dataComp1; expr2 = dataComp2) -> (dataComp1, Some dataComp2) | _ -> (e, None) +let private getTypedHeadPattern (SynBinding(headPat = headPattern; returnInfo = returnInfo)) = + match returnInfo with + | None -> headPattern + | Some(SynBindingReturnInfo(typeName = typeName; range = range)) -> + SynPat.Typed(headPattern, typeName, unionRanges headPattern.Range range) + [] let (|ExprAsUseBang|_|) expr = match expr with @@ -865,7 +870,8 @@ let (|ExprAsUseBang|_|) expr = body = innerComp trivia = { LetOrUseKeyword = mBind }) -> match bindings with - | SynBinding(debugPoint = spBind; headPat = pat; expr = rhsExpr) :: andBangs -> + | SynBinding(debugPoint = spBind; expr = rhsExpr) as binding :: andBangs -> + let pat = getTypedHeadPattern binding ValueSome(spBind, isFromSource, pat, rhsExpr, andBangs, innerComp, mBind) | _ -> ValueNone | _ -> ValueNone @@ -881,7 +887,8 @@ let (|ExprAsLetBang|_|) expr = body = innerComp trivia = { LetOrUseKeyword = mBind }) -> match bindings with - | SynBinding(debugPoint = spBind; headPat = letPat; expr = letRhsExpr) :: andBangBindings -> + | SynBinding(debugPoint = spBind; expr = letRhsExpr) as binding :: andBangBindings -> + let letPat = getTypedHeadPattern binding ValueSome(spBind, isFromSource, letPat, letRhsExpr, andBangBindings, innerComp, mBind) | _ -> ValueNone | _ -> ValueNone @@ -2006,7 +2013,7 @@ let rec TryTranslateComputationExpression |> List.map (fun expr -> mkSourceExprConditional isFromSource expr ceenv.sourceMethInfo ceenv.builderValName) let pats = - letPat :: [ for SynBinding(headPat = andPat) in andBangBindings -> andPat ] + letPat :: [ for binding in andBangBindings -> getTypedHeadPattern binding ] let sourcesRange = sources |> List.map (fun e -> e.Range) |> List.reduce unionRanges diff --git a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs index e4da01a33ec..dcff8ec01ad 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs @@ -2072,6 +2072,167 @@ task { Error 1, Line 7, Col 11, Line 7, Col 17, "This expression was expected to have type 'IDisposable' but here has type +'int' " + ] + + [] + let ``Preview: let! return type check error 01`` () = + FSharp """ +module Test + +open System.Threading.Tasks + +task { + let! x: string = Task.FromResult(1) + () +} +|> ignore +""" + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withDiagnostics [ + Error 1, Line 7, Col 10, Line 7, Col 19, "This expression was expected to have type + 'int' +but here has type + 'string' " + ] + + [] + let ``Preview: let! return type check error 02`` () = + FSharp """ +module Test + +open System.Threading.Tasks + +task { + let! (x: string): int = Task.FromResult(1) + () +} +|> ignore +""" + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withDiagnostics [ + Error 1, Line 7, Col 11, Line 7, Col 20, "This expression was expected to have type + 'int' +but here has type + 'string' " + ] + + [] + let ``Preview: let! return type check error 03`` () = + FSharp """ +module Test + +open System.Threading.Tasks + +task { + let! (x: string): int = Task.FromResult("") + () +} +|> ignore +""" + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withDiagnostics [ + Error 1, Line 7, Col 10, Line 7, Col 26, "This expression was expected to have type + 'string' +but here has type + 'int' " + ] + + [] + let ``Preview: let!-and! return type check error 01`` () = + FSharp """ +module Test + +type MyBuilder() = + member _.Return(x: int): Result = failwith "" + member _.Bind(m: Result, f: int -> Result): Result = failwith "" + member _.Bind2(m1: Result, m2: Result, f: int * int -> Result): Result = failwith "" + +let builder = MyBuilder() + +builder { + let! x: int = Ok 1 + and! y: string = Ok 2 + return 0 +} +|> ignore +""" + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withDiagnostics [ + Error 1, Line 13, Col 10, Line 13, Col 19, "This expression was expected to have type +'int' +but here has type +'string' "; + Warning 25, Line 12, Col 10, Line 12, Col 16, "Incomplete pattern matches on this expression." + ] + + [] + let ``Preview: let!-and! return type check error 02`` () = + FSharp """ +module Test + +type MyBuilder() = + member _.Return(x: int): Result = failwith "" + member _.Bind(m: Result, f: int -> Result): Result = failwith "" + member _.Bind2(m1: Result, m2: Result, f: int * int -> Result): Result = failwith "" + +let builder = MyBuilder() + +builder { + let! x: int = Ok 1 + and! (y: string): int = Ok 2 + return 0 +} +|> ignore +""" + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withDiagnostics [ + Error 1, Line 13, Col 11, Line 13, Col 20, "This expression was expected to have type +'int' +but here has type +'string' " + ] + + [] + let ``Preview: let!-and! return type check error 03`` () = + FSharp """ +module Test + +type MyBuilder() = + member _.Return(x: int): Result = failwith "" + member _.Bind(m: Result, f: int -> Result): Result = failwith "" + member _.Bind2(m1: Result, m2: Result, f: int * int -> Result): Result = failwith "" + +let builder = MyBuilder() + +builder { + let! x: int = Ok 1 + and! (y: int): string = Ok 1 + return 0 +} +|> ignore +""" + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withDiagnostics [ + Error 1, Line 13, Col 10, Line 13, Col 26, "This expression was expected to have type +'int' +but here has type +'string' " + Error 1, Line 13, Col 11, Line 13, Col 17, "This expression was expected to have type +'string' +but here has type 'int' " ] From 2b5a42b1051fc67127a651cf15cfaade0267e96f Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Wed, 22 Oct 2025 00:44:26 +0300 Subject: [PATCH 6/8] wip --- .../Language/ComputationExpressionTests.fs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs index dcff8ec01ad..9959628042a 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs @@ -2092,6 +2092,7 @@ task { |> typecheck |> shouldFail |> withDiagnostics [ + // x: string Error 1, Line 7, Col 10, Line 7, Col 19, "This expression was expected to have type 'int' but here has type @@ -2115,6 +2116,7 @@ task { |> typecheck |> shouldFail |> withDiagnostics [ + // x: string Error 1, Line 7, Col 11, Line 7, Col 20, "This expression was expected to have type 'int' but here has type @@ -2138,6 +2140,7 @@ task { |> typecheck |> shouldFail |> withDiagnostics [ + // (x: string): int Error 1, Line 7, Col 10, Line 7, Col 26, "This expression was expected to have type 'string' but here has type @@ -2167,10 +2170,12 @@ builder { |> typecheck |> shouldFail |> withDiagnostics [ + // y: string Error 1, Line 13, Col 10, Line 13, Col 19, "This expression was expected to have type 'int' but here has type -'string' "; +'string' " + // x: int Warning 25, Line 12, Col 10, Line 12, Col 16, "Incomplete pattern matches on this expression." ] @@ -2197,6 +2202,7 @@ builder { |> typecheck |> shouldFail |> withDiagnostics [ + // y: string Error 1, Line 13, Col 11, Line 13, Col 20, "This expression was expected to have type 'int' but here has type @@ -2226,10 +2232,12 @@ builder { |> typecheck |> shouldFail |> withDiagnostics [ + // (y: int): string Error 1, Line 13, Col 10, Line 13, Col 26, "This expression was expected to have type 'int' but here has type 'string' " + // y: int Error 1, Line 13, Col 11, Line 13, Col 17, "This expression was expected to have type 'string' but here has type From 45ad26f64a7c8272c4427dea661db766ae6d10b2 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Wed, 22 Oct 2025 01:51:24 +0300 Subject: [PATCH 7/8] wip --- .../Expressions/CheckComputationExpressions.fs | 8 ++++---- .../Language/ComputationExpressionTests.fs | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs index 04e19b92fd0..b035249f48f 100644 --- a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs @@ -853,7 +853,7 @@ let (|OptionalSequential|) e = | SynExpr.Sequential(debugPoint = _sp; isTrueSeq = true; expr1 = dataComp1; expr2 = dataComp2) -> (dataComp1, Some dataComp2) | _ -> (e, None) -let private getTypedHeadPattern (SynBinding(headPat = headPattern; returnInfo = returnInfo)) = +let private mkTypedHeadPat (SynBinding(headPat = headPattern; returnInfo = returnInfo)) = match returnInfo with | None -> headPattern | Some(SynBindingReturnInfo(typeName = typeName; range = range)) -> @@ -871,7 +871,7 @@ let (|ExprAsUseBang|_|) expr = trivia = { LetOrUseKeyword = mBind }) -> match bindings with | SynBinding(debugPoint = spBind; expr = rhsExpr) as binding :: andBangs -> - let pat = getTypedHeadPattern binding + let pat = mkTypedHeadPat binding ValueSome(spBind, isFromSource, pat, rhsExpr, andBangs, innerComp, mBind) | _ -> ValueNone | _ -> ValueNone @@ -888,7 +888,7 @@ let (|ExprAsLetBang|_|) expr = trivia = { LetOrUseKeyword = mBind }) -> match bindings with | SynBinding(debugPoint = spBind; expr = letRhsExpr) as binding :: andBangBindings -> - let letPat = getTypedHeadPattern binding + let letPat = mkTypedHeadPat binding ValueSome(spBind, isFromSource, letPat, letRhsExpr, andBangBindings, innerComp, mBind) | _ -> ValueNone | _ -> ValueNone @@ -2013,7 +2013,7 @@ let rec TryTranslateComputationExpression |> List.map (fun expr -> mkSourceExprConditional isFromSource expr ceenv.sourceMethInfo ceenv.builderValName) let pats = - letPat :: [ for binding in andBangBindings -> getTypedHeadPattern binding ] + letPat :: [ for binding in andBangBindings -> mkTypedHeadPat binding ] let sourcesRange = sources |> List.map (fun e -> e.Range) |> List.reduce unionRanges diff --git a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs index 9959628042a..4d167ef0370 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs @@ -2076,7 +2076,7 @@ but here has type ] [] - let ``Preview: let! return type check error 01`` () = + let ``Preview: let! return type mismatch error 01`` () = FSharp """ module Test @@ -2100,7 +2100,7 @@ but here has type ] [] - let ``Preview: let! return type check error 02`` () = + let ``Preview: let! return type mismatch error 02`` () = FSharp """ module Test @@ -2124,7 +2124,7 @@ but here has type ] [] - let ``Preview: let! return type check error 03`` () = + let ``Preview: let! return type mismatch error 03`` () = FSharp """ module Test @@ -2148,7 +2148,7 @@ but here has type ] [] - let ``Preview: let!-and! return type check error 01`` () = + let ``Preview: let!-and! return type mismatch error 01`` () = FSharp """ module Test @@ -2180,7 +2180,7 @@ but here has type ] [] - let ``Preview: let!-and! return type check error 02`` () = + let ``Preview: let!-and! return type mismatch error 02`` () = FSharp """ module Test @@ -2210,7 +2210,7 @@ but here has type ] [] - let ``Preview: let!-and! return type check error 03`` () = + let ``Preview: let!-and! return type mismatch error 03`` () = FSharp """ module Test From e5b5efddb7b73eac052b588571326c678d17868f Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Wed, 22 Oct 2025 01:55:56 +0300 Subject: [PATCH 8/8] fantomas --- .../Checking/Expressions/CheckComputationExpressions.fs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs index b035249f48f..a43a1544517 100644 --- a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs @@ -2012,8 +2012,7 @@ let rec TryTranslateComputationExpression (letRhsExpr :: [ for SynBinding(expr = andExpr) in andBangBindings -> andExpr ]) |> List.map (fun expr -> mkSourceExprConditional isFromSource expr ceenv.sourceMethInfo ceenv.builderValName) - let pats = - letPat :: [ for binding in andBangBindings -> mkTypedHeadPat binding ] + let pats = letPat :: [ for binding in andBangBindings -> mkTypedHeadPat binding ] let sourcesRange = sources |> List.map (fun e -> e.Range) |> List.reduce unionRanges