import TcPat
import TcMType
import TcType
+import TcIface ( checkWiredInTyCon )
import Id
import DataCon
import Name
= do { tvs <- newBoxyTyVars [argTypeKind | e <- exprs]
; let tup_tc = tupleTyCon boxity (length exprs)
tup_res_ty = mkTyConApp tup_tc (mkTyVarTys tvs)
- ; arg_tys <- preSubType tvs (mkVarSet tvs) tup_res_ty res_ty
- ; exprs' <- tcPolyExprs exprs arg_tys
+ ; checkWiredInTyCon tup_tc -- Ensure instances are available
+ ; arg_tys <- preSubType tvs (mkVarSet tvs) tup_res_ty res_ty
+ ; exprs' <- tcPolyExprs exprs arg_tys
; arg_tys' <- mapM refineBox arg_tys
- ; co_fn <- tcFunResTy (tyConName tup_tc) (mkTyConApp tup_tc arg_tys') res_ty
+ ; co_fn <- tcFunResTy (tyConName tup_tc) (mkTyConApp tup_tc arg_tys') res_ty
; return (mkHsWrap co_fn (ExplicitTuple exprs' boxity)) }
tcExpr (HsProc pat cmd) res_ty
-- don't know how to do the update otherwise.
-tcExpr expr@(RecordUpd record_expr hrbinds@(HsRecordBinds rbinds) _ _ _) res_ty
+tcExpr expr@(RecordUpd record_expr rbinds _ _ _) res_ty
= -- STEP 0
-- Check that the field names are really field names
- ASSERT( notNull rbinds )
let
- field_names = map fst rbinds
+ field_names = hsRecFields rbinds
in
- mappM (tcLookupField . unLoc) field_names `thenM` \ sel_ids ->
+ ASSERT( notNull field_names )
+ mappM tcLookupField field_names `thenM` \ sel_ids ->
-- The renamer has already checked that they
-- are all in scope
let
bad_guys = [ setSrcSpan loc $ addErrTc (notSelector field_name)
- | (L loc field_name, sel_id) <- field_names `zip` sel_ids,
- not (isRecordSelector sel_id) -- Excludes class ops
+ | (fld, sel_id) <- rec_flds rbinds `zip` sel_ids,
+ not (isRecordSelector sel_id), -- Excludes class ops
+ let L loc field_name = hsRecFieldId fld
]
in
checkM (null bad_guys) (sequenceM bad_guys `thenM_` failM) `thenM_`
-- Figure out the tycon and data cons from the first field name
let
-- It's OK to use the non-tc splitters here (for a selector)
- upd_field_lbls = recBindFields hrbinds
sel_id : _ = sel_ids
(tycon, _) = recordSelectorFieldLabel sel_id -- We've failed already if
data_cons = tyConDataCons tycon -- it's not a field label
-- NB: for a data type family, the tycon is the instance tycon
relevant_cons = filter is_relevant data_cons
- is_relevant con = all (`elem` dataConFieldLabels con) upd_field_lbls
+ is_relevant con = all (`elem` dataConFieldLabels con) field_names
in
-- STEP 2
-- Check that at least one constructor has all the named fields
-- i.e. has an empty set of bad fields returned by badFields
checkTc (not (null relevant_cons))
- (badFieldsUpd hrbinds) `thenM_`
+ (badFieldsUpd rbinds) `thenM_`
-- Check that all relevant data cons are vanilla. Doing record updates on
-- GADTs and/or existentials is more than my tiny brain can cope with today
(con1_tyvars, theta, con1_arg_tys, con1_res_ty) = dataConSig con1
con1_flds = dataConFieldLabels con1
common_tyvars = exactTyVarsOfTypes [ty | (fld,ty) <- con1_flds `zip` con1_arg_tys
- , not (fld `elem` upd_field_lbls) ]
+ , not (fld `elem` field_names) ]
is_common_tv tv = tv `elemVarSet` common_tyvars
con1_arg_tys' = map (substTy result_inst_env) con1_arg_tys
in
tcSubExp result_ty res_ty `thenM` \ co_fn ->
- tcRecordBinds con1 con1_arg_tys' hrbinds `thenM` \ rbinds' ->
+ tcRecordBinds con1 con1_arg_tys' rbinds `thenM` \ rbinds' ->
-- STEP 5: Typecheck the expression to be updated
let
= idHsWrapper
in
-- Phew!
- returnM (mkHsWrap co_fn (RecordUpd (mkLHsWrap scrut_co record_expr') rbinds'
+ returnM (mkHsWrap co_fn (RecordUpd (mkLHsWrap scrut_co record_expr') rbinds'
relevant_cons scrut_inst_tys result_inst_tys))
\end{code}
-> HsRecordBinds Name
-> TcM (HsRecordBinds TcId)
-tcRecordBinds data_con arg_tys (HsRecordBinds rbinds)
+tcRecordBinds data_con arg_tys (HsRecFields rbinds dd)
= do { mb_binds <- mappM do_bind rbinds
- ; return (HsRecordBinds (catMaybes mb_binds)) }
+ ; return (HsRecFields (catMaybes mb_binds) dd) }
where
flds_w_tys = zipEqual "tcRecordBinds" (dataConFieldLabels data_con) arg_tys
- do_bind (L loc field_lbl, rhs)
+ do_bind fld@(HsRecField { hsRecFieldId = L loc field_lbl, hsRecFieldArg = rhs })
| Just field_ty <- assocMaybe flds_w_tys field_lbl
= addErrCtxt (fieldCtxt field_lbl) $
do { rhs' <- tcPolyExprNC rhs field_ty
; sel_id <- tcLookupField field_lbl
; ASSERT( isRecordSelector sel_id )
- return (Just (L loc sel_id, rhs')) }
+ return (Just (fld { hsRecFieldId = L loc sel_id, hsRecFieldArg = rhs' })) }
| otherwise
= do { addErrTc (badFieldCon data_con field_lbl)
; return Nothing }
not (fl `elem` field_names_used)
]
- field_names_used = recBindFields rbinds
+ field_names_used = hsRecFields rbinds
field_labels = dataConFieldLabels data_con
field_info = zipEqual "missingFields"
ptext SLIT("Use pattern-matching instead")]
badFieldsUpd rbinds
= hang (ptext SLIT("No constructor has all these fields:"))
- 4 (pprQuotedList (recBindFields rbinds))
+ 4 (pprQuotedList (hsRecFields rbinds))
naughtyRecordSel sel_id
= ptext SLIT("Cannot use record selector") <+> quotes (ppr sel_id) <+>