Skip to content

Commit

Permalink
Add type "holes", enabled by -XTypeHoles, Trac #5910
Browse files Browse the repository at this point in the history
This single commit combines a lot of work done by
Thijs Alkemade <thijsalkemade@gmail.com>, plus a slew
of subsequent refactoring by Simon PJ.

The basic idea is
* Add a new expression form "_", a hole, standing for a not-yet-written expression
* Give a useful error message that
   (a) gives the type of the hole
   (b) gives the types of some enclosing value bindings that
       mention the hole

Driven by this goal I did a LOT of refactoring in TcErrors, which in turn
allows us to report enclosing value bindings for other errors, not just
holes.  (Thijs rightly did not attempt this!)

The major data type change is a new form of constraint
  data Ct = ...
    	  | CHoleCan {
    	      cc_ev       :: CtEvidence,
    	      cc_hole_ty  :: TcTauType,
    	      cc_depth    :: SubGoalDepth }

I'm still in two minds about whether this is the best plan. Another
possibility would be to have a predicate type for holes, somthing like
   class Hole a where
     holeValue :: a

It works the way it is, but there are some annoying special cases for
CHoleCan (just grep for "CHoleCan").
  • Loading branch information
Simon Peyton Jones committed Sep 17, 2012
1 parent b0db930 commit 8a9a7a8
Show file tree
Hide file tree
Showing 20 changed files with 565 additions and 401 deletions.
1 change: 1 addition & 0 deletions compiler/deSugar/Coverage.lhs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -576,6 +576,7 @@ addTickHsExpr (HsWrap w e) =
(addTickHsExpr e) -- explicitly no tick on inside (addTickHsExpr e) -- explicitly no tick on inside
addTickHsExpr e@(HsType _) = return e addTickHsExpr e@(HsType _) = return e
addTickHsExpr HsHole = panic "addTickHsExpr.HsHole"
-- Others dhould never happen in expression content. -- Others dhould never happen in expression content.
addTickHsExpr e = pprPanic "addTickHsExpr" (ppr e) addTickHsExpr e = pprPanic "addTickHsExpr" (ppr e)
Expand Down
2 changes: 2 additions & 0 deletions compiler/deSugar/DsExpr.lhs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ dsExpr (HsLamCase arg matches@(MatchGroup _ rhs_ty))
dsExpr (HsApp fun arg) dsExpr (HsApp fun arg)
= mkCoreAppDs <$> dsLExpr fun <*> dsLExpr arg = mkCoreAppDs <$> dsLExpr fun <*> dsLExpr arg
dsExpr HsHole = panic "dsExpr: HsHole"
\end{code} \end{code}


Note [Desugaring vars] Note [Desugaring vars]
Expand Down
3 changes: 3 additions & 0 deletions compiler/hsSyn/HsExpr.lhs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ data HsExpr id
| HsWrap HsWrapper -- TRANSLATION | HsWrap HsWrapper -- TRANSLATION
(HsExpr id) (HsExpr id)
| HsHole
deriving (Data, Typeable) deriving (Data, Typeable)
-- HsTupArg is used for tuple sections -- HsTupArg is used for tuple sections
Expand Down Expand Up @@ -559,6 +560,8 @@ ppr_expr (HsArrForm (L _ (HsVar v)) (Just _) [arg1, arg2])
ppr_expr (HsArrForm op _ args) ppr_expr (HsArrForm op _ args)
= hang (ptext (sLit "(|") <> ppr_lexpr op) = hang (ptext (sLit "(|") <> ppr_lexpr op)
4 (sep (map (pprCmdArg.unLoc) args) <> ptext (sLit "|)")) 4 (sep (map (pprCmdArg.unLoc) args) <> ptext (sLit "|)"))
ppr_expr HsHole
= ptext $ sLit "_"
pprCmdArg :: OutputableBndr id => HsCmdTop id -> SDoc pprCmdArg :: OutputableBndr id => HsCmdTop id -> SDoc
pprCmdArg (HsCmdTop cmd@(L _ (HsArrForm _ Nothing [])) _ _ _) pprCmdArg (HsCmdTop cmd@(L _ (HsArrForm _ Nothing [])) _ _ _)
Expand Down
4 changes: 3 additions & 1 deletion compiler/main/DynFlags.hs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ data ExtensionFlag
| Opt_TraditionalRecordSyntax | Opt_TraditionalRecordSyntax
| Opt_LambdaCase | Opt_LambdaCase
| Opt_MultiWayIf | Opt_MultiWayIf
| Opt_TypeHoles
deriving (Eq, Enum, Show) deriving (Eq, Enum, Show)


