@@ -438,6 +438,8 @@ type cenv =
438438 realsig: bool
439439
440440 specializedInlineVals: HashMultiMap < Stamp , TType * Expr >
441+
442+ signatureHidingInfo: SignatureHidingInfo
441443 }
442444
443445 override x.ToString () = " <cenv>"
@@ -3459,8 +3461,14 @@ and TryInlineApplication cenv env finfo (valExpr: Expr) (tyargs: TType list, arg
34593461 let allTyargsAreGeneric =
34603462 tyargs |> List.forall ( fun t -> not ( freeInType CollectTyparsNoCaching t) .FreeTypars.IsEmpty)
34613463
3464+ // When inside an inline function body being prepared for export (!cenv.optimizing),
3465+ // only emit a direct call if the callee is publicly accessible. Non-public vals
3466+ // (e.g. in internal modules, or hidden by .fsi) can't be called by consumers,
3467+ // so route those through the specialization path which inlines the body.
3468+ let isHiddenBySignature = cenv.signatureHidingInfo.HiddenVals.Contains vref.Deref
34623469 let canCallDirectly =
3463- hasNoTraits || ( allTyargsAreGeneric && vref.ValReprInfo.IsSome)
3470+ ( cenv.optimizing || ( vref.Accessibility.IsPublic && not isHiddenBySignature)) &&
3471+ ( hasNoTraits || ( allTyargsAreGeneric && vref.ValReprInfo.IsSome))
34643472
34653473 let argsR = args |> List.map ( OptimizeExpr cenv env >> fst)
34663474 let info = { TotalSize = 1 ; FunctionSize = 1 ; HasEffect = true ; MightMakeCriticalTailcall = false ; Info = UnknownValue }
@@ -4324,17 +4332,23 @@ and OptimizeBindings cenv isRec env xs =
43244332
43254333and OptimizeModuleExprWithSig cenv env mty def =
43264334 let g = cenv.g
4327- // Optimize the module implementation
4328- let ( def , info ), ( _env , bindInfosColl ) = OptimizeModuleContents cenv ( env, []) def
4329- let bindInfosColl = List.concat bindInfosColl
4330-
4335+
43314336 // Compute the elements truly hidden by the module signature.
43324337 // The hidden set here must contain NOT MORE THAN the set of values made inaccessible by
43334338 // the application of the signature. If it contains extra elements we'll accidentally eliminate
43344339 // bindings.
4335-
4340+ // This only walks structural elements (Val/Entity declarations), not expressions,
4341+ // so it gives the same result before and after optimization.
43364342 let _renaming , hidden as rpi = ComputeRemappingFromImplementationToSignature g def mty
43374343
4344+ // Make hiding info available during optimization so TryInlineApplication
4345+ // can avoid emitting direct calls to vals hidden by signature.
4346+ let cenv = { cenv with signatureHidingInfo = hidden }
4347+
4348+ // Optimize the module implementation
4349+ let ( def , info ), ( _env , bindInfosColl ) = OptimizeModuleContents cenv ( env, []) def
4350+ let bindInfosColl = List.concat bindInfosColl
4351+
43384352 let def =
43394353 if not cenv.settings.LocalOptimizationsEnabled then def else
43404354
@@ -4500,6 +4514,7 @@ let OptimizeImplFile (settings, ccu, tcGlobals, tcVal, importMap, optEnv, isIncr
45004514 stackGuard = StackGuard( " OptimizerStackGuardDepth" )
45014515 realsig = tcGlobals.realsig
45024516 specializedInlineVals = HashMultiMap( HashIdentity.Structural, true )
4517+ signatureHidingInfo = SignatureHidingInfo.Empty
45034518 }
45044519
45054520 let env , _ , _ , _ as results = OptimizeImplFileInternal cenv optEnv isIncrementalFragment hidden mimpls
0 commit comments