diff options
Diffstat (limited to 'compiler/GHC/Tc')
-rw-r--r-- | compiler/GHC/Tc/Gen/Bind.hs | 7 | ||||
-rw-r--r-- | compiler/GHC/Tc/Gen/Pat.hs | 8 | ||||
-rw-r--r-- | compiler/GHC/Tc/Gen/Sig.hs | 24 | ||||
-rw-r--r-- | compiler/GHC/Tc/TyCl/Class.hs | 1 | ||||
-rw-r--r-- | compiler/GHC/Tc/TyCl/Instance.hs | 9 | ||||
-rw-r--r-- | compiler/GHC/Tc/TyCl/PatSyn.hs | 19 |
6 files changed, 48 insertions, 20 deletions
diff --git a/compiler/GHC/Tc/Gen/Bind.hs b/compiler/GHC/Tc/Gen/Bind.hs index cf2cac142b..3d78ac9e02 100644 --- a/compiler/GHC/Tc/Gen/Bind.hs +++ b/compiler/GHC/Tc/Gen/Bind.hs @@ -637,6 +637,7 @@ tcPolyCheck prag_fn poly_id2 = mkLocalId mono_name (idMult poly_id) (idType poly_id) ; spec_prags <- tcSpecPrags poly_id prag_sigs ; poly_id <- addInlinePrags poly_id prag_sigs + ; poly_id <- addSpecRecPrags poly_id prag_sigs ; mod <- getModule ; tick <- funBindTicks (locA nm_loc) poly_id mod prag_sigs @@ -832,6 +833,7 @@ mkExport prag_fn residual insoluble qtvs theta -- NB: poly_id has a zonked type ; poly_id <- addInlinePrags poly_id prag_sigs + ; poly_id <- addSpecRecPrags poly_id prag_sigs ; spec_prags <- tcSpecPrags poly_id prag_sigs -- tcPrags requires a zonked poly_id @@ -1514,7 +1516,10 @@ tcLhsSigId no_gen (name, sig) newSigLetBndr :: LetBndrSpec -> Name -> TcIdSigInst -> TcM TcId newSigLetBndr (LetGblBndr prags) name (TISI { sig_inst_sig = id_sig }) | CompleteSig { sig_bndr = poly_id } <- id_sig - = addInlinePrags poly_id (lookupPragEnv prags name) + = do + poly_id <- addInlinePrags poly_id (lookupPragEnv prags name) + poly_id <- addSpecRecPrags poly_id (lookupPragEnv prags name) + return poly_id newSigLetBndr no_gen name (TISI { sig_inst_tau = tau }) = newLetBndr no_gen name ManyTy tau -- Binders with a signature are currently always of multiplicity diff --git a/compiler/GHC/Tc/Gen/Pat.hs b/compiler/GHC/Tc/Gen/Pat.hs index 35c2463cb6..e41845a395 100644 --- a/compiler/GHC/Tc/Gen/Pat.hs +++ b/compiler/GHC/Tc/Gen/Pat.hs @@ -32,7 +32,7 @@ import GHC.Hs.Syn.Type import GHC.Rename.Utils import GHC.Tc.Errors.Types import GHC.Tc.Utils.Zonk -import GHC.Tc.Gen.Sig( TcPragEnv, lookupPragEnv, addInlinePrags ) +import GHC.Tc.Gen.Sig import GHC.Tc.Utils.Monad import GHC.Tc.Utils.Instantiate import GHC.Types.FieldLabel @@ -265,7 +265,11 @@ newLetBndr LetLclBndr name w ty = do { mono_name <- cloneLocalName name ; return (mkLocalId mono_name w ty) } newLetBndr (LetGblBndr prags) name w ty - = addInlinePrags (mkLocalId name w ty) (lookupPragEnv prags name) + = do { let prags' = (lookupPragEnv prags name) + ; bndr <- addInlinePrags (mkLocalId name w ty) prags' + ; bndr <- addSpecRecPrags bndr prags' + ; return bndr + } tc_sub_type :: PatEnv -> ExpSigmaType -> TcSigmaType -> TcM HsWrapper -- tcSubTypeET with the UserTypeCtxt specialised to GenSigCtxt diff --git a/compiler/GHC/Tc/Gen/Sig.hs b/compiler/GHC/Tc/Gen/Sig.hs index 4163d06f6f..161a0cbb1b 100644 --- a/compiler/GHC/Tc/Gen/Sig.hs +++ b/compiler/GHC/Tc/Gen/Sig.hs @@ -22,7 +22,7 @@ module GHC.Tc.Gen.Sig( TcPragEnv, emptyPragEnv, lookupPragEnv, extendPragEnv, mkPragEnv, tcSpecPrags, tcSpecWrapper, tcImpPrags, - addInlinePrags, addInlinePragArity + addInlinePrags, addInlinePragArity, addSpecRecPrags ) where import GHC.Prelude @@ -56,8 +56,7 @@ import GHC.Core.TyCo.Rep( mkNakedFunTy ) import GHC.Types.Error import GHC.Types.Var ( TyVar, Specificity(..), tyVarKind, binderVars, invisArgTypeLike ) -import GHC.Types.Id ( Id, idName, idType, setIdPragmaInfo - , mkLocalId, realIdUnfolding ) +import GHC.Types.Id import GHC.Types.Id.Info import GHC.Types.Basic import GHC.Types.Name @@ -592,6 +591,7 @@ mkPragEnv sigs binds get_sig sig@(L _ (SpecSig _ (L _ nm) _ _)) = Just (nm, add_arity nm sig) get_sig sig@(L _ (InlineSig _ (L _ nm) _)) = Just (nm, add_arity nm sig) get_sig sig@(L _ (SCCFunSig _ (L _ nm) _)) = Just (nm, sig) + get_sig sig@(L _ (SpecRecSig _ (L _ nm) _)) = Just (nm, sig) get_sig _ = Nothing add_arity n sig -- Adjust inl_sat field to match visible arity of function @@ -633,7 +633,7 @@ computePragmaInfo info (prag:prags) -- INLINEABLE + NOINLINE | NoInline{} <- new_spec , isDefaultActivationPragma old_prag - -> computePragmaInfo (mkPragInfo prag True) prags + -> computePragmaInfo (mkPragInfo prag True spec_rec) prags | otherwise -> Nothing NoInline{} -- NOINLINE + INLINEABLE @@ -645,12 +645,13 @@ computePragmaInfo info (prag:prags) Opaque{} -> Nothing NoUserInlinePrag -> computePragmaInfo - (mkPragInfo prag (isInlinablePragma prag)) + (mkPragInfo prag (isInlinablePragma prag) spec_rec) prags where old_prag = pragInfoInline $ info old_spec = inl_inline old_prag new_spec = inl_inline prag + spec_rec = pragSpecRec info @@ -659,7 +660,7 @@ addInlinePrags :: TcId -> [LSig GhcRn] -> TcM TcId addInlinePrags poly_id prags_for_me | inl@(L _ inl_prag) : inls <- inl_prags = do { traceTc "addInlinePrag" (ppr poly_id $$ ppr inl_prag) - ; let init_info = (mkPragInfo inl_prag $ isInlinablePragma inl_prag) + ; let init_info = mkPragInfo inl_prag (isInlinablePragma inl_prag) (idSpecRec poly_id) m_prag_info = computePragmaInfo init_info (map unLoc inls) @@ -687,6 +688,15 @@ addInlinePrags poly_id prags_for_me let dia = TcRnMultipleInlinePragmas poly_id inl1 (inl2 NE.:| inls) in addDiagnosticTc dia +----------------- +addSpecRecPrags :: TcId -> [LSig GhcRn] -> TcM TcId +addSpecRecPrags poly_id prags_for_me + = case spec_rec of + [] -> return poly_id + [L _ act] -> return $ setHasSpecRec poly_id (Just act) + (_:_) -> error "TODO: Duplicate SpecRec" + where + spec_rec = [L loc act | L loc (SpecRecSig _ _ act) <- prags_for_me] {- Note [Pattern synonym inline arity] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -829,7 +839,7 @@ tcSpecPrags poly_id prag_sigs where spec_sigs = filter isSpecLSig prag_sigs bad_sigs = filter is_bad_sig prag_sigs - is_bad_sig s = not (isSpecLSig s || isInlineLSig s || isSCCFunSig s) + is_bad_sig s = not (isSpecLSig s || isSpecRecLSig s || isInlineLSig s || isSCCFunSig s) warn_discarded_sigs bad_sigs_ne = let dia = TcRnUnexpectedPragmas poly_id bad_sigs_ne diff --git a/compiler/GHC/Tc/TyCl/Class.hs b/compiler/GHC/Tc/TyCl/Class.hs index 9da7b05192..03ac19e3f6 100644 --- a/compiler/GHC/Tc/TyCl/Class.hs +++ b/compiler/GHC/Tc/TyCl/Class.hs @@ -253,6 +253,7 @@ tcDefMeth clas tyvars this_dict binds_in hs_sig_fn prag_fn global_dm_id <- tcLookupId dm_name ; global_dm_id <- addInlinePrags global_dm_id prags + ; global_dm_id <- addSpecRecPrags global_dm_id prags ; local_dm_name <- newNameAt (getOccName sel_name) bndr_loc -- Base the local_dm_name on the selector name, because -- type errors from tcInstanceMethodBody come from here diff --git a/compiler/GHC/Tc/TyCl/Instance.hs b/compiler/GHC/Tc/TyCl/Instance.hs index f3980ed481..08d8f349e5 100644 --- a/compiler/GHC/Tc/TyCl/Instance.hs +++ b/compiler/GHC/Tc/TyCl/Instance.hs @@ -1900,6 +1900,7 @@ tcMethodBody clas tyvars dfun_ev_vars inst_tys tcMethodBodyHelp sig_fn sel_id local_meth_id (L bind_loc lm_bind) ; global_meth_id <- addInlinePrags global_meth_id prags + ; global_meth_id <- addSpecRecPrags global_meth_id prags ; spec_prags <- tcSpecPrags global_meth_id prags ; let specs = mk_meth_spec_prags global_meth_id spec_inst_prags spec_prags @@ -2113,7 +2114,11 @@ mkDefMethBind loc dfun_id clas sel_id dm_name = [] -- Copy the inline pragma (if any) from the default method -- to this version. Note [INLINE and default methods] - + spec_rec = idSpecRec dm_id + spec_rec_prag | Just act <- spec_rec + = [noLocA (SpecRecSig noAnn fn act)] + | otherwise + = [] fn = noLocA (idName sel_id) visible_inst_tys = [ ty | (tcb, ty) <- tyConBinders (classTyCon clas) `zip` inst_tys , tyConBinderForAllTyFlag tcb /= Inferred ] @@ -2127,7 +2132,7 @@ mkDefMethBind loc dfun_id clas sel_id dm_name (vcat [ppr clas <+> ppr inst_tys, nest 2 (ppr sel_id <+> equals <+> ppr rhs)])) - ; return (bind, inline_prags) } + ; return (bind, spec_rec_prag ++ inline_prags) } where (_, _, _, inst_tys) = tcSplitDFunTy (idType dfun_id) diff --git a/compiler/GHC/Tc/TyCl/PatSyn.hs b/compiler/GHC/Tc/TyCl/PatSyn.hs index 4c691185aa..3b6e6bceda 100644 --- a/compiler/GHC/Tc/TyCl/PatSyn.hs +++ b/compiler/GHC/Tc/TyCl/PatSyn.hs @@ -26,8 +26,7 @@ import GHC.Tc.Utils.TcMType import GHC.Tc.Utils.Zonk import GHC.Tc.Errors.Types import GHC.Tc.Utils.Monad -import GHC.Tc.Gen.Sig ( TcPragEnv, emptyPragEnv, completeSigFromId, lookupPragEnv - , addInlinePrags, addInlinePragArity ) +import GHC.Tc.Gen.Sig import GHC.Tc.Solver import GHC.Tc.Utils.Unify import GHC.Tc.Utils.TcType @@ -851,9 +850,11 @@ tcPatSynMatcher (L loc ps_name) lpat prag_fn -- Add INLINE pragmas; see Note [Pragmas for pattern synonyms] -- NB: prag_fn is keyed by the PatSyn Name, not the (internal) matcher name - ; matcher_prag_id <- addInlinePrags matcher_id $ - map (addInlinePragArity matcher_arity) $ - lookupPragEnv prag_fn ps_name + ; let prags = map (addInlinePragArity matcher_arity) $ + lookupPragEnv prag_fn ps_name + + ; matcher_prag_id <- addInlinePrags matcher_id prags + ; matcher_prag_id <- addSpecRecPrags matcher_prag_id prags ; let bind = FunBind{ fun_id = L loc matcher_prag_id , fun_matches = mg @@ -949,9 +950,11 @@ tcPatSynBuilderBind prag_fn (PSB { psb_id = ps_lname@(L loc ps_name) -- Add INLINE pragmas; see Note [Pragmas for pattern synonyms] -- NB: prag_fn is keyed by the PatSyn Name, not the (internal) builder name - ; builder_id <- addInlinePrags builder_id $ - map (addInlinePragArity builder_arity) $ - lookupPragEnv prag_fn ps_name + ; let prags = map (addInlinePragArity builder_arity) $ + lookupPragEnv prag_fn ps_name + ; builder_id <- addInlinePrags builder_id prags + ; builder_id <- addSpecRecPrags builder_id prags + ; let match_group' | need_dummy_arg = add_dummy_arg match_group | otherwise = match_group |