-- | Contains not only a collection of 'DynFlag's but also a plethora of -- | Contains not only a collection of 'DynFlag's but also a plethora of
Expand Down Expand Up @@ -2449,7 +2450,8 @@ xFlags = [
( "OverlappingInstances", Opt_OverlappingInstances, nop ), ( "OverlappingInstances", Opt_OverlappingInstances, nop ),
( "UndecidableInstances", Opt_UndecidableInstances, nop ), ( "UndecidableInstances", Opt_UndecidableInstances, nop ),
( "IncoherentInstances", Opt_IncoherentInstances, nop ), ( "IncoherentInstances", Opt_IncoherentInstances, nop ),
( "PackageImports", Opt_PackageImports, nop ) ( "PackageImports", Opt_PackageImports, nop ),
( "TypeHoles", Opt_TypeHoles, nop )
] ]


defaultFlags :: Platform -> [DynFlag] defaultFlags :: Platform -> [DynFlag]
Expand Down
11 changes: 9 additions & 2 deletions compiler/rename/RnExpr.lhs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import HsSyn
import TcRnMonad import TcRnMonad
import TcEnv ( thRnBrack ) import TcEnv ( thRnBrack )
import RnEnv import RnEnv
import RnTypes import RnTypes
import RnPat import RnPat
import DynFlags import DynFlags
import BasicTypes ( FixityDirection(..) ) import BasicTypes ( FixityDirection(..) )
Expand Down Expand Up @@ -299,14 +299,21 @@ rnExpr (ArithSeq _ seq)
rnExpr (PArrSeq _ seq) rnExpr (PArrSeq _ seq)
= rnArithSeq seq `thenM` \ (new_seq, fvs) -> = rnArithSeq seq `thenM` \ (new_seq, fvs) ->
return (PArrSeq noPostTcExpr new_seq, fvs) return (PArrSeq noPostTcExpr new_seq, fvs)
rnExpr HsHole
= return (HsHole, emptyFVs)
\end{code} \end{code}


These three are pattern syntax appearing in expressions. These three are pattern syntax appearing in expressions.
Since all the symbols are reservedops we can simply reject them. Since all the symbols are reservedops we can simply reject them.
We return a (bogus) EWildPat in each case. We return a (bogus) EWildPat in each case.


