@@ -5343,9 +5343,8 @@ and TcExprNoRecover cenv ty (env: TcEnv) tpenv (expr: SynExpr) =
53435343 if GetCtorShapeCounter env > 0 then AdjustCtorShapeCounter (fun x -> x - 1) env
53445344 else env
53455345
5346- let tm,tpenv = TcExprThen cenv ty env tpenv expr []
5346+ TcExprThen cenv ty env tpenv expr []
53475347
5348- tm,tpenv
53495348
53505349// This recursive entry is only used from one callsite (DiscardAfterMissingQualificationAfterDot)
53515350// and has been added relatively late in F# 4.0 to preserve the structure of previous code. It pushes a 'delayed' parameter
@@ -5696,8 +5695,8 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) =
56965695 ((if cenv.g.compilingFslib then id else mkCallSeq cenv.g m genCollElemTy)
56975696 (mkCoerceExpr(expr,genEnumTy,expr.Range,exprty))),tpenv
56985697
5699- | SynExpr.LetOrUse (isRec,isUse,binds,body,m) ->
5700- TcLinearLetExprs (TcExprThatCanBeCtorBody cenv) cenv env overallTy (fun x -> x) tpenv (true(*consume use bindings*),isRec,isUse,binds,body,m )
5698+ | SynExpr.LetOrUse _ ->
5699+ TcLinearExprs (TcExprThatCanBeCtorBody cenv) cenv env overallTy tpenv false expr (fun x -> x)
57015700
57025701 | SynExpr.TryWith (e1,_mTryToWith,clauses,mWithToLast,mTryToLast,spTry,spWith) ->
57035702 let e1',tpenv = TcExpr cenv overallTy env tpenv e1
@@ -5736,17 +5735,7 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) =
57365735
57375736 | SynExpr.Sequential (sp,dir,e1,e2,m) ->
57385737 if dir then
5739- // Use continuations to cope with long linear sequences
5740- let rec TcLinearSeqs expr cont =
5741- match expr with
5742- | SynExpr.Sequential (sp,true,e1,e2,m) ->
5743- let e1',_ = TcStmtThatCantBeCtorBody cenv env tpenv e1
5744- TcLinearSeqs e2 (fun (e2',tpenv) ->
5745- cont (Expr.Sequential(e1',e2',NormalSeq,sp,m),tpenv))
5746-
5747- | _ ->
5748- cont (TcExprThatCanBeCtorBody cenv overallTy env tpenv expr)
5749- TcLinearSeqs expr (fun res -> res)
5738+ TcLinearExprs (TcExprThatCanBeCtorBody cenv) cenv env overallTy tpenv false expr (fun x -> x)
57505739 else
57515740 // Constructors using "new (...) = <ctor-expr> then <expr>"
57525741 let e1',tpenv = TcExprThatCanBeCtorBody cenv overallTy env tpenv e1
@@ -7946,13 +7935,14 @@ and TcSequenceExpression cenv env tpenv comp overallTy m =
79467935 Some(mkCond spIfToThen SequencePointAtTarget mIfToEndOfElseBranch genOuterTy guardExpr' thenExpr elseExpr, tpenv)
79477936
79487937 // 'let x = expr in expr'
7949- | SynExpr.LetOrUse (isRec ,false (* not a 'use' binding *),binds,body,m ) ->
7950- TcLinearLetExprs
7938+ | SynExpr.LetOrUse (_ ,false (* not a 'use' binding *),_,_,_ ) ->
7939+ TcLinearExprs
79517940 (fun ty envinner tpenv e -> tcSequenceExprBody envinner ty tpenv e)
79527941 cenv env overallTy
7953- (fun x -> x)
79547942 tpenv
7955- (false(* don't consume 'use' bindings*),isRec,false,binds,body,m) |> Some
7943+ true
7944+ comp
7945+ (fun x -> x) |> Some
79567946
79577947 // 'use x = expr in expr'
79587948 | SynExpr.LetOrUse (_isRec,true,[Binding (_vis,NormalBinding,_,_,_,_,_,pat,_,rhsExpr,_,_spBind)],innerComp,wholeExprMark) ->
@@ -9766,32 +9756,34 @@ and CheckRecursiveBindingIds binds =
97669756 error(Duplicate("value",nm,m))
97679757 else hashOfBinds.[nm] <- b
97689758
9769- /// Process a sequence of iterated lets "let ... in let ... in ..." in a tail recursive way
9770- /// This avoids stack overflow on really larger "let" and "letrec" lists
9771- and TcLinearLetExprs bodyChecker cenv env overallTy builder tpenv (processUseBindings,isRec,isUse,binds,body,m) =
9772- assert (not isUse || processUseBindings)
9759+ /// Process a sequence of seqeuntials mixed with iterated lets "let ... in let ... in ..." in a tail recursive way
9760+ /// This avoids stack overflow on really large "let" and "letrec" lists
9761+ and TcLinearExprs bodyChecker cenv env overallTy tpenv isCompExpr expr cont =
9762+ match expr with
9763+ | SynExpr.Sequential (sp,true,e1,e2,m) when not isCompExpr ->
9764+ let e1',_ = TcStmtThatCantBeCtorBody cenv env tpenv e1
9765+ // tailcall
9766+ TcLinearExprs bodyChecker cenv env overallTy tpenv isCompExpr e2 (fun (e2',tpenv) ->
9767+ cont (Expr.Sequential(e1',e2',NormalSeq,sp,m),tpenv))
9768+
9769+ | SynExpr.LetOrUse (isRec,isUse,binds,body,m) when not (isUse && isCompExpr) ->
97739770
9774- if isRec then
9775- // TcLinearLetExprs processes at most one recursive binding
9776- CheckRecursiveBindingIds binds
9777- let binds = List.map (fun x -> RecDefnBindingInfo(ExprContainerInfo,NoNewSlots,ExpressionBinding,x)) binds
9778- if isUse then errorR(Error(FSComp.SR.tcBindingCannotBeUseAndRec(),m))
9779- let binds,envinner,tpenv = TcLetrec ErrorOnOverrides cenv env tpenv (binds,m,m)
9780- let bodyExpr,tpenv = bodyChecker overallTy envinner tpenv body
9781- let bodyExpr = bindLetRec (FlatList.ofList binds) m bodyExpr
9782- fst (builder (bodyExpr,overallTy)),tpenv
9783- else
9784- // TcLinearLetExprs processes multiple 'let' bindings in a tail recursive way
9785- // We process one binding, then look for additional linear bindings and accumulate the builder continuation.
9786- // Don't processes 'use' bindings (e.g. in sequence expressions) unless directed to.
9787- let mkf,envinner,tpenv = TcLetBinding cenv isUse env ExprContainerInfo ExpressionBinding tpenv (binds,m,body.Range)
9788- let builder' x = builder (mkf x)
9789- match body with
9790- | SynExpr.LetOrUse (isRec',isUse',binds',bodyExpr,m') when (not isUse' || processUseBindings) ->
9791- TcLinearLetExprs bodyChecker cenv envinner overallTy builder' tpenv (processUseBindings,isRec',isUse',binds',bodyExpr,m')
9792- | _ ->
9771+ if isRec then
9772+ // TcLinearExprs processes at most one recursive binding, this is not tailcalling
9773+ CheckRecursiveBindingIds binds
9774+ let binds = List.map (fun x -> RecDefnBindingInfo(ExprContainerInfo,NoNewSlots,ExpressionBinding,x)) binds
9775+ if isUse then errorR(Error(FSComp.SR.tcBindingCannotBeUseAndRec(),m))
9776+ let binds,envinner,tpenv = TcLetrec ErrorOnOverrides cenv env tpenv (binds,m,m)
97939777 let bodyExpr,tpenv = bodyChecker overallTy envinner tpenv body
9794- fst (builder' (bodyExpr,overallTy)),tpenv
9778+ let bodyExpr = bindLetRec (FlatList.ofList binds) m bodyExpr
9779+ cont (bodyExpr,tpenv)
9780+ else
9781+ // TcLinearExprs processes multiple 'let' bindings in a tail recursive way
9782+ let mkf,envinner,tpenv = TcLetBinding cenv isUse env ExprContainerInfo ExpressionBinding tpenv (binds,m,body.Range)
9783+ TcLinearExprs bodyChecker cenv envinner overallTy tpenv isCompExpr body (fun (x,tpenv) ->
9784+ cont (fst (mkf (x,overallTy)), tpenv))
9785+ | _ ->
9786+ cont (bodyChecker overallTy env tpenv expr)
97959787
97969788/// Typecheck and compile pattern-matching constructs
97979789and TcAndPatternCompileMatchClauses mExpr matchm actionOnFailure cenv inputTy resultTy env tpenv clauses =
@@ -10437,7 +10429,7 @@ and TcLetBinding cenv isUse env containerInfo declKind tpenv (binds,bindsm,scope
1043710429 else
1043810430 (bodyExpr,bodyExprTy)
1043910431
10440- ((mkRhsBind << mkPatBind << mkCleanup << mkf_sofar ),
10432+ ((mkf_sofar >> mkCleanup >> mkPatBind >> mkRhsBind ),
1044110433 AddLocalValMap cenv.tcSink scopem prelimRecValues env,
1044210434 tpenv))
1044310435
0 commit comments