Florian Ragwitz pushed to branch wip/rafl/hpc-instances at Glasgow Haskell Compiler / GHC
Commits:
-
5dd9f195
by Florian Ragwitz at 2026-10-07T11:04:51-07:00
-
1e0330f0
by Florian Ragwitz at 2026-10-07T11:04:51-07:00
10 changed files:
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/HsToCore.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Types/Id/Info.hs
- testsuite/tests/hpc/instmeths/instmeths.stdout
Changes:
| ... | ... | @@ -3082,6 +3082,7 @@ wantCallsFor _env f |
| 3082 | 3082 | JoinId {} -> True
|
| 3083 | 3083 | WorkerLikeId {} -> True
|
| 3084 | 3084 | RepPolyId {} -> True
|
| 3085 | + InstMethId {} -> True
|
|
| 3085 | 3086 | |
| 3086 | 3087 | interestingDict :: SpecEnv -> CoreExpr -> Bool
|
| 3087 | 3088 | -- This is a subtle and important function
|
| ... | ... | @@ -453,6 +453,7 @@ toIfaceTopBndr id |
| 453 | 453 | |
| 454 | 454 | toIfaceIdDetails :: IdDetails -> IfaceIdDetails
|
| 455 | 455 | toIfaceIdDetails VanillaId = IfVanillaId
|
| 456 | +toIfaceIdDetails (InstMethId {}) = IfVanillaId
|
|
| 456 | 457 | toIfaceIdDetails (WorkerLikeId dmds) = IfWorkerLikeId dmds
|
| 457 | 458 | toIfaceIdDetails (DFunId {}) = IfDFunId
|
| 458 | 459 | toIfaceIdDetails (RecSelId { sel_naughty = n
|
| ... | ... | @@ -147,7 +147,6 @@ deSugar hsc_env |
| 147 | 147 | tcg_tcs = tcs,
|
| 148 | 148 | tcg_default_exports = defaults,
|
| 149 | 149 | tcg_insts = insts,
|
| 150 | - tcg_inst_meths = inst_meths,
|
|
| 151 | 150 | tcg_fam_insts = fam_insts,
|
| 152 | 151 | tcg_complete_matches = complete_matches,
|
| 153 | 152 | tcg_self_boot = self_boot
|
| ... | ... | @@ -172,7 +171,7 @@ deSugar hsc_env |
| 172 | 171 | (initTicksConfig (hsc_dflags hsc_env))
|
| 173 | 172 | mod mod_loc
|
| 174 | 173 | export_set (typeEnvTyCons type_env)
|
| 175 | - insts inst_meths binds
|
|
| 174 | + insts binds
|
|
| 176 | 175 | else return (binds, Nothing)
|
| 177 | 176 | ; let modBreaks
|
| 178 | 177 | | Just (_, _, breakpointSpecs) <- m_tickInfo
|
| 1 | -{-# LANGUAGE NondecreasingIndentation, DataKinds #-}
|
|
| 1 | +{-# LANGUAGE NondecreasingIndentation, DataKinds, ViewPatterns #-}
|
|
| 2 | 2 | |
| 3 | 3 | {-# OPTIONS_GHC -Wno-incomplete-record-updates #-}
|
| 4 | 4 | |
| ... | ... | @@ -45,12 +45,12 @@ import GHC.Types.Var.Set |
| 45 | 45 | import GHC.Types.Var.Env
|
| 46 | 46 | import GHC.Types.Name.Set
|
| 47 | 47 | import GHC.Types.Name
|
| 48 | +import GHC.Types.Name.Env
|
|
| 48 | 49 | import GHC.Types.CostCentre
|
| 49 | 50 | import GHC.Types.CostCentre.State
|
| 50 | 51 | import GHC.Types.Tickish
|
| 51 | 52 | import GHC.Types.ProfAuto
|
| 52 | 53 | import GHC.Tc.Types.ErrCtxt
|
| 53 | -import GHC.Tc.Utils.TcType
|
|
| 54 | 54 | |
| 55 | 55 | import Control.Monad
|
| 56 | 56 | import Data.List (isSuffixOf, intersperse)
|
| ... | ... | @@ -105,14 +105,11 @@ addTicksToBinds |
| 105 | 105 | -- hasn't set it), so we have to work from this set.
|
| 106 | 106 | -> [TyCon] -- ^ Type constructors in this module
|
| 107 | 107 | -> [ClsInst] -- ^ Class instances in this module
|
| 108 | - -> IdEnv DFunId -- ^ Mapping from class method Ids to the DFunIds
|
|
| 109 | - -- of the class instance they belong to. See Note
|
|
| 110 | - -- [Instance Method Coverage].
|
|
| 111 | 108 | -> LHsBinds GhcTc
|
| 112 | 109 | -> IO (LHsBinds GhcTc, Maybe (FilePath, SizedSeq Tick, SizedSeq Tick))
|
| 113 | 110 | |
| 114 | 111 | addTicksToBinds logger cfg
|
| 115 | - mod mod_loc exports tyCons insts inst_meths binds
|
|
| 112 | + mod mod_loc exports tyCons insts binds
|
|
| 116 | 113 | | let passes = ticks_passes cfg
|
| 117 | 114 | , not (null passes)
|
| 118 | 115 | , Just orig_file <- ml_hs_file mod_loc = do
|
| ... | ... | @@ -137,8 +134,8 @@ addTicksToBinds logger cfg |
| 137 | 134 | , this_mod = mod
|
| 138 | 135 | , tickishType = tickish
|
| 139 | 136 | , recSelBinds = emptyVarEnv
|
| 140 | - , instMeths = inst_meths
|
|
| 141 | - , instTicks = emptyVarEnv
|
|
| 137 | + , instMeths = emptyVarEnv
|
|
| 138 | + , instTicks = emptyNameEnv
|
|
| 142 | 139 | }
|
| 143 | 140 | addTick = do
|
| 144 | 141 | instTicks <- allocInstTicks insts
|
| ... | ... | @@ -276,7 +273,9 @@ addTickLHsBind (L pos (XHsBindsLR bind@(AbsBinds { abs_binds = binds |
| 276 | 273 | env{ instMeths = instMeths env `extendVarEnvList`
|
| 277 | 274 | [ (abe_mono, dfun)
|
| 278 | 275 | | ABE{ abe_poly, abe_mono } <- abs_exports
|
| 279 | - , Just dfun <- [lookupVarEnv (instMeths env) abe_poly] ] }
|
|
| 276 | + , Just dfun <- [instMeth abe_poly] ] }
|
|
| 277 | + where instMeth (idDetails -> InstMethId dfun) = Just dfun
|
|
| 278 | + instMeth id = lookupVarEnv (instMeths env) id
|
|
| 280 | 279 | |
| 281 | 280 | addTickLHsBind (L pos (funBind@(FunBind { fun_id = L _ id, fun_matches = matches }))) = do
|
| 282 | 281 | let name = getOccString id
|
| ... | ... | @@ -375,11 +374,9 @@ addTickLHsBind (L pos (funBind@(FunBind { fun_id = L _ id, fun_matches = matches |
| 375 | 374 | -- inherited and hand-written, we need to go out of our way to create top-level
|
| 376 | 375 | -- tick boxes only for methods which correspond to user-written code.
|
| 377 | 376 | --
|
| 378 | --- To do so, 'addTicksToBinds' receives a mapping from class instance 'Id's to
|
|
| 379 | --- the 'DFunId's of the dictionary backing the associated instance. When
|
|
| 380 | --- creating tick boxes for top-level bindings, we can then decide if a given
|
|
| 381 | --- 'FunBind' corresponds to an inherited/generated instance method of a class
|
|
| 382 | --- and skip creating the tick box for it.
|
|
| 377 | +-- Instance method 'Id's carry the name of the 'DFunId' of the instance they
|
|
| 378 | +-- belong to. When creating tick boxes for top-level bindings, we can use this
|
|
| 379 | +-- information to skip creating boxes for inherited/generated instance methods.
|
|
| 383 | 380 | --
|
| 384 | 381 | -- Additionally, we also want to inform the user whether or not their class
|
| 385 | 382 | -- instance as a whole has been used at run-time. To do so, we create a single
|
| ... | ... | @@ -1152,8 +1149,8 @@ data TickTransEnv = TTE { fileName :: FastString |
| 1152 | 1149 | , this_mod :: Module
|
| 1153 | 1150 | , tickishType :: TickishType
|
| 1154 | 1151 | , recSelBinds :: IdEnv DVarSet
|
| 1155 | - , instMeths :: IdEnv DFunId
|
|
| 1156 | - , instTicks :: IdEnv CoreTickish
|
|
| 1152 | + , instMeths :: IdEnv Name
|
|
| 1153 | + , instTicks :: NameEnv CoreTickish
|
|
| 1157 | 1154 | }
|
| 1158 | 1155 | |
| 1159 | 1156 | -- deriving Show
|
| ... | ... | @@ -1295,19 +1292,18 @@ isBlackListed GeneratedSrcSpan{} = return False |
| 1295 | 1292 | isBlackListed UnhelpfulSpan{} = return False
|
| 1296 | 1293 | |
| 1297 | 1294 | -- See Note [Instance Method Coverage].
|
| 1298 | -allocInstTicks :: [ClsInst] -> TM (IdEnv CoreTickish)
|
|
| 1295 | +allocInstTicks :: [ClsInst] -> TM (NameEnv CoreTickish)
|
|
| 1299 | 1296 | allocInstTicks insts =
|
| 1300 | - ifDensity TickForCoverage (mkVarEnv . catMaybes <$> mapM alloc insts) (pure emptyVarEnv)
|
|
| 1297 | + ifDensity TickForCoverage (mkNameEnv . catMaybes <$> mapM alloc insts) (pure emptyNameEnv)
|
|
| 1301 | 1298 | where
|
| 1302 | 1299 | alloc ClsInst{ is_dfun, is_cls }
|
| 1303 | 1300 | | null (classMethods is_cls) = pure Nothing
|
| 1304 | - | otherwise = fmap (is_dfun,) <$> allocATickBox (TopLevelBox [s])
|
|
| 1305 | - False True (getSrcSpan is_dfun) noFVs
|
|
| 1306 | - where s = showSDocOneLine defaultSDocContext (pprSigmaType (idType is_dfun))
|
|
| 1301 | + | otherwise = fmap (idName is_dfun,) <$> allocATickBox (TopLevelBox [getOccString is_dfun])
|
|
| 1302 | + False True (getSrcSpan is_dfun) noFVs
|
|
| 1307 | 1303 | |
| 1308 | 1304 | -- See Note [Instance Method Coverage].
|
| 1309 | 1305 | instMethTick :: Id -> TM (Maybe CoreTickish)
|
| 1310 | -instMethTick id = getEnv <&> \e -> lookupVarEnv (instMeths e) id >>= lookupVarEnv (instTicks e)
|
|
| 1306 | +instMethTick id = getEnv <&> \e -> lookupVarEnv (instMeths e) id >>= lookupNameEnv (instTicks e)
|
|
| 1311 | 1307 | |
| 1312 | 1308 | -- the tick application inherits the source position of its
|
| 1313 | 1309 | -- expression argument to support nested box allocations
|
| ... | ... | @@ -1768,7 +1768,7 @@ tcTopSrcDecls (HsGroup { hs_tyclds = tycl_decls, |
| 1768 | 1768 | -- Second pass over class and instance declarations,
|
| 1769 | 1769 | -- now using the kind-checked decls
|
| 1770 | 1770 | traceTc "Tc6" empty ;
|
| 1771 | - (inst_binds, inst_meths) <- tcInstDecls2 (tyClGroupTyClDecls tycl_decls) inst_infos ;
|
|
| 1771 | + inst_binds <- tcInstDecls2 (tyClGroupTyClDecls tycl_decls) inst_infos ;
|
|
| 1772 | 1772 | |
| 1773 | 1773 | -- Foreign exports
|
| 1774 | 1774 | traceTc "Tc7" empty ;
|
| ... | ... | @@ -1800,9 +1800,8 @@ tcTopSrcDecls (HsGroup { hs_tyclds = tycl_decls, |
| 1800 | 1800 | , tcg_anns = tcg_anns tcg_env ++ annotations
|
| 1801 | 1801 | , tcg_ann_env = extendAnnEnvList (tcg_ann_env tcg_env) annotations
|
| 1802 | 1802 | , tcg_fords = tcg_fords tcg_env ++ foe_decls ++ fi_decls
|
| 1803 | - , tcg_dus = tcg_dus tcg_env `plusDU` usesOnly fo_fvs
|
|
| 1803 | + , tcg_dus = tcg_dus tcg_env `plusDU` usesOnly fo_fvs } } ;
|
|
| 1804 | 1804 | -- tcg_dus: see Note [Newtype constructor usage in foreign declarations]
|
| 1805 | - , tcg_inst_meths = tcg_inst_meths tcg_env `plusVarEnv` inst_meths } } ;
|
|
| 1806 | 1805 | |
| 1807 | 1806 | -- See Note [Newtype constructor usage in foreign declarations]
|
| 1808 | 1807 | addUsedGREs NoDeprecationWarnings (bagToList fo_gres) ;
|
| ... | ... | @@ -59,7 +59,7 @@ import GHC.Core.FamInstEnv |
| 59 | 59 | import GHC.Core.Type
|
| 60 | 60 | import GHC.Core.Multiplicity
|
| 61 | 61 | import GHC.Core.InstEnv
|
| 62 | -import GHC.Core.Predicate( classMethodInstTy )
|
|
| 62 | +import GHC.Core.Predicate( classMethodInstTy, isCoVarType )
|
|
| 63 | 63 | import GHC.Core.TyCon
|
| 64 | 64 | import GHC.Core.Coercion.Axiom
|
| 65 | 65 | import GHC.Core.DataCon
|
| ... | ... | @@ -72,6 +72,7 @@ import GHC.Types.Var.Set |
| 72 | 72 | import GHC.Types.Basic
|
| 73 | 73 | import GHC.Types.ForeignCall ( typeCheckCType )
|
| 74 | 74 | import GHC.Types.Id
|
| 75 | +import GHC.Types.Id.Info
|
|
| 75 | 76 | import GHC.Types.InlinePragma
|
| 76 | 77 | import GHC.Types.SourceFile
|
| 77 | 78 | import GHC.Types.SourceText
|
| ... | ... | @@ -1285,7 +1286,7 @@ takes a slightly different approach. |
| 1285 | 1286 | ********************************************************************* -}
|
| 1286 | 1287 | |
| 1287 | 1288 | tcInstDecls2 :: [LTyClDecl GhcRn] -> [InstInfo GhcRn]
|
| 1288 | - -> TcM (LHsBinds GhcTc, IdEnv DFunId)
|
|
| 1289 | + -> TcM (LHsBinds GhcTc)
|
|
| 1289 | 1290 | -- (a) From each class declaration,
|
| 1290 | 1291 | -- generate any default-method bindings
|
| 1291 | 1292 | -- (b) From each instance decl
|
| ... | ... | @@ -1302,11 +1303,11 @@ tcInstDecls2 tycl_decls inst_decls |
| 1302 | 1303 | -- Add the default method Ids (again)
|
| 1303 | 1304 | -- (they were already added in GHC.Tc.TyCl.Utils.tcAddImplicits)
|
| 1304 | 1305 | -- See Note [Default methods in the type environment]
|
| 1305 | - ; (inst_binds_s, inst_meths_s) <- unzip <$> (tcExtendGlobalValEnv dm_ids $
|
|
| 1306 | - mapM tcInstDecl2 inst_decls)
|
|
| 1306 | + ; inst_binds_s <- tcExtendGlobalValEnv dm_ids $
|
|
| 1307 | + mapM tcInstDecl2 inst_decls
|
|
| 1307 | 1308 | |
| 1308 | 1309 | -- Done
|
| 1309 | - ; return (dm_binds ++ concat inst_binds_s, plusVarEnvList inst_meths_s) }
|
|
| 1310 | + ; return (dm_binds ++ concat inst_binds_s) }
|
|
| 1310 | 1311 | |
| 1311 | 1312 | {- Note [Default methods in the type environment]
|
| 1312 | 1313 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -1322,12 +1323,12 @@ So right here in tcInstDecls2 we must re-extend the type envt with |
| 1322 | 1323 | the default method Ids replete with their INLINE pragmas. Urk.
|
| 1323 | 1324 | -}
|
| 1324 | 1325 | |
| 1325 | -tcInstDecl2 :: InstInfo GhcRn -> TcM (LHsBinds GhcTc, IdEnv DFunId)
|
|
| 1326 | +tcInstDecl2 :: InstInfo GhcRn -> TcM (LHsBinds GhcTc)
|
|
| 1326 | 1327 | -- Returns a binding for the dfun
|
| 1327 | 1328 | tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = ibinds })
|
| 1328 | - = recoverM (return (emptyLHsBinds, emptyVarEnv)) $
|
|
| 1329 | - setSrcSpan loc $
|
|
| 1330 | - addErrCtxt (instDeclCtxt2 dfun_ty) $
|
|
| 1329 | + = recoverM (return emptyLHsBinds) $
|
|
| 1330 | + setSrcSpan loc $
|
|
| 1331 | + addErrCtxt (instDeclCtxt2 dfun_ty) $
|
|
| 1331 | 1332 | do { -- Instantiate the instance decl with skolem constants
|
| 1332 | 1333 | (skol_info, inst_tyvars, dfun_theta, clas, inst_tys) <- tcSkolDFunType dfun_ty
|
| 1333 | 1334 | ; dfun_ev_vars <- newEvVars dfun_theta
|
| ... | ... | @@ -1345,7 +1346,7 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = ibinds }) |
| 1345 | 1346 | -- See Note [Typechecking plan for instance declarations]
|
| 1346 | 1347 | ; dfun_ev_binds_var <- newTcEvBinds
|
| 1347 | 1348 | ; let dfun_ev_binds = TcEvBinds dfun_ev_binds_var
|
| 1348 | - ; (tclvl, (sc_meth_ids, sc_meth_binds, sc_meth_implics, meth_ids))
|
|
| 1349 | + ; (tclvl, (sc_meth_ids, sc_meth_binds, sc_meth_implics))
|
|
| 1349 | 1350 | <- pushTcLevelM $
|
| 1350 | 1351 | do { (sc_ids, sc_binds, sc_implics)
|
| 1351 | 1352 | <- tcSuperClasses skol_info dfun_id clas inst_tyvars
|
| ... | ... | @@ -1359,8 +1360,7 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = ibinds }) |
| 1359 | 1360 | |
| 1360 | 1361 | ; return ( sc_ids ++ meth_ids
|
| 1361 | 1362 | , sc_binds ++ meth_binds
|
| 1362 | - , sc_implics `unionBags` meth_implics
|
|
| 1363 | - , meth_ids ) }
|
|
| 1363 | + , sc_implics `unionBags` meth_implics ) }
|
|
| 1364 | 1364 | |
| 1365 | 1365 | ; imp <- newImplication
|
| 1366 | 1366 | ; emitImplication $
|
| ... | ... | @@ -1417,7 +1417,7 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = ibinds }) |
| 1417 | 1417 | , abs_binds = [dict_bind]
|
| 1418 | 1418 | , abs_sig = True }
|
| 1419 | 1419 | |
| 1420 | - ; return (L loc' main_bind : sc_meth_binds, mkVarEnv $ (,dfun_id) <$> meth_ids)
|
|
| 1420 | + ; return (L loc' main_bind : sc_meth_binds)
|
|
| 1421 | 1421 | }
|
| 1422 | 1422 | where
|
| 1423 | 1423 | dfun_id = instanceDFunId ispec
|
| ... | ... | @@ -1860,7 +1860,7 @@ tcMethods _skol_info dfun_id clas tyvars dfun_ev_vars inst_tys |
| 1860 | 1860 | tc_item :: ClassOpItem -> TcM (Id, LHsBind GhcTc, Maybe Implication)
|
| 1861 | 1861 | tc_item (sel_id, dm_info)
|
| 1862 | 1862 | | Just (user_bind, bndr_loc, prags) <- findMethodBind (idName sel_id) binds prag_fn
|
| 1863 | - = tcMethodBody False clas tyvars dfun_ev_vars inst_tys
|
|
| 1863 | + = tcMethodBody False dfun_id clas tyvars dfun_ev_vars inst_tys
|
|
| 1864 | 1864 | dfun_ev_binds is_derived hs_sig_fn
|
| 1865 | 1865 | spec_inst_prags prags
|
| 1866 | 1866 | sel_id user_bind bndr_loc
|
| ... | ... | @@ -1880,7 +1880,7 @@ tcMethods _skol_info dfun_id clas tyvars dfun_ev_vars inst_tys |
| 1880 | 1880 | -- See Note [Implementation of Unsatisfiable constraints],
|
| 1881 | 1881 | -- in GHC.Tc.Errors, point (D).
|
| 1882 | 1882 | _ | (theta_id,unsat_msg) : _ <- unsat_thetas
|
| 1883 | - -> do { (meth_id, _) <- mkMethIds clas tyvars dfun_ev_vars
|
|
| 1883 | + -> do { (meth_id, _) <- mkMethIds dfun_id clas tyvars dfun_ev_vars
|
|
| 1884 | 1884 | inst_tys sel_id
|
| 1885 | 1885 | ; unsat_id <- tcLookupKnownKeyId unsatisfiableIdKey
|
| 1886 | 1886 | -- Recall that unsatisfiable :: forall {rep} (msg :: ErrorMessage) (a :: TYPE rep). Unsatisfiable msg => a
|
| ... | ... | @@ -1897,7 +1897,7 @@ tcMethods _skol_info dfun_id clas tyvars dfun_ev_vars inst_tys |
| 1897 | 1897 | Just (dm_name, dm_spec) ->
|
| 1898 | 1898 | do { (meth_bind, inline_prags) <- mkDefMethBind inst_loc dfun_id clas sel_id dm_name dm_spec
|
| 1899 | 1899 | ; tcMethodBody (is_vanilla_dm dm_spec)
|
| 1900 | - clas tyvars dfun_ev_vars inst_tys
|
|
| 1900 | + dfun_id clas tyvars dfun_ev_vars inst_tys
|
|
| 1901 | 1901 | dfun_ev_binds is_derived hs_sig_fn
|
| 1902 | 1902 | spec_inst_prags inline_prags
|
| 1903 | 1903 | sel_id meth_bind inst_loc }
|
| ... | ... | @@ -1905,7 +1905,7 @@ tcMethods _skol_info dfun_id clas tyvars dfun_ev_vars inst_tys |
| 1905 | 1905 | -- No default method
|
| 1906 | 1906 | Nothing ->
|
| 1907 | 1907 | do { traceTc "tc_def: warn" (ppr sel_id)
|
| 1908 | - ; (meth_id, _) <- mkMethIds clas tyvars dfun_ev_vars
|
|
| 1908 | + ; (meth_id, _) <- mkMethIds dfun_id clas tyvars dfun_ev_vars
|
|
| 1909 | 1909 | inst_tys sel_id
|
| 1910 | 1910 | ; dflags <- getDynFlags
|
| 1911 | 1911 | -- Add a binding whose RHS is an error
|
| ... | ... | @@ -2031,13 +2031,13 @@ Instead, we take the following approach: |
| 2031 | 2031 | tcMethodBody :: Bool -- True <=> This is a vanilla default method
|
| 2032 | 2032 | -- See (TRC5) in Note [Tracking needed EvIds]
|
| 2033 | 2033 | -- in GHC.Tc.Solver.Solve
|
| 2034 | - -> Class -> [TcTyVar] -> [EvVar] -> [TcType]
|
|
| 2034 | + -> DFunId -> Class -> [TcTyVar] -> [EvVar] -> [TcType]
|
|
| 2035 | 2035 | -> TcEvBinds -> Bool
|
| 2036 | 2036 | -> HsSigFun
|
| 2037 | 2037 | -> [LTcSpecPrag] -> [LSig GhcRn]
|
| 2038 | 2038 | -> Id -> LHsBind GhcRn -> SrcSpan
|
| 2039 | 2039 | -> TcM (TcId, LHsBind GhcTc, Maybe Implication)
|
| 2040 | -tcMethodBody is_vanilla_dm clas tyvars dfun_ev_vars inst_tys
|
|
| 2040 | +tcMethodBody is_vanilla_dm dfun_id clas tyvars dfun_ev_vars inst_tys
|
|
| 2041 | 2041 | dfun_ev_binds is_derived
|
| 2042 | 2042 | sig_fn spec_inst_prags prags
|
| 2043 | 2043 | sel_id (L bind_loc meth_bind) bndr_loc
|
| ... | ... | @@ -2045,7 +2045,7 @@ tcMethodBody is_vanilla_dm clas tyvars dfun_ev_vars inst_tys |
| 2045 | 2045 | do { traceTc "tcMethodBody" (ppr sel_id <+> ppr (idType sel_id) $$ ppr bndr_loc)
|
| 2046 | 2046 | ; let skol_info = MethSkol meth_name is_vanilla_dm
|
| 2047 | 2047 | ; (global_meth_id, local_meth_id) <- setSrcSpan bndr_loc $
|
| 2048 | - mkMethIds clas tyvars dfun_ev_vars
|
|
| 2048 | + mkMethIds dfun_id clas tyvars dfun_ev_vars
|
|
| 2049 | 2049 | inst_tys sel_id
|
| 2050 | 2050 | |
| 2051 | 2051 | ; let lm_bind = meth_bind { fun_id = L (noAnnSrcSpan bndr_loc)
|
| ... | ... | @@ -2163,16 +2163,19 @@ tcMethodBodyHelp hs_sig_fn sel_id local_meth_id meth_bind |
| 2163 | 2163 | -- they are all for meth_id
|
| 2164 | 2164 | |
| 2165 | 2165 | ------------------------
|
| 2166 | -mkMethIds :: Class -> [TcTyVar] -> [EvVar]
|
|
| 2166 | +mkMethIds :: DFunId -> Class -> [TcTyVar] -> [EvVar]
|
|
| 2167 | 2167 | -> [TcType] -> Id -> TcM (TcId, TcId)
|
| 2168 | 2168 | -- returns (poly_id, local_id), but ignoring any instance signature
|
| 2169 | 2169 | -- See Note [Instance method signatures]
|
| 2170 | -mkMethIds clas tyvars dfun_ev_vars inst_tys sel_id
|
|
| 2170 | +mkMethIds dfun_id clas tyvars dfun_ev_vars inst_tys sel_id
|
|
| 2171 | 2171 | = do { poly_meth_name <- newName (mkClassOpAuxOcc sel_occ)
|
| 2172 | 2172 | ; local_meth_name <- newName sel_occ
|
| 2173 | 2173 | -- Base the local_meth_name on the selector name, because
|
| 2174 | 2174 | -- type errors from tcMethodBody come from here
|
| 2175 | - ; let poly_meth_id = mkLocalId poly_meth_name ManyTy poly_meth_ty
|
|
| 2175 | + ; let poly_meth_id =
|
|
| 2176 | + assert (not (isCoVarType poly_meth_ty)) $
|
|
| 2177 | + Var.mkLocalVar (InstMethId (idName dfun_id))
|
|
| 2178 | + poly_meth_name ManyTy poly_meth_ty vanillaIdInfo
|
|
| 2176 | 2179 | local_meth_id = mkLocalId local_meth_name ManyTy local_meth_ty
|
| 2177 | 2180 | |
| 2178 | 2181 | ; return (poly_meth_id, local_meth_id) }
|
| ... | ... | @@ -158,7 +158,6 @@ import GHC.Types.Name.Env |
| 158 | 158 | import GHC.Types.Name.Set
|
| 159 | 159 | import GHC.Types.Avail
|
| 160 | 160 | import GHC.Types.Var
|
| 161 | -import GHC.Types.Var.Env
|
|
| 162 | 161 | import GHC.Types.TypeEnv
|
| 163 | 162 | import GHC.Types.SourceFile
|
| 164 | 163 | import GHC.Types.SrcLoc
|
| ... | ... | @@ -532,9 +531,6 @@ data TcGblEnv |
| 532 | 531 | -- NB. BangPattern is to fix a leak, see #15111
|
| 533 | 532 | tcg_fam_inst_env :: !FamInstEnv, -- ^ Ditto for family instances
|
| 534 | 533 | -- NB. BangPattern is to fix a leak, see #15111
|
| 535 | - tcg_inst_meths :: IdEnv DFunId,
|
|
| 536 | - -- ^ Maps instance method Ids to the DFunId of the instance they belong to.
|
|
| 537 | - -- See Note [Instance Method Coverage] in GHC.HsToCore.Ticks.
|
|
| 538 | 534 | tcg_ann_env :: AnnEnv, -- ^ And for annotations
|
| 539 | 535 | tcg_complete_match_env :: CompleteMatches,
|
| 540 | 536 | -- ^ The complete matches for all /home-package/ modules;
|
| ... | ... | @@ -409,7 +409,6 @@ initTcGblEnv hsc_env hsc_src keep_rn_syntax mod loc = |
| 409 | 409 | , tcg_knot_vars = hsc_type_env_vars hsc_env
|
| 410 | 410 | , tcg_known_key_maps = known_key_maps_var
|
| 411 | 411 | , tcg_inst_env = emptyInstEnv
|
| 412 | - , tcg_inst_meths = emptyVarEnv
|
|
| 413 | 412 | , tcg_fam_inst_env = emptyFamInstEnv
|
| 414 | 413 | , tcg_ann_env = emptyAnnEnv
|
| 415 | 414 | , tcg_complete_match_env = []
|
| ... | ... | @@ -222,6 +222,9 @@ data IdDetails |
| 222 | 222 | -- - the [CbvMark] is always empty (and ignored) until after Tidy
|
| 223 | 223 | -- for ids from the current module
|
| 224 | 224 | -- - If non-empty, at least is isMarkedCbbv; see (CBV2)
|
| 225 | + | InstMethId Name
|
|
| 226 | + -- ^ An instance method. The 'Name' identifies the dictionary of the
|
|
| 227 | + -- instance it belongs to.
|
|
| 225 | 228 | |
| 226 | 229 | data RecSelInfo
|
| 227 | 230 | = RSI { rsi_def :: [ConLike] -- Record selector defined for these
|
| ... | ... | @@ -449,6 +452,7 @@ pprIdDetails other = brackets (pp other) |
| 449 | 452 | ppWhen is_naughty (text "(naughty)")
|
| 450 | 453 | pp CoVarId = text "CoVarId"
|
| 451 | 454 | pp (JoinId arity marks) = text "JoinId" <> parens (int arity) <> parens (ppr marks)
|
| 455 | + pp (InstMethId name) = text "InstMethId" <> parens (ppr name)
|
|
| 452 | 456 | |
| 453 | 457 | {-
|
| 454 | 458 | ************************************************************************
|
| 1 | 1 | True
|
| 2 | 2 | "Foo (T' a) instance"
|
| 3 | -(1,"Eq a => Eq (T a)","Eq")
|
|
| 4 | -(0,"Foo (T a)","Foo (T a)")
|
|
| 5 | -(1,"Foo (T' a)","Foo (T' a)")
|
|
| 6 | -(1,"Functor T","Functor")
|
|
| 7 | -(0,"Show a => Show (T a)","Show")
|
|
| 3 | +(1,"$fEqT","Eq")
|
|
| 4 | +(0,"$fFooT","Foo (T a)")
|
|
| 5 | +(1,"$fFooT'","Foo (T' a)")
|
|
| 6 | +(1,"$fFunctorT","Functor")
|
|
| 7 | +(0,"$fShowT","Show")
|
|
| 8 | 8 | (0,"defMeth","defMeth = const \"class default\"")
|
| 9 | 9 | (0,"defMeth","defMeth = const \"Foo (T' a) instance\"")
|
| 10 | 10 | (0,"defMeth'","defMeth' = const \"class default\"")
|