diff options
author | Dr. ERDI Gergo <gergo@erdi.hu> | 2015-01-03 15:37:36 +0800 |
---|---|---|
committer | Dr. ERDI Gergo <gergo@erdi.hu> | 2015-01-03 20:58:48 +0800 |
commit | 355a5fa25dafdfcbfca655db980bc2fc5b9211b6 (patch) | |
tree | d2e94faa723ca0162c5406b33764232ae1d6768f | |
parent | 2e2563376b6fa2b382e046e87a3cb132594a6dfb (diff) | |
download | haskell-355a5fa25dafdfcbfca655db980bc2fc5b9211b6.tar.gz |
Extract implicit equalities from result type of pattern synonym type signature
-rw-r--r-- | compiler/typecheck/TcPatSyn.hs | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/compiler/typecheck/TcPatSyn.hs b/compiler/typecheck/TcPatSyn.hs index e444ee4652..d0b316e1ee 100644 --- a/compiler/typecheck/TcPatSyn.hs +++ b/compiler/typecheck/TcPatSyn.hs @@ -130,6 +130,34 @@ tcCheckPatSynDecl PSB{ psb_id = lname@(L loc name), psb_args = details, ; checkTc (length arg_names == ty_arity) (wrongNumberOfParmsErr ty_arity) + -- Recover implicit type equalities + ; (pat_ty, spec_tvs, spec_eqs) <- case tcSplitTyConApp_maybe pat_ty of + Nothing -> return (pat_ty, [], []) + Just (tyCon, conArgs) -> do + { spec_eqs <- forM conArgs $ \conArg -> do + { tv <- zonkQuantifiedTyVar =<< newMetaTyVar SigTv (typeKind conArg) + ; return (tv, conArg) } + ; let spec_tvs = map fst spec_eqs + pat_ty' = mkTyConApp tyCon (map mkTyVarTy spec_tvs) + ; return (pat_ty', spec_tvs, spec_eqs) } + ; traceTc "tcCheckPatSynDecl spec {" $ + ppr pat_ty $$ + ppr spec_tvs $$ + ppr spec_eqs + + ; let con_arg_tvs = tcTyVarsOfTypes (map snd spec_eqs) + spec_theta = [ mkEqPred (mkTyVarTy tv) conArg + | (tv, conArg) <- spec_eqs ] + ; univ_tvs <- return $ filter (not . (`elemVarSet` con_arg_tvs)) univ_tvs ++ spec_tvs + ; ex_tvs <- return $ ex_tvs ++ varSetElems con_arg_tvs + -- ex_tys' = ex_tys ++ map mkTyVarTy (varSetElems con_arg_tvs) + ; prov_theta <- return $ prov_theta ++ spec_theta + + ; traceTc "tcCheckPatSynDecl spec }" $ + ppr univ_tvs $$ + ppr ex_tvs $$ + ppr prov_theta + -- Typecheck the pattern against pat_ty, then unify the type of args -- against arg_tys, with ex_tvs changed to SigTyVars. -- We get out of this: |