{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}

module Language.Haskell.Liquid.GHC.Plugin.Types
    ( SpecComment(..)

    -- * Dealing with specs and their dependencies
    , LiquidLib
    , mkLiquidLib
    , libTarget
    , libDeps
    , allDeps
    , addLibDependencies

    -- * Caching specs into interfaces
    , CachedSpec
    , toCached
    , cachedSpecStableModuleId
    , cachedSpecModule
    , fromCached

    -- * Merging specs together
    , InputSpec
    , CompanionSpec
    , LiquidSpec
    , downcastSpec
    , mkInputSpec
    , mkCompanionSpec
    , mergeInputWithCompanion

    -- * Carrying data across stages of the compilation pipeline
    , PipelineData(..)

    -- * Acquiring and manipulating data from the typechecking phase
    , TcData
    , tcAllImports
    , tcQualifiedImports
    , tcResolvedNames
    , tcAvailableTyCons
    , tcAvailableVars
    , mkTcData

    -- * Wrapper type to talk about unoptimised things
    , Unoptimised(fromUnoptimised)
    , toUnoptimised
    ) where

import           Data.Binary                             as B
import           Data.Data                                ( Data )
import           Data.Foldable
import           Outputable                        hiding ( (<>) )
import           GHC.Generics                      hiding ( moduleName )
import           HscTypes                                 (ModGuts)
import           GHC                                      ( Name
                                                          , TyThing
                                                          , TyCon
                                                          , LImportDecl
                                                          , GhcRn
                                                          )
import           Var                                      ( Var )
import           Module                                   ( Module, moduleStableString )

import qualified Data.HashSet        as HS
import           Data.Hashable

import           Language.Fixpoint.Types.Spans
import           Language.Haskell.Liquid.Types.Specs
import qualified Language.Haskell.Liquid.GHC.Interface   as LH
import           Language.Fixpoint.Types.Names            ( Symbol )


data LiquidLib = LiquidLib
  {  LiquidLib -> LiftedSpec
llTarget :: LiftedSpec
  -- ^ The target /LiftedSpec/.
  ,  LiquidLib -> TargetDependencies
llDeps   :: TargetDependencies
  -- ^ The specs which were necessary to produce the target 'BareSpec'.
  } deriving (Int -> LiquidLib -> ShowS
[LiquidLib] -> ShowS
LiquidLib -> String
(Int -> LiquidLib -> ShowS)
-> (LiquidLib -> String)
-> ([LiquidLib] -> ShowS)
-> Show LiquidLib
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LiquidLib] -> ShowS
$cshowList :: [LiquidLib] -> ShowS
show :: LiquidLib -> String
$cshow :: LiquidLib -> String
showsPrec :: Int -> LiquidLib -> ShowS
$cshowsPrec :: Int -> LiquidLib -> ShowS
Show, (forall x. LiquidLib -> Rep LiquidLib x)
-> (forall x. Rep LiquidLib x -> LiquidLib) -> Generic LiquidLib
forall x. Rep LiquidLib x -> LiquidLib
forall x. LiquidLib -> Rep LiquidLib x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep LiquidLib x -> LiquidLib
$cfrom :: forall x. LiquidLib -> Rep LiquidLib x
Generic)

instance B.Binary LiquidLib

-- | Creates a new 'LiquidLib' with no dependencies.
mkLiquidLib :: LiftedSpec -> LiquidLib
mkLiquidLib :: LiftedSpec -> LiquidLib
mkLiquidLib LiftedSpec
s = LiftedSpec -> TargetDependencies -> LiquidLib
LiquidLib LiftedSpec
s TargetDependencies
forall a. Monoid a => a
mempty

-- | Adds a set of dependencies to the input 'LiquidLib'.
addLibDependencies :: TargetDependencies -> LiquidLib -> LiquidLib
addLibDependencies :: TargetDependencies -> LiquidLib -> LiquidLib
addLibDependencies TargetDependencies
deps LiquidLib
lib = LiquidLib
lib { llDeps :: TargetDependencies
llDeps = TargetDependencies
deps TargetDependencies -> TargetDependencies -> TargetDependencies
forall a. Semigroup a => a -> a -> a
<> (LiquidLib -> TargetDependencies
llDeps LiquidLib
lib) }

-- | Returns the target 'LiftedSpec' of this 'LiquidLib'.
libTarget :: LiquidLib -> LiftedSpec
libTarget :: LiquidLib -> LiftedSpec
libTarget = LiquidLib -> LiftedSpec
llTarget

-- | Returns all the dependencies of this 'LiquidLib'.
libDeps :: LiquidLib -> TargetDependencies
libDeps :: LiquidLib -> TargetDependencies
libDeps = LiquidLib -> TargetDependencies
llDeps

