import TcClassDcl ( tcMethodBind, mkMethodBind, badMethodErr,
tcClassDecl2, getGenericInstances )
import TcRnMonad
-import TcMType ( tcSkolSigType, checkValidTheta, checkValidInstHead, instTypeErr,
+import TcMType ( tcSkolSigType, checkValidTheta, checkValidInstHead,
+ checkInstTermination, instTypeErr,
checkAmbiguity, SourceTyCtxt(..) )
import TcType ( mkClassPred, tyVarsOfType,
tcSplitSigmaTy, tcSplitDFunHead, mkTyVarTys,
import MkId ( mkDictFunId, rUNTIME_ERROR_ID )
import FunDeps ( checkInstFDs )
import Name ( Name, getSrcLoc )
-import UnicodeUtil ( stringToUtf8 )
import Maybe ( catMaybes )
import SrcLoc ( srcLocSpan, unLoc, noLoc, Located(..), srcSpanStart )
import ListSetOps ( minusList )
import Outputable
import Bag
-import BasicTypes ( Activation( AlwaysActive ) )
+import BasicTypes ( Activation( AlwaysActive ), InlineSpec(..) )
import FastString
\end{code}
-- Type-check all the stuff before the "where"
--
-- We check for respectable instance type, and context
- -- but only do this for non-imported instance decls.
- -- Imported ones should have been checked already, and may indeed
- -- contain something illegal in normal Haskell, notably
- -- instance CCallable [Char]
tcLocalInstDecl1 decl@(L loc (InstDecl poly_ty binds uprags))
= -- Prime error recovery, set source location
recoverM (returnM Nothing) $
checkValidTheta InstThetaCtxt theta `thenM_`
checkAmbiguity tyvars theta (tyVarsOfType tau) `thenM_`
checkValidInstHead tau `thenM` \ (clas,inst_tys) ->
+ checkInstTermination theta inst_tys `thenM_`
checkTc (checkInstFDs theta clas inst_tys)
(instTypeErr (pprClassPred clas inst_tys) msg) `thenM_`
newDFunName clas inst_tys (srcSpanStart loc) `thenM` \ dfun_name ->
scs_and_meths = map instToId sc_dicts ++ meth_ids
this_dict_id = instToId this_dict
inline_prag | null dfun_arg_dicts = []
- | otherwise = [InlinePrag True AlwaysActive]
+ | otherwise = [InlinePrag (Inline AlwaysActive True)]
-- Always inline the dfun; this is an experimental decision
-- because it makes a big performance difference sometimes.
-- Often it means we can do the method selection, and then
-- See Note [Inline dfuns] below
dict_rhs
- | null scs_and_meths
- = -- Blatant special case for CCallable, CReturnable
- -- If the dictionary is empty then we should never
- -- select anything from it, so we make its RHS just
- -- emit an error message. This in turn means that we don't
- -- mention the constructor, which doesn't exist for CCallable, CReturnable
- -- Hardly beautiful, but only three extra lines.
- nlHsApp (noLoc $ TyApp (nlHsVar rUNTIME_ERROR_ID)
- [idType this_dict_id])
- (nlHsLit (HsStringPrim (mkFastString (stringToUtf8 msg))))
-
- | otherwise -- The common case
= mkHsConApp dict_constr inst_tys' (map HsVar scs_and_meths)
-- We don't produce a binding for the dict_constr; instead we
-- rely on the simplifier to unfold this saturated application