Copyright | (c) 2013-2016 Galois Inc. |
---|---|
License | BSD3 |
Maintainer | cryptol@galois.com |
Stability | provisional |
Portability | portable |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
Cryptol.TypeCheck.Monad
Description
Synopsis
- data InferInput = InferInput {
- inpRange :: Range
- inpVars :: Map Name Schema
- inpTSyns :: Map Name TySyn
- inpNominalTypes :: Map Name NominalType
- inpSignatures :: !(Map Name ModParamNames)
- inpTopModules :: ModName -> Maybe (ModuleG (), IfaceG ())
- inpTopSignatures :: ModName -> Maybe ModParamNames
- inpParams :: !ModParamNames
- inpNameSeeds :: NameSeeds
- inpMonoBinds :: Bool
- inpCallStacks :: Bool
- inpSearchPath :: [FilePath]
- inpPrimNames :: !PrimMap
- inpSupply :: !Supply
- inpSolver :: Solver
- data InferOutput a
- data NameSeeds = NameSeeds {}
- newtype InferM a = IM {}
- data RW = RW {}
- data RO = RO {
- iRange :: Range
- iVars :: Map Name VarType
- iTVars :: [TParam]
- iExtModules :: ModName -> Maybe (ModuleG (), IfaceG ())
- iExtSignatures :: ModName -> Maybe ModParamNames
- iExtScope :: ModuleG ScopeName
- iSolvedHasLazy :: Map Int HasGoalSln
- iMonoBinds :: Bool
- iCallStacks :: Bool
- iSolver :: Solver
- iPrimNames :: !PrimMap
- iSolveCounter :: !(IORef Int)
- data ScopeName
- newtype KindM a = KM {}
- data KRO = KRO {}
- data KRW = KRW {
- typeParams :: Map Name Kind
- kCtrs :: [(ConstraintSource, [Prop])]
- data AllowWildCards
- data LkpTyVar
- newName :: (NameSeeds -> (a, NameSeeds)) -> InferM a
- inRange :: Range -> InferM a -> InferM a
- newTVar :: TypeSource -> Kind -> InferM TVar
- io :: IO a -> InferM a
- inNewScope :: InferM a -> InferM a
- getScope :: Semigroup a => (ModuleG ScopeName -> a) -> InferM a
- getPrimMap :: InferM PrimMap
- lookupModule :: ImpName Name -> InferM (IfaceG ())
- nameSeeds :: NameSeeds
- runInferM :: TVars a => InferInput -> InferM a -> IO (InferOutput a)
- lookupVar :: Name -> InferM VarType
- newLocalScope :: InferM ()
- endLocalScope :: InferM ([DeclGroup], Map Name TySyn)
- withTParams :: [TParam] -> InferM a -> InferM a
- unify :: TypeWithSource -> Type -> InferM [Prop]
- newGoals :: ConstraintSource -> [Prop] -> InferM ()
- newType :: TypeSource -> Kind -> InferM Type
- applySubst :: TVars t => t -> InferM t
- solveHasGoal :: Int -> HasGoalSln -> InferM ()
- newLocalName :: Namespace -> Ident -> InferM Name
- getCallStacks :: InferM Bool
- curRange :: InferM Range
- recordError :: Error -> InferM ()
- recordWarning :: Warning -> InferM ()
- bumpCounter :: InferM ()
- selectorScope :: InferM a -> InferM a
- abortIfErrors :: InferM ()
- inRangeMb :: Maybe Range -> InferM a -> InferM a
- recordErrorLoc :: Maybe Range -> Error -> InferM ()
- getSolver :: InferM Solver
- newGoal :: ConstraintSource -> Prop -> InferM Goal
- addGoals :: [Goal] -> InferM ()
- getGoals :: InferM [Goal]
- simpGoals :: [Goal] -> InferM [Goal]
- collectGoals :: InferM a -> InferM (a, [Goal])
- simpGoal :: Goal -> InferM [Goal]
- newHasGoal :: Selector -> Type -> Type -> InferM HasGoalSln
- newGoalName :: InferM Int
- addHasGoal :: HasGoal -> InferM ()
- getHasGoals :: InferM [HasGoal]
- newTVar' :: TypeSource -> Set TParam -> Kind -> InferM TVar
- getBoundInScope :: InferM (Set TParam)
- checkParamKind :: TParam -> TPFlavor -> Kind -> InferM ()
- newTParam :: TParam Name -> TPFlavor -> Kind -> InferM TParam
- freshTParam :: (Name -> TPFlavor) -> TParam -> InferM TParam
- extendSubst :: Subst -> InferM ()
- getSubst :: InferM Subst
- applySubstPreds :: [Prop] -> InferM [Prop]
- applySubstGoals :: [Goal] -> InferM [Goal]
- varsWithAsmps :: InferM (Set TVar)
- lookupTParam :: Name -> InferM (Maybe TParam)
- lookupTSyn :: Name -> InferM (Maybe TySyn)
- getTSyns :: InferM (Map Name TySyn)
- lookupNominal :: Name -> InferM (Maybe NominalType)
- getNominalTypes :: InferM (Map Name NominalType)
- lookupParamType :: Name -> InferM (Maybe ModTParam)
- getParamTypes :: InferM (Map Name ModTParam)
- lookupSignature :: ImpName Name -> InferM ModParamNames
- getSignatures :: InferM (Map Name ModParamNames)
- lookupTopModule :: ModName -> InferM (Maybe (ModuleG (), IfaceG ()))
- lookupFunctor :: ImpName Name -> InferM (ModuleG ())
- getCurDecls :: InferM (ModuleG ())
- lookupModParam :: Ident -> InferM (Maybe ModParam)
- existVar :: Name -> Kind -> InferM Type
- getParamConstraints :: InferM [Located Prop]
- getTVars :: InferM (Set Name)
- getMonoBinds :: InferM Bool
- checkTShadowing :: String -> Name -> InferM ()
- withTParam :: TParam -> InferM a -> InferM a
- newScope :: ScopeName -> InferM ()
- newSignatureScope :: Name -> Maybe Text -> InferM ()
- updScope :: (ModuleG ScopeName -> ModuleG ScopeName) -> InferM ()
- newTopSignatureScope :: ModName -> InferM ()
- newSubmoduleScope :: Name -> [Text] -> ExportSpec Name -> NamingEnv -> InferM ()
- newModuleScope :: [Text] -> ModName -> ExportSpec Name -> NamingEnv -> InferM ()
- endSubmodule :: InferM ()
- endModule :: InferM TCTopEntity
- endSignature :: InferM ()
- endTopSignature :: InferM TCTopEntity
- addDecls :: DeclGroup -> InferM ()
- addTySyn :: TySyn -> InferM ()
- addNominal :: NominalType -> InferM ()
- addParamType :: ModTParam -> InferM ()
- addSignatures :: Map Name ModParamNames -> InferM ()
- addSubmodules :: Map Name Submodule -> InferM ()
- addFunctors :: Map Name (ModuleG Name) -> InferM ()
- setNested :: Set Name -> InferM ()
- addParamFun :: ModVParam -> InferM ()
- addParameterConstraints :: [Located Prop] -> InferM ()
- addModParam :: ModParam -> InferM ()
- withVarType :: Name -> VarType -> InferM a -> InferM a
- withVarTypes :: [(Name, VarType)] -> InferM a -> InferM a
- withVar :: Name -> Schema -> InferM a -> InferM a
- withMonoType :: (Name, Located Type) -> InferM a -> InferM a
- withMonoTypes :: Map Name (Located Type) -> InferM a -> InferM a
- runKindM :: AllowWildCards -> [(Name, Maybe Kind, TParam)] -> KindM a -> InferM (a, Map Name Kind, [(ConstraintSource, [Prop])])
- kLookupTyVar :: Name -> KindM (Maybe LkpTyVar)
- kWildOK :: KindM AllowWildCards
- kRecordError :: Error -> KindM ()
- kInInferM :: InferM a -> KindM a
- kRecordWarning :: Warning -> KindM ()
- kIO :: IO a -> KindM a
- kNewType :: TypeSource -> Kind -> KindM Type
- kLookupTSyn :: Name -> KindM (Maybe TySyn)
- kLookupNominal :: Name -> KindM (Maybe NominalType)
- kLookupParamType :: Name -> KindM (Maybe ModTParam)
- kExistTVar :: Name -> Kind -> KindM Type
- kInstantiateT :: Type -> [(TParam, Type)] -> KindM Type
- kSetKind :: Name -> Kind -> KindM ()
- kInRange :: Range -> KindM a -> KindM a
- kNewGoals :: ConstraintSource -> [Prop] -> KindM ()
- module Cryptol.TypeCheck.InferTypes
Documentation
data InferInput Source #
Information needed for type inference.
Constructors
InferInput | |
Fields
|
data InferOutput a Source #
The results of type inference.
Constructors
InferFailed NameMap [(Range, Warning)] [(Range, Error)] | We found some errors |
InferOK NameMap [(Range, Warning)] NameSeeds Supply a | Type inference was successful. |
Instances
Show a => Show (InferOutput a) Source # | |
Defined in Cryptol.TypeCheck.Monad Methods showsPrec :: Int -> InferOutput a -> ShowS # show :: InferOutput a -> String # showList :: [InferOutput a] -> ShowS # |
This is used for generating various names.
Instances
Generic NameSeeds Source # | |
Show NameSeeds Source # | |
NFData NameSeeds Source # | |
Defined in Cryptol.TypeCheck.Monad | |
type Rep NameSeeds Source # | |
Defined in Cryptol.TypeCheck.Monad type Rep NameSeeds = D1 ('MetaData "NameSeeds" "Cryptol.TypeCheck.Monad" "cryptol-3.3.0-7OIQa8lMv7L2xoAlM9JEI6" 'False) (C1 ('MetaCons "NameSeeds" 'PrefixI 'True) (S1 ('MetaSel ('Just "seedTVar") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Int) :*: S1 ('MetaSel ('Just "seedGoal") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Int))) |
Read-write component of the monad.
Constructors
RW | |
Fields
|
Read-only component of the monad.
Constructors
RO | |
Fields
|
Constructors
ExternalScope | |
LocalScope | |
SubModule Name | |
SignatureScope Name (Maybe Text) | The Text is docs |
TopSignatureScope ModName | |
MTopModule ModName |
Constructors
KRO | |
Fields
|
Constructors
KRW | |
Fields
|
data AllowWildCards Source #
Do we allow wild cards in the given context.
Constructors
AllowWildCards | |
NoWildCards |
This is what's returned when we lookup variables during kind checking.
inRange :: Range -> InferM a -> InferM a Source #
The monadic computation is about the given range of source code. This is useful for error reporting.
inNewScope :: InferM a -> InferM a Source #
Perform the given computation in a new scope (i.e., the subcomputation may use existential type variables). This is a different kind of scope from the nested modules one.
getScope :: Semigroup a => (ModuleG ScopeName -> a) -> InferM a Source #
Get an environment combining all nested scopes.
getPrimMap :: InferM PrimMap Source #
Retrieve the mapping between identifiers and declarations in the prelude.
lookupModule :: ImpName Name -> InferM (IfaceG ()) Source #
Get information about the things defined in the module.
Note that, in general, the interface may contain *more* than just the
definitions in the module, however the ifNames
should indicate which
ones are part of the module.
nameSeeds :: NameSeeds Source #
The initial seeds, used when checking a fresh program. XXX: why does this start at 10?
runInferM :: TVars a => InferInput -> InferM a -> IO (InferOutput a) Source #
newLocalScope :: InferM () Source #
unify :: TypeWithSource -> Type -> InferM [Prop] Source #
Record that the two types should be syntactically equal.
newGoals :: ConstraintSource -> [Prop] -> InferM () Source #
Record some constraints that need to be solved. The string explains where the constraints came from.
newType :: TypeSource -> Kind -> InferM Type Source #
Generate an unknown type. The doc is a note about what is this type about.
applySubst :: TVars t => t -> InferM t Source #
Apply the accumulated substitution to something with free type variables.
solveHasGoal :: Int -> HasGoalSln -> InferM () Source #
Specify the solution (Expr -> Expr
) for the given constraint (Int
).
newLocalName :: Namespace -> Ident -> InferM Name Source #
Generate a fresh variable name to be used in a local binding.
recordError :: Error -> InferM () Source #
Report an error.
recordWarning :: Warning -> InferM () Source #
bumpCounter :: InferM () Source #
selectorScope :: InferM a -> InferM a Source #
This introduces a new "selector scope" which is currently a module. I think that it might be possible to have selectors scopes be groups of recursive declarations instead, as we are not going to learn anything additional once we are done with the recursive group that generated the selectors constraints. We do it at the module level because this allows us to report more errors at once.
A selector scope does the following: * Keep track of the Has constraints generated in this scope * Keep track of the solutions for discharged selector constraints: - this uses a laziness trick where we build up a map containing the solutions for the Has constraints in the state - the *final* value for this map (i.e., at the value the end of the scope) is passed in as thunk in the reader component of the moment - as we type check expressions when we need the solution for a Has constraint we look it up from the reader environment; note that since the map is not yet built up we just get back a thunk, so we have to be carefule to not force it until *after* we've solved the goals - all of this happens in the `rec` block below * At the end of a selector scope we make sure that all Has constraints were discharged. If not, we *abort* further type checking. The reason for aborting rather than just recording an error is that the expression which produce contains thunks that will lead to non-termination if forced, and some type-checking operations (e.g., instantiation a functor) require us to traverse the expressions.
abortIfErrors :: InferM () Source #
If there are any recoded errors than abort firther type-checking.
getGoals :: InferM [Goal] Source #
The constraints are removed, and returned to the caller. The substitution IS applied to them.
collectGoals :: InferM a -> InferM (a, [Goal]) Source #
Collect the goals emitted by the given sub-computation. Does not emit any new goals.
newHasGoal :: Selector -> Type -> Type -> InferM HasGoalSln Source #
Record a constraint that when we select from the first type, we should get a value of the second type. The returned function should be used to wrap the expression from which we are selecting (i.e., the record or tuple). Plese note that the resulting expression should not be forced before the constraint is solved.
newGoalName :: InferM Int Source #
Generate a new name for a goal.
addHasGoal :: HasGoal -> InferM () Source #
Add a previously generated Has
constraint
getHasGoals :: InferM [HasGoal] Source #
Get the Has
constraints. Each of this should either be solved,
or added back using addHasGoal
.
newTVar' :: TypeSource -> Set TParam -> Kind -> InferM TVar Source #
Generate a new free type variable that depends on these additional type parameters.
getBoundInScope :: InferM (Set TParam) Source #
Return the keys of the bound variables that are in scope.
checkParamKind :: TParam -> TPFlavor -> Kind -> InferM () Source #
Check that the given "flavor" of parameter is allowed to have the given type, and raise an error if not
newTParam :: TParam Name -> TPFlavor -> Kind -> InferM TParam Source #
Generate a new free type variable.
freshTParam :: (Name -> TPFlavor) -> TParam -> InferM TParam Source #
Generate a new version of a type parameter. We use this when instantiating module parameters (the "backtick" imports)
extendSubst :: Subst -> InferM () Source #
Add to the accumulated substitution, checking that the datatype
invariant for Subst
is maintained.
varsWithAsmps :: InferM (Set TVar) Source #
Variables that are either mentioned in the environment or in a selector constraint.
lookupTParam :: Name -> InferM (Maybe TParam) Source #
Lookup a type variable. Return Nothing
if there is no such variable
in scope, in which case we must be dealing with a type constant.
lookupNominal :: Name -> InferM (Maybe NominalType) Source #
Lookup the definition of a nominal type
getNominalTypes :: InferM (Map Name NominalType) Source #
Returns the nominal type declarations that are in scope.
lookupTopModule :: ModName -> InferM (Maybe (ModuleG (), IfaceG ())) Source #
Lookup an external (i.e., previously loaded) top module.
getCurDecls :: InferM (ModuleG ()) Source #
existVar :: Name -> Kind -> InferM Type Source #
Check if we already have a name for this existential type variable and, if so, return the definition. If not, try to create a new definition, if this is allowed. If not, returns nothing.
getMonoBinds :: InferM Bool Source #
Retrieve the value of the `mono-binds` option.
checkTShadowing :: String -> Name -> InferM () Source #
We disallow shadowing between type synonyms and type variables because it is confusing. As a bonus, in the implementation we don't need to worry about where we lookup things (i.e., in the variable or type synonym environment.
withTParam :: TParam -> InferM a -> InferM a Source #
The sub-computation is performed with the given type parameter in scope.
newScope :: ScopeName -> InferM () Source #
Execute the given computation in a new top scope. The sub-computation would typically be validating a module.
updScope :: (ModuleG ScopeName -> ModuleG ScopeName) -> InferM () Source #
Update the current scope (first in the list). Assumes there is one.
newTopSignatureScope :: ModName -> InferM () Source #
newSubmoduleScope :: Name -> [Text] -> ExportSpec Name -> NamingEnv -> InferM () Source #
Start a new submodule scope. The imports and exports are just used to initialize an empty module. As we type check declarations they are added to this module's scope.
newModuleScope :: [Text] -> ModName -> ExportSpec Name -> NamingEnv -> InferM () Source #
endSubmodule :: InferM () Source #
endSignature :: InferM () Source #
addTySyn :: TySyn -> InferM () Source #
The sub-computation is performed with the given type-synonym in scope.
addNominal :: NominalType -> InferM () Source #
addParamType :: ModTParam -> InferM () Source #
addSignatures :: Map Name ModParamNames -> InferM () Source #
addParamFun :: ModVParam -> InferM () Source #
The sub-computation is performed with the given abstract function in scope.
addParameterConstraints :: [Located Prop] -> InferM () Source #
Add some assumptions for an entire module
addModParam :: ModParam -> InferM () Source #
withVarType :: Name -> VarType -> InferM a -> InferM a Source #
The sub-computation is performed with the given variable in scope.
withMonoType :: (Name, Located Type) -> InferM a -> InferM a Source #
The sub-computation is performed with the given variables in scope.
withMonoTypes :: Map Name (Located Type) -> InferM a -> InferM a Source #
The sub-computation is performed with the given variables in scope.
Arguments
:: AllowWildCards | |
-> [(Name, Maybe Kind, TParam)] | See comment |
-> KindM a | |
-> InferM (a, Map Name Kind, [(ConstraintSource, [Prop])]) |
The arguments to this function are as follows:
(type param. name, kind signature (opt.), type parameter)
The type parameter is just a thunk that we should not force. The reason is that the parameter depends on the kind that we are in the process of computing.
As a result we return the value of the sub-computation and the computed kinds of the type parameters.
kWildOK :: KindM AllowWildCards Source #
Are type wild-cards OK in this context?
kRecordError :: Error -> KindM () Source #
Reports an error.
kRecordWarning :: Warning -> KindM () Source #
kNewType :: TypeSource -> Kind -> KindM Type Source #
Generate a fresh unification variable of the given kind.
NOTE: We do not simplify these, because we end up with bottom.
See hs
XXX: Perhaps we can avoid the recursion?
kLookupNominal :: Name -> KindM (Maybe NominalType) Source #
Lookup the definition of a nominal type.
kInstantiateT :: Type -> [(TParam, Type)] -> KindM Type Source #
Replace the given bound variables with concrete types.
kSetKind :: Name -> Kind -> KindM () Source #
Record the kind for a local type variable. This assumes that we already checked that there was no other valid kind for the variable (if there was one, it gets over-written).
kInRange :: Range -> KindM a -> KindM a Source #
The sub-computation is about the given range of the source code.
module Cryptol.TypeCheck.InferTypes