reportInjectivityErrors
   :: DynFlags
   -> CoAxiom br   -- ^ Type family for which we generate errors
   -> CoAxBranch   -- ^ Currently checked equation (represented by axiom)
   -> [Bool]       -- ^ Injectivity annotation
   -> TcM ()
reportInjectivityErrors dflags fi_ax axiom inj
  = ASSERT2( any id inj, text "No injective type variables" )
    do let lhs             = coAxBranchLHS axiom
           rhs             = coAxBranchRHS axiom
           fam_tc          = coAxiomTyCon fi_ax
           (unused_inj_tvs, unused_vis, undec_inst_flag)
                           = unusedInjTvsInRHS dflags fam_tc lhs rhs
           inj_tvs_unused  = not $ isEmptyVarSet unused_inj_tvs
           tf_headed       = isTFHeaded rhs
           bare_variables  = bareTvInRHSViolated lhs rhs
           wrong_bare_rhs  = not $ null bare_variables

       when inj_tvs_unused $ reportUnusedInjectiveVarsErr fam_tc unused_inj_tvs
                                                          unused_vis undec_inst_flag axiom
       when tf_headed      $ reportTfHeadedErr            fam_tc axiom
       when wrong_bare_rhs $ reportBareVariableInRHSErr   fam_tc bare_variables axiom

-- | Is type headed by a type family application?
reportInjectivityErrors
   :: DynFlags
   -> CoAxiom br   -- ^ Type family for which we generate errors
   -> CoAxBranch   -- ^ Currently checked equation (represented by axiom)
   -> [Bool]       -- ^ Injectivity annotation
   -> TcM ()
reportInjectivityErrors dflags fi_ax axiom inj
  = ASSERT2( any id inj, text "No injective type variables" )
    do let lhs             = coAxBranchLHS axiom
           rhs             = coAxBranchRHS axiom
           fam_tc          = coAxiomTyCon fi_ax
           (unused_inj_tvs, unused_vis, undec_inst_flag)
                           = unusedInjTvsInRHS dflags fam_tc lhs rhs
           inj_tvs_unused  = not $ isEmptyVarSet unused_inj_tvs
           tf_headed       = isTFHeaded rhs
           bare_variables  = bareTvInRHSViolated lhs rhs
           wrong_bare_rhs  = not $ null bare_variables

       when inj_tvs_unused $ reportUnusedInjectiveVarsErr fam_tc unused_inj_tvs
                                                          unused_vis undec_inst_flag axiom
       when tf_headed      $ reportTfHeadedErr            fam_tc axiom
       when wrong_bare_rhs $ reportBareVariableInRHSErr   fam_tc bare_variables axiom

-- | Is type headed by a type family application?
reportInjectivityErrors dflags fi_ax axiom inj
  = ASSERT2( any id inj, text "No injective type variables" )
    do let lhs             = coAxBranchLHS axiom
           rhs             = coAxBranchRHS axiom
           fam_tc          = coAxiomTyCon fi_ax
           (unused_inj_tvs, unused_vis, undec_inst_flag)
                           = unusedInjTvsInRHS dflags fam_tc lhs rhs
           inj_tvs_unused  = not $ isEmptyVarSet unused_inj_tvs
           tf_headed       = isTFHeaded rhs
           bare_variables  = bareTvInRHSViolated lhs rhs
           wrong_bare_rhs  = not $ null bare_variables

       when inj_tvs_unused $ reportUnusedInjectiveVarsErr fam_tc unused_inj_tvs
                                                          unused_vis undec_inst_flag axiom
       when tf_headed      $ reportTfHeadedErr            fam_tc axiom
       when wrong_bare_rhs $ reportBareVariableInRHSErr   fam_tc bare_variables axiom

-- | Is type headed by a type family application?