diff --git a/src/Fantomas.Tests/LetBindingTests.fs b/src/Fantomas.Tests/LetBindingTests.fs index dc3d22ebb5..dcff73e3c2 100644 --- a/src/Fantomas.Tests/LetBindingTests.fs +++ b/src/Fantomas.Tests/LetBindingTests.fs @@ -1831,3 +1831,42 @@ type Viewport = longitude: float zoom: int } """ + +[] +let ``recursive let bindings in sequential expression, 1628`` () = + formatSourceString + false + """ +let foobar () = + Console.WriteLine("Hello") + + let rec foo () = bar "Hello" + and bar str = printf "%s" str |> ignore + + foo () + +let foobar () = + let rec foo () = bar "Hello" + and bar str = printf "%s" str |> ignore + + foo () +""" + config + |> prepend newline + |> should + equal + """ +let foobar () = + Console.WriteLine("Hello") + + let rec foo () = bar "Hello" + and bar str = printf "%s" str |> ignore + + foo () + +let foobar () = + let rec foo () = bar "Hello" + and bar str = printf "%s" str |> ignore + + foo () +""" diff --git a/src/Fantomas/CodePrinter.fs b/src/Fantomas/CodePrinter.fs index 9f3748af0d..4aca11372c 100644 --- a/src/Fantomas/CodePrinter.fs +++ b/src/Fantomas/CodePrinter.fs @@ -1426,10 +1426,7 @@ and genExpr astContext synExpr ctx = | CompExprBody statements -> let genCompExprStatement astContext ces = match ces with - | LetOrUseStatement (isRecursive, isUse, binding) -> - let prefix = - sprintf "%s%s" (if isUse then "use " else "let ") (if isRecursive then "rec " else "") - + | LetOrUseStatement (prefix, binding) -> enterNodeFor (synBindingToFsAstType binding) binding.RangeOfBindingAndRhs +> genLetBinding astContext prefix binding | LetOrUseBangStatement (isUse, pat, expr, r) -> @@ -1448,14 +1445,14 @@ and genExpr astContext synExpr ctx = let getRangeOfCompExprStatement ces = match ces with - | LetOrUseStatement (_, _, binding) -> binding.RangeOfBindingAndRhs + | LetOrUseStatement (_, binding) -> binding.RangeOfBindingAndRhs | LetOrUseBangStatement (_, _, _, r) -> r | AndBangStatement (_, _, r) -> r | OtherStatement expr -> expr.Range let getSepNln ces r = match ces with - | LetOrUseStatement (_, _, b) -> + | LetOrUseStatement (_, b) -> sepNlnConsideringTriviaContentBeforeForMainNode (synBindingToFsAstType b) r | LetOrUseBangStatement _ -> sepNlnConsideringTriviaContentBeforeForMainNode SynExpr_LetOrUseBang r | AndBangStatement _ -> sepNlnConsideringTriviaContentBeforeForToken AND_BANG r diff --git a/src/Fantomas/SourceParser.fs b/src/Fantomas/SourceParser.fs index b6417dd959..d7f1c6654b 100644 --- a/src/Fantomas/SourceParser.fs +++ b/src/Fantomas/SourceParser.fs @@ -906,22 +906,20 @@ let rec (|LetOrUses|_|) = | _ -> None type ComputationExpressionStatement = - | LetOrUseStatement of recursive: bool * isUse: bool * SynBinding + | LetOrUseStatement of prefix: string * binding: SynBinding | LetOrUseBangStatement of isUse: bool * SynPat * SynExpr * range | AndBangStatement of SynPat * SynExpr * range | OtherStatement of SynExpr let rec collectComputationExpressionStatements e : ComputationExpressionStatement list = match e with - | SynExpr.LetOrUse (isRecursive, isUse, bindings, body, _) -> - let bindings = - bindings - |> List.map (fun b -> LetOrUseStatement(isRecursive, isUse, b)) + | LetOrUses (bindings, body) -> + let letBindings = bindings |> List.map LetOrUseStatement let returnExpr = collectComputationExpressionStatements body - [ yield! bindings; yield! returnExpr ] + letBindings @ returnExpr | SynExpr.LetOrUseBang (_, isUse, _, pat, expr, andBangs, body, r) -> let letOrUseBang = LetOrUseBangStatement(isUse, pat, expr, r)