Skip to content

Commit

Permalink
Speed up Constraint Solver's overload resolution (II) (#1650)
Browse files Browse the repository at this point in the history
* 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.

* Adjust resulting error code and message from test.

* Use additional argument instead of permitWeakResolution
  • Loading branch information
gusty authored and KevinRansom committed Nov 7, 2016
1 parent b8dbef0 commit 0c37abe
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 10 deletions.
23 changes: 15 additions & 8 deletions src/fsharp/ConstraintSolver.fs
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ let ShowAccessDomain ad =
// Solve

exception NonRigidTypar of DisplayEnv * string option * range * TType * TType * range
exception LocallyAbortOperationThatFailsToResolveOverload
exception LocallyAbortOperationThatLosesAbbrevs
let localAbortD = ErrorD LocallyAbortOperationThatLosesAbbrevs

Expand Down Expand Up @@ -730,7 +731,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)
)))


Expand All @@ -740,14 +741,15 @@ 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 ->
// If this is an overload resolution at this point it's safe to assume the candidate member being evaluated solves this member constraint.
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
Expand Down Expand Up @@ -925,7 +927,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<bool> =
and SolveMemberConstraint (csenv:ConstraintSolverEnv) ignoreUnresolvedOverload permitWeakResolution ndeep m2 trace (TTrait(tys,nm,memFlags,argtys,rty,sln)) : OperationResult<bool> =
// Do not re-solve if already solved
if sln.Value.IsSome then ResultD true else
let g = csenv.g
Expand Down Expand Up @@ -1287,7 +1289,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 ignoreUnresolvedOverload && (not (nm = "op_Explicit" || nm = "op_Implicit")) -> ErrorD LocallyAbortOperationThatFailsToResolveOverload
| _ -> ResultD TTraitUnsolved)
)
++
(fun res -> RecordMemberConstraintSolution csenv.SolverState m trace traitInfo res))
Expand Down Expand Up @@ -1429,7 +1434,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
Expand Down Expand Up @@ -1945,7 +1950,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)
Expand Down Expand Up @@ -2495,7 +2502,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

Expand Down Expand Up @@ -2550,7 +2557,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()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// #Conformance #DeclarationElements #MemberDefinitions #Overloading
// https://github.com/Microsoft/visualfsharp/issues/351 - slow overlaod resolution
//<Expects id="FS0001" status="error">No overloads match</Expects>
//<Expects id="FS0003" status="error">This value is not a function and cannot be applied</Expects>
type Switcher = Switcher

let inline checker< ^s, ^r when (^s or ^r) : (static member pass : ^r -> unit)> (s : ^s) (r : ^r) = ()
Expand All @@ -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
0 // return an integer exit code

0 comments on commit 0c37abe

Please sign in to comment.