diff options
author | Joachim Breitner <mail@joachim-breitner.de> | 2013-11-21 16:40:42 +0000 |
---|---|---|
committer | Joachim Breitner <mail@joachim-breitner.de> | 2013-11-22 18:01:05 +0000 |
commit | e9e413ecbcc9676d12f7de6e461ab17e56a8ced5 (patch) | |
tree | 464e3f1eebc8618ebc9a31c2e86602f4cea28ce8 | |
parent | b6b5c4179b3363f2ceafc55e64b545316c11dc26 (diff) | |
download | haskell-e9e413ecbcc9676d12f7de6e461ab17e56a8ced5.tar.gz |
Large refactor: Move CtLoc field from Ct to CtEvidence
-rw-r--r-- | compiler/typecheck/Inst.lhs | 6 | ||||
-rw-r--r-- | compiler/typecheck/TcCanonical.lhs | 313 | ||||
-rw-r--r-- | compiler/typecheck/TcErrors.lhs | 39 | ||||
-rw-r--r-- | compiler/typecheck/TcExpr.lhs | 2 | ||||
-rw-r--r-- | compiler/typecheck/TcInteract.lhs | 143 | ||||
-rw-r--r-- | compiler/typecheck/TcMType.lhs | 8 | ||||
-rw-r--r-- | compiler/typecheck/TcRnTypes.lhs | 33 | ||||
-rw-r--r-- | compiler/typecheck/TcSMonad.lhs | 69 | ||||
-rw-r--r-- | compiler/typecheck/TcUnify.lhs | 7 |
9 files changed, 303 insertions, 317 deletions
diff --git a/compiler/typecheck/Inst.lhs b/compiler/typecheck/Inst.lhs index db49902b81..e26d921953 100644 --- a/compiler/typecheck/Inst.lhs +++ b/compiler/typecheck/Inst.lhs @@ -83,7 +83,8 @@ emitWanted :: CtOrigin -> TcPredType -> TcM EvVar emitWanted origin pred = do { loc <- getCtLoc origin ; ev <- newWantedEvVar pred - ; emitFlat (mkNonCanonical loc (CtWanted { ctev_pred = pred, ctev_evar = ev })) + ; emitFlat $ mkNonCanonical $ + CtWanted { ctev_pred = pred, ctev_evar = ev, ctev_loc = loc } ; return ev } newMethodFromName :: CtOrigin -> Name -> TcRhoType -> TcM (HsExpr TcId) @@ -568,8 +569,7 @@ tidyCt env ct = case ct of CHoleCan { cc_ev = ev } -> ct { cc_ev = tidy_ev env ev } - _ -> CNonCanonical { cc_ev = tidy_ev env (cc_ev ct) - , cc_loc = cc_loc ct } + _ -> mkNonCanonical (tidy_ev env (ctEvidence ct)) where tidy_ev :: TidyEnv -> CtEvidence -> CtEvidence -- NB: we do not tidy the ctev_evtm/var field because we don't diff --git a/compiler/typecheck/TcCanonical.lhs b/compiler/typecheck/TcCanonical.lhs index 90780a7252..3c81c34c53 100644 --- a/compiler/typecheck/TcCanonical.lhs +++ b/compiler/typecheck/TcCanonical.lhs @@ -157,46 +157,42 @@ EvBinds, so we are again good. -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ canonicalize :: Ct -> TcS StopOrContinue -canonicalize ct@(CNonCanonical { cc_ev = ev, cc_loc = d }) +canonicalize ct@(CNonCanonical { cc_ev = ev }) = do { traceTcS "canonicalize (non-canonical)" (ppr ct) ; {-# SCC "canEvVar" #-} - canEvNC d ev } + canEvNC ev } -canonicalize (CDictCan { cc_loc = d - , cc_ev = ev +canonicalize (CDictCan { cc_ev = ev , cc_class = cls , cc_tyargs = xis }) = {-# SCC "canClass" #-} - canClass d ev cls xis -- Do not add any superclasses -canonicalize (CTyEqCan { cc_loc = d - , cc_ev = ev + canClass ev cls xis -- Do not add any superclasses +canonicalize (CTyEqCan { cc_ev = ev , cc_tyvar = tv , cc_rhs = xi }) = {-# SCC "canEqLeafTyVarEq" #-} - canEqLeafTyVar d ev tv xi + canEqLeafTyVar ev tv xi -canonicalize (CFunEqCan { cc_loc = d - , cc_ev = ev +canonicalize (CFunEqCan { cc_ev = ev , cc_fun = fn , cc_tyargs = xis1 , cc_rhs = xi2 }) = {-# SCC "canEqLeafFunEq" #-} - canEqLeafFun d ev fn xis1 xi2 + canEqLeafFun ev fn xis1 xi2 -canonicalize (CIrredEvCan { cc_ev = ev - , cc_loc = d }) - = canIrred d ev -canonicalize (CHoleCan { cc_ev = ev, cc_loc = d, cc_occ = occ }) - = canHole d ev occ +canonicalize (CIrredEvCan { cc_ev = ev }) + = canIrred ev +canonicalize (CHoleCan { cc_ev = ev, cc_occ = occ }) + = canHole ev occ -canEvNC :: CtLoc -> CtEvidence -> TcS StopOrContinue +canEvNC :: CtEvidence -> TcS StopOrContinue -- Called only for non-canonical EvVars -canEvNC d ev +canEvNC ev = case classifyPredType (ctEvPred ev) of - ClassPred cls tys -> traceTcS "canEvNC:cls" (ppr cls <+> ppr tys) >> canClassNC d ev cls tys - EqPred ty1 ty2 -> traceTcS "canEvNC:eq" (ppr ty1 $$ ppr ty2) >> canEqNC d ev ty1 ty2 - TuplePred tys -> traceTcS "canEvNC:tup" (ppr tys) >> canTuple d ev tys - IrredPred {} -> traceTcS "canEvNC:irred" (ppr (ctEvPred ev)) >> canIrred d ev + ClassPred cls tys -> traceTcS "canEvNC:cls" (ppr cls <+> ppr tys) >> canClassNC ev cls tys + EqPred ty1 ty2 -> traceTcS "canEvNC:eq" (ppr ty1 $$ ppr ty2) >> canEqNC ev ty1 ty2 + TuplePred tys -> traceTcS "canEvNC:tup" (ppr tys) >> canTuple ev tys + IrredPred {} -> traceTcS "canEvNC:irred" (ppr (ctEvPred ev)) >> canIrred ev \end{code} @@ -207,13 +203,13 @@ canEvNC d ev %************************************************************************ \begin{code} -canTuple :: CtLoc -> CtEvidence -> [PredType] -> TcS StopOrContinue -canTuple d ev tys +canTuple :: CtEvidence -> [PredType] -> TcS StopOrContinue +canTuple ev tys = do { traceTcS "can_pred" (text "TuplePred!") ; let xcomp = EvTupleMk xdecomp x = zipWith (\_ i -> EvTupleSel x i) tys [0..] ; ctevs <- xCtFlavor ev tys (XEvTerm xcomp xdecomp) - ; canEvVarsCreated d ctevs } + ; canEvVarsCreated ctevs } \end{code} %************************************************************************ @@ -224,8 +220,7 @@ canTuple d ev tys \begin{code} canClass, canClassNC - :: CtLoc - -> CtEvidence + :: CtEvidence -> Class -> [Type] -> TcS StopOrContinue -- Precondition: EvVar is class evidence @@ -234,12 +229,12 @@ canClass, canClassNC -- for already-canonical class constraints (but which might have -- been subsituted or somthing), and hence do not need superclasses -canClassNC d ev cls tys - = canClass d ev cls tys +canClassNC ev cls tys + = canClass ev cls tys `andWhenContinue` emitSuperclasses -canClass d ev cls tys - = do { (xis, cos) <- flattenMany d FMFullFlatten ev tys +canClass ev cls tys + = do { (xis, cos) <- flattenMany FMFullFlatten ev tys ; let co = mkTcTyConAppCo (classTyCon cls) cos xi = mkClassPred cls xis ; mb <- rewriteCtFlavor ev xi co @@ -248,15 +243,14 @@ canClass d ev cls tys ; case mb of Nothing -> return Stop Just new_ev -> continueWith $ - CDictCan { cc_ev = new_ev, cc_loc = d + CDictCan { cc_ev = new_ev , cc_tyargs = xis, cc_class = cls } } emitSuperclasses :: Ct -> TcS StopOrContinue -emitSuperclasses ct@(CDictCan { cc_loc = d, cc_ev = ev - , cc_tyargs = xis_new, cc_class = cls }) +emitSuperclasses ct@(CDictCan { cc_ev = ev , cc_tyargs = xis_new, cc_class = cls }) -- Add superclasses of this one here, See Note [Adding superclasses]. -- But only if we are not simplifying the LHS of a rule. - = do { newSCWorkFromFlavored d ev cls xis_new + = do { newSCWorkFromFlavored ev cls xis_new -- Arguably we should "seq" the coercions if they are derived, -- as we do below for emit_kind_constraint, to allow errors in -- superclasses to be executed if deferred to runtime! @@ -328,10 +322,9 @@ By adding superclasses definitely only once, during canonicalisation, this situa happen. \begin{code} -newSCWorkFromFlavored :: CtLoc -- Depth - -> CtEvidence -> Class -> [Xi] -> TcS () +newSCWorkFromFlavored :: CtEvidence -> Class -> [Xi] -> TcS () -- Returns superclasses, see Note [Adding superclasses] -newSCWorkFromFlavored d flavor cls xis +newSCWorkFromFlavored flavor cls xis | isDerived flavor = return () -- Deriveds don't yield more superclasses because we will -- add them transitively in the case of wanteds. @@ -342,7 +335,7 @@ newSCWorkFromFlavored d flavor cls xis xev = XEvTerm { ev_comp = panic "Can't compose for given!" , ev_decomp = xev_decomp } ; ctevs <- xCtFlavor flavor sc_theta xev - ; emitWorkNC d ctevs } + ; emitWorkNC ctevs } | isEmptyVarSet (tyVarsOfTypes xis) = return () -- Wanteds with no variables yield no deriveds. @@ -351,9 +344,10 @@ newSCWorkFromFlavored d flavor cls xis | otherwise -- Wanted case, just add those SC that can lead to improvement. = do { let sc_rec_theta = transSuperClasses cls xis impr_theta = filter is_improvement_pty sc_rec_theta + loc = ctev_loc flavor ; traceTcS "newSCWork/Derived" $ text "impr_theta =" <+> ppr impr_theta - ; mb_der_evs <- mapM newDerived impr_theta - ; emitWorkNC d (catMaybes mb_der_evs) } + ; mb_der_evs <- mapM (newDerived loc) impr_theta + ; emitWorkNC (catMaybes mb_der_evs) } is_improvement_pty :: PredType -> Bool -- Either it's an equality, or has some functional dependency @@ -375,12 +369,12 @@ is_improvement_pty ty = go (classifyPredType ty) \begin{code} -canIrred :: CtLoc -> CtEvidence -> TcS StopOrContinue +canIrred :: CtEvidence -> TcS StopOrContinue -- Precondition: ty not a tuple and no other evidence form -canIrred d old_ev +canIrred old_ev = do { let old_ty = ctEvPred old_ev ; traceTcS "can_pred" (text "IrredPred = " <+> ppr old_ty) - ; (xi,co) <- flatten d FMFullFlatten old_ev old_ty -- co :: xi ~ old_ty + ; (xi,co) <- flatten FMFullFlatten old_ev old_ty -- co :: xi ~ old_ty ; mb <- rewriteCtFlavor old_ev xi co ; case mb of { Nothing -> return Stop ; @@ -388,12 +382,12 @@ canIrred d old_ev do { -- Re-classify, in case flattening has improved its shape ; case classifyPredType (ctEvPred new_ev) of - ClassPred cls tys -> canClassNC d new_ev cls tys - TuplePred tys -> canTuple d new_ev tys + ClassPred cls tys -> canClassNC new_ev cls tys + TuplePred tys -> canTuple new_ev tys EqPred ty1 ty2 - | something_changed old_ty ty1 ty2 -> canEqNC d new_ev ty1 ty2 + | something_changed old_ty ty1 ty2 -> canEqNC new_ev ty1 ty2 _ -> continueWith $ - CIrredEvCan { cc_ev = new_ev, cc_loc = d } } } } + CIrredEvCan { cc_ev = new_ev } } } } where -- If the constraint was a kind-mis-matched equality, we must -- retry canEqNC only if something has changed, otherwise we @@ -407,13 +401,13 @@ canIrred d old_ev | otherwise = True -canHole :: CtLoc -> CtEvidence -> OccName -> TcS StopOrContinue -canHole d ev occ +canHole :: CtEvidence -> OccName -> TcS StopOrContinue +canHole ev occ = do { let ty = ctEvPred ev - ; (xi,co) <- flatten d FMFullFlatten ev ty -- co :: xi ~ ty + ; (xi,co) <- flatten FMFullFlatten ev ty -- co :: xi ~ ty ; mb <- rewriteCtFlavor ev xi co ; case mb of - Just new_ev -> emitInsoluble (CHoleCan { cc_ev = new_ev, cc_loc = d, cc_occ = occ }) + Just new_ev -> emitInsoluble (CHoleCan { cc_ev = new_ev, cc_occ = occ }) Nothing -> return () -- Found a cached copy; won't happen ; return Stop } \end{code} @@ -469,7 +463,7 @@ unexpanded synonym. data FlattenMode = FMSubstOnly | FMFullFlatten -- Flatten a bunch of types all at once. -flattenMany :: CtLoc -> FlattenMode +flattenMany :: FlattenMode -> CtEvidence -> [Type] -> TcS ([Xi], [TcCoercion]) -- Coercions :: Xi ~ Type @@ -477,46 +471,46 @@ flattenMany :: CtLoc -> FlattenMode -- NB: The EvVar inside the 'ctxt :: CtEvidence' is unused, -- we merely want (a) Given/Solved/Derived/Wanted info -- (b) the GivenLoc/WantedLoc for when we create new evidence -flattenMany d f ctxt tys +flattenMany f ctxt tys = -- pprTrace "flattenMany" empty $ go tys where go [] = return ([],[]) - go (ty:tys) = do { (xi,co) <- flatten d f ctxt ty + go (ty:tys) = do { (xi,co) <- flatten f ctxt ty ; (xis,cos) <- go tys ; return (xi:xis,co:cos) } -- Flatten a type to get rid of type function applications, returning -- the new type-function-free type, and a collection of new equality -- constraints. See Note [Flattening] for more detail. -flatten :: CtLoc -> FlattenMode +flatten :: FlattenMode -> CtEvidence -> TcType -> TcS (Xi, TcCoercion) -- Postcondition: Coercion :: Xi ~ TcType -flatten loc f ctxt ty +flatten f ctxt ty | Just ty' <- tcView ty - = do { (xi, co) <- flatten loc f ctxt ty' - ; if tcEqType xi ty then return (ty,co) else return (xi,co) } + = do { (xi, co) <- flatten f ctxt ty' + ; if eqType xi ty then return (ty,co) else return (xi,co) } -- Small tweak for better error messages -flatten _ _ _ xi@(LitTy {}) = return (xi, mkTcReflCo xi) +flatten _ _ xi@(LitTy {}) = return (xi, mkTcReflCo xi) -flatten loc f ctxt (TyVarTy tv) - = flattenTyVar loc f ctxt tv +flatten f ctxt (TyVarTy tv) + = flattenTyVar f ctxt tv -flatten loc f ctxt (AppTy ty1 ty2) - = do { (xi1,co1) <- flatten loc f ctxt ty1 - ; (xi2,co2) <- flatten loc f ctxt ty2 +flatten f ctxt (AppTy ty1 ty2) + = do { (xi1,co1) <- flatten f ctxt ty1 + ; (xi2,co2) <- flatten f ctxt ty2 ; return (mkAppTy xi1 xi2, mkTcAppCo co1 co2) } -flatten loc f ctxt (FunTy ty1 ty2) - = do { (xi1,co1) <- flatten loc f ctxt ty1 - ; (xi2,co2) <- flatten loc f ctxt ty2 +flatten f ctxt (FunTy ty1 ty2) + = do { (xi1,co1) <- flatten f ctxt ty1 + ; (xi2,co2) <- flatten f ctxt ty2 ; return (mkFunTy xi1 xi2, mkTcFunCo co1 co2) } -flatten loc f ctxt (TyConApp tc tys) +flatten f ctxt (TyConApp tc tys) -- For a normal type constructor or data family application, we just -- recursively flatten the arguments. | not (isSynFamilyTyCon tc) - = do { (xis,cos) <- flattenMany loc f ctxt tys + = do { (xis,cos) <- flattenMany f ctxt tys ; return (mkTyConApp tc xis, mkTcTyConAppCo tc cos) } -- Otherwise, it's a type function application, and we have to @@ -524,7 +518,7 @@ flatten loc f ctxt (TyConApp tc tys) -- between the application and a newly generated flattening skolem variable. | otherwise = ASSERT( tyConArity tc <= length tys ) -- Type functions are saturated - do { (xis, cos) <- flattenMany loc f ctxt tys + do { (xis, cos) <- flattenMany f ctxt tys ; let (xi_args, xi_rest) = splitAt (tyConArity tc) xis (cos_args, cos_rest) = splitAt (tyConArity tc) cos -- The type function might be *over* saturated @@ -549,7 +543,7 @@ flatten loc f ctxt (TyConApp tc tys) -- cache as well when we interact an equality with the inert. -- The design choice is: do we keep the flat cache rewritten or not? -- For now I say we don't keep it fully rewritten. - do { (rhs_xi,co) <- flatten loc f ctev rhs_ty + do { (rhs_xi,co) <- flatten f ctev rhs_ty ; let final_co = evTermCoercion (ctEvTerm ctev) `mkTcTransCo` mkTcSymCo co ; traceTcS "flatten/flat-cache hit" $ (ppr ctev $$ ppr rhs_xi $$ ppr final_co) @@ -559,8 +553,7 @@ flatten loc f ctxt (TyConApp tc tys) ; let ct = CFunEqCan { cc_ev = ctev , cc_fun = tc , cc_tyargs = xi_args - , cc_rhs = rhs_xi - , cc_loc = loc } + , cc_rhs = rhs_xi } ; updWorkListTcS $ extendWorkListFunEq ct ; traceTcS "flatten/flat-cache miss" $ (ppr fam_ty $$ ppr rhs_xi $$ ppr ctev) ; return (evTermCoercion (ctEvTerm ctev), rhs_xi) } @@ -573,11 +566,11 @@ flatten loc f ctxt (TyConApp tc tys) ) } -flatten loc _f ctxt ty@(ForAllTy {}) +flatten _f ctxt ty@(ForAllTy {}) -- We allow for-alls when, but only when, no type function -- applications inside the forall involve the bound type variables. = do { let (tvs, rho) = splitForAllTys ty - ; (rho', co) <- flatten loc FMSubstOnly ctxt rho + ; (rho', co) <- flatten FMSubstOnly ctxt rho -- Substitute only under a forall -- See Note [Flattening under a forall] ; return (mkForAllTys tvs rho', foldr mkTcForAllCo co tvs) } @@ -602,27 +595,26 @@ and we have not begun to think about how to make that work! \begin{code} flattenTyVar, flattenFinalTyVar - :: CtLoc -> FlattenMode - -> CtEvidence -> TcTyVar -> TcS (Xi, TcCoercion) + :: FlattenMode -> CtEvidence -> TcTyVar -> TcS (Xi, TcCoercion) -- "Flattening" a type variable means to apply the substitution to it -- The substitution is actually the union of the substitution in the TyBinds -- for the unification variables that have been unified already with the inert -- equalities, see Note [Spontaneously solved in TyBinds] in TcInteract. -flattenTyVar loc f ctxt tv +flattenTyVar f ctxt tv | not (isTcTyVar tv) -- Happens when flatten under a (forall a. ty) - = flattenFinalTyVar loc f ctxt tv -- So ty contains referneces to the non-TcTyVar a + = flattenFinalTyVar f ctxt tv -- So ty contains referneces to the non-TcTyVar a | otherwise = do { mb_ty <- isFilledMetaTyVar_maybe tv ; case mb_ty of { Just ty -> do { traceTcS "Following filled tyvar" (ppr tv <+> equals <+> ppr ty) - ; flatten loc f ctxt ty } ; + ; flatten f ctxt ty } ; Nothing -> -- Try in ty_binds do { ty_binds <- getTcSTyBindsMap ; case lookupVarEnv ty_binds tv of { Just (_tv,ty) -> do { traceTcS "Following bound tyvar" (ppr tv <+> equals <+> ppr ty) - ; flatten loc f ctxt ty } ; + ; flatten f ctxt ty } ; -- NB: ty_binds coercions are all ReflCo, -- so no need to transitively compose co' with another coercion, -- unlike in 'flatten_from_inerts' @@ -634,19 +626,19 @@ flattenTyVar loc f ctxt tv ; case mco of { Just (co,ty) -> do { traceTcS "Following inert tyvar" (ppr tv <+> equals <+> ppr ty) - ; (ty_final,co') <- flatten loc f ctxt ty + ; (ty_final,co') <- flatten f ctxt ty ; return (ty_final, co' `mkTcTransCo` mkTcSymCo co) } ; -- NB recursive call. -- Why? Because inert subst. non-idempotent, Note [Detailed InertCans Invariants] -- In fact, because of flavors, it couldn't possibly be idempotent, -- this is explained in Note [Non-idempotent inert substitution] - Nothing -> flattenFinalTyVar loc f ctxt tv + Nothing -> flattenFinalTyVar f ctxt tv } } } } } } where tv_eq_subst subst tv | Just (ct:_) <- lookupVarEnv subst tv -- If the first doesn't work, the - , let ctev = cc_ev ct -- subsequent ones won't either + , let ctev = ctEvidence ct -- subsequent ones won't either rhs = cc_rhs ct , ctev `canRewrite` ctxt = Just (evTermCoercion (ctEvTerm ctev), rhs) @@ -654,10 +646,10 @@ flattenTyVar loc f ctxt tv -- touch the actual coercion so we are fine. | otherwise = Nothing -flattenFinalTyVar loc f ctxt tv +flattenFinalTyVar f ctxt tv = -- Done, but make sure the kind is zonked do { let knd = tyVarKind tv - ; (new_knd, _kind_co) <- flatten loc f ctxt knd + ; (new_knd, _kind_co) <- flatten f ctxt knd ; let ty = mkTyVarTy (setVarType tv new_knd) ; return (ty, mkTcReflCo ty) } \end{code} @@ -698,25 +690,25 @@ Insufficient (non-recursive) rewriting was the reason for #5668. %************************************************************************ \begin{code} -canEvVarsCreated :: CtLoc -> [CtEvidence] -> TcS StopOrContinue -canEvVarsCreated _loc [] = return Stop +canEvVarsCreated :: [CtEvidence] -> TcS StopOrContinue +canEvVarsCreated [] = return Stop -- Add all but one to the work list -- and return the first (if any) for futher processing -canEvVarsCreated loc (ev : evs) - = do { emitWorkNC loc evs; canEvNC loc ev } +canEvVarsCreated (ev : evs) + = do { emitWorkNC evs; canEvNC ev } -- Note the "NC": these are fresh goals, not necessarily canonical -emitWorkNC :: CtLoc -> [CtEvidence] -> TcS () -emitWorkNC loc evs +emitWorkNC :: [CtEvidence] -> TcS () +emitWorkNC evs | null evs = return () | otherwise = updWorkListTcS (extendWorkListCts (map mk_nc evs)) where - mk_nc ev = CNonCanonical { cc_ev = ev, cc_loc = loc } + mk_nc ev = mkNonCanonical ev ------------------------- -canEqNC :: CtLoc -> CtEvidence -> Type -> Type -> TcS StopOrContinue +canEqNC :: CtEvidence -> Type -> Type -> TcS StopOrContinue -canEqNC _loc ev ty1 ty2 +canEqNC ev ty1 ty2 | tcEqType ty1 ty2 -- Dealing with equality here avoids -- later spurious occurs checks for a~a = if isWanted ev then @@ -727,36 +719,36 @@ canEqNC _loc ev ty1 ty2 -- If one side is a variable, orient and flatten, -- WITHOUT expanding type synonyms, so that we tend to -- substitute a ~ Age rather than a ~ Int when @type Age = Int@ -canEqNC loc ev ty1@(TyVarTy {}) ty2 - = canEqLeaf loc ev ty1 ty2 -canEqNC loc ev ty1 ty2@(TyVarTy {}) - = canEqLeaf loc ev ty1 ty2 +canEqNC ev ty1@(TyVarTy {}) ty2 + = canEqLeaf ev ty1 ty2 +canEqNC ev ty1 ty2@(TyVarTy {}) + = canEqLeaf ev ty1 ty2 -- See Note [Naked given applications] -canEqNC loc ev ty1 ty2 - | Just ty1' <- tcView ty1 = canEqNC loc ev ty1' ty2 - | Just ty2' <- tcView ty2 = canEqNC loc ev ty1 ty2' +canEqNC ev ty1 ty2 + | Just ty1' <- tcView ty1 = canEqNC ev ty1' ty2 + | Just ty2' <- tcView ty2 = canEqNC ev ty1 ty2' -canEqNC loc ev ty1@(TyConApp fn tys) ty2 +canEqNC ev ty1@(TyConApp fn tys) ty2 | isSynFamilyTyCon fn, length tys == tyConArity fn - = canEqLeaf loc ev ty1 ty2 -canEqNC loc ev ty1 ty2@(TyConApp fn tys) + = canEqLeaf ev ty1 ty2 +canEqNC ev ty1 ty2@(TyConApp fn tys) | isSynFamilyTyCon fn, length tys == tyConArity fn - = canEqLeaf loc ev ty1 ty2 + = canEqLeaf ev ty1 ty2 -canEqNC loc ev ty1 ty2 +canEqNC ev ty1 ty2 | Just (tc1,tys1) <- tcSplitTyConApp_maybe ty1 , Just (tc2,tys2) <- tcSplitTyConApp_maybe ty2 , isDecomposableTyCon tc1 && isDecomposableTyCon tc2 - = canDecomposableTyConApp loc ev tc1 tys1 tc2 tys2 + = canDecomposableTyConApp ev tc1 tys1 tc2 tys2 -canEqNC loc ev s1@(ForAllTy {}) s2@(ForAllTy {}) +canEqNC ev s1@(ForAllTy {}) s2@(ForAllTy {}) | tcIsForAllTy s1, tcIsForAllTy s2 - , CtWanted { ctev_evar = orig_ev } <- ev + , CtWanted { ctev_loc = loc, ctev_evar = orig_ev } <- ev = do { let (tvs1,body1) = tcSplitForAllTys s1 (tvs2,body2) = tcSplitForAllTys s2 ; if not (equalLength tvs1 tvs2) then - canEqFailure loc ev s1 s2 + canEqFailure ev s1 s2 else do { traceTcS "Creating implication for polytype equality" $ ppr ev ; deferTcSForAllEq (loc,orig_ev) (tvs1,body1) (tvs2,body2) @@ -770,9 +762,9 @@ canEqNC loc ev s1@(ForAllTy {}) s2@(ForAllTy {}) -- e.g. F a b ~ Maybe c where F has arity 1 -- See Note [Equality between type applications] -- Note [Care with type applications] in TcUnify -canEqNC loc ev ty1 ty2 - = do { (s1, co1) <- flatten loc FMSubstOnly ev ty1 - ; (s2, co2) <- flatten loc FMSubstOnly ev ty2 +canEqNC ev ty1 ty2 + = do { (s1, co1) <- flatten FMSubstOnly ev ty1 + ; (s2, co2) <- flatten FMSubstOnly ev ty2 ; mb_ct <- rewriteCtFlavor ev (mkTcEqPred s1 s2) (mkHdEqPred s2 co1 co2) ; case mb_ct of Nothing -> return Stop @@ -782,7 +774,7 @@ canEqNC loc ev ty1 ty2 | Just (tc1,tys1) <- tcSplitTyConApp_maybe ty1 , Just (tc2,tys2) <- tcSplitTyConApp_maybe ty2 , isDecomposableTyCon tc1 && isDecomposableTyCon tc2 - = canDecomposableTyConApp loc ev tc1 tys1 tc2 tys2 + = canDecomposableTyConApp ev tc1 tys1 tc2 tys2 | Just (s1,t1) <- tcSplitAppTy_maybe ty1 , Just (s2,t2) <- tcSplitAppTy_maybe ty2 @@ -791,37 +783,37 @@ canEqNC loc ev ty1 ty2 xevdecomp x = let xco = evTermCoercion x in [EvCoercion (mkTcLRCo CLeft xco), EvCoercion (mkTcLRCo CRight xco)] ; ctevs <- xCtFlavor ev [mkTcEqPred s1 s2, mkTcEqPred t1 t2] (XEvTerm xevcomp xevdecomp) - ; canEvVarsCreated loc ctevs } + ; canEvVarsCreated ctevs } | otherwise - = do { emitInsoluble (CNonCanonical { cc_ev = ev, cc_loc = loc }) + = do { emitInsoluble (mkNonCanonical ev) ; return Stop } ------------------------ -canDecomposableTyConApp :: CtLoc -> CtEvidence +canDecomposableTyConApp :: CtEvidence -> TyCon -> [TcType] -> TyCon -> [TcType] -> TcS StopOrContinue -canDecomposableTyConApp loc ev tc1 tys1 tc2 tys2 +canDecomposableTyConApp ev tc1 tys1 tc2 tys2 | tc1 /= tc2 || length tys1 /= length tys2 -- Fail straight away for better error messages - = canEqFailure loc ev (mkTyConApp tc1 tys1) (mkTyConApp tc2 tys2) + = canEqFailure ev (mkTyConApp tc1 tys1) (mkTyConApp tc2 tys2) | otherwise = do { let xcomp xs = EvCoercion (mkTcTyConAppCo tc1 (map evTermCoercion xs)) xdecomp x = zipWith (\_ i -> EvCoercion $ mkTcNthCo i (evTermCoercion x)) tys1 [0..] xev = XEvTerm xcomp xdecomp ; ctevs <- xCtFlavor ev (zipWith mkTcEqPred tys1 tys2) xev - ; canEvVarsCreated loc ctevs } + ; canEvVarsCreated ctevs } -canEqFailure :: CtLoc -> CtEvidence -> TcType -> TcType -> TcS StopOrContinue +canEqFailure :: CtEvidence -> TcType -> TcType -> TcS StopOrContinue -- See Note [Make sure that insolubles are fully rewritten] -canEqFailure loc ev ty1 ty2 - = do { (s1, co1) <- flatten loc FMSubstOnly ev ty1 - ; (s2, co2) <- flatten loc FMSubstOnly ev ty2 +canEqFailure ev ty1 ty2 + = do { (s1, co1) <- flatten FMSubstOnly ev ty1 + ; (s2, co2) <- flatten FMSubstOnly ev ty2 ; mb_ct <- rewriteCtFlavor ev (mkTcEqPred s1 s2) (mkHdEqPred s2 co1 co2) ; case mb_ct of - Just new_ev -> emitInsoluble (CNonCanonical { cc_ev = new_ev, cc_loc = loc }) + Just new_ev -> emitInsoluble (mkNonCanonical new_ev) Nothing -> pprPanic "canEqFailure" (ppr ev $$ ppr ty1 $$ ppr ty2) ; return Stop } \end{code} @@ -1036,7 +1028,7 @@ reOrient (VarCls tv1) (VarCls tv2) ------------------ -canEqLeaf :: CtLoc -> CtEvidence +canEqLeaf :: CtEvidence -> Type -> Type -> TcS StopOrContinue -- Canonicalizing "leaf" equality constraints which cannot be @@ -1051,7 +1043,7 @@ canEqLeaf :: CtLoc -> CtEvidence -- NB: at this point we do NOT know that the kinds of s1 and s2 are -- compatible. See Note [Equalities with incompatible kinds] -canEqLeaf loc ev s1 s2 +canEqLeaf ev s1 s2 | cls1 `reOrient` cls2 = do { traceTcS "canEqLeaf (reorienting)" doc ; let xcomp [x] = EvCoercion (mkTcSymCo (evTermCoercion x)) @@ -1061,12 +1053,12 @@ canEqLeaf loc ev s1 s2 ; ctevs <- xCtFlavor ev [mkTcEqPred s2 s1] xev ; case ctevs of [] -> return Stop - [ctev] -> canEqLeafOriented loc ctev cls2 s1 + [ctev] -> canEqLeafOriented ctev cls2 s1 _ -> panic "canEqLeaf" } | otherwise = do { traceTcS "canEqLeaf" doc - ; canEqLeafOriented loc ev cls1 s2 } + ; canEqLeafOriented ev cls1 s2 } where cls1 = classify s1 cls2 = classify s2 @@ -1074,23 +1066,21 @@ canEqLeaf loc ev s1 s2 , hang (ppr s1) 2 (dcolon <+> ppr (typeKind s1)) , hang (ppr s2) 2 (dcolon <+> ppr (typeKind s2)) ] -canEqLeafOriented :: CtLoc -> CtEvidence - -> TypeClassifier -> TcType -> TcS StopOrContinue +canEqLeafOriented :: CtEvidence -> TypeClassifier -> TcType -> TcS StopOrContinue -- By now s1 will either be a variable or a type family application -canEqLeafOriented loc ev (FunCls fn tys1) s2 = canEqLeafFun loc ev fn tys1 s2 -canEqLeafOriented loc ev (VarCls tv) s2 = canEqLeafTyVar loc ev tv s2 -canEqLeafOriented _ ev (OtherCls {}) _ = pprPanic "canEqLeafOriented" (ppr (ctEvPred ev)) +canEqLeafOriented ev (FunCls fn tys1) s2 = canEqLeafFun ev fn tys1 s2 +canEqLeafOriented ev (VarCls tv) s2 = canEqLeafTyVar ev tv s2 +canEqLeafOriented ev (OtherCls {}) _ = pprPanic "canEqLeafOriented" (ppr (ctEvPred ev)) -canEqLeafFun :: CtLoc -> CtEvidence - -> TyCon -> [TcType] -> TcType -> TcS StopOrContinue -canEqLeafFun loc ev fn tys1 ty2 -- ev :: F tys1 ~ ty2 +canEqLeafFun :: CtEvidence -> TyCon -> [TcType] -> TcType -> TcS StopOrContinue +canEqLeafFun ev fn tys1 ty2 -- ev :: F tys1 ~ ty2 = do { traceTcS "canEqLeafFun" $ pprEq (mkTyConApp fn tys1) ty2 -- Flatten type function arguments -- cos1 :: xis1 ~ tys1 -- co2 :: xi2 ~ ty2 - ; (xis1,cos1) <- flattenMany loc FMFullFlatten ev tys1 - ; (xi2, co2) <- flatten loc FMFullFlatten ev ty2 + ; (xis1,cos1) <- flattenMany FMFullFlatten ev tys1 + ; (xi2, co2) <- flatten FMFullFlatten ev ty2 -- Fancy higher-dimensional coercion between equalities! -- SPJ asks why? Why not just co : F xis1 ~ F tys1? @@ -1103,17 +1093,16 @@ canEqLeafFun loc ev fn tys1 ty2 -- ev :: F tys1 ~ ty2 Nothing -> return Stop Just new_ev | typeKind fam_head `isSubKind` typeKind xi2 -- Establish CFunEqCan kind invariant - -> continueWith (CFunEqCan { cc_ev = new_ev, cc_loc = loc - , cc_fun = fn, cc_tyargs = xis1, cc_rhs = xi2 }) + -> continueWith (CFunEqCan { cc_ev = new_ev, cc_fun = fn + , cc_tyargs = xis1, cc_rhs = xi2 }) | otherwise - -> checkKind loc new_ev fam_head xi2 } + -> checkKind new_ev fam_head xi2 } -canEqLeafTyVar :: CtLoc -> CtEvidence - -> TcTyVar -> TcType -> TcS StopOrContinue -canEqLeafTyVar loc ev tv s2 -- ev :: tv ~ s2 +canEqLeafTyVar :: CtEvidence -> TcTyVar -> TcType -> TcS StopOrContinue +canEqLeafTyVar ev tv s2 -- ev :: tv ~ s2 = do { traceTcS "canEqLeafTyVar 1" $ pprEq (mkTyVarTy tv) s2 - ; (xi1,co1) <- flattenTyVar loc FMFullFlatten ev tv -- co1 :: xi1 ~ tv - ; (xi2,co2) <- flatten loc FMFullFlatten ev s2 -- co2 :: xi2 ~ s2 + ; (xi1,co1) <- flattenTyVar FMFullFlatten ev tv -- co1 :: xi1 ~ tv + ; (xi2,co2) <- flatten FMFullFlatten ev s2 -- co2 :: xi2 ~ s2 ; let co = mkHdEqPred s2 co1 co2 -- co :: (xi1 ~ xi2) ~ (tv ~ s2) @@ -1124,7 +1113,7 @@ canEqLeafTyVar loc ev tv s2 -- ev :: tv ~ s2 do { mb <- rewriteCtFlavor ev (mkTcEqPred xi1 xi2) co ; case mb of Nothing -> return Stop - Just new_ev -> canEqNC loc new_ev xi1 xi2 } + Just new_ev -> canEqNC new_ev xi1 xi2 } (Just tv1, Just tv2) | tv1 == tv2 -> do { when (isWanted ev) $ @@ -1132,14 +1121,14 @@ canEqLeafTyVar loc ev tv s2 -- ev :: tv ~ s2 ; return Stop } (Just tv1, _) -> do { dflags <- getDynFlags - ; canEqLeafTyVar2 dflags loc ev tv1 xi2 co } } + ; canEqLeafTyVar2 dflags ev tv1 xi2 co } } -canEqLeafTyVar2 :: DynFlags -> CtLoc -> CtEvidence +canEqLeafTyVar2 :: DynFlags -> CtEvidence -> TyVar -> Type -> TcCoercion -> TcS StopOrContinue -- LHS rewrote to a type variable, -- RHS to something else (possibly a tyvar, but not the *same* tyvar) -canEqLeafTyVar2 dflags loc ev tv1 xi2 co +canEqLeafTyVar2 dflags ev tv1 xi2 co | OC_OK xi2' <- occurCheckExpand dflags tv1 xi2 -- No occurs check = do { mb <- rewriteCtFlavor ev (mkTcEqPred xi1 xi2') co -- Ensure that the new goal has enough type synonyms @@ -1151,21 +1140,20 @@ canEqLeafTyVar2 dflags loc ev tv1 xi2 co -- Establish CTyEqCan kind invariant -- Reorientation has done its best, but the kinds might -- simply be incompatible - -> continueWith (CTyEqCan { cc_ev = new_ev, cc_loc = loc + -> continueWith (CTyEqCan { cc_ev = new_ev , cc_tyvar = tv1, cc_rhs = xi2' }) | otherwise - -> checkKind loc new_ev xi1 xi2' } + -> checkKind new_ev xi1 xi2' } | otherwise -- Occurs check error = do { mb <- rewriteCtFlavor ev (mkTcEqPred xi1 xi2) co ; case mb of Nothing -> return Stop - Just new_ev -> canEqFailure loc new_ev xi1 xi2 } + Just new_ev -> canEqFailure new_ev xi1 xi2 } where xi1 = mkTyVarTy tv1 -checkKind :: CtLoc - -> CtEvidence -- t1~t2 +checkKind :: CtEvidence -- t1~t2 -> TcType -> TcType -- s1~s2, flattened and zonked -> TcS StopOrContinue -- LHS and RHS have incompatible kinds, so emit an "irreducible" constraint @@ -1175,16 +1163,16 @@ checkKind :: CtLoc -- a second attempt at solving -- See Note [Equalities with incompatible kinds] -checkKind loc new_ev s1 s2 +checkKind new_ev s1 s2 = ASSERT( isKind k1 && isKind k2 ) do { -- See Note [Equalities with incompatible kinds] traceTcS "canEqLeaf: incompatible kinds" (vcat [ppr k1, ppr k2]) ; updWorkListTcS $ extendWorkListNonEq $ - CIrredEvCan { cc_ev = new_ev, cc_loc = loc } - ; mw <- newDerived (mkEqPred k1 k2) + CIrredEvCan { cc_ev = new_ev } + ; mw <- newDerived kind_co_loc (mkEqPred k1 k2) ; case mw of Nothing -> return Stop - Just kev -> canEqNC kind_co_loc kev k1 k2 } + Just kev -> canEqNC kev k1 k2 } -- Always create a Wanted kind equality even if -- you are decomposing a given constraint. @@ -1192,6 +1180,7 @@ checkKind loc new_ev s1 s2 where k1 = typeKind s1 k2 = typeKind s2 + loc = ctev_loc new_ev kind_co_loc = setCtLocOrigin loc (KindEqOrigin s1 s2 (ctLocOrigin loc)) diff --git a/compiler/typecheck/TcErrors.lhs b/compiler/typecheck/TcErrors.lhs index 63e22f63fd..a89cf7cd31 100644 --- a/compiler/typecheck/TcErrors.lhs +++ b/compiler/typecheck/TcErrors.lhs @@ -337,7 +337,7 @@ mkGroupReporter :: (ReportErrCtxt -> [Ct] -> TcM ErrMsg) mkGroupReporter mk_err ctxt cts = mapM_ (reportGroup mk_err ctxt) (equivClasses cmp_loc cts) where - cmp_loc ct1 ct2 = ctLocSpan (cc_loc ct1) `compare` ctLocSpan (cc_loc ct2) + cmp_loc ct1 ct2 = ctLocSpan (ctev_loc (ctEvidence ct1)) `compare` ctLocSpan (ctev_loc (ctEvidence ct2)) reportGroup :: (ReportErrCtxt -> [Ct] -> TcM ErrMsg) -> ReportErrCtxt -> [Ct] -> TcM () @@ -361,7 +361,7 @@ maybeReportError ctxt err maybeAddDeferredBinding :: ReportErrCtxt -> ErrMsg -> Ct -> TcM () -- See Note [Deferring coercion errors to runtime] maybeAddDeferredBinding ctxt err ct - | CtWanted { ctev_pred = pred, ctev_evar = ev_id } <- cc_ev ct + | CtWanted { ctev_pred = pred, ctev_evar = ev_id } <- ctEvidence ct -- Only add deferred bindings for Wanted constraints , isHoleCt ct || cec_defer ctxt -- And it's a hole or we have -fdefer-type-errors , Just ev_binds_var <- cec_binds ctxt -- We have somewhere to put the bindings @@ -418,13 +418,13 @@ pprWithArising (ct:cts) | otherwise = (loc, vcat (map ppr_one (ct:cts))) where - loc = cc_loc ct + loc = ctev_loc (ctEvidence ct) ppr_one ct = hang (parens (pprType (ctPred ct))) - 2 (pprArisingAt (cc_loc ct)) + 2 (pprArisingAt (ctev_loc (ctEvidence ct))) mkErrorMsg :: ReportErrCtxt -> Ct -> SDoc -> TcM ErrMsg mkErrorMsg ctxt ct msg - = do { let tcl_env = ctLocEnv (cc_loc ct) + = do { let tcl_env = ctLocEnv (ctev_loc (ctEvidence ct)) ; err_info <- mkErrInfo (cec_tidy ctxt) (tcl_ctxt tcl_env) ; mkLongErrAt (tcl_loc tcl_env) msg err_info } @@ -518,7 +518,7 @@ mkIrredErr ctxt cts ; mkErrorMsg ctxt ct1 (msg $$ binds_msg) } where (ct1:_) = cts - orig = ctLocOrigin (cc_loc ct1) + orig = ctLocOrigin (ctev_loc (ctEvidence ct1)) givens = getUserGivens ctxt msg = couldNotDeduce givens (map ctPred cts, orig) @@ -528,7 +528,7 @@ mkHoleError ctxt ct@(CHoleCan { cc_occ = occ }) = do { let tyvars = varSetElems (tyVarsOfCt ct) tyvars_msg = map loc_msg tyvars msg = vcat [ hang (ptext (sLit "Found hole") <+> quotes (ppr occ)) - 2 (ptext (sLit "with type:") <+> pprType (ctEvPred (cc_ev ct))) + 2 (ptext (sLit "with type:") <+> pprType (ctEvPred (ctEvidence ct))) , ppUnless (null tyvars_msg) (ptext (sLit "Where:") <+> vcat tyvars_msg) ] ; (ctxt, binds_doc) <- relevantBindings False ctxt ct -- The 'False' means "don't filter the bindings; see Trac #8191 @@ -551,7 +551,7 @@ mkIPErr ctxt cts ; mkErrorMsg ctxt ct1 (msg $$ bind_msg) } where (ct1:_) = cts - orig = ctLocOrigin (cc_loc ct1) + orig = ctLocOrigin (ctev_loc (ctEvidence ct1)) preds = map ctPred cts givens = getUserGivens ctxt msg | null givens @@ -602,25 +602,26 @@ mkEqErr1 ctxt ct ; let (given_loc, given_msg) = mk_given (cec_encl ctxt) ; dflags <- getDynFlags ; mkEqErr_help dflags ctxt (given_msg $$ binds_msg) - (ct { cc_loc = given_loc}) -- Note [Inaccessible code] + (ct { cc_ev = ev {ctev_loc = given_loc}}) -- Note [Inaccessible code] Nothing ty1 ty2 } | otherwise -- Wanted or derived = do { (ctxt, binds_msg) <- relevantBindings True ctxt ct - ; (ctxt, tidy_orig) <- zonkTidyOrigin ctxt (ctLocOrigin (cc_loc ct)) + ; (ctxt, tidy_orig) <- zonkTidyOrigin ctxt (ctLocOrigin loc) ; let (is_oriented, wanted_msg) = mk_wanted_extra tidy_orig ; dflags <- getDynFlags ; mkEqErr_help dflags ctxt (wanted_msg $$ binds_msg) ct is_oriented ty1 ty2 } where - ev = cc_ev ct + ev = ctEvidence ct + loc = ctev_loc ev (ty1, ty2) = getEqPredTys (ctEvPred ev) mk_given :: [Implication] -> (CtLoc, SDoc) -- For given constraints we overwrite the env (and hence src-loc) -- with one from the implication. See Note [Inaccessible code] - mk_given [] = (cc_loc ct, empty) - mk_given (implic : _) = (setCtLocEnv (cc_loc ct) (ic_env implic) + mk_given [] = (loc, empty) + mk_given (implic : _) = (setCtLocEnv loc (ic_env implic) , hang (ptext (sLit "Inaccessible code in")) 2 (ppr (ic_info implic))) @@ -993,7 +994,7 @@ mk_dict_err ctxt (ct, (matches, unifiers, safe_haskell)) | otherwise = return (ctxt, safe_haskell_msg) where - orig = ctLocOrigin (cc_loc ct) + orig = ctLocOrigin (ctev_loc (ctEvidence ct)) pred = ctPred ct (clas, tys) = getClassPredTys pred ispecs = [ispec | (ispec, _) <- matches] @@ -1324,7 +1325,7 @@ relevantBindings want_filtering ctxt ct else do { traceTc "rb" doc ; return (ctxt { cec_tidy = tidy_env' }, doc) } } where - lcl_env = ctLocEnv (cc_loc ct) + lcl_env = ctLocEnv (ctev_loc (ctEvidence ct)) ct_tvs = tyVarsOfCt ct run_out :: Maybe Int -> Bool @@ -1396,16 +1397,16 @@ are created by in RtClosureInspect.zonkRTTIType. %************************************************************************ \begin{code} -solverDepthErrorTcS :: SubGoalCounter -> Ct -> TcM a -solverDepthErrorTcS cnt ct +solverDepthErrorTcS :: SubGoalCounter -> CtEvidence -> TcM a +solverDepthErrorTcS cnt ev = setCtLoc loc $ - do { pred <- zonkTcType (ctPred ct) + do { pred <- zonkTcType (ctEvPred ev) ; env0 <- tcInitTidyEnv ; let tidy_env = tidyFreeTyVars env0 (tyVarsOfType pred) tidy_pred = tidyType tidy_env pred ; failWithTcM (tidy_env, hang (msg cnt) 2 (ppr tidy_pred)) } where - loc = cc_loc ct + loc = ctev_loc ev depth = ctLocDepth loc value = subGoalCounterValue cnt depth msg CountConstraints = diff --git a/compiler/typecheck/TcExpr.lhs b/compiler/typecheck/TcExpr.lhs index 2b4f6aa702..6f3eb41ffd 100644 --- a/compiler/typecheck/TcExpr.lhs +++ b/compiler/typecheck/TcExpr.lhs @@ -137,7 +137,7 @@ tcHole occ res_ty ; name <- newSysName occ ; let ev = mkLocalId name ty ; loc <- getCtLoc HoleOrigin - ; let can = CHoleCan { cc_ev = CtWanted ty ev, cc_loc = loc, cc_occ = occ } + ; let can = CHoleCan { cc_ev = CtWanted ty ev loc, cc_occ = occ } ; emitInsoluble can ; tcWrapResult (HsVar ev) ty res_ty } \end{code} diff --git a/compiler/typecheck/TcInteract.lhs b/compiler/typecheck/TcInteract.lhs index 8b9e758d29..36d0c09c38 100644 --- a/compiler/typecheck/TcInteract.lhs +++ b/compiler/typecheck/TcInteract.lhs @@ -95,12 +95,14 @@ solveInteractGiven loc fsks givens -- See Note [Do not decompose given polytype equalities] -- in TcCanonical where - given_bag = listToBag [ mkNonCanonical loc $ CtGiven { ctev_evtm = EvId ev_id - , ctev_pred = evVarPred ev_id } + given_bag = listToBag [ mkNonCanonical $ CtGiven { ctev_evtm = EvId ev_id + , ctev_pred = evVarPred ev_id + , ctev_loc = loc } | ev_id <- givens ] - fsk_bag = listToBag [ mkNonCanonical loc $ CtGiven { ctev_evtm = EvCoercion (mkTcReflCo tv_ty) - , ctev_pred = pred } + fsk_bag = listToBag [ mkNonCanonical $ CtGiven { ctev_evtm = EvCoercion (mkTcReflCo tv_ty) + , ctev_pred = pred + , ctev_loc = loc } | tv <- fsks , let FlatSkol fam_ty = tcTyVarDetails tv tv_ty = mkTyVarTy tv @@ -125,7 +127,7 @@ solveInteract cts NoWorkRemaining -- Done, successfuly (modulo frozen) -> return () MaxDepthExceeded cnt ct -- Failure, depth exceeded - -> wrapErrTcS $ solverDepthErrorTcS cnt ct + -> wrapErrTcS $ solverDepthErrorTcS cnt (ctEvidence ct) NextWorkItem ct -- More work, loop around! -> do { runSolverPipeline thePipeline ct; solve_loop max_depth } } @@ -151,7 +153,7 @@ selectNextWorkItem max_depth (Nothing,_) -> (NoWorkRemaining,wl) -- No more work (Just ct, new_wl) - | Just cnt <- subGoalDepthExceeded max_depth (ctLocDepth (cc_loc ct)) -- Depth exceeded + | Just cnt <- subGoalDepthExceeded max_depth (ctLocDepth (ctev_loc (ctEvidence ct))) -- Depth exceeded -> (MaxDepthExceeded cnt ct,new_wl) (Just ct, new_wl) -> (NextWorkItem ct, new_wl) -- New workitem and worklist @@ -408,8 +410,9 @@ interactGivenIP _ wi = pprPanic "interactGivenIP" (ppr wi) addFunDepWork :: Ct -> Ct -> TcS () addFunDepWork work_ct inert_ct - = do { let work_loc = cc_loc work_ct - inert_pred_loc = (ctPred inert_ct, pprArisingAt (cc_loc inert_ct)) + = do { let work_loc = ctev_loc (ctEvidence work_ct) + inert_loc = ctev_loc (ctEvidence inert_ct) + inert_pred_loc = (ctPred inert_ct, pprArisingAt inert_loc) work_item_pred_loc = (ctPred work_ct, pprArisingAt work_loc) ; let fd_eqns = improveFromAnother inert_pred_loc work_item_pred_loc @@ -489,13 +492,13 @@ I can think of two ways to fix this: \begin{code} interactFunEq :: InertCans -> Ct -> TcS (Maybe InertCans, StopNowFlag) interactFunEq inerts workItem@(CFunEqCan { cc_ev = ev, cc_fun = tc - , cc_tyargs = args, cc_rhs = rhs, cc_loc = loc }) + , cc_tyargs = args, cc_rhs = rhs }) | (CFunEqCan { cc_ev = ev_i, cc_rhs = rhs_i } : _) <- matching_inerts , ev_i `canRewrite` ev = do { traceTcS "interact with inerts: FunEq/FunEq" $ vcat [ text "workItem =" <+> ppr workItem , text "inertItem=" <+> ppr ev_i ] - ; solveFunEq loc ev_i rhs_i ev rhs + ; solveFunEq ev_i rhs_i ev rhs ; return (Nothing, True) } | (ev_i : _) <- [ ev_i | CFunEqCan { cc_ev = ev_i, cc_rhs = rhs_i } <- matching_inerts @@ -507,15 +510,15 @@ interactFunEq inerts workItem@(CFunEqCan { cc_ev = ev, cc_fun = tc | eq_is@(eq_i : _) <- matching_inerts , ev `canRewrite` ctEvidence eq_i -- This is unusual = do { let solve (CFunEqCan { cc_ev = ev_i, cc_rhs = rhs_i }) - = solveFunEq loc ev rhs ev_i rhs_i + = solveFunEq ev rhs ev_i rhs_i solve ct = pprPanic "interactFunEq" (ppr ct) ; mapM_ solve eq_is ; return (Just (inerts { inert_funeqs = replaceFunEqs funeqs tc args workItem }), True) } | (CFunEqCan { cc_rhs = rhs_i } : _) <- matching_inerts - = do { mb <- newDerived (mkTcEqPred rhs_i rhs) + = do { mb <- newDerived loc (mkTcEqPred rhs_i rhs) ; case mb of - Just x -> updWorkListTcS (extendWorkListEq (mkNonCanonical loc x)) + Just x -> updWorkListTcS (extendWorkListEq (mkNonCanonical x)) Nothing -> return () ; return (Nothing, False) } @@ -524,13 +527,13 @@ interactFunEq inerts workItem@(CFunEqCan { cc_ev = ev, cc_fun = tc ; traceTcS "builtInCandidates: " $ ppr is ; let interact = sfInteractInert ops args rhs ; impMbs <- sequence - [ do mb <- newDerived (mkTcEqPred lhs_ty rhs_ty) + [ do mb <- newDerived (ctev_loc iev) (mkTcEqPred lhs_ty rhs_ty) case mb of - Just x -> return $ Just $ mkNonCanonical d x + Just x -> return $ Just $ mkNonCanonical x Nothing -> return Nothing | CFunEqCan { cc_tyargs = iargs , cc_rhs = ixi - , cc_loc = d } <- is + , cc_ev = iev } <- is , Pair lhs_ty rhs_ty <- interact iargs ixi ] ; let imps = catMaybes impMbs @@ -542,22 +545,22 @@ interactFunEq inerts workItem@(CFunEqCan { cc_ev = ev, cc_fun = tc where funeqs = inert_funeqs inerts matching_inerts = findFunEqs funeqs tc args + loc = ctev_loc ev interactFunEq _ wi = pprPanic "interactFunEq" (ppr wi) -solveFunEq :: CtLoc - -> CtEvidence -- From this :: F tys ~ xi1 +solveFunEq :: CtEvidence -- From this :: F tys ~ xi1 -> Type -> CtEvidence -- Solve this :: F tys ~ xi2 -> Type -> TcS () -solveFunEq loc from_this xi1 solve_this xi2 +solveFunEq from_this xi1 solve_this xi2 = do { ctevs <- xCtFlavor solve_this [mkTcEqPred xi2 xi1] xev -- No caching! See Note [Cache-caused loops] -- Why not (mkTcEqPred xi1 xi2)? See Note [Efficient orientation] - ; emitWorkNC loc ctevs } + ; emitWorkNC ctevs } where from_this_co = evTermCoercion $ ctEvTerm from_this @@ -664,8 +667,7 @@ test when solving pairwise CFunEqCan. \begin{code} interactTyVarEq :: InertCans -> Ct -> TcS (Maybe InertCans, StopNowFlag) -- CTyEqCans are always consumed, returning Stop -interactTyVarEq inerts workItem@(CTyEqCan { cc_tyvar = tv, cc_rhs = rhs - , cc_ev = ev, cc_loc = loc }) +interactTyVarEq inerts workItem@(CTyEqCan { cc_tyvar = tv, cc_rhs = rhs , cc_ev = ev }) | (ev_i : _) <- [ ev_i | CTyEqCan { cc_ev = ev_i, cc_rhs = rhs_i } <- findTyEqs (inert_eqs inerts) tv , ev_i `canRewriteOrSame` ev @@ -689,7 +691,7 @@ interactTyVarEq inerts workItem@(CTyEqCan { cc_tyvar = tv, cc_rhs = rhs ; return (Nothing, True) } | otherwise - = do { mb_solved <- trySpontaneousSolve ev tv rhs loc + = do { mb_solved <- trySpontaneousSolve ev tv rhs ; case mb_solved of SPCantSolve -- Includes givens -> do { untch <- getUntouchables @@ -716,7 +718,8 @@ interactTyVarEq _ wi = pprPanic "interactTyVarEq" (ppr wi) givenFlavour :: CtEvidence -- Used just to pass to kickOutRewritable givenFlavour = CtGiven { ctev_pred = panic "givenFlavour:ev" - , ctev_evtm = panic "givenFlavour:tm" } + , ctev_evtm = panic "givenFlavour:tm" + , ctev_loc = panic "givenFlavour:loc" } ppr_kicked :: Int -> SDoc ppr_kicked 0 = empty @@ -893,8 +896,8 @@ data SPSolveResult = SPCantSolve -- @trySpontaneousSolve wi@ solves equalities where one side is a -- touchable unification variable. -trySpontaneousSolve :: CtEvidence -> TcTyVar -> Xi -> CtLoc -> TcS SPSolveResult -trySpontaneousSolve gw tv1 xi d +trySpontaneousSolve :: CtEvidence -> TcTyVar -> Xi -> TcS SPSolveResult +trySpontaneousSolve gw tv1 xi | isGiven gw -- See Note [Touchables and givens] = return SPCantSolve @@ -902,36 +905,34 @@ trySpontaneousSolve gw tv1 xi d = do { tch1 <- isTouchableMetaTyVarTcS tv1 ; tch2 <- isTouchableMetaTyVarTcS tv2 ; case (tch1, tch2) of - (True, True) -> trySpontaneousEqTwoWay d gw tv1 tv2 - (True, False) -> trySpontaneousEqOneWay d gw tv1 xi - (False, True) -> trySpontaneousEqOneWay d gw tv2 (mkTyVarTy tv1) + (True, True) -> trySpontaneousEqTwoWay gw tv1 tv2 + (True, False) -> trySpontaneousEqOneWay gw tv1 xi + (False, True) -> trySpontaneousEqOneWay gw tv2 (mkTyVarTy tv1) _ -> return SPCantSolve } | otherwise = do { tch1 <- isTouchableMetaTyVarTcS tv1 - ; if tch1 then trySpontaneousEqOneWay d gw tv1 xi + ; if tch1 then trySpontaneousEqOneWay gw tv1 xi else return SPCantSolve } ---------------- -trySpontaneousEqOneWay :: CtLoc -> CtEvidence - -> TcTyVar -> Xi -> TcS SPSolveResult +trySpontaneousEqOneWay :: CtEvidence -> TcTyVar -> Xi -> TcS SPSolveResult -- tv is a MetaTyVar, not untouchable -trySpontaneousEqOneWay d gw tv xi +trySpontaneousEqOneWay gw tv xi | not (isSigTyVar tv) || isTyVarTy xi , typeKind xi `tcIsSubKind` tyVarKind tv - = solveWithIdentity d gw tv xi + = solveWithIdentity gw tv xi | otherwise -- Still can't solve, sig tyvar and non-variable rhs = return SPCantSolve ---------------- -trySpontaneousEqTwoWay :: CtLoc -> CtEvidence - -> TcTyVar -> TcTyVar -> TcS SPSolveResult +trySpontaneousEqTwoWay :: CtEvidence -> TcTyVar -> TcTyVar -> TcS SPSolveResult -- Both tyvars are *touchable* MetaTyvars so there is only a chance for kind error here -trySpontaneousEqTwoWay d gw tv1 tv2 +trySpontaneousEqTwoWay gw tv1 tv2 | k1 `tcIsSubKind` k2 && nicer_to_update_tv2 - = solveWithIdentity d gw tv2 (mkTyVarTy tv1) + = solveWithIdentity gw tv2 (mkTyVarTy tv1) | k2 `tcIsSubKind` k1 - = solveWithIdentity d gw tv1 (mkTyVarTy tv2) + = solveWithIdentity gw tv1 (mkTyVarTy tv2) | otherwise = return SPCantSolve where @@ -959,7 +960,7 @@ double unifications is the main reason we disallow touchable unification variables as RHS of type family equations: F xis ~ alpha. \begin{code} -solveWithIdentity :: CtLoc -> CtEvidence -> TcTyVar -> Xi -> TcS SPSolveResult +solveWithIdentity :: CtEvidence -> TcTyVar -> Xi -> TcS SPSolveResult -- Solve with the identity coercion -- Precondition: kind(xi) is a sub-kind of kind(tv) -- Precondition: CtEvidence is Wanted or Derived @@ -972,7 +973,7 @@ solveWithIdentity :: CtLoc -> CtEvidence -> TcTyVar -> Xi -> TcS SPSolveResult -- arises from a CTyEqCan, a *canonical* constraint. Its invariants -- say that in (a ~ xi), the type variable a does not appear in xi. -- See TcRnTypes.Ct invariants. -solveWithIdentity _d wd tv xi +solveWithIdentity wd tv xi = do { let tv_ty = mkTyVarTy tv ; traceTcS "Sneaky unification:" $ vcat [text "Unifies:" <+> ppr tv <+> ptext (sLit ":=") <+> ppr xi, @@ -1361,9 +1362,9 @@ instFunDepEqn loc (FDEqn { fd_qtvs = tvs, fd_eqs = eqs | tcEqType sty1 sty2 = return ievs -- Return no trivial equalities | otherwise - = do { mb_eqv <- newDerived (mkTcEqPred sty1 sty2) + = do { mb_eqv <- newDerived der_loc (mkTcEqPred sty1 sty2) ; case mb_eqv of - Just ev -> return (mkNonCanonical der_loc ev : ievs) + Just ev -> return (mkNonCanonical (ev {ctev_loc = der_loc}) : ievs) Nothing -> return ievs } -- We are eventually going to emit FD work back in the work list so -- it is important that we only return the /freshly created/ and not @@ -1425,22 +1426,19 @@ doTopReact :: InertSet -> WorkItem -> TcS TopInteractResult doTopReact inerts workItem = do { traceTcS "doTopReact" (ppr workItem) ; case workItem of - CDictCan { cc_ev = fl, cc_class = cls, cc_tyargs = xis - , cc_loc = d } - -> doTopReactDict inerts fl cls xis d + CDictCan { cc_ev = fl, cc_class = cls, cc_tyargs = xis } + -> doTopReactDict inerts fl cls xis - CFunEqCan { cc_ev = fl, cc_fun = tc, cc_tyargs = args - , cc_rhs = xi, cc_loc = d } - -> doTopReactFunEq workItem fl tc args xi d + CFunEqCan { cc_ev = fl, cc_fun = tc, cc_tyargs = args , cc_rhs = xi } + -> doTopReactFunEq workItem fl tc args xi _ -> -- Any other work item does not react with any top-level equations return NoTopInt } -------------------- -doTopReactDict :: InertSet -> CtEvidence -> Class -> [Xi] - -> CtLoc -> TcS TopInteractResult +doTopReactDict :: InertSet -> CtEvidence -> Class -> [Xi] -> TcS TopInteractResult -- Try to use type-class instance declarations to simplify the constraint -doTopReactDict inerts fl cls xis loc +doTopReactDict inerts fl cls xis | not (isWanted fl) -- Never use instances for Given or Derived constraints = try_fundeps_and_return @@ -1459,6 +1457,7 @@ doTopReactDict inerts fl cls xis loc arising_sdoc = pprArisingAt loc dict_id = ctEvId fl pred = mkClassPred cls xis + loc = ctev_loc fl solve_from_instance :: [CtEvidence] -> EvTerm -> TcS TopInteractResult -- Precondition: evidence term matches the predicate workItem @@ -1475,8 +1474,7 @@ doTopReactDict inerts fl cls xis loc ppr dict_id ; setEvBind dict_id ev_term ; let mk_new_wanted ev - = CNonCanonical { cc_ev = ev - , cc_loc = bumpCtLocDepth CountConstraints loc } + = mkNonCanonical (ev {ctev_loc = bumpCtLocDepth CountConstraints loc }) ; updWorkListTcS (extendWorkListCts (map mk_new_wanted evs)) ; return $ SomeTopInt { tir_rule = "Dict/Top (solved, more work)" @@ -1495,9 +1493,8 @@ doTopReactDict inerts fl cls xis loc ; return NoTopInt } -------------------- -doTopReactFunEq :: Ct -> CtEvidence -> TyCon -> [Xi] -> Xi - -> CtLoc -> TcS TopInteractResult -doTopReactFunEq _ct fl fun_tc args xi loc +doTopReactFunEq :: Ct -> CtEvidence -> TyCon -> [Xi] -> Xi -> TcS TopInteractResult +doTopReactFunEq _ct fl fun_tc args xi = ASSERT(isSynFamilyTyCon fun_tc) -- No associated data families have -- reached this far -- Look in the cache of solved funeqs @@ -1522,13 +1519,13 @@ doTopReactFunEq _ct fl fun_tc args xi loc ; succeed_with "Fun/Top" co ty } } } } } where fam_ty = mkTyConApp fun_tc args + loc = ctev_loc fl try_improvement | Just ops <- isBuiltInSynFamTyCon_maybe fun_tc = do { let eqns = sfInteractTop ops args xi - ; impsMb <- mapM (\(Pair x y) -> newDerived (mkTcEqPred x y)) - eqns - ; let work = map (mkNonCanonical loc) (catMaybes impsMb) + ; impsMb <- mapM (\(Pair x y) -> newDerived loc (mkTcEqPred x y)) eqns + ; let work = map mkNonCanonical (catMaybes impsMb) ; unless (null work) (updWorkListTcS (extendWorkListEqs work)) } | otherwise = return () @@ -1539,8 +1536,7 @@ doTopReactFunEq _ct fl fun_tc args xi loc ; traceTcS ("doTopReactFunEq " ++ str) (ppr ctevs) ; case ctevs of [ctev] -> updWorkListTcS $ extendWorkListEq $ - CNonCanonical { cc_ev = ctev - , cc_loc = bumpCtLocDepth CountTyFunApps loc } + mkNonCanonical (ctev { ctev_loc = bumpCtLocDepth CountTyFunApps loc }) ctevs -> -- No subgoal (because it's cached) ASSERT( null ctevs) return () ; return $ SomeTopInt { tir_rule = str @@ -1844,12 +1840,12 @@ matchClassInst _ clas [ ty ] _ _ -> panicTcS (text "Unexpected evidence for" <+> ppr (className clas) $$ vcat (map (ppr . idType) (classMethods clas))) -matchClassInst _ clas [ _k, ty1, ty2 ] _ +matchClassInst _ clas [ _k, ty1, ty2 ] loc | clas == coercibleClass = do traceTcS "matchClassInst for" $ ppr clas <+> ppr ty1 <+> ppr ty2 rdr_env <- getGlobalRdrEnvTcS safeMode <- safeLanguageOn `fmap` getDynFlags - ev <- getCoercibleInst safeMode rdr_env ty1 ty2 + ev <- getCoercibleInst safeMode rdr_env loc ty1 ty2 traceTcS "matchClassInst returned" $ ppr ev return ev @@ -1903,7 +1899,7 @@ matchClassInst inerts clas tys loc ; if null theta then return (GenInst [] (EvDFunApp dfun_id tys [])) else do - { evc_vars <- instDFunConstraints theta + { evc_vars <- instDFunConstraints loc theta ; let new_ev_vars = freshGoals evc_vars -- new_ev_vars are only the real new variables that can be emitted dfun_app = EvDFunApp dfun_id tys (getEvTerms evc_vars) @@ -1935,8 +1931,8 @@ matchClassInst inerts clas tys loc -- See Note [Coercible Instances] -- Changes to this logic should likely be reflected in coercible_msg in TcErrors. -getCoercibleInst :: Bool -> GlobalRdrEnv -> TcType -> TcType -> TcS LookupInstResult -getCoercibleInst safeMode rdr_env ty1 ty2 +getCoercibleInst :: Bool -> GlobalRdrEnv -> CtLoc -> TcType -> TcType -> TcS LookupInstResult +getCoercibleInst safeMode rdr_env loc ty1 ty2 | ty1 `tcEqType` ty2 = do return $ GenInst [] $ EvCoercible (EvCoercibleRefl ty1) @@ -1952,7 +1948,7 @@ getCoercibleInst safeMode rdr_env ty1 ty2 arg_evs <- flip mapM (zip3 (tyConRoles tc1) tyArgs1 tyArgs2) $ \(r,ta1,ta2) -> case r of Nominal -> return (Nothing, EvCoercibleArgN ta1 {- == ta2, due to nominalArgsAgree -}) Representational -> do - ct_ev <- requestCoercible ta1 ta2 + ct_ev <- requestCoercible loc ta1 ta2 return (freshGoal ct_ev, EvCoercibleArgR (getEvTerm ct_ev)) Phantom -> do return (Nothing, EvCoercibleArgP ta1 ta2) @@ -1966,7 +1962,7 @@ getCoercibleInst safeMode rdr_env ty1 ty2 dataConsInScope rdr_env tc -- Do noot look at all tyConsOfTyCon = do markDataConsAsUsed rdr_env tc let concTy = newTyConInstRhs tc tyArgs - ct_ev <- requestCoercible concTy ty2 + ct_ev <- requestCoercible loc concTy ty2 return $ GenInst (freshGoals [ct_ev]) $ EvCoercible (EvCoercibleNewType CLeft tc tyArgs (getEvTerm ct_ev)) @@ -1977,7 +1973,7 @@ getCoercibleInst safeMode rdr_env ty1 ty2 dataConsInScope rdr_env tc -- Do noot look at all tyConsOfTyCon = do markDataConsAsUsed rdr_env tc let concTy = newTyConInstRhs tc tyArgs - ct_ev <- requestCoercible ty1 concTy + ct_ev <- requestCoercible loc ty1 concTy return $ GenInst (freshGoals [ct_ev]) $ EvCoercible (EvCoercibleNewType CRight tc tyArgs (getEvTerm ct_ev)) @@ -2006,10 +2002,11 @@ markDataConsAsUsed rdr_env tc = addUsedRdrNamesTcS , not (null gres) , Imported (imp_spec:_) <- [gre_prov (head gres)] ] -requestCoercible :: TcType -> TcType -> TcS MaybeNew -requestCoercible ty1 ty2 = +requestCoercible :: CtLoc -> TcType -> TcType -> TcS MaybeNew +requestCoercible loc ty1 ty2 = ASSERT2( typeKind ty1 `tcEqKind` typeKind ty2, ppr ty1 <+> ppr ty2) - newWantedEvVar (coercibleClass `mkClassPred` [typeKind ty1, ty1, ty2]) + newWantedEvVar loc (coercibleClass `mkClassPred` [typeKind ty1, ty1, ty2]) + \end{code} Note [Coercible Instances] diff --git a/compiler/typecheck/TcMType.lhs b/compiler/typecheck/TcMType.lhs index 93e3c828da..ee93eb6d5a 100644 --- a/compiler/typecheck/TcMType.lhs +++ b/compiler/typecheck/TcMType.lhs @@ -170,9 +170,10 @@ newFlatWanteds orig theta where inst_to_wanted loc pty = do { v <- newWantedEvVar pty - ; return $ mkNonCanonical loc $ + ; return $ mkNonCanonical $ CtWanted { ctev_evar = v - , ctev_pred = pty } } + , ctev_pred = pty + , ctev_loc = loc } } \end{code} %************************************************************************ @@ -874,8 +875,7 @@ zonkCt ct@(CHoleCan { cc_ev = ev }) ; return $ ct { cc_ev = ev' } } zonkCt ct = do { fl' <- zonkCtEvidence (cc_ev ct) - ; return (CNonCanonical { cc_ev = fl' - , cc_loc = cc_loc ct }) } + ; return (mkNonCanonical fl') } zonkCtEvidence :: CtEvidence -> TcM CtEvidence zonkCtEvidence ctev@(CtGiven { ctev_pred = pred }) diff --git a/compiler/typecheck/TcRnTypes.lhs b/compiler/typecheck/TcRnTypes.lhs index b58d5ef6f8..cc93ca975a 100644 --- a/compiler/typecheck/TcRnTypes.lhs +++ b/compiler/typecheck/TcRnTypes.lhs @@ -913,19 +913,16 @@ data Ct = CDictCan { -- e.g. Num xi cc_ev :: CtEvidence, -- See Note [Ct/evidence invariant] cc_class :: Class, - cc_tyargs :: [Xi], - - cc_loc :: CtLoc + cc_tyargs :: [Xi] } | CIrredEvCan { -- These stand for yet-unusable predicates - cc_ev :: CtEvidence, -- See Note [Ct/evidence invariant] + cc_ev :: CtEvidence -- See Note [Ct/evidence invariant] -- The ctev_pred of the evidence is -- of form (tv xi1 xi2 ... xin) -- or (tv1 ~ ty2) where the CTyEqCan kind invariant fails -- or (F tys ~ ty) where the CFunEqCan kind invariant fails -- See Note [CIrredEvCan constraints] - cc_loc :: CtLoc } | CTyEqCan { -- tv ~ xi (recall xi means function free) @@ -936,8 +933,7 @@ data Ct -- * We prefer unification variables on the left *JUST* for efficiency cc_ev :: CtEvidence, -- See Note [Ct/evidence invariant] cc_tyvar :: TcTyVar, - cc_rhs :: Xi, - cc_loc :: CtLoc + cc_rhs :: Xi } | CFunEqCan { -- F xis ~ xi @@ -947,21 +943,17 @@ data Ct cc_ev :: CtEvidence, -- See Note [Ct/evidence invariant] cc_fun :: TyCon, -- A type function cc_tyargs :: [Xi], -- Either under-saturated or exactly saturated - cc_rhs :: Xi, -- *never* over-saturated (because if so + cc_rhs :: Xi -- *never* over-saturated (because if so -- we should have decomposed) - - cc_loc :: CtLoc } | CNonCanonical { -- See Note [NonCanonical Semantics] - cc_ev :: CtEvidence, - cc_loc :: CtLoc + cc_ev :: CtEvidence } | CHoleCan { -- Treated as an "insoluble" constraint -- See Note [Insoluble constraints] cc_ev :: CtEvidence, - cc_loc :: CtLoc, cc_occ :: OccName -- The name of this hole } \end{code} @@ -1039,11 +1031,11 @@ the evidence may *not* be fully zonked; we are careful not to look at it during constraint solving. See Note [Evidence field of CtEvidence] \begin{code} -mkNonCanonical :: CtLoc -> CtEvidence -> Ct -mkNonCanonical loc ev = CNonCanonical { cc_ev = ev, cc_loc = loc } +mkNonCanonical :: CtEvidence -> Ct +mkNonCanonical ev = CNonCanonical { cc_ev = ev } mkNonCanonicalCt :: Ct -> Ct -mkNonCanonicalCt ct = CNonCanonical { cc_ev = cc_ev ct, cc_loc = cc_loc ct } +mkNonCanonicalCt ct = CNonCanonical { cc_ev = cc_ev ct } ctEvidence :: Ct -> CtEvidence ctEvidence = cc_ev @@ -1384,15 +1376,18 @@ may be un-zonked. \begin{code} data CtEvidence = CtGiven { ctev_pred :: TcPredType -- See Note [Ct/evidence invariant] - , ctev_evtm :: EvTerm } -- See Note [Evidence field of CtEvidence] + , ctev_evtm :: EvTerm -- See Note [Evidence field of CtEvidence] + , ctev_loc :: CtLoc } -- Truly given, not depending on subgoals -- NB: Spontaneous unifications belong here | CtWanted { ctev_pred :: TcPredType -- See Note [Ct/evidence invariant] - , ctev_evar :: EvVar } -- See Note [Evidence field of CtEvidence] + , ctev_evar :: EvVar -- See Note [Evidence field of CtEvidence] + , ctev_loc :: CtLoc } -- Wanted goal - | CtDerived { ctev_pred :: TcPredType } + | CtDerived { ctev_pred :: TcPredType + , ctev_loc :: CtLoc } -- A goal that we don't really have to solve and can't immediately -- rewrite anything other than a derived (there's no evidence!) -- but if we do manage to solve it may help in solving other goals. diff --git a/compiler/typecheck/TcSMonad.lhs b/compiler/typecheck/TcSMonad.lhs index d2b9ea3edf..ca95914306 100644 --- a/compiler/typecheck/TcSMonad.lhs +++ b/compiler/typecheck/TcSMonad.lhs @@ -627,7 +627,8 @@ prepareInertsForImplications is where ev = ctEvidence funeq given_ev = CtGiven { ctev_evtm = EvId (ctev_evar ev) - , ctev_pred = ctev_pred ev } + , ctev_pred = ctev_pred ev + , ctev_loc = ctev_loc ev } given_from_wanted _ fhm = fhm -- Drop derived constraints @@ -1034,9 +1035,10 @@ traceFireTcS ct doc do { dflags <- getDynFlags ; when (dopt Opt_D_dump_cs_trace dflags && traceLevel dflags >= 1) $ do { n <- TcM.readTcRef (tcs_count env) - ; let msg = int n <> brackets (ppr (ctLocDepth (cc_loc ct))) - <+> ppr (ctEvidence ct) <> colon <+> doc + ; let msg = int n <> brackets (ppr (ctLocDepth (ctev_loc ev))) + <+> ppr ev <> colon <+> doc ; TcM.debugDumpTcRn msg } } + where ev = cc_ev ct runTcS :: TcS a -- What to run -> TcM (a, Bag EvBind) @@ -1421,7 +1423,8 @@ newFlattenSkolem ev fam_ty ; let rhs_ty = mkTyVarTy tv ctev = CtGiven { ctev_pred = mkTcEqPred fam_ty rhs_ty - , ctev_evtm = EvCoercion (mkTcReflCo fam_ty) } + , ctev_evtm = EvCoercion (mkTcReflCo fam_ty) + , ctev_loc = ctev_loc ev } ; dflags <- getDynFlags ; updInertTcS $ \ is@(IS { inert_fsks = fsks }) -> extendFlatCache dflags fam_ty ctev rhs_ty @@ -1431,7 +1434,7 @@ newFlattenSkolem ev fam_ty | otherwise -- Wanted or Derived: make new unification variable = do { rhs_ty <- newFlexiTcSTy (typeKind fam_ty) - ; ctev <- newWantedEvVarNC (mkTcEqPred fam_ty rhs_ty) + ; ctev <- newWantedEvVarNC (ctev_loc ev) (mkTcEqPred fam_ty rhs_ty) -- NC (no-cache) version because we've already -- looked in the solved goals an inerts (lookupFlatEqn) ; dflags <- getDynFlags @@ -1531,43 +1534,43 @@ setEvBind the_ev tm ; tc_evbinds <- getTcEvBinds ; wrapTcS $ TcM.addTcEvBind tc_evbinds the_ev tm } -newGivenEvVar :: TcPredType -> EvTerm -> TcS CtEvidence +newGivenEvVar :: CtLoc -> TcPredType -> EvTerm -> TcS CtEvidence -- Make a new variable of the given PredType, -- immediately bind it to the given term -- and return its CtEvidence -newGivenEvVar pred rhs +newGivenEvVar loc pred rhs = do { new_ev <- wrapTcS $ TcM.newEvVar pred ; setEvBind new_ev rhs - ; return (CtGiven { ctev_pred = pred, ctev_evtm = EvId new_ev }) } + ; return (CtGiven { ctev_pred = pred, ctev_evtm = EvId new_ev, ctev_loc = loc }) } -newWantedEvVarNC :: TcPredType -> TcS CtEvidence +newWantedEvVarNC :: CtLoc -> TcPredType -> TcS CtEvidence -- Don't look up in the solved/inerts; we know it's not there -newWantedEvVarNC pty +newWantedEvVarNC loc pty = do { new_ev <- wrapTcS $ TcM.newEvVar pty - ; return (CtWanted { ctev_pred = pty, ctev_evar = new_ev })} + ; return (CtWanted { ctev_pred = pty, ctev_evar = new_ev, ctev_loc = loc })} -newWantedEvVar :: TcPredType -> TcS MaybeNew -newWantedEvVar pty +newWantedEvVar :: CtLoc -> TcPredType -> TcS MaybeNew +newWantedEvVar loc pty = do { mb_ct <- lookupInInerts pty ; case mb_ct of Just ctev | not (isDerived ctev) -> do { traceTcS "newWantedEvVar/cache hit" $ ppr ctev ; return (Cached (ctEvTerm ctev)) } - _ -> do { ctev <- newWantedEvVarNC pty + _ -> do { ctev <- newWantedEvVarNC loc pty ; traceTcS "newWantedEvVar/cache miss" $ ppr ctev ; return (Fresh ctev) } } -newDerived :: TcPredType -> TcS (Maybe CtEvidence) +newDerived :: CtLoc -> TcPredType -> TcS (Maybe CtEvidence) -- Returns Nothing if cached, -- Just pred if not cached -newDerived pty +newDerived loc pty = do { mb_ct <- lookupInInerts pty ; return (case mb_ct of Just {} -> Nothing - Nothing -> Just (CtDerived { ctev_pred = pty })) } + Nothing -> Just (CtDerived { ctev_pred = pty, ctev_loc = loc })) } -instDFunConstraints :: TcThetaType -> TcS [MaybeNew] -instDFunConstraints = mapM newWantedEvVar +instDFunConstraints :: CtLoc -> TcThetaType -> TcS [MaybeNew] +instDFunConstraints loc = mapM (newWantedEvVar loc) \end{code} @@ -1616,18 +1619,18 @@ xCtFlavor :: CtEvidence -- Original flavor -> XEvTerm -- Instructions about how to manipulate evidence -> TcS [CtEvidence] -xCtFlavor (CtGiven { ctev_evtm = tm }) ptys xev +xCtFlavor (CtGiven { ctev_evtm = tm, ctev_loc = loc }) ptys xev = ASSERT( equalLength ptys (ev_decomp xev tm) ) - zipWithM newGivenEvVar ptys (ev_decomp xev tm) + zipWithM (newGivenEvVar loc) ptys (ev_decomp xev tm) -- See Note [Bind new Givens immediately] -xCtFlavor (CtWanted { ctev_evar = evar }) ptys xev - = do { new_evars <- mapM newWantedEvVar ptys +xCtFlavor (CtWanted { ctev_evar = evar, ctev_loc = loc }) ptys xev + = do { new_evars <- mapM (newWantedEvVar loc) ptys ; setEvBind evar (ev_comp xev (getEvTerms new_evars)) ; return (freshGoals new_evars) } -xCtFlavor (CtDerived {}) ptys _xev - = do { ders <- mapM newDerived ptys +xCtFlavor (CtDerived { ctev_loc = loc }) ptys _xev + = do { ders <- mapM (newDerived loc) ptys ; return (catMaybes ders) } ----------------------------- @@ -1659,7 +1662,7 @@ Main purpose: create new evidence for new_pred; -} -rewriteCtFlavor (CtDerived {}) new_pred _co +rewriteCtFlavor (CtDerived { ctev_loc = loc }) new_pred _co = -- If derived, don't even look at the coercion. -- This is very important, DO NOT re-order the equations for -- rewriteCtFlavor to put the isTcReflCo test first! @@ -1667,7 +1670,7 @@ rewriteCtFlavor (CtDerived {}) new_pred _co -- was produced by flattening, may contain suspended calls to -- (ctEvTerm c), which fails for Derived constraints. -- (Getting this wrong caused Trac #7384.) - newDerived new_pred + newDerived loc new_pred rewriteCtFlavor old_ev new_pred co | isTcReflCo co -- If just reflexivity then you may re-use the same variable @@ -1680,14 +1683,14 @@ rewriteCtFlavor old_ev new_pred co -- However, if they *do* look the same, we'd prefer to stick with old_pred -- then retain the old type, so that error messages come out mentioning synonyms -rewriteCtFlavor (CtGiven { ctev_evtm = old_tm }) new_pred co - = do { new_ev <- newGivenEvVar new_pred new_tm -- See Note [Bind new Givens immediately] +rewriteCtFlavor (CtGiven { ctev_evtm = old_tm , ctev_loc = loc }) new_pred co + = do { new_ev <- newGivenEvVar loc new_pred new_tm -- See Note [Bind new Givens immediately] ; return (Just new_ev) } where new_tm = mkEvCast old_tm (mkTcSymCo co) -- mkEvCast optimises ReflCo -rewriteCtFlavor (CtWanted { ctev_evar = evar }) new_pred co - = do { new_evar <- newWantedEvVar new_pred +rewriteCtFlavor (CtWanted { ctev_evar = evar, ctev_loc = loc }) new_pred co + = do { new_evar <- newWantedEvVar loc new_pred ; setEvBind evar (mkEvCast (getEvTerm new_evar) co) ; case new_evar of Fresh ctev -> return (Just ctev) @@ -1741,13 +1744,13 @@ deferTcSForAllEq (loc,orig_ev) (tvs1,body1) (tvs2,body2) phi1 = Type.substTy subst1 body1 phi2 = Type.substTy (zipTopTvSubst tvs2 tys) body2 skol_info = UnifyForAllSkol skol_tvs phi1 - ; mev <- newWantedEvVar (mkTcEqPred phi1 phi2) + ; mev <- newWantedEvVar loc (mkTcEqPred phi1 phi2) ; coe_inside <- case mev of Cached ev_tm -> return (evTermCoercion ev_tm) Fresh ctev -> do { ev_binds_var <- wrapTcS $ TcM.newTcEvBinds ; env <- wrapTcS $ TcM.getLclEnv ; let ev_binds = TcEvBinds ev_binds_var - new_ct = mkNonCanonical loc ctev + new_ct = mkNonCanonical ctev new_co = evTermCoercion (ctEvTerm ctev) new_untch = pushUntouchables (tcl_untch env) ; let wc = WC { wc_flat = singleCt new_ct diff --git a/compiler/typecheck/TcUnify.lhs b/compiler/typecheck/TcUnify.lhs index b226e4bb72..4a24504860 100644 --- a/compiler/typecheck/TcUnify.lhs +++ b/compiler/typecheck/TcUnify.lhs @@ -539,9 +539,10 @@ uType, uType_defer uType_defer origin ty1 ty2 = do { eqv <- newEq ty1 ty2 ; loc <- getCtLoc origin - ; let ctev = CtWanted { ctev_evar = eqv - , ctev_pred = mkTcEqPred ty1 ty2 } - ; emitFlat $ mkNonCanonical loc ctev + ; emitFlat $ mkNonCanonical $ + CtWanted { ctev_evar = eqv + , ctev_pred = mkTcEqPred ty1 ty2 + , ctev_loc = loc } -- Error trace only -- NB. do *not* call mkErrInfo unless tracing is on, because |