-- | Extracts all the dependencies from a collection of 'LiquidLib's.
allDeps :: Foldable f => f LiquidLib -> TargetDependencies
allDeps :: f LiquidLib -> TargetDependencies
allDeps = (TargetDependencies -> LiquidLib -> TargetDependencies)
-> TargetDependencies -> f LiquidLib -> TargetDependencies
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\TargetDependencies
acc LiquidLib
lib -> TargetDependencies
acc TargetDependencies -> TargetDependencies -> TargetDependencies
forall a. Semigroup a => a -> a -> a
<> LiquidLib -> TargetDependencies
llDeps LiquidLib
lib) TargetDependencies
forall a. Monoid a => a
mempty

-- | A cached spec which can be serialised into an interface.
data CachedSpec = CachedSpec StableModule LiftedSpec deriving (Int -> CachedSpec -> ShowS
[CachedSpec] -> ShowS
CachedSpec -> String
(Int -> CachedSpec -> ShowS)
-> (CachedSpec -> String)
-> ([CachedSpec] -> ShowS)
-> Show CachedSpec
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CachedSpec] -> ShowS
$cshowList :: [CachedSpec] -> ShowS
show :: CachedSpec -> String
$cshow :: CachedSpec -> String
showsPrec :: Int -> CachedSpec -> ShowS
$cshowsPrec :: Int -> CachedSpec -> ShowS
Show, (forall x. CachedSpec -> Rep CachedSpec x)
-> (forall x. Rep CachedSpec x -> CachedSpec) -> Generic CachedSpec
forall x. Rep CachedSpec x -> CachedSpec
forall x. CachedSpec -> Rep CachedSpec x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CachedSpec x -> CachedSpec
$cfrom :: forall x. CachedSpec -> Rep CachedSpec x
Generic)

instance Binary CachedSpec

instance Eq CachedSpec where
    (CachedSpec StableModule
id1 LiftedSpec
_) == :: CachedSpec -> CachedSpec -> Bool
== (CachedSpec StableModule
id2 LiftedSpec
_) = StableModule
id1 StableModule -> StableModule -> Bool
forall a. Eq a => a -> a -> Bool
== StableModule
id2

instance Hashable CachedSpec where
    hashWithSalt :: Int -> CachedSpec -> Int
hashWithSalt Int
s (CachedSpec (StableModule Module
mdl) LiftedSpec
_) =
      Int -> String -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
s (Module -> String
moduleStableString Module
mdl)

-- | Converts the input 'BareSpec' into a 'CachedSpec', inforcing the invariant that termination checking
-- needs to be disabled as this is now considered safe to use for \"clients\".
toCached :: Module -> LiftedSpec -> CachedSpec
toCached :: Module -> LiftedSpec -> CachedSpec
toCached Module
mdl LiftedSpec
liftedSpec = StableModule -> LiftedSpec -> CachedSpec
CachedSpec (Module -> StableModule
toStableModule Module
mdl) LiftedSpec
liftedSpec

cachedSpecStableModuleId :: CachedSpec -> String
cachedSpecStableModuleId :: CachedSpec -> String
cachedSpecStableModuleId (CachedSpec (StableModule Module
m) LiftedSpec
_) = Module -> String
moduleStableString Module
m

cachedSpecModule :: CachedSpec -> Module
cachedSpecModule :: CachedSpec -> Module
cachedSpecModule (CachedSpec (StableModule Module
m) LiftedSpec
_) = Module
m

fromCached :: CachedSpec -> (StableModule, LiftedSpec)
fromCached :: CachedSpec -> (StableModule, LiftedSpec)
fromCached (CachedSpec StableModule
sm LiftedSpec
s) = (StableModule
sm, LiftedSpec
s)

---
--- A Liquid spec and its (many) flavours
---

data InputSpec
data CompanionSpec

data LiquidSpec t where
    MkInputSpec     :: BareSpec   -> LiquidSpec InputSpec
    MkCompanionSpec :: BareSpec   -> LiquidSpec CompanionSpec

deriving instance Show (LiquidSpec InputSpec)
deriving instance Show (LiquidSpec CompanionSpec)

mkInputSpec :: BareSpec -> LiquidSpec InputSpec
mkInputSpec :: BareSpec -> LiquidSpec InputSpec
mkInputSpec = BareSpec -> LiquidSpec InputSpec
MkInputSpec

mkCompanionSpec :: BareSpec -> LiquidSpec CompanionSpec
mkCompanionSpec :: BareSpec -> LiquidSpec CompanionSpec
mkCompanionSpec = BareSpec -> LiquidSpec CompanionSpec
MkCompanionSpec

downcastSpec :: LiquidSpec t -> BareSpec
downcastSpec :: LiquidSpec t -> BareSpec
downcastSpec = \case
  MkInputSpec BareSpec
