@@ -3439,15 +3439,15 @@ and TryInlineApplication cenv env finfo (valExpr: Expr) (tyargs: TType list, arg
34393439 let argsR = args |> List.map ( OptimizeExpr cenv env >> fst)
34403440 let info = { TotalSize = 1 ; FunctionSize = 1 ; HasEffect = true ; MightMakeCriticalTailcall = false ; Info = UnknownValue }
34413441
3442- let canCallDirectly =
3443- let hasNoTraits =
3444- let tps , _ = tryDestForallTy g vref.Type
3445- GetTraitConstraintInfosOfTypars g tps |> List.isEmpty
3442+ let hasNoTraits =
3443+ let tps , _ = tryDestForallTy g vref.Type
3444+ GetTraitConstraintInfosOfTypars g tps |> List.isEmpty
34463445
3447- let hasNoFreeTyargs =
3448- tyargs |> List.forall ( fun t -> ( freeInType CollectTyparsNoCaching t) .FreeTypars.IsEmpty) |> not
3446+ let allTyargsAreConcrete =
3447+ tyargs |> List.forall ( fun t -> ( freeInType CollectTyparsNoCaching t) .FreeTypars.IsEmpty)
34493448
3450- hasNoTraits || hasNoFreeTyargs
3449+ let canCallDirectly =
3450+ hasNoTraits || ( not allTyargsAreConcrete && vref.ValReprInfo.IsSome)
34513451
34523452 if canCallDirectly then
34533453 Some( mkApps g (( exprForValRef m vref, vref.Type), [ tyargs], argsR, m), info)
@@ -3457,17 +3457,27 @@ and TryInlineApplication cenv env finfo (valExpr: Expr) (tyargs: TType list, arg
34573457 let specLambdaTy = tyOfExpr g specLambda
34583458
34593459 let specLambdaR =
3460- match cenv.specializedInlineVals.FindAll( origLambdaId) |> List.tryFind ( fun ( ty , _ ) -> typeEquiv g ty specLambdaTy) with
3461- | Some (_, body) -> copyExpr g CloneAll body
3462- | None ->
3463-
3464- let specLambdaR , _ = OptimizeExpr cenv { env with dontInline = Zset.add origLambdaId env.dontInline } specLambda
3465- cenv.specializedInlineVals.Add( origLambdaId, ( specLambdaTy, specLambdaR))
3466- specLambdaR
3460+ if allTyargsAreConcrete then
3461+ match cenv.specializedInlineVals.FindAll( origLambdaId) |> List.tryFind ( fun ( ty , _ ) -> typeEquiv g ty specLambdaTy) with
3462+ | Some (_, body) -> copyExpr g CloneAll body
3463+ | None ->
3464+
3465+ let specLambdaR , _ = OptimizeExpr cenv { env with dontInline = Zset.add origLambdaId env.dontInline } specLambda
3466+ cenv.specializedInlineVals.Add( origLambdaId, ( specLambdaTy, specLambdaR))
3467+ specLambdaR
3468+ else
3469+ let specLambdaR , _ = OptimizeExpr cenv { env with dontInline = Zset.add origLambdaId env.dontInline } specLambda
3470+ specLambdaR
34673471
34683472 let debugVal =
34693473 let name = $" <{vref.LogicalName}>__debug"
3470- let valReprInfo = Some( InferValReprInfoOfExpr g AllowTypeDirectedDetupling.No specLambdaTy [] [] specLambdaR)
3474+ // When tyargs have free type variables, omit ValReprInfo so IlxGen compiles this
3475+ // as a closure that captures type variables and witnesses from the enclosing scope.
3476+ let valReprInfo =
3477+ if allTyargsAreConcrete then
3478+ Some( InferValReprInfoOfExpr g AllowTypeDirectedDetupling.No specLambdaTy [] [] specLambdaR)
3479+ else
3480+ None
34713481
34723482 Construct.NewVal( name, m, None, specLambdaTy, Immutable, true , valReprInfo, taccessPublic, ValNotInRecScope, None,
34733483 NormalVal, [], ValInline.InlinedDefinition, XmlDoc.Empty, false , false , false , false , false , false , None,
0 commit comments