{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE LambdaCase #-} module GHC.Types.DefaultEnv ( ClassDefaults (..) , DefaultProvenance (..) , DefaultEnv , emptyDefaultEnv , isEmptyDefaultEnv , defaultEnv , unitDefaultEnv , lookupDefaultEnv , filterDefaultEnv , defaultList , plusDefaultEnv , mkDefaultEnv , insertDefaultEnv , isHaskell2010Default ) where import GHC.Core.Class (Class (className)) import GHC.Prelude import GHC.Hs.Extension (GhcRn) import GHC.Tc.Utils.TcType (Type) import GHC.Types.Name (Name, nameUnique, stableNameCmp) import GHC.Types.Name.Env import GHC.Types.Unique.FM (lookupUFM_Directly) import GHC.Types.SrcLoc (SrcSpan) import GHC.Unit.Module.Warnings (WarningTxt) import GHC.Unit.Types (Module) import GHC.Utils.Outputable import Data.Data (Data) import Data.List (sortBy) import Data.Function (on) -- See Note [Named default declarations] in GHC.Tc.Gen.Default -- | Default environment mapping class name @Name@ to their default type lists -- -- NB: this includes Haskell98 default declarations, at the 'Num' key. type DefaultEnv = NameEnv ClassDefaults {- Note [DefaultProvenance] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Each `ClassDefault` is annotated with its `DefaultProvenance`, which says where the default came from. Specifically * `DP_Local loc h98`: the default came from an explicit `default` declaration in the module being compiled, at location `loc`, and the boolean `h98` indicates whether it was from a Haskell 98 default declaration (e.g. `default (Int, Double)`). * `DP_Imported M`: the default was imported, it is explicitly exported by module `M`. * `DP_Builtin`: the default was automatically provided by GHC. see Note [Builtin class defaults] in GHC.Tc.Utils.Env These annotations are used to disambiguate multiple defaults for the same class. For example, consider the following modules: module M( default C ) where { default C( ... ) } module M2( default C) where { import M } module N( default C () where { default C(... ) } module A where { import M2 } module B where { import M2; import N } module A1 where { import N; default C ( ... ) } module B2 where { default C ( ... ); default C ( ... ) } When compiling N, the default for C is annotated with DP_Local loc. When compiling M2, the default for C is annotated with DP_Local M. When compiling A, the default for C is annotated with DP_Imported M2. Cases we needed to disambiguate: * Compiling B, two defaults for C: DP_Imported M2, DP_Imported N. * Compiling A1, two defaults for C: DP_Imported N, DP_Local loc. * Compiling B2, two defaults for C: DP_Local loc1, DP_Local loc2. For how we disambiguate these cases, See Note [Disambiguation of multiple default declarations] in GHC.Tc.Module. -} -- | The provenance of a collection of default types for a class. -- see Note [DefaultProvenance] for more details data DefaultProvenance -- | A locally defined default declaration. = DP_Local { defaultDeclLoc :: SrcSpan -- ^ The 'SrcSpan' of the default declaration , defaultDeclH98 :: Bool -- ^ Is this a Haskell 98 default declaration? } -- | Built-in class defaults. | DP_Builtin -- | Imported class defaults. | DP_Imported Module -- ^ The module from which the defaults were imported deriving (Eq, Data) instance Outputable DefaultProvenance where ppr (DP_Local loc h98) = ppr loc <> (if h98 then text " (H98)" else empty) ppr DP_Builtin = text "built-in" ppr (DP_Imported mod) = ppr mod isHaskell2010Default :: DefaultProvenance -> Bool isHaskell2010Default = \case DP_Local { defaultDeclH98 = isH98 } -> isH98 DP_Builtin -> True DP_Imported {} -> False -- | Defaulting type assignments for the given class. data ClassDefaults = ClassDefaults { cd_class :: Class -- ^ The class whose defaults are being defined , cd_types :: [Type] , cd_provenance :: DefaultProvenance -- ^ Where the defaults came from -- see Note [Default exports] in GHC.Tc.Gen.Export , cd_warn :: Maybe (WarningTxt GhcRn) -- ^ Warning emitted when the default is used } deriving Data instance Outputable ClassDefaults where ppr ClassDefaults {cd_class = cls, cd_types = tys} = text "default" <+> ppr cls <+> parens (interpp'SP tys) emptyDefaultEnv :: DefaultEnv emptyDefaultEnv = emptyNameEnv isEmptyDefaultEnv :: DefaultEnv -> Bool isEmptyDefaultEnv = isEmptyNameEnv unitDefaultEnv :: ClassDefaults -> DefaultEnv unitDefaultEnv d = unitNameEnv (className $ cd_class d) d defaultEnv :: [ClassDefaults] -> DefaultEnv defaultEnv = mkNameEnvWith (className . cd_class) defaultList :: DefaultEnv -> [ClassDefaults] defaultList = sortBy (stableNameCmp `on` className . cd_class) . nonDetNameEnvElts -- sortBy recovers determinism insertDefaultEnv :: ClassDefaults -> DefaultEnv -> DefaultEnv insertDefaultEnv d env = extendNameEnv env (className $ cd_class d) d lookupDefaultEnv :: DefaultEnv -> Name -> Maybe ClassDefaults lookupDefaultEnv env = lookupUFM_Directly env . nameUnique filterDefaultEnv :: (ClassDefaults -> Bool) -> DefaultEnv -> DefaultEnv filterDefaultEnv = filterNameEnv plusDefaultEnv :: DefaultEnv -> DefaultEnv -> DefaultEnv plusDefaultEnv = plusNameEnv -- | Create a 'DefaultEnv' from a list of (Name, ClassDefaults) pairs -- it is useful if we don't want to poke into the 'ClassDefaults' structure -- to get the 'Name' of the class, it can be problematic, see #25858 mkDefaultEnv :: [(Name, ClassDefaults)] -> DefaultEnv mkDefaultEnv = mkNameEnv