-\begin{code}
-tcStmt :: (RenamedHsExpr -> TcType s -> TcM s (TcExpr s, LIE s)) -- This is tcExpr
- -- The sole, disgusting, reason for this parameter
- -- is to get the effect of polymorphic recursion
- -- ToDo: rm when booting with Haskell 1.3
- -> DoOrListComp
- -> (TcType s -> TcType s) -- Relationship type of pat and rhs in pat <- rhs
- -> (TcStmt s -> Maybe (TcType s) -> thing -> thing)
- -> RenamedStmt
- -> TcM s (thing, LIE s)
- -> TcM s (thing, LIE s)
-
-tcStmt tc_expr do_or_lc m combine stmt@(ReturnStmt exp) do_next
- = ASSERT( case do_or_lc of { DoStmt -> False; ListComp -> True; Guard -> True } )
- tcSetErrCtxt (stmtCtxt do_or_lc stmt) (
- newTyVarTy mkTypeKind `thenNF_Tc` \ exp_ty ->
- tc_expr exp exp_ty `thenTc` \ (exp', exp_lie) ->
- returnTc (ReturnStmt exp', exp_lie, m exp_ty)
- ) `thenTc` \ (stmt', stmt_lie, stmt_ty) ->
- do_next `thenTc` \ (thing', thing_lie) ->
- returnTc (combine stmt' (Just stmt_ty) thing',
- stmt_lie `plusLIE` thing_lie)
-
-tcStmt tc_expr do_or_lc m combine stmt@(GuardStmt exp src_loc) do_next
- = ASSERT( case do_or_lc of { DoStmt -> False; ListComp -> True; Guard -> True } )
- newTyVarTy mkTypeKind `thenNF_Tc` \ exp_ty ->
- tcAddSrcLoc src_loc (
- tcSetErrCtxt (stmtCtxt do_or_lc stmt) (
- tc_expr exp boolTy `thenTc` \ (exp', exp_lie) ->
- returnTc (GuardStmt exp' src_loc, exp_lie)
- )) `thenTc` \ (stmt', stmt_lie) ->
- do_next `thenTc` \ (thing', thing_lie) ->
- returnTc (combine stmt' Nothing thing',
- stmt_lie `plusLIE` thing_lie)
-
-tcStmt tc_expr do_or_lc m combine stmt@(ExprStmt exp src_loc) do_next
- = ASSERT( case do_or_lc of { DoStmt -> True; ListComp -> False; Guard -> False } )
- newTyVarTy mkTypeKind `thenNF_Tc` \ exp_ty ->
- tcAddSrcLoc src_loc (
- tcSetErrCtxt (stmtCtxt do_or_lc stmt) (
- newTyVarTy mkTypeKind `thenNF_Tc` \ tau ->
- let
- -- exp has type (m tau) for some tau (doesn't matter what)
- exp_ty = m tau
- in
- tc_expr exp exp_ty `thenTc` \ (exp', exp_lie) ->
- returnTc (ExprStmt exp' src_loc, exp_lie, exp_ty)
- )) `thenTc` \ (stmt', stmt_lie, stmt_ty) ->
- do_next `thenTc` \ (thing', thing_lie) ->
- returnTc (combine stmt' (Just stmt_ty) thing',
- stmt_lie `plusLIE` thing_lie)
-
-tcStmt tc_expr do_or_lc m combine stmt@(BindStmt pat exp src_loc) do_next
- = newMonoIds (collectPatBinders pat) mkBoxedTypeKind $ \ _ ->
- tcAddSrcLoc src_loc (
- tcSetErrCtxt (stmtCtxt do_or_lc stmt) (
- tcPat pat `thenTc` \ (pat', pat_lie, pat_ty) ->
- tc_expr exp (m pat_ty) `thenTc` \ (exp', exp_lie) ->
-
- -- NB: the environment has been extended with the new binders
- -- which the rhs can't "see", but the renamer should have made
- -- sure that everything is distinct by now, so there's no problem.
- -- Putting the tcExpr before the newMonoIds messes up the nesting
- -- of error contexts, so I didn't bother
-
- returnTc (BindStmt pat' exp' src_loc, pat_lie `plusLIE` exp_lie)
- )) `thenTc` \ (stmt', stmt_lie) ->
- do_next `thenTc` \ (thing', thing_lie) ->
- returnTc (combine stmt' Nothing thing',
- stmt_lie `plusLIE` thing_lie)
-
-tcStmt tc_expr do_or_lc m combine (LetStmt binds) do_next
- = tcBindsAndThen -- No error context, but a binding group is
- combine' -- rather a large thing for an error context anyway
- binds
- do_next
- where
- combine' is_rec binds' thing' = combine (LetStmt (MonoBind binds' [] is_rec)) Nothing thing'
+#ifndef GHCI
+ tc_local_id id th_bind_lvl proc_lvl -- Non-TH case
+ = checkProcLevel id proc_lvl `thenM_`
+ loop (HsVar id) (idType id)
+
+#else /* GHCI and TH is on */
+ tc_local_id id th_bind_lvl proc_lvl -- TH case
+ = checkProcLevel id proc_lvl `thenM_`
+
+ -- Check for cross-stage lifting
+ getStage `thenM` \ use_stage ->
+ case use_stage of
+ Brack use_lvl ps_var lie_var
+ | use_lvl > th_bind_lvl
+ -> -- E.g. \x -> [| h x |]
+ -- We must behave as if the reference to x was
+
+ -- h $(lift x)
+ -- We use 'x' itself as the splice proxy, used by
+ -- the desugarer to stitch it all back together.
+ -- If 'x' occurs many times we may get many identical
+ -- bindings of the same splice proxy, but that doesn't
+ -- matter, although it's a mite untidy.
+ let
+ id_ty = idType id
+ in
+ checkTc (isTauTy id_ty) (polySpliceErr id) `thenM_`
+ -- If x is polymorphic, its occurrence sites might
+ -- have different instantiations, so we can't use plain
+ -- 'x' as the splice proxy name. I don't know how to
+ -- solve this, and it's probably unimportant, so I'm
+ -- just going to flag an error for now
+
+ setLIEVar lie_var (
+ newMethodFromName orig id_ty DsMeta.liftName `thenM` \ lift ->
+ -- Put the 'lift' constraint into the right LIE
+
+ -- Update the pending splices
+ readMutVar ps_var `thenM` \ ps ->
+ writeMutVar ps_var ((name, nlHsApp (nlHsVar lift) (nlHsVar id)) : ps) `thenM_`
+
+ returnM (HsVar id, id_ty))
+
+ other ->
+ checkWellStaged (quotes (ppr id)) th_bind_lvl use_stage `thenM_`
+ loop (HsVar id) (idType id)
+#endif /* GHCI */
+
+ loop (HsVar fun_id) fun_ty
+ | want_method_inst fun_ty
+ = tcInstType VanillaTv fun_ty `thenM` \ (tyvars, theta, tau) ->
+ newMethodWithGivenTy orig fun_id
+ (mkTyVarTys tyvars) theta tau `thenM` \ meth_id ->
+ loop (HsVar meth_id) tau
+
+ loop fun fun_ty
+ | isSigmaTy fun_ty
+ = tcInstCall orig fun_ty `thenM` \ (inst_fn, tau) ->
+ loop (inst_fn <$> fun) tau
+
+ | otherwise
+ = returnM (fun, fun_ty)
+
+ -- Hack Alert (want_method_inst)!
+ -- If f :: (%x :: T) => Int -> Int
+ -- Then if we have two separate calls, (f 3, f 4), we cannot
+ -- make a method constraint that then gets shared, thus:
+ -- let m = f %x in (m 3, m 4)
+ -- because that loses the linearity of the constraint.
+ -- The simplest thing to do is never to construct a method constraint
+ -- in the first place that has a linear implicit parameter in it.
+ want_method_inst fun_ty
+ | opt_NoMethodSharing = False
+ | otherwise = case tcSplitSigmaTy fun_ty of
+ (_,[],_) -> False -- Not overloaded
+ (_,theta,_) -> not (any isLinearPred theta)
+
+
+ -- We treat data constructors differently, because we have to generate
+ -- constraints for their silly theta, which no longer appears in
+ -- the type of dataConWrapId (see note on "stupid context" in DataCon.lhs
+ -- It's dual to TcPat.tcConstructor
+ inst_data_con data_con
+ = tcInstDataCon orig data_con `thenM` \ (ty_args, ex_dicts, arg_tys, result_ty, _) ->
+ extendLIEs ex_dicts `thenM_`
+ getSrcSpanM `thenM` \ loc ->
+ returnM (unLoc (mkHsDictApp (mkHsTyApp (L loc (HsVar (dataConWrapId data_con))) ty_args)
+ (map instToId ex_dicts)),
+ mkFunTys arg_tys result_ty)
+ -- ToDo: nasty loc/unloc stuff here
+
+ orig = OccurrenceOf name