From 6a04e7b35dbe0b969911e9ba4a77940ee5c3425d Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Fri, 3 Apr 2026 20:55:44 +0200 Subject: [PATCH 01/29] Optimizer: don't inline named functions in debug builds --- src/Compiler/CodeGen/IlxGen.fs | 4 + src/Compiler/Driver/CompilerConfig.fs | 4 + src/Compiler/Driver/CompilerConfig.fsi | 4 + src/Compiler/Driver/CompilerOptions.fs | 8 + src/Compiler/Driver/OptimizeInputs.fs | 4 + src/Compiler/FSComp.txt | 1 + src/Compiler/Optimize/Optimizer.fs | 68 ++- src/Compiler/Optimize/Optimizer.fsi | 2 + src/Compiler/Symbols/Symbols.fs | 2 +- src/Compiler/TypedTree/TypedTree.fs | 13 +- src/Compiler/TypedTree/TypedTree.fsi | 3 + .../EmittedIL/DebugInlineAsCall.fs | 414 ++++++++++++++++++ .../FSharp.Compiler.ComponentTests.fsproj | 1 + 13 files changed, 516 insertions(+), 12 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index 4e3452a2d8..1d990259e5 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -312,6 +312,7 @@ type cenv = /// Guard the stack and move to a new one if necessary mutable stackGuard: StackGuard + emittedSpecializedInlineVals: HashSet } member cenv.options = @@ -8567,6 +8568,8 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt = GenExpr cenv cgbuf eenv cctorBody discard | Method(valReprInfo, _, mspec, mspecW, _, ctps, mtps, curriedArgInfos, paramInfos, witnessInfos, argTys, retInfo) when not isStateVar -> + if vspec.InlineInfo = ValInline.InlinedDefinition && not (cenv.emittedSpecializedInlineVals.Add(vspec.Stamp)) then + CommitStartScope cgbuf startMarkOpt else let methLambdaTypars, methLambdaCtorThisValOpt, methLambdaBaseValOpt, methLambdaCurriedVars, methLambdaBody, methLambdaBodyTy = IteratedAdjustLambdaToMatchValReprInfo g cenv.amap valReprInfo rhsExpr @@ -12486,6 +12489,7 @@ type IlxAssemblyGenerator(amap: ImportMap, g: TcGlobals, tcVal: ConstraintSolver optimizeDuringCodeGen = (fun _flag expr -> expr) stackGuard = getEmptyStackGuard () delayedGenMethods = Queue() + emittedSpecializedInlineVals = HashSet() } /// Register a set of referenced assemblies with the ILX code generator diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index 0fbe48fb2e..6075a7a32a 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -600,6 +600,8 @@ type TcConfigBuilder = mutable strictIndentation: bool option + mutable inlineNamedFunctions: bool option + mutable exename: string option // If true - the compiler will copy FSharp.Core.dll along the produced binaries @@ -853,6 +855,7 @@ type TcConfigBuilder = dumpSignatureData = false realsig = false strictIndentation = None + inlineNamedFunctions = None compilationMode = TcGlobals.CompilationMode.Unset } @@ -1253,6 +1256,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) = member _.fsiMultiAssemblyEmit = data.fsiMultiAssemblyEmit member _.FxResolver = data.FxResolver member _.strictIndentation = data.strictIndentation + member _.inlineNamedFunctions = data.inlineNamedFunctions member _.primaryAssembly = data.primaryAssembly member _.noFeedback = data.noFeedback member _.stackReserveSize = data.stackReserveSize diff --git a/src/Compiler/Driver/CompilerConfig.fsi b/src/Compiler/Driver/CompilerConfig.fsi index 17e035109a..85ce24133a 100644 --- a/src/Compiler/Driver/CompilerConfig.fsi +++ b/src/Compiler/Driver/CompilerConfig.fsi @@ -472,6 +472,8 @@ type TcConfigBuilder = mutable strictIndentation: bool option + mutable inlineNamedFunctions: bool option + mutable exename: string option mutable copyFSharpCore: CopyFSharpCoreFlag @@ -814,6 +816,8 @@ type TcConfig = member strictIndentation: bool option + member inlineNamedFunctions: bool option + member GetTargetFrameworkDirectories: unit -> string list /// Get the loaded sources that exist and issue a warning for the ones that don't diff --git a/src/Compiler/Driver/CompilerOptions.fs b/src/Compiler/Driver/CompilerOptions.fs index 98cec17265..0ba0afb60c 100644 --- a/src/Compiler/Driver/CompilerOptions.fs +++ b/src/Compiler/Driver/CompilerOptions.fs @@ -1207,6 +1207,14 @@ let languageFlags tcConfigB = None, Some(FSComp.SR.optsStrictIndentation (formatOptionSwitch (Option.defaultValue false tcConfigB.strictIndentation))) ) + + CompilerOption( + "inline-named-functions", + tagNone, + OptionSwitch(fun switch -> tcConfigB.inlineNamedFunctions <- Some(switch = OptionSwitch.On)), + None, + Some(FSComp.SR.optsInlineNamedFunctions ()) + ) ] // OptionBlock: Advanced user options diff --git a/src/Compiler/Driver/OptimizeInputs.fs b/src/Compiler/Driver/OptimizeInputs.fs index 78bca4bf97..cace428af4 100644 --- a/src/Compiler/Driver/OptimizeInputs.fs +++ b/src/Compiler/Driver/OptimizeInputs.fs @@ -327,6 +327,9 @@ let ApplyAllOptimizations // Only do abstractBigTargets in the first phase, and only when TLR is on. abstractBigTargets = tcConfig.doTLR reportingPhase = true + inlineNamedFunctions = + tcConfig.inlineNamedFunctions + |> Option.defaultValue (not tcConfig.debuginfo || tcConfig.optSettings.LocalOptimizationsEnabled) } // Only do these two steps in the first phase. @@ -334,6 +337,7 @@ let ApplyAllOptimizations { firstLoopSettings with abstractBigTargets = false reportingPhase = false + inlineNamedFunctions = false } let addPhaseDiagnostics (f: PhaseFunc) (info: Phase) = diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index a4007147b9..cc05986e2e 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1560,6 +1560,7 @@ optsSetLangVersion,"Specify language version such as 'latest' or 'preview'." optsDisableLanguageFeature,"Disable a specific language feature by name." optsSupportedLangVersions,"Supported language versions:" optsStrictIndentation,"Override indentation rules implied by the language version (%s by default)" +optsInlineNamedFunctions,"Inline named 'inline' functions" nativeResourceFormatError,"Stream does not begin with a null resource and is not in '.RES' format." nativeResourceHeaderMalformed,"Resource header beginning at offset %s is malformed." formatDashItem," - %s" diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs index 3cbb574598..8026cc54b9 100644 --- a/src/Compiler/Optimize/Optimizer.fs +++ b/src/Compiler/Optimize/Optimizer.fs @@ -23,6 +23,7 @@ open FSharp.Compiler.Text.LayoutRender open FSharp.Compiler.Text.TaggedText open FSharp.Compiler.TypedTree open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.Xml open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.TypedTreeOps.DebugPrint open FSharp.Compiler.TypedTreePickle @@ -327,6 +328,8 @@ type OptimizationSettings = reportTotalSizes : bool processingMode : OptimizationProcessingMode + + inlineNamedFunctions: bool } static member Defaults = @@ -344,6 +347,7 @@ type OptimizationSettings = reportHasEffect = false reportTotalSizes = false processingMode = OptimizationProcessingMode.Parallel + inlineNamedFunctions = false } /// Determines if JIT optimizations are enabled @@ -432,6 +436,8 @@ type cenv = stackGuard: StackGuard realsig: bool + + specializedInlineVals: HashMultiMap } override x.ToString() = "" @@ -1692,6 +1698,7 @@ let TryEliminateBinding cenv _env bind e2 _m = not vspec1.IsCompilerGenerated then None elif vspec1.IsFixed then None + elif vspec1.InlineInfo = ValInline.InlinedDefinition then None elif vspec1.LogicalName.StartsWithOrdinal stackVarPrefix || vspec1.LogicalName.Contains suffixForVariablesThatMayNotBeEliminated then None else @@ -3421,8 +3428,60 @@ and TryDevirtualizeApplication cenv env (f, tyargs, args, m) = | _ -> None /// Attempt to inline an application of a known value at callsites -and TryInlineApplication cenv env finfo (tyargs: TType list, args: Expr list, m) = +and TryInlineApplication cenv env finfo (valExpr: Expr) (tyargs: TType list, args: Expr list, m) = let g = cenv.g + + match cenv.settings.inlineNamedFunctions, stripExpr valExpr with + | false, Expr.Val(vref, _, _) when vref.ShouldInline -> + let origFinfo = GetInfoForValWithCheck cenv env m vref + match stripValue origFinfo.ValExprInfo with + | CurriedLambdaValue(origLambdaId, _, _, origLambda, origLambdaTy) when not (Zset.contains origLambdaId env.dontInline) -> + let argsR = args |> List.map (OptimizeExpr cenv env >> fst) + let info = { TotalSize = 1; FunctionSize = 1; HasEffect = true; MightMakeCriticalTailcall = false; Info = UnknownValue } + + let canCallDirectly = + let hasNoTraits = + match vref.ValReprInfo with + | Some reprInfo -> + let tps, _, _, _ = GetValReprTypeInFSharpForm g reprInfo vref.Type m + GetTraitWitnessInfosOfTypars g 0 tps |> List.isEmpty + | None -> false + + let hasNoFreeTyargs = + tyargs |> List.forall (fun t -> (freeInType CollectTyparsNoCaching t).FreeTypars.IsEmpty) |> not + + hasNoTraits || hasNoFreeTyargs + + if canCallDirectly then + Some(mkApps g ((exprForValRef m vref, vref.Type), [tyargs], argsR, m), info) + else + let f2R = CopyExprForInlining cenv true origLambda m + let specLambda = MakeApplicationAndBetaReduce g (f2R, origLambdaTy, [tyargs], [], m) + let specLambdaTy = tyOfExpr g specLambda + + let debugVal, specLambdaR = + match cenv.specializedInlineVals.FindAll(origLambdaId) |> List.tryFind (fun (ty, _, _) -> typeEquiv g ty specLambdaTy) with + | Some (_, v, body) -> v, body + | None -> + + let specLambdaR, _ = OptimizeExpr cenv { env with dontInline = Zset.add origLambdaId env.dontInline } specLambda + let debugVal = + let name = $"<{vref.LogicalName}>__debug" + let valReprInfo = Some(InferValReprInfoOfExpr g AllowTypeDirectedDetupling.No specLambdaTy [] [] specLambdaR) + + Construct.NewVal(name, m, None, specLambdaTy, Immutable, true, valReprInfo, taccessPublic, ValNotInRecScope, None, + NormalVal, [], ValInline.InlinedDefinition, XmlDoc.Empty, false, false, false, false, false, false, None, + ParentNone) + + cenv.specializedInlineVals.Add(origLambdaId, (specLambdaTy, debugVal, specLambdaR)) + debugVal, specLambdaR + + let callExpr = mkApps g ((exprForVal m debugVal, specLambdaTy), [], argsR, m) + Some(mkCompGenLet m debugVal specLambdaR callExpr, info) + + | _ -> None + | _ -> + // Considering inlining app match finfo.Info with | StripLambdaValue (lambdaId, arities, size, f2, f2ty) when @@ -3621,7 +3680,7 @@ and OptimizeApplication cenv env (f0, f0ty, tyargs, args, m) = OptimizeExpr cenv env remade | Choice2Of2 (newf0, remake) -> - match TryInlineApplication cenv env finfo (tyargs, args, m) with + match TryInlineApplication cenv env finfo f0 (tyargs, args, m) with | Some (res, info) -> // inlined (res |> remake), info @@ -3869,6 +3928,10 @@ and OptimizeLambdas (vspec: Val option) cenv env valReprInfo expr exprTy = // can't inline any values with semi-recursive object references to self or base let value_ = + match vspec with + | Some v when v.InlineInfo = ValInline.InlinedDefinition -> UnknownValue + | _ -> + match baseValOpt with | None -> CurriedLambdaValue (lambdaId, arities, bsize, exprR, exprTy) | Some baseVal -> @@ -4403,6 +4466,7 @@ let OptimizeImplFile (settings, ccu, tcGlobals, tcVal, importMap, optEnv, isIncr casApplied=Dictionary() stackGuard = StackGuard("OptimizerStackGuardDepth") realsig = tcGlobals.realsig + specializedInlineVals = HashMultiMap(HashIdentity.Structural, true) } let env, _, _, _ as results = OptimizeImplFileInternal cenv optEnv isIncrementalFragment hidden mimpls diff --git a/src/Compiler/Optimize/Optimizer.fsi b/src/Compiler/Optimize/Optimizer.fsi index 17912af759..10335e93a6 100644 --- a/src/Compiler/Optimize/Optimizer.fsi +++ b/src/Compiler/Optimize/Optimizer.fsi @@ -51,6 +51,8 @@ type OptimizationSettings = reportTotalSizes: bool processingMode: OptimizationProcessingMode + + inlineNamedFunctions: bool } member JitOptimizationsEnabled: bool diff --git a/src/Compiler/Symbols/Symbols.fs b/src/Compiler/Symbols/Symbols.fs index 08252dd76d..6348ec6464 100644 --- a/src/Compiler/Symbols/Symbols.fs +++ b/src/Compiler/Symbols/Symbols.fs @@ -1857,7 +1857,7 @@ type FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = match v.InlineInfo with | ValInline.Always -> FSharpInlineAnnotation.AlwaysInline | ValInline.Optional -> FSharpInlineAnnotation.OptionalInline - | ValInline.Never -> FSharpInlineAnnotation.NeverInline + | ValInline.Never | ValInline.InlinedDefinition -> FSharpInlineAnnotation.NeverInline member _.IsMutable = if isUnresolved() then false else diff --git a/src/Compiler/TypedTree/TypedTree.fs b/src/Compiler/TypedTree/TypedTree.fs index 995071138b..8a2f6f2840 100644 --- a/src/Compiler/TypedTree/TypedTree.fs +++ b/src/Compiler/TypedTree/TypedTree.fs @@ -41,21 +41,15 @@ type StampMap<'T> = Map [] type ValInline = - - /// Indicates the value is inlined but the .NET IL code for the function still exists, e.g. to satisfy interfaces on objects, but that it is also always inlined | Always - - /// Indicates the value may optionally be inlined by the optimizer | Optional - - /// Indicates the value must never be inlined by the optimizer | Never + | InlinedDefinition - /// Returns true if the implementation of a value should be inlined member x.ShouldInline = match x with | ValInline.Always -> true - | ValInline.Optional | ValInline.Never -> false + | ValInline.Optional | ValInline.Never | ValInline.InlinedDefinition -> false /// A flag associated with values that indicates whether the recursive scope of the value is currently being processed, and /// if the value has been generalized or not as yet. @@ -110,6 +104,7 @@ type ValFlags(flags: int64) = (if isCompGen then 0b00000000000000001000L else 0b000000000000000000000L) ||| (match inlineInfo with + | ValInline.InlinedDefinition -> 0b00000000000000000000L | ValInline.Always -> 0b00000000000000010000L | ValInline.Optional -> 0b00000000000000100000L | ValInline.Never -> 0b00000000000000110000L) ||| @@ -166,7 +161,7 @@ type ValFlags(flags: int64) = member x.InlineInfo = match (flags &&& 0b00000000000000110000L) with - | 0b00000000000000000000L + | 0b00000000000000000000L -> ValInline.InlinedDefinition | 0b00000000000000010000L -> ValInline.Always | 0b00000000000000100000L -> ValInline.Optional | 0b00000000000000110000L -> ValInline.Never diff --git a/src/Compiler/TypedTree/TypedTree.fsi b/src/Compiler/TypedTree/TypedTree.fsi index 0cd4bfd230..3c317425c1 100644 --- a/src/Compiler/TypedTree/TypedTree.fsi +++ b/src/Compiler/TypedTree/TypedTree.fsi @@ -41,6 +41,9 @@ type ValInline = /// Indicates the value must never be inlined by the optimizer | Never + /// Indicates a debug-only value produced from inlining an 'inline' function definition. + | InlinedDefinition + /// Returns true if the implementation of a value must always be inlined member ShouldInline: bool diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs new file mode 100644 index 0000000000..94fb1c79a4 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs @@ -0,0 +1,414 @@ +namespace EmittedIL + +open Xunit +open FSharp.Test.Compiler + +module DebugInlineAsCall = + + [] + let ``Call 01 - Release`` () = + FSharp """ +let inline f (x: int) = + x + x + +let i = f 5 +""" + |> asExe + |> compile + |> verifyILContains ["ldc.i4.s 10"] + |> shouldSucceed + + [] + let ``Call 02 - Debug`` () = + FSharp """ +let inline f (x: int) = + x + x + +[] +let main _ = + let i = f 5 + if i = 10 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains ["call int32 Test::f(int32)"] + |> shouldSucceed + + [] + let ``Call 03 - Two args`` () = + FSharp """ + +let inline add a b = + a + b + +[] +let main _ = + let i = add 1 2 + if i = 3 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains ["call int32 Test::'__debug@8'(int32,"] + |> shouldSucceed + + [] + let ``Call 04 - Function arg`` () = + FSharp """ +let inline apply (f: 'a -> 'b -> 'c) (x: 'a) (y: 'b) : 'c = + f x y + +[] +let main _ = + let i = apply (+) 3 4 + if i = 7 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains ["call !!2 Test::apply(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,"] + |> shouldSucceed + + + [] + let ``Call 05 - Nested inline`` () = + FSharp """ +let inline double (x: int) = + x + x + +let inline quadruple (x: int) = + double (double x) + +[] +let main _ = + let i = quadruple 3 + if i = 12 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains + ["call int32 Test::double(int32)" + "call int32 Test::quadruple(int32)"] + |> shouldSucceed + + [] + let ``Call 06 - Multiple calls`` () = + FSharp """ +let inline double (x: int) = + x + x + +[] +let main _ = + let i = double 1 + double 2 + if i = 6 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains [ "call int32 Test::double(int32)" ] + + [] + let ``Call 07 - Local function`` () = + FSharp """ +[] +let main _ = + let inline double (x: int) = x + x + let i = double 5 + if i = 10 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains ["call int32 Test::'__debug@5'(int32)"] + |> shouldSucceed + + [] + let ``Call 08 - Local generic function`` () = + FSharp """ +[] +let main _ = + let inline apply (f: 'a -> 'b) (x: 'a) : 'b = f x + let i = apply (fun x -> x + 1) 5 + if i = 6 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains ["call int32 Test::'__debug@5'(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,"] + |> shouldSucceed + + [] + let ``Call 09 - FSharp.Core not`` () = + FSharp """ +[] +let main _ = + let b = not true + if b = false then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains ["call bool [FSharp.Core]Microsoft.FSharp.Core.Operators::Not(bool)"] + |> shouldSucceed + + [] + let ``Call 10 - Different assembly`` () = + let library = + FSharp """ +module MyLib + +let inline triple (x: int) = x + x + x +""" + |> withDebug + |> withNoOptimize + |> asLibrary + |> withName "mylib" + + FSharp """ +open MyLib + +[] +let main _ = + let i = triple 3 + if i = 9 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> withReferences [library] + |> asExe + |> compileAndRun + |> verifyILContains ["call int32 [mylib]MyLib::triple(int32)"] + |> shouldSucceed + + [] + let ``Call 11 - Measure`` () = + FSharp """ +[] type cm + +let inline scale (x: float<'u>) = x * 2.0 + +[] +let main _ = + let v = scale 5.0 + if v = 10.0 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains ["call float64 Test::scale(float64)"] + |> shouldSucceed + + [] + let ``Call 12 - No inner optimization`` () = + FSharp """ +[] +let main _ = + let inline f (x: int) = + let i = 5 + 10 + x + i + + let i = f 20 + if i = 35 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains + [ "ldc.i4.5" + "ldc.i4.s 10" + "call int32 Test::'__debug@8'(int32)" ] + |> shouldSucceed + + [] + let ``SRTP 01`` () = + FSharp """ +let inline add (x: ^T) (y: ^T) = + x + y + +[] +let main _ = + let i = add 3 4 + if i = 7 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains ["call int32 Test::'__debug@7'(int32,"] + |> shouldSucceed + + [] + let ``SRTP 02 - Local `` () = + FSharp """ +[] +let main _ = + let inline add (x: ^T) (y: ^T) = x + y + let i = add 3 4 + if i = 7 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains ["call int32 Test::'__debug@5'(int32,"] + |> shouldSucceed + + [] + let ``SRTP 03 - Different type arguments`` () = + FSharp """ +let inline getLength (x: ^T) = + (^T : (member Length : int) x) + +[] +let main _ = + let i = getLength "hello" + let j = getLength [1; 2; 3] + if i = 5 && j = 3 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains + [ "call int32 Test::'__debug@7'(string)" + "call int32 Test::'__debug@8-1'(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1)" ] + |> shouldSucceed + + [] + let ``SRTP 04 - Multiple calls`` () = + FSharp """ +let inline add (x: ^T) (y: ^T) = x + y + +[] +let main _ = + let i = add 1 2 + add 3 4 + if i = 10 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains [ "call int32 Test::'__debug@6'(int32," ] + |> shouldSucceed + + + [] + let ``SRTP 05 - Different assembly`` () = + let library = + FSharp """ +module MyLib + +let inline add (x: ^T) (y: ^T) = x + y +""" + |> withDebug + |> withNoOptimize + |> asLibrary + |> withName "mylib2" + + FSharp """ +open MyLib + +[] +let main _ = + let i = add 3 4 + if i = 7 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> withReferences [library] + |> asExe + |> compileAndRun + |> verifyILContains ["call int32 Test::'__debug@6'(int32,"] + |> shouldSucceed + + [] + let ``SRTP 06 - Different assembly`` () = + let library = + FSharp """ +module MyLib + +let inline add (x: ^T) (y: ^T) = x + y +""" + |> withDebug + |> withNoOptimize + |> asLibrary + |> withName "mylib3" + + FSharp """ +open MyLib + +let inline double (x: ^T) = add x x + +[] +let main _ = + let i = double 5 + if i = 10 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> withReferences [library] + |> asExe + |> compileAndRun + |> verifyILContains + [ "call int32 Test::'__debug@8'(int32)" + "call int32 Test::'__debug@4'(int32," ] + |> shouldSucceed + + [] + let ``SRTP 07 - Nested - Same project`` () = + FSharp """ +let inline add (x: ^T) (y: ^T) = x + y + +let inline double (x: ^T) = add x x + +[] +let main _ = + let i = double 5 + if i = 10 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains + [ "call int32 Test::'__debug@8'(int32)" + "call int32 Test::'__debug@4'(int32," ] + |> shouldSucceed + + + + [] + let ``SRTP 08 - Nested - Different type arguments`` () = + FSharp """ +let inline add (x: ^T) (y: ^T) = x + y + +let inline addBoth (x: ^A) (y: ^B) = + let a = add x x + let b = add y y + (a, b) + +[] +let main _ = + let (a, b) = addBoth 2 3.0 + if a = 4 && b = 6.0 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains + [ "call int32 Test::'__debug@5'(int32," + "call float64 Test::'__debug@6-1'(float64," ] + |> shouldSucceed diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index f5d1048408..0a891f7dfd 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -227,6 +227,7 @@ + From 0054ff16cc2da865df212e2631bce15989c38d94 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Tue, 7 Apr 2026 15:09:05 +0200 Subject: [PATCH 02/29] Xlf --- src/Compiler/xlf/FSComp.txt.cs.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.de.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.es.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.fr.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.it.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.ja.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.ko.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.pl.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.ru.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.tr.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 9 +++++++-- 13 files changed, 91 insertions(+), 26 deletions(-) diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 6896c33a6a..4cd898ee34 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -1032,6 +1032,11 @@ Zobrazí povolené hodnoty pro jazykovou verzi. + + Inline named 'inline' functions + Inline named 'inline' functions + + Invalid use of emitting a reference assembly, do not use '--standalone or --staticlink' with '--refonly or --refout'. Neplatné použití generování referenčního sestavení, nepoužívejte --standalone ani --staticlink s --refonly nebo --refout. @@ -8952,12 +8957,12 @@ Rozšíření správce závislostí {0} nešlo načíst. Zpráva: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 3966a59a85..95d6c30cfb 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -1032,6 +1032,11 @@ Anzeigen der zulässigen Werte für die Sprachversion. + + Inline named 'inline' functions + Inline named 'inline' functions + + Invalid use of emitting a reference assembly, do not use '--standalone or --staticlink' with '--refonly or --refout'. Ungültige Verwendung der Ausgabe einer Referenzassembly. Verwenden Sie nicht „--standalone“ oder „--staticlink“ mit „--refonly“ oder „--refout“. @@ -8952,12 +8957,12 @@ Die Abhängigkeits-Manager-Erweiterung "{0}" konnte nicht geladen werden. Meldung: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 08828606dd..2b680093a7 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -1032,6 +1032,11 @@ Muestra los valores permitidos para la versión del lenguaje. + + Inline named 'inline' functions + Inline named 'inline' functions + + Invalid use of emitting a reference assembly, do not use '--standalone or --staticlink' with '--refonly or --refout'. Uso no válido de emisión de un ensamblado de referencia, no use '--standalone or --staticlink' con '--refonly or --refout'. @@ -8952,12 +8957,12 @@ No se pudo cargar la extensión del administrador de dependencias {0}. Mensaje: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 5a28ec1595..1995b80fcc 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -1032,6 +1032,11 @@ Affichez les valeurs autorisées pour la version du langage. + + Inline named 'inline' functions + Inline named 'inline' functions + + Invalid use of emitting a reference assembly, do not use '--standalone or --staticlink' with '--refonly or --refout'. Utilisation non valide de l’émission d’un assembly de référence, n’utilisez pas '--standalone ou --staticlink' avec '--refonly ou --refout'. @@ -8952,12 +8957,12 @@ Impossible de charger l'extension du gestionnaire de dépendances {0}. Message : {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 5dead052c6..ed72202e21 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -1032,6 +1032,11 @@ Visualizzare i valori consentiti per la versione della lingua. + + Inline named 'inline' functions + Inline named 'inline' functions + + Invalid use of emitting a reference assembly, do not use '--standalone or --staticlink' with '--refonly or --refout'. Utilizzo non valido della creazione di un assembly di riferimento. Non usare insieme '--standalone o --staticlink' con '--refonly o --refout'.. @@ -8952,12 +8957,12 @@ Non è stato possibile caricare l'estensione {0} di gestione delle dipendenze. Messaggio: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index f491fb0c4c..836f2b3fa8 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -1032,6 +1032,11 @@ 言語バージョンで許可されている値を表示します。 + + Inline named 'inline' functions + Inline named 'inline' functions + + Invalid use of emitting a reference assembly, do not use '--standalone or --staticlink' with '--refonly or --refout'. 参照アセンブリの出力の使用が無効です。'--standalone または --staticlink' を '--relabelly または --refout' と共に使用しないでください。 @@ -8952,12 +8957,12 @@ 依存関係マネージャーの拡張機能 {0} を読み込むことができませんでした。メッセージ: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index f8185fb2a2..5378e0c8b9 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -1032,6 +1032,11 @@ 언어 버전에 허용되는 값을 표시합니다. + + Inline named 'inline' functions + Inline named 'inline' functions + + Invalid use of emitting a reference assembly, do not use '--standalone or --staticlink' with '--refonly or --refout'. 참조 어셈블리 내보내기를 잘못 사용했습니다. '--refonly 또는 --refout'과 함께 '--standalone 또는 --staticlink'를 사용하지 마세요. @@ -8952,12 +8957,12 @@ 종속성 관리자 확장 {0}을(를) 로드할 수 없습니다. 메시지: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 7e81e135ee..c84c5bbf12 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -1032,6 +1032,11 @@ Wyświetl dozwolone wartości dla wersji językowej. + + Inline named 'inline' functions + Inline named 'inline' functions + + Invalid use of emitting a reference assembly, do not use '--standalone or --staticlink' with '--refonly or --refout'. Nieprawidłowe użycie emitowania zestawu odwołania. Nie używaj elementu „--standalone ani --staticlink” z elementem „--refonly lub --refout”. @@ -8952,12 +8957,12 @@ Nie można załadować rozszerzenia menedżera zależności {0}. Komunikat: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 22a5db4504..86ba8ffb2d 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -1032,6 +1032,11 @@ Exiba os valores permitidos para a versão do idioma. + + Inline named 'inline' functions + Inline named 'inline' functions + + Invalid use of emitting a reference assembly, do not use '--standalone or --staticlink' with '--refonly or --refout'. Uso inválido da emissão de um assembly de referência, não use '--standalone ou --staticlink' com '--refonly ou --refout'. @@ -8952,12 +8957,12 @@ Não foi possível carregar a extensão do gerenciador de dependências {0}. Mensagem: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 8f5220ba47..be60184841 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -1032,6 +1032,11 @@ Отображение допустимых значений для версии языка. + + Inline named 'inline' functions + Inline named 'inline' functions + + Invalid use of emitting a reference assembly, do not use '--standalone or --staticlink' with '--refonly or --refout'. Недопустимое использование при создании базовой сборки. Не используйте "--standalone or --staticlink" с "--refonly or --refout". @@ -8952,12 +8957,12 @@ Не удалось загрузить расширение диспетчера зависимостей {0}. Сообщение: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 1750982712..64a85b582f 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -1032,6 +1032,11 @@ Dil sürümü için izin verilen değerleri görüntüleyin. + + Inline named 'inline' functions + Inline named 'inline' functions + + Invalid use of emitting a reference assembly, do not use '--standalone or --staticlink' with '--refonly or --refout'. Başvuru bütünleştirilmiş kodu oluşturmanın geçersiz kullanımı; '--standalone’ veya ‘--staticlink' seçeneğini '--refonly’ veya ‘--refout' ile birlikte kullanmayın. @@ -8952,12 +8957,12 @@ {0} bağımlılık yöneticisi uzantısı yüklenemedi. İleti: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index bf26625f8e..6ccf9a7c77 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -1032,6 +1032,11 @@ 显示语言版本的允许值。 + + Inline named 'inline' functions + Inline named 'inline' functions + + Invalid use of emitting a reference assembly, do not use '--standalone or --staticlink' with '--refonly or --refout'. 发出引用程序集的使用无效,请勿将 '--standalone 或 --staticlink' 与 '--refonly 或 --refout' 一起使用。 @@ -8952,12 +8957,12 @@ 无法加载依赖项管理器扩展 {0}。消息: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 2a63e5ad75..360bfd1ede 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -1032,6 +1032,11 @@ 顯示語言版本的允許值。 + + Inline named 'inline' functions + Inline named 'inline' functions + + Invalid use of emitting a reference assembly, do not use '--standalone or --staticlink' with '--refonly or --refout'. 發出參考組件的使用無效,請勿同時使用 '--standalone 或 '--refonly' 和 '--refout'。 @@ -8952,12 +8957,12 @@ 無法載入相依性管理員延伸模組 {0}。訊息: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. From 257c702ca51daa808221dca2cebe21ef01b2327b Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Tue, 7 Apr 2026 15:11:35 +0200 Subject: [PATCH 03/29] Release notes --- docs/release-notes/.FSharp.Compiler.Service/11.0.100.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md index d5c2087765..7f91810e09 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -22,3 +22,4 @@ * Added warning FS3884 when a function or delegate value is used as an interpolated string argument. ([PR #19289](https://github.com/dotnet/fsharp/pull/19289)) * Add `#version;;` directive to F# Interactive to display version and environment information. ([Issue #13307](https://github.com/dotnet/fsharp/issues/13307), [PR #19332](https://github.com/dotnet/fsharp/pull/19332)) +* Optimizer: don't inline named functions in debug builds ([PR #19548](https://github.com/dotnet/fsharp/pull/19548) \ No newline at end of file From 193c36c836426fd727ac5dbcf6db4b14d903c44e Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Tue, 7 Apr 2026 16:37:54 +0200 Subject: [PATCH 04/29] Don't specialize local functions --- src/Compiler/Optimize/Optimizer.fs | 7 ++----- .../EmittedIL/DebugInlineAsCall.fs | 6 +++--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs index 8026cc54b9..226cfa76a5 100644 --- a/src/Compiler/Optimize/Optimizer.fs +++ b/src/Compiler/Optimize/Optimizer.fs @@ -3441,11 +3441,8 @@ and TryInlineApplication cenv env finfo (valExpr: Expr) (tyargs: TType list, arg let canCallDirectly = let hasNoTraits = - match vref.ValReprInfo with - | Some reprInfo -> - let tps, _, _, _ = GetValReprTypeInFSharpForm g reprInfo vref.Type m - GetTraitWitnessInfosOfTypars g 0 tps |> List.isEmpty - | None -> false + let tps, _ = tryDestForallTy g vref.Type + GetTraitConstraintInfosOfTypars g tps |> List.isEmpty let hasNoFreeTyargs = tyargs |> List.forall (fun t -> (freeInType CollectTyparsNoCaching t).FreeTypars.IsEmpty) |> not diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs index 94fb1c79a4..dea745e707 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs @@ -127,7 +127,7 @@ let main _ = |> withNoOptimize |> asExe |> compileAndRun - |> verifyILContains ["call int32 Test::'__debug@5'(int32)"] + |> verifyILContains ["callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0)"] |> shouldSucceed [] @@ -143,7 +143,7 @@ let main _ = |> withNoOptimize |> asExe |> compileAndRun - |> verifyILContains ["call int32 Test::'__debug@5'(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,"] + |> verifyILContains ["call !!0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,int32>::InvokeFast(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,"] |> shouldSucceed [] @@ -228,7 +228,7 @@ let main _ = |> verifyILContains [ "ldc.i4.5" "ldc.i4.s 10" - "call int32 Test::'__debug@8'(int32)" ] + "callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0)" ] |> shouldSucceed [] From d2298042213149934138be5db638036d4de730fd Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Tue, 7 Apr 2026 17:03:03 +0200 Subject: [PATCH 05/29] Remove specialized values caching --- src/Compiler/CodeGen/IlxGen.fs | 4 ---- src/Compiler/Optimize/Optimizer.fs | 24 +++++++++---------- .../EmittedIL/DebugInlineAsCall.fs | 4 +++- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index 1d990259e5..4e3452a2d8 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -312,7 +312,6 @@ type cenv = /// Guard the stack and move to a new one if necessary mutable stackGuard: StackGuard - emittedSpecializedInlineVals: HashSet } member cenv.options = @@ -8568,8 +8567,6 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt = GenExpr cenv cgbuf eenv cctorBody discard | Method(valReprInfo, _, mspec, mspecW, _, ctps, mtps, curriedArgInfos, paramInfos, witnessInfos, argTys, retInfo) when not isStateVar -> - if vspec.InlineInfo = ValInline.InlinedDefinition && not (cenv.emittedSpecializedInlineVals.Add(vspec.Stamp)) then - CommitStartScope cgbuf startMarkOpt else let methLambdaTypars, methLambdaCtorThisValOpt, methLambdaBaseValOpt, methLambdaCurriedVars, methLambdaBody, methLambdaBodyTy = IteratedAdjustLambdaToMatchValReprInfo g cenv.amap valReprInfo rhsExpr @@ -12489,7 +12486,6 @@ type IlxAssemblyGenerator(amap: ImportMap, g: TcGlobals, tcVal: ConstraintSolver optimizeDuringCodeGen = (fun _flag expr -> expr) stackGuard = getEmptyStackGuard () delayedGenMethods = Queue() - emittedSpecializedInlineVals = HashSet() } /// Register a set of referenced assemblies with the ILX code generator diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs index 226cfa76a5..5edc4dd37a 100644 --- a/src/Compiler/Optimize/Optimizer.fs +++ b/src/Compiler/Optimize/Optimizer.fs @@ -437,7 +437,7 @@ type cenv = realsig: bool - specializedInlineVals: HashMultiMap + specializedInlineVals: HashMultiMap } override x.ToString() = "" @@ -3456,22 +3456,22 @@ and TryInlineApplication cenv env finfo (valExpr: Expr) (tyargs: TType list, arg let specLambda = MakeApplicationAndBetaReduce g (f2R, origLambdaTy, [tyargs], [], m) let specLambdaTy = tyOfExpr g specLambda - let debugVal, specLambdaR = - match cenv.specializedInlineVals.FindAll(origLambdaId) |> List.tryFind (fun (ty, _, _) -> typeEquiv g ty specLambdaTy) with - | Some (_, v, body) -> v, body + let specLambdaR = + match cenv.specializedInlineVals.FindAll(origLambdaId) |> List.tryFind (fun (ty, _) -> typeEquiv g ty specLambdaTy) with + | Some (_, body) -> copyExpr g CloneAll body | None -> let specLambdaR, _ = OptimizeExpr cenv { env with dontInline = Zset.add origLambdaId env.dontInline } specLambda - let debugVal = - let name = $"<{vref.LogicalName}>__debug" - let valReprInfo = Some(InferValReprInfoOfExpr g AllowTypeDirectedDetupling.No specLambdaTy [] [] specLambdaR) + cenv.specializedInlineVals.Add(origLambdaId, (specLambdaTy, specLambdaR)) + specLambdaR - Construct.NewVal(name, m, None, specLambdaTy, Immutable, true, valReprInfo, taccessPublic, ValNotInRecScope, None, - NormalVal, [], ValInline.InlinedDefinition, XmlDoc.Empty, false, false, false, false, false, false, None, - ParentNone) + let debugVal = + let name = $"<{vref.LogicalName}>__debug" + let valReprInfo = Some(InferValReprInfoOfExpr g AllowTypeDirectedDetupling.No specLambdaTy [] [] specLambdaR) - cenv.specializedInlineVals.Add(origLambdaId, (specLambdaTy, debugVal, specLambdaR)) - debugVal, specLambdaR + Construct.NewVal(name, m, None, specLambdaTy, Immutable, true, valReprInfo, taccessPublic, ValNotInRecScope, None, + NormalVal, [], ValInline.InlinedDefinition, XmlDoc.Empty, false, false, false, false, false, false, None, + ParentNone) let callExpr = mkApps g ((exprForVal m debugVal, specLambdaTy), [], argsR, m) Some(mkCompGenLet m debugVal specLambdaR callExpr, info) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs index dea745e707..e85be18d47 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs @@ -300,7 +300,9 @@ let main _ = |> withNoOptimize |> asExe |> compileAndRun - |> verifyILContains [ "call int32 Test::'__debug@6'(int32," ] + |> verifyILContains + [ "call int32 Test::'__debug@6'(int32," + "call int32 Test::'__debug@6-1'(int32," ] |> shouldSucceed From a8491d1e90421b73885c7df107281c02bf7c4012 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Wed, 8 Apr 2026 16:20:46 +0200 Subject: [PATCH 06/29] Fix witness passing --- src/Compiler/Optimize/Optimizer.fs | 40 +++++++++++++++++++----------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs index 5edc4dd37a..b092fa4603 100644 --- a/src/Compiler/Optimize/Optimizer.fs +++ b/src/Compiler/Optimize/Optimizer.fs @@ -3439,15 +3439,15 @@ and TryInlineApplication cenv env finfo (valExpr: Expr) (tyargs: TType list, arg let argsR = args |> List.map (OptimizeExpr cenv env >> fst) let info = { TotalSize = 1; FunctionSize = 1; HasEffect = true; MightMakeCriticalTailcall = false; Info = UnknownValue } - let canCallDirectly = - let hasNoTraits = - let tps, _ = tryDestForallTy g vref.Type - GetTraitConstraintInfosOfTypars g tps |> List.isEmpty + let hasNoTraits = + let tps, _ = tryDestForallTy g vref.Type + GetTraitConstraintInfosOfTypars g tps |> List.isEmpty - let hasNoFreeTyargs = - tyargs |> List.forall (fun t -> (freeInType CollectTyparsNoCaching t).FreeTypars.IsEmpty) |> not + let allTyargsAreConcrete = + tyargs |> List.forall (fun t -> (freeInType CollectTyparsNoCaching t).FreeTypars.IsEmpty) - hasNoTraits || hasNoFreeTyargs + let canCallDirectly = + hasNoTraits || (not allTyargsAreConcrete && vref.ValReprInfo.IsSome) if canCallDirectly then 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 let specLambdaTy = tyOfExpr g specLambda let specLambdaR = - match cenv.specializedInlineVals.FindAll(origLambdaId) |> List.tryFind (fun (ty, _) -> typeEquiv g ty specLambdaTy) with - | Some (_, body) -> copyExpr g CloneAll body - | None -> - - let specLambdaR, _ = OptimizeExpr cenv { env with dontInline = Zset.add origLambdaId env.dontInline } specLambda - cenv.specializedInlineVals.Add(origLambdaId, (specLambdaTy, specLambdaR)) - specLambdaR + if allTyargsAreConcrete then + match cenv.specializedInlineVals.FindAll(origLambdaId) |> List.tryFind (fun (ty, _) -> typeEquiv g ty specLambdaTy) with + | Some (_, body) -> copyExpr g CloneAll body + | None -> + + let specLambdaR, _ = OptimizeExpr cenv { env with dontInline = Zset.add origLambdaId env.dontInline } specLambda + cenv.specializedInlineVals.Add(origLambdaId, (specLambdaTy, specLambdaR)) + specLambdaR + else + let specLambdaR, _ = OptimizeExpr cenv { env with dontInline = Zset.add origLambdaId env.dontInline } specLambda + specLambdaR let debugVal = let name = $"<{vref.LogicalName}>__debug" - let valReprInfo = Some(InferValReprInfoOfExpr g AllowTypeDirectedDetupling.No specLambdaTy [] [] specLambdaR) + // When tyargs have free type variables, omit ValReprInfo so IlxGen compiles this + // as a closure that captures type variables and witnesses from the enclosing scope. + let valReprInfo = + if allTyargsAreConcrete then + Some(InferValReprInfoOfExpr g AllowTypeDirectedDetupling.No specLambdaTy [] [] specLambdaR) + else + None Construct.NewVal(name, m, None, specLambdaTy, Immutable, true, valReprInfo, taccessPublic, ValNotInRecScope, None, NormalVal, [], ValInline.InlinedDefinition, XmlDoc.Empty, false, false, false, false, false, false, None, From 23d09eb7ae708ec2c9231d449395f4b2fde28354 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 9 Apr 2026 16:53:27 +0200 Subject: [PATCH 07/29] Inline NoDynamicInvocation and some builtin functions --- src/Compiler/Optimize/Optimizer.fs | 13 ++++++++++++- src/Compiler/TypedTree/TcGlobals.fs | 14 ++++++++++++++ src/Compiler/TypedTree/TcGlobals.fsi | 2 ++ .../EmittedIL/DebugInlineAsCall.fs | 3 +-- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs index b092fa4603..39aa5fc4d3 100644 --- a/src/Compiler/Optimize/Optimizer.fs +++ b/src/Compiler/Optimize/Optimizer.fs @@ -2341,6 +2341,17 @@ let inline IsStateMachineExpr g overallExpr = isReturnsResumableCodeTy g valRef.TauType | _ -> false +let shouldForceInlineMembersInDebug (g: TcGlobals) (tcref: EntityRef) = + match g.fslibForceInlineModules.TryGetValue tcref.LogicalName with + | true, modRef -> tyconRefEq g tcref modRef + | _ -> false + +let shouldForceInlineInDebug (g: TcGlobals) (vref: ValRef) : bool = + ValHasWellKnownAttribute g WellKnownValAttributes.NoDynamicInvocationAttribute_True vref.Deref || + ValHasWellKnownAttribute g WellKnownValAttributes.NoDynamicInvocationAttribute_False vref.Deref || + + vref.HasDeclaringEntity && shouldForceInlineMembersInDebug g vref.DeclaringEntity + /// Optimize/analyze an expression let rec OptimizeExpr cenv (env: IncrementalOptimizationEnv) expr = cenv.stackGuard.Guard <| fun () -> @@ -3432,7 +3443,7 @@ and TryInlineApplication cenv env finfo (valExpr: Expr) (tyargs: TType list, arg let g = cenv.g match cenv.settings.inlineNamedFunctions, stripExpr valExpr with - | false, Expr.Val(vref, _, _) when vref.ShouldInline -> + | false, Expr.Val(vref, _, _) when vref.ShouldInline && not (shouldForceInlineInDebug cenv.g vref) -> let origFinfo = GetInfoForValWithCheck cenv env m vref match stripValue origFinfo.ValExprInfo with | CurriedLambdaValue(origLambdaId, _, _, origLambda, origLambdaTy) when not (Zset.contains origLambdaId env.dontInline) -> diff --git a/src/Compiler/TypedTree/TcGlobals.fs b/src/Compiler/TypedTree/TcGlobals.fs index ef6e00ffb1..6af6e0ea5f 100644 --- a/src/Compiler/TypedTree/TcGlobals.fs +++ b/src/Compiler/TypedTree/TcGlobals.fs @@ -646,6 +646,18 @@ type TcGlobals( yield nleref.LastItemMangledName, ERefNonLocal nleref ] + let v_FSharpCoreForceInlineModules = + dict [ for nleref in [ fslib_MFIntrinsicFunctions_nleref + fslib_MFIntrinsicOperators_nleref + fslib_MFLanguagePrimitives_nleref + fslib_MFOperators_nleref + fslib_MFOperatorIntrinsics_nleref + fslib_MFOperatorsChecked_nleref + fslib_MFOperatorsUnchecked_nleref + fslib_MFNativePtrModule_nleref ] do + + yield nleref.LastItemMangledName, ERefNonLocal nleref ] + let tryDecodeTupleTy tupInfo l = match l with | [t1;t2;t3;t4;t5;t6;t7;markerTy] -> @@ -1133,6 +1145,8 @@ type TcGlobals( // better the job we do of mapping from provided expressions back to FSharp.Core F# functions and values. member _.knownFSharpCoreModules = v_knownFSharpCoreModules + member _.fslibForceInlineModules = v_FSharpCoreForceInlineModules + member _.compilingFSharpCore = compilingFSharpCore member _.useReflectionFreeCodeGen = useReflectionFreeCodeGen diff --git a/src/Compiler/TypedTree/TcGlobals.fsi b/src/Compiler/TypedTree/TcGlobals.fsi index e27bc1605a..214ad0d17c 100644 --- a/src/Compiler/TypedTree/TcGlobals.fsi +++ b/src/Compiler/TypedTree/TcGlobals.fsi @@ -698,6 +698,8 @@ type internal TcGlobals = member knownFSharpCoreModules: System.Collections.Generic.IDictionary + member fslibForceInlineModules: System.Collections.Generic.IDictionary + member knownIntrinsics: System.Collections.Concurrent.ConcurrentDictionary diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs index e85be18d47..b85bf372fa 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs @@ -158,8 +158,7 @@ let main _ = |> withNoOptimize |> asExe |> compileAndRun - |> verifyILContains ["call bool [FSharp.Core]Microsoft.FSharp.Core.Operators::Not(bool)"] - |> shouldSucceed + |> verifyILNotPresent ["call bool [FSharp.Core]Microsoft.FSharp.Core.Operators::Not(bool)"] [] let ``Call 10 - Different assembly`` () = From b550111e93360b9250460df3b1950a433e472254 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 9 Apr 2026 17:07:13 +0200 Subject: [PATCH 08/29] Add more tests --- .../EmittedIL/DebugInlineAsCall.fs | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs index b85bf372fa..51d6f49212 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs @@ -413,3 +413,196 @@ let main _ = [ "call int32 Test::'__debug@5'(int32," "call float64 Test::'__debug@6-1'(float64," ] |> shouldSucceed + + [] + let ``SRTP 09 - Witness`` () = + FSharp """ +let check s (b1: 'a) (b2: 'a) = if b1 = b2 then () else failwith s + +let inline add (x: ^T) (y: ^T) = x + y + +[] +let main _ = + check "int" (add 3 4) 7 + check "float" (add 1.0 2.0) 3.0 + 0 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> shouldSucceed + + [] + let ``SRTP 10 - Witness`` () = + FSharp """ +type MyNum = + { Value: float } + static member FromFloat (_: MyNum) = fun (x: float) -> { Value = x } + +type T = + static member inline Invoke(x: float) : 'Num = + let inline call (a: ^a) = (^a: (static member FromFloat : _ -> _) a) + call Unchecked.defaultof<'Num> x + +[] +let main _ = + let result = T.Invoke(3.14) + if result.Value = 3.14 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains [ "call class Test/MyNum Test::'__debug@13'(float64)" ] + |> shouldSucceed + + [] + let ``SRTP 11 - Witness`` () = + FSharp """ +type MyNum = + { Value: float } + static member FromFloat (_: MyNum, _: T) = fun (x: float) -> { Value = x } + +and T = + { Dummy: int } + static member inline Invoke(x: float) : 'Num = + let inline call2 (a: ^a, b: ^b) = ((^a or ^b) : (static member FromFloat : _ * _ -> _) (b, a)) + let inline call (a: 'a) = fun (x: 'x) -> call2 (a, Unchecked.defaultof<'r>) x : 'r + call Unchecked.defaultof x + +[] +let main _ = + let result = T.Invoke(2.71) + if result.Value = 2.71 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains [ "call class Test/MyNum Test::'__debug@15'(float64)" ] + |> shouldSucceed + + + [] + let ``Member 01 - Non-generic`` () = + FSharp """ +type T() = + member inline _.Double(x: int) = x + x + +[] +let main _ = + let t = T() + let i = t.Double(5) + if i = 10 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains ["callvirt instance int32 Test/T::Double(int32)"] + |> shouldSucceed + + [] + let ``Member 02 - Generic`` () = + FSharp """ +type T() = + member inline _.Apply(f: 'a -> 'b, x: 'a) : 'b = f x + +[] +let main _ = + let t = T() + let i = t.Apply((fun x -> x + 1), 5) + if i = 6 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains ["callvirt instance !!1 Test/T::Apply(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,"] + |> shouldSucceed + + [] + let ``Member 03 - SRTP`` () = + FSharp """ +type T() = + member inline _.Add(x: ^T, y: ^T) = x + y + +[] +let main _ = + let t = T() + let i = t.Add(3, 4) + if i = 7 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains ["call int32 Test::'__debug@8'(class Test/T,"] + |> shouldSucceed + + [] + let ``Operator 01 - Top-level`` () = + FSharp """ +let inline (++) (x: int) (y: int) = x + y + 1 + +[] +let main _ = + let i = 3 ++ 4 + if i = 8 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains ["call int32 Test::op_PlusPlus(int32,"] + |> shouldSucceed + + [] + let ``Operator 02 - Top-level SRTP`` () = + FSharp """ +let inline (++) (x: ^T) (y: ^T) = x + y + +[] +let main _ = + let i = 3 ++ 4 + if i = 7 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains ["call int32 Test::'__debug@6'(int32,"] + |> shouldSucceed + + [] + let ``Operator 03 - Local`` () = + FSharp """ +[] +let main _ = + let inline (++) (x: int) (y: int) = x + y + 1 + let i = 3 ++ 4 + if i = 8 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains ["call !!0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::InvokeFast(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,"] + |> shouldSucceed + + [] + let ``Operator 04 - Local SRTP`` () = + FSharp """ +[] +let main _ = + let inline (++) (x: ^T) (y: ^T) = x + y + let i = 3 ++ 4 + if i = 7 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> verifyILContains ["call int32 Test::'__debug@5'(int32,"] + |> shouldSucceed From d7291496b864d013b86e784067d1c0a39dbaa0da Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 9 Apr 2026 17:07:36 +0200 Subject: [PATCH 09/29] Update compiler options test baseline --- .../CompilerOptions/fsc/misc/compiler_help_output.bsl | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/misc/compiler_help_output.bsl b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/misc/compiler_help_output.bsl index 3cfd389dc8..b87d8aa697 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/misc/compiler_help_output.bsl +++ b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/misc/compiler_help_output.bsl @@ -84,6 +84,7 @@ Copyright (c) Microsoft Corporation. All Rights Reserved. --checked[+|-] Generate overflow checks (off by default) --define: Define conditional compilation symbols (Short form: -d) --strict-indentation[+|-] Override indentation rules implied by the language version (off by default) +--inline-named-functions[+|-] Inline named 'inline' functions - MISCELLANEOUS - From be87db78f09ea8067224ba289dc29b336f8ef0f6 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Sat, 11 Apr 2026 10:03:23 +0200 Subject: [PATCH 10/29] More witness fixes --- src/Compiler/Optimize/Optimizer.fs | 5 +- .../EmittedIL/DebugInlineAsCall.fs | 55 +++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs index 39aa5fc4d3..0ca64d982d 100644 --- a/src/Compiler/Optimize/Optimizer.fs +++ b/src/Compiler/Optimize/Optimizer.fs @@ -3457,8 +3457,11 @@ and TryInlineApplication cenv env finfo (valExpr: Expr) (tyargs: TType list, arg let allTyargsAreConcrete = tyargs |> List.forall (fun t -> (freeInType CollectTyparsNoCaching t).FreeTypars.IsEmpty) + let allTyargsAreGeneric = + tyargs |> List.forall (fun t -> not (freeInType CollectTyparsNoCaching t).FreeTypars.IsEmpty) + let canCallDirectly = - hasNoTraits || (not allTyargsAreConcrete && vref.ValReprInfo.IsSome) + hasNoTraits || (allTyargsAreGeneric && vref.ValReprInfo.IsSome) if canCallDirectly then Some(mkApps g ((exprForValRef m vref, vref.Type), [tyargs], argsR, m), info) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs index 51d6f49212..299232238b 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs @@ -484,6 +484,61 @@ let main _ = |> shouldSucceed + [] + let ``SRTP 12 - Witness - Struct with partially resolved type args`` () = + FSharp """ +[] +type S = + member _.M() = () + +type T() = + member _.N() = () + +let inline f (a: ^A when ^A: (member M: unit -> unit)) (_b: ^B when ^B: (member N: unit -> unit)) = + (^A: (member M: unit -> unit) a) + +let inline g b = f (S()) b + +[] +let main _ = + g (T()) + 0 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> shouldSucceed + + [] + let ``SRTP 13 - Witness - Struct with ResumableCode and partially resolved type args`` () = + FSharp """ +open Microsoft.FSharp.Core.CompilerServices + +[] +type S = member this.Foo() = () + +type D = member _.Bar() = true + +let inline f (x: ^A) = + ResumableCode< ^B, _>(fun sm -> + (^A: (member Foo: unit -> unit) x) + (^B: (member Bar: unit -> bool) sm.Data) + ) + +let inline g () = f (S()) + +[] +let main _ = + let _ : ResumableCode = g () + 0 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> shouldSucceed + [] let ``Member 01 - Non-generic`` () = FSharp """ From bdfc882bf71d1725493dee8cd204b565aa073fd9 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Fri, 10 Apr 2026 17:27:50 +0200 Subject: [PATCH 11/29] Don't check accessibility for non-inlined functions --- src/Compiler/Optimize/Optimizer.fs | 31 +++++++++--------- .../EmittedIL/DebugInlineAsCall.fs | 32 +++++++++++++++++++ 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs index 0ca64d982d..4d035ade8b 100644 --- a/src/Compiler/Optimize/Optimizer.fs +++ b/src/Compiler/Optimize/Optimizer.fs @@ -506,8 +506,9 @@ let CheckInlineValueIsComplete (v: Val) res = errorR(Error(FSComp.SR.optValueMarkedInlineButIncomplete(v.DisplayName), v.Range)) //System.Diagnostics.Debug.Assert(false, sprintf "Break for incomplete inline value %s" v.DisplayName) -let check (vref: ValRef) (res: ValInfo) = - CheckInlineValueIsComplete vref.Deref res.ValExprInfo +let check (cenv: cenv) (vref: ValRef) (res: ValInfo) = + if cenv.settings.inlineNamedFunctions then + CheckInlineValueIsComplete vref.Deref res.ValExprInfo (vref, res) //------------------------------------------------------------------------- @@ -697,7 +698,7 @@ let GetInfoForVal cenv env m (vref: ValRef) = let GetInfoForValWithCheck cenv env m (vref: ValRef) = let res = GetInfoForVal cenv env m vref - check vref res |> ignore + check cenv vref res |> ignore res let IsPartialExpr cenv env m x = @@ -1331,7 +1332,7 @@ let CombineValueInfos einfos res = let CombineValueInfosUnknown einfos = CombineValueInfos einfos UnknownValue /// Hide information because of a signature -let AbstractLazyModulInfoByHiding isAssemblyBoundary mhi = +let AbstractLazyModulInfoByHiding isAssemblyBoundary (cenv: cenv) mhi = // The freevars and FreeTyvars can indicate if the non-public (hidden) items have been used. // Under those checks, the further hidden* checks may be subsumed (meaning, not required anymore). @@ -1406,7 +1407,7 @@ let AbstractLazyModulInfoByHiding isAssemblyBoundary mhi = ValInfos = ValInfos(ss.ValInfos.Entries |> Seq.filter (fun (vref, _) -> not (hiddenVal vref.Deref)) - |> Seq.map (fun (vref, e) -> check (* "its implementation uses a binding hidden by a signature" m *) vref (abstractValInfo e) )) } + |> Seq.map (fun (vref, e) -> check cenv vref (abstractValInfo e) )) } and abstractLazyModulInfo (ss: LazyModuleInfo) = ss.Force() |> abstractModulInfo |> notlazy @@ -1425,7 +1426,7 @@ let AbstractOptimizationInfoToEssentials = abstractLazyModulInfo /// Hide information because of a "let ... in ..." or "let rec ... in ... " -let AbstractExprInfoByVars (boundVars: Val list, boundTyVars) ivalue = +let AbstractExprInfoByVars (cenv: cenv) (boundVars: Val list, boundTyVars) ivalue = // Module and member bindings can be skipped when checking abstraction, since abstraction of these values has already been done when // we hit the end of the module and called AbstractLazyModulInfoByHiding. If we don't skip these then we end up quadratically retraversing // the inferred optimization data, i.e. at each binding all the way up a sequences of 'lets' in a module. @@ -1485,7 +1486,7 @@ let AbstractExprInfoByVars (boundVars: Val list, boundTyVars) ivalue = let rec abstractModulInfo ss = { ModuleOrNamespaceInfos = ss.ModuleOrNamespaceInfos |> NameMap.map (InterruptibleLazy.force >> abstractModulInfo >> notlazy) ValInfos = ss.ValInfos.Map (fun (vref, e) -> - check vref (abstractValInfo e) ) } + check cenv vref (abstractValInfo e)) } abstractExprInfo ivalue @@ -1525,9 +1526,9 @@ let RemapOptimizationInfo g tmenv = remapLazyModulInfo /// Hide information when a value is no longer visible -let AbstractAndRemapModulInfo g (repackage, hidden) info = +let AbstractAndRemapModulInfo g (cenv: cenv) (repackage, hidden) info = let mrpi = mkRepackageRemapping repackage - let info = info |> AbstractLazyModulInfoByHiding false hidden + let info = info |> AbstractLazyModulInfoByHiding false cenv hidden let info = info |> RemapOptimizationInfo g mrpi info @@ -2850,7 +2851,7 @@ and OptimizeLetRec cenv env (binds, bodyExpr, m) = let fvs = List.fold (fun acc x -> unionFreeVars acc (fst x |> freeInBindingRhs CollectLocals)) fvs0 bindsR SplitValuesByIsUsedOrHasEffect cenv (fun () -> fvs.FreeLocals) bindsR // Trim out any optimization info that involves escaping values - let evalueR = AbstractExprInfoByVars (vs, []) einfo.Info + let evalueR = AbstractExprInfoByVars cenv (vs, []) einfo.Info // REVIEW: size of constructing new closures - should probably add #freevars + #recfixups here let bodyExprR = Expr.LetRec (bindsRR, bodyExprR, m, Construct.NewFreeVarsCache()) let info = CombineValueInfos (einfo :: bindinfos) evalueR @@ -2926,7 +2927,7 @@ and OptimizeLinearExpr cenv env expr contf = Info = UnknownValue } else // On the way back up: Trim out any optimization info that involves escaping values on the way back up - let evalueR = AbstractExprInfoByVars ([bindR.Var], []) bodyInfo.Info + let evalueR = AbstractExprInfoByVars cenv ([bindR.Var], []) bodyInfo.Info // Preserve the debug points for eliminated bindings that have debug points. let bodyR = @@ -4101,7 +4102,7 @@ and OptimizeDecisionTreeTarget cenv env _m (TTarget(vs, expr, flags)) = let env = BindInternalValsToUnknown cenv vs env let exprR, einfo = OptimizeExpr cenv env expr let exprR, einfo = ConsiderSplitToMethod cenv.settings.abstractBigTargets cenv.settings.bigTargetSize cenv env (exprR, einfo) - let evalueR = AbstractExprInfoByVars (vs, []) einfo.Info + let evalueR = AbstractExprInfoByVars cenv (vs, []) einfo.Info TTarget(vs, exprR, flags), { TotalSize=einfo.TotalSize FunctionSize=einfo.FunctionSize @@ -4385,7 +4386,7 @@ and OptimizeModuleExprWithSig cenv env mty def = elimModuleDefn def - let info = AbstractAndRemapModulInfo g rpi info + let info = AbstractAndRemapModulInfo g cenv rpi info def, info @@ -4458,14 +4459,14 @@ and OptimizeImplFileInternal cenv env isIncrementalFragment hidden implFile = // This optimizes and builds minfo ignoring the signature let (defR, minfo), (_env, _bindInfosColl) = OptimizeModuleContents cenv (env, []) contents let hidden = ComputeImplementationHidingInfoAtAssemblyBoundary defR hidden - let minfo = AbstractLazyModulInfoByHiding false hidden minfo + let minfo = AbstractLazyModulInfoByHiding false cenv hidden minfo let env = BindValsInModuleOrNamespace cenv minfo env env, defR, minfo, hidden else // This optimizes and builds minfo w.r.t. the signature let mexprR, minfo = OptimizeModuleExprWithSig cenv env signature contents let hidden = ComputeSignatureHidingInfoAtAssemblyBoundary signature hidden - let minfoExternal = AbstractLazyModulInfoByHiding true hidden minfo + let minfoExternal = AbstractLazyModulInfoByHiding true cenv hidden minfo let env = BindValsInModuleOrNamespace cenv minfo env env, mexprR, minfoExternal, hidden diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs index 299232238b..ef0ac23b70 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs @@ -661,3 +661,35 @@ let main _ = |> compileAndRun |> verifyILContains ["call int32 Test::'__debug@5'(int32,"] |> shouldSucceed + + [] + let ``Accessibility 01`` () = + FSharp """ +module Module + +let inline internal fInternal () = () +let inline f () = fInternal () +""" + |> withDebug + |> withNoOptimize + |> asLibrary + |> compile + |> shouldSucceed + + [] + let ``Accessibility 02`` () = + FSharp """ +module Module + +type T() = + member inline internal this.InternalMethod() = + () + + member inline this.Method() = + this.InternalMethod() +""" + |> withDebug + |> withNoOptimize + |> asLibrary + |> compile + |> shouldSucceed \ No newline at end of file From 66e2f26dd84bd53c2a185395df1c5990aafeec09 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Sun, 12 Apr 2026 17:10:51 +0200 Subject: [PATCH 12/29] Fix --- src/Compiler/CodeGen/IlxGen.fs | 11 +++- src/Compiler/CodeGen/IlxGen.fsi | 3 + src/Compiler/Driver/OptimizeInputs.fs | 3 + .../EmittedIL/DebugInlineAsCall.fs | 56 +++++++++++++++++++ 4 files changed, 71 insertions(+), 2 deletions(-) diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index 4e3452a2d8..e1c1c43f51 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -269,6 +269,8 @@ type IlxGenOptions = /// When set to true, the IlxGen will delay generation of method bodies and generated them later in parallel (parallelized across files) parallelIlxGenEnabled: bool + + inlineNamedFunctions: bool } /// Compilation environment for compiling a fragment of an assembly @@ -5586,8 +5588,13 @@ and GenTraitCall (cenv: cenv) cgbuf eenv (traitInfo: TraitConstraintInfo, argExp | None -> - // If witnesses are available, we should now always find trait witnesses in scope - assert not generateWitnesses + // When inlineNamedFunctions is true, all trait calls should be resolved via witnesses in scope. + // When inlineNamedFunctions is false, inline functions are kept as calls rather than inlined. + // Their witness arguments may contain TraitCall operations for constraints that were resolved + // without a witness (e.g., when the constraint is satisfied by a known concrete type). + // In such cases, generateWitnesses can be true (because other witnesses are in scope) but + // the specific trait's witness is not found. Fall through to the constraint solver to resolve it. + assert (not generateWitnesses || not cenv.options.inlineNamedFunctions) let exprOpt = CommitOperationResult(ConstraintSolver.CodegenWitnessExprForTraitConstraint cenv.tcVal g cenv.amap m traitInfo argExprs) diff --git a/src/Compiler/CodeGen/IlxGen.fsi b/src/Compiler/CodeGen/IlxGen.fsi index cd9dd0f2ff..abf5320b69 100644 --- a/src/Compiler/CodeGen/IlxGen.fsi +++ b/src/Compiler/CodeGen/IlxGen.fsi @@ -61,6 +61,9 @@ type internal IlxGenOptions = /// When set to true, the IlxGen will delay generation of method bodies and generate them later in parallel (parallelized across files) parallelIlxGenEnabled: bool + + /// Indicates if inline named functions are being inlined or emitted as calls + inlineNamedFunctions: bool } /// The results of the ILX compilation of one fragment of an assembly diff --git a/src/Compiler/Driver/OptimizeInputs.fs b/src/Compiler/Driver/OptimizeInputs.fs index cace428af4..81825929f3 100644 --- a/src/Compiler/Driver/OptimizeInputs.fs +++ b/src/Compiler/Driver/OptimizeInputs.fs @@ -582,6 +582,9 @@ let GenerateIlxCode isInteractiveItExpr = isInteractiveItExpr alwaysCallVirt = tcConfig.alwaysCallVirt parallelIlxGenEnabled = tcConfig.parallelIlxGen + inlineNamedFunctions = + tcConfig.inlineNamedFunctions + |> Option.defaultValue (not tcConfig.debuginfo || tcConfig.optSettings.LocalOptimizationsEnabled) } ilxGenerator.GenerateCode(ilxGenOpts, optimizedImpls, topAttrs.assemblyAttrs, topAttrs.netModuleAttrs) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs index ef0ac23b70..9869c9febd 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs @@ -539,6 +539,62 @@ let main _ = |> compileAndRun |> shouldSucceed + [] + let ``SRTP 14 - StateMachine with unresolved trait from composed inline function`` () = + FSharp """ +open Microsoft.FSharp.Core.CompilerServices +open Microsoft.FSharp.Core.CompilerServices.StateMachineHelpers +open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators + +[] +type S<'T> = member _.M(_: 'T) = () + +let inline f<'A, 'R, 'B when 'A: (member M: int -> 'R) and 'B: (member M: 'R -> unit)> (_a: 'A) : 'B = Unchecked.defaultof<_> + +let inline g (_: S<'T>) = + if __useResumableCode then + __stateMachine, int> + (MoveNextMethodImpl<_>(fun _ -> ())) + (SetStateMachineMethodImpl<_>(fun _ _ -> ())) + (AfterCode<_, _>(fun _ -> 0)) + else 0 + +let inline h a = g (f a) + +[] +let main _ = + let _ = h (S()) + 0 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> shouldSucceed + + [] + let ``SRTP 15 - Composed inline with linked constraints`` () = + FSharp """ +[] +type S<'T> = member _.M(_: 'T) = () + +let inline f<'A, 'R, 'B when 'A: (member M: int -> 'R) and 'B: (member M: 'R -> unit)> (_a: 'A) : 'B = Unchecked.defaultof<_> + +let inline g (_: S<'T>) = 42 + +let inline h a = g (f a) + +[] +let main _ = + let i = h (S()) + if i = 42 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> shouldSucceed + [] let ``Member 01 - Non-generic`` () = FSharp """ From 7d922d94126b7239b3137b78112f9bb77eb28fe3 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Sun, 12 Apr 2026 19:37:33 +0200 Subject: [PATCH 13/29] Fix same line name --- src/Compiler/Optimize/Optimizer.fs | 6 ++ .../EmittedIL/DebugInlineAsCall.fs | 58 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs index 4d035ade8b..66764a2981 100644 --- a/src/Compiler/Optimize/Optimizer.fs +++ b/src/Compiler/Optimize/Optimizer.fs @@ -3484,6 +3484,12 @@ and TryInlineApplication cenv env finfo (valExpr: Expr) (tyargs: TType list, arg let specLambdaR, _ = OptimizeExpr cenv { env with dontInline = Zset.add origLambdaId env.dontInline } specLambda specLambdaR + let specLambdaR = + match specLambdaR with + | Expr.Lambda(uniq, a, b, c, d, _, ty) -> Expr.Lambda(uniq, a, b, c, d, m, ty) + | Expr.TyLambda(uniq, a, b, _, ty) -> Expr.TyLambda(uniq, a, b, m, ty) + | _ -> specLambdaR + let debugVal = let name = $"<{vref.LogicalName}>__debug" // When tyargs have free type variables, omit ValReprInfo so IlxGen compiles this diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs index 9869c9febd..4f814e9d7f 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs @@ -595,6 +595,64 @@ let main _ = |> compileAndRun |> shouldSucceed + [] + let ``SRTP 16 - Same line`` () = + let additionalSource = FsSourceWithFileName "Program.fs" """ +module Program + +open Module + +let inline foo (a: 'a) = U.F(a, 0); fun () -> () + +[] +let main _ = + let _ = foo (T()) + 0 +""" + FSharpWithFileName "Module.fs" """ +module Module + +type T() = member _.M() = () + +type U = static member inline F<'a, 'b when 'a: (member M: unit -> unit)>(_a: 'a, _b: 'b) = () +""" + |> withAdditionalSourceFile additionalSource + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> shouldSucceed + + [] + let ``SRTP 17 - Same line`` () = + let library = + FSharp """ +module Module + +let inline add<'a, 'b, 'c when 'a: (static member (+): 'a * 'a -> 'b)> (x: 'a) (y: 'a) = + x + y +""" + |> withDebug + |> withNoOptimize + |> asLibrary + + FSharp """ +open Module + +let inline foo x y = add x y |> ignore; fun () -> () + +[] +let main _ = + let _ = foo 1 2 + 0 +""" + |> withDebug + |> withNoOptimize + |> withReferences [library] + |> asExe + |> compileAndRun + |> shouldSucceed + [] let ``Member 01 - Non-generic`` () = FSharp """ From af085c226d9920869f1426b6697ae8e5eddf3a90 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Sun, 12 Apr 2026 22:06:25 +0200 Subject: [PATCH 14/29] More SRTP --- src/Compiler/CodeGen/IlxGen.fs | 12 ++++++++ .../EmittedIL/DebugInlineAsCall.fs | 30 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index e1c1c43f51..a909760108 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -7080,6 +7080,18 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenv takenNames let cloFreeTyvars = cloFreeTyvars.FreeTypars |> Zset.elements + // When generating witnesses, witness types may reference type variables that appear + // only in SRTP constraints of the captured type variables (e.g. 'b in 'a : (member M: unit -> 'b)). + // Include those so they are available when generating witness field types. + let cloFreeTyvars = + if ComputeGenerateWitnesses g eenv then + let extra = + GetTraitWitnessInfosOfTypars g 0 cloFreeTyvars + |> List.collect (fun w -> (freeInType CollectTyparsNoCaching (GenWitnessTy g w)).FreeTypars |> Zset.elements) + (cloFreeTyvars @ extra) |> List.distinctBy (fun tp -> tp.Stamp) + else + cloFreeTyvars + let eenvinner = eenv |> EnvForTypars cloFreeTyvars let ilCloTyInner = diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs index 4f814e9d7f..69a4df4a23 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs @@ -653,6 +653,36 @@ let main _ = |> compileAndRun |> shouldSucceed + [] + let ``SRTP 18 - Type abbreviation with constraint`` () = + let additionalSource = FsSourceWithFileName "Program.fs" """ +module Program + +open Module + +type T() = member _.M() = 42 + +let inline foo (a: 'a) = C.F(a); fun () -> () + +[] +let main _ = + let _ = foo (T()) + 0 +""" + FSharpWithFileName "Module.fs" """ +module Module + +type C<'a, 'b when 'a: (member M: unit -> 'b)> = 'a + +type C = static member inline F<'a, 'b, 'c when C<'a, 'b>>(_a: 'a) = () +""" + |> withAdditionalSourceFile additionalSource + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> shouldSucceed + [] let ``Member 01 - Non-generic`` () = FSharp """ From 3a857f58072b4fae1331c56f4e0d4856bd1df442 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Mon, 13 Apr 2026 12:30:20 +0200 Subject: [PATCH 15/29] Accessibility --- src/Compiler/Optimize/Optimizer.fs | 121 +++++++++--------- .../EmittedIL/DebugInlineAsCall.fs | 94 +++++++++++++- 2 files changed, 156 insertions(+), 59 deletions(-) diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs index 66764a2981..1a5e66974d 100644 --- a/src/Compiler/Optimize/Optimizer.fs +++ b/src/Compiler/Optimize/Optimizer.fs @@ -1358,8 +1358,9 @@ let AbstractLazyModulInfoByHiding isAssemblyBoundary (cenv: cenv) mhi = then detailR else ValValue (vref2, detailR) - // Check for escape in lambda - | CurriedLambdaValue (_, _, _, expr, _) | ConstExprValue(_, expr) when + // Check for escape in lambda + | CurriedLambdaValue (_, _, _, expr, _) | ConstExprValue(_, expr) when + cenv.settings.inlineNamedFunctions && (let fvs = freeInExpr CollectAll expr (isAssemblyBoundary && not (freeVarsAllPublic fvs)) || Zset.exists hiddenVal fvs.FreeLocals || @@ -1406,7 +1407,9 @@ let AbstractLazyModulInfoByHiding isAssemblyBoundary (cenv: cenv) mhi = { ModuleOrNamespaceInfos = NameMap.map abstractLazyModulInfo ss.ModuleOrNamespaceInfos ValInfos = ValInfos(ss.ValInfos.Entries - |> Seq.filter (fun (vref, _) -> not (hiddenVal vref.Deref)) + |> Seq.filter (fun (vref, _) -> + not (hiddenVal vref.Deref) || + (not cenv.settings.inlineNamedFunctions && vref.Deref.ShouldInline)) |> Seq.map (fun (vref, e) -> check cenv vref (abstractValInfo e) )) } and abstractLazyModulInfo (ss: LazyModuleInfo) = @@ -3104,7 +3107,8 @@ and TryOptimizeVal cenv env (vOpt: ValRef option, shouldInline, inlineIfLambda, failwith "tuple, union and record values cannot be marked 'inline'" | UnknownValue when shouldInline -> - warning(Error(FSComp.SR.optValueMarkedInlineHasUnexpectedValue(), m)) + if cenv.settings.inlineNamedFunctions then + warning(Error(FSComp.SR.optValueMarkedInlineHasUnexpectedValue(), m)) None | _ when shouldInline -> @@ -3153,7 +3157,7 @@ and OptimizeVal cenv env expr (v: ValRef, m) = e, AddValEqualityInfo g m v einfo | None -> - if v.ShouldInline then + if v.ShouldInline && cenv.settings.inlineNamedFunctions then match valInfoForVal.ValExprInfo with | UnknownValue -> error(Error(FSComp.SR.optFailedToInlineValue(v.DisplayName), m)) | _ -> warning(Error(FSComp.SR.optFailedToInlineValue(v.DisplayName), m)) @@ -3445,67 +3449,68 @@ and TryInlineApplication cenv env finfo (valExpr: Expr) (tyargs: TType list, arg match cenv.settings.inlineNamedFunctions, stripExpr valExpr with | false, Expr.Val(vref, _, _) when vref.ShouldInline && not (shouldForceInlineInDebug cenv.g vref) -> - let origFinfo = GetInfoForValWithCheck cenv env m vref - match stripValue origFinfo.ValExprInfo with - | CurriedLambdaValue(origLambdaId, _, _, origLambda, origLambdaTy) when not (Zset.contains origLambdaId env.dontInline) -> - let argsR = args |> List.map (OptimizeExpr cenv env >> fst) - let info = { TotalSize = 1; FunctionSize = 1; HasEffect = true; MightMakeCriticalTailcall = false; Info = UnknownValue } + let hasNoTraits = + let tps, _ = tryDestForallTy g vref.Type + GetTraitConstraintInfosOfTypars g tps |> List.isEmpty - let hasNoTraits = - let tps, _ = tryDestForallTy g vref.Type - GetTraitConstraintInfosOfTypars g tps |> List.isEmpty + let allTyargsAreConcrete = + tyargs |> List.forall (fun t -> (freeInType CollectTyparsNoCaching t).FreeTypars.IsEmpty) - let allTyargsAreConcrete = - tyargs |> List.forall (fun t -> (freeInType CollectTyparsNoCaching t).FreeTypars.IsEmpty) + let allTyargsAreGeneric = + tyargs |> List.forall (fun t -> not (freeInType CollectTyparsNoCaching t).FreeTypars.IsEmpty) - let allTyargsAreGeneric = - tyargs |> List.forall (fun t -> not (freeInType CollectTyparsNoCaching t).FreeTypars.IsEmpty) + let canCallDirectly = + hasNoTraits || (allTyargsAreGeneric && vref.ValReprInfo.IsSome) - let canCallDirectly = - hasNoTraits || (allTyargsAreGeneric && vref.ValReprInfo.IsSome) + let argsR = args |> List.map (OptimizeExpr cenv env >> fst) + let info = { TotalSize = 1; FunctionSize = 1; HasEffect = true; MightMakeCriticalTailcall = false; Info = UnknownValue } - if canCallDirectly then - Some(mkApps g ((exprForValRef m vref, vref.Type), [tyargs], argsR, m), info) - else - let f2R = CopyExprForInlining cenv true origLambda m - let specLambda = MakeApplicationAndBetaReduce g (f2R, origLambdaTy, [tyargs], [], m) - let specLambdaTy = tyOfExpr g specLambda + if canCallDirectly then + Some(mkApps g ((exprForValRef m vref, vref.Type), [tyargs], argsR, m), info) + else - let specLambdaR = + let origFinfo = GetInfoForValWithCheck cenv env m vref + match stripValue origFinfo.ValExprInfo with + | CurriedLambdaValue(origLambdaId, _, _, origLambda, origLambdaTy) when not (Zset.contains origLambdaId env.dontInline) -> + let f2R = CopyExprForInlining cenv true origLambda m + let specLambda = MakeApplicationAndBetaReduce g (f2R, origLambdaTy, [tyargs], [], m) + let specLambdaTy = tyOfExpr g specLambda + + let specLambdaR = + if allTyargsAreConcrete then + match cenv.specializedInlineVals.FindAll(origLambdaId) |> List.tryFind (fun (ty, _) -> typeEquiv g ty specLambdaTy) with + | Some (_, body) -> copyExpr g CloneAll body + | None -> + + let specLambdaR, _ = OptimizeExpr cenv { env with dontInline = Zset.add origLambdaId env.dontInline } specLambda + cenv.specializedInlineVals.Add(origLambdaId, (specLambdaTy, specLambdaR)) + specLambdaR + else + let specLambdaR, _ = OptimizeExpr cenv { env with dontInline = Zset.add origLambdaId env.dontInline } specLambda + specLambdaR + + let specLambdaR = + match specLambdaR with + | Expr.Lambda(uniq, a, b, c, d, _, ty) -> Expr.Lambda(uniq, a, b, c, d, m, ty) + | Expr.TyLambda(uniq, a, b, _, ty) -> Expr.TyLambda(uniq, a, b, m, ty) + | _ -> specLambdaR + + let debugVal = + let name = $"<{vref.LogicalName}>__debug" + // When tyargs have free type variables, omit ValReprInfo so IlxGen compiles this + // as a closure that captures type variables and witnesses from the enclosing scope. + let valReprInfo = if allTyargsAreConcrete then - match cenv.specializedInlineVals.FindAll(origLambdaId) |> List.tryFind (fun (ty, _) -> typeEquiv g ty specLambdaTy) with - | Some (_, body) -> copyExpr g CloneAll body - | None -> - - let specLambdaR, _ = OptimizeExpr cenv { env with dontInline = Zset.add origLambdaId env.dontInline } specLambda - cenv.specializedInlineVals.Add(origLambdaId, (specLambdaTy, specLambdaR)) - specLambdaR + Some(InferValReprInfoOfExpr g AllowTypeDirectedDetupling.No specLambdaTy [] [] specLambdaR) else - let specLambdaR, _ = OptimizeExpr cenv { env with dontInline = Zset.add origLambdaId env.dontInline } specLambda - specLambdaR - - let specLambdaR = - match specLambdaR with - | Expr.Lambda(uniq, a, b, c, d, _, ty) -> Expr.Lambda(uniq, a, b, c, d, m, ty) - | Expr.TyLambda(uniq, a, b, _, ty) -> Expr.TyLambda(uniq, a, b, m, ty) - | _ -> specLambdaR - - let debugVal = - let name = $"<{vref.LogicalName}>__debug" - // When tyargs have free type variables, omit ValReprInfo so IlxGen compiles this - // as a closure that captures type variables and witnesses from the enclosing scope. - let valReprInfo = - if allTyargsAreConcrete then - Some(InferValReprInfoOfExpr g AllowTypeDirectedDetupling.No specLambdaTy [] [] specLambdaR) - else - None - - Construct.NewVal(name, m, None, specLambdaTy, Immutable, true, valReprInfo, taccessPublic, ValNotInRecScope, None, - NormalVal, [], ValInline.InlinedDefinition, XmlDoc.Empty, false, false, false, false, false, false, None, - ParentNone) - - let callExpr = mkApps g ((exprForVal m debugVal, specLambdaTy), [], argsR, m) - Some(mkCompGenLet m debugVal specLambdaR callExpr, info) + None + + Construct.NewVal(name, m, None, specLambdaTy, Immutable, true, valReprInfo, taccessPublic, ValNotInRecScope, None, + NormalVal, [], ValInline.InlinedDefinition, XmlDoc.Empty, false, false, false, false, false, false, None, + ParentNone) + + let callExpr = mkApps g ((exprForVal m debugVal, specLambdaTy), [], argsR, m) + Some(mkCompGenLet m debugVal specLambdaR callExpr, info) | _ -> None | _ -> diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs index 69a4df4a23..342ac0f8a8 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs @@ -836,4 +836,96 @@ type T() = |> withNoOptimize |> asLibrary |> compile - |> shouldSucceed \ No newline at end of file + |> shouldSucceed + + [] + let ``Accessibility 03`` () = + let library = + FSharp """ +module Lib + +type T() = + member inline internal _.F(x) = x + member inline this.G(x) = this.F(x) +""" + |> withDebug + |> withNoOptimize + |> asLibrary + |> withName "lib" + + FSharp """ +module App +let r = Lib.T().G(1) +""" + |> withDebug + |> withNoOptimize + |> withReferences [library] + |> compile + |> shouldSucceed + + + [] + let ``Accessibility 04`` () = + let library = + FSharp """ +module MyLib + +let inline internal addInternal (x: ^T) (y: ^T) = x + y +let inline addPublic (x: ^T) (y: ^T) = addInternal x y +""" + |> withDebug + |> withNoOptimize + |> asLibrary + + FSharp """ +open MyLib + +[] +let main _ = + let i = addPublic 3 4 + if i = 7 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> withReferences [library] + |> asExe + |> compileAndRun + |> shouldSucceed + + [] + let ``Accessibility 05`` () = + let library = + FSharp """ +module Module + +type MyNum = + { Value: float } + static member FromFloat (_: MyNum) = fun (x: float) -> { Value = x } + +type T = + static member inline internal InvokeInternal(x: float) : 'Num = + let inline call (a: ^a) = (^a: (static member FromFloat : _ -> _) a) + call Unchecked.defaultof<'Num> x + + static member inline Invoke(x: float) : 'Num = + T.InvokeInternal<'Num>(x) +""" + |> withDebug + |> withNoOptimize + |> asLibrary + |> withName "Library" + + FSharp """ +open Module + +[] +let main _ = + let result = T.Invoke(3.14) + if result.Value = 3.14 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> withReferences [library] + |> asExe + |> compileAndRun + |> shouldSucceed From 4b2880b5599ccf918384939de2572f33f5ef414b Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Mon, 13 Apr 2026 12:54:19 +0200 Subject: [PATCH 16/29] Fantomas --- src/Compiler/CodeGen/IlxGen.fs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index a909760108..01df61bb92 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -7087,7 +7087,10 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenv takenNames if ComputeGenerateWitnesses g eenv then let extra = GetTraitWitnessInfosOfTypars g 0 cloFreeTyvars - |> List.collect (fun w -> (freeInType CollectTyparsNoCaching (GenWitnessTy g w)).FreeTypars |> Zset.elements) + |> List.collect (fun w -> + (freeInType CollectTyparsNoCaching (GenWitnessTy g w)).FreeTypars + |> Zset.elements) + (cloFreeTyvars @ extra) |> List.distinctBy (fun tp -> tp.Stamp) else cloFreeTyvars From 67bbcf4fa72b063d8ffdcbb36e902f77c7fbbbd4 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Mon, 13 Apr 2026 16:37:40 +0200 Subject: [PATCH 17/29] Inline when extra optimization loops --- src/Compiler/Driver/CompilerConfig.fs | 10 +++++++++- src/Compiler/Driver/CompilerConfig.fsi | 2 +- src/Compiler/Driver/OptimizeInputs.fs | 9 ++------- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index 6075a7a32a..ed8d791449 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -1256,7 +1256,15 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) = member _.fsiMultiAssemblyEmit = data.fsiMultiAssemblyEmit member _.FxResolver = data.FxResolver member _.strictIndentation = data.strictIndentation - member _.inlineNamedFunctions = data.inlineNamedFunctions + + member _.inlineNamedFunctions = + data.inlineNamedFunctions + |> Option.defaultValue ( + not data.debuginfo + || data.optSettings.LocalOptimizationsEnabled + || data.extraOptimizationIterations > 0 + ) + member _.primaryAssembly = data.primaryAssembly member _.noFeedback = data.noFeedback member _.stackReserveSize = data.stackReserveSize diff --git a/src/Compiler/Driver/CompilerConfig.fsi b/src/Compiler/Driver/CompilerConfig.fsi index 85ce24133a..b81a37917c 100644 --- a/src/Compiler/Driver/CompilerConfig.fsi +++ b/src/Compiler/Driver/CompilerConfig.fsi @@ -816,7 +816,7 @@ type TcConfig = member strictIndentation: bool option - member inlineNamedFunctions: bool option + member inlineNamedFunctions: bool member GetTargetFrameworkDirectories: unit -> string list diff --git a/src/Compiler/Driver/OptimizeInputs.fs b/src/Compiler/Driver/OptimizeInputs.fs index 81825929f3..120285358a 100644 --- a/src/Compiler/Driver/OptimizeInputs.fs +++ b/src/Compiler/Driver/OptimizeInputs.fs @@ -327,9 +327,7 @@ let ApplyAllOptimizations // Only do abstractBigTargets in the first phase, and only when TLR is on. abstractBigTargets = tcConfig.doTLR reportingPhase = true - inlineNamedFunctions = - tcConfig.inlineNamedFunctions - |> Option.defaultValue (not tcConfig.debuginfo || tcConfig.optSettings.LocalOptimizationsEnabled) + inlineNamedFunctions = tcConfig.inlineNamedFunctions } // Only do these two steps in the first phase. @@ -337,7 +335,6 @@ let ApplyAllOptimizations { firstLoopSettings with abstractBigTargets = false reportingPhase = false - inlineNamedFunctions = false } let addPhaseDiagnostics (f: PhaseFunc) (info: Phase) = @@ -582,9 +579,7 @@ let GenerateIlxCode isInteractiveItExpr = isInteractiveItExpr alwaysCallVirt = tcConfig.alwaysCallVirt parallelIlxGenEnabled = tcConfig.parallelIlxGen - inlineNamedFunctions = - tcConfig.inlineNamedFunctions - |> Option.defaultValue (not tcConfig.debuginfo || tcConfig.optSettings.LocalOptimizationsEnabled) + inlineNamedFunctions = tcConfig.inlineNamedFunctions } ilxGenerator.GenerateCode(ilxGenOpts, optimizedImpls, topAttrs.assemblyAttrs, topAttrs.netModuleAttrs) From 777423f8093623fe9d686727682756beb4d382a6 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Mon, 13 Apr 2026 17:13:50 +0200 Subject: [PATCH 18/29] Specialize signature-hidden values --- src/Compiler/Optimize/Optimizer.fs | 27 +++++-- .../EmittedIL/DebugInlineAsCall.fs | 80 +++++++++++++++++++ 2 files changed, 101 insertions(+), 6 deletions(-) diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs index 1a5e66974d..4c8470c53c 100644 --- a/src/Compiler/Optimize/Optimizer.fs +++ b/src/Compiler/Optimize/Optimizer.fs @@ -438,6 +438,8 @@ type cenv = realsig: bool specializedInlineVals: HashMultiMap + + signatureHidingInfo: SignatureHidingInfo } override x.ToString() = "" @@ -3459,8 +3461,14 @@ and TryInlineApplication cenv env finfo (valExpr: Expr) (tyargs: TType list, arg let allTyargsAreGeneric = tyargs |> List.forall (fun t -> not (freeInType CollectTyparsNoCaching t).FreeTypars.IsEmpty) + // When inside an inline function body being prepared for export (!cenv.optimizing), + // only emit a direct call if the callee is publicly accessible. Non-public vals + // (e.g. in internal modules, or hidden by .fsi) can't be called by consumers, + // so route those through the specialization path which inlines the body. + let isHiddenBySignature = cenv.signatureHidingInfo.HiddenVals.Contains vref.Deref let canCallDirectly = - hasNoTraits || (allTyargsAreGeneric && vref.ValReprInfo.IsSome) + (cenv.optimizing || (vref.Accessibility.IsPublic && not isHiddenBySignature)) && + (hasNoTraits || (allTyargsAreGeneric && vref.ValReprInfo.IsSome)) let argsR = args |> List.map (OptimizeExpr cenv env >> fst) let info = { TotalSize = 1; FunctionSize = 1; HasEffect = true; MightMakeCriticalTailcall = false; Info = UnknownValue } @@ -4324,17 +4332,23 @@ and OptimizeBindings cenv isRec env xs = and OptimizeModuleExprWithSig cenv env mty def = let g = cenv.g - // Optimize the module implementation - let (def, info), (_env, bindInfosColl) = OptimizeModuleContents cenv (env, []) def - let bindInfosColl = List.concat bindInfosColl - + // Compute the elements truly hidden by the module signature. // The hidden set here must contain NOT MORE THAN the set of values made inaccessible by // the application of the signature. If it contains extra elements we'll accidentally eliminate // bindings. - + // This only walks structural elements (Val/Entity declarations), not expressions, + // so it gives the same result before and after optimization. let _renaming, hidden as rpi = ComputeRemappingFromImplementationToSignature g def mty + // Make hiding info available during optimization so TryInlineApplication + // can avoid emitting direct calls to vals hidden by signature. + let cenv = { cenv with signatureHidingInfo = hidden } + + // Optimize the module implementation + let (def, info), (_env, bindInfosColl) = OptimizeModuleContents cenv (env, []) def + let bindInfosColl = List.concat bindInfosColl + let def = if not cenv.settings.LocalOptimizationsEnabled then def else @@ -4500,6 +4514,7 @@ let OptimizeImplFile (settings, ccu, tcGlobals, tcVal, importMap, optEnv, isIncr stackGuard = StackGuard("OptimizerStackGuardDepth") realsig = tcGlobals.realsig specializedInlineVals = HashMultiMap(HashIdentity.Structural, true) + signatureHidingInfo = SignatureHidingInfo.Empty } let env, _, _, _ as results = OptimizeImplFileInternal cenv optEnv isIncrementalFragment hidden mimpls diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs index 342ac0f8a8..dcfb2f9029 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs @@ -922,6 +922,86 @@ open Module let main _ = let result = T.Invoke(3.14) if result.Value = 3.14 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> withReferences [library] + |> asExe + |> compileAndRun + |> shouldSucceed + + [] + let ``Accessibility 06`` () = + let impl = + FsSource """ +module Lib + +module internal Impl = + let inline implFn (x: int) = + x * x + +let inline publicFn (x: int) = + Impl.implFn x + 1 +""" + let fsi = Fsi """ +module Lib + +val inline publicFn: x: int -> int +""" + let library = + fsi + |> withAdditionalSourceFile impl + |> withDebug + |> withNoOptimize + |> asLibrary + + FSharp """ +open Lib + +[] +let main _ = + let i = publicFn 3 + if i = 10 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> withReferences [library] + |> asExe + |> compileAndRun + |> shouldSucceed + + [] + let ``Accessibility 07`` () = + let impl = + FsSource """ +module Lib + +module Impl = + let inline implFn (x: int) = + x * x + +let inline publicFn (x: int) = + Impl.implFn x + 1 +""" + let fsi = Fsi """ +module Lib + +val inline publicFn: x: int -> int +""" + let library = + fsi + |> withAdditionalSourceFile impl + |> withDebug + |> withNoOptimize + |> asLibrary + + FSharp """ +open Lib + +[] +let main _ = + let i = publicFn 3 + if i = 10 then 0 else 1 """ |> withDebug |> withNoOptimize From 0ab324580c8818a8015c938e6ce636f3b599985f Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Tue, 14 Apr 2026 12:59:48 +0200 Subject: [PATCH 19/29] Byref --- src/Compiler/Optimize/Optimizer.fs | 6 +- .../EmittedIL/DebugInlineAsCall.fs | 147 +++++++++++++++++- 2 files changed, 146 insertions(+), 7 deletions(-) diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs index 4c8470c53c..9f47f31c7e 100644 --- a/src/Compiler/Optimize/Optimizer.fs +++ b/src/Compiler/Optimize/Optimizer.fs @@ -3509,7 +3509,11 @@ and TryInlineApplication cenv env finfo (valExpr: Expr) (tyargs: TType list, arg // as a closure that captures type variables and witnesses from the enclosing scope. let valReprInfo = if allTyargsAreConcrete then - Some(InferValReprInfoOfExpr g AllowTypeDirectedDetupling.No specLambdaTy [] [] specLambdaR) + match vref.ValReprInfo with + | Some(ValReprInfo(_, argInfos, retInfo)) -> + Some(ValReprInfo([], argInfos, retInfo)) + | None -> + Some(InferValReprInfoOfExpr g AllowTypeDirectedDetupling.No specLambdaTy [] [] specLambdaR) else None diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs index dcfb2f9029..36de5f4536 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs @@ -171,7 +171,7 @@ let inline triple (x: int) = x + x + x |> withDebug |> withNoOptimize |> asLibrary - |> withName "mylib" + |> withName "Lib" FSharp """ open MyLib @@ -186,7 +186,7 @@ let main _ = |> withReferences [library] |> asExe |> compileAndRun - |> verifyILContains ["call int32 [mylib]MyLib::triple(int32)"] + |> verifyILContains ["call int32 [Lib]MyLib::triple(int32)"] |> shouldSucceed [] @@ -230,6 +230,51 @@ let main _ = "callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0)" ] |> shouldSucceed + [] + let ``Call 13`` () = + FSharp """ +[] +let inline f x = x + 1 + +let inline g x = f x + +g 1 |> ignore +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + + [] + let ``Call 14`` () = + FSharp """ +[] +let inline f x = x + 1 + +let inline g (x: ^T) (y: ^T) = f (x + y) + +g 1 2 |> ignore +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + + [] + let ``Call 15`` () = + FSharp """ +[] +let inline f (x: ^T) = x + +let inline g (x: ^T) (y: ^T) = f (x + y) + +g 1 2 |> ignore +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + [] let ``SRTP 01`` () = FSharp """ @@ -316,7 +361,6 @@ let inline add (x: ^T) (y: ^T) = x + y |> withDebug |> withNoOptimize |> asLibrary - |> withName "mylib2" FSharp """ open MyLib @@ -345,7 +389,6 @@ let inline add (x: ^T) (y: ^T) = x + y |> withDebug |> withNoOptimize |> asLibrary - |> withName "mylib3" FSharp """ open MyLib @@ -683,6 +726,100 @@ type C = static member inline F<'a, 'b, 'c when C<'a, 'b>>(_a: 'a) = () |> compileAndRun |> shouldSucceed + [] + let ``SRTP 19 - byref`` () = + FSharp """ +let inline f<'T, 'U when 'T: (member M: byref<'U> -> unit)> (x: byref<'T>, y: byref<'U>) = + x.M(&y) + +[] +type S = + member _.M(x: byref) = x <- 42 + +[] +let main _ = + let mutable s = S() + let mutable v = 0 + f(&s, &v) + if v = 42 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> shouldSucceed + + [] + let ``SRTP 20 - byref`` () = + let library = + FSharp """ +module MyLib + +let inline f<'T, 'U when 'T: (member M: byref<'U> -> unit)> (x: byref<'T>, y: byref<'U>) = + x.M(&y) +""" + |> withDebug + |> withNoOptimize + |> asLibrary + + FSharp """ +open MyLib + +[] +type S = + member _.M(x: byref) = x <- 42 + +[] +let main _ = + let mutable s = S() + let mutable v = 0 + f(&s, &v) + if v = 42 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> withReferences [library] + |> asExe + |> compileAndRun + |> shouldSucceed + + [] + let ``SRTP 21 - byref`` () = + let library = + FSharp """ +module MyLib + +let inline f<'T, 'U when 'T: (member M: byref<'U> -> unit)> (x: byref<'T>, y: byref<'U>) = + x.M(&y) + +let inline g<'T, 'U when 'T: (member M: byref<'U> -> unit)> (x: byref<'T>, y: byref<'U>) = + f(&x, &y) +""" + |> withDebug + |> withNoOptimize + |> asLibrary + + FSharp """ +open MyLib + +[] +type S = + member _.M(x: byref) = x <- 42 + +[] +let main _ = + let mutable s = S() + let mutable v = 0 + g(&s, &v) + if v = 42 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> withReferences [library] + |> asExe + |> compileAndRun + |> shouldSucceed + [] let ``Member 01 - Non-generic`` () = FSharp """ @@ -851,7 +988,6 @@ type T() = |> withDebug |> withNoOptimize |> asLibrary - |> withName "lib" FSharp """ module App @@ -913,7 +1049,6 @@ type T = |> withDebug |> withNoOptimize |> asLibrary - |> withName "Library" FSharp """ open Module From ddc38be6b311bcbb60769d893aa838a8ea8e1bd2 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Tue, 14 Apr 2026 15:09:27 +0200 Subject: [PATCH 20/29] More verify in tests --- .../EmittedIL/DebugInlineAsCall.fs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs index 36de5f4536..d56d753ae4 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs @@ -244,6 +244,9 @@ g 1 |> ignore |> withNoOptimize |> asExe |> compileAndRun + |> verifyILContains ["call int32 Test::g(int32)"] + |> shouldSucceed + |> verifyILNotPresent ["Test::'__debug"] [] let ``Call 14`` () = @@ -259,6 +262,9 @@ g 1 2 |> ignore |> withNoOptimize |> asExe |> compileAndRun + |> verifyILContains ["call int32 Test::'__debug@7'(int32,"] + |> shouldSucceed + |> verifyILNotPresent ["Test::'__debug"] [] let ``Call 15`` () = @@ -274,6 +280,9 @@ g 1 2 |> ignore |> withNoOptimize |> asExe |> compileAndRun + |> verifyILContains ["call int32 Test::'__debug@7'(int32,"] + |> shouldSucceed + |> verifyILNotPresent ["Test::'__debug"] [] let ``SRTP 01`` () = @@ -474,6 +483,9 @@ let main _ = |> withNoOptimize |> asExe |> compileAndRun + |> verifyILContains + [ "call int32 Test::'__debug@8'(int32," + "call float64 Test::'__debug@9-1'(float64," ] |> shouldSucceed [] @@ -551,6 +563,7 @@ let main _ = |> withNoOptimize |> asExe |> compileAndRun + |> verifyILContains ["call void Test::'__debug@16'(class Test/T)"] |> shouldSucceed [] @@ -580,6 +593,7 @@ let main _ = |> withNoOptimize |> asExe |> compileAndRun + |> verifyILContains ["Test::'__debug@19'()"] |> shouldSucceed [] @@ -613,6 +627,7 @@ let main _ = |> withNoOptimize |> asExe |> compileAndRun + |> verifyILContains ["call int32 Test::'__debug@23'(valuetype Test/S`1)"] |> shouldSucceed [] @@ -636,6 +651,7 @@ let main _ = |> withNoOptimize |> asExe |> compileAndRun + |> verifyILContains ["call int32 Test::'__debug@13'(valuetype Test/S`1)"] |> shouldSucceed [] @@ -664,6 +680,7 @@ type U = static member inline F<'a, 'b when 'a: (member M: unit -> unit)>(_a: 'a |> withNoOptimize |> asExe |> compileAndRun + |> verifyILContains ["Program::'__debug@10'(class Module/T)"] |> shouldSucceed [] @@ -694,6 +711,7 @@ let main _ = |> withReferences [library] |> asExe |> compileAndRun + |> verifyILContains ["Test::'__debug@8'(int32,"] |> shouldSucceed [] @@ -724,6 +742,7 @@ type C = static member inline F<'a, 'b, 'c when C<'a, 'b>>(_a: 'a) = () |> withNoOptimize |> asExe |> compileAndRun + |> verifyILContains ["Program::'__debug@12'(class Program/T)"] |> shouldSucceed [] @@ -747,6 +766,7 @@ let main _ = |> withNoOptimize |> asExe |> compileAndRun + |> verifyILContains ["call void Test::'__debug@13'(valuetype Test/S&,"] |> shouldSucceed [] @@ -781,6 +801,7 @@ let main _ = |> withReferences [library] |> asExe |> compileAndRun + |> verifyILContains ["call void Test::'__debug@12'(valuetype Test/S&,"] |> shouldSucceed [] @@ -818,6 +839,7 @@ let main _ = |> withReferences [library] |> asExe |> compileAndRun + |> verifyILContains ["call void Test::'__debug@12'(valuetype Test/S&,"] |> shouldSucceed [] @@ -955,6 +977,7 @@ let inline f () = fInternal () |> withNoOptimize |> asLibrary |> compile + |> verifyILContains ["call void Module::'__debug@5'()"] |> shouldSucceed [] @@ -973,6 +996,7 @@ type T() = |> withNoOptimize |> asLibrary |> compile + |> verifyILContains ["call void Module/T::'__debug@9'(class Module/T)"] |> shouldSucceed [] @@ -997,6 +1021,7 @@ let r = Lib.T().G(1) |> withNoOptimize |> withReferences [library] |> compile + |> verifyILContains ["Lib/T::G(!!0)"] |> shouldSucceed @@ -1026,6 +1051,7 @@ let main _ = |> withReferences [library] |> asExe |> compileAndRun + |> verifyILContains ["call int32 Test::'__debug@6'(int32,"] |> shouldSucceed [] @@ -1063,6 +1089,7 @@ let main _ = |> withReferences [library] |> asExe |> compileAndRun + |> verifyILContains ["Test::'__debug@6'(float64)"] |> shouldSucceed [] @@ -1089,6 +1116,7 @@ val inline publicFn: x: int -> int |> withDebug |> withNoOptimize |> asLibrary + |> withName "Lib" FSharp """ open Lib @@ -1103,6 +1131,7 @@ let main _ = |> withReferences [library] |> asExe |> compileAndRun + |> verifyILContains ["call int32 [Lib]Lib::publicFn(int32)"] |> shouldSucceed [] @@ -1129,6 +1158,7 @@ val inline publicFn: x: int -> int |> withDebug |> withNoOptimize |> asLibrary + |> withName "Lib" FSharp """ open Lib @@ -1143,4 +1173,5 @@ let main _ = |> withReferences [library] |> asExe |> compileAndRun + |> verifyILContains ["call int32 [Lib]Lib::publicFn(int32)"] |> shouldSucceed From 3aaead6bbb2d6e8ec87fd689744b99599ac77726 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Tue, 14 Apr 2026 18:44:01 +0200 Subject: [PATCH 21/29] Resumable tests --- .../EmittedIL/DebugInlineAsCall.fs | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs index d56d753ae4..d2a90331e4 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs @@ -1175,3 +1175,68 @@ let main _ = |> compileAndRun |> verifyILContains ["call int32 [Lib]Lib::publicFn(int32)"] |> shouldSucceed + + [] + let ``Resumable 01`` () = + FSharp """ +open System.Threading.Tasks + +[] +let main _ = + let t = task { return 1 } + if t.Result = 1 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> shouldSucceed + + [] + let ``Resumable 02`` () = + FSharp """ +open System.Threading.Tasks + +[] +let main _ = + let t = task { + let! x = Task.FromResult(1) + let! y = Task.FromResult(2) + return x + y + } + if t.Result = 3 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> shouldSucceed + + [] + let ``Resumable 03`` () = + FSharp """ +open Microsoft.FSharp.Core.CompilerServices +open Microsoft.FSharp.Core.CompilerServices.StateMachineHelpers +open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators + +[] +type S<'T> = member _.M(_: 'T) = () + +let inline g (_: S<'T>) = + if __useResumableCode then + __stateMachine, int> + (MoveNextMethodImpl<_>(fun _ -> ())) + (SetStateMachineMethodImpl<_>(fun _ _ -> ())) + (AfterCode<_, _>(fun _ -> 42)) + else 42 + +[] +let main _ = + let r = g (S()) + if r = 42 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> shouldSucceed From 79412f1dc4fda35e1447ffe2436355f2e7b80765 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Wed, 15 Apr 2026 09:56:30 +0200 Subject: [PATCH 22/29] Another accessibility attempt --- src/Compiler/Optimize/Optimizer.fs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs index 9f47f31c7e..f4ce5c2952 100644 --- a/src/Compiler/Optimize/Optimizer.fs +++ b/src/Compiler/Optimize/Optimizer.fs @@ -1362,14 +1362,14 @@ let AbstractLazyModulInfoByHiding isAssemblyBoundary (cenv: cenv) mhi = // Check for escape in lambda | CurriedLambdaValue (_, _, _, expr, _) | ConstExprValue(_, expr) when - cenv.settings.inlineNamedFunctions && (let fvs = freeInExpr CollectAll expr - (isAssemblyBoundary && not (freeVarsAllPublic fvs)) || - Zset.exists hiddenVal fvs.FreeLocals || - Zset.exists hiddenTycon fvs.FreeTyvars.FreeTycons || Zset.exists hiddenTyconRepr fvs.FreeLocalTyconReprs || Zset.exists hiddenRecdField fvs.FreeRecdFields || - Zset.exists hiddenUnionCase fvs.FreeUnionCases ) -> + Zset.exists hiddenUnionCase fvs.FreeUnionCases || + (cenv.settings.inlineNamedFunctions && + ((isAssemblyBoundary && not (freeVarsAllPublic fvs)) || + Zset.exists hiddenVal fvs.FreeLocals || + Zset.exists hiddenTycon fvs.FreeTyvars.FreeTycons))) -> UnknownValue // Check for escape in constant From 43ce57af402be16834998aa444fe4b395ff5b9d3 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Wed, 15 Apr 2026 12:14:48 +0200 Subject: [PATCH 23/29] Fix inlined definition check --- src/Compiler/Optimize/Optimizer.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs index f4ce5c2952..46391fcce0 100644 --- a/src/Compiler/Optimize/Optimizer.fs +++ b/src/Compiler/Optimize/Optimizer.fs @@ -1704,7 +1704,7 @@ let TryEliminateBinding cenv _env bind e2 _m = not vspec1.IsCompilerGenerated then None elif vspec1.IsFixed then None - elif vspec1.InlineInfo = ValInline.InlinedDefinition then None + elif not cenv.settings.inlineNamedFunctions && vspec1.InlineInfo = ValInline.InlinedDefinition then None elif vspec1.LogicalName.StartsWithOrdinal stackVarPrefix || vspec1.LogicalName.Contains suffixForVariablesThatMayNotBeEliminated then None else @@ -3974,7 +3974,7 @@ and OptimizeLambdas (vspec: Val option) cenv env valReprInfo expr exprTy = // can't inline any values with semi-recursive object references to self or base let value_ = match vspec with - | Some v when v.InlineInfo = ValInline.InlinedDefinition -> UnknownValue + | Some v when not cenv.settings.inlineNamedFunctions && v.InlineInfo = ValInline.InlinedDefinition -> UnknownValue | _ -> match baseValOpt with From 2dc1443df3ffe0bddcca52cd0186028532c23f61 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Wed, 15 Apr 2026 12:56:35 +0200 Subject: [PATCH 24/29] Optimized to debug --- src/Compiler/Optimize/Optimizer.fs | 10 +++--- .../EmittedIL/DebugInlineAsCall.fs | 35 +++++++++++++++++++ 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs index 46391fcce0..208df34bff 100644 --- a/src/Compiler/Optimize/Optimizer.fs +++ b/src/Compiler/Optimize/Optimizer.fs @@ -3096,7 +3096,9 @@ and TryOptimizeVal cenv env (vOpt: ValRef option, shouldInline, inlineIfLambda, | ConstExprValue(_size, expr) -> Some (remarkExpr m (copyExpr g CloneAllAndMarkExprValsAsCompilerGenerated expr)) - | CurriedLambdaValue (_, _, _, expr, _) when shouldInline || inlineIfLambda -> + | CurriedLambdaValue (_, _, _, expr, _) when + shouldInline && (cenv.settings.inlineNamedFunctions || Option.exists (shouldForceInlineInDebug cenv.g) vOpt) || + inlineIfLambda -> let fvs = freeInExpr CollectLocals expr if fvs.UsesMethodLocalConstructs then // Discarding lambda for binding because uses protected members --- TBD: Should we warn or error here @@ -3113,7 +3115,7 @@ and TryOptimizeVal cenv env (vOpt: ValRef option, shouldInline, inlineIfLambda, warning(Error(FSComp.SR.optValueMarkedInlineHasUnexpectedValue(), m)) None - | _ when shouldInline -> + | _ when shouldInline && cenv.settings.inlineNamedFunctions -> warning(Error(FSComp.SR.optValueMarkedInlineCouldNotBeInlined(), m)) None @@ -3973,10 +3975,6 @@ and OptimizeLambdas (vspec: Val option) cenv env valReprInfo expr exprTy = // can't inline any values with semi-recursive object references to self or base let value_ = - match vspec with - | Some v when not cenv.settings.inlineNamedFunctions && v.InlineInfo = ValInline.InlinedDefinition -> UnknownValue - | _ -> - match baseValOpt with | None -> CurriedLambdaValue (lambdaId, arities, bsize, exprR, exprTy) | Some baseVal -> diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs index d2a90331e4..24c401679d 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs @@ -284,6 +284,41 @@ g 1 2 |> ignore |> shouldSucceed |> verifyILNotPresent ["Test::'__debug"] + [] + let ``Call 16 - Debug lib called from optimized app`` () = + let lib = + FSharp """ +module Module + +let inline double (x: int) = x + x + +let inline quadruple (x: int) = double (double x) +""" + |> withDebug + |> withNoOptimize + |> asLibrary + + lib + |> compile + |> verifyILContains ["call int32 Module::double(int32)"] + |> shouldSucceed + |> ignore + + FSharp """ +open Module + +[] +let main (args: string[]) = + let i = quadruple args.Length + i +""" + |> withOptimize + |> withReferences [lib] + |> asExe + |> compile + |> verifyILContains ["add"] |> shouldSucceed + |> verifyILNotPresent ["quadruple"; "double"] + [] let ``SRTP 01`` () = FSharp """ From 07adb24402a55868d3181f74d3481c0ec23e9382 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Wed, 15 Apr 2026 15:17:52 +0200 Subject: [PATCH 25/29] Update baseline --- ...mplNoInline02.fs.RealInternalSignatureOff.il.bsl | 13 +------------ ...ImplNoInline02.fs.RealInternalSignatureOn.il.bsl | 2 +- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Misc/MethodImplNoInline02.fs.RealInternalSignatureOff.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Misc/MethodImplNoInline02.fs.RealInternalSignatureOff.il.bsl index 80c502560e..5090f0e752 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Misc/MethodImplNoInline02.fs.RealInternalSignatureOff.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Misc/MethodImplNoInline02.fs.RealInternalSignatureOff.il.bsl @@ -16,16 +16,6 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 -} -.mresource public FSharpSignatureCompressedData.assembly -{ - - -} -.mresource public FSharpOptimizationCompressedData.assembly -{ - - } .module assembly.exe @@ -77,7 +67,7 @@ .entrypoint .maxstack 8 - IL_0000: call void assembly::g() + IL_0000: call void assembly::f() IL_0005: nop IL_0006: ret } @@ -88,4 +78,3 @@ - diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Misc/MethodImplNoInline02.fs.RealInternalSignatureOn.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Misc/MethodImplNoInline02.fs.RealInternalSignatureOn.il.bsl index 170b3c6df0..7d67a6cf63 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Misc/MethodImplNoInline02.fs.RealInternalSignatureOn.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Misc/MethodImplNoInline02.fs.RealInternalSignatureOn.il.bsl @@ -68,7 +68,7 @@ { .maxstack 8 - IL_0000: call void assembly::g() + IL_0000: call void assembly::f() IL_0005: nop IL_0006: ret } From 87e613221fc71d2183d1d878bcdf7345563fb02a Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Wed, 15 Apr 2026 16:03:11 +0200 Subject: [PATCH 26/29] Fix Optimize flag in mass-converted tuple tests --- .../Tuples/OptionalArg01.fs.il.netcore.bsl | 600 ++++-------------- .../Tuples/TupleElimination.fs.il.netcore.bsl | 231 ++----- .../EmittedIL/Tuples/Tuples.fs | 25 +- 3 files changed, 186 insertions(+), 670 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Tuples/OptionalArg01.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Tuples/OptionalArg01.fs.il.netcore.bsl index 845bf348e8..caa78fe92e 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Tuples/OptionalArg01.fs.il.netcore.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Tuples/OptionalArg01.fs.il.netcore.bsl @@ -5,11 +5,6 @@ .assembly extern runtime { } .assembly extern FSharp.Core { } -.assembly extern System.Collections -{ - .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) - .ver 9:0:0:0 -} .assembly assembly { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, @@ -70,9 +65,7 @@ IL_0008: ret } - .method public static class [System.Collections]System.Collections.Generic.List`1 - F(class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 x1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 x2) cil managed + .method public static class [runtime]System.Collections.Generic.List`1 F(class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 x1, class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 x2) cil managed { .param [1] .custom instance void [FSharp.Core]Microsoft.FSharp.Core.OptionalArgumentAttribute::.ctor() = ( 01 00 00 00 ) @@ -82,511 +75,152 @@ .maxstack 4 .locals init (int32 V_0, int32 V_1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_2, + class [runtime]System.Collections.Generic.List`1 V_2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_3, - int32 V_4, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_5, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_6, - class [System.Collections]System.Collections.Generic.List`1 V_7, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_8, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_9, - class assembly/A V_10, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_11, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_12, - class assembly/A V_13) - IL_0000: ldc.i4.0 - IL_0001: stloc.0 + class assembly/A V_4) + IL_0000: nop + IL_0001: nop IL_0002: ldarg.0 - IL_0003: stloc.2 - IL_0004: ldloc.2 - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000d - - IL_0009: ldloc.0 - IL_000a: nop - IL_000b: br.s IL_0013 - - IL_000d: ldloc.2 - IL_000e: stloc.3 - IL_000f: ldloc.0 - IL_0010: ldc.i4.1 - IL_0011: add - IL_0012: nop - IL_0013: stloc.1 - IL_0014: ldarg.1 - IL_0015: stloc.s V_5 - IL_0017: ldloc.s V_5 - IL_0019: brfalse.s IL_001d - - IL_001b: br.s IL_0021 + IL_0003: brfalse.s IL_0007 + + IL_0005: br.s IL_000b + + IL_0007: ldc.i4.0 + IL_0008: nop + IL_0009: br.s IL_000d + + IL_000b: ldc.i4.1 + IL_000c: nop + IL_000d: stloc.0 + IL_000e: nop + IL_000f: ldarg.1 + IL_0010: brfalse.s IL_0014 + + IL_0012: br.s IL_0018 + IL_0014: ldloc.0 + IL_0015: nop + IL_0016: br.s IL_001c + + IL_0018: ldloc.0 + IL_0019: ldc.i4.1 + IL_001a: add + IL_001b: nop + IL_001c: stloc.1 IL_001d: ldloc.1 - IL_001e: nop - IL_001f: br.s IL_0029 - - IL_0021: ldloc.s V_5 - IL_0023: stloc.s V_6 - IL_0025: ldloc.1 - IL_0026: ldc.i4.1 - IL_0027: add - IL_0028: nop - IL_0029: stloc.s V_4 - IL_002b: ldloc.s V_4 - IL_002d: newobj instance void class [System.Collections]System.Collections.Generic.List`1::.ctor(int32) - IL_0032: stloc.s V_7 - IL_0034: ldarg.0 - IL_0035: stloc.s V_8 - IL_0037: ldloc.s V_8 - IL_0039: brfalse.s IL_003d - - IL_003b: br.s IL_0041 - - IL_003d: nop - IL_003e: nop - IL_003f: br.s IL_0058 - - IL_0041: ldloc.s V_8 - IL_0043: stloc.s V_9 - IL_0045: ldloc.s V_9 - IL_0047: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() - IL_004c: stloc.s V_10 - IL_004e: ldloc.s V_7 - IL_0050: ldloc.s V_10 - IL_0052: callvirt instance void class [System.Collections]System.Collections.Generic.List`1::Add(!0) - IL_0057: nop - IL_0058: ldarg.1 - IL_0059: stloc.s V_11 - IL_005b: ldloc.s V_11 - IL_005d: brfalse.s IL_0061 - - IL_005f: br.s IL_0065 - - IL_0061: nop - IL_0062: nop - IL_0063: br.s IL_007c - - IL_0065: ldloc.s V_11 - IL_0067: stloc.s V_12 - IL_0069: ldloc.s V_12 - IL_006b: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() - IL_0070: stloc.s V_13 - IL_0072: ldloc.s V_7 - IL_0074: ldloc.s V_13 - IL_0076: callvirt instance void class [System.Collections]System.Collections.Generic.List`1::Add(!0) - IL_007b: nop - IL_007c: ldloc.s V_7 - IL_007e: ret + IL_001e: newobj instance void class [runtime]System.Collections.Generic.List`1::.ctor(int32) + IL_0023: stloc.2 + IL_0024: nop + IL_0025: ldarg.0 + IL_0026: brfalse.s IL_002a + + IL_0028: br.s IL_002e + + IL_002a: nop + IL_002b: nop + IL_002c: br.s IL_0041 + + IL_002e: ldarg.0 + IL_002f: stloc.3 + IL_0030: ldloc.3 + IL_0031: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() + IL_0036: stloc.s V_4 + IL_0038: ldloc.2 + IL_0039: ldloc.s V_4 + IL_003b: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_0040: nop + IL_0041: nop + IL_0042: ldarg.1 + IL_0043: brfalse.s IL_0047 + + IL_0045: br.s IL_004b + + IL_0047: nop + IL_0048: nop + IL_0049: br.s IL_005e + + IL_004b: ldarg.1 + IL_004c: stloc.3 + IL_004d: ldloc.3 + IL_004e: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() + IL_0053: stloc.s V_4 + IL_0055: ldloc.2 + IL_0056: ldloc.s V_4 + IL_0058: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_005d: nop + IL_005e: ldloc.2 + IL_005f: ret } } - .method public static class [System.Collections]System.Collections.Generic.List`1 test() cil managed + .method public static class [runtime]System.Collections.Generic.List`1 test() cil managed { - .maxstack 4 - .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_0, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_1, - int32 V_2, - int32 V_3, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_4, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_5, - int32 V_6, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_7, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_8, - class [System.Collections]System.Collections.Generic.List`1 V_9, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_10, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_11, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_12, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_13) - IL_0000: ldnull - IL_0001: stloc.0 - IL_0002: ldnull - IL_0003: stloc.1 - IL_0004: ldc.i4.0 - IL_0005: stloc.2 - IL_0006: ldloc.0 - IL_0007: stloc.s V_4 - IL_0009: ldloc.s V_4 - IL_000b: brfalse.s IL_000f - - IL_000d: br.s IL_0013 - - IL_000f: ldloc.2 - IL_0010: nop - IL_0011: br.s IL_001b - - IL_0013: ldloc.s V_4 - IL_0015: stloc.s V_5 - IL_0017: ldloc.2 - IL_0018: ldc.i4.1 - IL_0019: add - IL_001a: nop - IL_001b: stloc.3 - IL_001c: ldloc.1 - IL_001d: stloc.s V_7 - IL_001f: ldloc.s V_7 - IL_0021: brfalse.s IL_0025 - - IL_0023: br.s IL_0029 - - IL_0025: ldloc.3 - IL_0026: nop - IL_0027: br.s IL_0031 - - IL_0029: ldloc.s V_7 - IL_002b: stloc.s V_8 - IL_002d: ldloc.3 - IL_002e: ldc.i4.1 - IL_002f: add - IL_0030: nop - IL_0031: stloc.s V_6 - IL_0033: ldloc.s V_6 - IL_0035: newobj instance void class [System.Collections]System.Collections.Generic.List`1::.ctor(int32) - IL_003a: stloc.s V_9 - IL_003c: ldloc.0 - IL_003d: stloc.s V_10 - IL_003f: ldloc.s V_10 - IL_0041: brfalse.s IL_0045 - - IL_0043: br.s IL_0048 - - IL_0045: nop - IL_0046: br.s IL_005b - - IL_0048: ldloc.s V_10 - IL_004a: stloc.s V_11 - IL_004c: ldloc.s V_9 - IL_004e: ldloc.s V_11 - IL_0050: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() - IL_0055: callvirt instance void class [System.Collections]System.Collections.Generic.List`1::Add(!0) - IL_005a: nop - IL_005b: ldloc.1 - IL_005c: stloc.s V_12 - IL_005e: ldloc.s V_12 - IL_0060: brfalse.s IL_0064 - - IL_0062: br.s IL_0067 - - IL_0064: nop - IL_0065: br.s IL_007a - - IL_0067: ldloc.s V_12 - IL_0069: stloc.s V_13 - IL_006b: ldloc.s V_9 - IL_006d: ldloc.s V_13 - IL_006f: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() - IL_0074: callvirt instance void class [System.Collections]System.Collections.Generic.List`1::Add(!0) - IL_0079: nop - IL_007a: ldloc.s V_9 - IL_007c: ret + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: newobj instance void class [runtime]System.Collections.Generic.List`1::.ctor(int32) + IL_0006: ret } - .method public static class [System.Collections]System.Collections.Generic.List`1 test2() cil managed + .method public static class [runtime]System.Collections.Generic.List`1 test2() cil managed { .maxstack 4 - .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_0, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_1, - int32 V_2, - int32 V_3, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_4, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_5, - int32 V_6, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_7, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_8, - class [System.Collections]System.Collections.Generic.List`1 V_9, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_10, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_11, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_12, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_13) + .locals init (class assembly/A V_0, + class [runtime]System.Collections.Generic.List`1 V_1) IL_0000: newobj instance void assembly/A::.ctor() - IL_0005: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::Some(!0) - IL_000a: stloc.0 - IL_000b: ldnull + IL_0005: stloc.0 + IL_0006: ldc.i4.1 + IL_0007: newobj instance void class [runtime]System.Collections.Generic.List`1::.ctor(int32) IL_000c: stloc.1 - IL_000d: ldc.i4.0 - IL_000e: stloc.2 - IL_000f: ldloc.0 - IL_0010: stloc.s V_4 - IL_0012: ldloc.s V_4 - IL_0014: brfalse.s IL_0018 - - IL_0016: br.s IL_001c - - IL_0018: ldloc.2 - IL_0019: nop - IL_001a: br.s IL_0024 - - IL_001c: ldloc.s V_4 - IL_001e: stloc.s V_5 - IL_0020: ldloc.2 - IL_0021: ldc.i4.1 - IL_0022: add - IL_0023: nop - IL_0024: stloc.3 - IL_0025: ldloc.1 - IL_0026: stloc.s V_7 - IL_0028: ldloc.s V_7 - IL_002a: brfalse.s IL_002e - - IL_002c: br.s IL_0032 - - IL_002e: ldloc.3 - IL_002f: nop - IL_0030: br.s IL_003a - - IL_0032: ldloc.s V_7 - IL_0034: stloc.s V_8 - IL_0036: ldloc.3 - IL_0037: ldc.i4.1 - IL_0038: add - IL_0039: nop - IL_003a: stloc.s V_6 - IL_003c: ldloc.s V_6 - IL_003e: newobj instance void class [System.Collections]System.Collections.Generic.List`1::.ctor(int32) - IL_0043: stloc.s V_9 - IL_0045: ldloc.0 - IL_0046: stloc.s V_10 - IL_0048: ldloc.s V_10 - IL_004a: brfalse.s IL_004e - - IL_004c: br.s IL_0051 - - IL_004e: nop - IL_004f: br.s IL_0064 - - IL_0051: ldloc.s V_10 - IL_0053: stloc.s V_11 - IL_0055: ldloc.s V_9 - IL_0057: ldloc.s V_11 - IL_0059: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() - IL_005e: callvirt instance void class [System.Collections]System.Collections.Generic.List`1::Add(!0) - IL_0063: nop - IL_0064: ldloc.1 - IL_0065: stloc.s V_12 - IL_0067: ldloc.s V_12 - IL_0069: brfalse.s IL_006d - - IL_006b: br.s IL_0070 - - IL_006d: nop - IL_006e: br.s IL_0083 - - IL_0070: ldloc.s V_12 - IL_0072: stloc.s V_13 - IL_0074: ldloc.s V_9 - IL_0076: ldloc.s V_13 - IL_0078: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() - IL_007d: callvirt instance void class [System.Collections]System.Collections.Generic.List`1::Add(!0) - IL_0082: nop - IL_0083: ldloc.s V_9 - IL_0085: ret + IL_000d: ldloc.1 + IL_000e: ldloc.0 + IL_000f: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_0014: ldloc.1 + IL_0015: ret } - .method public static class [System.Collections]System.Collections.Generic.List`1 test3() cil managed + .method public static class [runtime]System.Collections.Generic.List`1 test3() cil managed { .maxstack 4 - .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_0, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_1, - int32 V_2, - int32 V_3, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_4, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_5, - int32 V_6, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_7, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_8, - class [System.Collections]System.Collections.Generic.List`1 V_9, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_10, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_11, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_12, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_13) - IL_0000: ldnull - IL_0001: stloc.0 - IL_0002: newobj instance void assembly/A::.ctor() - IL_0007: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::Some(!0) + .locals init (class assembly/A V_0, + class [runtime]System.Collections.Generic.List`1 V_1) + IL_0000: newobj instance void assembly/A::.ctor() + IL_0005: stloc.0 + IL_0006: ldc.i4.1 + IL_0007: newobj instance void class [runtime]System.Collections.Generic.List`1::.ctor(int32) IL_000c: stloc.1 - IL_000d: ldc.i4.0 - IL_000e: stloc.2 - IL_000f: ldloc.0 - IL_0010: stloc.s V_4 - IL_0012: ldloc.s V_4 - IL_0014: brfalse.s IL_0018 - - IL_0016: br.s IL_001c - - IL_0018: ldloc.2 - IL_0019: nop - IL_001a: br.s IL_0024 - - IL_001c: ldloc.s V_4 - IL_001e: stloc.s V_5 - IL_0020: ldloc.2 - IL_0021: ldc.i4.1 - IL_0022: add - IL_0023: nop - IL_0024: stloc.3 - IL_0025: ldloc.1 - IL_0026: stloc.s V_7 - IL_0028: ldloc.s V_7 - IL_002a: brfalse.s IL_002e - - IL_002c: br.s IL_0032 - - IL_002e: ldloc.3 - IL_002f: nop - IL_0030: br.s IL_003a - - IL_0032: ldloc.s V_7 - IL_0034: stloc.s V_8 - IL_0036: ldloc.3 - IL_0037: ldc.i4.1 - IL_0038: add - IL_0039: nop - IL_003a: stloc.s V_6 - IL_003c: ldloc.s V_6 - IL_003e: newobj instance void class [System.Collections]System.Collections.Generic.List`1::.ctor(int32) - IL_0043: stloc.s V_9 - IL_0045: ldloc.0 - IL_0046: stloc.s V_10 - IL_0048: ldloc.s V_10 - IL_004a: brfalse.s IL_004e - - IL_004c: br.s IL_0051 - - IL_004e: nop - IL_004f: br.s IL_0064 - - IL_0051: ldloc.s V_10 - IL_0053: stloc.s V_11 - IL_0055: ldloc.s V_9 - IL_0057: ldloc.s V_11 - IL_0059: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() - IL_005e: callvirt instance void class [System.Collections]System.Collections.Generic.List`1::Add(!0) - IL_0063: nop - IL_0064: ldloc.1 - IL_0065: stloc.s V_12 - IL_0067: ldloc.s V_12 - IL_0069: brfalse.s IL_006d - - IL_006b: br.s IL_0070 - - IL_006d: nop - IL_006e: br.s IL_0083 - - IL_0070: ldloc.s V_12 - IL_0072: stloc.s V_13 - IL_0074: ldloc.s V_9 - IL_0076: ldloc.s V_13 - IL_0078: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() - IL_007d: callvirt instance void class [System.Collections]System.Collections.Generic.List`1::Add(!0) - IL_0082: nop - IL_0083: ldloc.s V_9 - IL_0085: ret + IL_000d: ldloc.1 + IL_000e: ldloc.0 + IL_000f: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_0014: ldloc.1 + IL_0015: ret } - .method public static class [System.Collections]System.Collections.Generic.List`1 test4() cil managed + .method public static class [runtime]System.Collections.Generic.List`1 test4() cil managed { .maxstack 4 - .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_0, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_1, - int32 V_2, - int32 V_3, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_4, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_5, - int32 V_6, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_7, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_8, - class [System.Collections]System.Collections.Generic.List`1 V_9, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_10, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_11, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_12, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_13) + .locals init (class assembly/A V_0, + class assembly/A V_1, + class [runtime]System.Collections.Generic.List`1 V_2) IL_0000: newobj instance void assembly/A::.ctor() - IL_0005: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::Some(!0) - IL_000a: stloc.0 - IL_000b: newobj instance void assembly/A::.ctor() - IL_0010: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::Some(!0) - IL_0015: stloc.1 - IL_0016: ldc.i4.0 - IL_0017: stloc.2 - IL_0018: ldloc.0 - IL_0019: stloc.s V_4 - IL_001b: ldloc.s V_4 - IL_001d: brfalse.s IL_0021 - - IL_001f: br.s IL_0025 - + IL_0005: stloc.0 + IL_0006: newobj instance void assembly/A::.ctor() + IL_000b: stloc.1 + IL_000c: ldc.i4.2 + IL_000d: newobj instance void class [runtime]System.Collections.Generic.List`1::.ctor(int32) + IL_0012: stloc.2 + IL_0013: ldloc.2 + IL_0014: ldloc.0 + IL_0015: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_001a: ldloc.2 + IL_001b: ldloc.1 + IL_001c: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) IL_0021: ldloc.2 - IL_0022: nop - IL_0023: br.s IL_002d - - IL_0025: ldloc.s V_4 - IL_0027: stloc.s V_5 - IL_0029: ldloc.2 - IL_002a: ldc.i4.1 - IL_002b: add - IL_002c: nop - IL_002d: stloc.3 - IL_002e: ldloc.1 - IL_002f: stloc.s V_7 - IL_0031: ldloc.s V_7 - IL_0033: brfalse.s IL_0037 - - IL_0035: br.s IL_003b - - IL_0037: ldloc.3 - IL_0038: nop - IL_0039: br.s IL_0043 - - IL_003b: ldloc.s V_7 - IL_003d: stloc.s V_8 - IL_003f: ldloc.3 - IL_0040: ldc.i4.1 - IL_0041: add - IL_0042: nop - IL_0043: stloc.s V_6 - IL_0045: ldloc.s V_6 - IL_0047: newobj instance void class [System.Collections]System.Collections.Generic.List`1::.ctor(int32) - IL_004c: stloc.s V_9 - IL_004e: ldloc.0 - IL_004f: stloc.s V_10 - IL_0051: ldloc.s V_10 - IL_0053: brfalse.s IL_0057 - - IL_0055: br.s IL_005a - - IL_0057: nop - IL_0058: br.s IL_006d - - IL_005a: ldloc.s V_10 - IL_005c: stloc.s V_11 - IL_005e: ldloc.s V_9 - IL_0060: ldloc.s V_11 - IL_0062: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() - IL_0067: callvirt instance void class [System.Collections]System.Collections.Generic.List`1::Add(!0) - IL_006c: nop - IL_006d: ldloc.1 - IL_006e: stloc.s V_12 - IL_0070: ldloc.s V_12 - IL_0072: brfalse.s IL_0076 - - IL_0074: br.s IL_0079 - - IL_0076: nop - IL_0077: br.s IL_008c - - IL_0079: ldloc.s V_12 - IL_007b: stloc.s V_13 - IL_007d: ldloc.s V_9 - IL_007f: ldloc.s V_13 - IL_0081: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() - IL_0086: callvirt instance void class [System.Collections]System.Collections.Generic.List`1::Add(!0) - IL_008b: nop - IL_008c: ldloc.s V_9 - IL_008e: ret + IL_0022: ret } } diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Tuples/TupleElimination.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Tuples/TupleElimination.fs.il.netcore.bsl index f5931c2d00..e986d8e95e 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Tuples/TupleElimination.fs.il.netcore.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Tuples/TupleElimination.fs.il.netcore.bsl @@ -5,11 +5,6 @@ .assembly extern runtime { } .assembly extern FSharp.Core { } -.assembly extern System.Collections -{ - .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) - .ver 9:0:0:0 -} .assembly assembly { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, @@ -38,187 +33,75 @@ extends [runtime]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit p@5 - extends [FSharp.Core]Microsoft.FSharp.Core.FSharpTypeFunc - { - .field static assembly initonly class assembly/p@5 @_instance - .method assembly specialname rtspecialname instance void .ctor() cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpTypeFunc::.ctor() - IL_0006: ret - } - - .method public strict virtual instance object Specialize() cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: newobj instance void class assembly/p@5T::.ctor(class assembly/p@5) - IL_0006: box class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 - IL_000b: ret - } - - .method private specialname rtspecialname static void .cctor() cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 10 - IL_0000: newobj instance void assembly/p@5::.ctor() - IL_0005: stsfld class assembly/p@5 assembly/p@5::@_instance - IL_000a: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit p@5T - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 - { - .field public class assembly/p@5 self0@ - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(class assembly/p@5 self0@) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class assembly/p@5 class assembly/p@5T::self0@ - IL_000d: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Core.Unit Invoke(!a v) cil managed - { - - .maxstack 7 - .locals init (class assembly/p@5 V_0) - IL_0000: ldarg.0 - IL_0001: ldfld class assembly/p@5 class assembly/p@5T::self0@ - IL_0006: stloc.0 - IL_0007: ldstr "%A" - IL_000c: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [runtime]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,!a>::.ctor(string) - IL_0011: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0016: ldarg.1 - IL_0017: tail. - IL_0019: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_001e: ret - } - - } - .method public static int32 main(string[] argv) cil managed { .entrypoint .custom instance void [FSharp.Core]Microsoft.FSharp.Core.EntryPointAttribute::.ctor() = ( 01 00 00 00 ) .maxstack 5 - .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpTypeFunc V_0, - class [System.Collections]System.Collections.Generic.Dictionary`2 V_1, - class [runtime]System.Tuple`2 V_2, + .locals init (class [runtime]System.Collections.Generic.Dictionary`2 V_0, + int32 V_1, + bool V_2, int32 V_3, - int32 V_4, + int64 V_4, bool V_5, - bool V_6, - int32 V_7, - class [runtime]System.Tuple`2 V_8, - int64 V_9, - int64 V_10, - bool V_11, - bool V_12, - int64 V_13, - class [runtime]System.Tuple`2 V_14, - class [runtime]System.Tuple`2 V_15) - IL_0000: ldsfld class assembly/p@5 assembly/p@5::@_instance + class [runtime]System.Tuple`2 V_6, + int64 V_7) + IL_0000: newobj instance void class [runtime]System.Collections.Generic.Dictionary`2::.ctor() IL_0005: stloc.0 - IL_0006: newobj instance void class [System.Collections]System.Collections.Generic.Dictionary`2::.ctor() - IL_000b: stloc.1 - IL_000c: ldloc.1 - IL_000d: ldc.i4.1 - IL_000e: ldloca.s V_3 - IL_0010: callvirt instance bool class [System.Collections]System.Collections.Generic.Dictionary`2::TryGetValue(!0, + IL_0006: ldloc.0 + IL_0007: ldc.i4.1 + IL_0008: ldloca.s V_1 + IL_000a: callvirt instance bool class [runtime]System.Collections.Generic.Dictionary`2::TryGetValue(!0, !1&) - IL_0015: ldloc.3 - IL_0016: newobj instance void class [runtime]System.Tuple`2::.ctor(!0, - !1) - IL_001b: stloc.2 - IL_001c: ldloc.2 - IL_001d: call instance !1 class [runtime]System.Tuple`2::get_Item2() - IL_0022: stloc.s V_4 - IL_0024: ldloc.2 - IL_0025: call instance !0 class [runtime]System.Tuple`2::get_Item1() - IL_002a: stloc.s V_5 - IL_002c: ldloc.0 - IL_002d: ldloc.s V_5 - IL_002f: stloc.s V_6 - IL_0031: callvirt instance object [FSharp.Core]Microsoft.FSharp.Core.FSharpTypeFunc::Specialize() - IL_0036: unbox.any class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 - IL_003b: ldloc.s V_6 - IL_003d: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0042: pop - IL_0043: ldloc.0 - IL_0044: ldloc.s V_4 - IL_0046: stloc.s V_7 - IL_0048: callvirt instance object [FSharp.Core]Microsoft.FSharp.Core.FSharpTypeFunc::Specialize() - IL_004d: unbox.any class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 - IL_0052: ldloc.s V_7 - IL_0054: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0059: pop - IL_005a: ldstr "123" - IL_005f: ldloca.s V_9 - IL_0061: call bool [runtime]System.Int64::TryParse(string, + IL_000f: stloc.2 + IL_0010: ldstr "%A" + IL_0015: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [runtime]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,bool>::.ctor(string) + IL_001a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_001f: ldloc.2 + IL_0020: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0025: pop + IL_0026: ldloc.1 + IL_0027: stloc.3 + IL_0028: ldstr "%A" + IL_002d: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [runtime]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) + IL_0032: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0037: ldloc.3 + IL_0038: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_003d: pop + IL_003e: ldstr "123" + IL_0043: ldloca.s V_4 + IL_0045: call bool [runtime]System.Int64::TryParse(string, int64&) - IL_0066: ldloc.s V_9 - IL_0068: newobj instance void class [runtime]System.Tuple`2::.ctor(!0, + IL_004a: stloc.s V_5 + IL_004c: ldloc.s V_5 + IL_004e: ldloc.s V_4 + IL_0050: newobj instance void class [runtime]System.Tuple`2::.ctor(!0, !1) - IL_006d: stloc.s V_8 - IL_006f: ldloc.s V_8 - IL_0071: call instance !1 class [runtime]System.Tuple`2::get_Item2() - IL_0076: stloc.s V_10 - IL_0078: ldloc.s V_8 - IL_007a: call instance !0 class [runtime]System.Tuple`2::get_Item1() - IL_007f: stloc.s V_11 - IL_0081: ldloc.0 - IL_0082: ldloc.s V_11 - IL_0084: stloc.s V_12 - IL_0086: callvirt instance object [FSharp.Core]Microsoft.FSharp.Core.FSharpTypeFunc::Specialize() - IL_008b: unbox.any class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 - IL_0090: ldloc.s V_12 - IL_0092: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0097: pop - IL_0098: ldloc.0 - IL_0099: ldloc.s V_10 - IL_009b: stloc.s V_13 - IL_009d: callvirt instance object [FSharp.Core]Microsoft.FSharp.Core.FSharpTypeFunc::Specialize() - IL_00a2: unbox.any class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 - IL_00a7: ldloc.s V_13 - IL_00a9: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_00ae: pop - IL_00af: ldloc.s V_8 - IL_00b1: stloc.s V_14 - IL_00b3: ldloc.0 - IL_00b4: ldloc.s V_14 - IL_00b6: stloc.s V_15 - IL_00b8: callvirt instance object [FSharp.Core]Microsoft.FSharp.Core.FSharpTypeFunc::Specialize>() - IL_00bd: unbox.any class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Core.Unit> - IL_00c2: ldloc.s V_15 - IL_00c4: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Core.Unit>::Invoke(!0) - IL_00c9: pop - IL_00ca: ldc.i4.0 - IL_00cb: ret + IL_0055: stloc.s V_6 + IL_0057: ldstr "%A" + IL_005c: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [runtime]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,bool>::.ctor(string) + IL_0061: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0066: ldloc.s V_5 + IL_0068: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_006d: pop + IL_006e: ldloc.s V_4 + IL_0070: stloc.s V_7 + IL_0072: ldstr "%A" + IL_0077: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [runtime]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int64>::.ctor(string) + IL_007c: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0081: ldloc.s V_7 + IL_0083: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0088: pop + IL_0089: nop + IL_008a: ldstr "%A" + IL_008f: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit>,class [runtime]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [runtime]System.Tuple`2>::.ctor(string) + IL_0094: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine,class [FSharp.Core]Microsoft.FSharp.Core.Unit>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0099: ldloc.s V_6 + IL_009b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Core.Unit>::Invoke(!0) + IL_00a0: pop + IL_00a1: ldc.i4.0 + IL_00a2: ret } } diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Tuples/Tuples.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Tuples/Tuples.fs index 483e270931..b45517a305 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Tuples/Tuples.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Tuples/Tuples.fs @@ -11,7 +11,6 @@ module Tuples = compilation |> withOptions [ "--test:EmitFeeFeeAs100001" ] |> asExe - |> withNoOptimize |> withEmbeddedPdb |> withEmbedAllSource |> ignoreWarnings @@ -19,84 +18,84 @@ module Tuples = |> verifyILBaseline // SOURCE=Tuple01.fs SCFLAGS="-g --test:EmitFeeFeeAs100001 --optimize-" COMPILE_ONLY=1 POSTCMD="..\\CompareIL.cmd Tuple01.exe" # Tuple01.fs - [] + [] let ``Tuple01_fs`` compilation = compilation |> getCompilation |> verifyCompilation // SOURCE=Tuple02.fs SCFLAGS="-g --test:EmitFeeFeeAs100001 --optimize-" COMPILE_ONLY=1 POSTCMD="..\\CompareIL.cmd Tuple02.exe" # Tuple02.fs - - [] + [] let ``Tuple02_fs`` compilation = compilation |> getCompilation |> verifyCompilation // SOURCE=Tuple03.fs SCFLAGS="-g --test:EmitFeeFeeAs100001 --optimize-" COMPILE_ONLY=1 POSTCMD="..\\CompareIL.cmd Tuple03.exe" # Tuple03.fs - - [] + [] let ``Tuple03_fs`` compilation = compilation |> getCompilation |> verifyCompilation // SOURCE=Tuple04.fs SCFLAGS="-g --test:EmitFeeFeeAs100001 --optimize-" COMPILE_ONLY=1 POSTCMD="..\\CompareIL.cmd Tuple04.exe" # Tuple04.fs - - [] + [] let ``Tuple04_fs`` compilation = compilation |> getCompilation |> verifyCompilation // SOURCE=Tuple05.fs SCFLAGS="-g --test:EmitFeeFeeAs100001 --optimize-" COMPILE_ONLY=1 POSTCMD="..\\CompareIL.cmd Tuple05.exe" # Tuple05.fs - - [] + [] let ``Tuple05_fs`` compilation = compilation |> getCompilation |> verifyCompilation // SOURCE=Tuple06.fs SCFLAGS="-g --test:EmitFeeFeeAs100001 --optimize-" COMPILE_ONLY=1 POSTCMD="..\\CompareIL.cmd Tuple06.exe" # Tuple06.fs - - [] + [] let ``Tuple06_fs`` compilation = compilation |> getCompilation |> verifyCompilation // SOURCE=Tuple07.fs SCFLAGS="-g --test:EmitFeeFeeAs100001 --optimize-" COMPILE_ONLY=1 POSTCMD="..\\CompareIL.cmd Tuple07.exe" # Tuple07.fs - - [] + [] let ``Tuple07_fs`` compilation = compilation |> getCompilation |> verifyCompilation // SOURCE=Tuple08.fs SCFLAGS="-g --test:EmitFeeFeeAs100001 --optimize-" COMPILE_ONLY=1 POSTCMD="..\\CompareIL.cmd Tuple08.exe" # Tuple08.fs - - [] + [] let ``Tuple08_fs`` compilation = compilation |> getCompilation |> verifyCompilation // SOURCE=OptionalArg01.fs SCFLAGS="-g --optimize+" COMPILE_ONLY=1 POSTCMD="..\\CompareIL.cmd OptionalArg01.exe" # OptionalArg01.fs - test optimizations - [] + [] let ``OptionalArg01_fs`` compilation = compilation |> getCompilation |> verifyCompilation // SOURCE=TupleMonster.fs SCFLAGS="-g --test:EmitFeeFeeAs100001 --optimize-" COMPILE_ONLY=1 POSTCMD="..\\CompareIL.cmd TupleMonster.exe" # TupleMonster.fs - - [] + [] let ``TupleMonster_fs`` compilation = compilation |> getCompilation |> verifyCompilation // SOURCE=TupleElimination.fs SCFLAGS="-g --test:EmitFeeFeeAs100001 --optimize+" COMPILE_ONLY=1 POSTCMD="..\\CompareIL.cmd TupleElimination.exe" # TupleElimination.fs - - [] + [] let ``TupleElimination_fs`` compilation = compilation |> getCompilation |> verifyCompilation // SOURCE=ValueTupleAliasConstructor.fs SCFLAGS="-g --test:EmitFeeFeeAs100001 --optimize+" COMPILE_ONLY=1 POSTCMD="..\\CompareIL.cmd ValueTupleAliasConstructor.exe" # ValueTupleAliasConstructor.fs - - [] + [] let ``ValueTupleAliasConstructor_fs`` compilation = compilation |> getCompilation From 3b27d906603067a36e892e63ef782db7e3b7d7f7 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Wed, 15 Apr 2026 16:08:08 +0200 Subject: [PATCH 27/29] Async baselines --- ...3.fs.RealInternalSignatureOff.il.debug.bsl | 52 +-- ...t3.fs.RealInternalSignatureOn.il.debug.bsl | 52 +-- ...4.fs.RealInternalSignatureOff.il.debug.bsl | 145 +----- ...t4.fs.RealInternalSignatureOn.il.debug.bsl | 145 +----- ...5.fs.RealInternalSignatureOff.il.debug.bsl | 127 +----- ...t5.fs.RealInternalSignatureOn.il.debug.bsl | 127 +----- ...6.fs.RealInternalSignatureOff.il.debug.bsl | 414 +++--------------- ...t6.fs.RealInternalSignatureOn.il.debug.bsl | 414 +++--------------- 8 files changed, 204 insertions(+), 1272 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest3.fs.RealInternalSignatureOff.il.debug.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest3.fs.RealInternalSignatureOff.il.debug.bsl index 3cd259184d..b95c997fd1 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest3.fs.RealInternalSignatureOff.il.debug.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest3.fs.RealInternalSignatureOff.il.debug.bsl @@ -37,42 +37,6 @@ extends [runtime]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@10-1' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public int32 'value' - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(int32 'value') cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 assembly/assembly/'f3@10-1'::'value' - IL_000d: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld int32 assembly/assembly/'f3@10-1'::'value' - IL_0007: tail. - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::Success(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - !0) - IL_000e: ret - } - - } - .class auto ansi serializable sealed nested assembly beforefieldinit f3@5 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { @@ -100,9 +64,7 @@ .maxstack 7 .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_0, class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_1, - int32 V_2, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_3, - int32 V_4) + int32 V_2) IL_0000: ldc.i4.0 IL_0001: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) IL_0006: stloc.0 @@ -131,14 +93,10 @@ IL_0039: stloc.2 IL_003a: ldarg.0 IL_003b: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f3@5::builder@ - IL_0040: stloc.3 - IL_0041: ldloc.2 - IL_0042: stloc.s V_4 - IL_0044: ldloc.s V_4 - IL_0046: newobj instance void assembly/assembly/'f3@10-1'::.ctor(int32) - IL_004b: tail. - IL_004d: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_0052: ret + IL_0040: ldloc.2 + IL_0041: tail. + IL_0043: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Return(!!0) + IL_0048: ret } } diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest3.fs.RealInternalSignatureOn.il.debug.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest3.fs.RealInternalSignatureOn.il.debug.bsl index 1f5c0f2704..e71ecaac09 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest3.fs.RealInternalSignatureOn.il.debug.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest3.fs.RealInternalSignatureOn.il.debug.bsl @@ -37,42 +37,6 @@ extends [runtime]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@10-1' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public int32 'value' - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(int32 'value') cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 assembly/assembly/'f3@10-1'::'value' - IL_000d: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld int32 assembly/assembly/'f3@10-1'::'value' - IL_0007: tail. - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::Success(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - !0) - IL_000e: ret - } - - } - .class auto ansi serializable sealed nested assembly beforefieldinit f3@5 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { @@ -100,9 +64,7 @@ .maxstack 7 .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_0, class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_1, - int32 V_2, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_3, - int32 V_4) + int32 V_2) IL_0000: ldc.i4.0 IL_0001: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) IL_0006: stloc.0 @@ -131,14 +93,10 @@ IL_0039: stloc.2 IL_003a: ldarg.0 IL_003b: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f3@5::builder@ - IL_0040: stloc.3 - IL_0041: ldloc.2 - IL_0042: stloc.s V_4 - IL_0044: ldloc.s V_4 - IL_0046: newobj instance void assembly/assembly/'f3@10-1'::.ctor(int32) - IL_004b: tail. - IL_004d: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_0052: ret + IL_0040: ldloc.2 + IL_0041: tail. + IL_0043: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Return(!!0) + IL_0048: ret } } diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest4.fs.RealInternalSignatureOff.il.debug.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest4.fs.RealInternalSignatureOff.il.debug.bsl index 348b1d1471..c6dc4802db 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest4.fs.RealInternalSignatureOff.il.debug.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest4.fs.RealInternalSignatureOff.il.debug.bsl @@ -37,42 +37,6 @@ extends [runtime]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit 'f4@10-2' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public int32 'value' - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(int32 'value') cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 assembly/assembly/'f4@10-2'::'value' - IL_000d: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld int32 assembly/assembly/'f4@10-2'::'value' - IL_0007: tail. - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::Success(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - !0) - IL_000e: ret - } - - } - .class auto ansi serializable sealed nested assembly beforefieldinit 'f4@7-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { @@ -103,9 +67,7 @@ .maxstack 6 .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_0, - int32 V_1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_2, - int32 V_3) + int32 V_1) IL_0000: nop IL_0001: ldc.i4.0 IL_0002: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) @@ -124,19 +86,15 @@ IL_0027: stloc.1 IL_0028: ldarg.0 IL_0029: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f4@7-1'::builder@ - IL_002e: stloc.2 - IL_002f: ldloc.1 - IL_0030: stloc.3 - IL_0031: ldloc.3 - IL_0032: newobj instance void assembly/assembly/'f4@10-2'::.ctor(int32) - IL_0037: tail. - IL_0039: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_003e: ret + IL_002e: ldloc.1 + IL_002f: tail. + IL_0031: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Return(!!0) + IL_0036: ret } } - .class auto ansi serializable sealed nested assembly beforefieldinit 'f4@12-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f4@12-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x @@ -150,7 +108,7 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 assembly/assembly/'f4@12-3'::x + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 assembly/assembly/'f4@12-2'::x IL_000d: ret } @@ -160,9 +118,9 @@ .maxstack 8 IL_0000: nop IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 assembly/assembly/'f4@12-3'::x + IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 assembly/assembly/'f4@12-2'::x IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 assembly/assembly/'f4@12-3'::x + IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 assembly/assembly/'f4@12-2'::x IL_000d: callvirt instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1::get_Value() IL_0012: callvirt instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1::set_Value(!0) IL_0017: nop @@ -175,52 +133,6 @@ } - .class auto ansi serializable sealed nested assembly beforefieldinit 'f4@6-4' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 compensation - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 compensation) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f4@6-4'::computation - IL_000d: ldarg.0 - IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/assembly/'f4@6-4'::compensation - IL_0014: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f4@6-4'::computation - IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/assembly/'f4@6-4'::compensation - IL_000d: tail. - IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::TryFinally(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0014: ret - } - - } - .class auto ansi serializable sealed nested assembly beforefieldinit f4@5 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { @@ -245,36 +157,27 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed { - .maxstack 7 - .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_0, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_2, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_3) + .maxstack 8 + .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_0) IL_0000: ldc.i4.0 IL_0001: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) IL_0006: stloc.0 IL_0007: ldarg.0 IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f4@5::builder@ - IL_000d: stloc.1 - IL_000e: ldarg.0 - IL_000f: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f4@5::builder@ - IL_0014: ldarg.0 - IL_0015: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f4@5::builder@ - IL_001a: ldloc.0 - IL_001b: newobj instance void assembly/assembly/'f4@7-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, + IL_000d: ldarg.0 + IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f4@5::builder@ + IL_0013: ldarg.0 + IL_0014: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f4@5::builder@ + IL_0019: ldloc.0 + IL_001a: newobj instance void assembly/assembly/'f4@7-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_0020: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0025: stloc.2 - IL_0026: ldloc.0 - IL_0027: newobj instance void assembly/assembly/'f4@12-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_002c: stloc.3 - IL_002d: ldloc.2 - IL_002e: ldloc.3 - IL_002f: newobj instance void assembly/assembly/'f4@6-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0034: tail. - IL_0036: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_003b: ret + IL_001f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0024: ldloc.0 + IL_0025: newobj instance void assembly/assembly/'f4@12-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_002a: tail. + IL_002c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::TryFinally(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) + IL_0031: ret } } diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest4.fs.RealInternalSignatureOn.il.debug.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest4.fs.RealInternalSignatureOn.il.debug.bsl index 143ba00c7d..0f4b2257cb 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest4.fs.RealInternalSignatureOn.il.debug.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest4.fs.RealInternalSignatureOn.il.debug.bsl @@ -37,42 +37,6 @@ extends [runtime]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit 'f4@10-2' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public int32 'value' - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(int32 'value') cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 assembly/assembly/'f4@10-2'::'value' - IL_000d: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld int32 assembly/assembly/'f4@10-2'::'value' - IL_0007: tail. - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::Success(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - !0) - IL_000e: ret - } - - } - .class auto ansi serializable sealed nested assembly beforefieldinit 'f4@7-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { @@ -103,9 +67,7 @@ .maxstack 6 .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_0, - int32 V_1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_2, - int32 V_3) + int32 V_1) IL_0000: nop IL_0001: ldc.i4.0 IL_0002: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) @@ -124,19 +86,15 @@ IL_0027: stloc.1 IL_0028: ldarg.0 IL_0029: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f4@7-1'::builder@ - IL_002e: stloc.2 - IL_002f: ldloc.1 - IL_0030: stloc.3 - IL_0031: ldloc.3 - IL_0032: newobj instance void assembly/assembly/'f4@10-2'::.ctor(int32) - IL_0037: tail. - IL_0039: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_003e: ret + IL_002e: ldloc.1 + IL_002f: tail. + IL_0031: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Return(!!0) + IL_0036: ret } } - .class auto ansi serializable sealed nested assembly beforefieldinit 'f4@12-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f4@12-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x @@ -150,7 +108,7 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 assembly/assembly/'f4@12-3'::x + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 assembly/assembly/'f4@12-2'::x IL_000d: ret } @@ -160,9 +118,9 @@ .maxstack 8 IL_0000: nop IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 assembly/assembly/'f4@12-3'::x + IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 assembly/assembly/'f4@12-2'::x IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 assembly/assembly/'f4@12-3'::x + IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 assembly/assembly/'f4@12-2'::x IL_000d: callvirt instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1::get_Value() IL_0012: callvirt instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1::set_Value(!0) IL_0017: nop @@ -175,52 +133,6 @@ } - .class auto ansi serializable sealed nested assembly beforefieldinit 'f4@6-4' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 compensation - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 compensation) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f4@6-4'::computation - IL_000d: ldarg.0 - IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/assembly/'f4@6-4'::compensation - IL_0014: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f4@6-4'::computation - IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/assembly/'f4@6-4'::compensation - IL_000d: tail. - IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::TryFinally(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0014: ret - } - - } - .class auto ansi serializable sealed nested assembly beforefieldinit f4@5 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { @@ -245,36 +157,27 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed { - .maxstack 7 - .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_0, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_2, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_3) + .maxstack 8 + .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_0) IL_0000: ldc.i4.0 IL_0001: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) IL_0006: stloc.0 IL_0007: ldarg.0 IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f4@5::builder@ - IL_000d: stloc.1 - IL_000e: ldarg.0 - IL_000f: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f4@5::builder@ - IL_0014: ldarg.0 - IL_0015: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f4@5::builder@ - IL_001a: ldloc.0 - IL_001b: newobj instance void assembly/assembly/'f4@7-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, + IL_000d: ldarg.0 + IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f4@5::builder@ + IL_0013: ldarg.0 + IL_0014: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f4@5::builder@ + IL_0019: ldloc.0 + IL_001a: newobj instance void assembly/assembly/'f4@7-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_0020: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0025: stloc.2 - IL_0026: ldloc.0 - IL_0027: newobj instance void assembly/assembly/'f4@12-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_002c: stloc.3 - IL_002d: ldloc.2 - IL_002e: ldloc.3 - IL_002f: newobj instance void assembly/assembly/'f4@6-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0034: tail. - IL_0036: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_003b: ret + IL_001f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0024: ldloc.0 + IL_0025: newobj instance void assembly/assembly/'f4@12-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_002a: tail. + IL_002c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::TryFinally(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) + IL_0031: ret } } diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest5.fs.RealInternalSignatureOff.il.debug.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest5.fs.RealInternalSignatureOff.il.debug.bsl index 1c4d13e1c3..e9d89b5a24 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest5.fs.RealInternalSignatureOff.il.debug.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest5.fs.RealInternalSignatureOff.il.debug.bsl @@ -166,84 +166,6 @@ } - .class auto ansi serializable sealed nested assembly beforefieldinit 'f7@6-4' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> - { - .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation2 - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation2) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f7@6-4'::computation2 - IL_000d: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar0) cil managed - { - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f7@6-4'::computation2 - IL_0006: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit 'f7@6-5' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation1 - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> part2 - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation1, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> part2) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f7@6-5'::computation1 - IL_000d: ldarg.0 - IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f7@6-5'::part2 - IL_0014: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f7@6-5'::computation1 - IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f7@6-5'::part2 - IL_000d: tail. - IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0014: ret - } - - } - .class auto ansi serializable sealed nested assembly beforefieldinit f7@6 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { @@ -268,40 +190,27 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed { - .maxstack 7 - .locals init (class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_0, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_2, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_3) + .maxstack 8 IL_0000: ldarg.0 IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ - IL_0006: stloc.0 - IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ - IL_000d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 assembly/assembly::get_es() - IL_0012: ldarg.0 - IL_0013: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ - IL_0018: newobj instance void assembly/assembly/'f7@6-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) - IL_001d: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::For(class [runtime]System.Collections.Generic.IEnumerable`1, + IL_0006: ldarg.0 + IL_0007: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ + IL_000c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 assembly/assembly::get_es() + IL_0011: ldarg.0 + IL_0012: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ + IL_0017: newobj instance void assembly/assembly/'f7@6-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) + IL_001c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::For(class [runtime]System.Collections.Generic.IEnumerable`1, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0022: stloc.1 - IL_0023: ldarg.0 - IL_0024: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ - IL_0029: ldarg.0 - IL_002a: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ - IL_002f: newobj instance void assembly/assembly/'f7@9-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) - IL_0034: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0039: stloc.2 - IL_003a: ldloc.2 - IL_003b: newobj instance void assembly/assembly/'f7@6-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1) - IL_0040: stloc.3 - IL_0041: ldloc.1 - IL_0042: ldloc.3 - IL_0043: newobj instance void assembly/assembly/'f7@6-5'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0048: tail. - IL_004a: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_004f: ret + IL_0021: ldarg.0 + IL_0022: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ + IL_0027: ldarg.0 + IL_0028: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ + IL_002d: newobj instance void assembly/assembly/'f7@9-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) + IL_0032: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0037: tail. + IL_0039: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Combine(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1) + IL_003e: ret } } diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest5.fs.RealInternalSignatureOn.il.debug.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest5.fs.RealInternalSignatureOn.il.debug.bsl index f2f84fbd48..abc834a81f 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest5.fs.RealInternalSignatureOn.il.debug.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest5.fs.RealInternalSignatureOn.il.debug.bsl @@ -166,84 +166,6 @@ } - .class auto ansi serializable sealed nested assembly beforefieldinit 'f7@6-4' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> - { - .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation2 - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation2) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f7@6-4'::computation2 - IL_000d: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar0) cil managed - { - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f7@6-4'::computation2 - IL_0006: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit 'f7@6-5' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation1 - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> part2 - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation1, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> part2) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f7@6-5'::computation1 - IL_000d: ldarg.0 - IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f7@6-5'::part2 - IL_0014: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f7@6-5'::computation1 - IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f7@6-5'::part2 - IL_000d: tail. - IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0014: ret - } - - } - .class auto ansi serializable sealed nested assembly beforefieldinit f7@6 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { @@ -268,40 +190,27 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed { - .maxstack 7 - .locals init (class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_0, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_2, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_3) + .maxstack 8 IL_0000: ldarg.0 IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ - IL_0006: stloc.0 - IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ - IL_000d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 assembly/assembly::get_es() - IL_0012: ldarg.0 - IL_0013: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ - IL_0018: newobj instance void assembly/assembly/'f7@6-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) - IL_001d: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::For(class [runtime]System.Collections.Generic.IEnumerable`1, + IL_0006: ldarg.0 + IL_0007: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ + IL_000c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 assembly/assembly::get_es() + IL_0011: ldarg.0 + IL_0012: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ + IL_0017: newobj instance void assembly/assembly/'f7@6-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) + IL_001c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::For(class [runtime]System.Collections.Generic.IEnumerable`1, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0022: stloc.1 - IL_0023: ldarg.0 - IL_0024: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ - IL_0029: ldarg.0 - IL_002a: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ - IL_002f: newobj instance void assembly/assembly/'f7@9-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) - IL_0034: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0039: stloc.2 - IL_003a: ldloc.2 - IL_003b: newobj instance void assembly/assembly/'f7@6-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1) - IL_0040: stloc.3 - IL_0041: ldloc.1 - IL_0042: ldloc.3 - IL_0043: newobj instance void assembly/assembly/'f7@6-5'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0048: tail. - IL_004a: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_004f: ret + IL_0021: ldarg.0 + IL_0022: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ + IL_0027: ldarg.0 + IL_0028: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f7@6::builder@ + IL_002d: newobj instance void assembly/assembly/'f7@9-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) + IL_0032: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0037: tail. + IL_0039: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Combine(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1) + IL_003e: ret } } diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest6.fs.RealInternalSignatureOff.il.debug.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest6.fs.RealInternalSignatureOff.il.debug.bsl index 791fe74ed5..0568407311 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest6.fs.RealInternalSignatureOff.il.debug.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest6.fs.RealInternalSignatureOff.il.debug.bsl @@ -37,42 +37,6 @@ extends [runtime]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit 'f2@10-1' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public int32 'value' - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(int32 'value') cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 assembly/assembly/'f2@10-1'::'value' - IL_000d: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld int32 assembly/assembly/'f2@10-1'::'value' - IL_0007: tail. - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::Success(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - !0) - IL_000e: ret - } - - } - .class auto ansi serializable sealed nested assembly beforefieldinit f2@5 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { @@ -100,9 +64,7 @@ .maxstack 7 .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_0, class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_1, - int32 V_2, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_3, - int32 V_4) + int32 V_2) IL_0000: ldc.i4.0 IL_0001: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) IL_0006: stloc.0 @@ -131,50 +93,10 @@ IL_0039: stloc.2 IL_003a: ldarg.0 IL_003b: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f2@5::builder@ - IL_0040: stloc.3 - IL_0041: ldloc.2 - IL_0042: stloc.s V_4 - IL_0044: ldloc.s V_4 - IL_0046: newobj instance void assembly/assembly/'f2@10-1'::.ctor(int32) - IL_004b: tail. - IL_004d: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_0052: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@20-5' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public int32 'value' - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(int32 'value') cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 assembly/assembly/'f3@20-5'::'value' - IL_000d: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld int32 assembly/assembly/'f3@20-5'::'value' - IL_0007: tail. - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::Success(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - !0) - IL_000e: ret + IL_0040: ldloc.2 + IL_0041: tail. + IL_0043: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Return(!!0) + IL_0048: ret } } @@ -216,9 +138,7 @@ .maxstack 6 .locals init (int32 V_0, - int32 V_1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_2, - int32 V_3) + int32 V_1) IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldarg.0 @@ -232,60 +152,10 @@ IL_0016: stloc.1 IL_0017: ldarg.0 IL_0018: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@19-4'::builder@ - IL_001d: stloc.2 - IL_001e: ldloc.1 - IL_001f: stloc.3 - IL_0020: ldloc.3 - IL_0021: newobj instance void assembly/assembly/'f3@20-5'::.ctor(int32) - IL_0026: tail. - IL_0028: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_002d: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@19-6' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f3@19-6'::computation - IL_000d: ldarg.0 - IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f3@19-6'::binder - IL_0014: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f3@19-6'::computation - IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f3@19-6'::binder - IL_000d: tail. - IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0014: ret + IL_001d: ldloc.1 + IL_001e: tail. + IL_0020: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Return(!!0) + IL_0025: ret } } @@ -318,12 +188,9 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(int32 _arg3) cil managed { - .maxstack 7 + .maxstack 9 .locals init (int32 V_0, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_2, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_3, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_4) + class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_1) IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldc.i4.0 @@ -338,71 +205,19 @@ IL_0017: nop IL_0018: ldarg.0 IL_0019: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@16-3'::builder@ - IL_001e: stloc.2 - IL_001f: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f2() - IL_0024: stloc.3 - IL_0025: ldarg.0 - IL_0026: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@16-3'::builder@ - IL_002b: ldarg.0 - IL_002c: ldfld int32 assembly/assembly/'f3@16-3'::x1 - IL_0031: ldloc.1 - IL_0032: newobj instance void assembly/assembly/'f3@19-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, + IL_001e: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f2() + IL_0023: ldarg.0 + IL_0024: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@16-3'::builder@ + IL_0029: ldarg.0 + IL_002a: ldfld int32 assembly/assembly/'f3@16-3'::x1 + IL_002f: ldloc.1 + IL_0030: newobj instance void assembly/assembly/'f3@19-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, int32, class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_0037: stloc.s V_4 - IL_0039: ldloc.3 - IL_003a: ldloc.s V_4 - IL_003c: newobj instance void assembly/assembly/'f3@19-6'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0041: tail. - IL_0043: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_0048: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@16-7' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f3@16-7'::computation - IL_000d: ldarg.0 - IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f3@16-7'::binder - IL_0014: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f3@16-7'::computation - IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f3@16-7'::binder - IL_000d: tail. - IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0014: ret + IL_0035: tail. + IL_0037: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Bind(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_003c: ret } } @@ -435,78 +250,23 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(int32 _arg2) cil managed { - .maxstack 6 - .locals init (int32 V_0, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_2, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_3) + .maxstack 8 + .locals init (int32 V_0) IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldarg.0 IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@15-2'::builder@ - IL_0008: stloc.1 - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f2() - IL_000e: stloc.2 - IL_000f: ldarg.0 - IL_0010: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@15-2'::builder@ - IL_0015: ldarg.0 - IL_0016: ldfld int32 assembly/assembly/'f3@15-2'::x1 - IL_001b: newobj instance void assembly/assembly/'f3@16-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, - int32) - IL_0020: stloc.3 - IL_0021: ldloc.2 - IL_0022: ldloc.3 - IL_0023: newobj instance void assembly/assembly/'f3@16-7'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0028: tail. - IL_002a: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_002f: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@16-8' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f3@16-8'::computation + IL_0008: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f2() IL_000d: ldarg.0 - IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f3@16-8'::binder - IL_0014: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f3@16-8'::computation - IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f3@16-8'::binder - IL_000d: tail. - IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0014: ret + IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@15-2'::builder@ + IL_0013: ldarg.0 + IL_0014: ldfld int32 assembly/assembly/'f3@15-2'::x1 + IL_0019: newobj instance void assembly/assembly/'f3@16-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, + int32) + IL_001e: tail. + IL_0020: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Bind(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0025: ret } } @@ -535,77 +295,22 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(int32 _arg1) cil managed { - .maxstack 6 - .locals init (int32 V_0, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_2, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_3) + .maxstack 8 + .locals init (int32 V_0) IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldarg.0 IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@14-1'::builder@ - IL_0008: stloc.1 - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f2() - IL_000e: stloc.2 - IL_000f: ldarg.0 - IL_0010: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@14-1'::builder@ - IL_0015: ldloc.0 - IL_0016: newobj instance void assembly/assembly/'f3@15-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, - int32) - IL_001b: stloc.3 - IL_001c: ldloc.2 - IL_001d: ldloc.3 - IL_001e: newobj instance void assembly/assembly/'f3@16-8'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0023: tail. - IL_0025: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_002a: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@16-9' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f3@16-9'::computation + IL_0008: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f2() IL_000d: ldarg.0 - IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f3@16-9'::binder - IL_0014: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f3@16-9'::computation - IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f3@16-9'::binder - IL_000d: tail. - IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0014: ret + IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@14-1'::builder@ + IL_0013: ldloc.0 + IL_0014: newobj instance void assembly/assembly/'f3@15-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, + int32) + IL_0019: tail. + IL_001b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Bind(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0020: ret } } @@ -634,26 +339,17 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed { - .maxstack 6 - .locals init (class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_0, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_2) + .maxstack 8 IL_0000: ldarg.0 IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f3@16::builder@ - IL_0006: stloc.0 - IL_0007: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f2() - IL_000c: stloc.1 - IL_000d: ldarg.0 - IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f3@16::builder@ - IL_0013: newobj instance void assembly/assembly/'f3@14-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) - IL_0018: stloc.2 - IL_0019: ldloc.1 - IL_001a: ldloc.2 - IL_001b: newobj instance void assembly/assembly/'f3@16-9'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0020: tail. - IL_0022: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_0027: ret + IL_0006: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f2() + IL_000b: ldarg.0 + IL_000c: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f3@16::builder@ + IL_0011: newobj instance void assembly/assembly/'f3@14-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) + IL_0016: tail. + IL_0018: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Bind(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_001d: ret } } diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest6.fs.RealInternalSignatureOn.il.debug.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest6.fs.RealInternalSignatureOn.il.debug.bsl index 8afb27a6f7..22e4769fcc 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest6.fs.RealInternalSignatureOn.il.debug.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest6.fs.RealInternalSignatureOn.il.debug.bsl @@ -37,42 +37,6 @@ extends [runtime]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit 'f2@10-1' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public int32 'value' - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(int32 'value') cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 assembly/assembly/'f2@10-1'::'value' - IL_000d: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld int32 assembly/assembly/'f2@10-1'::'value' - IL_0007: tail. - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::Success(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - !0) - IL_000e: ret - } - - } - .class auto ansi serializable sealed nested assembly beforefieldinit f2@5 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { @@ -100,9 +64,7 @@ .maxstack 7 .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_0, class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_1, - int32 V_2, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_3, - int32 V_4) + int32 V_2) IL_0000: ldc.i4.0 IL_0001: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) IL_0006: stloc.0 @@ -131,50 +93,10 @@ IL_0039: stloc.2 IL_003a: ldarg.0 IL_003b: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f2@5::builder@ - IL_0040: stloc.3 - IL_0041: ldloc.2 - IL_0042: stloc.s V_4 - IL_0044: ldloc.s V_4 - IL_0046: newobj instance void assembly/assembly/'f2@10-1'::.ctor(int32) - IL_004b: tail. - IL_004d: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_0052: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@20-5' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public int32 'value' - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(int32 'value') cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 assembly/assembly/'f3@20-5'::'value' - IL_000d: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld int32 assembly/assembly/'f3@20-5'::'value' - IL_0007: tail. - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::Success(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - !0) - IL_000e: ret + IL_0040: ldloc.2 + IL_0041: tail. + IL_0043: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Return(!!0) + IL_0048: ret } } @@ -216,9 +138,7 @@ .maxstack 6 .locals init (int32 V_0, - int32 V_1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_2, - int32 V_3) + int32 V_1) IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldarg.0 @@ -232,60 +152,10 @@ IL_0016: stloc.1 IL_0017: ldarg.0 IL_0018: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@19-4'::builder@ - IL_001d: stloc.2 - IL_001e: ldloc.1 - IL_001f: stloc.3 - IL_0020: ldloc.3 - IL_0021: newobj instance void assembly/assembly/'f3@20-5'::.ctor(int32) - IL_0026: tail. - IL_0028: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_002d: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@19-6' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f3@19-6'::computation - IL_000d: ldarg.0 - IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f3@19-6'::binder - IL_0014: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f3@19-6'::computation - IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f3@19-6'::binder - IL_000d: tail. - IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0014: ret + IL_001d: ldloc.1 + IL_001e: tail. + IL_0020: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Return(!!0) + IL_0025: ret } } @@ -318,12 +188,9 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(int32 _arg3) cil managed { - .maxstack 7 + .maxstack 9 .locals init (int32 V_0, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_2, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_3, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_4) + class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_1) IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldc.i4.0 @@ -338,71 +205,19 @@ IL_0017: nop IL_0018: ldarg.0 IL_0019: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@16-3'::builder@ - IL_001e: stloc.2 - IL_001f: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f2() - IL_0024: stloc.3 - IL_0025: ldarg.0 - IL_0026: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@16-3'::builder@ - IL_002b: ldarg.0 - IL_002c: ldfld int32 assembly/assembly/'f3@16-3'::x1 - IL_0031: ldloc.1 - IL_0032: newobj instance void assembly/assembly/'f3@19-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, + IL_001e: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f2() + IL_0023: ldarg.0 + IL_0024: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@16-3'::builder@ + IL_0029: ldarg.0 + IL_002a: ldfld int32 assembly/assembly/'f3@16-3'::x1 + IL_002f: ldloc.1 + IL_0030: newobj instance void assembly/assembly/'f3@19-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, int32, class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_0037: stloc.s V_4 - IL_0039: ldloc.3 - IL_003a: ldloc.s V_4 - IL_003c: newobj instance void assembly/assembly/'f3@19-6'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0041: tail. - IL_0043: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_0048: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@16-7' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f3@16-7'::computation - IL_000d: ldarg.0 - IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f3@16-7'::binder - IL_0014: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f3@16-7'::computation - IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f3@16-7'::binder - IL_000d: tail. - IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0014: ret + IL_0035: tail. + IL_0037: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Bind(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_003c: ret } } @@ -435,78 +250,23 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(int32 _arg2) cil managed { - .maxstack 6 - .locals init (int32 V_0, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_2, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_3) + .maxstack 8 + .locals init (int32 V_0) IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldarg.0 IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@15-2'::builder@ - IL_0008: stloc.1 - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f2() - IL_000e: stloc.2 - IL_000f: ldarg.0 - IL_0010: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@15-2'::builder@ - IL_0015: ldarg.0 - IL_0016: ldfld int32 assembly/assembly/'f3@15-2'::x1 - IL_001b: newobj instance void assembly/assembly/'f3@16-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, - int32) - IL_0020: stloc.3 - IL_0021: ldloc.2 - IL_0022: ldloc.3 - IL_0023: newobj instance void assembly/assembly/'f3@16-7'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0028: tail. - IL_002a: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_002f: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@16-8' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f3@16-8'::computation + IL_0008: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f2() IL_000d: ldarg.0 - IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f3@16-8'::binder - IL_0014: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f3@16-8'::computation - IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f3@16-8'::binder - IL_000d: tail. - IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0014: ret + IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@15-2'::builder@ + IL_0013: ldarg.0 + IL_0014: ldfld int32 assembly/assembly/'f3@15-2'::x1 + IL_0019: newobj instance void assembly/assembly/'f3@16-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, + int32) + IL_001e: tail. + IL_0020: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Bind(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0025: ret } } @@ -535,77 +295,22 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(int32 _arg1) cil managed { - .maxstack 6 - .locals init (int32 V_0, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_2, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_3) + .maxstack 8 + .locals init (int32 V_0) IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldarg.0 IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@14-1'::builder@ - IL_0008: stloc.1 - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f2() - IL_000e: stloc.2 - IL_000f: ldarg.0 - IL_0010: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@14-1'::builder@ - IL_0015: ldloc.0 - IL_0016: newobj instance void assembly/assembly/'f3@15-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, - int32) - IL_001b: stloc.3 - IL_001c: ldloc.2 - IL_001d: ldloc.3 - IL_001e: newobj instance void assembly/assembly/'f3@16-8'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0023: tail. - IL_0025: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_002a: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@16-9' - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> - { - .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder - .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f3@16-9'::computation + IL_0008: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f2() IL_000d: ldarg.0 - IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f3@16-9'::binder - IL_0014: ret - } - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly/'f3@16-9'::computation - IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/assembly/'f3@16-9'::binder - IL_000d: tail. - IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0014: ret + IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f3@14-1'::builder@ + IL_0013: ldloc.0 + IL_0014: newobj instance void assembly/assembly/'f3@15-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, + int32) + IL_0019: tail. + IL_001b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Bind(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0020: ret } } @@ -634,26 +339,17 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed { - .maxstack 6 - .locals init (class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_0, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_2) + .maxstack 8 IL_0000: ldarg.0 IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f3@16::builder@ - IL_0006: stloc.0 - IL_0007: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f2() - IL_000c: stloc.1 - IL_000d: ldarg.0 - IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f3@16::builder@ - IL_0013: newobj instance void assembly/assembly/'f3@14-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) - IL_0018: stloc.2 - IL_0019: ldloc.1 - IL_001a: ldloc.2 - IL_001b: newobj instance void assembly/assembly/'f3@16-9'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0020: tail. - IL_0022: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) - IL_0027: ret + IL_0006: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f2() + IL_000b: ldarg.0 + IL_000c: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f3@16::builder@ + IL_0011: newobj instance void assembly/assembly/'f3@14-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) + IL_0016: tail. + IL_0018: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Bind(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_001d: ret } } From 11f5c623e371980ad854e85139a7ef720e3ff2ae Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Wed, 15 Apr 2026 17:22:12 +0200 Subject: [PATCH 28/29] Nested inline with different type args --- src/Compiler/Optimize/Optimizer.fs | 33 ++++++++++++++----- .../EmittedIL/DebugInlineAsCall.fs | 23 +++++++++++++ 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs index 208df34bff..0fd81b090a 100644 --- a/src/Compiler/Optimize/Optimizer.fs +++ b/src/Compiler/Optimize/Optimizer.fs @@ -454,8 +454,12 @@ type IncrementalOptimizationEnv = { /// An identifier to help with name generation latestBoundId: Ident option - /// The set of lambda IDs we've inlined to reach this point. Helps to prevent recursive inlining - dontInline: Zset + /// Prevents recursive inlining/specialization. Maps lambda ID to a list of specialized types + /// currently being processed. An empty list means "block unconditionally" (used by normal + /// inlining and non-concrete debug specialization). A non-empty list means "block only these + /// specific type specializations" (used by concrete debug specialization, allowing different + /// type instantiations of the same function to proceed). + dontInline: Map /// Recursively bound vars. If an sub-expression that is a candidate for method splitting /// contains any of these variables then don't split it, for fear of mucking up tailcalls. @@ -479,7 +483,7 @@ type IncrementalOptimizationEnv = static member Empty = { latestBoundId = None - dontInline = Zset.empty Int64.order + dontInline = Map.empty typarInfos = [] functionVal = None dontSplitVars = ValMap.Empty @@ -3481,22 +3485,35 @@ and TryInlineApplication cenv env finfo (valExpr: Expr) (tyargs: TType list, arg let origFinfo = GetInfoForValWithCheck cenv env m vref match stripValue origFinfo.ValExprInfo with - | CurriedLambdaValue(origLambdaId, _, _, origLambda, origLambdaTy) when not (Zset.contains origLambdaId env.dontInline) -> + | CurriedLambdaValue(origLambdaId, _, _, origLambda, origLambdaTy) -> let f2R = CopyExprForInlining cenv true origLambda m let specLambda = MakeApplicationAndBetaReduce g (f2R, origLambdaTy, [tyargs], [], m) let specLambdaTy = tyOfExpr g specLambda + // For concrete type args, only block the exact same (stamp, type) pair, allowing different + // type instantiations to proceed (e.g. sumint> calling sum in its body). + // For non-concrete type args, block unconditionally. + let shouldInline = + match Map.tryFind origLambdaId env.dontInline with + | Some tys -> not allTyargsAreConcrete || tys.IsEmpty || tys |> List.exists (typeEquiv g specLambdaTy) + | None -> false + + if shouldInline then + None else + let specLambdaR = if allTyargsAreConcrete then match cenv.specializedInlineVals.FindAll(origLambdaId) |> List.tryFind (fun (ty, _) -> typeEquiv g ty specLambdaTy) with | Some (_, body) -> copyExpr g CloneAll body | None -> - let specLambdaR, _ = OptimizeExpr cenv { env with dontInline = Zset.add origLambdaId env.dontInline } specLambda + let existingTypes = defaultArg (Map.tryFind origLambdaId env.dontInline) [] + let env = { env with dontInline = Map.add origLambdaId (specLambdaTy :: existingTypes) env.dontInline } + let specLambdaR, _ = OptimizeExpr cenv env specLambda cenv.specializedInlineVals.Add(origLambdaId, (specLambdaTy, specLambdaR)) specLambdaR else - let specLambdaR, _ = OptimizeExpr cenv { env with dontInline = Zset.add origLambdaId env.dontInline } specLambda + let specLambdaR, _ = OptimizeExpr cenv { env with dontInline = Map.add origLambdaId [] env.dontInline } specLambda specLambdaR let specLambdaR = @@ -3537,7 +3554,7 @@ and TryInlineApplication cenv env finfo (valExpr: Expr) (tyargs: TType list, arg cenv.settings.InlineLambdas && not finfo.HasEffect && // Don't inline recursively! - not (Zset.contains lambdaId env.dontInline) && + not (Map.containsKey lambdaId env.dontInline) && (// Check the number of argument groups is enough to saturate the lambdas of the target. (if tyargs |> List.exists (fun t -> match t with TType_measure _ -> false | _ -> true) then 1 else 0) + args.Length = arities && if size <= cenv.settings.lambdaInlineThreshold + args.Length then true @@ -3609,7 +3626,7 @@ and TryInlineApplication cenv env finfo (valExpr: Expr) (tyargs: TType list, arg // Inlining: beta reducing let exprR = MakeApplicationAndBetaReduce g (f2R, f2ty, [tyargs], argsR, m) // Inlining: reoptimizing - Some(OptimizeExpr cenv {env with dontInline= Zset.add lambdaId env.dontInline} exprR) + Some(OptimizeExpr cenv {env with dontInline = Map.add lambdaId [] env.dontInline} exprR) | _ -> None diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs index 24c401679d..406ada6169 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DebugInlineAsCall.fs @@ -877,6 +877,29 @@ let main _ = |> verifyILContains ["call void Test::'__debug@12'(valuetype Test/S&,"] |> shouldSucceed + [] + let ``SRTP 22 - Recursive inline with different type arg`` () = + FSharp """ +type T = T with + static member ($) (T, _:int) = (+) + static member ($) (T, _:decimal) = (+) + +let inline sum (i:'a) (x:'a) :'r = (T $ Unchecked.defaultof<'r>) i x + +type T with + static member inline ($) (T, _:'t -> 'rest) = fun (a:'t) x -> sum (x + a) + +[] +let main _ = + let y:int = sum 2 3 4 + if y = 9 then 0 else 1 +""" + |> withDebug + |> withNoOptimize + |> asExe + |> compileAndRun + |> shouldSucceed + [] let ``Member 01 - Non-generic`` () = FSharp """ From 09d1f9c0a3936af172e17e70e74820e8e991abe5 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Wed, 15 Apr 2026 17:35:32 +0200 Subject: [PATCH 29/29] Update test --- .../Language/StateMachineTests.fs | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/StateMachineTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/StateMachineTests.fs index f7d2ebb906..72b88f6eab 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/StateMachineTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/StateMachineTests.fs @@ -3,13 +3,29 @@ namespace Language open Xunit -open FSharp.Test.Assert open FSharp.Test.Compiler +module StateMachineTests = + let verify3511AndRun code = + Fsx code + |> withNoOptimize + |> compile + |> shouldFail + |> withWarningCode 3511 + |> ignore + + Fsx code + |> withNoOptimize + |> withOptions ["--nowarn:3511"] + |> compileExeAndRun + [] + let ``Nested __useResumableCode is expanded correctly`` () = + FSharp """ // Inlined helper containing a "if __useResumableCode ..." construct failed to expand correctly, // executing the dynmamic branch at runtime even when the state machine was compiled statically. // see https://github.com/dotnet/fsharp/issues/19296 + module FailingInlinedHelper = open FSharp.Core.CompilerServices open FSharp.Core.CompilerServices.StateMachineHelpers @@ -38,25 +54,12 @@ module FailingInlinedHelper = failwith "dynamic state machine" #warnon 3513 -module StateMachineTests = - - let verify3511AndRun code = - Fsx code - |> withNoOptimize - |> compile - |> shouldFail - |> withWarningCode 3511 - |> ignore - - Fsx code - |> withNoOptimize - |> withOptions ["--nowarn:3511"] - |> compileExeAndRun - - [] - let ``Nested __useResumableCode is expanded correctly`` () = - FailingInlinedHelper.repro 42 - |> shouldEqual 42 +let i = FailingInlinedHelper.repro 42 +assert (i = 42) +""" + |> asExe + |> compileAndRun + |> shouldSucceed [] // https://github.com/dotnet/fsharp/issues/13067 let ``Local function with a flexible type``() =