summaryrefslogtreecommitdiff
path: root/compiler/typecheck/TcInstDcls.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/typecheck/TcInstDcls.hs')
-rw-r--r--compiler/typecheck/TcInstDcls.hs377
1 files changed, 232 insertions, 145 deletions
diff --git a/compiler/typecheck/TcInstDcls.hs b/compiler/typecheck/TcInstDcls.hs
index 022668b470..d69357a0e2 100644
--- a/compiler/typecheck/TcInstDcls.hs
+++ b/compiler/typecheck/TcInstDcls.hs
@@ -14,17 +14,19 @@ module TcInstDcls ( tcInstDecls1, tcInstDeclsDeriv, tcInstDecls2 ) where
#include "HsVersions.h"
+import GhcPrelude
+
import HsSyn
import TcBinds
import TcTyClsDecls
+import TcTyDecls ( addTyConsToGblEnv )
import TcClassDcl( tcClassDecl2, tcATDefault,
HsSigFun, mkHsSigFun,
findMethodBind, instantiateMethod )
import TcSigs
import TcRnMonad
import TcValidity
-import TcHsSyn ( zonkTyBndrsX, emptyZonkEnv
- , zonkTcTypeToTypes, zonkTcTypeToType )
+import TcHsSyn
import TcMType
import TcType
import BuildTyCl
@@ -49,14 +51,13 @@ import Class
import Var
import VarEnv
import VarSet
-import PrelNames ( typeableClassName, genericClassNames
- , knownNatClassName, knownSymbolClassName )
import Bag
import BasicTypes
import DynFlags
import ErrUtils
import FastString
import Id
+import ListSetOps
import MkId
import Name
import NameSet
@@ -412,13 +413,12 @@ addFamInsts :: [FamInst] -> TcM a -> TcM a
-- (b) the type envt with stuff from data type decls
addFamInsts fam_insts thing_inside
= tcExtendLocalFamInstEnv fam_insts $
- tcExtendGlobalEnv axioms $
- tcExtendTyConEnv data_rep_tycons $
+ tcExtendGlobalEnv axioms $
do { traceTc "addFamInsts" (pprFamInsts fam_insts)
- ; tcg_env <- tcAddImplicits data_rep_tycons
- -- Does not add its axiom; that comes from
- -- adding the 'axioms' above
- ; setGblEnv tcg_env thing_inside }
+ ; gbl_env <- addTyConsToGblEnv data_rep_tycons
+ -- Does not add its axiom; that comes
+ -- from adding the 'axioms' above
+ ; setGblEnv gbl_env thing_inside }
where
axioms = map (ACoAxiom . toBranchedAxiom . famInstAxiom) fam_insts
data_rep_tycons = famInstsRepTyCons fam_insts
@@ -460,6 +460,8 @@ tcLocalInstDecl (L loc (ClsInstD { cid_inst = decl }))
= do { (insts, fam_insts, deriv_infos) <- tcClsInstDecl (L loc decl)
; return (insts, fam_insts, deriv_infos) }
+tcLocalInstDecl (L _ (XInstDecl _)) = panic "tcLocalInstDecl"
+
tcClsInstDecl :: LClsInstDecl GhcRn
-> TcM ([InstInfo GhcRn], [FamInst], [DerivInfo])
-- The returned DerivInfos are for any associated data families
@@ -469,16 +471,19 @@ tcClsInstDecl (L loc (ClsInstDecl { cid_poly_ty = poly_ty, cid_binds = binds
, cid_datafam_insts = adts }))
= setSrcSpan loc $
addErrCtxt (instDeclCtxt1 poly_ty) $
- do { (tyvars, theta, clas, inst_tys) <- tcHsClsInstType InstDeclCtxt poly_ty
+ do { (tyvars, theta, clas, inst_tys)
+ <- tcHsClsInstType (InstDeclCtxt False) poly_ty
+ -- NB: tcHsClsInstType does checkValidInstance
+
; let mini_env = mkVarEnv (classTyVars clas `zip` inst_tys)
mini_subst = mkTvSubst (mkInScopeSet (mkVarSet tyvars)) mini_env
mb_info = Just (clas, tyvars, mini_env)
-- Next, process any associated types.
; traceTc "tcLocalInstDecl" (ppr poly_ty)
- ; tyfam_insts0 <- tcExtendTyVarEnv tyvars $
+ ; tyfam_insts0 <- scopeTyVars InstSkol tyvars $
mapAndRecoverM (tcTyFamInstDecl mb_info) ats
- ; datafam_stuff <- tcExtendTyVarEnv tyvars $
+ ; datafam_stuff <- scopeTyVars InstSkol tyvars $
mapAndRecoverM (tcDataFamInstDecl mb_info) adts
; let (datafam_insts, m_deriv_infos) = unzip datafam_stuff
deriv_infos = catMaybes m_deriv_infos
@@ -487,8 +492,11 @@ tcClsInstDecl (L loc (ClsInstDecl { cid_poly_ty = poly_ty, cid_binds = binds
-- from their defaults (if available)
; let defined_ats = mkNameSet (map (tyFamInstDeclName . unLoc) ats)
`unionNameSet`
- mkNameSet (map (unLoc . dfid_tycon . unLoc) adts)
- ; tyfam_insts1 <- mapM (tcATDefault True loc mini_subst defined_ats)
+ mkNameSet (map (unLoc . feqn_tycon
+ . hsib_body
+ . dfid_eqn
+ . unLoc) adts)
+ ; tyfam_insts1 <- mapM (tcATDefault loc mini_subst defined_ats)
(classATItems clas)
-- Finally, construct the Core representation of the instance.
@@ -507,59 +515,14 @@ tcClsInstDecl (L loc (ClsInstDecl { cid_poly_ty = poly_ty, cid_binds = binds
, ib_extensions = []
, ib_derived = False } }
- ; doClsInstErrorChecks inst_info
+ -- In hs-boot files there should be no bindings
+ ; is_boot <- tcIsHsBootOrSig
+ ; let no_binds = isEmptyLHsBinds binds && null uprags
+ ; failIfTc (is_boot && not no_binds) badBootDeclErr
; return ( [inst_info], tyfam_insts0 ++ concat tyfam_insts1 ++ datafam_insts
, deriv_infos ) }
-
-
-doClsInstErrorChecks :: InstInfo GhcRn -> TcM ()
-doClsInstErrorChecks inst_info
- = do { traceTc "doClsInstErrorChecks" (ppr ispec)
- ; dflags <- getDynFlags
- ; is_boot <- tcIsHsBootOrSig
-
- -- In hs-boot files there should be no bindings
- ; failIfTc (is_boot && not no_binds) badBootDeclErr
-
- -- If not in an hs-boot file, abstract classes cannot have
- -- instances declared
- ; failIfTc (not is_boot && isAbstractClass clas) abstractClassInstErr
-
- -- Handwritten instances of any rejected
- -- class is always forbidden
- -- #12837
- ; failIfTc (clas_nm `elem` rejectedClassNames) clas_err
-
- -- Check for hand-written Generic instances (disallowed in Safe Haskell)
- ; when (clas_nm `elem` genericClassNames) $
- do { failIfTc (safeLanguageOn dflags) gen_inst_err
- ; when (safeInferOn dflags) (recordUnsafeInfer emptyBag) }
- }
- where
- ispec = iSpec inst_info
- binds = iBinds inst_info
- no_binds = isEmptyLHsBinds (ib_binds binds) && null (ib_pragmas binds)
- clas_nm = is_cls_nm ispec
- clas = is_cls ispec
-
- gen_inst_err = hang (text ("Generic instances can only be "
- ++ "derived in Safe Haskell.") $+$
- text "Replace the following instance:")
- 2 (pprInstanceHdr ispec)
-
- abstractClassInstErr =
- text "Cannot define instance for abstract class" <+> quotes (ppr clas_nm)
-
- -- Report an error or a warning for certain class instances.
- -- If we are working on an .hs-boot file, we just report a warning,
- -- and ignore the instance. We do this, to give users a chance to fix
- -- their code.
- rejectedClassNames = [ typeableClassName
- , knownNatClassName
- , knownSymbolClassName ]
- clas_err = text "Class" <+> quotes (ppr clas_nm)
- <+> text "does not support user-specified instances"
+tcClsInstDecl (L _ (XClsInstDecl _)) = panic "tcClsInstDecl"
{-
************************************************************************
@@ -600,7 +563,7 @@ tcTyFamInstDecl :: Maybe ClsInstInfo
tcTyFamInstDecl mb_clsinfo (L loc decl@(TyFamInstDecl { tfid_eqn = eqn }))
= setSrcSpan loc $
tcAddTyFamInstCtxt decl $
- do { let fam_lname = tfe_tycon (unLoc eqn)
+ do { let fam_lname = feqn_tycon (hsib_body eqn)
; fam_tc <- tcFamInstDeclCombined mb_clsinfo fam_lname
-- (0) Check it's an open type family
@@ -609,7 +572,8 @@ tcTyFamInstDecl mb_clsinfo (L loc decl@(TyFamInstDecl { tfid_eqn = eqn }))
; checkTc (isOpenTypeFamilyTyCon fam_tc) (notOpenFamily fam_tc)
-- (1) do the work of verifying the synonym group
- ; co_ax_branch <- tcTyFamInstEqn (famTyConShape fam_tc) mb_clsinfo eqn
+ ; co_ax_branch <- tcTyFamInstEqn fam_tc mb_clsinfo
+ (L (getLoc fam_lname) eqn)
-- (2) check for validity
; checkValidCoAxBranch mb_clsinfo fam_tc co_ax_branch
@@ -623,12 +587,17 @@ tcDataFamInstDecl :: Maybe ClsInstInfo
-> LDataFamInstDecl GhcRn -> TcM (FamInst, Maybe DerivInfo)
-- "newtype instance" and "data instance"
tcDataFamInstDecl mb_clsinfo
- (L loc decl@(DataFamInstDecl
- { dfid_pats = pats
- , dfid_tycon = fam_tc_name
- , dfid_defn = defn@HsDataDefn { dd_ND = new_or_data, dd_cType = cType
- , dd_ctxt = ctxt, dd_cons = cons
- , dd_derivs = derivs } }))
+ (L loc decl@(DataFamInstDecl { dfid_eqn = HsIB { hsib_ext = tv_names
+ , hsib_body =
+ FamEqn { feqn_pats = pats
+ , feqn_tycon = fam_tc_name
+ , feqn_fixity = fixity
+ , feqn_rhs = HsDataDefn { dd_ND = new_or_data
+ , dd_cType = cType
+ , dd_ctxt = ctxt
+ , dd_cons = cons
+ , dd_kindSig = m_ksig
+ , dd_derivs = derivs } }}}))
= setSrcSpan loc $
tcAddDataFamInstCtxt decl $
do { fam_tc <- tcFamInstDeclCombined mb_clsinfo fam_tc_name
@@ -638,16 +607,17 @@ tcDataFamInstDecl mb_clsinfo
; checkTc (isDataFamilyTyCon fam_tc) (wrongKindOfFamily fam_tc)
-- Kind check type patterns
- ; tcFamTyPats (famTyConShape fam_tc) mb_clsinfo pats
- (kcDataDefn (unLoc fam_tc_name) pats defn) $
+ ; let mb_kind_env = thdOf3 <$> mb_clsinfo
+ ; tcFamTyPats fam_tc mb_clsinfo tv_names pats
+ (kcDataDefn mb_kind_env decl) $
\tvs pats res_kind ->
do { stupid_theta <- solveEqualities $ tcHsContext ctxt
-- Zonk the patterns etc into the Type world
- ; (ze, tvs') <- zonkTyBndrsX emptyZonkEnv tvs
- ; pats' <- zonkTcTypeToTypes ze pats
- ; res_kind' <- zonkTcTypeToType ze res_kind
- ; stupid_theta' <- zonkTcTypeToTypes ze stupid_theta
+ ; (ze, tvs') <- zonkTyBndrs tvs
+ ; pats' <- zonkTcTypesToTypesX ze pats
+ ; res_kind' <- zonkTcTypeToTypeX ze res_kind
+ ; stupid_theta' <- zonkTcTypesToTypesX ze stupid_theta
; gadt_syntax <- dataDeclChecks (tyConName fam_tc) new_or_data stupid_theta' cons
@@ -657,15 +627,25 @@ tcDataFamInstDecl mb_clsinfo
; let (eta_pats, etad_tvs) = eta_reduce pats'
eta_tvs = filterOut (`elem` etad_tvs) tvs'
- full_tvs = eta_tvs ++ etad_tvs
+ -- NB: the "extra" tvs from tcDataKindSig would always be eta-reduced
+
+ full_tcbs = mkTyConBindersPreferAnon (eta_tvs ++ etad_tvs) res_kind'
-- Put the eta-removed tyvars at the end
-- Remember, tvs' is in arbitrary order (except kind vars are
-- first, so there is no reason to suppose that the etad_tvs
-- (obtained from the pats) are at the end (Trac #11148)
- orig_res_ty = mkTyConApp fam_tc pats'
+
+ -- Deal with any kind signature.
+ -- See also Note [Arity of data families] in FamInstEnv
+ ; (extra_tcbs, final_res_kind) <- tcDataKindSig full_tcbs res_kind'
+ ; checkTc (tcIsLiftedTypeKind final_res_kind) (badKindSig True res_kind')
+
+ ; let extra_pats = map (mkTyVarTy . binderVar) extra_tcbs
+ all_pats = pats' `chkAppend` extra_pats
+ orig_res_ty = mkTyConApp fam_tc all_pats
; (rep_tc, axiom) <- fixM $ \ ~(rec_rep_tc, _) ->
- do { let ty_binders = mkTyConBindersPreferAnon full_tvs liftedTypeKind
+ do { let ty_binders = full_tcbs `chkAppend` extra_tcbs
; data_cons <- tcConDecls rec_rep_tc
(ty_binders, orig_res_ty) cons
; tc_rhs <- case new_or_data of
@@ -676,14 +656,14 @@ tcDataFamInstDecl mb_clsinfo
; let axiom = mkSingleCoAxiom Representational
axiom_name eta_tvs [] fam_tc eta_pats
(mkTyConApp rep_tc (mkTyVarTys eta_tvs))
- parent = DataFamInstTyCon axiom fam_tc pats'
+ parent = DataFamInstTyCon axiom fam_tc all_pats
- -- NB: Use the full_tvs from the pats. See bullet toward
+ -- NB: Use the full ty_binders from the pats. See bullet toward
-- the end of Note [Data type families] in TyCon
rep_tc = mkAlgTyCon rep_tc_name
ty_binders liftedTypeKind
- (map (const Nominal) full_tvs)
+ (map (const Nominal) ty_binders)
(fmap unLoc cType) stupid_theta
tc_rhs parent
gadt_syntax
@@ -697,10 +677,10 @@ tcDataFamInstDecl mb_clsinfo
-- Remember to check validity; no recursion to worry about here
-- Check that left-hand sides are ok (mono-types, no type families,
-- consistent instantiations, etc)
- ; checkValidFamPats mb_clsinfo fam_tc tvs' [] pats'
+ ; checkValidFamPats mb_clsinfo fam_tc tvs' [] pats' extra_pats pp_hs_pats
-- Result kind must be '*' (otherwise, we have too few patterns)
- ; checkTc (isLiftedTypeKind res_kind') $
+ ; checkTc (tcIsLiftedTypeKind final_res_kind) $
tooFewParmsErr (tyConArity fam_tc)
; checkValidTyCon rep_tc
@@ -730,6 +710,17 @@ tcDataFamInstDecl mb_clsinfo
= go pats (tv : etad_tvs)
go pats etad_tvs = (reverse pats, etad_tvs)
+ pp_hs_pats = pprFamInstLHS fam_tc_name pats fixity (unLoc ctxt) m_ksig
+
+tcDataFamInstDecl _
+ (L _ (DataFamInstDecl
+ { dfid_eqn = HsIB { hsib_body = FamEqn { feqn_rhs = XHsDataDefn _ }}}))
+ = panic "tcDataFamInstDecl"
+tcDataFamInstDecl _ (L _ (DataFamInstDecl (XHsImplicitBndrs _)))
+ = panic "tcDataFamInstDecl"
+tcDataFamInstDecl _ (L _ (DataFamInstDecl (HsIB _ (XFamEqn _))))
+ = panic "tcDataFamInstDecl"
+
{- *********************************************************************
* *
@@ -819,17 +810,14 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = ibinds })
, sc_binds `unionBags` meth_binds
, sc_implics `unionBags` meth_implics ) }
- ; env <- getLclEnv
- ; emitImplication $ Implic { ic_tclvl = tclvl
- , ic_skols = inst_tyvars
- , ic_no_eqs = False
- , ic_given = dfun_ev_vars
- , ic_wanted = mkImplicWC sc_meth_implics
- , ic_status = IC_Unsolved
- , ic_binds = dfun_ev_binds_var
- , ic_needed = emptyVarSet
- , ic_env = env
- , ic_info = InstSkol }
+ ; imp <- newImplication
+ ; emitImplication $
+ imp { ic_tclvl = tclvl
+ , ic_skols = inst_tyvars
+ , ic_given = dfun_ev_vars
+ , ic_wanted = mkImplicWC sc_meth_implics
+ , ic_binds = dfun_ev_binds_var
+ , ic_info = InstSkol }
-- Create the result bindings
; self_dict <- newDict clas inst_tys
@@ -847,14 +835,15 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = ibinds })
-- con_app_scs = MkD ty1 ty2 sc1 sc2
-- con_app_args = MkD ty1 ty2 sc1 sc2 op1 op2
con_app_tys = mkHsWrap (mkWpTyApps inst_tys)
- (HsConLikeOut (RealDataCon dict_constr))
+ (HsConLikeOut noExt (RealDataCon dict_constr))
-- NB: We *can* have covars in inst_tys, in the case of
-- promoted GADT constructors.
- con_app_args = foldl app_to_meth con_app_tys sc_meth_ids
+ con_app_args = foldl' app_to_meth con_app_tys sc_meth_ids
app_to_meth :: HsExpr GhcTc -> Id -> HsExpr GhcTc
- app_to_meth fun meth_id = L loc fun `HsApp` L loc (wrapId arg_wrapper meth_id)
+ app_to_meth fun meth_id = HsApp noExt (L loc fun)
+ (L loc (wrapId arg_wrapper meth_id))
inst_tv_tys = mkTyVarTys inst_tyvars
arg_wrapper = mkWpEvVarApps dfun_ev_vars <.> mkWpTyApps inst_tv_tys
@@ -867,16 +856,19 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = ibinds })
-- Newtype dfuns just inline unconditionally,
-- so don't attempt to specialise them
- export = ABE { abe_wrap = idHsWrapper
+ export = ABE { abe_ext = noExt
+ , abe_wrap = idHsWrapper
, abe_poly = dfun_id_w_prags
, abe_mono = self_dict
, abe_prags = dfun_spec_prags }
-- NB: see Note [SPECIALISE instance pragmas]
- main_bind = AbsBinds { abs_tvs = inst_tyvars
+ main_bind = AbsBinds { abs_ext = noExt
+ , abs_tvs = inst_tyvars
, abs_ev_vars = dfun_ev_vars
, abs_exports = [export]
, abs_ev_binds = []
- , abs_binds = unitBag dict_bind }
+ , abs_binds = unitBag dict_bind
+ , abs_sig = True }
; return (unitBag (L loc main_bind) `unionBags` sc_meth_binds)
}
@@ -916,8 +908,8 @@ addDFunPrags dfun_id sc_meth_ids
[dict_con] = tyConDataCons clas_tc
is_newtype = isNewTyCon clas_tc
-wrapId :: HsWrapper -> IdP id -> HsExpr id
-wrapId wrapper id = mkHsWrap wrapper (HsVar (noLoc id))
+wrapId :: HsWrapper -> IdP (GhcPass id) -> HsExpr (GhcPass id)
+wrapId wrapper id = mkHsWrap wrapper (HsVar noExt (noLoc id))
{- Note [Typechecking plan for instance declarations]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -966,7 +958,7 @@ Notice that
into *every* method or superclass definition. (Some of it will
be usused in some, but dead-code elimination will drop it.)
- We achieve this by putting the the evidence variable for the overall
+ We achieve this by putting the evidence variable for the overall
instance implication into the AbsBinds for each method/superclass.
Hence the 'dfun_ev_binds' passed into tcMethods and tcSuperClasses.
(And that in turn is why the abs_ev_binds field of AbBinds is a
@@ -1015,16 +1007,19 @@ tcSuperClasses dfun_id cls tyvars dfun_evs inst_tys dfun_ev_binds sc_theta
; addTcEvBind ev_binds_var $ mkWantedEvBind sc_ev_id sc_ev_tm
; let sc_top_ty = mkInvForAllTys tyvars (mkLamTypes dfun_evs sc_pred)
sc_top_id = mkLocalId sc_top_name sc_top_ty
- export = ABE { abe_wrap = idHsWrapper
+ export = ABE { abe_ext = noExt
+ , abe_wrap = idHsWrapper
, abe_poly = sc_top_id
, abe_mono = sc_ev_id
, abe_prags = noSpecPrags }
local_ev_binds = TcEvBinds ev_binds_var
- bind = AbsBinds { abs_tvs = tyvars
+ bind = AbsBinds { abs_ext = noExt
+ , abs_tvs = tyvars
, abs_ev_vars = dfun_evs
, abs_exports = [export]
, abs_ev_binds = [dfun_ev_binds, local_ev_binds]
- , abs_binds = emptyBag }
+ , abs_binds = emptyBag
+ , abs_sig = False }
; return (sc_top_id, L loc bind, sc_implic) }
-------------------
@@ -1036,19 +1031,13 @@ checkInstConstraints thing_inside
thing_inside
; ev_binds_var <- newTcEvBinds
- ; env <- getLclEnv
- ; let implic = Implic { ic_tclvl = tclvl
- , ic_skols = []
- , ic_no_eqs = False
- , ic_given = []
- , ic_wanted = wanted
- , ic_status = IC_Unsolved
- , ic_binds = ev_binds_var
- , ic_needed = emptyVarSet
- , ic_env = env
- , ic_info = InstSkol }
-
- ; return (implic, ev_binds_var, result) }
+ ; implic <- newImplication
+ ; let implic' = implic { ic_tclvl = tclvl
+ , ic_wanted = wanted
+ , ic_binds = ev_binds_var
+ , ic_info = InstSkol }
+
+ ; return (implic', ev_binds_var, result) }
{-
Note [Recursive superclasses]
@@ -1171,7 +1160,7 @@ Answer:
* When we make a superclass selection from InstSkol we use
a SkolemInfo of (InstSC size), where 'size' is the size of
- the constraint whose superclass we are taking. An similarly
+ the constraint whose superclass we are taking. A similarly
when taking the superclass of an InstSC. This is implemented
in TcCanonical.newSCWorkFromFlavored
@@ -1263,17 +1252,27 @@ tcMethods dfun_id clas tyvars dfun_ev_vars inst_tys
, ib_pragmas = sigs
, ib_extensions = exts
, ib_derived = is_derived })
- = tcExtendTyVarEnv2 (lexical_tvs `zip` tyvars) $
+ -- tcExtendTyVarEnv (not scopeTyVars) is OK because the TcLevel is pushed
+ -- in checkInstConstraints
+ = tcExtendNameTyVarEnv (lexical_tvs `zip` tyvars) $
-- The lexical_tvs scope over the 'where' part
do { traceTc "tcInstMeth" (ppr sigs $$ ppr binds)
; checkMinimalDefinition
+ ; checkMethBindMembership
; (ids, binds, mb_implics) <- set_exts exts $
+ unset_warnings_deriving $
mapAndUnzip3M tc_item op_items
; return (ids, listToBag binds, listToBag (catMaybes mb_implics)) }
where
set_exts :: [LangExt.Extension] -> TcM a -> TcM a
set_exts es thing = foldr setXOptM thing es
+ -- See Note [Avoid -Winaccessible-code when deriving]
+ unset_warnings_deriving :: TcM a -> TcM a
+ unset_warnings_deriving
+ | is_derived = unsetWOptM Opt_WarnInaccessibleCode
+ | otherwise = id
+
hs_sig_fn = mkHsSigFun sigs
inst_loc = getSrcSpan dfun_id
@@ -1309,13 +1308,12 @@ tcMethods dfun_id clas tyvars dfun_ev_vars inst_tys
mkLHsWrap lam_wrapper (error_rhs dflags)
; return (meth_id, meth_bind, Nothing) }
where
- error_rhs dflags = L inst_loc $ HsApp error_fun (error_msg dflags)
+ error_rhs dflags = L inst_loc $ HsApp noExt error_fun (error_msg dflags)
error_fun = L inst_loc $
wrapId (mkWpTyApps
- [ getRuntimeRep "tcInstanceMethods.tc_default" meth_tau
- , meth_tau])
+ [ getRuntimeRep meth_tau, meth_tau])
nO_METHOD_BINDING_ERROR_ID
- error_msg dflags = L inst_loc (HsLit (HsStringPrim noSourceText
+ error_msg dflags = L inst_loc (HsLit noExt (HsStringPrim NoSourceText
(unsafeMkByteString (error_string dflags))))
meth_tau = funResultTy (piResultTys (idType sel_id) inst_tys)
error_string dflags = showSDoc dflags
@@ -1330,6 +1328,90 @@ tcMethods dfun_id clas tyvars dfun_ev_vars inst_tys
methodExists meth = isJust (findMethodBind meth binds prag_fn)
+ ----------------------
+ -- Check if any method bindings do not correspond to the class.
+ -- See Note [Mismatched class methods and associated type families].
+ checkMethBindMembership
+ = let bind_nms = map unLoc $ collectMethodBinders binds
+ cls_meth_nms = map (idName . fst) op_items
+ mismatched_meths = bind_nms `minusList` cls_meth_nms
+ in forM_ mismatched_meths $ \mismatched_meth ->
+ addErrTc $ hsep
+ [ text "Class", quotes (ppr (className clas))
+ , text "does not have a method", quotes (ppr mismatched_meth)]
+
+{-
+Note [Mismatched class methods and associated type families]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+It's entirely possible for someone to put methods or associated type family
+instances inside of a class in which it doesn't belong. For instance, we'd
+want to fail if someone wrote this:
+
+ instance Eq () where
+ type Rep () = Maybe
+ compare = undefined
+
+Since neither the type family `Rep` nor the method `compare` belong to the
+class `Eq`. Normally, this is caught in the renamer when resolving RdrNames,
+since that would discover that the parent class `Eq` is incorrect.
+
+However, there is a scenario in which the renamer could fail to catch this:
+if the instance was generated through Template Haskell, as in #12387. In that
+case, Template Haskell will provide fully resolved names (e.g.,
+`GHC.Classes.compare`), so the renamer won't notice the sleight-of-hand going
+on. For this reason, we also put an extra validity check for this in the
+typechecker as a last resort.
+
+Note [Avoid -Winaccessible-code when deriving]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-Winaccessible-code can be particularly noisy when deriving instances for
+GADTs. Consider the following example (adapted from #8128):
+
+ data T a where
+ MkT1 :: Int -> T Int
+ MkT2 :: T Bool
+ MkT3 :: T Bool
+ deriving instance Eq (T a)
+ deriving instance Ord (T a)
+
+In the derived Ord instance, GHC will generate the following code:
+
+ instance Ord (T a) where
+ compare x y
+ = case x of
+ MkT2
+ -> case y of
+ MkT1 {} -> GT
+ MkT2 -> EQ
+ _ -> LT
+ ...
+
+However, that MkT1 is unreachable, since the type indices for MkT1 and MkT2
+differ, so if -Winaccessible-code is enabled, then deriving this instance will
+result in unwelcome warnings.
+
+One conceivable approach to fixing this issue would be to change `deriving Ord`
+such that it becomes smarter about not generating unreachable cases. This,
+however, would be a highly nontrivial refactor, as we'd have to propagate
+through typing information everywhere in the algorithm that generates Ord
+instances in order to determine which cases were unreachable. This seems like
+a lot of work for minimal gain, so we have opted not to go for this approach.
+
+Instead, we take the much simpler approach of always disabling
+-Winaccessible-code for derived code. To accomplish this, we do the following:
+
+1. In tcMethods (which typechecks method bindings), disable
+ -Winaccessible-code.
+2. When creating Implications during typechecking, record the Env
+ (through ic_env) at the time of creation. Since the Env also stores
+ DynFlags, this will remember that -Winaccessible-code was disabled over
+ the scope of that implication.
+3. After typechecking comes error reporting, where GHC must decide how to
+ report inaccessible code to the user, on an Implication-by-Implication
+ basis. If an Implication's DynFlags indicate that -Winaccessible-code was
+ disabled, then don't bother reporting it. That's it!
+-}
+
------------------------
tcMethodBody :: Class -> [TcTyVar] -> [EvVar] -> [TcType]
-> TcEvBinds -> Bool
@@ -1361,17 +1443,20 @@ tcMethodBody clas tyvars dfun_ev_vars inst_tys
; spec_prags <- tcSpecPrags global_meth_id prags
; let specs = mk_meth_spec_prags global_meth_id spec_inst_prags spec_prags
- export = ABE { abe_poly = global_meth_id
- , abe_mono = local_meth_id
- , abe_wrap = idHsWrapper
- , abe_prags = specs }
+ export = ABE { abe_ext = noExt
+ , abe_poly = global_meth_id
+ , abe_mono = local_meth_id
+ , abe_wrap = idHsWrapper
+ , abe_prags = specs }
local_ev_binds = TcEvBinds ev_binds_var
- full_bind = AbsBinds { abs_tvs = tyvars
+ full_bind = AbsBinds { abs_ext = noExt
+ , abs_tvs = tyvars
, abs_ev_vars = dfun_ev_vars
, abs_exports = [export]
, abs_ev_binds = [dfun_ev_binds, local_ev_binds]
- , abs_binds = tc_bind }
+ , abs_binds = tc_bind
+ , abs_sig = True }
; return (global_meth_id, L bind_loc full_bind, Just meth_implic) }
where
@@ -1408,15 +1493,17 @@ tcMethodBodyHelp hs_sig_fn sel_id local_meth_id meth_bind
; (tc_bind, [inner_id]) <- tcPolyCheck no_prag_fn inner_meth_sig meth_bind
- ; let export = ABE { abe_poly = local_meth_id
+ ; let export = ABE { abe_ext = noExt
+ , abe_poly = local_meth_id
, abe_mono = inner_id
, abe_wrap = hs_wrap
, abe_prags = noSpecPrags }
; return (unitBag $ L (getLoc meth_bind) $
- AbsBinds { abs_tvs = [], abs_ev_vars = []
+ AbsBinds { abs_ext = noExt, abs_tvs = [], abs_ev_vars = []
, abs_exports = [export]
- , abs_binds = tc_bind, abs_ev_binds = [] }) }
+ , abs_binds = tc_bind, abs_ev_binds = []
+ , abs_sig = True }) }
| otherwise -- No instance signature
= do { let ctxt = FunSigCtxt sel_name False
@@ -1520,7 +1607,7 @@ Wow! Three nested AbsBinds!
* The middle one is only present if there is an instance signature,
and does the impedance matching for that signature
* The inner one is for the method binding itself against either the
- signature from the class, or the the instance signature.
+ signature from the class, or the instance signature.
-}
----------------------
@@ -1559,7 +1646,7 @@ mkDefMethBind clas inst_tys sel_id dm_name
; dm_id <- tcLookupId dm_name
; let inline_prag = idInlinePragma dm_id
inline_prags | isAnyInlinePragma inline_prag
- = [noLoc (InlineSig fn inline_prag)]
+ = [noLoc (InlineSig noExt fn inline_prag)]
| otherwise
= []
-- Copy the inline pragma (if any) from the default method
@@ -1568,7 +1655,7 @@ mkDefMethBind clas inst_tys sel_id dm_name
fn = noLoc (idName sel_id)
visible_inst_tys = [ ty | (tcb, ty) <- tyConBinders (classTyCon clas) `zip` inst_tys
, tyConBinderArgFlag tcb /= Inferred ]
- rhs = foldl mk_vta (nlHsVar dm_name) visible_inst_tys
+ rhs = foldl' mk_vta (nlHsVar dm_name) visible_inst_tys
bind = noLoc $ mkTopFunBind Generated fn $
[mkSimpleMatch (mkPrefixFunRhs fn) [] rhs]
@@ -1579,8 +1666,8 @@ mkDefMethBind clas inst_tys sel_id dm_name
; return (bind, inline_prags) }
where
mk_vta :: LHsExpr GhcRn -> Type -> LHsExpr GhcRn
- mk_vta fun ty = noLoc (HsAppType fun (mkEmptyWildCardBndrs
- $ nlHsParTy $ noLoc $ HsCoreTy ty))
+ mk_vta fun ty = noLoc (HsAppType (mkEmptyWildCardBndrs $ nlHsParTy
+ $ noLoc $ XHsType $ NHsCoreTy ty) fun)
-- NB: use visible type application
-- See Note [Default methods in instances]
@@ -1646,7 +1733,7 @@ generic default methods.
Note [INLINE and default methods]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Default methods need special case. They are supposed to behave rather like
-macros. For exmample
+macros. For example
class Foo a where
op1, op2 :: Bool -> a -> a
@@ -1782,7 +1869,7 @@ tcSpecInstPrags dfun_id (InstBindings { ib_binds = binds, ib_pragmas = uprags })
------------------------------
tcSpecInst :: Id -> Sig GhcRn -> TcM TcSpecPrag
-tcSpecInst dfun_id prag@(SpecInstSig _ hs_ty)
+tcSpecInst dfun_id prag@(SpecInstSig _ _ hs_ty)
= addErrCtxt (spec_ctxt prag) $
do { (tyvars, theta, clas, tys) <- tcHsClsInstType SpecInstCtxt hs_ty
; let spec_dfun_ty = mkDictFunTy tyvars theta clas tys