Remove Linear Implicit Parameters, and all their works
[ghc-hetmet.git] / compiler / typecheck / TcExpr.lhs
index 36cda5a..d9e25c3 100644 (file)
@@ -12,7 +12,7 @@ module TcExpr ( tcPolyExpr, tcPolyExprNC,
 #ifdef GHCI    /* Only if bootstrapped */
 import {-# SOURCE #-}  TcSplice( tcSpliceExpr, tcBracket )
 import HsSyn           ( nlHsVar )
-import Id              ( Id )
+import Id              ( Id, idName )
 import Name            ( isExternalName )
 import TcType          ( isTauTy )
 import TcEnv           ( checkWellStaged )
@@ -21,51 +21,62 @@ import qualified DsMeta
 #endif
 
 import HsSyn           ( HsExpr(..), LHsExpr, ArithSeqInfo(..), recBindFields,
-                         HsMatchContext(..), HsRecordBinds, 
-                         mkHsCoerce, mkHsApp, mkHsDictApp, mkHsTyApp )
+                         HsMatchContext(..), HsRecordBinds, mkHsWrap,
+                         mkHsApp, mkLHsWrap )
 import TcHsSyn         ( hsLitType )
 import TcRnMonad
 import TcUnify         ( tcInfer, tcSubExp, tcFunResTy, tcGen, boxyUnify, subFunTys, zapToMonotype, stripBoxyType,
-                         boxySplitListTy, boxySplitTyConApp, wrapFunResCoercion, boxySubMatchType, 
+                         boxySplitListTy, boxySplitTyConApp, wrapFunResCoercion, preSubType,
                          unBox )
 import BasicTypes      ( Arity, isMarkedStrict )
-import Inst            ( newMethodFromName, newIPDict, instToId,
-                         newDicts, newMethodWithGivenTy, tcInstStupidTheta )
+import Inst            ( newMethodFromName, newIPDict, instCall,
+                         newMethodWithGivenTy, instStupidTheta )
 import TcBinds         ( tcLocalBinds )
-import TcEnv           ( tcLookup, tcLookupId, tcLookupDataCon, tcLookupField )
+import TcEnv           ( tcLookup, tcLookupDataCon, tcLookupField )
 import TcArrows                ( tcProc )
-import TcMatches       ( tcMatchesCase, tcMatchLambda, tcDoStmts, TcMatchCtxt(..) )
+import TcMatches       ( tcMatchesCase, tcMatchLambda, tcDoStmts, tcBody,
+                         TcMatchCtxt(..) )
 import TcHsType                ( tcHsSigType, UserTypeCtxt(..) )
-import TcPat           ( tcOverloadedLit, badFieldCon )
-import TcMType         ( tcInstTyVars, newFlexiTyVarTy, newBoxyTyVars, readFilledBox, 
-                         tcInstBoxyTyVar, tcInstTyVar )
-import TcType          ( TcType, TcSigmaType, TcRhoType, 
+import TcPat           ( tcOverloadedLit, addDataConStupidTheta, badFieldCon )
+import TcMType         ( tcInstTyVars, newFlexiTyVarTy, newBoxyTyVars,
+                         readFilledBox, zonkTcTypes )
+import TcType          ( TcType, TcSigmaType, TcRhoType, TvSubst,
                          BoxySigmaType, BoxyRhoType, ThetaType,
-                         mkTyVarTys, mkFunTys, tcMultiSplitSigmaTy, tcSplitFunTysN, 
-                         isSigmaTy, mkFunTy, mkTyConApp, isLinearPred,
-                         exactTyVarsOfType, exactTyVarsOfTypes, mkTyVarTy, 
-                         zipTopTvSubst, zipOpenTvSubst, substTys, substTyVar, lookupTyVar
+                         mkTyVarTys, mkFunTys, 
+                         tcMultiSplitSigmaTy, tcSplitFunTysN,
+                         tcSplitTyConApp_maybe, 
+                         isSigmaTy, mkFunTy, mkTyConApp, 
+                         exactTyVarsOfType, exactTyVarsOfTypes, 
+                         zipTopTvSubst, zipOpenTvSubst, substTys, substTyVar
                        )
-import Kind            ( argTypeKind )
-
-import Id              ( idType, idName, recordSelectorFieldLabel, isRecordSelector, 
-                         isNaughtyRecordSelector, isDataConId_maybe )
-import DataCon         ( DataCon, dataConFieldLabels, dataConStrictMarks, dataConSourceArity,
-                         dataConWrapId, isVanillaDataCon, dataConTyVars, dataConOrigArgTys )
+import {- Kind parts of -} 
+       Type            ( argTypeKind )
+
+import Id              ( idType, recordSelectorFieldLabel,
+                         isRecordSelector, isNaughtyRecordSelector,
+                         isDataConId_maybe )
+import DataCon         ( DataCon, dataConFieldLabels, dataConStrictMarks,
+                         dataConSourceArity, 
+                         dataConWrapId, isVanillaDataCon, dataConUnivTyVars,
+                         dataConOrigArgTys ) 
 import Name            ( Name )
-import TyCon           ( FieldLabel, tyConStupidTheta, tyConDataCons )
+import TyCon           ( FieldLabel, tyConStupidTheta, tyConDataCons,
+                         isEnumerationTyCon ) 
 import Type            ( substTheta, substTy )
 import Var             ( TyVar, tyVarKind )
 import VarSet          ( emptyVarSet, elemVarSet, unionVarSet )
 import TysWiredIn      ( boolTy, parrTyCon, tupleTyCon )
 import PrelNames       ( enumFromName, enumFromThenName, 
                          enumFromToName, enumFromThenToName,
-                         enumFromToPName, enumFromThenToPName, negateName
+                         enumFromToPName, enumFromThenToPName, negateName,
+                         hasKey
                        )
+import PrimOp          ( tagToEnumKey )
+
 import DynFlags
 import StaticFlags     ( opt_NoMethodSharing )
 import HscTypes                ( TyThing(..) )
-import SrcLoc          ( Located(..), unLoc, noLoc, getLoc )
+import SrcLoc          ( Located(..), unLoc )
 import Util
 import ListSetOps      ( assocMaybe )
 import Maybes          ( catMaybes )
@@ -103,7 +114,7 @@ tcPolyExprNC expr res_ty
   = do { (gen_fn, expr') <- tcGen res_ty emptyVarSet (tcPolyExprNC expr)
                -- Note the recursive call to tcPolyExpr, because the
                -- type may have multiple layers of for-alls
-       ; return (L (getLoc expr') (mkHsCoerce gen_fn (unLoc expr'))) }
+       ; return (mkLHsWrap gen_fn expr') }
 
   | otherwise
   = tcMonoExpr expr res_ty
@@ -179,7 +190,7 @@ tcExpr (HsIPVar ip) res_ty
        ; co_fn <- tcSubExp ip_ty res_ty
        ; (ip', inst) <- newIPDict (IPOccOrigin ip) ip ip_ty
        ; extendLIE inst
-       ; return (mkHsCoerce co_fn (HsIPVar ip')) }
+       ; return (mkHsWrap co_fn (HsIPVar ip')) }
 
 tcExpr (HsApp e1 e2) res_ty 
   = go e1 [e2]
@@ -187,19 +198,19 @@ tcExpr (HsApp e1 e2) res_ty
     go :: LHsExpr Name -> [LHsExpr Name] -> TcM (HsExpr TcId)
     go (L _ (HsApp e1 e2)) args = go e1 (e2:args)
     go lfun@(L loc fun) args
-       = do { (fun', args') <- addErrCtxt (callCtxt lfun args) $
+       = do { (fun', args') <- -- addErrCtxt (callCtxt lfun args) $
                                tcApp fun (length args) (tcArgs lfun args) res_ty
             ; return (unLoc (foldl mkHsApp (L loc fun') args')) }
 
 tcExpr (HsLam match) res_ty
   = do { (co_fn, match') <- tcMatchLambda match res_ty
-       ; return (mkHsCoerce co_fn (HsLam match')) }
+       ; return (mkHsWrap co_fn (HsLam match')) }
 
 tcExpr in_expr@(ExprWithTySig expr sig_ty) res_ty
  = do  { sig_tc_ty <- tcHsSigType ExprSigCtxt sig_ty
        ; expr' <- tcPolyExpr expr sig_tc_ty
        ; co_fn <- tcSubExp sig_tc_ty res_ty
-       ; return (mkHsCoerce co_fn (ExprWithTySigOut expr' sig_ty)) }
+       ; return (mkHsWrap co_fn (ExprWithTySigOut expr' sig_ty)) }
 
 tcExpr (HsType ty) res_ty
   = failWithTc (text "Can't handle type argument:" <+> ppr ty)
@@ -245,13 +256,14 @@ tcExpr in_expr@(SectionL arg1 lop@(L loc op)) res_ty
 tcExpr in_expr@(SectionR lop@(L loc op) arg2) res_ty
   = do { (co_fn, (op', arg2')) <- subFunTys doc 1 res_ty $ \ [arg1_ty'] res_ty' ->
                                   tcApp op 2 (tc_args arg1_ty') res_ty'
-       ; return (mkHsCoerce co_fn (SectionR (L loc op') arg2')) }
+       ; return (mkHsWrap co_fn (SectionR (L loc op') arg2')) }
   where
     doc = ptext SLIT("The section") <+> quotes (ppr in_expr)
                <+> ptext SLIT("takes one argument")
     tc_args arg1_ty' [arg1_ty, arg2_ty] 
        = do { boxyUnify arg1_ty' arg1_ty
             ; tcArg lop (arg2, arg2_ty, 2) }
+    tc_args arg1_ty' other = panic "tcExpr SectionR"
 \end{code}
 
 \begin{code}
@@ -278,7 +290,7 @@ tcExpr (HsCase scrut matches) exp_ty
        ; return (HsCase scrut' matches') }
  where
     match_ctxt = MC { mc_what = CaseAlt,
-                     mc_body = tcPolyExpr }
+                     mc_body = tcBody }
 
 tcExpr (HsIf pred b1 b2) res_ty
   = do { pred' <- addErrCtxt (predCtxt pred) $
@@ -436,7 +448,7 @@ tcExpr expr@(RecordUpd record_expr rbinds _ _) res_ty
                -- A constructor is only relevant to this process if
                -- it contains *all* the fields that are being updated
        con1            = head relevant_cons    -- A representative constructor
-       con1_tyvars     = dataConTyVars con1
+       con1_tyvars     = dataConUnivTyVars con1 
        con1_flds       = dataConFieldLabels con1
        con1_arg_tys    = dataConOrigArgTys con1
        common_tyvars   = exactTyVarsOfTypes [ty | (fld,ty) <- con1_flds `zip` con1_arg_tys
@@ -477,17 +489,14 @@ tcExpr expr@(RecordUpd record_expr rbinds _ _) res_ty
        -- dictionaries for the data type context, since we are going to
        -- do pattern matching over the data cons.
        --
-       -- What dictionaries do we need?  
-       -- We just take the context of the first data constructor
-       -- This isn't right, but I just can't bear to union up all the relevant ones
+       -- What dictionaries do we need?  The tyConStupidTheta tells us.
     let
        theta' = substTheta inst_env (tyConStupidTheta tycon)
     in
-    newDicts RecordUpdOrigin theta'    `thenM` \ dicts ->
-    extendLIEs dicts                   `thenM_`
+    instStupidTheta RecordUpdOrigin theta'     `thenM_`
 
        -- Phew!
-    returnM (mkHsCoerce co_fn (RecordUpd record_expr' rbinds' record_ty result_record_ty))
+    returnM (mkHsWrap co_fn (RecordUpd record_expr' rbinds' record_ty result_record_ty))
 \end{code}
 
 
@@ -629,10 +638,11 @@ tcIdApp :: Name                                   -- Function
 -- Then                fres <= bx_(k+1) -> ... -> bx_n -> res_ty
 
 tcIdApp fun_name n_args arg_checker res_ty
-  = do { fun_id <- lookupFun (OccurrenceOf fun_name) fun_name
+  = do { let orig = OccurrenceOf fun_name
+       ; (fun, fun_ty) <- lookupFun orig fun_name
 
        -- Split up the function type
-       ; let (tv_theta_prs, rho) = tcMultiSplitSigmaTy (idType fun_id)
+       ; let (tv_theta_prs, rho) = tcMultiSplitSigmaTy fun_ty
              (fun_arg_tys, fun_res_ty) = tcSplitFunTysN rho n_args
 
              qtvs = concatMap fst tv_theta_prs         -- Quantified tyvars
@@ -648,26 +658,7 @@ tcIdApp fun_name n_args arg_checker res_ty
        ; extra_arg_boxes <- newBoxyTyVars (replicate n_missing_args argTypeKind)
        ; let extra_arg_tys' = mkTyVarTys extra_arg_boxes
              res_ty'        = mkFunTys extra_arg_tys' res_ty
-             subst          = boxySubMatchType arg_qtvs fun_res_ty res_ty'
-                               -- Only bind arg_qtvs, since only they will be
-                               -- *definitely* be filled in by arg_checker
-                               -- E.g.  error :: forall a. String -> a
-                               --       (error "foo") :: bx5
-                               --  Don't make subst [a |-> bx5]
-                               --  because then the result subsumption becomes
-                               --              bx5 ~ bx5
-                               --  and the unifer doesn't expect the 
-                               --  same box on both sides
-             inst_qtv tv | Just boxy_ty <- lookupTyVar subst tv = return boxy_ty
-                         | tv `elemVarSet` tau_qtvs = do { tv' <- tcInstBoxyTyVar tv
-                                                         ; return (mkTyVarTy tv') }
-                         | otherwise                = do { tv' <- tcInstTyVar tv
-                                                         ; return (mkTyVarTy tv') }
-                       -- The 'otherwise' case handles type variables that are
-                       -- mentioned only in the constraints, not in argument or 
-                       -- result types.  We'll make them tau-types
-
-       ; qtys' <- mapM inst_qtv qtvs
+       ; qtys' <- preSubType qtvs tau_qtvs fun_res_ty res_ty'
        ; let arg_subst    = zipOpenTvSubst qtvs qtys'
              fun_arg_tys' = substTys arg_subst fun_arg_tys
 
@@ -675,8 +666,12 @@ tcIdApp fun_name n_args arg_checker res_ty
        -- Doing so will fill arg_qtvs and extra_arg_tys'
        ; args' <- arg_checker (fun_arg_tys' ++ extra_arg_tys')
 
+       -- Strip boxes from the qtvs that have been filled in by the arg checking
+       -- AND any variables that are mentioned in neither arg nor result
+       -- the latter are mentioned only in constraints; stripBoxyType will 
+       -- fill them with a monotype
        ; let strip qtv qty' | qtv `elemVarSet` arg_qtvs = stripBoxyType qty'
-                            | otherwise                 = return qty'
+                            | otherwise                 = return qty'
        ; qtys'' <- zipWithM strip qtvs qtys'
        ; extra_arg_tys'' <- mapM readFilledBox extra_arg_boxes
 
@@ -689,9 +684,9 @@ tcIdApp fun_name n_args arg_checker res_ty
        -- And pack up the results
        -- By applying the coercion just to the *function* we can make
        -- tcFun work nicely for OpApp and Sections too
-       ; fun' <- instFun fun_id qtvs qtys'' tv_theta_prs
+       ; fun' <- instFun orig fun res_subst tv_theta_prs
        ; co_fn' <- wrapFunResCoercion fun_arg_tys' co_fn
-       ; return (mkHsCoerce co_fn' fun', args') }
+       ; return (mkHsWrap co_fn' fun', args') }
 \end{code}
 
 Note [Silly type synonyms in smart-app]
@@ -718,27 +713,23 @@ tcId :: InstOrigin
      -> TcM (HsExpr TcId)
 tcId orig fun_name res_ty
   = do { traceTc (text "tcId" <+> ppr fun_name <+> ppr res_ty)
-       ; fun_id <- lookupFun orig fun_name
+       ; (fun, fun_ty) <- lookupFun orig fun_name
 
        -- Split up the function type
-       ; let (tv_theta_prs, fun_tau) = tcMultiSplitSigmaTy (idType fun_id)
-             qtvs     = concatMap fst tv_theta_prs     -- Quantified tyvars
-             tau_qtvs = exactTyVarsOfType fun_tau      -- Mentiond in the tau part
-             inst_qtv tv | tv `elemVarSet` tau_qtvs = do { tv' <- tcInstBoxyTyVar tv
-                                                         ; return (mkTyVarTy tv') }
-                         | otherwise                = do { tv' <- tcInstTyVar tv
-                                                         ; return (mkTyVarTy tv') }
+       ; let (tv_theta_prs, fun_tau) = tcMultiSplitSigmaTy fun_ty
+             qtvs = concatMap fst tv_theta_prs -- Quantified tyvars
+             tau_qtvs = exactTyVarsOfType fun_tau      -- Mentioned in the tau part
+       ; qtv_tys <- preSubType qtvs tau_qtvs fun_tau res_ty
 
        -- Do the subsumption check wrt the result type
-       ; qtv_tys <- mapM inst_qtv qtvs
-       ; let res_subst   = zipTopTvSubst qtvs qtv_tys
-             fun_tau' = substTy res_subst fun_tau
+       ; let res_subst = zipTopTvSubst qtvs qtv_tys
+             fun_tau'  = substTy res_subst fun_tau
 
        ; co_fn <- tcFunResTy fun_name fun_tau' res_ty
 
        -- And pack up the results
-       ; fun' <- instFun fun_id qtvs qtv_tys tv_theta_prs 
-       ; return (mkHsCoerce co_fn fun') }
+       ; fun' <- instFun orig fun res_subst tv_theta_prs 
+       ; return (mkHsWrap co_fn fun') }
 
 --     Note [Push result type in]
 --
@@ -771,60 +762,43 @@ tcSyntaxOp orig (HsVar op) ty = tcId orig op ty
 tcSyntaxOp orig other     ty = pprPanic "tcSyntaxOp" (ppr other)
 
 ---------------------------
-instFun :: TcId
-       -> [TyVar] -> [TcType]  -- Quantified type variables and 
-                               -- their instantiating types
-       -> [([TyVar], ThetaType)]       -- Stuff to instantiate
+instFun :: InstOrigin
+       -> HsExpr TcId
+       -> TvSubst                -- The instantiating substitution
+       -> [([TyVar], ThetaType)] -- Stuff to instantiate
        -> TcM (HsExpr TcId)    
-instFun fun_id qtvs qtv_tys []
-  = return (HsVar fun_id)      -- Common short cut
 
-instFun fun_id qtvs qtv_tys tv_theta_prs
-  = do         { let subst = zipOpenTvSubst qtvs qtv_tys
-             ty_theta_prs' = map subst_pr tv_theta_prs
-             subst_pr (tvs, theta) = (map (substTyVar subst) tvs, 
-                                      substTheta subst theta)
+instFun orig fun subst []
+  = return fun         -- Common short cut
 
-               -- The ty_theta_prs' is always non-empty
-             ((tys1',theta1') : further_prs') = ty_theta_prs'
-               
-               -- First, chuck in the constraints from 
-               -- the "stupid theta" of a data constructor (sigh)
-       ; case isDataConId_maybe fun_id of
-               Just con -> tcInstStupidTheta con tys1'
-               Nothing  -> return ()
-
-       ; if want_method_inst theta1'
-         then do { meth_id <- newMethodWithGivenTy orig fun_id tys1'
-                       -- See Note [Multiple instantiation]
-                 ; go (HsVar meth_id) further_prs' }
-         else go (HsVar fun_id) ty_theta_prs'
-       }
+instFun orig fun subst tv_theta_prs
+  = do         { let ty_theta_prs' = map subst_pr tv_theta_prs
+
+                -- Make two ad-hoc checks 
+       ; doStupidChecks fun ty_theta_prs'
+
+               -- Now do normal instantiation
+       ; go True fun ty_theta_prs' }
   where
-    orig = OccurrenceOf (idName fun_id)
+    subst_pr (tvs, theta) 
+       = (map (substTyVar subst) tvs, substTheta subst theta)
+
+    go _ fun [] = return fun
 
-    go fun [] = return fun
+    go True (HsVar fun_id) ((tys,theta) : prs)
+       | want_method_inst theta
+       = do { meth_id <- newMethodWithGivenTy orig fun_id tys
+            ; go False (HsVar meth_id) prs }
+               -- Go round with 'False' to prevent further use
+               -- of newMethod: see Note [Multiple instantiation]
 
-    go fun ((tys, theta) : prs)
-       = do { dicts <- newDicts orig theta
-            ; extendLIEs dicts
-            ; let the_app = unLoc $ mkHsDictApp (mkHsTyApp (noLoc fun) tys)
-                                                (map instToId dicts)
-            ; go the_app prs }
+    go _ fun ((tys, theta) : prs)
+       = do { co_fn <- instCall orig tys theta
+            ; go False (HsWrap co_fn fun) prs }
 
-       --      Hack Alert (want_method_inst)!
        -- See Note [No method sharing]
-       -- 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 theta =  not (null theta)                 -- Overloaded
-                          && not (any isLinearPred theta)      -- Not linear
+    want_method_inst theta =  not (null theta) -- Overloaded
                           && not opt_NoMethodSharing
-               -- See Note [No method sharing] below
 \end{code}
 
 Note [Multiple instantiation]
@@ -892,6 +866,56 @@ tcArg fun (arg, ty, arg_no) = addErrCtxt (funAppCtxt fun arg arg_no) $
 \end{code}
 
 
+Note [tagToEnum#]
+~~~~~~~~~~~~~~~~~
+Nasty check to ensure that tagToEnum# is applied to a type that is an
+enumeration TyCon.  Unification may refine the type later, but this
+check won't see that, alas.  It's crude but it works.
+
+Here's are two cases that should fail
+       f :: forall a. a
+       f = tagToEnum# 0        -- Can't do tagToEnum# at a type variable
+
+       g :: Int
+       g = tagToEnum# 0        -- Int is not an enumeration
+
+
+\begin{code}
+doStupidChecks :: HsExpr TcId
+              -> [([TcType], ThetaType)]
+              -> TcM ()
+-- Check two tiresome and ad-hoc cases
+-- (a) the "stupid theta" for a data con; add the constraints
+--     from the "stupid theta" of a data constructor (sigh)
+-- (b) deal with the tagToEnum# problem: see Note [tagToEnum#]
+
+doStupidChecks (HsVar fun_id) ((tys,_):_)
+  | Just con <- isDataConId_maybe fun_id   -- (a)
+  = addDataConStupidTheta con tys
+
+  | fun_id `hasKey` tagToEnumKey           -- (b)
+  = do { tys' <- zonkTcTypes tys
+       ; checkTc (ok tys') (tagToEnumError tys')
+       }
+  where
+    ok []      = False
+    ok (ty:tys) = case tcSplitTyConApp_maybe ty of
+                       Just (tc,_) -> isEnumerationTyCon tc
+                       Nothing     -> False
+
+doStupidChecks fun tv_theta_prs
+  = return () -- The common case
+                                     
+
+tagToEnumError tys
+  = hang (ptext SLIT("Bad call to tagToEnum#") <+> at_type)
+        2 (vcat [ptext SLIT("Specify the type by giving a type signature"),
+                 ptext SLIT("e.g. (tagToEnum# x) :: Bool")])
+  where
+    at_type | null tys = empty -- Probably never happens
+           | otherwise = ptext SLIT("at type") <+> ppr (head tys)
+\end{code}
+
 %************************************************************************
 %*                                                                     *
 \subsection{@tcId@ typchecks an identifier occurrence}
@@ -899,40 +923,47 @@ tcArg fun (arg, ty, arg_no) = addErrCtxt (funAppCtxt fun arg arg_no) $
 %************************************************************************
 
 \begin{code}
-lookupFun :: InstOrigin -> Name -> TcM TcId
+lookupFun :: InstOrigin -> Name -> TcM (HsExpr TcId, TcType)
 lookupFun orig id_name
   = do         { thing <- tcLookup id_name
        ; case thing of
-           AGlobal (ADataCon con) -> return (dataConWrapId con)
+           AGlobal (ADataCon con) -> return (HsVar wrap_id, idType wrap_id)
+                                  where
+                                     wrap_id = dataConWrapId con
 
            AGlobal (AnId id) 
                | isNaughtyRecordSelector id -> failWithTc (naughtyRecordSel id)
-               | otherwise                  -> return id
+               | otherwise                  -> return (HsVar id, idType id)
                -- A global cannot possibly be ill-staged
                -- nor does it need the 'lifting' treatment
 
-#ifndef GHCI
-           ATcId id th_level _ -> return id                    -- Non-TH case
-#else
-           ATcId id th_level _ -> do { use_stage <- getStage   -- TH case
-                                     ; thLocalId orig id_name id th_level use_stage }
-#endif
+           ATcId { tct_id = id, tct_type = ty, tct_co = mb_co, tct_level = lvl }
+               -> do { thLocalId orig id ty lvl
+                     ; case mb_co of
+                         Nothing -> return (HsVar id, ty)      -- Wobbly, or no free vars
+                         Just co -> return (mkHsWrap co (HsVar id), ty) }      
 
            other -> failWithTc (ppr other <+> ptext SLIT("used where a value identifer was expected"))
     }
 
-#ifdef GHCI  /* GHCI and TH is on */
+#ifndef GHCI  /* GHCI and TH is off */
 --------------------------------------
 -- thLocalId : Check for cross-stage lifting
-thLocalId orig id_name id th_bind_lvl (Brack use_lvl ps_var lie_var)
-  | use_lvl > th_bind_lvl
-  = thBrackId orig id_name id ps_var lie_var
-thLocalId orig id_name id th_bind_lvl use_stage
-  = do { checkWellStaged (quotes (ppr id)) th_bind_lvl use_stage
-       ; return id }
+thLocalId orig id id_ty th_bind_lvl
+  = return ()
+
+#else        /* GHCI and TH is on */
+thLocalId orig id id_ty th_bind_lvl 
+  = do { use_stage <- getStage -- TH case
+       ; case use_stage of
+           Brack use_lvl ps_var lie_var | use_lvl > th_bind_lvl
+                 -> thBrackId orig id ps_var lie_var
+           other -> do { checkWellStaged (quotes (ppr id)) th_bind_lvl use_stage
+                       ; return id }
+       }
 
 --------------------------------------
-thBrackId orig id_name id ps_var lie_var
+thBrackId orig id ps_var lie_var
   | isExternalName id_name
   =    -- Top-level identifiers in this module,
        -- (which have External Names)
@@ -979,6 +1010,8 @@ thBrackId orig id_name id ps_var lie_var
        ; writeMutVar ps_var ((id_name, nlHsApp (nlHsVar lift) (nlHsVar id)) : ps)
 
        ; return id } }
+ where
+   id_name = idName id
 #endif /* GHCI */
 \end{code}
 
@@ -1022,7 +1055,7 @@ tcRecordBinds data_con arg_tys rbinds
       | Just field_ty <- assocMaybe flds_w_tys field_lbl
       = addErrCtxt (fieldCtxt field_lbl)       $
        do { rhs'   <- tcPolyExprNC rhs field_ty
-          ; sel_id <- tcLookupId field_lbl
+          ; sel_id <- tcLookupField field_lbl
           ; ASSERT( isRecordSelector sel_id )
             return (Just (L loc sel_id, rhs')) }
       | otherwise