s    -> BareSpec
s
  MkCompanionSpec BareSpec
s -> BareSpec
s

-- | Merges a 'InputSpec' with its 'CompanionSpec'. Here duplicates are not checked as it's
-- user's responsibility to make sure there are no duplicates between the in-module annotations and the
-- companion spec.
mergeInputWithCompanion :: LiquidSpec InputSpec -> LiquidSpec CompanionSpec -> LiquidSpec InputSpec
mergeInputWithCompanion :: LiquidSpec InputSpec
-> LiquidSpec CompanionSpec -> LiquidSpec InputSpec
mergeInputWithCompanion (MkInputSpec BareSpec
s1) (MkCompanionSpec BareSpec
s2) = BareSpec -> LiquidSpec InputSpec
MkInputSpec (BareSpec
s1 BareSpec -> BareSpec -> BareSpec
forall a. Semigroup a => a -> a -> a
<> BareSpec
s2)

-- | Just a small wrapper around the 'SourcePos' and the text fragment of a LH spec comment.
newtype SpecComment =
    SpecComment (SourcePos, String)
    deriving (Int -> SpecComment -> ShowS
[SpecComment] -> ShowS
SpecComment -> String
(Int -> SpecComment -> ShowS)
-> (SpecComment -> String)
-> ([SpecComment] -> ShowS)
-> Show SpecComment
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SpecComment] -> ShowS
$cshowList :: [SpecComment] -> ShowS
show :: SpecComment -> String
$cshow :: SpecComment -> String
showsPrec :: Int -> SpecComment -> ShowS
$cshowsPrec :: Int -> SpecComment -> ShowS
Show, Typeable SpecComment
DataType
Constr
Typeable SpecComment
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> SpecComment -> c SpecComment)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c SpecComment)
-> (SpecComment -> Constr)
-> (SpecComment -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c SpecComment))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c SpecComment))
-> ((forall b. Data b => b -> b) -> SpecComment -> SpecComment)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> SpecComment -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> SpecComment -> r)
-> (forall u. (forall d. Data d => d -> u) -> SpecComment -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> SpecComment -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> SpecComment -> m SpecComment)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> SpecComment -> m SpecComment)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> SpecComment -> m SpecComment)
-> Data SpecComment
SpecComment -> DataType
SpecComment -> Constr
(forall b. Data b => b -> b) -> SpecComment -> SpecComment
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SpecComment -> c SpecComment
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SpecComment
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> SpecComment -> u
forall u. (forall d. Data d => d -> u) -> SpecComment -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SpecComment -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SpecComment -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SpecComment -> m SpecComment
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SpecComment -> m SpecComment
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SpecComment
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SpecComment -> c SpecComment
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SpecComment)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SpecComment)
$cSpecComment :: Constr
$tSpecComment :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> SpecComment -> m SpecComment
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SpecComment -> m SpecComment
gmapMp :: (forall d. Data d => d -> m d) -> SpecComment -> m SpecComment
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SpecComment -> m SpecComment
gmapM :: (forall d. Data d => d -> m d) -> SpecComment -> m SpecComment
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SpecComment -> m SpecComment
gmapQi :: Int -> (forall d. Data d => d -> u) -> SpecComment -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SpecComment -> u
gmapQ :: (forall d. Data d => d -> u) -> SpecComment -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> SpecComment -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SpecComment -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SpecComment -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SpecComment -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SpecComment -> r
gmapT :: (forall b. Data b => b -> b) -> SpecComment -> SpecComment
$cgmapT :: (forall b. Data b => b -> b) -> SpecComment -> SpecComment
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SpecComment)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SpecComment)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c SpecComment)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SpecComment)
dataTypeOf :: SpecComment -> DataType
$cdataTypeOf :: SpecComment -> DataType
toConstr :: SpecComment -> Constr
$ctoConstr :: SpecComment -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SpecComment
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SpecComment
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SpecComment -> c SpecComment
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SpecComment -> c SpecComment
$cp1Data :: Typeable SpecComment
Data)

newtype Unoptimised a = Unoptimised { Unoptimised a -> a
fromUnoptimised :: a }

toUnoptimised :: a -> Unoptimised a
toUnoptimised :: a -> Unoptimised a
toUnoptimised = a -> Unoptimised a
forall a. a -> Unoptimised a
Unoptimised

--
-- Passing data between stages of the pipeline
--
-- The plugin architecture doesn't provide a default system to \"thread\" data across stages of the
-- compilation pipeline, which means that plugin implementors have two choices:
--
-- 1. Serialise any data they want to carry around inside annotations, but this can be potentially costly;
-- 2. Pass data inside IORefs.

