summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/typecheck/TcCanonical.hs33
1 files changed, 19 insertions, 14 deletions
diff --git a/compiler/typecheck/TcCanonical.hs b/compiler/typecheck/TcCanonical.hs
index 1a35bcc280..3419400fc2 100644
--- a/compiler/typecheck/TcCanonical.hs
+++ b/compiler/typecheck/TcCanonical.hs
@@ -1823,25 +1823,27 @@ unifyWanted loc role orig_ty1 orig_ty2
= do { cos <- zipWith3M (unifyWanted loc)
(tyConRolesX role tc1) tys1 tys2
; return (mkTyConAppCo role tc1 cos) }
- go (TyVarTy tv) ty2
+
+ go ty1@(TyVarTy tv) ty2
= do { mb_ty <- isFilledMetaTyVar_maybe tv
; case mb_ty of
Just ty1' -> go ty1' ty2
- Nothing -> bale_out }
- go ty1 (TyVarTy tv)
+ Nothing -> bale_out ty1 ty2}
+ go ty1 ty2@(TyVarTy tv)
= do { mb_ty <- isFilledMetaTyVar_maybe tv
; case mb_ty of
Just ty2' -> go ty1 ty2'
- Nothing -> bale_out }
+ Nothing -> bale_out ty1 ty2 }
go ty1@(CoercionTy {}) (CoercionTy {})
= return (mkReflCo role ty1) -- we just don't care about coercions!
- go _ _ = bale_out
+ go ty1 ty2 = bale_out ty1 ty2
- bale_out = do { (new_ev, co) <- newWantedEq loc role orig_ty1 orig_ty2
- ; emitWorkNC [new_ev]
- ; return co }
+ bale_out ty1 ty2
+ | ty1 `tcEqType` ty2 = return (mkTcReflCo role ty1)
+ -- Check for equality; e.g. a ~ a, or (m a) ~ (m a)
+ | otherwise = emitNewWantedEq loc role orig_ty1 orig_ty2
unifyDeriveds :: CtLoc -> [Role] -> [TcType] -> [TcType] -> TcS ()
-- See Note [unifyWanted and unifyDerived]
@@ -1869,19 +1871,22 @@ unify_derived loc role orig_ty1 orig_ty2
| tc1 == tc2, tys1 `equalLength` tys2
, isInjectiveTyCon tc1 role
= unifyDeriveds loc (tyConRolesX role tc1) tys1 tys2
- go (TyVarTy tv) ty2
+ go ty1@(TyVarTy tv) ty2
= do { mb_ty <- isFilledMetaTyVar_maybe tv
; case mb_ty of
Just ty1' -> go ty1' ty2
- Nothing -> bale_out }
- go ty1 (TyVarTy tv)
+ Nothing -> bale_out ty1 ty2 }
+ go ty1 ty2@(TyVarTy tv)
= do { mb_ty <- isFilledMetaTyVar_maybe tv
; case mb_ty of
Just ty2' -> go ty1 ty2'
- Nothing -> bale_out }
- go _ _ = bale_out
+ Nothing -> bale_out ty1 ty2 }
+ go ty1 ty2 = bale_out ty1 ty2
- bale_out = emitNewDerivedEq loc role orig_ty1 orig_ty2
+ bale_out ty1 ty2
+ | ty1 `tcEqType` ty2 = return ()
+ -- Check for equality; e.g. a ~ a, or (m a) ~ (m a)
+ | otherwise = emitNewDerivedEq loc role orig_ty1 orig_ty2
maybeSym :: SwapFlag -> TcCoercion -> TcCoercion
maybeSym IsSwapped co = mkTcSymCo co