@@ -955,8 +955,12 @@ let AdjustValSynInfoInSignature g ty (SynValInfo(argsData, retData) as sigMD) =
955955 | _ ->
956956 sigMD
957957
958+ let getArgInfoCache =
959+ let options = Caches.CacheOptions.getDefault() |> Caches.CacheOptions.withNoEviction
960+ let factory _ = new Caches.Cache<_, ArgReprInfo>(options, "argInfoCache")
961+ WeakMap.getOrCreate factory
958962
959- let TranslateTopArgSynInfo ( cenv: cenv) isArg m tcAttributes (SynArgInfo(Attributes attrs, isOpt, nm)) =
963+ let TranslateTopArgSynInfo cenv isArg m tcAttributes (SynArgInfo(Attributes attrs, isOpt, nm)) =
960964 // Synthesize an artificial "OptionalArgument" attribute for the parameter
961965 let optAttrs =
962966 if isOpt then
@@ -977,20 +981,14 @@ let TranslateTopArgSynInfo (cenv: cenv) isArg m tcAttributes (SynArgInfo(Attribu
977981 // Call the attribute checking function
978982 let attribs = tcAttributes (optAttrs@attrs)
979983
980- let key = nm |> Option.map (fun id -> id.idText, id.idRange)
984+ let key = nm |> Option.map (fun id -> (id.idText, id.idRange))
985+
986+ let mkDefaultArgInfo _ : ArgReprInfo = { Attribs = attribs; Name = nm; OtherRange = None }
981987
982988 let argInfo =
983- key
984- |> Option.map cenv.argInfoCache.TryGetValue
985- |> Option.bind (fun (found, info) ->
986- if found then
987- Some info
988- else None)
989- |> Option.defaultValue ({ Attribs = attribs; Name = nm; OtherRange = None }: ArgReprInfo)
990-
991- match key with
992- | Some k -> cenv.argInfoCache.[k] <- argInfo
993- | None -> ()
989+ match key with
990+ | Some key -> (getArgInfoCache cenv).GetOrAdd(key, mkDefaultArgInfo)
991+ | _ -> mkDefaultArgInfo ()
994992
995993 // Set freshly computed attribs in case they are different in the cache
996994 argInfo.Attribs <- attribs
@@ -4051,6 +4049,13 @@ type ImplicitlyBoundTyparsAllowed =
40514049 | NewTyparsOK
40524050 | NoNewTypars
40534051
4052+ // In order to avoid checking implicit-yield expressions multiple times, we cache the resulting checked expressions.
4053+ // This avoids exponential behavior in the type checker when nesting implicit-yield expressions.
4054+ let getImplicitYieldExpressionsCache =
4055+ let options = Caches.CacheOptions.getReferenceIdentity() |> Caches.CacheOptions.withNoEviction
4056+ let factory _ = new Caches.Cache<SynExpr, _>(options, "implicitYieldExpressions")
4057+ WeakMap.getOrCreate factory
4058+
40544059//-------------------------------------------------------------------------
40554060// Checking types and type constraints
40564061//-------------------------------------------------------------------------
@@ -5503,19 +5508,12 @@ and CheckForAdjacentListExpression (cenv: cenv) synExpr hpa isInfix delayed (arg
55035508and TcExprThen (cenv: cenv) overallTy env tpenv isArg synExpr delayed =
55045509 let g = cenv.g
55055510
5506- let cachedExpression =
5507- env.eCachedImplicitYieldExpressions.FindAll synExpr.Range
5508- |> List.tryPick (fun (se, ty, e) ->
5509- if obj.ReferenceEquals(se, synExpr) then Some (ty, e) else None
5510- )
5511-
5512- match cachedExpression with
5513- | Some (ty, expr) ->
5511+ match (getImplicitYieldExpressionsCache cenv).TryGetValue synExpr with
5512+ | true, (ty, expr) ->
55145513 UnifyOverallType cenv env synExpr.Range overallTy ty
55155514 expr, tpenv
55165515 | _ ->
55175516
5518-
55195517 match synExpr with
55205518
55215519 // A.
@@ -6378,9 +6376,8 @@ and TcExprSequentialOrImplicitYield (cenv: cenv) overallTy env tpenv (sp, synExp
63786376 | Expr.DebugPoint(_,e) -> e
63796377 | _ -> expr1
63806378
6381- env.eCachedImplicitYieldExpressions.Add(synExpr1.Range, (synExpr1, expr1Ty, cachedExpr))
6382- try TcExpr cenv overallTy env tpenv otherExpr
6383- finally env.eCachedImplicitYieldExpressions.Remove synExpr1.Range
6379+ (getImplicitYieldExpressionsCache cenv).AddOrUpdate(synExpr1, (expr1Ty, cachedExpr))
6380+ TcExpr cenv overallTy env tpenv otherExpr
63846381
63856382and TcExprStaticOptimization (cenv: cenv) overallTy env tpenv (constraints, synExpr2, expr3, m) =
63866383 let constraintsR, tpenv = List.mapFold (TcStaticOptimizationConstraint cenv env) tpenv constraints
0 commit comments