- lift_grhs (GRHS stmts loc) = GRHS (map lift_stmt stmts) loc
-
- lift_stmt (ResultStmt e l) = ResultStmt (co_fn <$> e) l
- lift_stmt stmt = stmt
-
--- glue_on just avoids stupid dross
-glue_on _ EmptyMonoBinds grhss = grhss -- The common case
-glue_on is_rec mbinds (GRHSs grhss binds ty)
- = GRHSs grhss (mkMonoBind mbinds [] is_rec `ThenBinds` binds) ty
-
-
-tcGRHSs :: RenamedMatchContext -> RenamedGRHSs
- -> TcType
- -> TcM TcGRHSs
-
-tcGRHSs ctxt (GRHSs grhss binds _) expected_ty
- = tcBindsAndThen glue_on binds (tc_grhss grhss)
- where
- m_ty = (\ty -> ty, expected_ty)
-
- tc_grhss grhss
- = mappM tc_grhs grhss `thenM` \ grhss' ->
- returnM (GRHSs grhss' EmptyBinds expected_ty)
-
- tc_grhs (GRHS guarded locn)
- = addSrcLoc locn $
- tcStmts (PatGuard ctxt) m_ty guarded `thenM` \ guarded' ->
- returnM (GRHS guarded' locn)
-\end{code}
-
-
-%************************************************************************
-%* *
-\subsection{tcMatchPats}
-%* *
-%************************************************************************
-
-\begin{code}
-tcMatchPats
- :: [RenamedPat] -> TcType
- -> (TcType -> TcM a)
- -> TcM ([TcPat], a, TcDictBinds)
--- Typecheck the patterns, extend the environment to bind the variables,
--- do the thing inside, use any existentially-bound dictionaries to
--- discharge parts of the returning LIE, and deal with pattern type
--- signatures
-
-tcMatchPats pats expected_ty thing_inside
- = -- STEP 1: Bring pattern-signature type variables into scope
- tcAddScopedTyVars (collectSigTysFromPats pats) (
-
- -- STEP 2: Typecheck the patterns themselves, gathering all the stuff
- -- then do the thing inside
- getLIE (tc_match_pats pats expected_ty thing_inside)
-
- ) `thenM` \ ((pats', ex_tvs, ex_ids, ex_lie, result), lie_req) ->
-
- -- STEP 4: Check for existentially bound type variables
- -- Do this *outside* the scope of the tcAddScopedTyVars, else checkSigTyVars
- -- complains that 'a' is captured by the inscope 'a'! (Test (d) in checkSigTyVars.)
- --
- -- I'm a bit concerned that lie_req1 from an 'inner' pattern in the list
- -- might need (via lie_req2) something made available from an 'outer'
- -- pattern. But it's inconvenient to deal with, and I can't find an example
- tcCheckExistentialPat ex_tvs ex_ids ex_lie lie_req expected_ty `thenM` \ ex_binds ->
- -- NB: we *must* pass "expected_ty" not "result_ty" to tcCheckExistentialPat
- -- For example, we must reject this program:
- -- data C = forall a. C (a -> Int)
- -- f (C g) x = g x
- -- Here, result_ty will be simply Int, but expected_ty is (a -> Int).
-
- returnM (pats', result, ex_binds)
-
-tc_match_pats [] expected_ty thing_inside
- = thing_inside expected_ty `thenM` \ answer ->
- returnM ([], emptyBag, [], [], answer)
-
-tc_match_pats (pat:pats) expected_ty thing_inside
- = subFunTy expected_ty $ \ arg_ty rest_ty ->
- -- This is the unique place we call subFunTy
- -- The point is that if expected_y is a "hole", we want
- -- to make arg_ty and rest_ty as "holes" too.
- tcPat tcMonoPatBndr pat arg_ty `thenM` \ (pat', ex_tvs, pat_bndrs, ex_lie) ->
- let
- xve = bagToList pat_bndrs
- ex_ids = [id | (_, id) <- xve]
- -- ex_ids is all the pattern-bound Ids, a superset
- -- of the existential Ids used in checkExistentialPat
- in
- tcExtendLocalValEnv2 xve $
- tc_match_pats pats rest_ty thing_inside `thenM` \ (pats', exs_tvs, exs_ids, exs_lie, answer) ->
- returnM ( pat':pats',
- ex_tvs `unionBags` exs_tvs,
- ex_ids ++ exs_ids,
- ex_lie ++ exs_lie,
- answer
- )
-
-
-tcCheckExistentialPat :: Bag TcTyVar -- Existentially quantified tyvars bound by pattern
- -> [TcId] -- Ids bound by this pattern; used
- -- (a) by bindsInstsOfLocalFuns
- -- (b) to generate helpful error messages
- -> [Inst] -- and context
- -> [Inst] -- Required context
- -> TcType -- and type of the Match; vars in here must not escape
- -> TcM TcDictBinds -- LIE to float out and dict bindings
-tcCheckExistentialPat ex_tvs ex_ids ex_lie lie_req match_ty
- | isEmptyBag ex_tvs && all not_overloaded ex_ids
- -- Short cut for case when there are no existentials
- -- and no polymorphic overloaded variables
- -- e.g. f :: (forall a. Ord a => a -> a) -> Int -> Int
- -- f op x = ....
- -- Here we must discharge op Methods
- = ASSERT( null ex_lie )
- extendLIEs lie_req `thenM_`
- returnM EmptyMonoBinds
-
- | otherwise
- = addErrCtxtM (sigPatCtxt tv_list ex_ids match_ty) $
-
- -- In case there are any polymorpic, overloaded binders in the pattern
- -- (which can happen in the case of rank-2 type signatures, or data constructors
- -- with polymorphic arguments), we must do a bindInstsOfLocalFns here
- getLIE (bindInstsOfLocalFuns lie_req ex_ids) `thenM` \ (inst_binds, lie) ->
-
- -- Deal with overloaded functions bound by the pattern
- tcSimplifyCheck doc tv_list ex_lie lie `thenM` \ dict_binds ->
- checkSigTyVarsWrt (tyVarsOfType match_ty) tv_list `thenM_`
-
- returnM (dict_binds `AndMonoBinds` inst_binds)
+ tc_match ctxt pat_tys rhs_ty match@(Match pats maybe_rhs_sig grhss)
+ = addErrCtxt (matchCtxt (mc_what ctxt) match) $
+ do { (pats', grhss') <- tcPats LamPat pats pat_tys rhs_ty $
+ tc_grhss ctxt maybe_rhs_sig grhss
+ ; returnM (Match pats' Nothing grhss') }
+
+ tc_grhss ctxt Nothing grhss rhs_ty
+ = tcGRHSs ctxt grhss rhs_ty -- No result signature
+
+ tc_grhss ctxt (Just res_sig) grhss rhs_ty
+ = do { (inner_ty, sig_tvs) <- tcPatSig ResSigCtxt res_sig rhs_ty
+ ; tcExtendTyVarEnv2 sig_tvs $
+ tcGRHSs ctxt grhss inner_ty }
+
+-------------
+tcGRHSs :: TcMatchCtxt -> GRHSs Name -> BoxyRhoType -> TcM (GRHSs TcId)
+
+-- Notice that we pass in the full res_ty, so that we get
+-- good inference from simple things like
+-- f = \(x::forall a.a->a) -> <stuff>
+-- We used to force it to be a monotype when there was more than one guard
+-- but we don't need to do that any more
+
+tcGRHSs ctxt (GRHSs grhss binds) res_ty
+ = do { (binds', grhss') <- tcLocalBinds binds $
+ mappM (wrapLocM (tcGRHS ctxt res_ty)) grhss
+
+ ; returnM (GRHSs grhss' binds') }
+
+-------------
+tcGRHS :: TcMatchCtxt -> BoxyRhoType -> GRHS Name -> TcM (GRHS TcId)
+
+tcGRHS ctxt res_ty (GRHS guards rhs)
+ = do { (guards', rhs') <- tcStmts stmt_ctxt tcGuardStmt guards res_ty $
+ mc_body ctxt rhs
+ ; return (GRHS guards' rhs') }