[commit: ghc] wip/type-app: Propagate polytypes into if and case. (0dedbfa)

git at git.haskell.org git at git.haskell.org
Fri Aug 7 12:05:28 UTC 2015


Repository : ssh://git@git.haskell.org/ghc

On branch  : wip/type-app
Link       : http://ghc.haskell.org/trac/ghc/changeset/0dedbfa0ae5695d9afad7e47afc4112fc0f23035/ghc

>---------------------------------------------------------------

commit 0dedbfa0ae5695d9afad7e47afc4112fc0f23035
Author: Richard Eisenberg <eir at cis.upenn.edu>
Date:   Fri Jul 10 10:15:15 2015 -0400

    Propagate polytypes into if and case.


>---------------------------------------------------------------

0dedbfa0ae5695d9afad7e47afc4112fc0f23035
 compiler/typecheck/TcExpr.hs    |  6 ++----
 compiler/typecheck/TcMType.hs   | 21 +++++++++++++++++++++
 compiler/typecheck/TcMatches.hs | 11 ++++-------
 3 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/compiler/typecheck/TcExpr.hs b/compiler/typecheck/TcExpr.hs
index ca7cbc3..26ce358 100644
--- a/compiler/typecheck/TcExpr.hs
+++ b/compiler/typecheck/TcExpr.hs
@@ -456,12 +456,10 @@ tcExpr (HsIf Nothing pred b1 b2) res_ty    -- Ordinary 'if'
   = do { pred' <- tcMonoExpr pred boolTy
             -- this forces the branches to be fully instantiated
             -- (See #10619)
-       ; tau_ty <- newFlexiTyVarTy openTypeKind
-       ; wrap   <- tcSubTypeHR tau_ty res_ty
-       ; tau_ty <- zonkTcType tau_ty
+       ; tau_ty <- tauTvsForReturnTvs res_ty
        ; b1' <- tcMonoExpr b1 tau_ty
        ; b2' <- tcMonoExpr b2 tau_ty
-       ; return $ mkHsWrap wrap $ HsIf Nothing pred' b1' b2' }
+       ; tcWrapResult (HsIf Nothing pred' b1' b2') tau_ty res_ty }
 
 tcExpr (HsIf (Just fun) pred b1 b2) res_ty
   -- Note [Rebindable syntax for if]
diff --git a/compiler/typecheck/TcMType.hs b/compiler/typecheck/TcMType.hs
index 4bf725f..01853dc 100644
--- a/compiler/typecheck/TcMType.hs
+++ b/compiler/typecheck/TcMType.hs
@@ -22,6 +22,7 @@ module TcMType (
   newReturnTyVar, newReturnTyVarTy,
   newMetaKindVar, newMetaKindVars,
   mkTcTyVarName, cloneMetaTyVar,
+  tauTvsForReturnTvs,
 
   newMetaTyVar, readMetaTyVar, writeMetaTyVar, writeMetaTyVarRef,
   newMetaDetails, isFilledMetaTyVar, isUnfilledMetaTyVar,
@@ -435,6 +436,26 @@ newReturnTyVar kind = newMetaTyVar ReturnTv kind
 newReturnTyVarTy :: Kind -> TcM TcType
 newReturnTyVarTy kind = TyVarTy <$> newReturnTyVar kind
 
+-- | Replace all the ReturnTvs in a type with TauTvs. These types are
+-- *not* then unified. The caller may wish to do that. No variables
+-- are looked through here. Similarly, no synonyms are looked through,
+-- as doing so won't expose more ReturnTvs.
+tauTvsForReturnTvs :: TcType -> TcM TcType
+tauTvsForReturnTvs = go emptyTvSubst
+  where
+    go env ty@(TyVarTy tv)
+      | isReturnTyVar tv     = newFlexiTyVarTy (substTy env (tyVarKind tv))
+      | otherwise            = return $ substTy env ty
+    go env (AppTy ty1 ty2)   = AppTy <$> go env ty1 <*> go env ty2
+    go env (TyConApp tc tys) = TyConApp tc <$> mapM (go env) tys
+    go env (FunTy ty1 ty2)   = FunTy <$> go env ty1 <*> go env ty2
+    go env (ForAllTy tv ty)
+      = do { k <- go env (tyVarKind tv)
+           ; let tv'  = setTyVarKind tv k
+                 env' = extendTvSubst env tv (TyVarTy tv')
+           ; ForAllTy tv' <$> go env' ty }
+    go _   ty@(LitTy {})     = return ty
+
 tcInstTyVars :: [TKVar] -> TcM (TvSubst, [TcTyVar])
 -- Instantiate with META type variables
 -- Note that this works for a sequence of kind and type
diff --git a/compiler/typecheck/TcMatches.hs b/compiler/typecheck/TcMatches.hs
index fc3c18a..940679c 100644
--- a/compiler/typecheck/TcMatches.hs
+++ b/compiler/typecheck/TcMatches.hs
@@ -186,17 +186,14 @@ data TcMatchCtxt body   -- c.f. TcStmtCtxt, also in this module
 
 tcMatches ctxt pat_tys rhs_ty group@(MG { mg_alts = matches, mg_origin = origin })
   = ASSERT( not (null matches) )        -- Ensure that rhs_ty is filled in
-    do  { (wrap, rhs_ty') <-
+    do  { rhs_ty' <-
              if isSingletonMatchGroup group
                   -- no need to monomorphise the RHS if there's only one
-             then return (idHsWrapper, rhs_ty)
+             then return rhs_ty
                   -- TODO (RAE): Document this behavior.
-             else do { tau_ty <- newFlexiTyVarTy openTypeKind
-                     ; wrap   <- tcSubTypeDS GenSigCtxt tau_ty rhs_ty
-                     ; tau_ty <- zonkTcType tau_ty
-                         -- seems more efficient to zonk just once
-                     ; return (wrap, tau_ty) }
+             else tauTvsForReturnTvs rhs_ty
         ; matches' <- mapM (tcMatch ctxt pat_tys rhs_ty') matches
+        ; wrap <- tcSubTypeHR rhs_ty' rhs_ty
         ; return (wrap, MG { mg_alts = matches'
                            , mg_arg_tys = pat_tys
                            , mg_res_ty = rhs_ty'



More information about the ghc-commits mailing list