From ac4392269b120b68da5685d09b02486ff9cc547a Mon Sep 17 00:00:00 2001 From: Gusty Date: Mon, 24 Oct 2016 00:23:09 +0200 Subject: [PATCH 1/3] Commit constraint solution before the type equality test. * Commit constraint solution before the type equality test. * SolveMemberConstraint will signal through an internal exception that it failed due to an unresolved overload. --- src/fsharp/ConstraintSolver.fs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index 4a985fe5b40..7e3f1904bcd 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -340,6 +340,7 @@ let ShowAccessDomain ad = // Solve exception NonRigidTypar of DisplayEnv * string option * range * TType * TType * range +exception LocallyAbortOperationThatFailsToResolveOverload exception LocallyAbortOperationThatLosesAbbrevs let localAbortD = ErrorD LocallyAbortOperationThatLosesAbbrevs @@ -732,7 +733,6 @@ and SolveTypEqualsTyp (csenv:ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace let ndeep = ndeep + 1 let aenv = csenv.EquivEnv let g = csenv.g - if ty1 === ty2 then CompleteD else match cxsln with | Some (traitInfo, traitSln) when traitInfo.Solution.IsNone -> @@ -740,6 +740,8 @@ and SolveTypEqualsTyp (csenv:ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace TransactMemberConstraintSolution traitInfo trace traitSln | _ -> () + if ty1 === ty2 then CompleteD else + let canShortcut = not trace.HasTrace let sty1 = stripTyEqnsA csenv.g canShortcut ty1 let sty2 = stripTyEqnsA csenv.g canShortcut ty2 @@ -1280,7 +1282,10 @@ and SolveMemberConstraint (csenv:ConstraintSolverEnv) permitWeakResolution ndeep // If there's nothing left to learn then raise the errors (if (permitWeakResolution && List.isEmpty support) || List.isEmpty frees then errors // Otherwise re-record the trait waiting for canonicalization - else AddMemberConstraint csenv ndeep m2 trace traitInfo support frees) ++ (fun () -> ResultD TTraitUnsolved) + else AddMemberConstraint csenv ndeep m2 trace traitInfo support frees) ++ (fun () -> + match errors with + | ErrorResult (_,UnresolvedOverloading _) when not permitWeakResolution && (not (nm = "op_Explicit" || nm = "op_Implicit")) -> ErrorD LocallyAbortOperationThatFailsToResolveOverload + | _ -> ResultD TTraitUnsolved) ) ++ (fun res -> RecordMemberConstraintSolution csenv.SolverState m trace traitInfo res)) @@ -1952,7 +1957,9 @@ and private SolveTypSubsumesTypWithReport (csenv:ConstraintSolverEnv) ndeep m tr and private SolveTypEqualsTypWithReport contextInfo (csenv:ConstraintSolverEnv) ndeep m trace cxsln ty1 ty2 = TryD (fun () -> SolveTypEqualsTypKeepAbbrevsWithCxsln csenv ndeep m trace cxsln ty1 ty2) - (fun res -> ErrorD (ErrorFromAddingTypeEquation(csenv.g,csenv.DisplayEnv,ty1,ty2,res,contextInfo,m))) + (function + | LocallyAbortOperationThatFailsToResolveOverload -> CompleteD + | res -> ErrorD (ErrorFromAddingTypeEquation(csenv.g,csenv.DisplayEnv,ty1,ty2,res,contextInfo,m))) and ArgsMustSubsumeOrConvert (csenv:ConstraintSolverEnv) From 3b3aa1006e1ba3eab811e692ddfe2577cd43ecd5 Mon Sep 17 00:00:00 2001 From: Gusty Date: Tue, 25 Oct 2016 19:42:42 +0200 Subject: [PATCH 2/3] Adjust resulting error code and message from test. --- .../OverloadingMembers/SlowOverloadResolution.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OverloadingMembers/SlowOverloadResolution.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OverloadingMembers/SlowOverloadResolution.fs index 0f6d5f43532..5737cdebf2c 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OverloadingMembers/SlowOverloadResolution.fs +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OverloadingMembers/SlowOverloadResolution.fs @@ -1,6 +1,6 @@ // #Conformance #DeclarationElements #MemberDefinitions #Overloading // https://github.com/Microsoft/visualfsharp/issues/351 - slow overlaod resolution -//No overloads match +//This value is not a function and cannot be applied type Switcher = Switcher let inline checker< ^s, ^r when (^s or ^r) : (static member pass : ^r -> unit)> (s : ^s) (r : ^r) = () @@ -22,4 +22,4 @@ let main argv = let res : unit = format () "text" 5 "more text" () printfn "%A" res System.Console.ReadKey() - 0 // return an integer exit code \ No newline at end of file + 0 // return an integer exit code From 0e9273515f07664b56042d23c681be211d035036 Mon Sep 17 00:00:00 2001 From: Gustavo Leon Date: Fri, 4 Nov 2016 20:30:45 +0100 Subject: [PATCH 3/3] Use additional argument instead of permitWeakResolution --- src/fsharp/ConstraintSolver.fs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index 7e3f1904bcd..fb31dbb985a 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -723,7 +723,7 @@ and solveTypMeetsTyparConstraints (csenv:ConstraintSolverEnv) ndeep m2 trace ty | TyparConstraint.SimpleChoice(tys,m2) -> SolveTypChoice csenv ndeep m2 trace ty tys | TyparConstraint.CoercesTo(ty2,m2) -> SolveTypSubsumesTypKeepAbbrevs csenv ndeep m2 trace None ty2 ty | TyparConstraint.MayResolveMember(traitInfo,m2) -> - SolveMemberConstraint csenv false ndeep m2 trace traitInfo ++ (fun _ -> CompleteD) + SolveMemberConstraint csenv false false ndeep m2 trace traitInfo ++ (fun _ -> CompleteD) ))) @@ -919,7 +919,7 @@ and SolveDimensionlessNumericType (csenv:ConstraintSolverEnv) ndeep m2 trace ty /// We pretend int and other types support a number of operators. In the actual IL for mscorlib they /// don't, however the type-directed static optimization rules in the library code that makes use of this /// will deal with the problem. -and SolveMemberConstraint (csenv:ConstraintSolverEnv) permitWeakResolution ndeep m2 trace (TTrait(tys,nm,memFlags,argtys,rty,sln)) : OperationResult = +and SolveMemberConstraint (csenv:ConstraintSolverEnv) ignoreUnresolvedOverload permitWeakResolution ndeep m2 trace (TTrait(tys,nm,memFlags,argtys,rty,sln)) : OperationResult = // Do not re-solve if already solved if sln.Value.IsSome then ResultD true else let g = csenv.g @@ -1284,7 +1284,7 @@ and SolveMemberConstraint (csenv:ConstraintSolverEnv) permitWeakResolution ndeep // Otherwise re-record the trait waiting for canonicalization else AddMemberConstraint csenv ndeep m2 trace traitInfo support frees) ++ (fun () -> match errors with - | ErrorResult (_,UnresolvedOverloading _) when not permitWeakResolution && (not (nm = "op_Explicit" || nm = "op_Implicit")) -> ErrorD LocallyAbortOperationThatFailsToResolveOverload + | ErrorResult (_,UnresolvedOverloading _) when not ignoreUnresolvedOverload && (not (nm = "op_Explicit" || nm = "op_Implicit")) -> ErrorD LocallyAbortOperationThatFailsToResolveOverload | _ -> ResultD TTraitUnsolved) ) ++ @@ -1435,7 +1435,7 @@ and SolveRelevantMemberConstraintsForTypar (csenv:ConstraintSolverEnv) ndeep per cxs |> AtLeastOneD (fun (traitInfo,m2) -> let csenv = { csenv with m = m2 } - SolveMemberConstraint csenv permitWeakResolution (ndeep+1) m2 trace traitInfo) + SolveMemberConstraint csenv true permitWeakResolution (ndeep+1) m2 trace traitInfo) and CanonicalizeRelevantMemberConstraints (csenv:ConstraintSolverEnv) ndeep trace tps = SolveRelevantMemberConstraints csenv ndeep true trace tps @@ -2491,7 +2491,7 @@ let AddCxTypeMustSubsumeType contextInfo denv css m trace ty1 ty2 = |> RaiseOperationResult let AddCxMethodConstraint denv css m trace traitInfo = - TryD (fun () -> SolveMemberConstraint (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) false 0 m trace traitInfo ++ (fun _ -> CompleteD)) + TryD (fun () -> SolveMemberConstraint (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) true false 0 m trace traitInfo ++ (fun _ -> CompleteD)) (fun res -> ErrorD (ErrorFromAddingConstraint(denv,res,m))) |> RaiseOperationResult @@ -2546,7 +2546,7 @@ let CodegenWitnessThatTypSupportsTraitConstraint tcVal g amap m (traitInfo:Trait ExtraCxs=HashMultiMap(10, HashIdentity.Structural) InfoReader=new InfoReader(g,amap) } let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g) - SolveMemberConstraint csenv true 0 m NoTrace traitInfo ++ (fun _res -> + SolveMemberConstraint csenv true true 0 m NoTrace traitInfo ++ (fun _res -> let sln = match traitInfo.Solution with | None -> Choice4Of4()