\begin{code} \begin{code}
rnExpr e@EWildPat = patSynErr e rnExpr e@EWildPat = do { holes <- xoptM Opt_TypeHoles
; if holes
then return (HsHole, emptyFVs)
else patSynErr e
}
rnExpr e@(EAsPat {}) = patSynErr e rnExpr e@(EAsPat {}) = patSynErr e
rnExpr e@(EViewPat {}) = patSynErr e rnExpr e@(EViewPat {}) = patSynErr e
rnExpr e@(ELazyPat {}) = patSynErr e rnExpr e@(ELazyPat {}) = patSynErr e
Expand Down
31 changes: 17 additions & 14 deletions compiler/typecheck/Inst.lhs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -356,14 +356,14 @@ tcSyntaxName orig ty (std_nm, user_nm_expr) = do
syntaxNameCtxt :: HsExpr Name -> CtOrigin -> Type -> TidyEnv syntaxNameCtxt :: HsExpr Name -> CtOrigin -> Type -> TidyEnv
-> TcRn (TidyEnv, SDoc) -> TcRn (TidyEnv, SDoc)
syntaxNameCtxt name orig ty tidy_env = do syntaxNameCtxt name orig ty tidy_env
inst_loc <- getCtLoc orig = do { inst_loc <- getCtLoc orig
let ; let msg = vcat [ ptext (sLit "When checking that") <+> quotes (ppr name)
msg = vcat [ptext (sLit "When checking that") <+> quotes (ppr name) <+> <+> ptext (sLit "(needed by a syntactic construct)")
ptext (sLit "(needed by a syntactic construct)"), , nest 2 (ptext (sLit "has the required type:")
nest 2 (ptext (sLit "has the required type:") <+> ppr (tidyType tidy_env ty)), <+> ppr (tidyType tidy_env ty))
nest 2 (pprArisingAt inst_loc)] , nest 2 (pprArisingAt inst_loc) ]
return (tidy_env, msg) ; return (tidy_env, msg) }
\end{code} \end{code}
Expand Down Expand Up @@ -523,6 +523,7 @@ tyVarsOfCt (CTyEqCan { cc_tyvar = tv, cc_rhs = xi }) = extendVarSet (tyVarsOf
tyVarsOfCt (CFunEqCan { cc_tyargs = tys, cc_rhs = xi }) = tyVarsOfTypes (xi:tys) tyVarsOfCt (CFunEqCan { cc_tyargs = tys, cc_rhs = xi }) = tyVarsOfTypes (xi:tys)
tyVarsOfCt (CDictCan { cc_tyargs = tys }) = tyVarsOfTypes tys tyVarsOfCt (CDictCan { cc_tyargs = tys }) = tyVarsOfTypes tys
tyVarsOfCt (CIrredEvCan { cc_ty = ty }) = tyVarsOfType ty tyVarsOfCt (CIrredEvCan { cc_ty = ty }) = tyVarsOfType ty
tyVarsOfCt (CHoleCan { cc_hole_ty = ty }) = tyVarsOfType ty
tyVarsOfCt (CNonCanonical { cc_ev = fl }) = tyVarsOfType (ctEvPred fl) tyVarsOfCt (CNonCanonical { cc_ev = fl }) = tyVarsOfType (ctEvPred fl)
tyVarsOfCts :: Cts -> TcTyVarSet tyVarsOfCts :: Cts -> TcTyVarSet
Expand Down Expand Up @@ -551,8 +552,10 @@ tidyCt :: TidyEnv -> Ct -> Ct
-- Used only in error reporting -- Used only in error reporting
-- Also converts it to non-canonical -- Also converts it to non-canonical
tidyCt env ct tidyCt env ct
= CNonCanonical { cc_ev = tidy_flavor env (cc_ev ct) = case ct of
, cc_depth = cc_depth ct } CHoleCan {} -> ct { cc_ev = tidy_flavor env (cc_ev ct) }
_ -> CNonCanonical { cc_ev = tidy_flavor env (cc_ev ct)
, cc_depth = cc_depth ct }
where where
tidy_flavor :: TidyEnv -> CtEvidence -> CtEvidence tidy_flavor :: TidyEnv -> CtEvidence -> CtEvidence
-- NB: we do not tidy the ctev_evtm/var field because we don't -- NB: we do not tidy the ctev_evtm/var field because we don't
Expand All @@ -569,8 +572,8 @@ tidyEvVar :: TidyEnv -> EvVar -> EvVar
tidyEvVar env var = setVarType var (tidyType env (varType var)) tidyEvVar env var = setVarType var (tidyType env (varType var))
tidyGivenLoc :: TidyEnv -> GivenLoc -> GivenLoc tidyGivenLoc :: TidyEnv -> GivenLoc -> GivenLoc
tidyGivenLoc env (CtLoc skol span ctxt) tidyGivenLoc env (CtLoc skol lcl)
= CtLoc (tidySkolemInfo env skol) span ctxt = CtLoc (tidySkolemInfo env skol) lcl
tidySkolemInfo :: TidyEnv -> SkolemInfo -> SkolemInfo tidySkolemInfo :: TidyEnv -> SkolemInfo -> SkolemInfo
tidySkolemInfo env (SigSkol cx ty) = SigSkol cx (tidyType env ty) tidySkolemInfo env (SigSkol cx ty) = SigSkol cx (tidyType env ty)
Expand Down Expand Up @@ -635,8 +638,8 @@ substFlavor subst ctev@(CtDerived { ctev_pred = pty })
= ctev { ctev_pred = substTy subst pty } = ctev { ctev_pred = substTy subst pty }
substGivenLoc :: TvSubst -> GivenLoc -> GivenLoc substGivenLoc :: TvSubst -> GivenLoc -> GivenLoc
substGivenLoc subst (CtLoc skol span ctxt) substGivenLoc subst (CtLoc skol lcl)
= CtLoc (substSkolemInfo subst skol) span ctxt = CtLoc (substSkolemInfo subst skol) lcl
substSkolemInfo :: TvSubst -> SkolemInfo -> SkolemInfo substSkolemInfo :: TvSubst -> SkolemInfo -> SkolemInfo
substSkolemInfo subst (SigSkol cx ty) = SigSkol cx (substTy subst ty) substSkolemInfo subst (SigSkol cx ty) = SigSkol cx (substTy subst ty)
Expand Down
90 changes: 47 additions & 43 deletions compiler/typecheck/TcBinds.lhs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@


\begin{code} \begin{code}
module TcBinds ( tcLocalBinds, tcTopBinds, tcRecSelBinds, module TcBinds ( tcLocalBinds, tcTopBinds, tcRecSelBinds,
tcHsBootSigs, tcPolyBinds, tcPolyCheck, tcHsBootSigs, tcPolyCheck,
PragFun, tcSpecPrags, tcVectDecls, mkPragFun, PragFun, tcSpecPrags, tcVectDecls, mkPragFun,
TcSigInfo(..), TcSigFun, TcSigInfo(..), TcSigFun,
instTcTySig, instTcTySigFromId, instTcTySig, instTcTySigFromId,
Expand Down Expand Up @@ -274,7 +274,8 @@ tcValBinds top_lvl binds sigs thing_inside
-- Extend the envt right away with all -- Extend the envt right away with all
-- the Ids declared with type signatures -- the Ids declared with type signatures
; (binds', thing) <- tcExtendIdEnv poly_ids $ -- Use tcExtendIdEnv2 to avoid extending the TcIdBinder stack
; (binds', thing) <- tcExtendIdEnv2 [(idName id, id) | id <- poly_ids] $
tcBindGroups top_lvl sig_fn prag_fn tcBindGroups top_lvl sig_fn prag_fn
binds thing_inside binds thing_inside
Expand Down Expand Up @@ -336,7 +337,8 @@ tc_group top_lvl sig_fn prag_fn (Recursive, binds) thing_inside
go :: [SCC (LHsBind Name)] -> TcM (LHsBinds TcId, [TcId], thing) go :: [SCC (LHsBind Name)] -> TcM (LHsBinds TcId, [TcId], thing)
go (scc:sccs) = do { (binds1, ids1, closed) <- tc_scc scc go (scc:sccs) = do { (binds1, ids1, closed) <- tc_scc scc
; (binds2, ids2, thing) <- tcExtendLetEnv closed ids1 $ go sccs ; (binds2, ids2, thing) <- tcExtendLetEnv closed ids1 $
go sccs
; return (binds1 `unionBags` binds2, ids1 ++ ids2, thing) } ; return (binds1 `unionBags` binds2, ids1 ++ ids2, thing) }
go [] = do { thing <- thing_inside; return (emptyBag, [], thing) } go [] = do { thing <- thing_inside; return (emptyBag, [], thing) }
Expand Down Expand Up @@ -397,20 +399,15 @@ tcPolyBinds top_lvl sig_fn prag_fn rec_group rec_tc bind_list
{ traceTc "------------------------------------------------" empty { traceTc "------------------------------------------------" empty
; traceTc "Bindings for {" (ppr binder_names) ; traceTc "Bindings for {" (ppr binder_names)
-- -- Instantiate the polytypes of any binders that have signatures
-- -- (as determined by sig_fn), returning a TcSigInfo for each
-- ; tc_sig_fn <- tcInstSigs sig_fn binder_names
; dflags <- getDynFlags ; dflags <- getDynFlags
; type_env <- getLclTypeEnv ; type_env <- getLclTypeEnv
; let plan = decideGeneralisationPlan dflags type_env ; let plan = decideGeneralisationPlan dflags type_env
binder_names bind_list sig_fn binder_names bind_list sig_fn
; traceTc "Generalisation plan" (ppr plan) ; traceTc "Generalisation plan" (ppr plan)
; result@(tc_binds, poly_ids, _) <- case plan of ; result@(tc_binds, poly_ids, _) <- case plan of
NoGen -> tcPolyNoGen sig_fn prag_fn rec_tc bind_list NoGen -> tcPolyNoGen top_lvl rec_tc prag_fn sig_fn bind_list
InferGen mn cl -> tcPolyInfer mn cl sig_fn prag_fn rec_tc bind_list InferGen mn cl -> tcPolyInfer top_lvl rec_tc prag_fn sig_fn mn cl bind_list
CheckGen sig -> tcPolyCheck sig prag_fn rec_tc bind_list CheckGen sig -> tcPolyCheck top_lvl rec_tc prag_fn sig bind_list
-- Check whether strict bindings are ok -- Check whether strict bindings are ok
-- These must be non-recursive etc, and are not generalised -- These must be non-recursive etc, and are not generalised
Expand All @@ -429,17 +426,18 @@ tcPolyBinds top_lvl sig_fn prag_fn rec_group rec_tc bind_list
-- span that includes them all -- span that includes them all
------------------ ------------------
tcPolyNoGen tcPolyNoGen -- No generalisation whatsoever
:: TcSigFun -> PragFun :: TopLevelFlag
-> RecFlag -- Whether it's recursive after breaking -> RecFlag -- Whether it's recursive after breaking
-- dependencies based on type signatures -- dependencies based on type signatures
-> PragFun -> TcSigFun
-> [LHsBind Name] -> [LHsBind Name]
-> TcM (LHsBinds TcId, [TcId], TopLevelFlag) -> TcM (LHsBinds TcId, [TcId], TopLevelFlag)
-- No generalisation whatsoever
tcPolyNoGen tc_sig_fn prag_fn rec_tc bind_list tcPolyNoGen top_lvl rec_tc prag_fn tc_sig_fn bind_list
= do { (binds', mono_infos) <- tcMonoBinds tc_sig_fn (LetGblBndr prag_fn) = do { (binds', mono_infos) <- tcMonoBinds top_lvl rec_tc tc_sig_fn
rec_tc bind_list (LetGblBndr prag_fn)
bind_list
; mono_ids' <- mapM tc_mono_info mono_infos ; mono_ids' <- mapM tc_mono_info mono_infos
; return (binds', mono_ids', NotTopLevel) } ; return (binds', mono_ids', NotTopLevel) }
where where
Expand All @@ -455,17 +453,19 @@ tcPolyNoGen tc_sig_fn prag_fn rec_tc bind_list
-- So we can safely ignore _specs -- So we can safely ignore _specs
------------------ ------------------
tcPolyCheck :: TcSigInfo -> PragFun tcPolyCheck :: TopLevelFlag
-> RecFlag -- Whether it's recursive after breaking -> RecFlag -- Whether it's recursive after breaking
-- dependencies based on type signatures -- dependencies based on type signatures
-> PragFun -> TcSigInfo
-> [LHsBind Name] -> [LHsBind Name]
-> TcM (LHsBinds TcId, [TcId], TopLevelFlag) -> TcM (LHsBinds TcId, [TcId], TopLevelFlag)
-- There is just one binding, -- There is just one binding,
-- it binds a single variable, -- it binds a single variable,
-- it has a signature, -- it has a signature,
tcPolyCheck sig@(TcSigInfo { sig_id = poly_id, sig_tvs = tvs_w_scoped tcPolyCheck top_lvl rec_tc prag_fn
sig@(TcSigInfo { sig_id = poly_id, sig_tvs = tvs_w_scoped
, sig_theta = theta, sig_tau = tau, sig_loc = loc }) , sig_theta = theta, sig_tau = tau, sig_loc = loc })
prag_fn rec_tc bind_list bind_list
= do { ev_vars <- newEvVars theta = do { ev_vars <- newEvVars theta
; let skol_info = SigSkol (FunSigCtxt (idName poly_id)) (mkPhiTy theta tau) ; let skol_info = SigSkol (FunSigCtxt (idName poly_id)) (mkPhiTy theta tau)
prag_sigs = prag_fn (idName poly_id) prag_sigs = prag_fn (idName poly_id)
Expand All @@ -474,7 +474,7 @@ tcPolyCheck sig@(TcSigInfo { sig_id = poly_id, sig_tvs = tvs_w_scoped
<- setSrcSpan loc $ <- setSrcSpan loc $
checkConstraints skol_info tvs ev_vars $ checkConstraints skol_info tvs ev_vars $
tcExtendTyVarEnv2 [(n,tv) | (Just n, tv) <- tvs_w_scoped] $ tcExtendTyVarEnv2 [(n,tv) | (Just n, tv) <- tvs_w_scoped] $
tcMonoBinds (\_ -> Just sig) LetLclBndr rec_tc bind_list tcMonoBinds top_lvl rec_tc (\_ -> Just sig) LetLclBndr bind_list
; spec_prags <- tcSpecPrags poly_id prag_sigs ; spec_prags <- tcSpecPrags poly_id prag_sigs
; poly_id <- addInlinePrags poly_id prag_sigs ; poly_id <- addInlinePrags poly_id prag_sigs
Expand All @@ -494,17 +494,18 @@ tcPolyCheck sig@(TcSigInfo { sig_id = poly_id, sig_tvs = tvs_w_scoped
------------------ ------------------
tcPolyInfer tcPolyInfer
:: Bool -- True <=> apply the monomorphism restriction :: TopLevelFlag
-> Bool -- True <=> free vars have closed types
-> TcSigFun -> PragFun
-> RecFlag -- Whether it's recursive after breaking -> RecFlag -- Whether it's recursive after breaking
-- dependencies based on type signatures -- dependencies based on type signatures
-> PragFun -> TcSigFun
-> Bool -- True <=> apply the monomorphism restriction
-> Bool -- True <=> free vars have closed types
-> [LHsBind Name] -> [LHsBind Name]
-> TcM (LHsBinds TcId, [TcId], TopLevelFlag) -> TcM (LHsBinds TcId, [TcId], TopLevelFlag)
tcPolyInfer mono closed tc_sig_fn prag_fn rec_tc bind_list tcPolyInfer top_lvl rec_tc prag_fn tc_sig_fn mono closed bind_list
= do { ((binds', mono_infos), wanted) = do { ((binds', mono_infos), wanted)
<- captureConstraints $ <- captureConstraints $
tcMonoBinds tc_sig_fn LetLclBndr rec_tc bind_list tcMonoBinds top_lvl rec_tc tc_sig_fn LetLclBndr bind_list
; let name_taus = [(name, idType mono_id) | (name, _, mono_id) <- mono_infos] ; let name_taus = [(name, idType mono_id) | (name, _, mono_id) <- mono_infos]
; (qtvs, givens, mr_bites, ev_binds) <- ; (qtvs, givens, mr_bites, ev_binds) <-
Expand All @@ -524,10 +525,8 @@ tcPolyInfer mono closed tc_sig_fn prag_fn rec_tc bind_list
; traceTc "Binding:" (ppr final_closed $$ ; traceTc "Binding:" (ppr final_closed $$
ppr (poly_ids `zip` map idType poly_ids)) ppr (poly_ids `zip` map idType poly_ids))
; return (unitBag abs_bind, poly_ids, final_closed) ; return (unitBag abs_bind, poly_ids, final_closed) }
-- poly_ids are guaranteed zonked by mkExport -- poly_ids are guaranteed zonked by mkExport
}
-------------- --------------
mkExport :: PragFun mkExport :: PragFun
Expand Down Expand Up @@ -937,14 +936,15 @@ should not typecheck because
will not typecheck. will not typecheck.


\begin{code} \begin{code}
tcMonoBinds :: TcSigFun -> LetBndrSpec tcMonoBinds :: TopLevelFlag
-> RecFlag -- Whether the binding is recursive for typechecking purposes -> RecFlag -- Whether the binding is recursive for typechecking purposes
-- i.e. the binders are mentioned in their RHSs, and -- i.e. the binders are mentioned in their RHSs, and
-- we are not rescued by a type signature -- we are not rescued by a type signature
-> TcSigFun -> LetBndrSpec
-> [LHsBind Name] -> [LHsBind Name]
-> TcM (LHsBinds TcId, [MonoBindInfo]) -> TcM (LHsBinds TcId, [MonoBindInfo])
tcMonoBinds sig_fn no_gen is_rec tcMonoBinds top_lvl is_rec sig_fn no_gen
[ L b_loc (FunBind { fun_id = L nm_loc name, fun_infix = inf, [ L b_loc (FunBind { fun_id = L nm_loc name, fun_infix = inf,
fun_matches = matches, bind_fvs = fvs })] fun_matches = matches, bind_fvs = fvs })]
-- Single function binding, -- Single function binding,
Expand All @@ -956,15 +956,17 @@ tcMonoBinds sig_fn no_gen is_rec
-- e.g. f = \(x::forall a. a->a) -> <body> -- e.g. f = \(x::forall a. a->a) -> <body>
-- We want to infer a higher-rank type for f -- We want to infer a higher-rank type for f
setSrcSpan b_loc $ setSrcSpan b_loc $
do { ((co_fn, matches'), rhs_ty) <- tcInfer (tcMatchesFun name inf matches) do { rhs_ty <- newFlexiTyVarTy openTypeKind
; mono_id <- newNoSigLetBndr no_gen name rhs_ty ; mono_id <- newNoSigLetBndr no_gen name rhs_ty
; (co_fn, matches') <- tcExtendIdBndrs [TcIdBndr mono_id top_lvl] $
tcMatchesFun name inf matches rhs_ty
; return (unitBag (L b_loc (FunBind { fun_id = L nm_loc mono_id, fun_infix = inf, ; return (unitBag (L b_loc (FunBind { fun_id = L nm_loc mono_id, fun_infix = inf,
fun_matches = matches', bind_fvs = fvs, fun_matches = matches', bind_fvs = fvs,
fun_co_fn = co_fn, fun_tick = Nothing })), fun_co_fn = co_fn, fun_tick = Nothing })),
[(name, Nothing, mono_id)]) } [(name, Nothing, mono_id)]) }
tcMonoBinds sig_fn no_gen _ binds tcMonoBinds top_lvl _ sig_fn no_gen binds
= do { tc_binds <- mapM (wrapLocM (tcLhs sig_fn no_gen)) binds = do { tc_binds <- mapM (wrapLocM (tcLhs sig_fn no_gen)) binds
-- Bring the monomorphic Ids, into scope for the RHSs -- Bring the monomorphic Ids, into scope for the RHSs
Expand All @@ -973,10 +975,10 @@ tcMonoBinds sig_fn no_gen _ binds
-- A monomorphic binding for each term variable that lacks -- A monomorphic binding for each term variable that lacks
-- a type sig. (Ones with a sig are already in scope.) -- a type sig. (Ones with a sig are already in scope.)
; binds' <- tcExtendIdEnv2 rhs_id_env $ do ; traceTc "tcMonoBinds" $ vcat [ ppr n <+> ppr id <+> ppr (idType id)
traceTc "tcMonoBinds" $ vcat [ ppr n <+> ppr id <+> ppr (idType id) | (n,id) <- rhs_id_env]
| (n,id) <- rhs_id_env] ; binds' <- tcExtendIdEnv2 rhs_id_env $
mapM (wrapLocM tcRhs) tc_binds mapM (wrapLocM (tcRhs top_lvl)) tc_binds
; return (listToBag binds', mono_info) } ; return (listToBag binds', mono_info) }
------------------------ ------------------------
Expand Down Expand Up @@ -1032,22 +1034,24 @@ tcLhs _ _ other_bind = pprPanic "tcLhs" (ppr other_bind)
-- AbsBind, VarBind impossible -- AbsBind, VarBind impossible
------------------- -------------------
tcRhs :: TcMonoBind -> TcM (HsBind TcId) tcRhs :: TopLevelFlag -> TcMonoBind -> TcM (HsBind TcId)
-- When we are doing pattern bindings, or multiple function bindings at a time -- When we are doing pattern bindings, or multiple function bindings at a time
-- we *don't* bring any scoped type variables into scope -- we *don't* bring any scoped type variables into scope
-- Wny not? They are not completely rigid. -- Wny not? They are not completely rigid.
-- That's why we have the special case for a single FunBind in tcMonoBinds -- That's why we have the special case for a single FunBind in tcMonoBinds
tcRhs (TcFunBind (_,_,mono_id) loc inf matches) tcRhs top_lvl (TcFunBind (_,_,mono_id) loc inf matches)
= do { traceTc "tcRhs: fun bind" (ppr mono_id $$ ppr (idType mono_id)) = tcExtendIdBndrs [TcIdBndr mono_id top_lvl] $
do { traceTc "tcRhs: fun bind" (ppr mono_id $$ ppr (idType mono_id))
; (co_fn, matches') <- tcMatchesFun (idName mono_id) inf ; (co_fn, matches') <- tcMatchesFun (idName mono_id) inf
matches (idType mono_id) matches (idType mono_id)
; return (FunBind { fun_id = L loc mono_id, fun_infix = inf ; return (FunBind { fun_id = L loc mono_id, fun_infix = inf
, fun_matches = matches' , fun_matches = matches'
, fun_co_fn = co_fn , fun_co_fn = co_fn
, bind_fvs = placeHolderNames, fun_tick = Nothing }) } , bind_fvs = placeHolderNames, fun_tick = Nothing }) }
tcRhs (TcPatBind _ pat' grhss pat_ty) tcRhs top_lvl (TcPatBind infos pat' grhss pat_ty)
= do { traceTc "tcRhs: pat bind" (ppr pat' $$ ppr pat_ty) = tcExtendIdBndrs [ TcIdBndr mono_id top_lvl | (_,_,mono_id) <- infos ] $
do { traceTc "tcRhs: pat bind" (ppr pat' $$ ppr pat_ty)
; grhss' <- addErrCtxt (patMonoBindsCtxt pat' grhss) $ ; grhss' <- addErrCtxt (patMonoBindsCtxt pat' grhss) $
tcGRHSsPat grhss pat_ty tcGRHSsPat grhss pat_ty
; return (PatBind { pat_lhs = pat', pat_rhs = grhss', pat_rhs_ty = pat_ty ; return (PatBind { pat_lhs = pat', pat_rhs = grhss', pat_rhs_ty = pat_ty
Expand Down
Loading

0 comments on commit 8a9a7a8

Please sign in to comment.