data PipelineData = PipelineData {
    PipelineData -> Unoptimised ModGuts
pdUnoptimisedCore :: Unoptimised ModGuts
  , PipelineData -> TcData
pdTcData :: TcData
  , PipelineData -> [SpecComment]
pdSpecComments :: [SpecComment]
  }

-- | Data which can be \"safely\" passed to the \"Core\" stage of the pipeline.
-- The notion of \"safely\" here is a bit vague: things like imports are somewhat
-- guaranteed not to change, but things like identifiers might, so they shouldn't
-- land here.
data TcData = TcData {
    TcData -> HashSet Symbol
tcAllImports       :: HS.HashSet Symbol
  , TcData -> QImports
tcQualifiedImports :: QImports
  , TcData -> [(Name, Maybe TyThing)]
tcResolvedNames    :: [(Name, Maybe TyThing)]
  , TcData -> [TyCon]
tcAvailableTyCons  :: [GHC.TyCon]
  -- ^ Sometimes we might be in a situation where we have \"wrapper\" modules that
  -- simply re-exports everything from the original module, and therefore when LH
  -- tries to resolve the GHC identifier associated to a data constructor in scope
  -- (from the call to 'lookupTyThings') we might not be able to find a match because
  -- the 'mg_tcs' for the input 'ModGuts' is empty (because the type constructor are not
  -- defined in the /wrapper/ module, but rather in the /wrapped/ module itself). This is
  -- why we look at the 'ModGuts' 's 'AvailInfo' to extract any re-exported 'TyCon' out of that.
  , TcData -> [Var]
tcAvailableVars    :: [Var]
  -- ^ Ditto as for 'reflectedTyCons', but for identifiers.
  }

instance Outputable TcData where
    ppr :: TcData -> SDoc
ppr (TcData{[(Name, Maybe TyThing)]
[Var]
[TyCon]
HashSet Symbol
QImports
tcAvailableVars :: [Var]
tcAvailableTyCons :: [TyCon]
tcResolvedNames :: [(Name, Maybe TyThing)]
tcQualifiedImports :: QImports
tcAllImports :: HashSet Symbol
tcAvailableVars :: TcData -> [Var]
tcAvailableTyCons :: TcData -> [TyCon]
tcResolvedNames :: TcData -> [(Name, Maybe TyThing)]
tcQualifiedImports :: TcData -> QImports
tcAllImports :: TcData -> HashSet Symbol
..}) =
          String -> SDoc
text String
"TcData { imports     = " SDoc -> SDoc -> SDoc
<+> String -> SDoc
text ([Symbol] -> String
forall a. Show a => a -> String
show ([Symbol] -> String) -> [Symbol] -> String
forall a b. (a -> b) -> a -> b
$ HashSet Symbol -> [Symbol]
forall a. HashSet a -> [a]
HS.toList HashSet Symbol
tcAllImports)
      SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"       , qImports    = " SDoc -> SDoc -> SDoc
<+> String -> SDoc
text (QImports -> String
forall a. Show a => a -> String
show QImports
tcQualifiedImports)
      SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"       , names       = " SDoc -> SDoc -> SDoc
<+> [(Name, Maybe TyThing)] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [(Name, Maybe TyThing)]
tcResolvedNames
      SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"       , availTyCons = " SDoc -> SDoc -> SDoc
<+> [TyCon] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyCon]
tcAvailableTyCons
      SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
" }"

-- | Constructs a 'TcData' out of a 'TcGblEnv'.
mkTcData :: [LImportDecl GhcRn]
         -> [(Name, Maybe TyThing)]
         -> [TyCon]
         -> [Var]
         -> TcData
mkTcData :: [LImportDecl GhcRn]
-> [(Name, Maybe TyThing)] -> [TyCon] -> [Var] -> TcData
mkTcData [LImportDecl GhcRn]
imps [(Name, Maybe TyThing)]
resolvedNames [TyCon]
availTyCons [Var]
availVars = TcData :: HashSet Symbol
-> QImports
-> [(Name, Maybe TyThing)]
-> [TyCon]
-> [Var]
-> TcData
TcData {
    tcAllImports :: HashSet Symbol
tcAllImports       = [LImportDecl GhcRn] -> HashSet Symbol
LH.allImports       [LImportDecl GhcRn]
imps
  , tcQualifiedImports :: QImports
tcQualifiedImports = [LImportDecl GhcRn] -> QImports
LH.qualifiedImports [LImportDecl GhcRn]
imps
  , tcResolvedNames :: [(Name, Maybe TyThing)]
tcResolvedNames    = [(Name, Maybe TyThing)]
resolvedNames
  , tcAvailableTyCons :: [TyCon]
tcAvailableTyCons  = [TyCon]
availTyCons
  , tcAvailableVars :: [Var]
tcAvailableVars    = [Var]
availVars
  }