Improve implied lambda and delegate argument names (#15277)

* Improve implied lambda and delegate argument names

* Fix

* Add tests

* Revert non-preview tests

* Sigh

* Re-revert

* Fix test

* Add testx
This commit is contained in:
kerams 2023-06-05 13:44:43 +02:00 коммит произвёл GitHub
Родитель 97c650fe28
Коммит fd25719855
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
23 изменённых файлов: 322 добавлений и 16 удалений

Просмотреть файл

@ -8445,7 +8445,19 @@ and TcUnionCaseOrExnCaseOrActivePatternResultItemThen (cenv: cenv) overallTy env
// This is where the constructor expects arguments but is not applied to arguments, hence build a lambda
numArgTys,
(fun () ->
let vs, args = argTys |> List.mapi (fun i ty -> mkCompGenLocal mItem ("arg" + string i) ty) |> List.unzip
let argNamesIfFeatureEnabled =
if g.langVersion.SupportsFeature LanguageFeature.ImprovedImpliedArgumentNames then
argNames
else
[]
let vs, args =
argTys
|> List.mapi (fun i ty ->
let argName = argNamesIfFeatureEnabled |> List.tryItem i |> Option.map (fun x -> x.idText) |> Option.defaultWith (fun () -> "arg" + string i)
mkCompGenLocal mItem argName ty)
|> List.unzip
let constrApp = mkConstrApp mItem args
let lam = mkMultiLambda mItem vs (constrApp, tyOfExpr g constrApp)
lam)
@ -9535,7 +9547,13 @@ and TcMethodApplication_CheckArguments
let denv = env.DisplayEnv
match curriedCallerArgsOpt with
| None ->
let curriedArgTys, returnTy =
let curriedArgTys, curriedArgNamesIfFeatureEnabled, returnTy =
let paramNamesIfFeatureEnabled (g: TcGlobals) (meth: MethInfo) =
if g.langVersion.SupportsFeature LanguageFeature.ImprovedImpliedArgumentNames then
meth.GetParamNames()
else
[]
match candidates with
// "single named item" rule. This is where we have a single accessible method
// member x.M(arg1, ..., argN)
@ -9547,19 +9565,23 @@ and TcMethodApplication_CheckArguments
// to their default values (for optionals) and be part of the return tuple (for out args).
| [calledMeth] ->
let curriedArgTys, returnTy = UnifyMatchingSimpleArgumentTypes cenv env exprTy.Commit calledMeth mMethExpr mItem
curriedArgTys, MustEqual returnTy
curriedArgTys, paramNamesIfFeatureEnabled g calledMeth, MustEqual returnTy
| _ ->
let domainTy, returnTy = UnifyFunctionType None cenv denv mMethExpr exprTy.Commit
let argTys = if isUnitTy g domainTy then [] else tryDestRefTupleTy g domainTy
// Only apply this rule if a candidate method exists with this number of arguments
let argTys =
if candidates |> List.exists (CalledMethHasSingleArgumentGroupOfThisLength argTys.Length) then
argTys
else
[domainTy]
[argTys], MustEqual returnTy
let argTys, argNames =
match candidates |> List.tryFind (CalledMethHasSingleArgumentGroupOfThisLength argTys.Length) with
| Some meth -> argTys, paramNamesIfFeatureEnabled g meth
| None -> [domainTy], [[None]]
[argTys], argNames, MustEqual returnTy
let lambdaVarsAndExprs = curriedArgTys |> List.mapiSquared (fun i j ty -> mkCompGenLocal mMethExpr ("arg"+string i+string j) ty)
let lambdaVarsAndExprs =
curriedArgTys
|> List.mapiSquared (fun i j ty ->
let argName = curriedArgNamesIfFeatureEnabled |> List.tryItem i |> Option.bind (List.tryItem j) |> Option.flatten |> Option.defaultWith (fun () -> "arg" + string i + string j)
mkCompGenLocal mMethExpr argName ty)
let unnamedCurriedCallerArgs = lambdaVarsAndExprs |> List.mapSquared (fun (_, e) -> CallerArg(tyOfExpr g e, e.Range, false, e))
let namedCurriedCallerArgs = lambdaVarsAndExprs |> List.map (fun _ -> [])
let lambdaVars = List.mapSquared fst lambdaVarsAndExprs

Просмотреть файл

@ -1266,8 +1266,23 @@ let BuildNewDelegateExpr (eventInfoOpt: EventInfo option, g, amap, delegateTy, d
if List.exists (isByrefTy g) delArgTys then
error(Error(FSComp.SR.tcFunctionRequiresExplicitLambda(delArgTys.Length), m))
let delFuncArgNamesIfFeatureEnabled =
match delFuncExpr with
| Expr.Val (valRef = vref) when g.langVersion.SupportsFeature LanguageFeature.ImprovedImpliedArgumentNames ->
match vref.ValReprInfo with
| Some repr when repr.ArgNames.Length = delArgTys.Length -> Some repr.ArgNames
| _ -> None
| _ -> None
let delArgVals =
delArgTys |> List.mapi (fun i argTy -> fst (mkCompGenLocal m ("delegateArg" + string i) argTy))
delArgTys
|> List.mapi (fun i argTy ->
let argName =
match delFuncArgNamesIfFeatureEnabled with
| Some argNames -> argNames[i]
| None -> "delegateArg" + string i
fst (mkCompGenLocal m argName argTy))
let expr =
let args =

Просмотреть файл

@ -1100,6 +1100,21 @@ type MethInfo =
member x.GetFSharpReturnType(amap, m, minst) =
x.GetCompiledReturnType(amap, m, minst) |> GetFSharpViewOfReturnType amap.g
member x.GetParamNames() =
match x with
| FSMeth (g, _, vref, _) ->
ParamNameAndType.FromMember x.IsCSharpStyleExtensionMember g vref |> List.mapSquared (fun (ParamNameAndType (name, _)) -> name |> Option.map (fun x -> x.idText))
| ILMeth (ilMethInfo = ilminfo) ->
// A single group of tupled arguments
[ ilminfo.ParamMetadata |> List.map (fun x -> x.Name) ]
#if !NO_TYPEPROVIDERS
| ProvidedMeth (_, mi, _, m) ->
// A single group of tupled arguments
[ [ for p in mi.PApplyArray((fun mi -> mi.GetParameters()), "GetParameters", m) do
yield p.PUntaint((fun p -> Some p.Name), m) ] ]
#endif
| _ -> []
/// Get the parameter types of a method info
member x.GetParamTypes(amap, m, minst) =
match x with

Просмотреть файл

@ -517,6 +517,9 @@ type MethInfo =
/// Get the ParamData objects for the parameters of a MethInfo
member GetParamDatas: amap: ImportMap * m: range * minst: TType list -> ParamData list list
/// Get the parameter names of a MethInfo
member GetParamNames: unit -> string option list list
/// Get the parameter types of a method info
member GetParamTypes: amap: ImportMap * m: range * minst: TType list -> TType list list

Просмотреть файл

@ -1573,6 +1573,7 @@ featureNonInlineLiteralsAsPrintfFormat,"String values marked as literals and IL
featureNestedCopyAndUpdate,"Nested record field copy-and-update"
featureExtendedStringInterpolation,"Extended string interpolation similar to C# raw string literals."
featureWarningWhenMultipleRecdTypeChoice,"Raises warnings when multiple record type matches were found during name resolution because of overlapping field names."
featureImprovedImpliedArgumentNames,"Improved implied argument names"
3353,fsiInvalidDirective,"Invalid directive '#%s %s'"
3354,tcNotAFunctionButIndexerNamedIndexingNotYetEnabled,"This value supports indexing, e.g. '%s.[index]'. The syntax '%s[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation."
3354,tcNotAFunctionButIndexerIndexingNotYetEnabled,"This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation."

Просмотреть файл

@ -68,6 +68,7 @@ type LanguageFeature =
| NestedCopyAndUpdate
| ExtendedStringInterpolation
| WarningWhenMultipleRecdTypeChoice
| ImprovedImpliedArgumentNames
/// LanguageVersion management
type LanguageVersion(versionText) =
@ -159,6 +160,7 @@ type LanguageVersion(versionText) =
LanguageFeature.NestedCopyAndUpdate, previewVersion
LanguageFeature.ExtendedStringInterpolation, previewVersion
LanguageFeature.WarningWhenMultipleRecdTypeChoice, previewVersion
LanguageFeature.ImprovedImpliedArgumentNames, previewVersion
]
@ -282,6 +284,7 @@ type LanguageVersion(versionText) =
| LanguageFeature.NestedCopyAndUpdate -> FSComp.SR.featureNestedCopyAndUpdate ()
| LanguageFeature.ExtendedStringInterpolation -> FSComp.SR.featureExtendedStringInterpolation ()
| LanguageFeature.WarningWhenMultipleRecdTypeChoice -> FSComp.SR.featureWarningWhenMultipleRecdTypeChoice ()
| LanguageFeature.ImprovedImpliedArgumentNames -> FSComp.SR.featureImprovedImpliedArgumentNames ()
/// Get a version string associated with the given feature.
static member GetFeatureVersionString feature =

Просмотреть файл

@ -58,6 +58,7 @@ type LanguageFeature =
| NestedCopyAndUpdate
| ExtendedStringInterpolation
| WarningWhenMultipleRecdTypeChoice
| ImprovedImpliedArgumentNames
/// LanguageVersion management
type LanguageVersion =

Просмотреть файл

@ -272,6 +272,11 @@
<target state="translated">implicitní yield</target>
<note />
</trans-unit>
<trans-unit id="featureImprovedImpliedArgumentNames">
<source>Improved implied argument names</source>
<target state="new">Improved implied argument names</target>
<note />
</trans-unit>
<trans-unit id="featureIndexerNotationWithoutDot">
<source>expr[idx] notation for indexing and slicing</source>
<target state="translated">Notace expr[idx] pro indexování a vytváření řezů</target>

Просмотреть файл

@ -272,6 +272,11 @@
<target state="translated">implizite yield-Anweisung</target>
<note />
</trans-unit>
<trans-unit id="featureImprovedImpliedArgumentNames">
<source>Improved implied argument names</source>
<target state="new">Improved implied argument names</target>
<note />
</trans-unit>
<trans-unit id="featureIndexerNotationWithoutDot">
<source>expr[idx] notation for indexing and slicing</source>
<target state="translated">expr[idx]-Notation zum Indizieren und Aufteilen</target>

Просмотреть файл

@ -272,6 +272,11 @@
<target state="translated">elemento yield implícito</target>
<note />
</trans-unit>
<trans-unit id="featureImprovedImpliedArgumentNames">
<source>Improved implied argument names</source>
<target state="new">Improved implied argument names</target>
<note />
</trans-unit>
<trans-unit id="featureIndexerNotationWithoutDot">
<source>expr[idx] notation for indexing and slicing</source>
<target state="translated">Notación para indexación y segmentación expr[idx]</target>

Просмотреть файл

@ -272,6 +272,11 @@
<target state="translated">yield implicite</target>
<note />
</trans-unit>
<trans-unit id="featureImprovedImpliedArgumentNames">
<source>Improved implied argument names</source>
<target state="new">Improved implied argument names</target>
<note />
</trans-unit>
<trans-unit id="featureIndexerNotationWithoutDot">
<source>expr[idx] notation for indexing and slicing</source>
<target state="translated">Notation expr[idx] pour lindexation et le découpage</target>

Просмотреть файл

@ -272,6 +272,11 @@
<target state="translated">istruzione yield implicita</target>
<note />
</trans-unit>
<trans-unit id="featureImprovedImpliedArgumentNames">
<source>Improved implied argument names</source>
<target state="new">Improved implied argument names</target>
<note />
</trans-unit>
<trans-unit id="featureIndexerNotationWithoutDot">
<source>expr[idx] notation for indexing and slicing</source>
<target state="translated">Notazione expr[idx] per l'indicizzazione e il sezionamento</target>

Просмотреть файл

@ -272,6 +272,11 @@
<target state="translated">暗黙的な yield</target>
<note />
</trans-unit>
<trans-unit id="featureImprovedImpliedArgumentNames">
<source>Improved implied argument names</source>
<target state="new">Improved implied argument names</target>
<note />
</trans-unit>
<trans-unit id="featureIndexerNotationWithoutDot">
<source>expr[idx] notation for indexing and slicing</source>
<target state="translated">インデックス作成とスライス用の expr[idx] 表記</target>

Просмотреть файл

@ -272,6 +272,11 @@
<target state="translated">암시적 yield</target>
<note />
</trans-unit>
<trans-unit id="featureImprovedImpliedArgumentNames">
<source>Improved implied argument names</source>
<target state="new">Improved implied argument names</target>
<note />
</trans-unit>
<trans-unit id="featureIndexerNotationWithoutDot">
<source>expr[idx] notation for indexing and slicing</source>
<target state="translated">인덱싱 및 슬라이싱을 위한 expr[idx] 표기법</target>

Просмотреть файл

@ -272,6 +272,11 @@
<target state="translated">niejawne słowo kluczowe yield</target>
<note />
</trans-unit>
<trans-unit id="featureImprovedImpliedArgumentNames">
<source>Improved implied argument names</source>
<target state="new">Improved implied argument names</target>
<note />
</trans-unit>
<trans-unit id="featureIndexerNotationWithoutDot">
<source>expr[idx] notation for indexing and slicing</source>
<target state="translated">notacja wyrażenia expr[idx] do indeksowania i fragmentowania</target>

Просмотреть файл

@ -272,6 +272,11 @@
<target state="translated">yield implícito</target>
<note />
</trans-unit>
<trans-unit id="featureImprovedImpliedArgumentNames">
<source>Improved implied argument names</source>
<target state="new">Improved implied argument names</target>
<note />
</trans-unit>
<trans-unit id="featureIndexerNotationWithoutDot">
<source>expr[idx] notation for indexing and slicing</source>
<target state="translated">notação expr[idx] para indexação e fatia</target>

Просмотреть файл

@ -272,6 +272,11 @@
<target state="translated">неявное использование yield</target>
<note />
</trans-unit>
<trans-unit id="featureImprovedImpliedArgumentNames">
<source>Improved implied argument names</source>
<target state="new">Improved implied argument names</target>
<note />
</trans-unit>
<trans-unit id="featureIndexerNotationWithoutDot">
<source>expr[idx] notation for indexing and slicing</source>
<target state="translated">expr[idx] для индексации и среза</target>

Просмотреть файл

@ -272,6 +272,11 @@
<target state="translated">örtük yield</target>
<note />
</trans-unit>
<trans-unit id="featureImprovedImpliedArgumentNames">
<source>Improved implied argument names</source>
<target state="new">Improved implied argument names</target>
<note />
</trans-unit>
<trans-unit id="featureIndexerNotationWithoutDot">
<source>expr[idx] notation for indexing and slicing</source>
<target state="translated">Dizin oluşturma ve dilimleme için expr[idx] gösterimi</target>

Просмотреть файл

@ -272,6 +272,11 @@
<target state="translated">隐式 yield</target>
<note />
</trans-unit>
<trans-unit id="featureImprovedImpliedArgumentNames">
<source>Improved implied argument names</source>
<target state="new">Improved implied argument names</target>
<note />
</trans-unit>
<trans-unit id="featureIndexerNotationWithoutDot">
<source>expr[idx] notation for indexing and slicing</source>
<target state="translated">用于索引和切片的 expr[idx] 表示法</target>

Просмотреть файл

@ -272,6 +272,11 @@
<target state="translated">隱含 yield</target>
<note />
</trans-unit>
<trans-unit id="featureImprovedImpliedArgumentNames">
<source>Improved implied argument names</source>
<target state="new">Improved implied argument names</target>
<note />
</trans-unit>
<trans-unit id="featureIndexerNotationWithoutDot">
<source>expr[idx] notation for indexing and slicing</source>
<target state="translated">用於編製索引和分割的 expr[idx] 註釋</target>

Просмотреть файл

@ -0,0 +1,178 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace FSharp.Compiler.ComponentTests.EmittedIL
open Xunit
open FSharp.Test.Compiler
module ArgumentNames =
[<Fact>]
let ``Implied argument names are taken from method or constructor``() =
FSharp """
module ArgumentNames
type M (name: string, count: int) =
[<System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)>]
static member Open (fileName: string) = ()
let test1 = M
let test2 = M.Open
"""
|> withLangVersionPreview
|> compile
|> shouldSucceed
|> verifyIL ["""
.method public static class ArgumentNames/M
test1(string name,
int32 count) cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: newobj instance void ArgumentNames/M::.ctor(string,
int32)
IL_0007: ret
}
.method public static void test2(string fileName) cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: call void ArgumentNames/M::Open(string)
IL_0006: ret
} """ ]
[<Fact>]
let ``Implied argument names are taken from curried method``() =
FSharp """
module ArgumentNames
type M =
[<System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)>]
static member Write (fileName: string, offset: int) (data: byte[]) = ()
let test1 = M.Write
"""
|> withLangVersionPreview
|> compile
|> shouldSucceed
|> verifyIL ["""
.method public static void test1(string fileName,
int32 offset,
uint8[] data) cil managed
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 02 00 00 00 01 00 00 00 00 00 )
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: ldarg.2
IL_0003: call void ArgumentNames/M::Write(string,
int32,
uint8[])
IL_0008: ret
} """ ]
[<Fact>]
let ``Implied argument names are taken from C#-style extension method``() =
FSharp """
module ArgumentNames
open System.Runtime.CompilerServices
[<Extension>]
type Ext =
[<System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)>]
[<Extension>]
static member Print(x: int, yy: string) = printfn "%d%s" x yy
let test1 = (3).Print
"""
|> withLangVersionPreview
|> compile
|> shouldSucceed
|> verifyIL ["""
Invoke(string yy) cil managed
{
.maxstack 8
IL_0000: ldc.i4.3
IL_0001: ldarg.1
IL_0002: call void ArgumentNames/Ext::Print(int32,
string)
IL_0007: ldnull
IL_0008: ret
} """ ]
[<Fact>]
let ``Implied argument names are taken from DU case constructor or exception``() =
FSharp """
module ArgumentNames
exception X of code: int * string
type DU =
| Case1 of code: int * string
let test1 = X
let test2 = Case1
"""
|> withLangVersionPreview
|> compile
|> shouldSucceed
|> verifyIL ["""
.method public static class [runtime]System.Exception
test1(int32 code,
string Data1) cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: newobj instance void ArgumentNames/X::.ctor(int32,
string)
IL_0007: ret
}
.method public static class ArgumentNames/DU
test2(int32 code,
string Item2) cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call class ArgumentNames/DU ArgumentNames/DU::NewCase1(int32,
string)
IL_0007: ret
} """ ]
[<Fact>]
let ``Implied argument names are taken from function and used in delegate Invoke``() =
FSharp """
module ArgumentNames
[<System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)>]
let add num1 num2 = printfn "%d" (num1 + num2)
let test1 = System.Action<_, _>(add)
"""
|> withLangVersionPreview
|> compile
|> shouldSucceed
|> verifyIL ["""
.method assembly static void Invoke(int32 num1,
int32 num2) cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: tail.
IL_0004: call void ArgumentNames::'add'(int32,
int32)
IL_0009: ret
} """ ]

Просмотреть файл

@ -113,6 +113,7 @@
<Compile Include="EmittedIL\TupleElimination.fs" />
<Compile Include="EmittedIL\TypeTestsInPatternMatching.fs" />
<Compile Include="EmittedIL\WhileLoops.fs" />
<Compile Include="EmittedIL\ArgumentNames.fs" />
<Compile Include="EmittedIL\AssemblyBoundary\AssemblyBoundary.fs" />
<Compile Include="EmittedIL\AsyncExpressionStepping\AsyncExpressionStepping.fs" />
<Compile Include="EmittedIL\AttributeTargets\AttributeTargets.fs" />

Просмотреть файл

@ -661,7 +661,9 @@ let testMutableVar = mutableVar 1
let testMutableConst = mutableConst ()
"""
let createOptions() = createOptionsAux [fileSource1; fileSource2] []
let createOptionsWithArgs args = createOptionsAux [ fileSource1; fileSource2 ] args
let createOptions() = createOptionsWithArgs []
let operatorTests = """
module OperatorTests{0}
@ -732,7 +734,7 @@ let ignoreTestIfStackOverflowExpected () =
/// This test is run in unison with its optimized counterpart below
[<Test>]
let ``Test Unoptimized Declarations Project1`` () =
let cleanup, options = Project1.createOptions()
let cleanup, options = Project1.createOptionsWithArgs [ "--langversion:preview" ]
use _holder = cleanup
let exprChecker = FSharpChecker.Create(keepAssemblyContents=true)
let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate
@ -796,7 +798,7 @@ let ``Test Unoptimized Declarations Project1`` () =
"member .ctor(c,d) = (new Object(); ()) @ (105,5--105,20)";
"member Method(x) (a,b) = 1 @ (106,37--106,38)";
"member CurriedMethod(x) (a1,b1) (a2,b2) = 1 @ (107,63--107,64)";
"let testFunctionThatCallsMultiArgMethods(unitVar0) = let m: M.MultiArgMethods = new MultiArgMethods(3,4) in Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (arg0_0,arg1_0),m.Method(7,8),fun tupledArg -> let arg00: Microsoft.FSharp.Core.int = tupledArg.Item0 in let arg01: Microsoft.FSharp.Core.int = tupledArg.Item1 in fun tupledArg -> let arg10: Microsoft.FSharp.Core.int = tupledArg.Item0 in let arg11: Microsoft.FSharp.Core.int = tupledArg.Item1 in m.CurriedMethod(arg00,arg01,arg10,arg11) (9,10) (11,12)) @ (110,8--110,9)";
"let testFunctionThatCallsMultiArgMethods(unitVar0) = let m: M.MultiArgMethods = new MultiArgMethods(3,4) in Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (arg0_0,arg1_0),m.Method(7,8),fun tupledArg -> let a1: Microsoft.FSharp.Core.int = tupledArg.Item0 in let b1: Microsoft.FSharp.Core.int = tupledArg.Item1 in fun tupledArg -> let a2: Microsoft.FSharp.Core.int = tupledArg.Item0 in let b2: Microsoft.FSharp.Core.int = tupledArg.Item1 in m.CurriedMethod(a1,b1,a2,b2) (9,10) (11,12)) @ (110,8--110,9)";
"let testFunctionThatUsesUnitsOfMeasure(x) (y) = Operators.op_Addition<Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (arg0_0,arg1_0),x,y) @ (122,70--122,75)";
"let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = x in let y2: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.array = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref<Microsoft.FSharp.Core.int> (3) in let y3: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = [I_ldelema (NormalAddress, false, ILArrayShape [(Some 0, None)], !0)](arr,0) in let y4: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (arg0_0,arg1_0),Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (arg0_0,arg1_0),Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (arg0_0,arg1_0),x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (arg0_0,arg1_0),Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (arg0_0,arg1_0),Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (arg0_0,arg1_0),Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (arg0_0,arg1_0),Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (arg0_0,arg1_0),Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (arg0_0,arg1_0),Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (arg0_0,arg1_0),z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray<Microsoft.FSharp.Core.int> (arr,0)),r.contents))))) @ (125,16--125,17)";
"let testFunctionThatUsesStructs1(dt) = dt.AddDays(3) @ (139,57--139,72)";
@ -867,7 +869,7 @@ let ``Test Unoptimized Declarations Project1`` () =
[<Test>]
let ``Test Optimized Declarations Project1`` () =
let cleanup, options = Project1.createOptions()
let cleanup, options = Project1.createOptionsWithArgs [ "--langversion:preview" ]
use _holder = cleanup
let exprChecker = FSharpChecker.Create(keepAssemblyContents=true)
let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate
@ -931,7 +933,7 @@ let ``Test Optimized Declarations Project1`` () =
"member .ctor(c,d) = (new Object(); ()) @ (105,5--105,20)";
"member Method(x) (a,b) = 1 @ (106,37--106,38)";
"member CurriedMethod(x) (a1,b1) (a2,b2) = 1 @ (107,63--107,64)";
"let testFunctionThatCallsMultiArgMethods(unitVar0) = let m: M.MultiArgMethods = new MultiArgMethods(3,4) in Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (arg0_0,arg1_0),m.Method(7,8),let arg00: Microsoft.FSharp.Core.int = 9 in let arg01: Microsoft.FSharp.Core.int = 10 in let arg10: Microsoft.FSharp.Core.int = 11 in let arg11: Microsoft.FSharp.Core.int = 12 in m.CurriedMethod(arg00,arg01,arg10,arg11)) @ (110,8--110,9)";
"let testFunctionThatCallsMultiArgMethods(unitVar0) = let m: M.MultiArgMethods = new MultiArgMethods(3,4) in Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (arg0_0,arg1_0),m.Method(7,8),let a1: Microsoft.FSharp.Core.int = 9 in let b1: Microsoft.FSharp.Core.int = 10 in let a2: Microsoft.FSharp.Core.int = 11 in let b2: Microsoft.FSharp.Core.int = 12 in m.CurriedMethod(a1,b1,a2,b2)) @ (110,8--110,9)";
"let testFunctionThatUsesUnitsOfMeasure(x) (y) = Operators.op_Addition<Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (arg0_0,arg1_0),x,y) @ (122,70--122,75)";
"let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = x in let y2: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.array = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref<Microsoft.FSharp.Core.int> (3) in let y3: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = [I_ldelema (NormalAddress, false, ILArrayShape [(Some 0, None)], !0)](arr,0) in let y4: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (arg0_0,arg1_0),Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (arg0_0,arg1_0),Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (arg0_0,arg1_0),x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (arg0_0,arg1_0),Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (arg0_0,arg1_0),Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (arg0_0,arg1_0),Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (arg0_0,arg1_0),Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (arg0_0,arg1_0),Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (arg0_0,arg1_0),Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (arg0_0,arg1_0),z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray<Microsoft.FSharp.Core.int> (arr,0)),r.contents))))) @ (125,16--125,17)";
"let testFunctionThatUsesStructs1(dt) = dt.AddDays(3) @ (139,57--139,72)";