-- friends:
import TcMonad
import TypeRep ( Type(..), PredType(..) ) -- friend
-import Type ( funTyCon, Kind, unboxedTypeKind, boxedTypeKind, openTypeKind,
- superBoxity, typeCon, openKindCon, hasMoreBoxityInfo,
+import Type ( unboxedTypeKind, boxedTypeKind, openTypeKind,
+ typeCon, openKindCon, hasMoreBoxityInfo,
tyVarsOfType, typeKind,
- mkTyVarTy, mkFunTy, splitFunTy_maybe, splitTyConApp_maybe,
- isNotUsgTy, splitAppTy_maybe, mkTyConApp,
+ mkFunTy, splitFunTy_maybe, splitTyConApp_maybe,
+ splitAppTy_maybe, mkTyConApp,
tidyOpenType, tidyOpenTypes, tidyTyVar
)
import TyCon ( TyCon, isTupleTyCon, tupleTyConBoxity, tyConArity )
-import Name ( hasBetterProv )
-import Var ( TyVar, tyVarKind, varName, isSigTyVar )
+import Var ( tyVarKind, varName, isSigTyVar )
import VarSet ( varSetElems )
import TcType ( TcType, TcTauType, TcTyVar, TcKind, newBoxityVar,
newTyVarTy, newTyVarTys, tcGetTyVar, tcPutTyVar, zonkTcType
)
+import Name ( isSystemName )
-- others:
import BasicTypes ( Arity, Boxity, isBoxed )
-> TcM ()
-- Always expand synonyms (see notes at end)
- -- (this also throws away FTVs and usage annots)
+ -- (this also throws away FTVs)
uTys ps_ty1 (NoteTy _ ty1) ps_ty2 ty2 = uTys ps_ty1 ty1 ps_ty2 ty2
uTys ps_ty1 ty1 ps_ty2 (NoteTy _ ty2) = uTys ps_ty1 ty1 ps_ty2 ty2
+ -- Ignore usage annotations inside typechecker
+uTys ps_ty1 (UsageTy _ ty1) ps_ty2 ty2 = uTys ps_ty1 ty1 ps_ty2 ty2
+uTys ps_ty1 ty1 ps_ty2 (UsageTy _ ty2) = uTys ps_ty1 ty1 ps_ty2 ty2
+
-- Variables; go for uVar
uTys ps_ty1 (TyVarTy tyvar1) ps_ty2 ty2 = uVar False tyvar1 ps_ty2 ty2
uTys ps_ty1 ty1 ps_ty2 (TyVarTy tyvar2) = uVar True tyvar2 ps_ty1 ty1
| otherwise -> uTys ty1 ty1 ps_ty2 ty2 -- Same order
other -> uUnboundVar swapped tv1 maybe_ty1 ps_ty2 ty2
- -- Expand synonyms; ignore FTVs; ignore usage annots
+ -- Expand synonyms; ignore FTVs
uUnboundVar swapped tv1 maybe_ty1 ps_ty2 (NoteTy _ ty2)
= uUnboundVar swapped tv1 maybe_ty1 ps_ty2 ty2
case maybe_ty2 of
Just ty2' -> uUnboundVar swapped tv1 maybe_ty1 ty2' ty2'
- Nothing | tv1_dominates_tv2
+ Nothing | update_tv2
-> WARN( not (k1 `hasMoreBoxityInfo` k2), (ppr tv1 <+> ppr k1) $$ (ppr tv2 <+> ppr k2) )
tcPutTyVar tv2 (TyVarTy tv1) `thenNF_Tc_`
| otherwise
-> WARN( not (k2 `hasMoreBoxityInfo` k1), (ppr tv2 <+> ppr k2) $$ (ppr tv1 <+> ppr k1) )
- (ASSERT( isNotUsgTy ps_ty2 )
- tcPutTyVar tv1 ps_ty2 `thenNF_Tc_`
+ (tcPutTyVar tv1 ps_ty2 `thenNF_Tc_`
returnTc ())
where
k1 = tyVarKind tv1
k2 = tyVarKind tv2
- tv1_dominates_tv2 = isSigTyVar tv1
+ update_tv2 = (k2 == openTypeKind) || (k1 /= openTypeKind && nicer_to_update_tv2)
+ -- Try to get rid of open type variables as soon as poss
+
+ nicer_to_update_tv2 = isSigTyVar tv1
-- Don't unify a signature type variable if poss
- || k2 == openTypeKind
- -- Try to get rid of open type variables as soon as poss
- || varName tv1 `hasBetterProv` varName tv2
+ || isSystemName (varName tv2)
-- Try to update sys-y type variables in preference to sig-y ones
-- Second one isn't a type variable
uUnboundVar swapped tv1 maybe_ty1 ps_ty2 non_var_ty2
= checkKinds swapped tv1 non_var_ty2 `thenTc_`
occur_check non_var_ty2 `thenTc_`
- ASSERT( isNotUsgTy ps_ty2 )
checkTcM (not (isSigTyVar tv1))
(failWithTcM (unifyWithSigErr tv1 ps_ty2)) `thenTc_`