X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcCanonical.lhs;h=d72fae40833234ad6b3a6f9943ed0a83e8508852;hb=2207ce8cdc4c33838f77f285c7dd4f7c75dbae1c;hp=f834a4c3285d69944798d3d6dcf33290dce1a90c;hpb=67ed735fab12c12a1d48878d7bda33588c67fb78;p=ghc-hetmet.git diff --git a/compiler/typecheck/TcCanonical.lhs b/compiler/typecheck/TcCanonical.lhs index f834a4c..d72fae4 100644 --- a/compiler/typecheck/TcCanonical.lhs +++ b/compiler/typecheck/TcCanonical.lhs @@ -397,14 +397,6 @@ in Haskell are always same type from different type arguments. -Note [Kinding] -~~~~~~~~~~~~~~ -The canonicalizer assumes that it's provided with well-kinded equalities -as wanted or given, that is LHS kind and the RHS kind agree, modulo subkinding. - -Both canonicalization and interaction solving must preserve this invariant. -DV: TODO TODO: Check! - Note [Canonical ordering for equality constraints] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Implemented as (<+=) below: @@ -536,21 +528,23 @@ reOrient (FunCls {}) (VarCls tv2) = isMetaTyVar tv2 -- meta type variable is the RHS of a function equality reOrient (FunCls {}) _ = False -- Fun/Other on rhs - -reOrient (VarCls tv1) (FunCls {}) = not (isMetaTyVar tv1) +reOrient (VarCls tv1) (FunCls {}) = not (isMetaTyVar tv1) reOrient (VarCls {}) (OtherCls {}) = False +reOrient (VarCls {}) (VarCls {}) = False +{- -- Variables-variables are oriented according to their kind --- so that the invariant of CTyEqCan has the best chance of +-- so that the following property has the best chance of -- holding: tv ~ xi -- * If tv is a MetaTyVar, then typeKind xi <: typeKind tv -- a skolem, then typeKind xi = typeKind tv -reOrient (VarCls tv1) (VarCls tv2) + | k1 `eqKind` k2 = False | otherwise = k1 `isSubKind` k2 where k1 = tyVarKind tv1 k2 = tyVarKind tv2 +-} ------------------ canEqLeaf :: CtFlavor -> CoVar @@ -582,7 +576,9 @@ canEqLeafOriented :: CtFlavor -> CoVar -> TypeClassifier -> TcType -> TcS CanonicalCts -- First argument is not OtherCls canEqLeafOriented fl cv cls1@(FunCls fn tys) s2 - | not (kindAppResult (tyConKind fn) tys `eqKind` typeKind s2 ) + | let k1 = kindAppResult (tyConKind fn) tys, + let k2 = typeKind s2, + isGiven fl && not (k1 `eqKind` k2) -- Establish the kind invariant for CFunEqCan = do { kindErrorTcS fl (unClassify cls1) s2 ; return emptyCCan } | otherwise @@ -599,8 +595,7 @@ canEqLeafOriented fl cv cls1@(FunCls fn tys) s2 -- Otherwise, we have a variable on the left, so we flatten the RHS -- and then do an occurs check. canEqLeafOriented fl cv (VarCls tv) s2 - | not (k1 `eqKind` k2 || (isMetaTyVar tv && k2 `isSubKind` k1)) - -- Establish the kind invariant for CTyEqCan + | isGiven fl && not (k1 `eqKind` k2) -- Establish the kind invariant for CTyEqCan = do { kindErrorTcS fl (mkTyVarTy tv) s2 ; return emptyCCan }