diff --git a/src/Compiler/Service/ServiceParseTreeWalk.fs b/src/Compiler/Service/ServiceParseTreeWalk.fs index 2a335d274e9..8415ec401fd 100644 --- a/src/Compiler/Service/ServiceParseTreeWalk.fs +++ b/src/Compiler/Service/ServiceParseTreeWalk.fs @@ -594,7 +594,7 @@ module SyntaxTraversal = | SynExpr.TypeApp (synExpr, _, _synTypeList, _commas, _, _, _range) -> traverseSynExpr synExpr - | SynExpr.LetOrUse (_, isRecursive, synBindingList, synExpr, range, _) -> + | SynExpr.LetOrUse (isRecursive, _, synBindingList, synExpr, range, _) -> match visitor.VisitLetOrUse(path, isRecursive, traverseSynBinding path, synBindingList, range) with | None -> [ diff --git a/tests/service/TreeVisitorTests.fs b/tests/service/TreeVisitorTests.fs index 9bcfa47796a..58bda80d487 100644 --- a/tests/service/TreeVisitorTests.fs +++ b/tests/service/TreeVisitorTests.fs @@ -58,4 +58,20 @@ let ``Visit enum definition test`` () = match SyntaxTraversal.Traverse(pos0, parseTree, visitor) with | Some [ SynEnumCase (_, SynIdent(id1,_), _, _, _, _, _); SynEnumCase (_, SynIdent(id2,_), _, _, _, _, _) ] when id1.idText = "A" && id2.idText = "B" -> () - | _ -> failwith "Did not visit enum definition" \ No newline at end of file + | _ -> failwith "Did not visit enum definition" + +[] +let ``Visit recursive let binding`` () = + let visitor = + { new SyntaxVisitorBase<_>() with + member x.VisitExpr(_, _, defaultTraverse, expr) = defaultTraverse expr + member x.VisitLetOrUse(_, isRecursive, _, bindings, _) = + if not isRecursive then failwith $"{nameof isRecursive} should be true" + Some bindings } + + let source = "let rec fib n = if n < 2 then n else fib (n - 1) + fib (n - 2) in fib 10" + let parseTree = parseSourceCode("C:\\test.fs", source) + + match SyntaxTraversal.Traverse(pos0, parseTree, visitor) with + | Some [ SynBinding(valData = SynValData(valInfo = SynValInfo(curriedArgInfos = [ [ SynArgInfo(ident = Some id) ] ]))) ] when id.idText = "n" -> () + | _ -> failwith "Did not visit recursive let binding" \ No newline at end of file