From 31678f68bcd38dc72628f7dc87e08ab74405a0a5 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Wed, 30 Jun 2021 14:36:56 +0100 Subject: [PATCH 01/13] fix 11620 --- src/fsharp/IlxGen.fs | 42 +++++++++++++++++----------- tests/fsharp/core/innerpoly/test.fsx | 37 ++++++++++++++++++++++++ tests/fsharp/tests.fs | 5 ++++ 3 files changed, 68 insertions(+), 16 deletions(-) diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index 6cefacd50c3..c0cc7ac94d4 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -829,14 +829,14 @@ type ValStorage = | Method of ValReprInfo * ValRef * ILMethodSpec * ILMethodSpec * range * Typars * Typars * CurriedArgInfos * ArgReprInfo list * TraitWitnessInfos * TType list * ArgReprInfo /// Indicates the value is stored at the given position in the closure environment accessed via "ldarg 0" - | Env of ILType * ILFieldSpec * NamedLocalIlxClosureInfo ref option + | Env of ILType * ILFieldSpec * (FreeTyvars * NamedLocalIlxClosureInfo ref) option /// Indicates that the value is an argument of a method being generated | Arg of int /// Indicates that the value is stored in local of the method being generated. NamedLocalIlxClosureInfo is normally empty. /// It is non-empty for 'local type functions', see comments on definition of NamedLocalIlxClosureInfo. - | Local of idx: int * realloc: bool * NamedLocalIlxClosureInfo ref option + | Local of idx: int * realloc: bool * (FreeTyvars * NamedLocalIlxClosureInfo ref) option /// Indicates if there is a shadow local storage for a local, to make sure it gets a good name in debugging and OptionalShadowLocal = @@ -4883,23 +4883,32 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) eenvouter takenNames ex // Partition the free variables when some can be accessed from places besides the immediate environment // Also filter out the current value being bound, if any, as it is available from the "this" // pointer which gives the current closure itself. This is in the case e.g. let rec f = ... f ... + let freeLocals = cloFreeVarResults.FreeLocals |> Zset.elements let cloFreeVars = - cloFreeVarResults.FreeLocals - |> Zset.elements + freeLocals |> List.filter (fun fv -> (thisVars |> List.forall (fun v -> not (valRefEq g (mkLocalValRef fv) v))) && (match StorageForVal cenv.g m fv eenvouter with | (StaticField _ | StaticProperty _ | Method _ | Null) -> false | _ -> true)) - let cloFreeTyvars = cloFreeVarResults.FreeTyvars.FreeTypars |> Zset.elements + // Any closure using values represented as local type functions also captures the type variables captured + // by that local type function + let cloFreeTyvars = + (cloFreeVarResults.FreeTyvars, freeLocals) ||> List.fold (fun ftyvs fv -> + match StorageForVal cenv.g m fv eenvouter with + | Env (_, _, Some (moreFtyvs, _)) + | Local (_, _, Some (moreFtyvs, _)) -> unionFreeTyvars ftyvs moreFtyvs + | _ -> ftyvs) + + let cloFreeTypars = cloFreeTyvars.FreeTypars |> Zset.elements let cloAttribs = [] - let eenvinner = eenvouter |> EnvForTypars cloFreeTyvars + let eenvinner = eenvouter |> EnvForTypars cloFreeTypars let ilCloTyInner = - let ilCloGenericParams = GenGenericParams cenv eenvinner cloFreeTyvars + let ilCloGenericParams = GenGenericParams cenv eenvinner cloFreeTypars mkILFormalBoxedTy ilCloTypeRef ilCloGenericParams // If generating a named closure, add the closure itself as a var, available via "arg0" . @@ -4912,7 +4921,7 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) eenvouter takenNames ex let generateWitnesses = ComputeGenerateWitnesses g eenvinner if generateWitnesses then // The 0 here represents that a closure doesn't reside within a generic class - there are no "enclosing class type parameters" to lop off. - GetTraitWitnessInfosOfTypars g 0 cloFreeTyvars + GetTraitWitnessInfosOfTypars g 0 cloFreeTypars else [] @@ -4948,7 +4957,7 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) eenvouter takenNames ex let eenvinner = eenvinner |> AddStorageForLocalVals g ilCloFreeVarStorage // Return a various results - (cloAttribs, cloFreeTyvars, cloWitnessInfos, cloFreeVars, ilCloTypeRef, ilCloAllFreeVars, eenvinner) + (cloAttribs, cloFreeTypars, cloWitnessInfos, cloFreeVars, ilCloTypeRef, ilCloAllFreeVars, eenvinner) and GetIlxClosureInfo cenv m isLocalTypeFunc canUseStaticField thisVars eenvouter expr = let g = cenv.g @@ -6629,10 +6638,10 @@ and GenSetStorage m cgbuf storage = and CommitGetStorageSequel cenv cgbuf eenv m ty localCloInfo storeSequel = match localCloInfo, storeSequel with - | Some {contents =NamedLocalIlxClosureInfoGenerator _cloinfo}, _ -> + | Some (_, {contents =NamedLocalIlxClosureInfoGenerator _cloinfo}), _ -> error(InternalError("Unexpected generator", m)) - | Some {contents =NamedLocalIlxClosureInfoGenerated cloinfo}, Some (tyargs, args, m, sequel) when not (isNil tyargs) -> + | Some (_, {contents =NamedLocalIlxClosureInfoGenerated cloinfo}), Some (tyargs, args, m, sequel) when not (isNil tyargs) -> let actualRetTy = GenNamedLocalTyFuncCall cenv cgbuf eenv ty cloinfo tyargs m CommitGetStorageSequel cenv cgbuf eenv m actualRetTy None (Some ([], args, m, sequel)) @@ -6728,17 +6737,18 @@ and AllocLocalVal cenv cgbuf v eenv repr scopeMarks = if isUnitTy g ty && not v.IsMutable then Null, eenv else match repr with - | Some r when IsNamedLocalTypeFuncVal g v r -> + | Some repr when IsNamedLocalTypeFuncVal g v repr -> + let ftyvs = (freeInExpr CollectTypars repr).FreeTyvars // known, named, non-escaping type functions let cloinfoGenerate eenv = let eenvinner = {eenv with letBoundVars=(mkLocalValRef v) :: eenv.letBoundVars} - let cloinfo, _, _ = GetIlxClosureInfo cenv v.Range true true [] eenvinner (Option.get repr) + let cloinfo, _, _ = GetIlxClosureInfo cenv v.Range true true [] eenvinner repr cloinfo let idx, realloc, eenv = AllocLocal cenv cgbuf eenv v.IsCompilerGenerated (v.CompiledName g.CompilerGlobalState, g.ilg.typ_Object, false) scopeMarks - Local (idx, realloc, Some(ref (NamedLocalIlxClosureInfoGenerator cloinfoGenerate))), eenv + Local (idx, realloc, Some(ftyvs, ref (NamedLocalIlxClosureInfoGenerator cloinfoGenerate))), eenv | _ -> // normal local let idx, realloc, eenv = AllocLocal cenv cgbuf eenv v.IsCompilerGenerated (v.CompiledName g.CompilerGlobalState, GenTypeOfVal cenv eenv v, v.IsFixed) scopeMarks @@ -6759,8 +6769,8 @@ and AllocStorageForBinds cenv cgbuf scopeMarks eenv binds = match reprOpt with | Some repr -> match repr with - | Local(_, _, Some g) - | Env(_, _, Some g) -> + | Local(_, _, Some (_, g)) + | Env(_, _, Some (_, g)) -> match !g with | NamedLocalIlxClosureInfoGenerator f -> g := NamedLocalIlxClosureInfoGenerated (f eenv) | NamedLocalIlxClosureInfoGenerated _ -> () diff --git a/tests/fsharp/core/innerpoly/test.fsx b/tests/fsharp/core/innerpoly/test.fsx index 752ba98a3dd..f782aa95f1f 100644 --- a/tests/fsharp/core/innerpoly/test.fsx +++ b/tests/fsharp/core/innerpoly/test.fsx @@ -439,6 +439,43 @@ module Bug10408 = | [| |] -> x | _ -> x +module Bug11620A = + + let createService (metadata: 'T) : 'Data when 'Data :> System.IComparable = Unchecked.defaultof<'Data> + + let getCreateServiceCallback<'T> (thing: 'T) = + let getService () : 'Data = createService thing + (fun () -> getService) + +module Bug11620B = + + type Data = interface end + and Service<'Data when 'Data :> Data>() = class end + + type IThing = interface end + and Thing<'T> = { Metadata: 'T } with interface IThing + + let createService metadata = (Service<'Data>()) + + let getCreateServiceCallback<'T> (thing: IThing) = + let upcastThing = + thing + :?> Thing<'T> + let getService () = createService upcastThing.Metadata + (fun () -> getService) + + let main _ = + let dummyThing : Thing = { Thing.Metadata = 42 } + // crash occured on the following line + let callback = getCreateServiceCallback dummyThing + let resolvedService = callback () + printfn "Resolved service: %A" resolvedService + 0 + + main () + + + #if TESTS_AS_APP let RUN() = !failures #else diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index 214fbc8e821..d406e0beb9e 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -73,6 +73,11 @@ module CoreTests = [] let ``genericmeasures-FSI_BASIC`` () = singleTestBuildAndRun "core/genericmeasures" FSI_BASIC + [] + let ``innerpoly-no-optimize-FSC_BASIC`` () = + let cfg = testConfig "core/innerpoly" + singleTestBuildAndRunAux { cfg with fsc_flags = sprintf "%s --optimize-" cfg.fsc_flags } FSC_BASIC + [] let ``innerpoly-FSC_BASIC`` () = singleTestBuildAndRun "core/innerpoly" FSC_BASIC From 321686fd76711de9d604634931c2300df39d2b45 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Wed, 30 Jun 2021 15:53:55 +0100 Subject: [PATCH 02/13] reinstate debug mode testing --- src/fsharp/IlxGen.fs | 53 ++++++++++++-------- tests/fsharp/single-test.fs | 2 + tests/fsharp/tests.fs | 99 +++++++++++++++++++++++++++++++++++-- 3 files changed, 131 insertions(+), 23 deletions(-) diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index c0cc7ac94d4..2f3601e1a39 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -3578,6 +3578,25 @@ and FreeVarStorageForWitnessInfos (cenv: cenv) (eenv: IlxGenEnv) takenNames ilCl ilFv, (w, storage)) |> List.unzip +//-------------------------------------------------------------------------- +// Locally erased type functions +//-------------------------------------------------------------------------- + +/// Check for type lambda with entirely erased type arguments that is stored as +/// local variable (not method or property). For example +// let foo() = +// let a = 0<_> +// () +// in debug code , here `a` will be a TyLamba. However the compiled representation of +// `a` is an integer. +and IsLocalErasedTyLambda g eenv (v: Val) e = + match e with + | Expr.TyLambda (_, tyargs, body, _, _) when + tyargs |> List.forall (fun tp -> tp.IsErased) && + (match StorageForVal g v.Range v eenv with Local _ -> true | _ -> false) -> + Some body + | _ -> None + //-------------------------------------------------------------------------- // Named local type functions //-------------------------------------------------------------------------- @@ -4756,9 +4775,9 @@ and GenGenericArgs m (tyenv: TypeReprEnv) tps = tps |> DropErasedTypars |> List.map (fun c -> (mkILTyvarTy tyenv.[c, m])) /// Generate a local type function contract class and implementation -and GenClosureAsLocalTypeFunction cenv (cgbuf: CodeGenBuffer) eenv isLocalTypeFunc thisVars expr m = +and GenClosureAsLocalTypeFunction cenv (cgbuf: CodeGenBuffer) eenv thisVars expr m = let g = cenv.g - let cloinfo, body, eenvinner = GetIlxClosureInfo cenv m isLocalTypeFunc true thisVars eenv expr + let cloinfo, body, eenvinner = GetIlxClosureInfo cenv m true true thisVars eenv expr let ilCloTypeRef = cloinfo.cloSpec.TypeRef let entryPointInfo = thisVars |> List.map (fun v -> (v, BranchCallClosure (cloinfo.cloArityInfo))) // Now generate the actual closure implementation w.r.t. eenvinner @@ -4783,9 +4802,9 @@ and GenClosureAsLocalTypeFunction cenv (cgbuf: CodeGenBuffer) eenv isLocalTypeFu let cloTypeDefs = GenClosureTypeDefs cenv (ilCloTypeRef, cloinfo.cloILGenericParams, [], cloinfo.ilCloAllFreeVars, ilCloLambdas, ilCtorBody, cloMethods, [], g.ilg.typ_Object, [], Some cloinfo.cloSpec) cloinfo, ilCloTypeRef, cloTypeDefs -and GenClosureAsFirstClassFunction cenv (cgbuf: CodeGenBuffer) eenv isLocalTypeFunc thisVars m expr = +and GenClosureAsFirstClassFunction cenv (cgbuf: CodeGenBuffer) eenv thisVars m expr = let g = cenv.g - let cloinfo, body, eenvinner = GetIlxClosureInfo cenv m isLocalTypeFunc true thisVars eenv expr + let cloinfo, body, eenvinner = GetIlxClosureInfo cenv m false true thisVars eenv expr let entryPointInfo = thisVars |> List.map (fun v -> (v, BranchCallClosure (cloinfo.cloArityInfo))) let ilCloTypeRef = cloinfo.cloSpec.TypeRef @@ -4801,9 +4820,9 @@ and GenLambdaClosure cenv (cgbuf: CodeGenBuffer) eenv isLocalTypeFunc thisVars e let cloinfo, ilCloTypeRef, cloTypeDefs = if isLocalTypeFunc then - GenClosureAsLocalTypeFunction cenv cgbuf eenv isLocalTypeFunc thisVars expr m + GenClosureAsLocalTypeFunction cenv cgbuf eenv thisVars expr m else - GenClosureAsFirstClassFunction cenv cgbuf eenv isLocalTypeFunc thisVars m expr + GenClosureAsFirstClassFunction cenv cgbuf eenv thisVars m expr CountClosure() for cloTypeDef in cloTypeDefs do @@ -6573,26 +6592,20 @@ and GenGetVal cenv cgbuf eenv (v: ValRef, m) sequel = GenGetValRefAndSequel cenv cgbuf eenv m v None GenSequel cenv eenv.cloc cgbuf sequel -and GenBindingRhs cenv cgbuf eenv sp (vspec: Val) e = +and GenBindingRhs cenv cgbuf eenv sp (vspec: Val) expr = let g = cenv.g - match e with + match expr with | Expr.TyLambda _ | Expr.Lambda _ -> - let isLocalTypeFunc = IsNamedLocalTypeFuncVal g vspec e - match e with - | Expr.TyLambda (_, tyargs, body, _, ttype) when - ( - tyargs |> List.forall (fun tp -> tp.IsErased) && - (match StorageForVal g vspec.Range vspec eenv with Local _ -> true | _ -> false) && - (isLocalTypeFunc || isStructOrEnumTyconTy g ttype) - ) -> - // type lambda with erased type arguments that is stored as local variable (not method or property)- inline body + match IsLocalErasedTyLambda g eenv vspec expr with + | Some body -> GenExpr cenv cgbuf eenv sp body Continue - | _ -> + | None -> + let isLocalTypeFunc = IsNamedLocalTypeFuncVal g vspec expr let thisVars = if isLocalTypeFunc then [] else [ mkLocalValRef vspec ] - GenLambda cenv cgbuf eenv isLocalTypeFunc thisVars e Continue + GenLambda cenv cgbuf eenv isLocalTypeFunc thisVars expr Continue | _ -> - GenExpr cenv cgbuf eenv sp e Continue + GenExpr cenv cgbuf eenv sp expr Continue and CommitStartScope cgbuf startScopeMarkOpt = match startScopeMarkOpt with diff --git a/tests/fsharp/single-test.fs b/tests/fsharp/single-test.fs index 31b26fa76cb..09d4d4b090f 100644 --- a/tests/fsharp/single-test.fs +++ b/tests/fsharp/single-test.fs @@ -9,6 +9,7 @@ open FSharp.Compiler.IO type Permutation = | FSC_CORECLR + | FSC_CORECLR_OPT_MINUS | FSC_CORECLR_BUILDONLY | FSI_CORECLR #if !NETCOREAPP @@ -304,6 +305,7 @@ let singleTestBuildAndRunCore cfg copyFiles p languageVersion = match p with | FSC_CORECLR -> executeSingleTestBuildAndRun OutputType.Exe "coreclr" "net5.0" true false + | FSC_CORECLR_OPT_MINUS -> executeSingleTestBuildAndRun OutputType.Exe "coreclr" "net5.0" false false | FSC_CORECLR_BUILDONLY -> executeSingleTestBuildAndRun OutputType.Exe "coreclr" "net5.0" true true | FSI_CORECLR -> executeSingleTestBuildAndRun OutputType.Script "coreclr" "net5.0" true false diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index d406e0beb9e..31fc53a8112 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -21,10 +21,12 @@ open HandleExpects #if NETCOREAPP // Use these lines if you want to test CoreCLR let FSC_BASIC = FSC_CORECLR +let FSC_BASIC_OPT_MINUS = FSC_CORECLR_OPT_MINUS let FSC_BUILDONLY = FSC_CORECLR_BUILDONLY let FSI_BASIC = FSI_CORECLR #else let FSC_BASIC = FSC_OPT_PLUS_DEBUG +let FSC_BASIC_OPT_MINUS = FSC_OPT_MINUS_DEBUG let FSI_BASIC = FSI_FILE #endif // ^^^^^^^^^^^^ To run these tests in F# Interactive , 'build net40', then send this chunk, then evaluate body of a test ^^^^^^^^^^^^ @@ -37,36 +39,54 @@ let testConfig = getTestsDirectory >> testConfig [] module CoreTests = // These tests are enabled for .NET Framework and .NET Core + [] + let ``access-FSC_BASIC_OPT_MINUS``() = singleTestBuildAndRun "core/access" FSC_BASIC_OPT_MINUS + [] let ``access-FSC_BASIC``() = singleTestBuildAndRun "core/access" FSC_BASIC [] let ``access-FSI_BASIC``() = singleTestBuildAndRun "core/access" FSI_BASIC + [] + let ``apporder-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/apporder" FSC_BASIC_OPT_MINUS + [] let ``apporder-FSC_BASIC`` () = singleTestBuildAndRun "core/apporder" FSC_BASIC [] let ``apporder-FSI_BASIC`` () = singleTestBuildAndRun "core/apporder" FSI_BASIC + [] + let ``array-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/array" FSC_BASIC_OPT_MINUS + [] let ``array-FSC_BASIC`` () = singleTestBuildAndRun "core/array" FSC_BASIC [] let ``array-FSI_BASIC`` () = singleTestBuildAndRun "core/array" FSI_BASIC + [] + let ``comprehensions-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/comprehensions" FSC_BASIC_OPT_MINUS + [] let ``comprehensions-FSC_BASIC`` () = singleTestBuildAndRun "core/comprehensions" FSC_BASIC [] let ``comprehensions-FSI_BASIC`` () = singleTestBuildAndRun "core/comprehensions" FSI_BASIC + [] + let ``comprehensionshw-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/comprehensions-hw" FSC_BASIC_OPT_MINUS + [] let ``comprehensionshw-FSC_BASIC`` () = singleTestBuildAndRun "core/comprehensions-hw" FSC_BASIC [] let ``comprehensionshw-FSI_BASIC`` () = singleTestBuildAndRun "core/comprehensions-hw" FSI_BASIC + [] + let ``genericmeasures-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/genericmeasures" FSC_BASIC_OPT_MINUS + [] let ``genericmeasures-FSC_BASIC`` () = singleTestBuildAndRun "core/genericmeasures" FSC_BASIC @@ -74,9 +94,7 @@ module CoreTests = let ``genericmeasures-FSI_BASIC`` () = singleTestBuildAndRun "core/genericmeasures" FSI_BASIC [] - let ``innerpoly-no-optimize-FSC_BASIC`` () = - let cfg = testConfig "core/innerpoly" - singleTestBuildAndRunAux { cfg with fsc_flags = sprintf "%s --optimize-" cfg.fsc_flags } FSC_BASIC + let ``innerpoly-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/innerpoly" FSC_BASIC_OPT_MINUS [] let ``innerpoly-FSC_BASIC`` () = singleTestBuildAndRun "core/innerpoly" FSC_BASIC @@ -84,57 +102,87 @@ module CoreTests = [] let ``innerpoly-FSI_BASIC`` () = singleTestBuildAndRun "core/innerpoly" FSI_BASIC + [] + let ``namespaceAttributes-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/namespaces" FSC_BASIC_OPT_MINUS + [] let ``namespaceAttributes-FSC_BASIC`` () = singleTestBuildAndRun "core/namespaces" FSC_BASIC + [] + let ``unicode2-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/unicode" FSC_BASIC_OPT_MINUS // TODO: fails on coreclr + [] let ``unicode2-FSC_BASIC`` () = singleTestBuildAndRun "core/unicode" FSC_BASIC // TODO: fails on coreclr [] let ``unicode2-FSI_BASIC`` () = singleTestBuildAndRun "core/unicode" FSI_BASIC + [] + let ``lazy test-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/lazy" FSC_BASIC_OPT_MINUS + [] let ``lazy test-FSC_BASIC`` () = singleTestBuildAndRun "core/lazy" FSC_BASIC [] let ``lazy test-FSI_BASIC`` () = singleTestBuildAndRun "core/lazy" FSI_BASIC + [] + let ``letrec-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/letrec" FSC_BASIC_OPT_MINUS + [] let ``letrec-FSC_BASIC`` () = singleTestBuildAndRun "core/letrec" FSC_BASIC [] let ``letrec-FSI_BASIC`` () = singleTestBuildAndRun "core/letrec" FSI_BASIC + [] + let ``letrec (mutrec variations part one) FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/letrec-mutrec" FSC_BASIC_OPT_MINUS + [] let ``letrec (mutrec variations part one) FSC_BASIC`` () = singleTestBuildAndRun "core/letrec-mutrec" FSC_BASIC [] let ``letrec (mutrec variations part one) FSI_BASIC`` () = singleTestBuildAndRun "core/letrec-mutrec" FSI_BASIC + [] + let ``libtest-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/libtest" FSC_BASIC_OPT_MINUS + [] let ``libtest-FSC_BASIC`` () = singleTestBuildAndRun "core/libtest" FSC_BASIC [] let ``libtest-FSI_BASIC`` () = singleTestBuildAndRun "core/libtest" FSI_BASIC + [] + let ``lift-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/lift" FSC_BASIC_OPT_MINUS + [] let ``lift-FSC_BASIC`` () = singleTestBuildAndRun "core/lift" FSC_BASIC [] let ``lift-FSI_BASIC`` () = singleTestBuildAndRun "core/lift" FSI_BASIC + [] + let ``map-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/map" FSC_BASIC_OPT_MINUS + [] let ``map-FSC_BASIC`` () = singleTestBuildAndRun "core/map" FSC_BASIC [] let ``map-FSI_BASIC`` () = singleTestBuildAndRun "core/map" FSI_BASIC + [] + let ``measures-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/measures" FSC_BASIC_OPT_MINUS + [] let ``measures-FSC_BASIC`` () = singleTestBuildAndRun "core/measures" FSC_BASIC [] let ``measures-FSI_BASIC`` () = singleTestBuildAndRun "core/measures" FSI_BASIC + [] + let ``nested-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/nested" FSC_BASIC_OPT_MINUS + [] let ``nested-FSC_BASIC`` () = singleTestBuildAndRun "core/nested" FSC_BASIC @@ -144,15 +192,24 @@ module CoreTests = [] let ``members-ops-FSC_BASIC`` () = singleTestBuildAndRun "core/members/ops" FSC_BASIC + [] + let ``members-ops-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/members/ops" FSC_BASIC_OPT_MINUS + [] let ``members-ops-FSI_BASIC`` () = singleTestBuildAndRun "core/members/ops" FSI_BASIC + [] + let ``members-ops-mutrec-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/members/ops-mutrec" FSC_BASIC_OPT_MINUS + [] let ``members-ops-mutrec-FSC_BASIC`` () = singleTestBuildAndRun "core/members/ops-mutrec" FSC_BASIC [] let ``members-ops-mutrec-FSI_BASIC`` () = singleTestBuildAndRun "core/members/ops-mutrec" FSI_BASIC + [] + let ``seq-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/seq" FSC_BASIC_OPT_MINUS + [] let ``seq-FSC_BASIC`` () = singleTestBuildAndRun "core/seq" FSC_BASIC @@ -165,36 +222,54 @@ module CoreTests = [] let ``math-numbers-FSI_BASIC`` () = singleTestBuildAndRun "core/math/numbers" FSI_BASIC + [] + let ``members-ctree-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/members/ctree" FSC_BASIC_OPT_MINUS + [] let ``members-ctree-FSC_BASIC`` () = singleTestBuildAndRun "core/members/ctree" FSC_BASIC [] let ``members-ctree-FSI_BASIC`` () = singleTestBuildAndRun "core/members/ctree" FSI_BASIC + [] + let ``members-factors-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/members/factors" FSC_BASIC_OPT_MINUS + [] let ``members-factors-FSC_BASIC`` () = singleTestBuildAndRun "core/members/factors" FSC_BASIC [] let ``members-factors-FSI_BASIC`` () = singleTestBuildAndRun "core/members/factors" FSI_BASIC + [] + let ``members-factors-mutrec-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/members/factors-mutrec" FSC_BASIC_OPT_MINUS + [] let ``members-factors-mutrec-FSC_BASIC`` () = singleTestBuildAndRun "core/members/factors-mutrec" FSC_BASIC [] let ``members-factors-mutrec-FSI_BASIC`` () = singleTestBuildAndRun "core/members/factors-mutrec" FSI_BASIC + [] + let ``graph-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "perf/graph" FSC_BASIC_OPT_MINUS + [] let ``graph-FSC_BASIC`` () = singleTestBuildAndRun "perf/graph" FSC_BASIC [] let ``graph-FSI_BASIC`` () = singleTestBuildAndRun "perf/graph" FSI_BASIC + [] + let ``nbody-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "perf/nbody" FSC_BASIC_OPT_MINUS + [] let ``nbody-FSC_BASIC`` () = singleTestBuildAndRun "perf/nbody" FSC_BASIC [] let ``nbody-FSI_BASIC`` () = singleTestBuildAndRun "perf/nbody" FSI_BASIC + [] + let ``letrec (mutrec variations part two) FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/letrec-mutrec2" FSC_BASIC_OPT_MINUS + [] let ``letrec (mutrec variations part two) FSC_BASIC`` () = singleTestBuildAndRun "core/letrec-mutrec2" FSC_BASIC @@ -207,36 +282,54 @@ module CoreTests = [] let ``printf-interpolated`` () = singleTestBuildAndRunVersion "core/printf-interpolated" FSC_BASIC "preview" + [] + let ``tlr-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/tlr" FSC_BASIC_OPT_MINUS + [] let ``tlr-FSC_BASIC`` () = singleTestBuildAndRun "core/tlr" FSC_BASIC [] let ``tlr-FSI_BASIC`` () = singleTestBuildAndRun "core/tlr" FSI_BASIC + [] + let ``subtype-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/subtype" FSC_BASIC_OPT_MINUS + [] let ``subtype-FSC_BASIC`` () = singleTestBuildAndRun "core/subtype" FSC_BASIC [] let ``subtype-FSI_BASIC`` () = singleTestBuildAndRun "core/subtype" FSI_BASIC + [] + let ``syntax-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/syntax" FSC_BASIC_OPT_MINUS + [] let ``syntax-FSC_BASIC`` () = singleTestBuildAndRun "core/syntax" FSC_BASIC [] let ``syntax-FSI_BASIC`` () = singleTestBuildAndRun "core/syntax" FSI_BASIC + [] + let ``test int32-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/int32" FSC_BASIC_OPT_MINUS + [] let ``test int32-FSC_BASIC`` () = singleTestBuildAndRun "core/int32" FSC_BASIC [] let ``test int32-FSI_BASIC`` () = singleTestBuildAndRun "core/int32" FSI_BASIC + [] + let ``quotes-FSC-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/quotes" FSC_BASIC_OPT_MINUS + [] let ``quotes-FSC-BASIC`` () = singleTestBuildAndRun "core/quotes" FSC_BASIC [] let ``quotes-FSI-BASIC`` () = singleTestBuildAndRun "core/quotes" FSI_BASIC + [] + let ``recordResolution-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/recordResolution" FSC_BASIC_OPT_MINUS + [] let ``recordResolution-FSC_BASIC`` () = singleTestBuildAndRun "core/recordResolution" FSC_BASIC From fede9e09c0577ae8d46ab833fbe472f7e6dddc44 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Wed, 30 Jun 2021 16:02:46 +0100 Subject: [PATCH 03/13] remove assert in debug code --- tests/fsharp/core/quotes/test.fsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 35d1a057b45..39d2e4218ed 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -2912,7 +2912,7 @@ module ReflectionOverTypeInstantiations = let notRequired opname item = let msg = sprintf "The operation '%s' on item '%s' should not be called on provided type, member or parameter" opname item - System.Diagnostics.Debug.Assert (false, msg) + //System.Diagnostics.Debug.Assert (false, msg) raise (System.NotSupportedException msg) /// DO NOT ADJUST THIS TYPE - it is the implementation of symbol types from the F# type provider starer pack. From 6c87827b238aa95ba7c490910ad37d7e3f94472c Mon Sep 17 00:00:00 2001 From: Don Syme Date: Tue, 10 Aug 2021 20:16:28 +0100 Subject: [PATCH 04/13] merge main --- src/fsharp/IlxGen.fs | 43 +++++-------------------------------------- tests/fsharp/tests.fs | 6 ------ 2 files changed, 5 insertions(+), 44 deletions(-) diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index 8b6fdda763f..e16746fae8b 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -5103,11 +5103,7 @@ and GenGenericArgs m (tyenv: TypeReprEnv) tps = /// Generate a local type function contract class and implementation and GenClosureAsLocalTypeFunction cenv (cgbuf: CodeGenBuffer) eenv thisVars expr m = let g = cenv.g -<<<<<<< HEAD - let cloinfo, body, eenvinner = GetIlxClosureInfo cenv m true true thisVars eenv expr -======= - let cloinfo, body, eenvinner = GetIlxClosureInfo cenv m ILBoxity.AsObject isLocalTypeFunc true thisVars eenv expr ->>>>>>> 3b0e1b7aec8ed028d208a185b97833fefec77f44 + let cloinfo, body, eenvinner = GetIlxClosureInfo cenv m ILBoxity.AsObject true true thisVars eenv expr let ilCloTypeRef = cloinfo.cloSpec.TypeRef let entryPointInfo = thisVars |> List.map (fun v -> (v, BranchCallClosure cloinfo.cloArityInfo)) // Now generate the actual closure implementation w.r.t. eenvinner @@ -5134,13 +5130,8 @@ and GenClosureAsLocalTypeFunction cenv (cgbuf: CodeGenBuffer) eenv thisVars expr and GenClosureAsFirstClassFunction cenv (cgbuf: CodeGenBuffer) eenv thisVars m expr = let g = cenv.g -<<<<<<< HEAD - let cloinfo, body, eenvinner = GetIlxClosureInfo cenv m false true thisVars eenv expr + let cloinfo, body, eenvinner = GetIlxClosureInfo cenv m ILBoxity.AsObject false true thisVars eenv expr let entryPointInfo = thisVars |> List.map (fun v -> (v, BranchCallClosure (cloinfo.cloArityInfo))) -======= - let cloinfo, body, eenvinner = GetIlxClosureInfo cenv m ILBoxity.AsObject isLocalTypeFunc true thisVars eenv expr - let entryPointInfo = thisVars |> List.map (fun v -> (v, BranchCallClosure cloinfo.cloArityInfo)) ->>>>>>> 3b0e1b7aec8ed028d208a185b97833fefec77f44 let ilCloTypeRef = cloinfo.cloSpec.TypeRef let ilCloBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways, entryPointInfo, cloinfo.cloName, eenvinner, 1, body, Return) @@ -5254,24 +5245,14 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenvouter takenN | Env (_, _, Some (moreFtyvs, _)) | Local (_, _, Some (moreFtyvs, _)) -> unionFreeTyvars ftyvs moreFtyvs | _ -> ftyvs) -<<<<<<< HEAD let cloFreeTypars = cloFreeTyvars.FreeTypars |> Zset.elements -======= ->>>>>>> 3b0e1b7aec8ed028d208a185b97833fefec77f44 - - let cloFreeTyvars = cloFreeTyvars.FreeTypars |> Zset.elements let eenvinner = eenvouter |> EnvForTypars cloFreeTypars let ilCloTyInner = -<<<<<<< HEAD let ilCloGenericParams = GenGenericParams cenv eenvinner cloFreeTypars - mkILFormalBoxedTy ilCloTypeRef ilCloGenericParams -======= - let ilCloGenericParams = GenGenericParams cenv eenvinner cloFreeTyvars - mkILFormalNamedTy boxity ilCloTypeRef ilCloGenericParams ->>>>>>> 3b0e1b7aec8ed028d208a185b97833fefec77f44 + mkILFormalBoxedTy boxity ilCloTypeRef ilCloGenericParams // If generating a named closure, add the closure itself as a var, available via "arg0" . // The latter doesn't apply for the delegate implementation of closures. @@ -5319,12 +5300,7 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenvouter takenN let eenvinner = eenvinner |> AddStorageForLocalVals g ilCloFreeVarStorage // Return a various results -<<<<<<< HEAD - (cloAttribs, cloFreeTypars, cloWitnessInfos, cloFreeVars, ilCloTypeRef, ilCloAllFreeVars, eenvinner) -======= - (cloFreeTyvars, cloWitnessInfos, cloFreeVars, ilCloTypeRef, ilCloAllFreeVars, eenvinner) - ->>>>>>> 3b0e1b7aec8ed028d208a185b97833fefec77f44 + (cloFreeTypars, cloWitnessInfos, cloFreeVars, ilCloTypeRef, ilCloAllFreeVars, eenvinner) and GetIlxClosureInfo cenv m boxity isLocalTypeFunc canUseStaticField thisVars eenvouter expr = let g = cenv.g @@ -7127,23 +7103,14 @@ and AllocLocalVal cenv cgbuf v eenv repr scopeMarks = if isUnitTy g ty && not v.IsMutable then Null, eenv else match repr with -<<<<<<< HEAD | Some repr when IsNamedLocalTypeFuncVal g v repr -> let ftyvs = (freeInExpr CollectTypars repr).FreeTyvars -======= - | Some r when IsNamedLocalTypeFuncVal g v r -> - let ftyvs = (freeInExpr CollectTypars r).FreeTyvars ->>>>>>> 3b0e1b7aec8ed028d208a185b97833fefec77f44 // known, named, non-escaping type functions let cloinfoGenerate eenv = let eenvinner = {eenv with letBoundVars=(mkLocalValRef v) :: eenv.letBoundVars} -<<<<<<< HEAD - let cloinfo, _, _ = GetIlxClosureInfo cenv v.Range true true [] eenvinner repr -======= - let cloinfo, _, _ = GetIlxClosureInfo cenv v.Range ILBoxity.AsObject true true [] eenvinner r ->>>>>>> 3b0e1b7aec8ed028d208a185b97833fefec77f44 + let cloinfo, _, _ = GetIlxClosureInfo cenv v.Range ILBoxity.AsObject true true [] eenvinner repr cloinfo let idx, realloc, eenv = AllocLocal cenv cgbuf eenv v.IsCompilerGenerated (v.CompiledName g.CompilerGlobalState, g.ilg.typ_Object, false) scopeMarks diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index e859771f0c3..66ded92e62f 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -60,12 +60,6 @@ module CoreTests = [] let ``array-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/array" FSC_BASIC_OPT_MINUS -<<<<<<< HEAD - - [] - let ``array-FSC_BASIC`` () = singleTestBuildAndRun "core/array" FSC_BASIC -======= ->>>>>>> 3b0e1b7aec8ed028d208a185b97833fefec77f44 [] let ``array-FSC_BASIC`` () = singleTestBuildAndRun "core/array" FSC_BASIC From 37945febb9dded35d00681b259932176ae255bce Mon Sep 17 00:00:00 2001 From: Don Syme Date: Tue, 10 Aug 2021 23:15:58 +0100 Subject: [PATCH 05/13] Update IlxGen.fs --- src/fsharp/IlxGen.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index e16746fae8b..9d136b13ac3 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -5252,7 +5252,7 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenvouter takenN let ilCloTyInner = let ilCloGenericParams = GenGenericParams cenv eenvinner cloFreeTypars - mkILFormalBoxedTy boxity ilCloTypeRef ilCloGenericParams + mkILFormalNamedTy boxity ilCloTypeRef ilCloGenericParams // If generating a named closure, add the closure itself as a var, available via "arg0" . // The latter doesn't apply for the delegate implementation of closures. From fdd36bd2a44f3bda384779a315cfacd910b4a9be Mon Sep 17 00:00:00 2001 From: Don Syme Date: Tue, 10 Aug 2021 23:17:20 +0100 Subject: [PATCH 06/13] Update IlxGen.fs --- src/fsharp/IlxGen.fs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index 9d136b13ac3..5f5228de0cc 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -5246,12 +5246,12 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenvouter takenN | Local (_, _, Some (moreFtyvs, _)) -> unionFreeTyvars ftyvs moreFtyvs | _ -> ftyvs) - let cloFreeTypars = cloFreeTyvars.FreeTypars |> Zset.elements + let cloFreeTyvars = cloFreeTyvars.FreeTypars |> Zset.elements - let eenvinner = eenvouter |> EnvForTypars cloFreeTypars + let eenvinner = eenvouter |> EnvForTypars cloFreeTyvars let ilCloTyInner = - let ilCloGenericParams = GenGenericParams cenv eenvinner cloFreeTypars + let ilCloGenericParams = GenGenericParams cenv eenvinner cloFreeTyvars mkILFormalNamedTy boxity ilCloTypeRef ilCloGenericParams // If generating a named closure, add the closure itself as a var, available via "arg0" . @@ -5264,7 +5264,7 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenvouter takenN let generateWitnesses = ComputeGenerateWitnesses g eenvinner if generateWitnesses then // The 0 here represents that a closure doesn't reside within a generic class - there are no "enclosing class type parameters" to lop off. - GetTraitWitnessInfosOfTypars g 0 cloFreeTypars + GetTraitWitnessInfosOfTypars g 0 cloFreeTyvars else [] @@ -5300,7 +5300,7 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenvouter takenN let eenvinner = eenvinner |> AddStorageForLocalVals g ilCloFreeVarStorage // Return a various results - (cloFreeTypars, cloWitnessInfos, cloFreeVars, ilCloTypeRef, ilCloAllFreeVars, eenvinner) + (cloFreeTyvars, cloWitnessInfos, cloFreeVars, ilCloTypeRef, ilCloAllFreeVars, eenvinner) and GetIlxClosureInfo cenv m boxity isLocalTypeFunc canUseStaticField thisVars eenvouter expr = let g = cenv.g From 907b8710cd2c6750c61597f0900a086d22deca95 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Tue, 10 Aug 2021 23:18:03 +0100 Subject: [PATCH 07/13] Update FSharp.Compiler.Service.Tests.fsproj --- .../FSharp.Compiler.Service.Tests.fsproj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj index ec7f2fa2f84..9a57b8d7a83 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj @@ -2,7 +2,8 @@ Exe - net472;net5.0 + net472;net5.0 + net5.0 $(NoWarn);44;75; true false @@ -80,4 +81,4 @@ - \ No newline at end of file + From a3a2541cb80b53bdbaf38255a558f4edc882f66f Mon Sep 17 00:00:00 2001 From: Don Syme Date: Tue, 10 Aug 2021 23:18:38 +0100 Subject: [PATCH 08/13] Update FSharp.Test.Utilities.fsproj --- tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj b/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj index 07250b365ad..e1d3a54ed4f 100644 --- a/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj +++ b/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj @@ -1,7 +1,7 @@  - net472;net5.0 + net472;net5.0 net5.0 win-x86;win-x64;linux-x64;osx-x64 $(AssetTargetFallback);portable-net45+win8+wp8+wpa81 From f6ca018396d736bcc120ced5e02c97a72a4ec7ae Mon Sep 17 00:00:00 2001 From: Don Syme Date: Tue, 10 Aug 2021 23:19:01 +0100 Subject: [PATCH 09/13] Update FSharp.Compiler.Service.Tests.fsproj --- .../FSharp.Compiler.Service.Tests.fsproj | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj index 9a57b8d7a83..3b89936fed6 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj @@ -12,6 +12,7 @@ + From e3f3d1f9d4eb08c73209d526816d3cea69ff5570 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Tue, 10 Aug 2021 23:19:13 +0100 Subject: [PATCH 10/13] Update FSharp.Compiler.Service.Tests.fsproj --- .../FSharp.Compiler.Service.Tests.fsproj | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj index 3b89936fed6..c4d4843f328 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj @@ -80,6 +80,7 @@ + From be02c2526581c39b6526d7d3acfdf538bdd08113 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Tue, 10 Aug 2021 23:37:44 +0100 Subject: [PATCH 11/13] Update tests.fs --- tests/fsharp/tests.fs | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index 66ded92e62f..4d864994ec0 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -88,9 +88,6 @@ module CoreTests = [] let ``comprehensionshw-FSI_BASIC`` () = singleTestBuildAndRun "core/comprehensions-hw" FSI_BASIC - [] - let ``genericmeasures-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/genericmeasures" FSC_BASIC_OPT_MINUS - [] let ``genericmeasures-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/genericmeasures" FSC_BASIC_OPT_MINUS From 5d5a3bb976f60cf3497597649d7e4a89504f3fa1 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Wed, 11 Aug 2021 20:04:34 +0100 Subject: [PATCH 12/13] fix test --- src/fsharp/IlxGen.fs | 6 ++++-- tests/fsharp/core/unitsOfMeasure/test.fs | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index 5f5228de0cc..e1cd687dee8 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -3675,7 +3675,7 @@ and FreeVarStorageForWitnessInfos (cenv: cenv) (eenv: IlxGenEnv) takenNames ilCl /// local variable (not method or property). For example // let foo() = // let a = 0<_> -// () +// () // in debug code , here `a` will be a TyLamba. However the compiled representation of // `a` is an integer. and IsLocalErasedTyLambda g eenv (v: Val) e = @@ -3683,7 +3683,9 @@ and IsLocalErasedTyLambda g eenv (v: Val) e = | Expr.TyLambda (_, tyargs, body, _, _) when tyargs |> List.forall (fun tp -> tp.IsErased) && (match StorageForVal g v.Range v eenv with Local _ -> true | _ -> false) -> - Some body + match stripExpr body with + | Expr.Lambda _ -> None + | _ -> Some body | _ -> None //-------------------------------------------------------------------------- diff --git a/tests/fsharp/core/unitsOfMeasure/test.fs b/tests/fsharp/core/unitsOfMeasure/test.fs index deafae9588a..10d312434bf 100644 --- a/tests/fsharp/core/unitsOfMeasure/test.fs +++ b/tests/fsharp/core/unitsOfMeasure/test.fs @@ -40,6 +40,22 @@ let nullReferenceError weightedList = let ``is this null?`` = nullReferenceError [ 0.3; 0.3; 0.4 ] +type C< [] 'u> = + abstract Invoke: float<'u> list -> int + +let rec loop<[]'u> = + { new C<'u> with + member _.Invoke(xs) = + match xs with + | [] -> 1 + | weight :: tail -> + loop<'u>.Invoke(tail) } + +let nullReferenceError2 (weightedList: float<'u> list) = + loop<'u>.Invoke(weightedList) + +let ``is this null 2?`` = nullReferenceError2 [ 0.3; 0.3; 0.4 ] + module TestLibrary = [] From 1e068b9a5e3f387d9dbeb2748c1e37f2c6cdb386 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Thu, 12 Aug 2021 12:10:16 +0100 Subject: [PATCH 13/13] add extra tests --- tests/fsharp/core/genericmeasures/test.fsx | 19 +++++++++- tests/fsharp/core/unitsOfMeasure/test.fs | 44 ++++++++++++---------- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/tests/fsharp/core/genericmeasures/test.fsx b/tests/fsharp/core/genericmeasures/test.fsx index 265b1865826..374c8e8321e 100644 --- a/tests/fsharp/core/genericmeasures/test.fsx +++ b/tests/fsharp/core/genericmeasures/test.fsx @@ -8,17 +8,26 @@ module Core_genericMeasures = type C<'T> = class end [] type t + [] type t2 let f1 (_ : int) = () let f2 (_ : float) = () let f3 (_ : int<_>) = () let f4 (_ : float<_>) = () let f5 (_ : C<'a>) = () - let f6 (_ : list<'a>) = () + let f6 (xs : list<'a>) = + match box xs with + | null -> failwith "unexpected null list" + | _ -> if List.length xs <> 0 then failwith "expected empty list" + let f7 (xs : list<'a>) = + match box xs with + | null -> failwith "unexpected null list" + | _ -> if List.length xs <> 0 then failwith "expected empty list" let foo() = let a = 0<_> let b = 0.0<_> let c = null : C> + let c2 = c : C> let d = null : C> let e = [] : list> let f = [] : list> @@ -26,12 +35,14 @@ module Core_genericMeasures = let h = null : C<_ * int<_> * _> let i : List> = List.empty let j : List> = List.empty + let k : List> = j f1 a f2 b f3 a f4 b f5 c + f5 c2 f5 d f6 e f6 f @@ -39,6 +50,12 @@ module Core_genericMeasures = f5 h f6 i f6 j + f7 (i : List>) + f7 (i : List>) + f7 (j : List>) + f7 (j : List>) + f7 (k : List>) + f7 (k : List>) type T = static member Foo(_ : int) = () diff --git a/tests/fsharp/core/unitsOfMeasure/test.fs b/tests/fsharp/core/unitsOfMeasure/test.fs index 10d312434bf..93094a79892 100644 --- a/tests/fsharp/core/unitsOfMeasure/test.fs +++ b/tests/fsharp/core/unitsOfMeasure/test.fs @@ -29,32 +29,36 @@ let foo = problem // Error: Incorrect number of type arguments to local call -let nullReferenceError weightedList = - let rec loop accumululatedWeight (remaining : float<'u> list) = - match remaining with - | [] -> accumululatedWeight - | weight :: tail -> - loop (accumululatedWeight + weight) tail +// This was causing bad codegen in debug code +module InnerFunctionGenericOnlyByMeasure = + let nullReferenceError weightedList = + let rec loop accumululatedWeight (remaining : float<'u> list) = + match remaining with + | [] -> accumululatedWeight + | weight :: tail -> + loop (accumululatedWeight + weight) tail - loop 0.0<_> weightedList + loop 0.0<_> weightedList -let ``is this null?`` = nullReferenceError [ 0.3; 0.3; 0.4 ] + let ``is this null?`` = nullReferenceError [ 0.3; 0.3; 0.4 ] -type C< [] 'u> = - abstract Invoke: float<'u> list -> int +// Another variation on the above test case, where the recursive thing is a type function generic unly by a unit of measure +module TopLevelTypeFunctionGenericOnlyByMeasure = + type C< [] 'u> = + abstract Invoke: float<'u> list -> int -let rec loop<[]'u> = - { new C<'u> with - member _.Invoke(xs) = - match xs with - | [] -> 1 - | weight :: tail -> - loop<'u>.Invoke(tail) } + let rec loop<[]'u> = + { new C<'u> with + member _.Invoke(xs) = + match xs with + | [] -> 1 + | weight :: tail -> + loop<'u>.Invoke(tail) } -let nullReferenceError2 (weightedList: float<'u> list) = - loop<'u>.Invoke(weightedList) + let nullReferenceError2 (weightedList: float<'u> list) = + loop<'u>.Invoke(weightedList) -let ``is this null 2?`` = nullReferenceError2 [ 0.3; 0.3; 0.4 ] + let ``is this null 2?`` = nullReferenceError2 [ 0.3; 0.3; 0.4 ] module TestLibrary =