@@ -223,7 +223,9 @@ type cenv =
223223 mutable entryPointGiven: bool
224224
225225 /// Callback required for quotation generation
226- tcVal: ConstraintSolver .TcValF }
226+ tcVal: ConstraintSolver .TcValF
227+
228+ inlineBindingBodies: Dictionary < Stamp , Expr > }
227229
228230 override x.ToString () = " <cenv>"
229231
@@ -519,6 +521,9 @@ let AccessInternalsVisibleToAsInternal thisCompPath internalsVisibleToPaths acce
519521 ( access, internalsVisibleToPaths) ||> List.fold ( fun access internalsVisibleToPath ->
520522 accessSubstPaths ( thisCompPath, internalsVisibleToPath) access)
521523
524+ let isLessAccessibleWithVisibility ( cenv : cenv ) itemAccess refAccess =
525+ let thisCompPath = compPathOfCcu cenv.viewCcu
526+ isLessAccessible ( itemAccess |> AccessInternalsVisibleToAsInternal thisCompPath cenv.internalsVisibleToPaths) refAccess
522527
523528let CheckTypeForAccess ( cenv : cenv ) env objName valAcc m ty =
524529 if cenv.reportErrors then
@@ -529,9 +534,7 @@ let CheckTypeForAccess (cenv: cenv) env objName valAcc m ty =
529534 match tryTcrefOfAppTy cenv.g ty with
530535 | ValueNone -> ()
531536 | ValueSome tcref ->
532- let thisCompPath = compPathOfCcu cenv.viewCcu
533- let tyconAcc = tcref.Accessibility |> AccessInternalsVisibleToAsInternal thisCompPath cenv.internalsVisibleToPaths
534- if isLessAccessible tyconAcc valAcc then
537+ if isLessAccessibleWithVisibility cenv tcref.Accessibility valAcc then
535538 errorR( Error( FSComp.SR.chkTypeLessAccessibleThanType( tcref.DisplayName, objName()), m))
536539
537540 CheckTypeDeep cenv ( visitType, None, None, None, None) cenv.g env NoInfo ty
@@ -545,9 +548,7 @@ let WarnOnWrongTypeForAccess (cenv: cenv) env objName valAcc m ty =
545548 match tryTcrefOfAppTy cenv.g ty with
546549 | ValueNone -> ()
547550 | ValueSome tcref ->
548- let thisCompPath = compPathOfCcu cenv.viewCcu
549- let tyconAcc = tcref.Accessibility |> AccessInternalsVisibleToAsInternal thisCompPath cenv.internalsVisibleToPaths
550- if isLessAccessible tyconAcc valAcc then
551+ if isLessAccessibleWithVisibility cenv tcref.Accessibility valAcc then
551552 let errorText = FSComp.SR.chkTypeLessAccessibleThanType( tcref.DisplayName, objName()) |> snd
552553 let warningText = errorText + Environment.NewLine + FSComp.SR.tcTypeAbbreviationsCheckedAtCompileTime()
553554 warning( ObsoleteDiagnostic( false , None, Some warningText, None, m))
@@ -2081,6 +2082,29 @@ and AdjustAccess isHidden (cpath: unit -> CompilationPath) access =
20812082 else
20822083 access
20832084
2085+ // An 'inline' value is inlined into (possibly external) callers, so any function it references must be
2086+ // at least as accessible as the value itself (FS1113). Inline callees are followed transitively because
2087+ // the optimizer inlines them away; only module/member bindings can escape their scope.
2088+ and CheckInlineValueIsSufficientlyAccessible cenv env ( v : Val ) bindRhs =
2089+ if cenv.reportErrors && v.ShouldInline && not v.IsCompilerGenerated &&
2090+ ( v.IsMemberOrModuleBinding || v.IsMember) && not v.IsIncrClassGeneratedMember then
2091+ let inlineAcc =
2092+ AdjustAccess ( IsHiddenVal env.sigToImplRemapInfo v) ( fun () -> v.DeclaringEntity.CompilationPath) v.Accessibility
2093+ let visited = HashSet< Stamp>()
2094+ let rec escapes expr =
2095+ ( freeInExpr CollectLocals expr) .FreeLocals |> Zset.exists ( fun w ->
2096+ ( w.IsMemberOrModuleBinding || w.IsMember) &&
2097+ isLessAccessibleWithVisibility cenv w.Accessibility inlineAcc &&
2098+ ( if w.ShouldInline then
2099+ visited.Add w.Stamp &&
2100+ ( match cenv.inlineBindingBodies.TryGetValue w.Stamp with
2101+ | true , body -> escapes body
2102+ | _ -> false )
2103+ else
2104+ true ))
2105+ if escapes bindRhs then
2106+ errorR( Error( FSComp.SR.optValueMarkedInlineButIncomplete( v.DisplayName), v.Range))
2107+
20842108and CheckBinding cenv env alwaysCheckNoReraise ctxt ( TBind ( v , bindRhs , _ ) as bind ) : Limit =
20852109 let vref = mkLocalValRef v
20862110 let g = cenv.g
@@ -2113,6 +2137,8 @@ and CheckBinding cenv env alwaysCheckNoReraise ctxt (TBind(v, bindRhs, _) as bin
21132137 let access = AdjustAccess ( IsHiddenVal env.sigToImplRemapInfo v) ( fun () -> v.DeclaringEntity.CompilationPath) v.Accessibility
21142138 CheckTypeForAccess cenv env ( fun () -> NicePrint.stringOfQualifiedValOrMember cenv.denv cenv.infoReader vref) access v.Range v.Type
21152139
2140+ CheckInlineValueIsSufficientlyAccessible cenv env v bindRhs
2141+
21162142 if cenv.reportErrors then
21172143
21182144 // Check top-level let-bound values
@@ -2781,7 +2807,20 @@ let CheckImplFileContents cenv env implFileTy implFileContents =
27812807 UpdatePrettyTyparNames.updateModuleOrNamespaceType implFileTy
27822808 CheckDefnInModule cenv env implFileContents
27832809
2810+ let rec private collectInlineBindingBodies ( acc : Dictionary < Stamp , Expr >) mdef =
2811+ match mdef with
2812+ | TMDefRec( bindings = mbinds) ->
2813+ for mbind in mbinds do
2814+ match mbind with
2815+ | ModuleOrNamespaceBinding.Binding ( TBind( v, e, _)) -> if v.ShouldInline then acc[ v.Stamp] <- e
2816+ | ModuleOrNamespaceBinding.Module(_, def) -> collectInlineBindingBodies acc def
2817+ | TMDefLet( TBind( v, e, _), _) -> if v.ShouldInline then acc[ v.Stamp] <- e
2818+ | TMDefDo _ | TMDefOpens _ -> ()
2819+ | TMDefs defs -> for def in defs do collectInlineBindingBodies acc def
2820+
27842821let CheckImplFile ( g , amap , reportErrors , infoReader , internalsVisibleToPaths , viewCcu , tcValF , denv , implFileTy , implFileContents , extraAttribs , isLastCompiland : bool * bool , isInternalTestSpanStackReferring ) =
2822+ let inlineBindingBodies = Dictionary< Stamp, Expr>( HashIdentity.Structural)
2823+ collectInlineBindingBodies inlineBindingBodies implFileContents
27852824 let cenv =
27862825 { g = g
27872826 reportErrors = reportErrors
@@ -2799,7 +2838,8 @@ let CheckImplFile (g, amap, reportErrors, infoReader, internalsVisibleToPaths, v
27992838 isLastCompiland = isLastCompiland
28002839 isInternalTestSpanStackReferring = isInternalTestSpanStackReferring
28012840 tcVal = tcValF
2802- entryPointGiven = false }
2841+ entryPointGiven = false
2842+ inlineBindingBodies = inlineBindingBodies }
28032843
28042844 // Certain type equality checks go faster if these TyconRefs are pre-resolved.
28052845 // This is because pre-resolving allows tycon equality to be determined by pointer equality on the entities.
0 commit comments