buildDataCon :: FamInstEnvs
            -> Name
            -> Bool                     -- Declared infix
            -> TyConRepName
            -> [HsSrcBang]
            -> Maybe [HsImplBang]
                -- See Note [Bangs on imported data constructors] in MkId
           -> [FieldLabel]             -- Field labels
           -> [TyVar]                  -- Universals
           -> [TyVar]                  -- Existentials
           -> [TyVarBinder]            -- User-written 'TyVarBinder's
           -> [EqSpec]                 -- Equality spec
           -> ThetaType                -- Does not include the "stupid theta"
                                       -- or the GADT equalities
           -> [Type] -> Type           -- Argument and result types
           -> TyCon                    -- Rep tycon
           -> TcRnIf m n DataCon
-- A wrapper for DataCon.mkDataCon that
--   a) makes the worker Id
--   b) makes the wrapper Id if necessary, including
--      allocating its unique (hence monadic)
buildDataCon fam_envs src_name declared_infix prom_info src_bangs impl_bangs field_lbls
             univ_tvs ex_tvs user_tvbs eq_spec ctxt arg_tys res_ty rep_tycon
  = do  { wrap_name <- newImplicitBinder src_name mkDataConWrapperOcc
        ; work_name <- newImplicitBinder src_name mkDataConWorkerOcc
        -- This last one takes the name of the data constructor in the source
        -- code, which (for Haskell source anyway) will be in the DataName name
        -- space, and puts it into the VarName name space

        ; traceIf (text "buildDataCon 1" <+> ppr src_name)
        ; us <- newUniqueSupply
        ; dflags <- getDynFlags
        ; let stupid_ctxt = mkDataConStupidTheta rep_tycon arg_tys univ_tvs
              data_con = mkDataCon src_name declared_infix prom_info
                                   src_bangs field_lbls
                                   univ_tvs ex_tvs user_tvbs eq_spec ctxt
                                   arg_tys res_ty NoRRI rep_tycon
                                   stupid_ctxt dc_wrk dc_rep
              dc_wrk = mkDataConWorkId work_name data_con
              dc_rep = initUs_ us (mkDataConRep dflags fam_envs wrap_name
                                                impl_bangs data_con)

        ; traceIf (text "buildDataCon 2" <+> ppr src_name)
        ; return data_con }
buildDataCon :: FamInstEnvs
            -> Name
            -> Bool                     -- Declared infix
            -> TyConRepName
            -> [HsSrcBang]
            -> Maybe [HsImplBang]
                -- See Note [Bangs on imported data constructors] in MkId
           -> [FieldLabel]             -- Field labels
           -> [TyVar]                  -- Universals
           -> [TyVar]                  -- Existentials
           -> [TyVarBinder]            -- User-written 'TyVarBinder's
           -> [EqSpec]                 -- Equality spec
           -> ThetaType                -- Does not include the "stupid theta"
                                       -- or the GADT equalities
           -> [Type] -> Type           -- Argument and result types
           -> TyCon                    -- Rep tycon
           -> TcRnIf m n DataCon
buildDataCon fam_envs src_name declared_infix prom_info src_bangs impl_bangs field_lbls
             univ_tvs ex_tvs user_tvbs eq_spec ctxt arg_tys res_ty rep_tycon
  = do  { wrap_name <- newImplicitBinder src_name mkDataConWrapperOcc
        ; work_name <- newImplicitBinder src_name mkDataConWorkerOcc
        -- This last one takes the name of the data constructor in the source
        -- code, which (for Haskell source anyway) will be in the DataName name
        -- space, and puts it into the VarName name space

        ; traceIf (text "buildDataCon 1" <+> ppr src_name)
        ; us <- newUniqueSupply
        ; dflags <- getDynFlags
        ; let stupid_ctxt = mkDataConStupidTheta rep_tycon arg_tys univ_tvs
              data_con = mkDataCon src_name declared_infix prom_info
                                   src_bangs field_lbls
                                   univ_tvs ex_tvs user_tvbs eq_spec ctxt
                                   arg_tys res_ty NoRRI rep_tycon
                                   stupid_ctxt dc_wrk dc_rep
              dc_wrk = mkDataConWorkId work_name data_con
              dc_rep = initUs_ us (mkDataConRep dflags fam_envs wrap_name
                                                impl_bangs data_con)

        ; traceIf (text "buildDataCon 2" <+> ppr src_name)
        ; return data_con }
buildDataCon fam_envs src_name declared_infix prom_info src_bangs impl_bangs field_lbls
             univ_tvs ex_tvs user_tvbs eq_spec ctxt arg_tys res_ty rep_tycon
  = do  { wrap_name <- newImplicitBinder src_name mkDataConWrapperOcc
        ; work_name <- newImplicitBinder src_name mkDataConWorkerOcc
        -- This last one takes the name of the data constructor in the source
        -- code, which (for Haskell source anyway) will be in the DataName name
        -- space, and puts it into the VarName name space

        ; traceIf (text "buildDataCon 1" <+> ppr src_name)
        ; us <- newUniqueSupply
        ; dflags <- getDynFlags
        ; let stupid_ctxt = mkDataConStupidTheta rep_tycon arg_tys univ_tvs
              data_con = mkDataCon src_name declared_infix prom_info
                                   src_bangs field_lbls
                                   univ_tvs ex_tvs user_tvbs eq_spec ctxt
                                   arg_tys res_ty NoRRI rep_tycon
                                   stupid_ctxt dc_wrk dc_rep
              dc_wrk = mkDataConWorkId work_name data_con
              dc_rep = initUs_ us (mkDataConRep dflags fam_envs wrap_name
                                                impl_bangs data_con)

        ; traceIf (text "buildDataCon 2" <+> ppr src_name)
        ; return data_con }