diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index 807261c21b0b2e3e302f3e240508a65c29cc0831..01ccd1168c0b48089872dac1b18ce791681df685 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -778,7 +778,7 @@ and SolveTypEqualsTyp (csenv:ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace match sty1, sty2 with // type vars inside forall-types may be alpha-equivalent - | TType_var tp1, TType_var tp2 when typarEq tp1 tp2 || (aenv.EquivTypars.ContainsKey tp1 && typeEquiv g aenv.EquivTypars.[tp1] ty2) -> CompleteD + | TType_var tp1, TType_var tp2 when typarEq tp1 tp2 || (match aenv.EquivTypars.TryFind tp1 with | Some v when typeEquiv g v ty2 -> true | _ -> false) -> CompleteD | TType_var tp1, TType_var tp2 when PreferUnifyTypar tp1 tp2 -> SolveTyparEqualsTyp csenv ndeep m2 trace sty1 ty2 | TType_var tp1, TType_var tp2 when not csenv.MatchingOnly && PreferUnifyTypar tp2 tp1 -> SolveTyparEqualsTyp csenv ndeep m2 trace sty2 ty1 @@ -850,12 +850,17 @@ and SolveTypSubsumesTyp (csenv:ConstraintSolverEnv) ndeep m2 (trace: OptionalTra let aenv = csenv.EquivEnv let denv = csenv.DisplayEnv match sty1, sty2 with - | TType_var tp1, _ when aenv.EquivTypars.ContainsKey tp1 -> - SolveTypSubsumesTyp csenv ndeep m2 trace cxsln aenv.EquivTypars.[tp1] ty2 - - | TType_var r1, TType_var r2 when typarEq r1 r2 -> CompleteD + | TType_var tp1, _ -> + match aenv.EquivTypars.TryFind tp1 with + | Some v -> SolveTypSubsumesTyp csenv ndeep m2 trace cxsln v ty2 + | _ -> + match sty2 with + | TType_var r2 when typarEq tp1 r2 -> CompleteD + | TType_var r when not csenv.MatchingOnly -> SolveTyparSubtypeOfType csenv ndeep m2 trace r ty1 + | _ -> SolveTypEqualsTypKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ty1 ty2 + | _, TType_var r when not csenv.MatchingOnly -> SolveTyparSubtypeOfType csenv ndeep m2 trace r ty1 - | TType_var _ , _ -> SolveTypEqualsTypKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ty1 ty2 + | TType_tuple (tupInfo1, l1) , TType_tuple (tupInfo2, l2) -> if evalTupInfoIsStruct tupInfo1 <> evalTupInfoIsStruct tupInfo2 then ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m, m2)) else SolveTypEqualsTypEqns csenv ndeep m2 trace cxsln l1 l2 (* nb. can unify since no variance *) diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index 03180754a18ad61d8b7afe5e0a6522efd76d74ce..8769bb8eefd1275b3ffae9d9e4f4291c417eb9cf 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -43,6 +43,10 @@ type TyparMap<'T> = let (TPMap m) = tm m.ContainsKey(v.Stamp) + member tm.TryFind (v: Typar) = + let (TPMap m) = tm + m.TryFind(v.Stamp) + member tm.Add (v: Typar, x) = let (TPMap m) = tm TPMap (m.Add(v.Stamp, x)) diff --git a/src/fsharp/TastOps.fsi b/src/fsharp/TastOps.fsi index 9f23629b25e35ca7ff429aba842ab955f59a08a8..63ee7ee670a564fadfe64f92fd264c0c89e6d5fb 100755 --- a/src/fsharp/TastOps.fsi +++ b/src/fsharp/TastOps.fsi @@ -306,6 +306,7 @@ type ValMultiMap<'T> = type TyparMap<'T> = member Item : Typar -> 'T with get member ContainsKey : Typar -> bool + member TryFind : Typar -> 'T option member Add : Typar * 'T -> TyparMap<'T> static member Empty : TyparMap<'T>