[commit: ghc] wip/redundant-constraints: Use a less fragile method for defaulting (e4c7531)
git at git.haskell.org
git at git.haskell.org
Mon Jan 5 15:01:24 UTC 2015
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/redundant-constraints
Link : http://ghc.haskell.org/trac/ghc/changeset/e4c7531db4d0999fe815fdb85e1a9069017a5492/ghc
>---------------------------------------------------------------
commit e4c7531db4d0999fe815fdb85e1a9069017a5492
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date: Mon Jan 5 10:53:37 2015 +0000
Use a less fragile method for defaulting
When doing top-level defaulting, in TcSimplify.applyDefaultingRules, we
were temporarily making a unification variable equal to the default type
(Integer, say, or Float), as a 'given', and trying to solve. But this
relied on the unification variable being untouchable, which seems
complicated. It's much simpler just to generate a new set of
constraints to solve, using newWantedEvVarNC in disambigGroup.
(I tripped over an ASSERT failure, and this solved it in a robust way.)
>---------------------------------------------------------------
e4c7531db4d0999fe815fdb85e1a9069017a5492
compiler/typecheck/TcSimplify.hs | 60 +++++++++++++++++++++++-----------------
1 file changed, 34 insertions(+), 26 deletions(-)
diff --git a/compiler/typecheck/TcSimplify.hs b/compiler/typecheck/TcSimplify.hs
index 0c9b093..61fd591 100644
--- a/compiler/typecheck/TcSimplify.hs
+++ b/compiler/typecheck/TcSimplify.hs
@@ -101,7 +101,7 @@ simpl_top wanteds
| isEmptyWC wc
= return wc
| otherwise -- See Note [When to do type-class defaulting]
- = do { something_happened <- applyDefaultingRules (approximateWC wc)
+ = do { something_happened <- applyDefaultingRules wc
-- See Note [Top-level Defaulting Plan]
; if something_happened
then do { wc_residual <- nestTcS (solveWantedsAndDrop wc)
@@ -1337,13 +1337,13 @@ to beta[1], and that means the (a ~ beta[1]) will be stuck, as it should be.
*********************************************************************************
-}
-applyDefaultingRules :: Cts -> TcS Bool
+applyDefaultingRules :: WantedConstraints -> TcS Bool
-- True <=> I did some defaulting, reflected in ty_binds
-- Return some extra derived equalities, which express the
-- type-class default choice.
applyDefaultingRules wanteds
- | isEmptyBag wanteds
+ | isEmptyWC wanteds
= return False
| otherwise
= do { traceTcS "applyDefaultingRules { " $
@@ -1351,8 +1351,10 @@ applyDefaultingRules wanteds
; info@(default_tys, _) <- getDefaultInfo
; let groups = findDefaultableGroups info wanteds
+
; traceTcS "findDefaultableGroups" $ vcat [ text "groups=" <+> ppr groups
, text "info=" <+> ppr info ]
+
; something_happeneds <- mapM (disambigGroup default_tys) groups
; traceTcS "applyDefaultingRules }" (ppr something_happeneds)
@@ -1361,19 +1363,27 @@ applyDefaultingRules wanteds
findDefaultableGroups
:: ( [Type]
- , (Bool,Bool) ) -- (Overloaded strings, extended default rules)
- -> Cts -- Unsolved (wanted or derived)
- -> [[(Ct,Class,TcTyVar)]]
+ , (Bool,Bool) ) -- (Overloaded strings, extended default rules)
+ -> WantedConstraints -- Unsolved (wanted or derived)
+ -> [(TyVar, [Class], Cts)]
findDefaultableGroups (default_tys, (ovl_strings, extended_defaults)) wanteds
- | null default_tys = []
- | otherwise = defaultable_groups
+ | null default_tys
+ = []
+ | otherwise
+ = [ (tv, clss, listToBag (map fstOf3 group))
+ | group@((_,_,tv):_) <- groups
+ , let clss = map sndOf3 group
+ , defaultable_tyvar tv
+ , defaultable_classes clss ]
where
- defaultable_groups = filter is_defaultable_group groups
- groups = equivClasses cmp_tv unaries
- unaries :: [(Ct, Class, TcTyVar)] -- (C tv) constraints
- non_unaries :: [Ct] -- and *other* constraints
+ simples = approximateWC wanteds
+ (unaries, non_unaries) = partitionWith find_unary (bagToList simples)
+ groups = equivClasses cmp_tv unaries
+
+ groups :: [[(Ct, Class, TcTyVar)]] -- (C tv) constraints
+ unaries :: [(Ct, Class, TcTyVar)] -- (C tv) constraints
+ non_unaries :: [Ct] -- and *other* constraints
- (unaries, non_unaries) = partitionWith find_unary (bagToList wanteds)
-- Finds unary type-class constraints
-- But take account of polykinded classes like Typeable,
-- which may look like (Typeable * (a:*)) (Trac #8931)
@@ -1392,12 +1402,10 @@ findDefaultableGroups (default_tys, (ovl_strings, extended_defaults)) wanteds
cmp_tv (_,_,tv1) (_,_,tv2) = tv1 `compare` tv2
- is_defaultable_group ds@((_,_,tv):_)
+ defaultable_tyvar tv
= let b1 = isTyConableTyVar tv -- Note [Avoiding spurious errors]
b2 = not (tv `elemVarSet` bad_tvs)
- b4 = defaultable_classes [cls | (_,cls,_) <- ds]
- in (b1 && b2 && b4)
- is_defaultable_group [] = panic "defaultable_group"
+ in b1 && b2
defaultable_classes clss
| extended_defaults = any isInteractiveClass clss
@@ -1417,20 +1425,22 @@ findDefaultableGroups (default_tys, (ovl_strings, extended_defaults)) wanteds
------------------------------
disambigGroup :: [Type] -- The default types
- -> [(Ct, Class, TcTyVar)] -- All classes of the form (C a)
+ -> (TcTyVar, [Class], Cts) -- All classes of the form (C a)
-- sharing same type variable
-> TcS Bool -- True <=> something happened, reflected in ty_binds
-disambigGroup [] _grp
+disambigGroup [] _
= return False
-disambigGroup (default_ty:default_tys) group
- = do { traceTcS "disambigGroup {" (ppr group $$ ppr default_ty)
+disambigGroup (default_ty:default_tys) group@(the_tv, clss, wanteds)
+ = do { traceTcS "disambigGroup {" (vcat [ ppr default_ty, ppr the_tv, ppr wanteds ])
; fake_ev_binds_var <- TcS.newTcEvBinds
- ; given_ev_var <- TcS.newEvVar (mkTcEqPred (mkTyVarTy the_tv) default_ty)
; tclvl <- TcS.getTcLevel
; success <- nestImplicTcS fake_ev_binds_var (pushTcLevel tclvl) $
- do { solveSimpleGivens loc [given_ev_var]
- ; residual_wanted <- solveSimpleWanteds wanteds
+ do { wanted_evs <- mapM (newWantedEvVarNC loc)
+ [ mkClassPred cls [default_ty]
+ | cls <- clss ]
+ ; residual_wanted <- solveSimpleWanteds $ listToBag $
+ map mkNonCanonical wanted_evs
; return (isEmptyWC residual_wanted) }
; if success then
@@ -1445,8 +1455,6 @@ disambigGroup (default_ty:default_tys) group
(ppr default_ty)
; disambigGroup default_tys group } }
where
- wanteds = listToBag (map fstOf3 group)
- ((_,_,the_tv):_) = group
loc = CtLoc { ctl_origin = GivenOrigin UnkSkol
, ctl_env = panic "disambigGroup:env"
, ctl_depth = initialSubGoalDepth }
More information about the ghc-commits
mailing list