Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 2 additions & 1 deletion docs/release-notes/.FSharp.Compiler.Service/11.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@
* Parallel compilation features: ref resolution, graph based checking, ILXGen and optimization enabled by default ([PR #18998](https://github.com/dotnet/fsharp/pull/18998))
* Make graph based type checking and parallel optimizations deterministic ([PR #19028](https://github.com/dotnet/fsharp/pull/19028))


### Breaking Changes

* Remove LetOrUseKeyword from SynExprLetOrUseTrivia. Information is now captured by SynLeadingKeyword in SynBinding. ([PR #19090](https://github.com/dotnet/fsharp/pull/19090))
6 changes: 3 additions & 3 deletions src/Compiler/Checking/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5113,7 +5113,7 @@ let ElimSynModuleDeclExpr bind =
match bind with
| SynModuleDecl.Expr (expr, m) ->
let bind2 = SynBinding (None, SynBindingKind.StandaloneExpression, false, false, [], PreXmlDoc.Empty, SynInfo.emptySynValData, SynPat.Wild m, None, expr, m, DebugPointAtBinding.NoneAtDo, SynBindingTrivia.Zero)
SynModuleDecl.Let(false, [bind2], m)
SynModuleDecl.Let(false, [bind2], m, SynModuleDeclLetTrivia.Zero)
| _ -> bind

let TcMutRecDefnsEscapeCheck (binds: MutRecShapes<_, _, _>) env =
Expand Down Expand Up @@ -5187,7 +5187,7 @@ let TcModuleOrNamespaceElementsMutRec (cenv: cenv) parent typeNames m envInitial
let decls = typeDefs |> List.map MutRecShape.Tycon
decls, (false, false, attrs)

| SynModuleDecl.Let (letrec, binds, m) ->
| SynModuleDecl.Let (isRecursive = letrec; bindings = binds; range = m) ->
let binds =
if isNamespace then
CheckLetOrDoInNamespace binds m; []
Expand Down Expand Up @@ -5292,7 +5292,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv: cenv) parent typeNames scopem
| _ -> [ TMDefOpens openDecls ]
return (defns, [], []), env, env

| SynModuleDecl.Let (letrec, binds, m) ->
| SynModuleDecl.Let (isRecursive = letrec; bindings = binds; range = m) ->

match parent with
| ParentNone ->
Expand Down
17 changes: 7 additions & 10 deletions src/Compiler/Checking/CheckRecordSyntaxHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,10 @@ let BindOriginalRecdExpr (withExpr: SynExpr * BlockSeparator) mkRecdExpr =
None,
SynBindingTrivia.Zero)

SynExpr.LetOrUse(
isRecursive = false,
isUse = false,
isFromSource = false, // compiler generated during desugaring
isBang = false,
bindings = [ binding ],
body = mkRecdExpr (Some withExpr),
range = mOrigExprSynth,
trivia = SynExprLetOrUseTrivia.Zero
)
SynExpr.LetOrUse
{
IsRecursive = false
Bindings = [ binding ]
Body = mkRecdExpr (Some withExpr)
Range = mOrigExprSynth
}
272 changes: 127 additions & 145 deletions src/Compiler/Checking/Expressions/CheckComputationExpressions.fs

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions src/Compiler/Checking/Expressions/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6073,8 +6073,9 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE

| SynExpr.DoBang (trivia = { DoBangKeyword = m })
| SynExpr.MatchBang (trivia = { MatchBangKeyword = m })
| SynExpr.WhileBang (range = m)
| SynExpr.LetOrUse (isBang = true; trivia = { LetOrUseKeyword = m }) ->
| SynExpr.WhileBang (range = m) ->
error(Error(FSComp.SR.tcConstructRequiresComputationExpression(), m))
| SynExpr.LetOrUse(({ Range = m}) as letOrUse) when letOrUse.IsBang ->
error(Error(FSComp.SR.tcConstructRequiresComputationExpression(), m))

| SynExpr.IndexFromEnd (rightExpr, m) ->
Expand Down Expand Up @@ -9207,7 +9208,6 @@ and TcImplicitOpItemThen (cenv: cenv) overallTy env id sln tpenv mItem delayed =
| SynExpr.YieldOrReturn _
| SynExpr.YieldOrReturnFrom _
| SynExpr.MatchBang _
| SynExpr.LetOrUse (isBang = true)
| SynExpr.DoBang _
| SynExpr.WhileBang _
| SynExpr.TraitCall _
Expand Down Expand Up @@ -10622,20 +10622,20 @@ and TcLinearExprs bodyChecker cenv env overallTy tpenv isCompExpr synExpr cont =
TcLinearExprs bodyChecker cenv env2 overallTy tpenv isCompExpr expr2 (fun (expr2R, tpenv) ->
cont (Expr.Sequential (expr1R, expr2R, NormalSeq, m), tpenv))

| SynExpr.LetOrUse (isRecursive = isRec; isUse= isUse; bindings = binds; body = body; range = m) when not (isUse && isCompExpr) ->
| SynExpr.LetOrUse ({ IsRecursive = isRec; Bindings = binds; Body = body; Range = m } as letOrUse) when not (letOrUse.IsUse && isCompExpr) ->
if isRec then
// TcLinearExprs processes at most one recursive binding, this is not tailcalling
CheckRecursiveBindingIds binds
let binds = List.map (fun x -> RecDefnBindingInfo(ExprContainerInfo, NoNewSlots, ExpressionBinding, x)) binds
if isUse then errorR(Error(FSComp.SR.tcBindingCannotBeUseAndRec(), m))
if letOrUse.IsUse then errorR(Error(FSComp.SR.tcBindingCannotBeUseAndRec(), m))
let binds, envinner, tpenv = TcLetrecBindings ErrorOnOverrides cenv env tpenv (binds, m, m)
let envinner = { envinner with eIsControlFlow = true }
let bodyExpr, tpenv = bodyChecker overallTy envinner tpenv body
let bodyExpr = bindLetRec binds m bodyExpr
cont (bodyExpr, tpenv)
else
// TcLinearExprs processes multiple 'let' bindings in a tail recursive way
let mkf, envinner, tpenv = TcLetBinding cenv isUse env ExprContainerInfo ExpressionBinding tpenv (binds, m, body.Range)
let mkf, envinner, tpenv = TcLetBinding cenv letOrUse.IsUse env ExprContainerInfo ExpressionBinding tpenv (binds, m, body.Range)
let envinner = ShrinkContext envinner m body.Range
let envinner = { envinner with eIsControlFlow = true }
// tailcall
Expand Down
11 changes: 5 additions & 6 deletions src/Compiler/Checking/Expressions/CheckExpressionsOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ let YieldFree (cenv: TcFileState) expr =
| SynExpr.MatchBang(clauses = clauses) -> clauses |> List.forall (fun (SynMatchClause(resultExpr = res)) -> YieldFree res)

| SynExpr.For(doBody = body)
| SynExpr.TryFinally(tryExpr = body)
| SynExpr.LetOrUse(body = body)
| SynExpr.TryFinally(tryExpr = body) -> YieldFree body
| SynExpr.LetOrUse({ Body = body } as letOrUse) when not letOrUse.IsBang -> YieldFree body
| SynExpr.While(doExpr = body)
| SynExpr.WhileBang(doExpr = body)
| SynExpr.ForEach(bodyExpr = body) -> YieldFree body
Expand All @@ -223,13 +223,12 @@ let YieldFree (cenv: TcFileState) expr =
| SynExpr.MatchBang(clauses = clauses) -> clauses |> List.forall (fun (SynMatchClause(resultExpr = res)) -> YieldFree res)

| SynExpr.For(doBody = body)
| SynExpr.TryFinally(tryExpr = body)
| SynExpr.LetOrUse(body = body)
| SynExpr.TryFinally(tryExpr = body) -> YieldFree body
| SynExpr.LetOrUse({ Body = body } as letOrUse) when not letOrUse.IsBang -> YieldFree body
| SynExpr.While(doExpr = body)
| SynExpr.WhileBang(doExpr = body)
| SynExpr.ForEach(bodyExpr = body) -> YieldFree body

| SynExpr.LetOrUse(isBang = true)
| SynExpr.LetOrUse letOrUse when letOrUse.IsBang -> false
| SynExpr.YieldOrReturnFrom _
| SynExpr.YieldOrReturn _
| SynExpr.ImplicitZero _
Expand Down
23 changes: 13 additions & 10 deletions src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT
Some(mkCond spIfToThen mIfToEndOfElseBranch genOuterTy guardExpr' thenExpr elseExpr, tpenv)

// 'let x = expr in expr'
| SynExpr.LetOrUse(isUse = false) ->
| SynExpr.LetOrUse letOrUse when not letOrUse.IsUse ->
TcLinearExprs
(fun overallTy envinner tpenv e -> tcSequenceExprBody envinner overallTy.Commit tpenv e)
cenv
Expand All @@ -229,12 +229,15 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT
|> Some

// 'use x = expr in expr'
| SynExpr.LetOrUse(
isUse = true
bindings = [ SynBinding(kind = SynBindingKind.Normal; headPat = pat; expr = rhsExpr) ]
body = innerComp
range = wholeExprMark
trivia = { LetOrUseKeyword = mBind }) ->
| SynExpr.LetOrUse({
Bindings = [ SynBinding(
kind = SynBindingKind.Normal
headPat = pat
expr = rhsExpr
trivia = { LeadingKeyword = leadingKeyword }) ]
Body = innerComp
Range = wholeExprMark
} as letOrUse) when letOrUse.IsUse ->

let bindPatTy = NewInferenceType g
let inputExprTy = NewInferenceType g
Expand All @@ -257,12 +260,12 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT
let matchv, matchExpr =
compileSeqExprMatchClauses cenv envinner inputExprMark (pat', vspecs) innerExpr (Some inputExpr) bindPatTy genOuterTy

let consumeExpr = mkLambda mBind matchv (matchExpr, genOuterTy)
let consumeExpr = mkLambda leadingKeyword.Range matchv (matchExpr, genOuterTy)

// The 'mBind' is attached to the lambda
// The 'leadingKeyword.Range' is attached to the lambda
Some(mkSeqUsing cenv env wholeExprMark bindPatTy genOuterTy inputExpr consumeExpr, tpenv)

| SynExpr.LetOrUse(isBang = true; range = m) -> error (Error(FSComp.SR.tcUseForInSequenceExpression (), m))
| SynExpr.LetOrUse letOrUse when letOrUse.IsBang -> error (Error(FSComp.SR.tcUseForInSequenceExpression (), letOrUse.Range))

| SynExpr.Match(spMatch, expr, clauses, _m, _trivia) ->
let inputExpr, inputTy, tpenv = TcExprOfUnknownType cenv env tpenv expr
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Driver/GraphChecking/FileContentMapping.fs
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ let visitSynExpr (e: SynExpr) : FileContentEntry list =
visit funcExpr (fun funcNodes -> visit argExpr (fun argNodes -> funcNodes @ argNodes |> continuation))
| SynExpr.TypeApp(expr = expr; typeArgs = typeArgs) ->
visit expr (fun exprNodes -> exprNodes @ List.collect visitSynType typeArgs |> continuation)
| SynExpr.LetOrUse(bindings = bindings; body = body) ->
| SynExpr.LetOrUse({ Bindings = bindings; Body = body }) ->
visit body (fun nodes -> List.collect visitBinding bindings @ nodes |> continuation)
| SynExpr.TryWith(tryExpr = tryExpr; withCases = withCases) ->
visit tryExpr (fun nodes -> nodes @ List.collect visitSynMatchClause withCases |> continuation)
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Interactive/fsi.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2587,7 +2587,7 @@ type internal FsiDynamicCompiler
)

let bindingA = mkBind (mkSynPatVar None itID) expr
let defA = SynModuleDecl.Let(false, [ bindingA ], m)
let defA = SynModuleDecl.Let(false, [ bindingA ], m, SynModuleDeclLetTrivia.Zero)
[ defA ]

// Construct an invisible call to Debugger.Break(), in the specified range
Expand Down
6 changes: 3 additions & 3 deletions src/Compiler/Service/FSharpParseFileResults.fs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput,
else
walkBinding expr2 workingRange

| SynExpr.LetOrUse(bindings = bindings; body = bodyExpr) ->
| SynExpr.LetOrUse({ Bindings = bindings; Body = bodyExpr }) ->
let potentialNestedRange =
bindings
|> List.tryFind (fun binding -> rangeContainsPos binding.RangeOfBindingWithRhs pos)
Expand Down Expand Up @@ -696,7 +696,7 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput,
yield! walkExprOpt true whenExpr
yield! walkExpr true tgtExpr

| SynExpr.LetOrUse(bindings = binds; body = bodyExpr) ->
| SynExpr.LetOrUse({ Bindings = binds; Body = bodyExpr }) ->
yield! walkBinds binds
yield! walkExpr true bodyExpr

Expand Down Expand Up @@ -821,7 +821,7 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput,
let rec walkDecl decl =
[
match decl with
| SynModuleDecl.Let(_, binds, m) when isMatchRange m -> yield! walkBinds binds
| SynModuleDecl.Let(bindings = binds; range = m) when isMatchRange m -> yield! walkBinds binds
| SynModuleDecl.Expr(expr, m) when isMatchRange m -> yield! walkExpr true expr
| SynModuleDecl.ModuleAbbrev _ -> ()
| SynModuleDecl.NestedModule(decls = decls; range = m) when isMatchRange m ->
Expand Down
8 changes: 5 additions & 3 deletions src/Compiler/Service/ServiceInterfaceStubGenerator.fs
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,7 @@ module InterfaceStubGenerator =
else
match decl with
| SynModuleDecl.Exception(SynExceptionDefn(_, _, synMembers, _), _) -> List.tryPick walkSynMemberDefn synMembers
| SynModuleDecl.Let(_isRecursive, bindings, _range) -> List.tryPick walkBinding bindings
| SynModuleDecl.Let(bindings = bindings) -> List.tryPick walkBinding bindings
| SynModuleDecl.ModuleAbbrev(_lhs, _rhs, _range) -> None
| SynModuleDecl.NamespaceFragment(fragment) -> walkSynModuleOrNamespace fragment
| SynModuleDecl.NestedModule(decls = modules) -> List.tryPick walkSynModuleDecl modules
Expand Down Expand Up @@ -909,8 +909,10 @@ module InterfaceStubGenerator =

| SynExpr.TypeApp(synExpr, _, _synTypeList, _commas, _, _, _range) -> walkExpr synExpr

| SynExpr.LetOrUse(bindings = synBindingList; body = synExpr) ->
Option.orElse (List.tryPick walkBinding synBindingList) (walkExpr synExpr)
| SynExpr.LetOrUse({
Bindings = synBindingList
Body = synExpr
}) -> Option.orElse (List.tryPick walkBinding synBindingList) (walkExpr synExpr)

| SynExpr.TryWith(tryExpr = synExpr) -> walkExpr synExpr

Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/Service/ServiceNavigation.fs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ module NavigationImpl =
[
for decl in decls do
match decl with
| SynModuleDecl.Let(_, binds, _) ->
| SynModuleDecl.Let(bindings = binds) ->
for bind in binds do
yield! processBinding false NavigationEntityKind.Module false bind
| _ -> ()
Expand Down Expand Up @@ -955,7 +955,7 @@ module NavigateTo =

for m in synMembers do
walkSynMemberDefn m container
| SynModuleDecl.Let(_, bindings, _) ->
| SynModuleDecl.Let(bindings = bindings) ->
for binding in bindings do
addBinding binding None container
| SynModuleDecl.ModuleAbbrev(lhs, _, _) -> addModuleAbbreviation lhs false container
Expand Down
9 changes: 7 additions & 2 deletions src/Compiler/Service/ServiceParseTreeWalk.fs
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ module SyntaxTraversal =
|> List.map (fun x -> dive x x.Range (traverseSynModuleDecl path))
|> List.append (attributeApplicationDives path attributes)
|> pick decl
| SynModuleDecl.Let(isRecursive, synBindingList, range) ->
| SynModuleDecl.Let(isRecursive = isRecursive; bindings = synBindingList; range = range) ->
match visitor.VisitLetOrUse(path, isRecursive, traverseSynBinding path, synBindingList, range) with
| Some x -> Some x
| None ->
Expand Down Expand Up @@ -679,7 +679,12 @@ module SyntaxTraversal =
]
|> pick expr

| SynExpr.LetOrUse(isRecursive = isRecursive; bindings = synBindingList; body = synExpr; range = range) ->
| SynExpr.LetOrUse({
IsRecursive = isRecursive
Bindings = synBindingList
Body = synExpr
Range = range
}) ->
match visitor.VisitLetOrUse(path, isRecursive, traverseSynBinding path, synBindingList, range) with
| None ->
[
Expand Down
8 changes: 4 additions & 4 deletions src/Compiler/Service/ServiceParsedInputOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,7 @@ module ParsedInput =
walkExprWithKind (Some EntityKind.Type) e
|> Option.orElseWith (fun () -> List.tryPick walkType tys)

| SynExpr.LetOrUse(bindings = bindings; body = e) ->
| SynExpr.LetOrUse({ Bindings = bindings; Body = e }) ->
List.tryPick walkBinding bindings
|> Option.orElseWith (fun () -> walkExprWithKind parentKind e)

Expand Down Expand Up @@ -990,7 +990,7 @@ module ParsedInput =

| SynModuleDecl.Open _ -> None

| SynModuleDecl.Let(_, bindings, _) -> List.tryPick walkBinding bindings
| SynModuleDecl.Let(bindings = bindings) -> List.tryPick walkBinding bindings

| SynModuleDecl.Expr(expr, _) -> walkExpr expr

Expand Down Expand Up @@ -2127,7 +2127,7 @@ module ParsedInput =
List.iter walkType tys
walkExpr e

| SynExpr.LetOrUse(bindings = bindings; body = e) ->
| SynExpr.LetOrUse({ Bindings = bindings; Body = e }) ->
List.iter walkBinding bindings
walkExpr e

Expand Down Expand Up @@ -2331,7 +2331,7 @@ module ParsedInput =
| SynModuleDecl.NestedModule(moduleInfo = info; decls = modules) ->
walkComponentInfo false info
List.iter walkSynModuleDecl modules
| SynModuleDecl.Let(_, bindings, _) -> List.iter walkBinding bindings
| SynModuleDecl.Let(bindings = bindings) -> List.iter walkBinding bindings
| SynModuleDecl.Expr(expr, _) -> walkExpr expr
| SynModuleDecl.Types(types, _) -> List.iter walkTypeDefn types
| SynModuleDecl.Attributes(Attributes attrs, _) -> List.iter walkAttribute attrs
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/Service/ServiceStructure.fs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ module Structure =
rcheck Scope.For Collapse.Below r r
parseExpr e

| SynExpr.LetOrUse(bindings = bindings; body = body) ->
| SynExpr.LetOrUse({ Bindings = bindings; Body = body }) ->
parseBindings bindings
parseExpr body

Expand Down Expand Up @@ -772,7 +772,7 @@ module Structure =

let rec parseDeclaration (decl: SynModuleDecl) =
match decl with
| SynModuleDecl.Let(_, bindings, r) ->
| SynModuleDecl.Let(bindings = bindings; range = r) ->
for binding in bindings do
let collapse = Range.endToEnd binding.RangeOfBindingWithoutRhs r
rcheck Scope.LetOrUse Collapse.Below r collapse
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Service/ServiceXmlDocParser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ module XmlDocParsing =
| SynModuleDecl.NestedModule(decls = decls) ->
for decl in decls do
yield! getXmlDocablesSynModuleDecl decl
| SynModuleDecl.Let(_, synBindingList, range) ->
| SynModuleDecl.Let(bindings = synBindingList; range = range) ->
let anyXmlDoc =
synBindingList
|> List.exists (fun (SynBinding(xmlDoc = preXmlDoc)) -> not (isEmptyXmlDoc preXmlDoc))
Expand Down
Loading
Loading