X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcUnify.lhs;h=31352e14911b633cb7aafad655e36b8605f93a24;hp=f74f1af07fc8ccac1621e705804a3ead87371d5f;hb=35a1ec430a5e44a9bc79d385b997422c20cb427b;hpb=06cadfcbac371e8f2d58c04c331bc8f54df5e60b diff --git a/compiler/typecheck/TcUnify.lhs b/compiler/typecheck/TcUnify.lhs index f74f1af..31352e1 100644 --- a/compiler/typecheck/TcUnify.lhs +++ b/compiler/typecheck/TcUnify.lhs @@ -27,8 +27,8 @@ module TcUnify ( import HsSyn import TypeRep - -import TcErrors ( typeExtraInfoMsg, unifyCtxt ) +import CoreUtils( mkPiTypes ) +import TcErrors ( unifyCtxt ) import TcMType import TcIface import TcRnMonad @@ -44,7 +44,6 @@ import VarEnv import Name import ErrUtils import BasicTypes -import Bag import Maybes ( allMaybes ) import Util @@ -284,7 +283,6 @@ matchExpectedAppTy orig_ty %************************************************************************ All the tcSub calls have the form - tcSub actual_ty expected_ty which checks actual_ty <= expected_ty @@ -298,14 +296,14 @@ which takes an HsExpr of type actual_ty into one of type expected_ty. \begin{code} -tcSubType :: CtOrigin -> SkolemInfo -> TcSigmaType -> TcSigmaType -> TcM HsWrapper +tcSubType :: CtOrigin -> UserTypeCtxt -> TcSigmaType -> TcSigmaType -> TcM HsWrapper -- Check that ty_actual is more polymorphic than ty_expected -- Both arguments might be polytypes, so we must instantiate and skolemise -- Returns a wrapper of shape ty_actual ~ ty_expected -tcSubType origin skol_info ty_actual ty_expected +tcSubType origin ctxt ty_actual ty_expected | isSigmaTy ty_actual = do { (sk_wrap, inst_wrap) - <- tcGen skol_info ty_expected $ \ _ sk_rho -> do + <- tcGen ctxt ty_expected $ \ _ sk_rho -> do { (in_wrap, in_rho) <- deeplyInstantiate origin ty_actual ; coi <- unifyType in_rho sk_rho ; return (coiToHsWrapper coi <.> in_wrap) } @@ -353,16 +351,16 @@ wrapFunResCoercion arg_tys co_fn_res %************************************************************************ \begin{code} -tcGen :: SkolemInfo -> TcType +tcGen :: UserTypeCtxt -> TcType -> ([TcTyVar] -> TcRhoType -> TcM result) -> TcM (HsWrapper, result) -- The expression has type: spec_ty -> expected_ty -tcGen skol_info expected_ty thing_inside +tcGen ctxt expected_ty thing_inside -- We expect expected_ty to be a forall-type -- If not, the call is a no-op = do { traceTc "tcGen" empty - ; (wrap, tvs', given, rho') <- deeplySkolemise skol_info expected_ty + ; (wrap, tvs', given, rho') <- deeplySkolemise expected_ty ; when debugIsOn $ traceTc "tcGen" $ vcat [ @@ -379,9 +377,13 @@ tcGen skol_info expected_ty thing_inside -- So now s' isn't unconstrained because it's linked to a. -- -- However [Oct 10] now that the untouchables are a range of - -- TcTyVars, all tihs is handled automatically with no need for + -- TcTyVars, all this is handled automatically with no need for -- extra faffing around + -- Use the *instantiated* type in the SkolemInfo + -- so that the names of displayed type variables line up + ; let skol_info = SigSkol ctxt (mkPiTypes given rho') + ; (ev_binds, result) <- checkConstraints skol_info tvs' given $ thing_inside tvs' rho' @@ -414,7 +416,7 @@ newImplication skol_info skol_tvs given thing_inside captureUntouchables $ thing_inside - ; if isEmptyBag wanted && not (hasEqualities given) + ; if isEmptyWC wanted && not (hasEqualities given) -- Optimisation : if there are no wanteds, and the givens -- are sufficiently simple, don't generate an implication -- at all. Reason for the hasEqualities test: @@ -426,16 +428,15 @@ newImplication skol_info skol_tvs given thing_inside { ev_binds_var <- newTcEvBinds ; lcl_env <- getLclTypeEnv ; loc <- getCtLoc skol_info - ; let implic = Implic { ic_untch = untch - , ic_env = lcl_env - , ic_skols = mkVarSet skol_tvs - , ic_scoped = panic "emitImplication" - , ic_given = given - , ic_wanted = wanted - , ic_binds = ev_binds_var - , ic_loc = loc } - - ; emitConstraint (WcImplic implic) + ; emitImplication $ Implic { ic_untch = untch + , ic_env = lcl_env + , ic_skols = mkVarSet skol_tvs + , ic_given = given + , ic_wanted = wanted + , ic_insol = insolubleWC wanted + , ic_binds = ev_binds_var + , ic_loc = loc } + ; return (TcEvBinds ev_binds_var, result) } } \end{code} @@ -518,11 +519,16 @@ uType, uType_np, uType_defer -- It is always safe to defer unification to the main constraint solver -- See Note [Deferred unification] uType_defer (item : origin) ty1 ty2 - = do { co_var <- newWantedCoVar ty1 ty2 - ; traceTc "utype_defer" (vcat [ppr co_var, ppr ty1, ppr ty2, ppr origin]) + = wrapEqCtxt origin $ + do { co_var <- newCoVar ty1 ty2 ; loc <- getCtLoc (TypeEqOrigin item) - ; wrapEqCtxt origin $ - emitConstraint (WcEvVar (WantedEvVar co_var loc)) + ; emitFlat (mkEvVarX co_var loc) + + -- Error trace only + ; ctxt <- getErrCtxt + ; doc <- mkErrInfo emptyTidyEnv ctxt + ; traceTc "utype_defer" (vcat [ppr co_var, ppr ty1, ppr ty2, ppr origin, doc]) + ; return $ ACo $ mkTyVarTy co_var } uType_defer [] _ _ = panic "uType_defer" @@ -629,7 +635,7 @@ unifySigmaTy origin ty1 ty2 = do { let (tvs1, body1) = tcSplitForAllTys ty1 (tvs2, body2) = tcSplitForAllTys ty2 ; unless (equalLength tvs1 tvs2) (failWithMisMatch origin) - ; skol_tvs <- tcInstSkolTyVars UnkSkol tvs1 -- Not a helpful SkolemInfo + ; skol_tvs <- tcInstSkolTyVars tvs1 -- Get location from monad, not from tvs1 ; let tys = mkTyVarTys skol_tvs in_scope = mkInScopeSet (mkVarSet skol_tvs) @@ -641,9 +647,12 @@ unifySigmaTy origin ty1 ty2 captureUntouchables $ uType origin phi1 phi2 -- Check for escape; e.g. (forall a. a->b) ~ (forall a. a->a) - ; let bad_lie = filterBag is_bad lie - is_bad w = any (`elemVarSet` tyVarsOfWanted w) skol_tvs - ; when (not (isEmptyBag bad_lie)) + -- VERY UNSATISFACTORY; the constraint might be fine, but + -- we fail eagerly because we don't have any place to put + -- the bindings from an implication constraint + -- This only works because most constraints get solved on the fly + -- See Note [Avoid deferring] + ; when (any (`elemVarSet` tyVarsOfWC lie) skol_tvs) (failWithMisMatch origin) -- ToDo: give details from bad_lie ; emitConstraints lie @@ -849,9 +858,13 @@ uUnfilledVar origin swapped tv1 details1 non_var_ty2 -- ty2 is not a type varia Just ty2' -> updateMeta tv1 ref1 ty2' } - _other -> do { traceTc "Skolem defer" (ppr tv1); defer } -- Skolems of all sorts + _other -> do { traceTc "Skolem defer" (ppr tv1); defer } -- Skolems of all sorts where - defer = unSwap swapped (uType_defer origin) (mkTyVarTy tv1) non_var_ty2 + defer | Just ty2' <- tcView non_var_ty2 -- Note [Avoid deferring] + -- non_var_ty2 isn't expanded yet + = uUnfilledVar origin swapped tv1 details1 ty2' + | otherwise + = unSwap swapped (uType_defer origin) (mkTyVarTy tv1) non_var_ty2 -- Occurs check or an untouchable: just defer -- NB: occurs check isn't necessarily fatal: -- eg tv1 occured in type family parameter @@ -886,8 +899,8 @@ uUnfilledVars origin swapped tv1 details1 tv2 details2 ty1 = mkTyVarTy tv1 ty2 = mkTyVarTy tv2 - nicer_to_update_tv1 _ (SigTv _) = True - nicer_to_update_tv1 (SigTv _) _ = False + nicer_to_update_tv1 _ SigTv = True + nicer_to_update_tv1 SigTv _ = False nicer_to_update_tv1 _ _ = isSystemName (Var.varName tv1) -- Try not to update SigTvs; and try to update sys-y type -- variables in preference to ones gotten (say) by @@ -950,14 +963,26 @@ checkTauTvUpdate tv ty = Just (EqPred ty1' ty2') -- Fall-through ok_pred _pty = Nothing - \end{code} +Note [Avoid deferring] +~~~~~~~~~~~~~~~~~~~~~~ +We try to avoid creating deferred constraints for two reasons. + * First, efficiency. + * Second, currently we can only defer some constraints + under a forall. See unifySigmaTy. +So expanding synonyms here is a good thing to do. Example (Trac #4917) + a ~ Const a b +where type Const a b = a. We can solve this immediately, even when +'a' is a skolem, just by expanding the synonym; and we should do so + in case this unification happens inside unifySigmaTy (sigh). + Note [Type synonyms and the occur check] -~~~~~~~~~~~~~~~~~~~~ -Generally speaking we need to update a variable with type synonyms not expanded, which -improves later error messages, except for when looking inside a type synonym may help resolve -a spurious occurs check error. Consider: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Generally speaking we try to update a variable with type synonyms not +expanded, which improves later error messages, unless looking +inside a type synonym may help resolve a spurious occurs check +error. Consider: type A a = () f :: (A a -> a -> ()) -> () @@ -1019,7 +1044,7 @@ lookupTcTyVar tyvar Indirect ty -> return (Filled ty) Flexi -> do { is_untch <- isUntouchable tyvar ; let -- Note [Unifying untouchables] - ret_details | is_untch = SkolemTv UnkSkol + ret_details | is_untch = vanillaSkolemTv | otherwise = details ; return (Unfilled ret_details) } } | otherwise @@ -1075,18 +1100,14 @@ failWithMisMatch (item:origin) ; env0 <- tcInitTidyEnv ; let (env1, pp_exp) = tidyOpenType env0 ty_exp (env2, pp_act) = tidyOpenType env1 ty_act - ; failWithTcM (misMatchMsg env2 pp_act pp_exp) } + ; failWithTcM (env2, misMatchMsg pp_act pp_exp) } failWithMisMatch [] = panic "failWithMisMatch" -misMatchMsg :: TidyEnv -> TcType -> TcType -> (TidyEnv, SDoc) -misMatchMsg env ty_act ty_exp - = (env2, sep [sep [ ptext (sLit "Couldn't match expected type") <+> quotes (ppr ty_exp) - , nest 12 $ ptext (sLit "with actual type") <+> quotes (ppr ty_act)] - , nest 2 (extra1 $$ extra2) ]) - where - (env1, extra1) = typeExtraInfoMsg env ty_exp - (env2, extra2) = typeExtraInfoMsg env1 ty_act +misMatchMsg :: TcType -> TcType -> SDoc +misMatchMsg ty_act ty_exp + = sep [ ptext (sLit "Couldn't match expected type") <+> quotes (ppr ty_exp) + , nest 12 $ ptext (sLit "with actual type") <+> quotes (ppr ty_act)] \end{code}