-dataConTag :: DataCon -> ConTag -- will panic if not a DataCon
-dataConTag (Id {idDetails = AlgConId tag _ _ _ _ _ _ _ _}) = tag
-dataConTag (Id {idDetails = TupleConId _}) = fIRST_TAG
-
-dataConTyCon :: DataCon -> TyCon -- will panic if not a DataCon
-dataConTyCon (Id {idDetails = AlgConId _ _ _ _ _ _ _ _ tycon}) = tycon
-dataConTyCon (Id {idDetails = TupleConId a}) = tupleTyCon a
-
-dataConSig :: DataCon -> ([TyVar], ThetaType, [TyVar], ThetaType, [TauType], TyCon)
- -- will panic if not a DataCon
-
-dataConSig (Id {idDetails = AlgConId _ _ _ tyvars theta con_tyvars con_theta arg_tys tycon})
- = (tyvars, theta, con_tyvars, con_theta, arg_tys, tycon)
-
-dataConSig (Id {idDetails = TupleConId arity})
- = (tyvars, [], [], [], tyvar_tys, tupleTyCon arity)
- where
- tyvars = take arity alphaTyVars
- tyvar_tys = mkTyVarTys tyvars
-
-
--- dataConRepType returns the type of the representation of a contructor
--- This may differ from the type of the contructor Id itself for two reasons:
--- a) the constructor Id may be overloaded, but the dictionary isn't stored
--- e.g. data Eq a => T a = MkT a a
---
--- b) the constructor may store an unboxed version of a strict field.
---
--- Here's an example illustrating both:
--- data Ord a => T a = MkT Int! a
--- Here
--- T :: Ord a => Int -> a -> T a
--- but the rep type is
--- Trep :: Int# -> a -> T a
--- Actually, the unboxed part isn't implemented yet!
-
-dataConRepType :: Id -> Type
-dataConRepType (Id {idDetails = AlgConId _ _ _ tyvars theta con_tyvars con_theta arg_tys tycon})
- = mkForAllTys (tyvars++con_tyvars)
- (mkFunTys arg_tys (mkTyConApp tycon (mkTyVarTys tyvars)))
-dataConRepType other_id
- = ASSERT( isDataCon other_id )
- idType other_id
-
-dataConFieldLabels :: DataCon -> [FieldLabel]
-dataConFieldLabels (Id {idDetails = AlgConId _ _ fields _ _ _ _ _ _}) = fields
-dataConFieldLabels (Id {idDetails = TupleConId _}) = []
-#ifdef DEBUG
-dataConFieldLabels x@(Id {idDetails = idt}) =
- panic ("dataConFieldLabel: " ++
- (case idt of
- VanillaId _ -> "l"
- PrimitiveId _ -> "p"
- RecordSelId _ -> "r"))
-#endif
-
-dataConStrictMarks :: DataCon -> [StrictnessMark]
-dataConStrictMarks (Id {idDetails = AlgConId _ stricts _ _ _ _ _ _ _}) = stricts
-dataConStrictMarks (Id {idDetails = TupleConId arity}) = nOfThem arity NotMarkedStrict
-
-dataConRawArgTys :: DataCon -> [TauType] -- a function of convenience
-dataConRawArgTys con = case (dataConSig con) of { (_,_, _, _, arg_tys,_) -> arg_tys }
-
-dataConArgTys :: DataCon
- -> [Type] -- Instantiated at these types
- -> [Type] -- Needs arguments of these types
-dataConArgTys con_id inst_tys
- = map (instantiateTy tenv) arg_tys
- where
- (tyvars, _, _, _, arg_tys, _) = dataConSig con_id
- tenv = zipTyVarEnv tyvars inst_tys
+recordSelectorFieldLabel :: Id -> (TyCon, FieldLabel)
+recordSelectorFieldLabel id = case globalIdDetails id of
+ RecordSelId tycon lbl _ -> (tycon,lbl)
+ other -> panic "recordSelectorFieldLabel"
+
+isRecordSelector id = case globalIdDetails id of
+ RecordSelId {} -> True
+ other -> False
+
+isNaughtyRecordSelector id = case globalIdDetails id of
+ RecordSelId { sel_naughty = n } -> n
+ other -> False
+
+isClassOpId_maybe id = case globalIdDetails id of
+ ClassOpId cls -> Just cls
+ _other -> Nothing
+
+isPrimOpId id = case globalIdDetails id of
+ PrimOpId op -> True
+ other -> False
+
+isPrimOpId_maybe id = case globalIdDetails id of
+ PrimOpId op -> Just op
+ other -> Nothing
+
+isFCallId id = case globalIdDetails id of
+ FCallId call -> True
+ other -> False
+
+isFCallId_maybe id = case globalIdDetails id of
+ FCallId call -> Just call
+ other -> Nothing
+
+isDataConWorkId id = case globalIdDetails id of
+ DataConWorkId _ -> True
+ other -> False
+
+isDataConWorkId_maybe id = case globalIdDetails id of
+ DataConWorkId con -> Just con
+ other -> Nothing
+
+isDataConId_maybe :: Id -> Maybe DataCon
+isDataConId_maybe id = case globalIdDetails id of
+ DataConWorkId con -> Just con
+ DataConWrapId con -> Just con
+ other -> Nothing
+
+idDataCon :: Id -> DataCon
+-- Get from either the worker or the wrapper to the DataCon
+-- Currently used only in the desugarer
+-- INVARIANT: idDataCon (dataConWrapId d) = d
+-- (Remember, dataConWrapId can return either the wrapper or the worker.)
+idDataCon id = case globalIdDetails id of
+ DataConWorkId con -> con
+ DataConWrapId con -> con
+ other -> pprPanic "idDataCon" (ppr id)
+
+
+isDictId :: Id -> Bool
+isDictId id = isDictTy (idType id)
+
+-- hasNoBinding returns True of an Id which may not have a
+-- binding, even though it is defined in this module.
+-- Data constructor workers used to be things of this kind, but
+-- they aren't any more. Instead, we inject a binding for
+-- them at the CorePrep stage.
+-- EXCEPT: unboxed tuples, which definitely have no binding
+hasNoBinding id = case globalIdDetails id of
+ PrimOpId _ -> True
+ FCallId _ -> True
+ DataConWorkId dc -> isUnboxedTupleCon dc
+ other -> False
+
+isImplicitId :: Id -> Bool
+ -- isImplicitId tells whether an Id's info is implied by other
+ -- declarations, so we don't need to put its signature in an interface
+ -- file, even if it's mentioned in some other interface unfolding.
+isImplicitId id
+ = case globalIdDetails id of
+ RecordSelId {} -> True
+ FCallId _ -> True
+ PrimOpId _ -> True
+ ClassOpId _ -> True
+ DataConWorkId _ -> True
+ DataConWrapId _ -> True
+ -- These are are implied by their type or class decl;
+ -- remember that all type and class decls appear in the interface file.
+ -- The dfun id is not an implicit Id; it must *not* be omitted, because
+ -- it carries version info for the instance decl
+ other -> False
+
+idIsFrom :: Module -> Id -> Bool
+idIsFrom mod id = nameIsLocalOrFrom mod (idName id)