packages feed

cryptol 2.13.0 → 3.0.0

raw patch · 105 files changed

+10640/−3132 lines, 105 filesdep +Win32dep +criterion-measurementdep +hgmpdep ~ghc-bignumdep ~sbvdep ~what4PVP ok

version bump matches the API change (PVP)

Dependencies added: Win32, criterion-measurement, hgmp, language-c99, language-c99-simple, libffi, pretty, pretty-show, unix, vector

Dependency ranges changed: ghc-bignum, sbv, what4

API changes (from Hackage documentation)

- Cryptol.Backend: type family SEval sym :: Type -> Type;
- Cryptol.Eval.Value: type family SEval sym :: Type -> Type;
- Cryptol.ModuleSystem: FailedToParameterizeModDefs :: ModName -> [Name] -> ModuleError
- Cryptol.ModuleSystem: IfaceParams :: Map Name ModTParam -> [Located Prop] -> Map Name ModVParam -> IfaceParams
- Cryptol.ModuleSystem: ImportedParamModule :: ModName -> ModuleError
- Cryptol.ModuleSystem: NotAParameterizedModule :: ModName -> ModuleError
- Cryptol.ModuleSystem: [ifModName] :: IfaceG mname -> !mname
- Cryptol.ModuleSystem: [ifParamConstraints] :: IfaceParams -> [Located Prop]
- Cryptol.ModuleSystem: [ifParamFuns] :: IfaceParams -> Map Name ModVParam
- Cryptol.ModuleSystem: [ifParamTypes] :: IfaceParams -> Map Name ModTParam
- Cryptol.ModuleSystem: [ifPrivate] :: IfaceG mname -> IfaceDecls
- Cryptol.ModuleSystem: [ifPublic] :: IfaceG mname -> IfaceDecls
- Cryptol.ModuleSystem: data IfaceParams
- Cryptol.ModuleSystem: type IfaceTySyn = TySyn
- Cryptol.ModuleSystem.Base: checkSingleModule :: Act (Module Name) Module -> ImportSource -> Module PName -> ModuleM (NamingEnv, Module)
- Cryptol.ModuleSystem.Env: [lmFingerprint] :: LoadedModule -> Fingerprint
- Cryptol.ModuleSystem.Env: [lmInterface] :: LoadedModule -> Iface
- Cryptol.ModuleSystem.Env: [lmModule] :: LoadedModule -> Module
- Cryptol.ModuleSystem.Env: data LoadedModule
- Cryptol.ModuleSystem.Env: instance Control.DeepSeq.NFData Cryptol.ModuleSystem.Env.LoadedModule
- Cryptol.ModuleSystem.Env: instance GHC.Generics.Generic Cryptol.ModuleSystem.Env.LoadedModule
- Cryptol.ModuleSystem.Env: instance GHC.Show.Show Cryptol.ModuleSystem.Env.LoadedModule
- Cryptol.ModuleSystem.Exports: modExports :: Ord name => ModuleG mname name -> ExportSpec name
- Cryptol.ModuleSystem.Exports: names :: (a -> ([Located a'], b)) -> TopLevel a -> [TopLevel a']
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Defines Cryptol.TypeCheck.AST.Decl
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Defines Cryptol.TypeCheck.AST.DeclGroup
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Defines t => Cryptol.ModuleSystem.InstantiateModule.Defines [t]
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Inst (Cryptol.ModuleSystem.Exports.ExportSpec Cryptol.ModuleSystem.Name.Name)
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Inst Cryptol.TypeCheck.AST.Decl
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Inst Cryptol.TypeCheck.AST.DeclDef
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Inst Cryptol.TypeCheck.AST.DeclGroup
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Inst Cryptol.TypeCheck.AST.Expr
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Inst Cryptol.TypeCheck.AST.Match
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Inst Cryptol.TypeCheck.TCon.TC
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Inst Cryptol.TypeCheck.TCon.TCon
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Inst Cryptol.TypeCheck.TCon.UserTC
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Inst Cryptol.TypeCheck.Type.AbstractType
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Inst Cryptol.TypeCheck.Type.Newtype
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Inst Cryptol.TypeCheck.Type.Schema
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Inst Cryptol.TypeCheck.Type.TySyn
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Inst Cryptol.TypeCheck.Type.Type
- Cryptol.ModuleSystem.InstantiateModule: instance Cryptol.ModuleSystem.InstantiateModule.Inst a => Cryptol.ModuleSystem.InstantiateModule.Inst [a]
- Cryptol.ModuleSystem.InstantiateModule: instance GHC.Show.Show Cryptol.ModuleSystem.InstantiateModule.Env
- Cryptol.ModuleSystem.InstantiateModule: instantiateModule :: FreshM m => Module -> ModName -> Map TParam Type -> Map Name Expr -> m (Name -> Name, [Located Prop], Module)
- Cryptol.ModuleSystem.Interface: IfaceParams :: Map Name ModTParam -> [Located Prop] -> Map Name ModVParam -> IfaceParams
- Cryptol.ModuleSystem.Interface: [ifModName] :: IfaceG mname -> !mname
- Cryptol.ModuleSystem.Interface: [ifParamConstraints] :: IfaceParams -> [Located Prop]
- Cryptol.ModuleSystem.Interface: [ifParamFuns] :: IfaceParams -> Map Name ModVParam
- Cryptol.ModuleSystem.Interface: [ifParamTypes] :: IfaceParams -> Map Name ModTParam
- Cryptol.ModuleSystem.Interface: [ifPrivate] :: IfaceG mname -> IfaceDecls
- Cryptol.ModuleSystem.Interface: [ifPublic] :: IfaceG mname -> IfaceDecls
- Cryptol.ModuleSystem.Interface: data IfaceParams
- Cryptol.ModuleSystem.Interface: flatPublicDecls :: IfaceDecls -> IfaceDecls
- Cryptol.ModuleSystem.Interface: flatPublicIface :: IfaceG mname -> IfaceDecls
- Cryptol.ModuleSystem.Interface: ifTySynName :: TySyn -> Name
- Cryptol.ModuleSystem.Interface: instance Control.DeepSeq.NFData Cryptol.ModuleSystem.Interface.IfaceParams
- Cryptol.ModuleSystem.Interface: instance Control.DeepSeq.NFData mname => Control.DeepSeq.NFData (Cryptol.ModuleSystem.Interface.IfaceG mname)
- Cryptol.ModuleSystem.Interface: instance GHC.Generics.Generic (Cryptol.ModuleSystem.Interface.IfaceG mname)
- Cryptol.ModuleSystem.Interface: instance GHC.Generics.Generic Cryptol.ModuleSystem.Interface.IfaceParams
- Cryptol.ModuleSystem.Interface: instance GHC.Show.Show Cryptol.ModuleSystem.Interface.IfaceParams
- Cryptol.ModuleSystem.Interface: instance GHC.Show.Show mname => GHC.Show.Show (Cryptol.ModuleSystem.Interface.IfaceG mname)
- Cryptol.ModuleSystem.Interface: isEmptyIfaceParams :: IfaceParams -> Bool
- Cryptol.ModuleSystem.Interface: noIfaceParams :: IfaceParams
- Cryptol.ModuleSystem.Interface: type IfaceNewtype = Newtype
- Cryptol.ModuleSystem.Interface: type IfaceTySyn = TySyn
- Cryptol.ModuleSystem.Monad: FailedToParameterizeModDefs :: ModName -> [Name] -> ModuleError
- Cryptol.ModuleSystem.Monad: ImportedParamModule :: ModName -> ModuleError
- Cryptol.ModuleSystem.Monad: NotAParameterizedModule :: ModName -> ModuleError
- Cryptol.ModuleSystem.Monad: failedToParameterizeModDefs :: ModName -> [Name] -> ModuleM a
- Cryptol.ModuleSystem.Monad: getIface :: ModName -> ModuleM Iface
- Cryptol.ModuleSystem.Monad: importParamModule :: ModName -> ModuleM a
- Cryptol.ModuleSystem.Monad: notAParameterizedModule :: ModName -> ModuleM a
- Cryptol.ModuleSystem.Name: Declared :: !ModPath -> !NameSource -> NameInfo
- Cryptol.ModuleSystem.Name: Parameter :: NameInfo
- Cryptol.ModuleSystem.Name: asParamName :: Name -> Name
- Cryptol.ModuleSystem.Name: instance GHC.Classes.Eq Cryptol.ModuleSystem.Name.NameInfo
- Cryptol.ModuleSystem.Name: mkParameter :: Namespace -> Ident -> Range -> Supply -> (Name, Supply)
- Cryptol.ModuleSystem.Name: paramModRecParam :: Name
- Cryptol.ModuleSystem.Name: toParamInstName :: Name -> Name
- Cryptol.ModuleSystem.NamingEnv: BuildNamingEnv :: SupplyT Id NamingEnv -> BuildNamingEnv
- Cryptol.ModuleSystem.NamingEnv: ImportIface :: Import -> Iface -> ImportIface
- Cryptol.ModuleSystem.NamingEnv: InModule :: Maybe ModPath -> a -> InModule a
- Cryptol.ModuleSystem.NamingEnv: [runBuild] :: BuildNamingEnv -> SupplyT Id NamingEnv
- Cryptol.ModuleSystem.NamingEnv: buildNamingEnv :: BuildNamingEnv -> Supply -> (NamingEnv, Supply)
- Cryptol.ModuleSystem.NamingEnv: class BindsNames a
- Cryptol.ModuleSystem.NamingEnv: collectNestedModules :: NamingEnv -> Module PName -> Supply -> (NestedMods, Supply)
- Cryptol.ModuleSystem.NamingEnv: collectNestedModulesDecls :: NamingEnv -> ModName -> [TopDecl PName] -> Supply -> (NestedMods, Supply)
- Cryptol.ModuleSystem.NamingEnv: collectNestedModulesDs :: ModPath -> NamingEnv -> [TopDecl PName] -> CollectM ()
- Cryptol.ModuleSystem.NamingEnv: data ImportIface
- Cryptol.ModuleSystem.NamingEnv: data InModule a
- Cryptol.ModuleSystem.NamingEnv: defsOf :: BindsNames a => a -> Supply -> (NamingEnv, Supply)
- Cryptol.ModuleSystem.NamingEnv: filterNames :: (PName -> Bool) -> NamingEnv -> NamingEnv
- Cryptol.ModuleSystem.NamingEnv: instance Cryptol.ModuleSystem.NamingEnv.BindsNames (Cryptol.ModuleSystem.NamingEnv.InModule (Cryptol.Parser.AST.Bind Cryptol.Parser.Name.PName))
- Cryptol.ModuleSystem.NamingEnv: instance Cryptol.ModuleSystem.NamingEnv.BindsNames (Cryptol.ModuleSystem.NamingEnv.InModule (Cryptol.Parser.AST.Decl Cryptol.Parser.Name.PName))
- Cryptol.ModuleSystem.NamingEnv: instance Cryptol.ModuleSystem.NamingEnv.BindsNames (Cryptol.ModuleSystem.NamingEnv.InModule (Cryptol.Parser.AST.NestedModule Cryptol.Parser.Name.PName))
- Cryptol.ModuleSystem.NamingEnv: instance Cryptol.ModuleSystem.NamingEnv.BindsNames (Cryptol.ModuleSystem.NamingEnv.InModule (Cryptol.Parser.AST.Newtype Cryptol.Parser.Name.PName))
- Cryptol.ModuleSystem.NamingEnv: instance Cryptol.ModuleSystem.NamingEnv.BindsNames (Cryptol.ModuleSystem.NamingEnv.InModule (Cryptol.Parser.AST.ParameterFun Cryptol.Parser.Name.PName))
- Cryptol.ModuleSystem.NamingEnv: instance Cryptol.ModuleSystem.NamingEnv.BindsNames (Cryptol.ModuleSystem.NamingEnv.InModule (Cryptol.Parser.AST.ParameterType Cryptol.Parser.Name.PName))
- Cryptol.ModuleSystem.NamingEnv: instance Cryptol.ModuleSystem.NamingEnv.BindsNames (Cryptol.ModuleSystem.NamingEnv.InModule (Cryptol.Parser.AST.PrimType Cryptol.Parser.Name.PName))
- Cryptol.ModuleSystem.NamingEnv: instance Cryptol.ModuleSystem.NamingEnv.BindsNames (Cryptol.ModuleSystem.NamingEnv.InModule (Cryptol.Parser.AST.TopDecl Cryptol.Parser.Name.PName))
- Cryptol.ModuleSystem.NamingEnv: instance Cryptol.ModuleSystem.NamingEnv.BindsNames (Cryptol.Parser.AST.Module Cryptol.Parser.Name.PName)
- Cryptol.ModuleSystem.NamingEnv: instance Cryptol.ModuleSystem.NamingEnv.BindsNames (Cryptol.Parser.AST.Schema Cryptol.Parser.Name.PName)
- Cryptol.ModuleSystem.NamingEnv: instance Cryptol.ModuleSystem.NamingEnv.BindsNames (Cryptol.Parser.AST.TParam Cryptol.Parser.Name.PName)
- Cryptol.ModuleSystem.NamingEnv: instance Cryptol.ModuleSystem.NamingEnv.BindsNames Cryptol.ModuleSystem.NamingEnv.ImportIface
- Cryptol.ModuleSystem.NamingEnv: instance Cryptol.ModuleSystem.NamingEnv.BindsNames Cryptol.ModuleSystem.NamingEnv.NamingEnv
- Cryptol.ModuleSystem.NamingEnv: instance Cryptol.ModuleSystem.NamingEnv.BindsNames a => Cryptol.ModuleSystem.NamingEnv.BindsNames (GHC.Maybe.Maybe a)
- Cryptol.ModuleSystem.NamingEnv: instance Cryptol.ModuleSystem.NamingEnv.BindsNames a => Cryptol.ModuleSystem.NamingEnv.BindsNames [a]
- Cryptol.ModuleSystem.NamingEnv: instance Data.Foldable.Foldable Cryptol.ModuleSystem.NamingEnv.InModule
- Cryptol.ModuleSystem.NamingEnv: instance Data.Traversable.Traversable Cryptol.ModuleSystem.NamingEnv.InModule
- Cryptol.ModuleSystem.NamingEnv: instance GHC.Base.Functor Cryptol.ModuleSystem.NamingEnv.InModule
- Cryptol.ModuleSystem.NamingEnv: instance GHC.Base.Monoid Cryptol.ModuleSystem.NamingEnv.BuildNamingEnv
- Cryptol.ModuleSystem.NamingEnv: instance GHC.Base.Semigroup Cryptol.ModuleSystem.NamingEnv.BuildNamingEnv
- Cryptol.ModuleSystem.NamingEnv: instance GHC.Show.Show a => GHC.Show.Show (Cryptol.ModuleSystem.NamingEnv.InModule a)
- Cryptol.ModuleSystem.NamingEnv: interpImportIface :: Import -> IfaceDecls -> NamingEnv
- Cryptol.ModuleSystem.NamingEnv: lookupTypeNames :: PName -> NamingEnv -> [Name]
- Cryptol.ModuleSystem.NamingEnv: lookupValNames :: PName -> NamingEnv -> [Name]
- Cryptol.ModuleSystem.NamingEnv: merge :: [Name] -> [Name] -> [Name]
- Cryptol.ModuleSystem.NamingEnv: moduleDefs :: ModPath -> ModuleG mname PName -> BuildNamingEnv
- Cryptol.ModuleSystem.NamingEnv: namingEnv :: BindsNames a => a -> BuildNamingEnv
- Cryptol.ModuleSystem.NamingEnv: namingEnvRename :: (Name -> Name) -> NamingEnv -> NamingEnv
- Cryptol.ModuleSystem.NamingEnv: newLocal :: FreshM m => Namespace -> PName -> Range -> m Name
- Cryptol.ModuleSystem.NamingEnv: newTop :: FreshM m => Namespace -> ModPath -> PName -> Maybe Fixity -> Range -> m Name
- Cryptol.ModuleSystem.NamingEnv: newtype BuildNamingEnv
- Cryptol.ModuleSystem.NamingEnv: singletonE :: PName -> Name -> NamingEnv
- Cryptol.ModuleSystem.NamingEnv: singletonT :: PName -> Name -> NamingEnv
- Cryptol.ModuleSystem.NamingEnv: type CollectM = StateT NestedMods (SupplyT Id)
- Cryptol.ModuleSystem.NamingEnv: type NestedMods = Map Name NamingEnv
- Cryptol.ModuleSystem.Renamer: BoundReservedType :: PName -> Maybe Range -> Doc -> RenamerError
- Cryptol.ModuleSystem.Renamer: InvalidConstraint :: Type PName -> RenamerError
- Cryptol.ModuleSystem.Renamer: MalformedBuiltin :: Type PName -> PName -> RenamerError
- Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Renamer.Rename (Cryptol.ModuleSystem.Renamer.WithMods Cryptol.Parser.AST.NestedModule)
- Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Renamer.Rename (Cryptol.ModuleSystem.Renamer.WithMods Cryptol.Parser.AST.TopDecl)
- Cryptol.ModuleSystem.Renamer: namingEnv :: BindsNames a => a -> BuildNamingEnv
- Cryptol.ModuleSystem.Renamer.Error: BoundReservedType :: PName -> Maybe Range -> Doc -> RenamerError
- Cryptol.ModuleSystem.Renamer.Error: InvalidConstraint :: Type PName -> RenamerError
- Cryptol.ModuleSystem.Renamer.Error: MalformedBuiltin :: Type PName -> PName -> RenamerError
- Cryptol.ModuleSystem.Renamer.Monad: [roIfaces] :: RO -> ModName -> Iface
- Cryptol.ModuleSystem.Renamer.Monad: checkEnv :: EnvCheck -> NamingEnv -> NamingEnv -> RW -> (NamingEnv, RW)
- Cryptol.ModuleSystem.Renamer.Monad: containsOverlap :: [Name] -> Seq RenamerError
- Cryptol.ModuleSystem.Renamer.Monad: lookupImport :: Import -> RenameM IfaceDecls
- Cryptol.ModuleSystem.Renamer.Monad: record :: RenamerError -> RenameM ()
- Cryptol.Parser.AST: EComplement :: Expr n -> Expr n
- Cryptol.Parser.AST: ENeg :: Expr n -> Expr n
- Cryptol.Parser.AST: [mDecls] :: ModuleG mname name -> [TopDecl name]
- Cryptol.Parser.AST: [mInstance] :: ModuleG mname name -> !Maybe (Located ModName)
- Cryptol.Parser.AST: instance GHC.Classes.Eq mname => GHC.Classes.Eq (Cryptol.Parser.AST.ImportG mname)
- Cryptol.Parser.AST: mSubmoduleImports :: ModuleG mname name -> [Located (ImportG name)]
- Cryptol.Parser.Lexer: KW_extern :: TokenKW
- Cryptol.Parser.Token: KW_extern :: TokenKW
- Cryptol.Transform.AddModParams: addModParams :: Module -> Either [Name] Module
- Cryptol.Transform.AddModParams: instance Cryptol.Transform.AddModParams.AddParams Cryptol.TypeCheck.AST.Decl
- Cryptol.Transform.AddModParams: instance Cryptol.Transform.AddModParams.AddParams Cryptol.TypeCheck.AST.DeclGroup
- Cryptol.Transform.AddModParams: instance Cryptol.Transform.AddModParams.AddParams Cryptol.TypeCheck.AST.Expr
- Cryptol.Transform.AddModParams: instance Cryptol.Transform.AddModParams.AddParams Cryptol.TypeCheck.Type.Newtype
- Cryptol.Transform.AddModParams: instance Cryptol.Transform.AddModParams.AddParams Cryptol.TypeCheck.Type.Schema
- Cryptol.Transform.AddModParams: instance Cryptol.Transform.AddModParams.AddParams Cryptol.TypeCheck.Type.TySyn
- Cryptol.Transform.AddModParams: instance Cryptol.Transform.AddModParams.AddParams Cryptol.TypeCheck.Type.Type
- Cryptol.Transform.AddModParams: instance Cryptol.Transform.AddModParams.AddParams a => Cryptol.Transform.AddModParams.AddParams [a]
- Cryptol.Transform.AddModParams: instance Cryptol.Transform.AddModParams.Inst Cryptol.TypeCheck.AST.Decl
- Cryptol.Transform.AddModParams: instance Cryptol.Transform.AddModParams.Inst Cryptol.TypeCheck.AST.DeclDef
- Cryptol.Transform.AddModParams: instance Cryptol.Transform.AddModParams.Inst Cryptol.TypeCheck.AST.DeclGroup
- Cryptol.Transform.AddModParams: instance Cryptol.Transform.AddModParams.Inst Cryptol.TypeCheck.AST.Expr
- Cryptol.Transform.AddModParams: instance Cryptol.Transform.AddModParams.Inst Cryptol.TypeCheck.AST.Match
- Cryptol.Transform.AddModParams: instance Cryptol.Transform.AddModParams.Inst Cryptol.TypeCheck.Type.Newtype
- Cryptol.Transform.AddModParams: instance Cryptol.Transform.AddModParams.Inst Cryptol.TypeCheck.Type.TySyn
- Cryptol.Transform.AddModParams: instance Cryptol.Transform.AddModParams.Inst Cryptol.TypeCheck.Type.Type
- Cryptol.Transform.AddModParams: instance Cryptol.Transform.AddModParams.Inst a => Cryptol.Transform.AddModParams.Inst [a]
- Cryptol.TypeCheck: [inpParamConstraints] :: InferInput -> ![Located Prop]
- Cryptol.TypeCheck: [inpParamFuns] :: InferInput -> !Map Name ModVParam
- Cryptol.TypeCheck: [inpParamTypes] :: InferInput -> !Map Name ModTParam
- Cryptol.TypeCheck: tcModuleInst :: IORef NamingEnv -> Module -> Module Name -> InferInput -> IO (InferOutput Module)
- Cryptol.TypeCheck.AST: [mImports] :: ModuleG mname -> [Import]
- Cryptol.TypeCheck.AST: [mSubModules] :: ModuleG mname -> Map Name (IfaceG Name)
- Cryptol.TypeCheck.CheckModuleInstance: checkModuleInstance :: Module -> Module -> InferM (Name -> Name, Module)
- Cryptol.TypeCheck.Infer: inferModule :: Module Name -> InferM Module
- Cryptol.TypeCheck.Monad: [inpParamConstraints] :: InferInput -> ![Located Prop]
- Cryptol.TypeCheck.Monad: [inpParamFuns] :: InferInput -> !Map Name ModVParam
- Cryptol.TypeCheck.Monad: [inpParamTypes] :: InferInput -> !Map Name ModTParam
- Cryptol.TypeCheck.Monad: endModuleInstance :: InferM ()
- Cryptol.TypeCheck.Monad: getParamFuns :: InferM (Map Name ModVParam)
- Cryptol.TypeCheck.Monad: lookupParamFun :: Name -> InferM (Maybe ModVParam)
- Cryptol.TypeCheck.Monad: newParamName :: Namespace -> Ident -> InferM Name
- Cryptol.TypeCheck.Solver.SMT: instance Cryptol.TypeCheck.Solver.SMT.Mk GHC.Integer.Type.Integer
- Cryptol.TypeCheck.Subst: instance Cryptol.TypeCheck.Subst.TVars Cryptol.TypeCheck.AST.Module
- Cryptol.TypeCheck.Type: [mtpNumber] :: ModTParam -> !Int
- Cryptol.Utils.Ident: isParamInstModName :: ModName -> Bool
- Cryptol.Utils.Ident: notParamInstModName :: ModName -> ModName
- Cryptol.Utils.Ident: paramInstModName :: ModName -> ModName
+ Cryptol.Backend: type SBit sym :: Type;
+ Cryptol.Backend: type SEval sym :: Type -> Type;
+ Cryptol.Backend: type SFloat sym :: Type;
+ Cryptol.Backend: type SInteger sym :: Type;
+ Cryptol.Backend: type SWord sym :: Type;
+ Cryptol.Backend.FFI: SomeFFIArg :: a -> SomeFFIArg
+ Cryptol.Backend.FFI: callForeignImpl :: forall a. FFIRet a => ForeignImpl -> [SomeFFIArg] -> IO a
+ Cryptol.Backend.FFI: class Storable a => FFIArg a
+ Cryptol.Backend.FFI: class Storable a => FFIRet a
+ Cryptol.Backend.FFI: data ForeignImpl
+ Cryptol.Backend.FFI: data ForeignSrc
+ Cryptol.Backend.FFI: data SomeFFIArg
+ Cryptol.Backend.FFI: foreignLibPath :: FilePath -> IO (Maybe FilePath)
+ Cryptol.Backend.FFI: getForeignSrcPath :: ForeignSrc -> Maybe FilePath
+ Cryptol.Backend.FFI: instance Control.DeepSeq.NFData Cryptol.Backend.FFI.ForeignSrc
+ Cryptol.Backend.FFI: instance Cryptol.Backend.FFI.FFIArg (GHC.Ptr.Ptr a)
+ Cryptol.Backend.FFI: instance Cryptol.Backend.FFI.FFIArg Foreign.C.Types.CDouble
+ Cryptol.Backend.FFI: instance Cryptol.Backend.FFI.FFIArg Foreign.C.Types.CFloat
+ Cryptol.Backend.FFI: instance Cryptol.Backend.FFI.FFIArg Foreign.C.Types.CSize
+ Cryptol.Backend.FFI: instance Cryptol.Backend.FFI.FFIArg GHC.Word.Word16
+ Cryptol.Backend.FFI: instance Cryptol.Backend.FFI.FFIArg GHC.Word.Word32
+ Cryptol.Backend.FFI: instance Cryptol.Backend.FFI.FFIArg GHC.Word.Word64
+ Cryptol.Backend.FFI: instance Cryptol.Backend.FFI.FFIArg GHC.Word.Word8
+ Cryptol.Backend.FFI: instance Cryptol.Backend.FFI.FFIRet ()
+ Cryptol.Backend.FFI: instance Cryptol.Backend.FFI.FFIRet Foreign.C.Types.CDouble
+ Cryptol.Backend.FFI: instance Cryptol.Backend.FFI.FFIRet Foreign.C.Types.CFloat
+ Cryptol.Backend.FFI: instance Cryptol.Backend.FFI.FFIRet GHC.Word.Word16
+ Cryptol.Backend.FFI: instance Cryptol.Backend.FFI.FFIRet GHC.Word.Word32
+ Cryptol.Backend.FFI: instance Cryptol.Backend.FFI.FFIRet GHC.Word.Word64
+ Cryptol.Backend.FFI: instance Cryptol.Backend.FFI.FFIRet GHC.Word.Word8
+ Cryptol.Backend.FFI: instance GHC.Show.Show Cryptol.Backend.FFI.ForeignSrc
+ Cryptol.Backend.FFI: loadForeignImpl :: ForeignSrc -> String -> IO (Either FFILoadError ForeignImpl)
+ Cryptol.Backend.FFI: loadForeignSrc :: FilePath -> IO (Either FFILoadError ForeignSrc)
+ Cryptol.Backend.FFI: unloadForeignSrc :: ForeignSrc -> IO ()
+ Cryptol.Backend.FFI.Error: CantLoadFFIImpl :: String -> String -> FFILoadError
+ Cryptol.Backend.FFI.Error: CantLoadFFISrc :: FilePath -> String -> FFILoadError
+ Cryptol.Backend.FFI.Error: FFIDuplicates :: [Name] -> FFILoadError
+ Cryptol.Backend.FFI.Error: FFIInFunctor :: Name -> FFILoadError
+ Cryptol.Backend.FFI.Error: data FFILoadError
+ Cryptol.Backend.FFI.Error: instance Control.DeepSeq.NFData Cryptol.Backend.FFI.Error.FFILoadError
+ Cryptol.Backend.FFI.Error: instance Cryptol.Utils.PP.PP Cryptol.Backend.FFI.Error.FFILoadError
+ Cryptol.Backend.FFI.Error: instance GHC.Generics.Generic Cryptol.Backend.FFI.Error.FFILoadError
+ Cryptol.Backend.FFI.Error: instance GHC.Show.Show Cryptol.Backend.FFI.Error.FFILoadError
+ Cryptol.Backend.FloatHelpers: floatFromDouble :: Double -> BF
+ Cryptol.Backend.Monad: FFINotSupported :: Name -> EvalError
+ Cryptol.Backend.Monad: FFITypeNumTooBig :: Name -> TParam -> Integer -> EvalError
+ Cryptol.Backend.Monad: NoMatchingPropGuardCase :: String -> EvalError
+ Cryptol.Eval: FFINotSupported :: Name -> EvalError
+ Cryptol.Eval: FFITypeNumTooBig :: Name -> TParam -> Integer -> EvalError
+ Cryptol.Eval: NoMatchingPropGuardCase :: String -> EvalError
+ Cryptol.Eval: checkProp :: Prop -> Bool
+ Cryptol.Eval.FFI: evalForeignDecls :: ForeignSrc -> [(Name, FFIFunType)] -> EvalEnv -> Eval (Either [FFILoadError] EvalEnv)
+ Cryptol.Eval.FFI: findForeignDecls :: ModuleG mname -> [(Name, FFIFunType)]
+ Cryptol.Eval.FFI.GenHeader: generateForeignHeader :: [(Name, FFIFunType)] -> String
+ Cryptol.Eval.FFI.GenHeader: instance GHC.Classes.Eq Cryptol.Eval.FFI.GenHeader.Include
+ Cryptol.Eval.FFI.GenHeader: instance GHC.Classes.Ord Cryptol.Eval.FFI.GenHeader.Include
+ Cryptol.Eval.Type: instance GHC.Show.Show Cryptol.Eval.Type.TypeEnv
+ Cryptol.Eval.Type: tvFloat64 :: TValue
+ Cryptol.Eval.Value: type SBit sym :: Type;
+ Cryptol.Eval.Value: type SEval sym :: Type -> Type;
+ Cryptol.Eval.Value: type SFloat sym :: Type;
+ Cryptol.Eval.Value: type SInteger sym :: Type;
+ Cryptol.Eval.Value: type SWord sym :: Type;
+ Cryptol.IR.TraverseNames: class TraverseNames t
+ Cryptol.IR.TraverseNames: instance (GHC.Classes.Ord a, Cryptol.IR.TraverseNames.TraverseNames a) => Cryptol.IR.TraverseNames.TraverseNames (Cryptol.ModuleSystem.Exports.ExportSpec a)
+ Cryptol.IR.TraverseNames: instance (GHC.Classes.Ord a, Cryptol.IR.TraverseNames.TraverseNames a) => Cryptol.IR.TraverseNames.TraverseNames (Data.Set.Internal.Set a)
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.ModuleSystem.Name.Name
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.AST.Decl
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.AST.DeclDef
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.AST.DeclGroup
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.AST.Expr
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.AST.Match
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.FFI.FFIType.FFIFunType
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.FFI.FFIType.FFIType
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.TCon.TC
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.TCon.TCon
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.TCon.UserTC
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.Type.ArgDescr
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.Type.ModTParam
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.Type.ModVParam
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.Type.Newtype
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.Type.Schema
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.Type.TPFlavor
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.Type.TParam
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.Type.TVar
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.Type.TVarInfo
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.Type.TySyn
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.Type.Type
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.Type.TypeSource
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames a => Cryptol.IR.TraverseNames.TraverseNames (Cryptol.Parser.Position.Located a)
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames a => Cryptol.IR.TraverseNames.TraverseNames (GHC.Maybe.Maybe a)
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames a => Cryptol.IR.TraverseNames.TraverseNames [a]
+ Cryptol.IR.TraverseNames: mapNames :: TraverseNames t => (Name -> Name) -> t -> t
+ Cryptol.IR.TraverseNames: traverseNames :: (TraverseNames t, Applicative f) => (Name -> f Name) -> t -> f t
+ Cryptol.IR.TraverseNames: traverseNamesIP :: (TraverseNames t, Applicative f, ?name :: Name -> f Name) => t -> f t
+ Cryptol.ModuleSystem: ExpandPropGuardsError :: ImportSource -> Error -> ModuleError
+ Cryptol.ModuleSystem: FFILoadErrors :: ModName -> [FFILoadError] -> ModuleError
+ Cryptol.ModuleSystem: [ifDeclIsPrim] :: IfaceDecl -> !Bool
+ Cryptol.ModuleSystem: [ifDefines] :: IfaceG name -> IfaceDecls
+ Cryptol.ModuleSystem: [ifFunctors] :: IfaceDecls -> !Map Name (IfaceG Name)
+ Cryptol.ModuleSystem: [ifNames] :: IfaceG name -> IfaceNames name
+ Cryptol.ModuleSystem: [ifSignatures] :: IfaceDecls -> !Map Name ModParamNames
+ Cryptol.ModuleSystem: benchmarkExpr :: Double -> Expr -> ModuleCmd BenchmarkStats
+ Cryptol.ModuleSystem: checkModuleByPath :: FilePath -> ModuleCmd (ModulePath, TCTopEntity)
+ Cryptol.ModuleSystem: getFileDependencies :: FilePath -> ModuleCmd (ModulePath, FileInfo)
+ Cryptol.ModuleSystem: getModuleDependencies :: ModName -> ModuleCmd (ModulePath, FileInfo)
+ Cryptol.ModuleSystem.Base: benchmarkExpr :: Double -> Expr -> ModuleM BenchmarkStats
+ Cryptol.ModuleSystem.Base: expandPropGuards :: Module PName -> ModuleM (Module PName)
+ Cryptol.ModuleSystem.Base: findDeps :: ModuleG mname name -> [ImportSource]
+ Cryptol.ModuleSystem.Base: findDeps' :: ModuleG mname name -> (Any, Endo [ImportSource])
+ Cryptol.ModuleSystem.Base: findDepsOf :: ModulePath -> ModuleM (ModulePath, FileInfo)
+ Cryptol.ModuleSystem.Base: findDepsOfModule :: ModName -> ModuleM (ModulePath, FileInfo)
+ Cryptol.ModuleSystem.Base: findModuleDeps :: ModuleG mname name -> Set ModName
+ Cryptol.ModuleSystem.Base: tcTopEntitytLinter :: ModName -> TCLinter TCTopEntity
+ Cryptol.ModuleSystem.Binds: AFunctor :: ModKind
+ Cryptol.ModuleSystem.Binds: AModule :: ModKind
+ Cryptol.ModuleSystem.Binds: ASignature :: ModKind
+ Cryptol.ModuleSystem.Binds: InModule :: Maybe ModPath -> a -> InModule a
+ Cryptol.ModuleSystem.Binds: Mod :: [ImportG (ImpName PName)] -> ModKind -> Map Name (ImpName PName, ModuleInstanceArgs PName) -> Map Name (Mod a) -> NamingEnv -> !Set Name -> a -> Mod a
+ Cryptol.ModuleSystem.Binds: TopInst :: ModName -> ImpName PName -> ModuleInstanceArgs PName -> TopDef
+ Cryptol.ModuleSystem.Binds: TopMod :: ModName -> Mod () -> TopDef
+ Cryptol.ModuleSystem.Binds: [modDefines] :: Mod a -> NamingEnv
+ Cryptol.ModuleSystem.Binds: [modImports] :: Mod a -> [ImportG (ImpName PName)]
+ Cryptol.ModuleSystem.Binds: [modInstances] :: Mod a -> Map Name (ImpName PName, ModuleInstanceArgs PName)
+ Cryptol.ModuleSystem.Binds: [modKind] :: Mod a -> ModKind
+ Cryptol.ModuleSystem.Binds: [modMods] :: Mod a -> Map Name (Mod a)
+ Cryptol.ModuleSystem.Binds: [modPublic] :: Mod a -> !Set Name
+ Cryptol.ModuleSystem.Binds: [modState] :: Mod a -> a
+ Cryptol.ModuleSystem.Binds: class BindsNames a
+ Cryptol.ModuleSystem.Binds: data InModule a
+ Cryptol.ModuleSystem.Binds: data Mod a
+ Cryptol.ModuleSystem.Binds: data ModKind
+ Cryptol.ModuleSystem.Binds: data TopDef
+ Cryptol.ModuleSystem.Binds: defsOf :: BindsNames a => a -> Supply -> (NamingEnv, Supply)
+ Cryptol.ModuleSystem.Binds: ifaceSigToMod :: ModParamNames -> Mod ()
+ Cryptol.ModuleSystem.Binds: ifaceToMod :: IfaceG name -> Mod ()
+ Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames (Cryptol.ModuleSystem.Binds.InModule (Cryptol.Parser.AST.Bind Cryptol.Parser.Name.PName))
+ Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames (Cryptol.ModuleSystem.Binds.InModule (Cryptol.Parser.AST.Decl Cryptol.Parser.Name.PName))
+ Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames (Cryptol.ModuleSystem.Binds.InModule (Cryptol.Parser.AST.NestedModule Cryptol.Parser.Name.PName))
+ Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames (Cryptol.ModuleSystem.Binds.InModule (Cryptol.Parser.AST.Newtype Cryptol.Parser.Name.PName))
+ Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames (Cryptol.ModuleSystem.Binds.InModule (Cryptol.Parser.AST.ParameterFun Cryptol.Parser.Name.PName))
+ Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames (Cryptol.ModuleSystem.Binds.InModule (Cryptol.Parser.AST.ParameterType Cryptol.Parser.Name.PName))
+ Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames (Cryptol.ModuleSystem.Binds.InModule (Cryptol.Parser.AST.PrimType Cryptol.Parser.Name.PName))
+ Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames (Cryptol.ModuleSystem.Binds.InModule (Cryptol.Parser.AST.SigDecl Cryptol.Parser.Name.PName))
+ Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames (Cryptol.ModuleSystem.Binds.InModule (Cryptol.Parser.AST.TopDecl Cryptol.Parser.Name.PName))
+ Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames (Cryptol.Parser.AST.Schema Cryptol.Parser.Name.PName)
+ Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames (Cryptol.Parser.AST.TParam Cryptol.Parser.Name.PName)
+ Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames Cryptol.ModuleSystem.NamingEnv.NamingEnv
+ Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames a => Cryptol.ModuleSystem.Binds.BindsNames (GHC.Maybe.Maybe a)
+ Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames a => Cryptol.ModuleSystem.Binds.BindsNames [a]
+ Cryptol.ModuleSystem.Binds: instance Data.Foldable.Foldable Cryptol.ModuleSystem.Binds.InModule
+ Cryptol.ModuleSystem.Binds: instance Data.Traversable.Traversable Cryptol.ModuleSystem.Binds.InModule
+ Cryptol.ModuleSystem.Binds: instance GHC.Base.Functor Cryptol.ModuleSystem.Binds.InModule
+ Cryptol.ModuleSystem.Binds: instance GHC.Base.Functor Cryptol.ModuleSystem.Binds.Mod
+ Cryptol.ModuleSystem.Binds: instance GHC.Base.Monoid Cryptol.ModuleSystem.Binds.BuildNamingEnv
+ Cryptol.ModuleSystem.Binds: instance GHC.Base.Semigroup Cryptol.ModuleSystem.Binds.BuildNamingEnv
+ Cryptol.ModuleSystem.Binds: instance GHC.Show.Show a => GHC.Show.Show (Cryptol.ModuleSystem.Binds.InModule a)
+ Cryptol.ModuleSystem.Binds: modBuilder :: ModBuilder a -> Supply -> ((a, [RenamerError]), Supply)
+ Cryptol.ModuleSystem.Binds: modNested :: Mod a -> Set Name
+ Cryptol.ModuleSystem.Binds: modToMap :: ImpName Name -> Mod () -> Map (ImpName Name) (Mod ()) -> Map (ImpName Name) (Mod ())
+ Cryptol.ModuleSystem.Binds: newModParam :: FreshM m => ModPath -> Ident -> Range -> Name -> m Name
+ Cryptol.ModuleSystem.Binds: topDeclsDefs :: ModPath -> [TopDecl PName] -> ModBuilder (Mod ())
+ Cryptol.ModuleSystem.Binds: topModuleDefs :: Module PName -> ModBuilder TopDef
+ Cryptol.ModuleSystem.Env: ALoadedFunctor :: LoadedModule -> LoadedEntity
+ Cryptol.ModuleSystem.Env: ALoadedInterface :: LoadedSignature -> LoadedEntity
+ Cryptol.ModuleSystem.Env: ALoadedModule :: LoadedModule -> LoadedEntity
+ Cryptol.ModuleSystem.Env: FileInfo :: Fingerprint -> Set FilePath -> Set ModName -> Set FilePath -> FileInfo
+ Cryptol.ModuleSystem.Env: FunctorParams :: FunctorParams -> ModContextParams
+ Cryptol.ModuleSystem.Env: InterfaceParams :: ModParamNames -> ModContextParams
+ Cryptol.ModuleSystem.Env: LoadedModuleData :: Iface -> Module -> Maybe ForeignSrc -> LoadedModuleData
+ Cryptol.ModuleSystem.Env: NoParams :: ModContextParams
+ Cryptol.ModuleSystem.Env: [fiFingerprint] :: FileInfo -> Fingerprint
+ Cryptol.ModuleSystem.Env: [fiForeignDeps] :: FileInfo -> Set FilePath
+ Cryptol.ModuleSystem.Env: [fiImportDeps] :: FileInfo -> Set ModName
+ Cryptol.ModuleSystem.Env: [fiIncludeDeps] :: FileInfo -> Set FilePath
+ Cryptol.ModuleSystem.Env: [lmData] :: LoadedModuleG a -> a
+ Cryptol.ModuleSystem.Env: [lmFileInfo] :: LoadedModuleG a -> !FileInfo
+ Cryptol.ModuleSystem.Env: [lmForeignSrc] :: LoadedModuleData -> Maybe ForeignSrc
+ Cryptol.ModuleSystem.Env: [lmLoadedSignatures] :: LoadedModules -> ![LoadedSignature]
+ Cryptol.ModuleSystem.Env: [lmdInterface] :: LoadedModuleData -> Iface
+ Cryptol.ModuleSystem.Env: [lmdModule] :: LoadedModuleData -> Module
+ Cryptol.ModuleSystem.Env: addLoadedSignature :: ModulePath -> String -> FileInfo -> NamingEnv -> ModName -> ModParamNames -> LoadedModules -> LoadedModules
+ Cryptol.ModuleSystem.Env: data FileInfo
+ Cryptol.ModuleSystem.Env: data LoadedEntity
+ Cryptol.ModuleSystem.Env: data LoadedModuleData
+ Cryptol.ModuleSystem.Env: data LoadedModuleG a
+ Cryptol.ModuleSystem.Env: data ModContextParams
+ Cryptol.ModuleSystem.Env: fileInfo :: Fingerprint -> Set FilePath -> Set ModName -> Maybe ForeignSrc -> FileInfo
+ Cryptol.ModuleSystem.Env: getLoadedEntities :: LoadedModules -> Map ModName LoadedEntity
+ Cryptol.ModuleSystem.Env: getLoadedNames :: LoadedModules -> Set ModName
+ Cryptol.ModuleSystem.Env: instance Control.DeepSeq.NFData Cryptol.ModuleSystem.Env.FileInfo
+ Cryptol.ModuleSystem.Env: instance Control.DeepSeq.NFData Cryptol.ModuleSystem.Env.LoadedModuleData
+ Cryptol.ModuleSystem.Env: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Cryptol.ModuleSystem.Env.LoadedModuleG a)
+ Cryptol.ModuleSystem.Env: instance GHC.Classes.Ord Cryptol.ModuleSystem.Env.ModulePath
+ Cryptol.ModuleSystem.Env: instance GHC.Generics.Generic (Cryptol.ModuleSystem.Env.LoadedModuleG a)
+ Cryptol.ModuleSystem.Env: instance GHC.Generics.Generic Cryptol.ModuleSystem.Env.FileInfo
+ Cryptol.ModuleSystem.Env: instance GHC.Generics.Generic Cryptol.ModuleSystem.Env.LoadedModuleData
+ Cryptol.ModuleSystem.Env: instance GHC.Show.Show Cryptol.ModuleSystem.Env.FileInfo
+ Cryptol.ModuleSystem.Env: instance GHC.Show.Show Cryptol.ModuleSystem.Env.LoadedModuleData
+ Cryptol.ModuleSystem.Env: instance GHC.Show.Show a => GHC.Show.Show (Cryptol.ModuleSystem.Env.LoadedModuleG a)
+ Cryptol.ModuleSystem.Env: isLoadedInterface :: ModName -> LoadedModules -> Bool
+ Cryptol.ModuleSystem.Env: lmInterface :: LoadedModule -> Iface
+ Cryptol.ModuleSystem.Env: lmModule :: LoadedModule -> Module
+ Cryptol.ModuleSystem.Env: lookupSignature :: ModName -> ModuleEnv -> Maybe LoadedSignature
+ Cryptol.ModuleSystem.Env: lookupTCEntity :: ModName -> ModuleEnv -> Maybe (LoadedModuleG TCTopEntity)
+ Cryptol.ModuleSystem.Env: modContextParamNames :: ModContextParams -> ModParamNames
+ Cryptol.ModuleSystem.Env: type LoadedModule = LoadedModuleG LoadedModuleData
+ Cryptol.ModuleSystem.Env: type LoadedSignature = LoadedModuleG ModParamNames
+ Cryptol.ModuleSystem.Exports: allExported :: Ord name => ExportSpec name -> Set name
+ Cryptol.ModuleSystem.Exports: exportedDecls :: Ord name => [TopDecl name] -> ExportSpec name
+ Cryptol.ModuleSystem.Fingerprint: fingerprintHexString :: Fingerprint -> String
+ Cryptol.ModuleSystem.Interface: IfaceNames :: name -> Set Name -> Set Name -> Set Name -> !Maybe Text -> IfaceNames name
+ Cryptol.ModuleSystem.Interface: [ifDeclIsPrim] :: IfaceDecl -> !Bool
+ Cryptol.ModuleSystem.Interface: [ifDefines] :: IfaceG name -> IfaceDecls
+ Cryptol.ModuleSystem.Interface: [ifFunctors] :: IfaceDecls -> !Map Name (IfaceG Name)
+ Cryptol.ModuleSystem.Interface: [ifNames] :: IfaceG name -> IfaceNames name
+ Cryptol.ModuleSystem.Interface: [ifSignatures] :: IfaceDecls -> !Map Name ModParamNames
+ Cryptol.ModuleSystem.Interface: [ifsDefines] :: IfaceNames name -> Set Name
+ Cryptol.ModuleSystem.Interface: [ifsDoc] :: IfaceNames name -> !Maybe Text
+ Cryptol.ModuleSystem.Interface: [ifsName] :: IfaceNames name -> name
+ Cryptol.ModuleSystem.Interface: [ifsNested] :: IfaceNames name -> Set Name
+ Cryptol.ModuleSystem.Interface: [ifsPublic] :: IfaceNames name -> Set Name
+ Cryptol.ModuleSystem.Interface: data IfaceNames name
+ Cryptol.ModuleSystem.Interface: ifModName :: IfaceG name -> name
+ Cryptol.ModuleSystem.Interface: ifaceForgetName :: IfaceG name -> IfaceG ()
+ Cryptol.ModuleSystem.Interface: ifaceOrigNameMap :: IfaceG name -> Map Namespace (Map OrigName Name)
+ Cryptol.ModuleSystem.Interface: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (Cryptol.ModuleSystem.Interface.IfaceG name)
+ Cryptol.ModuleSystem.Interface: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (Cryptol.ModuleSystem.Interface.IfaceNames name)
+ Cryptol.ModuleSystem.Interface: instance GHC.Generics.Generic (Cryptol.ModuleSystem.Interface.IfaceG name)
+ Cryptol.ModuleSystem.Interface: instance GHC.Generics.Generic (Cryptol.ModuleSystem.Interface.IfaceNames name)
+ Cryptol.ModuleSystem.Interface: instance GHC.Show.Show name => GHC.Show.Show (Cryptol.ModuleSystem.Interface.IfaceG name)
+ Cryptol.ModuleSystem.Interface: instance GHC.Show.Show name => GHC.Show.Show (Cryptol.ModuleSystem.Interface.IfaceNames name)
+ Cryptol.ModuleSystem.Monad: ExpandPropGuardsError :: ImportSource -> Error -> ModuleError
+ Cryptol.ModuleSystem.Monad: FFILoadErrors :: ModName -> [FFILoadError] -> ModuleError
+ Cryptol.ModuleSystem.Monad: FromSigImport :: Located ModName -> ImportSource
+ Cryptol.ModuleSystem.Monad: expandPropGuardsError :: Error -> ModuleM a
+ Cryptol.ModuleSystem.Monad: ffiLoadErrors :: ModName -> [FFILoadError] -> ModuleM a
+ Cryptol.ModuleSystem.Monad: getAllLoaded :: ModuleM (ModName -> Maybe (ModuleG (), IfaceG ()))
+ Cryptol.ModuleSystem.Monad: getAllLoadedSignatures :: ModuleM (ModName -> Maybe ModParamNames)
+ Cryptol.ModuleSystem.Monad: modifyEvalEnvM :: Traversable t => (EvalEnv -> Eval (t EvalEnv)) -> ModuleM (t ())
+ Cryptol.ModuleSystem.Name: GlobalName :: NameSource -> OrigName -> NameInfo
+ Cryptol.ModuleSystem.Name: LocalName :: Namespace -> Ident -> NameInfo
+ Cryptol.ModuleSystem.Name: asLocal :: Namespace -> Name -> Name
+ Cryptol.ModuleSystem.Name: freshNameFor :: ModPath -> Name -> Supply -> (Name, Supply)
+ Cryptol.ModuleSystem.Name: mapNameIdent :: (Ident -> Ident) -> Name -> Name
+ Cryptol.ModuleSystem.Name: mkLocal :: Namespace -> Ident -> Range -> Supply -> (Name, Supply)
+ Cryptol.ModuleSystem.Name: mkModParam :: ModPath -> Ident -> Range -> Name -> Supply -> (Name, Supply)
+ Cryptol.ModuleSystem.Name: nameModPath :: Name -> ModPath
+ Cryptol.ModuleSystem.Name: nameModPathMaybe :: Name -> Maybe ModPath
+ Cryptol.ModuleSystem.Name: nameTopModule :: Name -> ModName
+ Cryptol.ModuleSystem.Name: nameTopModuleMaybe :: Name -> Maybe ModName
+ Cryptol.ModuleSystem.Name: runSupply :: Supply -> (forall m. FreshM m => m a) -> (a, Supply)
+ Cryptol.ModuleSystem.Names: Ambig :: Set Name -> Names
+ Cryptol.ModuleSystem.Names: One :: Name -> Names
+ Cryptol.ModuleSystem.Names: anyOne :: Names -> Name
+ Cryptol.ModuleSystem.Names: data Names
+ Cryptol.ModuleSystem.Names: diffNames :: Names -> Names -> Maybe Names
+ Cryptol.ModuleSystem.Names: filterNames :: (Name -> Bool) -> Names -> Maybe Names
+ Cryptol.ModuleSystem.Names: instance Control.DeepSeq.NFData Cryptol.ModuleSystem.Names.Names
+ Cryptol.ModuleSystem.Names: instance GHC.Base.Semigroup Cryptol.ModuleSystem.Names.Names
+ Cryptol.ModuleSystem.Names: instance GHC.Generics.Generic Cryptol.ModuleSystem.Names.Names
+ Cryptol.ModuleSystem.Names: instance GHC.Show.Show Cryptol.ModuleSystem.Names.Names
+ Cryptol.ModuleSystem.Names: mapNames :: (Name -> Name) -> Names -> Names
+ Cryptol.ModuleSystem.Names: namesFromSet :: Set Name -> Names
+ Cryptol.ModuleSystem.Names: namesToList :: Names -> [Name]
+ Cryptol.ModuleSystem.Names: travNames :: Applicative f => (Name -> f Name) -> Names -> f Names
+ Cryptol.ModuleSystem.Names: unionManyNames :: [Names] -> Maybe Names
+ Cryptol.ModuleSystem.NamingEnv: filterPNames :: (PName -> Bool) -> NamingEnv -> NamingEnv
+ Cryptol.ModuleSystem.NamingEnv: filterUNames :: (Name -> Bool) -> NamingEnv -> NamingEnv
+ Cryptol.ModuleSystem.NamingEnv: findAmbig :: NamingEnv -> [[Name]]
+ Cryptol.ModuleSystem.NamingEnv: findShadowing :: NamingEnv -> NamingEnv -> [(PName, Name, [Name])]
+ Cryptol.ModuleSystem.NamingEnv: forceUnambig :: NamingEnv -> NamingEnv
+ Cryptol.ModuleSystem.NamingEnv: isEmptyNamingEnv :: NamingEnv -> Bool
+ Cryptol.ModuleSystem.NamingEnv: lookupListNS :: Namespace -> PName -> NamingEnv -> [Name]
+ Cryptol.ModuleSystem.NamingEnv: mapNamingEnv :: (Name -> Name) -> NamingEnv -> NamingEnv
+ Cryptol.ModuleSystem.NamingEnv: namingEnvFromNames :: Set Name -> NamingEnv
+ Cryptol.ModuleSystem.NamingEnv: without :: NamingEnv -> NamingEnv -> NamingEnv
+ Cryptol.ModuleSystem.NamingEnv: zipByTextName :: NamingEnv -> NamingEnv -> Map Name Name
+ Cryptol.ModuleSystem.Renamer: InvalidFunctorImport :: ImpName Name -> RenamerError
+ Cryptol.ModuleSystem.Renamer: ModuleKindMismatch :: Range -> ImpName Name -> ModKind -> ModKind -> RenamerError
+ Cryptol.ModuleSystem.Renamer: MultipleModParams :: Ident -> [Range] -> RenamerError
+ Cryptol.ModuleSystem.Renamer: PrefixAssocChanged :: PrefixOp -> Expr Name -> Located Name -> Fixity -> Expr Name -> RenamerWarning
+ Cryptol.ModuleSystem.Renamer: UnexpectedNest :: Range -> PName -> RenamerError
+ Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Renamer.Rename Cryptol.Parser.AST.ModParam
+ Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Renamer.Rename Cryptol.Parser.AST.ModuleInstanceArg
+ Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Renamer.Rename Cryptol.Parser.AST.ModuleInstanceArgs
+ Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Renamer.Rename Cryptol.Parser.AST.ModuleInstanceNamedArg
+ Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Renamer.Rename Cryptol.Parser.AST.NestedModule
+ Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Renamer.Rename Cryptol.Parser.AST.PropGuardCase
+ Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Renamer.Rename Cryptol.Parser.AST.SigDecl
+ Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Renamer.Rename Cryptol.Parser.AST.TopDecl
+ Cryptol.ModuleSystem.Renamer: instance Cryptol.Utils.PP.PP Cryptol.ModuleSystem.Renamer.RenamedModule
+ Cryptol.ModuleSystem.Renamer.Error: AFunctor :: ModKind
+ Cryptol.ModuleSystem.Renamer.Error: AModule :: ModKind
+ Cryptol.ModuleSystem.Renamer.Error: ASignature :: ModKind
+ Cryptol.ModuleSystem.Renamer.Error: InvalidFunctorImport :: ImpName Name -> RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: ModParamName :: Range -> Ident -> DepName
+ Cryptol.ModuleSystem.Renamer.Error: ModPath :: ModPath -> DepName
+ Cryptol.ModuleSystem.Renamer.Error: ModuleKindMismatch :: Range -> ImpName Name -> ModKind -> ModKind -> RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: MultipleModParams :: Ident -> [Range] -> RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: PrefixAssocChanged :: PrefixOp -> Expr Name -> Located Name -> Fixity -> Expr Name -> RenamerWarning
+ Cryptol.ModuleSystem.Renamer.Error: UnexpectedNest :: Range -> PName -> RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: data ModKind
+ Cryptol.ModuleSystem.Renamer.Error: instance Control.DeepSeq.NFData Cryptol.ModuleSystem.Renamer.Error.ModKind
+ Cryptol.ModuleSystem.Renamer.Error: instance Cryptol.Utils.PP.PP Cryptol.ModuleSystem.Renamer.Error.ModKind
+ Cryptol.ModuleSystem.Renamer.Error: instance GHC.Classes.Eq Cryptol.ModuleSystem.Renamer.Error.ModKind
+ Cryptol.ModuleSystem.Renamer.Error: instance GHC.Classes.Eq Cryptol.ModuleSystem.Renamer.Error.RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: instance GHC.Classes.Ord Cryptol.ModuleSystem.Renamer.Error.ModKind
+ Cryptol.ModuleSystem.Renamer.Error: instance GHC.Classes.Ord Cryptol.ModuleSystem.Renamer.Error.RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: instance GHC.Generics.Generic Cryptol.ModuleSystem.Renamer.Error.ModKind
+ Cryptol.ModuleSystem.Renamer.Error: instance GHC.Show.Show Cryptol.ModuleSystem.Renamer.Error.ModKind
+ Cryptol.ModuleSystem.Renamer.ImplicitImports: addImplicitNestedImports :: [TopDecl PName] -> [TopDecl PName]
+ Cryptol.ModuleSystem.Renamer.Imports: AFunctor :: ModKind
+ Cryptol.ModuleSystem.Renamer.Imports: AModule :: ModKind
+ Cryptol.ModuleSystem.Renamer.Imports: ASignature :: ModKind
+ Cryptol.ModuleSystem.Renamer.Imports: ResolvedModule :: NamingEnv -> !Set Name -> ModKind -> Set Name -> imps -> ResolvedModule imps
+ Cryptol.ModuleSystem.Renamer.Imports: [rmodDefines] :: ResolvedModule imps -> NamingEnv
+ Cryptol.ModuleSystem.Renamer.Imports: [rmodImports] :: ResolvedModule imps -> imps
+ Cryptol.ModuleSystem.Renamer.Imports: [rmodKind] :: ResolvedModule imps -> ModKind
+ Cryptol.ModuleSystem.Renamer.Imports: [rmodNested] :: ResolvedModule imps -> Set Name
+ Cryptol.ModuleSystem.Renamer.Imports: [rmodPublic] :: ResolvedModule imps -> !Set Name
+ Cryptol.ModuleSystem.Renamer.Imports: data ModKind
+ Cryptol.ModuleSystem.Renamer.Imports: data ResolvedModule imps
+ Cryptol.ModuleSystem.Renamer.Imports: instance Cryptol.ModuleSystem.Renamer.Imports.HasCurScope ()
+ Cryptol.ModuleSystem.Renamer.Imports: instance Cryptol.ModuleSystem.Renamer.Imports.HasCurScope Cryptol.ModuleSystem.Renamer.Imports.Todo
+ Cryptol.ModuleSystem.Renamer.Imports: resolveImports :: (ImpName Name -> Mod ()) -> TopDef -> Supply -> (Map (ImpName Name) ResolvedLocal, Supply)
+ Cryptol.ModuleSystem.Renamer.Imports: type ResolvedExt = ResolvedModule ()
+ Cryptol.ModuleSystem.Renamer.Imports: type ResolvedLocal = ResolvedModule NamingEnv
+ Cryptol.ModuleSystem.Renamer.Monad: RenModParam :: Ident -> Range -> ImpName Name -> Map Name Name -> RenModParam
+ Cryptol.ModuleSystem.Renamer.Monad: [renModParamInstance] :: RenModParam -> Map Name Name
+ Cryptol.ModuleSystem.Renamer.Monad: [renModParamName] :: RenModParam -> Ident
+ Cryptol.ModuleSystem.Renamer.Monad: [renModParamRange] :: RenModParam -> Range
+ Cryptol.ModuleSystem.Renamer.Monad: [renModParamSig] :: RenModParam -> ImpName Name
+ Cryptol.ModuleSystem.Renamer.Monad: [roExternal] :: RO -> Map ModName (Maybe Iface, Map (ImpName Name) (Mod ()))
+ Cryptol.ModuleSystem.Renamer.Monad: [roFromModParam] :: RO -> Map Name DepName
+ Cryptol.ModuleSystem.Renamer.Monad: [roModParams] :: RO -> Map Ident RenModParam
+ Cryptol.ModuleSystem.Renamer.Monad: [roResolvedModules] :: RO -> Map (ImpName Name) ResolvedLocal
+ Cryptol.ModuleSystem.Renamer.Monad: checkIsModule :: Range -> ImpName Name -> ModKind -> RenameM ()
+ Cryptol.ModuleSystem.Renamer.Monad: checkOverlap :: NamingEnv -> RenameM NamingEnv
+ Cryptol.ModuleSystem.Renamer.Monad: checkShadowing :: NamingEnv -> NamingEnv -> RenameM ()
+ Cryptol.ModuleSystem.Renamer.Monad: data RenModParam
+ Cryptol.ModuleSystem.Renamer.Monad: foldLoop :: [a] -> b -> (a -> b -> b) -> b
+ Cryptol.ModuleSystem.Renamer.Monad: getExternal :: RenameM (ImpName Name -> Mod ())
+ Cryptol.ModuleSystem.Renamer.Monad: getExternalMod :: ImpName Name -> RenameM (Mod ())
+ Cryptol.ModuleSystem.Renamer.Monad: getLocalModParamDeps :: RenameM (Map Ident DepName)
+ Cryptol.ModuleSystem.Renamer.Monad: getModParam :: Ident -> RenameM RenModParam
+ Cryptol.ModuleSystem.Renamer.Monad: getNamesFromModParams :: RenameM (Map Name DepName)
+ Cryptol.ModuleSystem.Renamer.Monad: getTopModuleIface :: ImpName Name -> RenameM (Maybe Iface)
+ Cryptol.ModuleSystem.Renamer.Monad: lookupDefines :: ImpName Name -> RenameM NamingEnv
+ Cryptol.ModuleSystem.Renamer.Monad: lookupDefinesAndSubs :: ImpName Name -> RenameM (NamingEnv, Set Name)
+ Cryptol.ModuleSystem.Renamer.Monad: lookupModuleThing :: ImpName Name -> RenameM (Either ResolvedLocal (Mod ()))
+ Cryptol.ModuleSystem.Renamer.Monad: lookupResolved :: ImpName Name -> RenameM ResolvedLocal
+ Cryptol.ModuleSystem.Renamer.Monad: recordError :: RenamerError -> RenameM ()
+ Cryptol.ModuleSystem.Renamer.Monad: recordImport :: Range -> ImpName Name -> RenameM ()
+ Cryptol.ModuleSystem.Renamer.Monad: recordWarning :: RenamerWarning -> RenameM ()
+ Cryptol.ModuleSystem.Renamer.Monad: setModParams :: [RenModParam] -> RenameM a -> RenameM a
+ Cryptol.ModuleSystem.Renamer.Monad: setResolvedLocals :: Map (ImpName Name) ResolvedLocal -> RenameM a -> RenameM a
+ Cryptol.Parser: RST :: PreProc
+ Cryptol.Parser.AST: AddParams :: ModuleInstanceArg name
+ Cryptol.Parser.AST: DForeign :: BindDef name
+ Cryptol.Parser.AST: DInterfaceConstraint :: Maybe Text -> Located [Prop name] -> TopDecl name
+ Cryptol.Parser.AST: DModParam :: ModParam name -> TopDecl name
+ Cryptol.Parser.AST: DParamDecl :: Range -> Signature name -> TopDecl name
+ Cryptol.Parser.AST: DParameterDecl :: SigDecl name -> ParamDecl name
+ Cryptol.Parser.AST: DPropGuards :: [PropGuardCase name] -> BindDef name
+ Cryptol.Parser.AST: DefaultInstAnonArg :: [TopDecl name] -> ModuleInstanceArgs name
+ Cryptol.Parser.AST: DefaultInstArg :: Located (ModuleInstanceArg name) -> ModuleInstanceArgs name
+ Cryptol.Parser.AST: EPrefix :: PrefixOp -> Expr n -> Expr n
+ Cryptol.Parser.AST: ExpandPropGuards :: String -> Pass
+ Cryptol.Parser.AST: FunctorInstance :: Located (ImpName name) -> ModuleInstanceArgs name -> ModuleInstance name -> ModuleDefinition name
+ Cryptol.Parser.AST: InterfaceModule :: Signature name -> ModuleDefinition name
+ Cryptol.Parser.AST: ModParam :: Located (ImpName name) -> Maybe ModName -> !Ident -> Maybe (Located Text) -> !Map name name -> ModParam name
+ Cryptol.Parser.AST: ModuleArg :: ImpName name -> ModuleInstanceArg name
+ Cryptol.Parser.AST: ModuleInstanceNamedArg :: Located Ident -> Located (ModuleInstanceArg name) -> ModuleInstanceNamedArg name
+ Cryptol.Parser.AST: NamedInstArgs :: [ModuleInstanceNamedArg name] -> ModuleInstanceArgs name
+ Cryptol.Parser.AST: NormalModule :: [TopDecl name] -> ModuleDefinition name
+ Cryptol.Parser.AST: ParameterArg :: Ident -> ModuleInstanceArg name
+ Cryptol.Parser.AST: PrefixComplement :: PrefixOp
+ Cryptol.Parser.AST: PrefixNeg :: PrefixOp
+ Cryptol.Parser.AST: PropGuardCase :: [Located (Prop name)] -> Expr name -> PropGuardCase name
+ Cryptol.Parser.AST: SigPropSyn :: PropSyn name -> Maybe Text -> SigDecl name
+ Cryptol.Parser.AST: SigTySyn :: TySyn name -> Maybe Text -> SigDecl name
+ Cryptol.Parser.AST: Signature :: ![Located (ImportG (ImpName name))] -> [ParameterType name] -> [Located (Prop name)] -> [SigDecl name] -> [ParameterFun name] -> Signature name
+ Cryptol.Parser.AST: [iInst] :: ImportG mname -> !Maybe (ModuleInstanceArgs PName)
+ Cryptol.Parser.AST: [mDef] :: ModuleG mname name -> ModuleDefinition name
+ Cryptol.Parser.AST: [mpAs] :: ModParam name -> Maybe ModName
+ Cryptol.Parser.AST: [mpDoc] :: ModParam name -> Maybe (Located Text)
+ Cryptol.Parser.AST: [mpName] :: ModParam name -> !Ident
+ Cryptol.Parser.AST: [mpRenaming] :: ModParam name -> !Map name name
+ Cryptol.Parser.AST: [mpSignature] :: ModParam name -> Located (ImpName name)
+ Cryptol.Parser.AST: [nConName] :: Newtype name -> !name
+ Cryptol.Parser.AST: [pgcExpr] :: PropGuardCase name -> Expr name
+ Cryptol.Parser.AST: [pgcProps] :: PropGuardCase name -> [Located (Prop name)]
+ Cryptol.Parser.AST: [sigConstraints] :: Signature name -> [Located (Prop name)]
+ Cryptol.Parser.AST: [sigDecls] :: Signature name -> [SigDecl name]
+ Cryptol.Parser.AST: [sigFunParams] :: Signature name -> [ParameterFun name]
+ Cryptol.Parser.AST: [sigImports] :: Signature name -> ![Located (ImportG (ImpName name))]
+ Cryptol.Parser.AST: [sigTypeParams] :: Signature name -> [ParameterType name]
+ Cryptol.Parser.AST: asEApps :: Expr n -> (Expr n, [Expr n])
+ Cryptol.Parser.AST: data ModParam name
+ Cryptol.Parser.AST: data ModuleDefinition name
+ Cryptol.Parser.AST: data ModuleInstanceArg name
+ Cryptol.Parser.AST: data ModuleInstanceArgs name
+ Cryptol.Parser.AST: data ModuleInstanceNamedArg name
+ Cryptol.Parser.AST: data ParamDecl name
+ Cryptol.Parser.AST: data PrefixOp
+ Cryptol.Parser.AST: data PropGuardCase name
+ Cryptol.Parser.AST: data SigDecl name
+ Cryptol.Parser.AST: data Signature name
+ Cryptol.Parser.AST: emptyModuleInstance :: Ord name => ModuleInstance name
+ Cryptol.Parser.AST: instance (GHC.Show.Show name, Cryptol.Utils.PP.PPName name) => Cryptol.Utils.PP.PP (Cryptol.Parser.AST.ModParam name)
+ Cryptol.Parser.AST: instance (GHC.Show.Show name, Cryptol.Utils.PP.PPName name) => Cryptol.Utils.PP.PP (Cryptol.Parser.AST.ModuleDefinition name)
+ Cryptol.Parser.AST: instance (GHC.Show.Show name, Cryptol.Utils.PP.PPName name) => Cryptol.Utils.PP.PP (Cryptol.Parser.AST.ModuleInstanceArg name)
+ Cryptol.Parser.AST: instance (GHC.Show.Show name, Cryptol.Utils.PP.PPName name) => Cryptol.Utils.PP.PP (Cryptol.Parser.AST.ModuleInstanceArgs name)
+ Cryptol.Parser.AST: instance (GHC.Show.Show name, Cryptol.Utils.PP.PPName name) => Cryptol.Utils.PP.PP (Cryptol.Parser.AST.ModuleInstanceNamedArg name)
+ Cryptol.Parser.AST: instance (GHC.Show.Show name, Cryptol.Utils.PP.PPName name) => Cryptol.Utils.PP.PP (Cryptol.Parser.AST.ParamDecl name)
+ Cryptol.Parser.AST: instance (GHC.Show.Show name, Cryptol.Utils.PP.PPName name) => Cryptol.Utils.PP.PP (Cryptol.Parser.AST.SigDecl name)
+ Cryptol.Parser.AST: instance Control.DeepSeq.NFData Cryptol.Parser.AST.PrefixOp
+ Cryptol.Parser.AST: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (Cryptol.Parser.AST.ModParam name)
+ Cryptol.Parser.AST: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (Cryptol.Parser.AST.ModuleDefinition name)
+ Cryptol.Parser.AST: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (Cryptol.Parser.AST.ModuleInstanceArg name)
+ Cryptol.Parser.AST: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (Cryptol.Parser.AST.ModuleInstanceArgs name)
+ Cryptol.Parser.AST: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (Cryptol.Parser.AST.ModuleInstanceNamedArg name)
+ Cryptol.Parser.AST: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (Cryptol.Parser.AST.ParamDecl name)
+ Cryptol.Parser.AST: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (Cryptol.Parser.AST.PropGuardCase name)
+ Cryptol.Parser.AST: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (Cryptol.Parser.AST.SigDecl name)
+ Cryptol.Parser.AST: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (Cryptol.Parser.AST.Signature name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.AST.NoPos (Cryptol.Parser.AST.ModParam name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.AST.NoPos (Cryptol.Parser.AST.ModuleDefinition name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.AST.NoPos (Cryptol.Parser.AST.ModuleInstanceArgs name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.AST.NoPos (Cryptol.Parser.AST.ModuleInstanceNamedArg name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.AST.NoPos (Cryptol.Parser.AST.ParamDecl name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.AST.NoPos (Cryptol.Parser.AST.SigDecl name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.AST.NoPos (Cryptol.Parser.AST.Signature name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.Position.HasLoc (Cryptol.Parser.AST.ModParam name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.Position.HasLoc (Cryptol.Parser.AST.ParamDecl name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.Position.HasLoc (Cryptol.Parser.AST.PropSyn name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.Position.HasLoc (Cryptol.Parser.AST.SigDecl name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.Position.HasLoc (Cryptol.Parser.AST.TySyn name)
+ Cryptol.Parser.AST: instance Cryptol.Utils.PP.PPName name => Cryptol.Utils.PP.PP [Cryptol.Parser.AST.Prop name]
+ Cryptol.Parser.AST: instance GHC.Base.Functor Cryptol.Parser.AST.PropGuardCase
+ Cryptol.Parser.AST: instance GHC.Classes.Eq Cryptol.Parser.AST.PrefixOp
+ Cryptol.Parser.AST: instance GHC.Classes.Eq name => GHC.Classes.Eq (Cryptol.Parser.AST.ImpName name)
+ Cryptol.Parser.AST: instance GHC.Classes.Eq name => GHC.Classes.Eq (Cryptol.Parser.AST.ModParam name)
+ Cryptol.Parser.AST: instance GHC.Classes.Eq name => GHC.Classes.Eq (Cryptol.Parser.AST.PropGuardCase name)
+ Cryptol.Parser.AST: instance GHC.Classes.Ord name => GHC.Classes.Ord (Cryptol.Parser.AST.ImpName name)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.ModParam name)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.ModuleDefinition name)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.ModuleInstanceArg name)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.ModuleInstanceArgs name)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.ModuleInstanceNamedArg name)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.ParamDecl name)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.PropGuardCase name)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.SigDecl name)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.Signature name)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic Cryptol.Parser.AST.PrefixOp
+ Cryptol.Parser.AST: instance GHC.Show.Show Cryptol.Parser.AST.PrefixOp
+ Cryptol.Parser.AST: instance GHC.Show.Show name => GHC.Show.Show (Cryptol.Parser.AST.ModParam name)
+ Cryptol.Parser.AST: instance GHC.Show.Show name => GHC.Show.Show (Cryptol.Parser.AST.ModuleDefinition name)
+ Cryptol.Parser.AST: instance GHC.Show.Show name => GHC.Show.Show (Cryptol.Parser.AST.ModuleInstanceArg name)
+ Cryptol.Parser.AST: instance GHC.Show.Show name => GHC.Show.Show (Cryptol.Parser.AST.ModuleInstanceArgs name)
+ Cryptol.Parser.AST: instance GHC.Show.Show name => GHC.Show.Show (Cryptol.Parser.AST.ModuleInstanceNamedArg name)
+ Cryptol.Parser.AST: instance GHC.Show.Show name => GHC.Show.Show (Cryptol.Parser.AST.ParamDecl name)
+ Cryptol.Parser.AST: instance GHC.Show.Show name => GHC.Show.Show (Cryptol.Parser.AST.PropGuardCase name)
+ Cryptol.Parser.AST: instance GHC.Show.Show name => GHC.Show.Show (Cryptol.Parser.AST.SigDecl name)
+ Cryptol.Parser.AST: instance GHC.Show.Show name => GHC.Show.Show (Cryptol.Parser.AST.Signature name)
+ Cryptol.Parser.AST: isParamDecl :: TopDecl a -> Bool
+ Cryptol.Parser.AST: mDecls :: ModuleG mname name -> [TopDecl name]
+ Cryptol.Parser.AST: mIsFunctor :: ModuleG mname nmae -> Bool
+ Cryptol.Parser.AST: mModParams :: ModuleG mname name -> [ModParam name]
+ Cryptol.Parser.AST: prefixFixity :: PrefixOp -> Fixity
+ Cryptol.Parser.AST: type ModuleInstance name = Map name name
+ Cryptol.Parser.ExpandPropGuards: NoSignature :: Located PName -> Error
+ Cryptol.Parser.ExpandPropGuards: data Error
+ Cryptol.Parser.ExpandPropGuards: expandBind :: Bind PName -> ExpandPropGuardsM [Bind PName]
+ Cryptol.Parser.ExpandPropGuards: expandDecl :: Decl PName -> ExpandPropGuardsM [Decl PName]
+ Cryptol.Parser.ExpandPropGuards: expandModuleDef :: ModuleDefinition PName -> ExpandPropGuardsM (ModuleDefinition PName)
+ Cryptol.Parser.ExpandPropGuards: expandPropGuards :: ModuleG mname PName -> ExpandPropGuardsM (ModuleG mname PName)
+ Cryptol.Parser.ExpandPropGuards: expandTopDecl :: TopDecl PName -> ExpandPropGuardsM [TopDecl PName]
+ Cryptol.Parser.ExpandPropGuards: instance Control.DeepSeq.NFData Cryptol.Parser.ExpandPropGuards.Error
+ Cryptol.Parser.ExpandPropGuards: instance Cryptol.Utils.PP.PP Cryptol.Parser.ExpandPropGuards.Error
+ Cryptol.Parser.ExpandPropGuards: instance GHC.Generics.Generic Cryptol.Parser.ExpandPropGuards.Error
+ Cryptol.Parser.ExpandPropGuards: instance GHC.Show.Show Cryptol.Parser.ExpandPropGuards.Error
+ Cryptol.Parser.ExpandPropGuards: newName :: Located PName -> [Prop PName] -> ExpandPropGuardsM (Located PName)
+ Cryptol.Parser.ExpandPropGuards: patternToExpr :: Pattern PName -> Expr PName
+ Cryptol.Parser.ExpandPropGuards: runExpandPropGuardsM :: ExpandPropGuardsM a -> Either Error a
+ Cryptol.Parser.ExpandPropGuards: type ExpandPropGuardsM a = Either Error a
+ Cryptol.Parser.Lexer: KW_foreign :: TokenKW
+ Cryptol.Parser.Lexer: KW_interface :: TokenKW
+ Cryptol.Parser.Name: ExpandPropGuards :: String -> Pass
+ Cryptol.Parser.Names: namesNT :: Newtype name -> ([Located name], ())
+ Cryptol.Parser.Position: rangeWithin :: Range -> Range -> Bool
+ Cryptol.Parser.Token: KW_foreign :: TokenKW
+ Cryptol.Parser.Token: KW_interface :: TokenKW
+ Cryptol.Parser.Unlit: RST :: PreProc
+ Cryptol.REPL.Help: helpForNamed :: PName -> REPL ()
+ Cryptol.REPL.Monad: InstantiationsNotFound :: Schema -> REPLException
+ Cryptol.REPL.Monad: getRandomGen :: REPL TFGen
+ Cryptol.REPL.Monad: setRandomGen :: TFGen -> REPL ()
+ Cryptol.REPL.Monad: withRandomGen :: (TFGen -> REPL (a, TFGen)) -> REPL a
+ Cryptol.Testing.Random: randomTests' :: (MonadIO m, RandomGen g) => (Integer -> m ()) -> Integer -> Value -> [Gen g Concrete] -> g -> m ((TestResult, Integer), g)
+ Cryptol.Testing.Random: returnTests' :: RandomGen g => g -> [Gen g Concrete] -> Value -> Int -> IO ([([Value], Value)], g)
+ Cryptol.TypeCheck: DeclarationRequiresSignatureCtrGrd :: Ident -> Error
+ Cryptol.TypeCheck: FunctorInstanceBadArgument :: Ident -> Error
+ Cryptol.TypeCheck: FunctorInstanceBadBacktick :: BadBacktickInstance -> Error
+ Cryptol.TypeCheck: FunctorInstanceMissingArgument :: Ident -> Error
+ Cryptol.TypeCheck: FunctorInstanceMissingName :: Namespace -> Ident -> Error
+ Cryptol.TypeCheck: InvalidConstraintGuard :: Prop -> Error
+ Cryptol.TypeCheck: MissingModParam :: Ident -> Error
+ Cryptol.TypeCheck: NestedConstraintGuard :: Ident -> Error
+ Cryptol.TypeCheck: NonExhaustivePropGuards :: Name -> Warning
+ Cryptol.TypeCheck: SchemaMismatch :: Ident -> Schema -> Schema -> Error
+ Cryptol.TypeCheck: UnsupportedFFIKind :: TypeSource -> TParam -> Kind -> Error
+ Cryptol.TypeCheck: UnsupportedFFIType :: TypeSource -> FFITypeError -> Error
+ Cryptol.TypeCheck: [inpParams] :: InferInput -> !ModParamNames
+ Cryptol.TypeCheck: [inpSignatures] :: InferInput -> !Map Name ModParamNames
+ Cryptol.TypeCheck: [inpTopModules] :: InferInput -> ModName -> Maybe (ModuleG (), IfaceG ())
+ Cryptol.TypeCheck: [inpTopSignatures] :: InferInput -> ModName -> Maybe ModParamNames
+ Cryptol.TypeCheck.AST: DForeign :: FFIFunType -> DeclDef
+ Cryptol.TypeCheck.AST: EPropGuards :: [([Prop], Expr)] -> Type -> Expr
+ Cryptol.TypeCheck.AST: ImpNested :: name -> ImpName name
+ Cryptol.TypeCheck.AST: ImpTop :: ModName -> ImpName name
+ Cryptol.TypeCheck.AST: TCTopModule :: ModuleG ModName -> TCTopEntity
+ Cryptol.TypeCheck.AST: TCTopSignature :: ModName -> ModParamNames -> TCTopEntity
+ Cryptol.TypeCheck.AST: [iInst] :: ImportG mname -> !Maybe (ModuleInstanceArgs PName)
+ Cryptol.TypeCheck.AST: [mDoc] :: ModuleG mname -> !Maybe Text
+ Cryptol.TypeCheck.AST: [mNested] :: ModuleG mname -> !Set Name
+ Cryptol.TypeCheck.AST: [mParams] :: ModuleG mname -> FunctorParams
+ Cryptol.TypeCheck.AST: [mSignatures] :: ModuleG mname -> !Map Name ModParamNames
+ Cryptol.TypeCheck.AST: [mSubmodules] :: ModuleG mname -> Map Name (IfaceNames Name)
+ Cryptol.TypeCheck.AST: data ImpName name
+ Cryptol.TypeCheck.AST: data TCTopEntity
+ Cryptol.TypeCheck.AST: dropLocs :: Expr -> Expr
+ Cryptol.TypeCheck.AST: findForeignDecls :: ModuleG mname -> [(Name, FFIFunType)]
+ Cryptol.TypeCheck.AST: findForeignDeclsInFunctors :: ModuleG mname -> [Name]
+ Cryptol.TypeCheck.AST: instance Control.DeepSeq.NFData Cryptol.TypeCheck.AST.TCTopEntity
+ Cryptol.TypeCheck.AST: instance Cryptol.Utils.PP.PP (Cryptol.TypeCheck.PP.WithNames Cryptol.TypeCheck.AST.TCTopEntity)
+ Cryptol.TypeCheck.AST: instance Cryptol.Utils.PP.PP Cryptol.TypeCheck.AST.TCTopEntity
+ Cryptol.TypeCheck.AST: instance GHC.Generics.Generic Cryptol.TypeCheck.AST.TCTopEntity
+ Cryptol.TypeCheck.AST: instance GHC.Show.Show Cryptol.TypeCheck.AST.TCTopEntity
+ Cryptol.TypeCheck.AST: splitApp :: Expr -> Maybe (Expr, Expr)
+ Cryptol.TypeCheck.AST: splitLoc :: Expr -> Maybe (Range, Expr)
+ Cryptol.TypeCheck.AST: tcTopEntityToModule :: TCTopEntity -> Module
+ Cryptol.TypeCheck.AST: tcTopEntitytName :: TCTopEntity -> ModName
+ Cryptol.TypeCheck.Error: BIAbstractType :: BIWhat
+ Cryptol.TypeCheck.Error: BIForeign :: BIWhat
+ Cryptol.TypeCheck.Error: BIFunctor :: BIWhat
+ Cryptol.TypeCheck.Error: BIInterface :: BIWhat
+ Cryptol.TypeCheck.Error: BIMultipleParams :: Ident -> BadBacktickInstance
+ Cryptol.TypeCheck.Error: BINested :: [(BIWhat, Name)] -> BadBacktickInstance
+ Cryptol.TypeCheck.Error: BIPolymorphicArgument :: Ident -> Ident -> BadBacktickInstance
+ Cryptol.TypeCheck.Error: BIPrimitive :: BIWhat
+ Cryptol.TypeCheck.Error: DeclarationRequiresSignatureCtrGrd :: Ident -> Error
+ Cryptol.TypeCheck.Error: FunctorInstanceBadArgument :: Ident -> Error
+ Cryptol.TypeCheck.Error: FunctorInstanceBadBacktick :: BadBacktickInstance -> Error
+ Cryptol.TypeCheck.Error: FunctorInstanceMissingArgument :: Ident -> Error
+ Cryptol.TypeCheck.Error: FunctorInstanceMissingName :: Namespace -> Ident -> Error
+ Cryptol.TypeCheck.Error: InvalidConstraintGuard :: Prop -> Error
+ Cryptol.TypeCheck.Error: MissingModParam :: Ident -> Error
+ Cryptol.TypeCheck.Error: NestedConstraintGuard :: Ident -> Error
+ Cryptol.TypeCheck.Error: NonExhaustivePropGuards :: Name -> Warning
+ Cryptol.TypeCheck.Error: SchemaMismatch :: Ident -> Schema -> Schema -> Error
+ Cryptol.TypeCheck.Error: UnsupportedFFIKind :: TypeSource -> TParam -> Kind -> Error
+ Cryptol.TypeCheck.Error: UnsupportedFFIType :: TypeSource -> FFITypeError -> Error
+ Cryptol.TypeCheck.Error: data BIWhat
+ Cryptol.TypeCheck.Error: data BadBacktickInstance
+ Cryptol.TypeCheck.Error: instance Control.DeepSeq.NFData Cryptol.TypeCheck.Error.BIWhat
+ Cryptol.TypeCheck.Error: instance Control.DeepSeq.NFData Cryptol.TypeCheck.Error.BadBacktickInstance
+ Cryptol.TypeCheck.Error: instance GHC.Generics.Generic Cryptol.TypeCheck.Error.BIWhat
+ Cryptol.TypeCheck.Error: instance GHC.Generics.Generic Cryptol.TypeCheck.Error.BadBacktickInstance
+ Cryptol.TypeCheck.Error: instance GHC.Show.Show Cryptol.TypeCheck.Error.BIWhat
+ Cryptol.TypeCheck.Error: instance GHC.Show.Show Cryptol.TypeCheck.Error.BadBacktickInstance
+ Cryptol.TypeCheck.FFI: toFFIFunType :: Schema -> Either FFITypeError ([Prop], FFIFunType)
+ Cryptol.TypeCheck.FFI.Error: FFIBadArrayType :: FFITypeErrorReason
+ Cryptol.TypeCheck.FFI.Error: FFIBadComponentTypes :: [FFITypeError] -> FFITypeErrorReason
+ Cryptol.TypeCheck.FFI.Error: FFIBadFloatSize :: FFITypeErrorReason
+ Cryptol.TypeCheck.FFI.Error: FFIBadType :: FFITypeErrorReason
+ Cryptol.TypeCheck.FFI.Error: FFIBadWordSize :: FFITypeErrorReason
+ Cryptol.TypeCheck.FFI.Error: FFINotFunction :: FFITypeErrorReason
+ Cryptol.TypeCheck.FFI.Error: FFITypeError :: Type -> FFITypeErrorReason -> FFITypeError
+ Cryptol.TypeCheck.FFI.Error: data FFITypeError
+ Cryptol.TypeCheck.FFI.Error: data FFITypeErrorReason
+ Cryptol.TypeCheck.FFI.Error: instance Control.DeepSeq.NFData Cryptol.TypeCheck.FFI.Error.FFITypeError
+ Cryptol.TypeCheck.FFI.Error: instance Control.DeepSeq.NFData Cryptol.TypeCheck.FFI.Error.FFITypeErrorReason
+ Cryptol.TypeCheck.FFI.Error: instance Cryptol.TypeCheck.Subst.TVars Cryptol.TypeCheck.FFI.Error.FFITypeError
+ Cryptol.TypeCheck.FFI.Error: instance Cryptol.TypeCheck.Subst.TVars Cryptol.TypeCheck.FFI.Error.FFITypeErrorReason
+ Cryptol.TypeCheck.FFI.Error: instance Cryptol.TypeCheck.Type.FVS Cryptol.TypeCheck.FFI.Error.FFITypeError
+ Cryptol.TypeCheck.FFI.Error: instance Cryptol.TypeCheck.Type.FVS Cryptol.TypeCheck.FFI.Error.FFITypeErrorReason
+ Cryptol.TypeCheck.FFI.Error: instance Cryptol.Utils.PP.PP (Cryptol.TypeCheck.PP.WithNames Cryptol.TypeCheck.FFI.Error.FFITypeError)
+ Cryptol.TypeCheck.FFI.Error: instance Cryptol.Utils.PP.PP (Cryptol.TypeCheck.PP.WithNames Cryptol.TypeCheck.FFI.Error.FFITypeErrorReason)
+ Cryptol.TypeCheck.FFI.Error: instance GHC.Generics.Generic Cryptol.TypeCheck.FFI.Error.FFITypeError
+ Cryptol.TypeCheck.FFI.Error: instance GHC.Generics.Generic Cryptol.TypeCheck.FFI.Error.FFITypeErrorReason
+ Cryptol.TypeCheck.FFI.Error: instance GHC.Show.Show Cryptol.TypeCheck.FFI.Error.FFITypeError
+ Cryptol.TypeCheck.FFI.Error: instance GHC.Show.Show Cryptol.TypeCheck.FFI.Error.FFITypeErrorReason
+ Cryptol.TypeCheck.FFI.FFIType: FFIArray :: [Type] -> FFIBasicType -> FFIType
+ Cryptol.TypeCheck.FFI.FFIType: FFIBasic :: FFIBasicType -> FFIType
+ Cryptol.TypeCheck.FFI.FFIType: FFIBasicRef :: FFIBasicRefType -> FFIBasicType
+ Cryptol.TypeCheck.FFI.FFIType: FFIBasicVal :: FFIBasicValType -> FFIBasicType
+ Cryptol.TypeCheck.FFI.FFIType: FFIBool :: FFIType
+ Cryptol.TypeCheck.FFI.FFIType: FFIFloat :: Integer -> Integer -> FFIFloatSize -> FFIBasicValType
+ Cryptol.TypeCheck.FFI.FFIType: FFIFloat32 :: FFIFloatSize
+ Cryptol.TypeCheck.FFI.FFIType: FFIFloat64 :: FFIFloatSize
+ Cryptol.TypeCheck.FFI.FFIType: FFIFunType :: [TParam] -> [FFIType] -> FFIType -> FFIFunType
+ Cryptol.TypeCheck.FFI.FFIType: FFIInteger :: Maybe Type -> FFIBasicRefType
+ Cryptol.TypeCheck.FFI.FFIType: FFIRational :: FFIBasicRefType
+ Cryptol.TypeCheck.FFI.FFIType: FFIRecord :: RecordMap Ident FFIType -> FFIType
+ Cryptol.TypeCheck.FFI.FFIType: FFITuple :: [FFIType] -> FFIType
+ Cryptol.TypeCheck.FFI.FFIType: FFIWord :: Integer -> FFIWordSize -> FFIBasicValType
+ Cryptol.TypeCheck.FFI.FFIType: FFIWord16 :: FFIWordSize
+ Cryptol.TypeCheck.FFI.FFIType: FFIWord32 :: FFIWordSize
+ Cryptol.TypeCheck.FFI.FFIType: FFIWord64 :: FFIWordSize
+ Cryptol.TypeCheck.FFI.FFIType: FFIWord8 :: FFIWordSize
+ Cryptol.TypeCheck.FFI.FFIType: [ffiArgTypes] :: FFIFunType -> [FFIType]
+ Cryptol.TypeCheck.FFI.FFIType: [ffiRetType] :: FFIFunType -> FFIType
+ Cryptol.TypeCheck.FFI.FFIType: [ffiTParams] :: FFIFunType -> [TParam]
+ Cryptol.TypeCheck.FFI.FFIType: data FFIBasicRefType
+ Cryptol.TypeCheck.FFI.FFIType: data FFIBasicType
+ Cryptol.TypeCheck.FFI.FFIType: data FFIBasicValType
+ Cryptol.TypeCheck.FFI.FFIType: data FFIFloatSize
+ Cryptol.TypeCheck.FFI.FFIType: data FFIFunType
+ Cryptol.TypeCheck.FFI.FFIType: data FFIType
+ Cryptol.TypeCheck.FFI.FFIType: data FFIWordSize
+ Cryptol.TypeCheck.FFI.FFIType: instance Control.DeepSeq.NFData Cryptol.TypeCheck.FFI.FFIType.FFIBasicRefType
+ Cryptol.TypeCheck.FFI.FFIType: instance Control.DeepSeq.NFData Cryptol.TypeCheck.FFI.FFIType.FFIBasicType
+ Cryptol.TypeCheck.FFI.FFIType: instance Control.DeepSeq.NFData Cryptol.TypeCheck.FFI.FFIType.FFIBasicValType
+ Cryptol.TypeCheck.FFI.FFIType: instance Control.DeepSeq.NFData Cryptol.TypeCheck.FFI.FFIType.FFIFloatSize
+ Cryptol.TypeCheck.FFI.FFIType: instance Control.DeepSeq.NFData Cryptol.TypeCheck.FFI.FFIType.FFIFunType
+ Cryptol.TypeCheck.FFI.FFIType: instance Control.DeepSeq.NFData Cryptol.TypeCheck.FFI.FFIType.FFIType
+ Cryptol.TypeCheck.FFI.FFIType: instance Control.DeepSeq.NFData Cryptol.TypeCheck.FFI.FFIType.FFIWordSize
+ Cryptol.TypeCheck.FFI.FFIType: instance GHC.Generics.Generic Cryptol.TypeCheck.FFI.FFIType.FFIBasicRefType
+ Cryptol.TypeCheck.FFI.FFIType: instance GHC.Generics.Generic Cryptol.TypeCheck.FFI.FFIType.FFIBasicType
+ Cryptol.TypeCheck.FFI.FFIType: instance GHC.Generics.Generic Cryptol.TypeCheck.FFI.FFIType.FFIBasicValType
+ Cryptol.TypeCheck.FFI.FFIType: instance GHC.Generics.Generic Cryptol.TypeCheck.FFI.FFIType.FFIFloatSize
+ Cryptol.TypeCheck.FFI.FFIType: instance GHC.Generics.Generic Cryptol.TypeCheck.FFI.FFIType.FFIFunType
+ Cryptol.TypeCheck.FFI.FFIType: instance GHC.Generics.Generic Cryptol.TypeCheck.FFI.FFIType.FFIType
+ Cryptol.TypeCheck.FFI.FFIType: instance GHC.Generics.Generic Cryptol.TypeCheck.FFI.FFIType.FFIWordSize
+ Cryptol.TypeCheck.FFI.FFIType: instance GHC.Show.Show Cryptol.TypeCheck.FFI.FFIType.FFIBasicRefType
+ Cryptol.TypeCheck.FFI.FFIType: instance GHC.Show.Show Cryptol.TypeCheck.FFI.FFIType.FFIBasicType
+ Cryptol.TypeCheck.FFI.FFIType: instance GHC.Show.Show Cryptol.TypeCheck.FFI.FFIType.FFIBasicValType
+ Cryptol.TypeCheck.FFI.FFIType: instance GHC.Show.Show Cryptol.TypeCheck.FFI.FFIType.FFIFloatSize
+ Cryptol.TypeCheck.FFI.FFIType: instance GHC.Show.Show Cryptol.TypeCheck.FFI.FFIType.FFIFunType
+ Cryptol.TypeCheck.FFI.FFIType: instance GHC.Show.Show Cryptol.TypeCheck.FFI.FFIType.FFIType
+ Cryptol.TypeCheck.FFI.FFIType: instance GHC.Show.Show Cryptol.TypeCheck.FFI.FFIType.FFIWordSize
+ Cryptol.TypeCheck.Infer: inferTopModule :: Module Name -> InferM TCTopEntity
+ Cryptol.TypeCheck.InferTypes: CtFFI :: Name -> ConstraintSource
+ Cryptol.TypeCheck.InferTypes: CtPropGuardsExhaustive :: Name -> ConstraintSource
+ Cryptol.TypeCheck.Interface: genIfaceNames :: ModuleG name -> IfaceNames name
+ Cryptol.TypeCheck.Interface: genIfaceWithNames :: IfaceNames name -> ModuleG ignored -> IfaceG name
+ Cryptol.TypeCheck.Interface: genModDefines :: ModuleG name -> Set Name
+ Cryptol.TypeCheck.Kind: checkPropGuards :: [Located (Prop Name)] -> InferM [Prop]
+ Cryptol.TypeCheck.Module: doFunctorInst :: Located (ImpName Name) -> Located (ImpName Name) -> ModuleInstanceArgs Name -> Map Name Name -> Maybe Text -> InferM (Maybe TCTopEntity)
+ Cryptol.TypeCheck.ModuleBacktickInstance: doBacktickInstance :: Set (MBQual TParam) -> [Prop] -> Map (MBQual Name) Type -> ModuleG (Located (ImpName Name)) -> InferM (ModuleG (Located (ImpName Name)))
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.AddParams Cryptol.TypeCheck.AST.Decl
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.AddParams Cryptol.TypeCheck.AST.DeclGroup
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.AddParams Cryptol.TypeCheck.Type.Newtype
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.AddParams Cryptol.TypeCheck.Type.TySyn
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.AddParams a => Cryptol.TypeCheck.ModuleBacktickInstance.AddParams (Data.Map.Internal.Map Cryptol.ModuleSystem.Name.Name a)
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.AddParams a => Cryptol.TypeCheck.ModuleBacktickInstance.AddParams [a]
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.RewType Cryptol.TypeCheck.Type.Schema
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.RewType Cryptol.TypeCheck.Type.Type
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.RewType a => Cryptol.TypeCheck.ModuleBacktickInstance.RewType [a]
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.RewType b => Cryptol.TypeCheck.ModuleBacktickInstance.RewType (Cryptol.Utils.RecordMap.RecordMap a b)
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.RewVal Cryptol.TypeCheck.AST.Decl
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.RewVal Cryptol.TypeCheck.AST.DeclDef
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.RewVal Cryptol.TypeCheck.AST.DeclGroup
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.RewVal Cryptol.TypeCheck.AST.Expr
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.RewVal Cryptol.TypeCheck.AST.Match
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.RewVal a => Cryptol.TypeCheck.ModuleBacktickInstance.RewVal [a]
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.RewVal b => Cryptol.TypeCheck.ModuleBacktickInstance.RewVal (Cryptol.Utils.RecordMap.RecordMap a b)
+ Cryptol.TypeCheck.ModuleBacktickInstance: type MBQual a = (Maybe ModName, a)
+ Cryptol.TypeCheck.ModuleInstance: class ModuleInstance t
+ Cryptol.TypeCheck.ModuleInstance: doMap :: (Su, ModuleInstance a) => Map Name a -> Map Name a
+ Cryptol.TypeCheck.ModuleInstance: doSet :: Su => Set Name -> Set Name
+ Cryptol.TypeCheck.ModuleInstance: doTInst :: (Su, TVars a) => a -> a
+ Cryptol.TypeCheck.ModuleInstance: doTVInst :: (Su, TVars a, TraverseNames a) => a -> a
+ Cryptol.TypeCheck.ModuleInstance: doVInst :: (Su, TraverseNames a) => a -> a
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance (Cryptol.TypeCheck.AST.ModuleG name)
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.ModuleSystem.Name.Name
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.TypeCheck.AST.Decl
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.TypeCheck.AST.DeclGroup
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.TypeCheck.Type.AbstractType
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.TypeCheck.Type.ModParam
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.TypeCheck.Type.ModParamNames
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.TypeCheck.Type.ModTParam
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.TypeCheck.Type.ModVParam
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.TypeCheck.Type.Newtype
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.TypeCheck.Type.Schema
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.TypeCheck.Type.TySyn
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.TypeCheck.Type.Type
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance a => Cryptol.TypeCheck.ModuleInstance.ModuleInstance (Cryptol.Parser.Position.Located a)
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance a => Cryptol.TypeCheck.ModuleInstance.ModuleInstance [a]
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance name => Cryptol.TypeCheck.ModuleInstance.ModuleInstance (Cryptol.ModuleSystem.Interface.IfaceNames name)
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance name => Cryptol.TypeCheck.ModuleInstance.ModuleInstance (Cryptol.Parser.AST.ImpName name)
+ Cryptol.TypeCheck.ModuleInstance: moduleInstance :: (ModuleInstance t, Su) => t -> t
+ Cryptol.TypeCheck.ModuleInstance: type Su = (?tSu :: Subst, ?vSu :: Map Name Name)
+ Cryptol.TypeCheck.Monad: SignatureScope :: Name -> Maybe Text -> ScopeName
+ Cryptol.TypeCheck.Monad: TopSignatureScope :: ModName -> ScopeName
+ Cryptol.TypeCheck.Monad: [iExtModules] :: RO -> ModName -> Maybe (ModuleG (), IfaceG ())
+ Cryptol.TypeCheck.Monad: [iExtSignatures] :: RO -> ModName -> Maybe ModParamNames
+ Cryptol.TypeCheck.Monad: [inpParams] :: InferInput -> !ModParamNames
+ Cryptol.TypeCheck.Monad: [inpSignatures] :: InferInput -> !Map Name ModParamNames
+ Cryptol.TypeCheck.Monad: [inpTopModules] :: InferInput -> ModName -> Maybe (ModuleG (), IfaceG ())
+ Cryptol.TypeCheck.Monad: [inpTopSignatures] :: InferInput -> ModName -> Maybe ModParamNames
+ Cryptol.TypeCheck.Monad: abortIfErrors :: InferM ()
+ Cryptol.TypeCheck.Monad: addFunctors :: Map Name (ModuleG Name) -> InferM ()
+ Cryptol.TypeCheck.Monad: addModParam :: ModParam -> InferM ()
+ Cryptol.TypeCheck.Monad: addSignatures :: Map Name ModParamNames -> InferM ()
+ Cryptol.TypeCheck.Monad: addSubmodules :: Map Name (IfaceNames Name) -> InferM ()
+ Cryptol.TypeCheck.Monad: endSignature :: InferM ()
+ Cryptol.TypeCheck.Monad: endTopSignature :: InferM TCTopEntity
+ Cryptol.TypeCheck.Monad: freshTParam :: (Name -> TPFlavor) -> TParam -> InferM TParam
+ Cryptol.TypeCheck.Monad: getCurDecls :: InferM (ModuleG ())
+ Cryptol.TypeCheck.Monad: getSignatures :: InferM (Map Name ModParamNames)
+ Cryptol.TypeCheck.Monad: lookupFunctor :: ImpName Name -> InferM (ModuleG ())
+ Cryptol.TypeCheck.Monad: lookupModParam :: Ident -> InferM (Maybe ModParam)
+ Cryptol.TypeCheck.Monad: lookupModule :: ImpName Name -> InferM (IfaceG ())
+ Cryptol.TypeCheck.Monad: lookupSignature :: ImpName Name -> InferM ModParamNames
+ Cryptol.TypeCheck.Monad: lookupTopModule :: ModName -> InferM (Maybe (ModuleG (), IfaceG ()))
+ Cryptol.TypeCheck.Monad: newLocalName :: Namespace -> Ident -> InferM Name
+ Cryptol.TypeCheck.Monad: newSignatureScope :: Name -> Maybe Text -> InferM ()
+ Cryptol.TypeCheck.Monad: newTopSignatureScope :: ModName -> InferM ()
+ Cryptol.TypeCheck.Monad: selectorScope :: InferM a -> InferM a
+ Cryptol.TypeCheck.Sanity: NotSame :: AreSame
+ Cryptol.TypeCheck.Sanity: SameIf :: [Prop] -> AreSame
+ Cryptol.TypeCheck.Sanity: data AreSame
+ Cryptol.TypeCheck.Sanity: instance (GHC.Classes.Eq a, Cryptol.TypeCheck.Sanity.Same b) => Cryptol.TypeCheck.Sanity.Same (Cryptol.TypeCheck.Sanity.Field a b)
+ Cryptol.TypeCheck.Sanity: instance Cryptol.Utils.PP.PP Cryptol.TypeCheck.Sanity.Error
+ Cryptol.TypeCheck.Sanity: onlyNonTrivial :: [ProofObligation] -> [ProofObligation]
+ Cryptol.TypeCheck.Solve: tryProveImplication :: Maybe Name -> [TParam] -> [Prop] -> [Goal] -> InferM Bool
+ Cryptol.TypeCheck.Solver.Numeric.Interval: ppIntervalsWithNames :: NameMap -> Map TVar Interval -> Doc
+ Cryptol.TypeCheck.Solver.SMT: assume :: Solver -> TVars -> Prop -> IO ()
+ Cryptol.TypeCheck.Solver.SMT: declareVars :: Solver -> [TVar] -> IO TVars
+ Cryptol.TypeCheck.Solver.SMT: inNewFrame :: Solver -> IO a -> IO a
+ Cryptol.TypeCheck.Solver.SMT: instance Cryptol.TypeCheck.Solver.SMT.Mk GHC.Num.Integer.Integer
+ Cryptol.TypeCheck.Solver.SMT: type TVars = Map TVar SExpr
+ Cryptol.TypeCheck.Solver.SMT: unsolvable :: Solver -> TVars -> [Prop] -> IO Bool
+ Cryptol.TypeCheck.Subst: instance Cryptol.TypeCheck.Subst.TVars (Cryptol.TypeCheck.AST.ModuleG names)
+ Cryptol.TypeCheck.Subst: instance Cryptol.TypeCheck.Subst.TVars Cryptol.TypeCheck.AST.TCTopEntity
+ Cryptol.TypeCheck.Subst: mergeDistinctSubst :: [Subst] -> Subst
+ Cryptol.TypeCheck.Type: ModParam :: Ident -> !Maybe ModName -> ImpName Name -> ModParamNames -> ModParam
+ Cryptol.TypeCheck.Type: ModParamNames :: Map Name ModTParam -> !Map Name TySyn -> [Located Prop] -> Map Name ModVParam -> !Maybe Text -> ModParamNames
+ Cryptol.TypeCheck.Type: [mpIface] :: ModParam -> ImpName Name
+ Cryptol.TypeCheck.Type: [mpName] :: ModParam -> Ident
+ Cryptol.TypeCheck.Type: [mpParameters] :: ModParam -> ModParamNames
+ Cryptol.TypeCheck.Type: [mpQual] :: ModParam -> !Maybe ModName
+ Cryptol.TypeCheck.Type: [mpnConstraints] :: ModParamNames -> [Located Prop]
+ Cryptol.TypeCheck.Type: [mpnDoc] :: ModParamNames -> !Maybe Text
+ Cryptol.TypeCheck.Type: [mpnFuns] :: ModParamNames -> Map Name ModVParam
+ Cryptol.TypeCheck.Type: [mpnTySyn] :: ModParamNames -> !Map Name TySyn
+ Cryptol.TypeCheck.Type: [mpnTypes] :: ModParamNames -> Map Name ModTParam
+ Cryptol.TypeCheck.Type: [ntConName] :: Newtype -> !Name
+ Cryptol.TypeCheck.Type: allParamNames :: FunctorParams -> ModParamNames
+ Cryptol.TypeCheck.Type: class FreeAbstract t
+ Cryptol.TypeCheck.Type: data ModParam
+ Cryptol.TypeCheck.Type: data ModParamNames
+ Cryptol.TypeCheck.Type: freeAbstract :: FreeAbstract t => t -> Set UserTC
+ Cryptol.TypeCheck.Type: instance (Cryptol.TypeCheck.Type.FreeAbstract a, Cryptol.TypeCheck.Type.FreeAbstract b) => Cryptol.TypeCheck.Type.FreeAbstract (a, b)
+ Cryptol.TypeCheck.Type: instance Control.DeepSeq.NFData Cryptol.TypeCheck.Type.ModParam
+ Cryptol.TypeCheck.Type: instance Control.DeepSeq.NFData Cryptol.TypeCheck.Type.ModParamNames
+ Cryptol.TypeCheck.Type: instance Cryptol.TypeCheck.TCon.HasKind Cryptol.TypeCheck.Type.AbstractType
+ Cryptol.TypeCheck.Type: instance Cryptol.TypeCheck.Type.FreeAbstract Cryptol.TypeCheck.TCon.TCon
+ Cryptol.TypeCheck.Type: instance Cryptol.TypeCheck.Type.FreeAbstract Cryptol.TypeCheck.Type.Type
+ Cryptol.TypeCheck.Type: instance Cryptol.TypeCheck.Type.FreeAbstract a => Cryptol.TypeCheck.Type.FreeAbstract [a]
+ Cryptol.TypeCheck.Type: instance Cryptol.Utils.PP.PP Cryptol.TypeCheck.Type.ModParamNames
+ Cryptol.TypeCheck.Type: instance Cryptol.Utils.PP.PP Cryptol.TypeCheck.Type.ModTParam
+ Cryptol.TypeCheck.Type: instance Cryptol.Utils.PP.PP Cryptol.TypeCheck.Type.ModVParam
+ Cryptol.TypeCheck.Type: instance GHC.Generics.Generic Cryptol.TypeCheck.Type.ModParam
+ Cryptol.TypeCheck.Type: instance GHC.Generics.Generic Cryptol.TypeCheck.Type.ModParamNames
+ Cryptol.TypeCheck.Type: instance GHC.Show.Show Cryptol.TypeCheck.Type.ModParam
+ Cryptol.TypeCheck.Type: instance GHC.Show.Show Cryptol.TypeCheck.Type.ModParamNames
+ Cryptol.TypeCheck.Type: pNegNumeric :: Prop -> [Prop]
+ Cryptol.TypeCheck.Type: ppNewtypeFull :: Newtype -> Doc
+ Cryptol.TypeCheck.Type: type FunctorParams = Map Ident ModParam
+ Cryptol.TypeCheck.TypePat: anAbstractType :: Pat Type UserTC
+ Cryptol.Utils.Benchmark: BenchmarkStats :: !Double -> !Double -> !Int64 -> BenchmarkStats
+ Cryptol.Utils.Benchmark: [benchAvgCpuTime] :: BenchmarkStats -> !Double
+ Cryptol.Utils.Benchmark: [benchAvgCycles] :: BenchmarkStats -> !Int64
+ Cryptol.Utils.Benchmark: [benchAvgTime] :: BenchmarkStats -> !Double
+ Cryptol.Utils.Benchmark: benchmark :: Double -> (a -> IO b) -> a -> IO BenchmarkStats
+ Cryptol.Utils.Benchmark: data BenchmarkStats
+ Cryptol.Utils.Benchmark: instance GHC.Show.Show Cryptol.Utils.Benchmark.BenchmarkStats
+ Cryptol.Utils.Benchmark: secs :: Double -> String
+ Cryptol.Utils.Fixity: instance GHC.Classes.Ord Cryptol.Utils.Fixity.Assoc
+ Cryptol.Utils.Fixity: instance GHC.Classes.Ord Cryptol.Utils.Fixity.Fixity
+ Cryptol.Utils.Ident: FromDefinition :: OrigSource
+ Cryptol.Utils.Ident: FromFunctorInst :: OrigSource
+ Cryptol.Utils.Ident: FromModParam :: Ident -> OrigSource
+ Cryptol.Utils.Ident: [ogSource] :: OrigName -> OrigSource
+ Cryptol.Utils.Ident: data OrigSource
+ Cryptol.Utils.Ident: identAnonArg :: Ident -> Ident
+ Cryptol.Utils.Ident: identAnonIfaceMod :: Ident -> Ident
+ Cryptol.Utils.Ident: identIsNormal :: Ident -> Bool
+ Cryptol.Utils.Ident: instance Control.DeepSeq.NFData Cryptol.Utils.Ident.MaybeAnon
+ Cryptol.Utils.Ident: instance Control.DeepSeq.NFData Cryptol.Utils.Ident.OrigSource
+ Cryptol.Utils.Ident: instance GHC.Classes.Eq Cryptol.Utils.Ident.MaybeAnon
+ Cryptol.Utils.Ident: instance GHC.Classes.Eq Cryptol.Utils.Ident.OrigSource
+ Cryptol.Utils.Ident: instance GHC.Classes.Ord Cryptol.Utils.Ident.MaybeAnon
+ Cryptol.Utils.Ident: instance GHC.Classes.Ord Cryptol.Utils.Ident.OrigSource
+ Cryptol.Utils.Ident: instance GHC.Generics.Generic Cryptol.Utils.Ident.MaybeAnon
+ Cryptol.Utils.Ident: instance GHC.Generics.Generic Cryptol.Utils.Ident.OrigSource
+ Cryptol.Utils.Ident: instance GHC.Show.Show Cryptol.Utils.Ident.MaybeAnon
+ Cryptol.Utils.Ident: instance GHC.Show.Show Cryptol.Utils.Ident.OrigSource
+ Cryptol.Utils.Ident: modNameArg :: ModName -> ModName
+ Cryptol.Utils.Ident: modNameChunksText :: ModName -> [Text]
+ Cryptol.Utils.Ident: modNameIfaceMod :: ModName -> ModName
+ Cryptol.Utils.Ident: modNameIsNormal :: ModName -> Bool
+ Cryptol.Utils.Ident: modNameToNormalModName :: ModName -> ModName
+ Cryptol.Utils.Ident: modPathIsNormal :: ModPath -> Bool
+ Cryptol.Utils.Ident: modPathIsOrContains :: ModPath -> ModPath -> Bool
+ Cryptol.Utils.Ident: ogFromModParam :: OrigName -> Bool
+ Cryptol.Utils.Ident: undefinedModName :: ModName
+ Cryptol.Utils.PP: PPCfg :: NameDisp -> Bool -> PPCfg
+ Cryptol.Utils.PP: [ppcfgNameDisp] :: PPCfg -> NameDisp
+ Cryptol.Utils.PP: [ppcfgShowNameUniques] :: PPCfg -> Bool
+ Cryptol.Utils.PP: data PPCfg
+ Cryptol.Utils.PP: debugShowUniques :: Doc -> Doc
+ Cryptol.Utils.PP: defaultPPCfg :: PPCfg
+ Cryptol.Utils.PP: fixPPCfg :: PPCfg -> Doc -> Doc
+ Cryptol.Utils.PP: instance Cryptol.Utils.PP.PP Cryptol.Utils.Ident.PrimIdent
+ Cryptol.Utils.PP: pipe :: Doc
+ Cryptol.Utils.PP: reflow :: Text -> Doc
+ Cryptol.Utils.PP: runDocWith :: PPCfg -> Doc -> Doc Void
+ Cryptol.Utils.PP: updPPCfg :: (PPCfg -> PPCfg) -> Doc -> Doc
+ Cryptol.Utils.PP: withPPCfg :: (PPCfg -> Doc) -> Doc
+ Cryptol.Utils.Panic: xxxTODO :: HasCallStack => String -> a
+ Cryptol.Utils.RecordMap: displayElements :: (Show a, Ord a) => RecordMap a b -> [b]
+ Cryptol.Utils.Types: float32ExpPrec :: (Integer, Integer)
+ Cryptol.Utils.Types: float64ExpPrec :: (Integer, Integer)
- Cryptol.ModuleSystem: Iface :: !mname -> IfaceDecls -> IfaceDecls -> IfaceParams -> IfaceG mname
+ Cryptol.ModuleSystem: Iface :: IfaceNames name -> FunctorParams -> IfaceDecls -> IfaceG name
- Cryptol.ModuleSystem: IfaceDecl :: !Name -> Schema -> [Pragma] -> Bool -> Maybe Fixity -> Maybe Text -> IfaceDecl
+ Cryptol.ModuleSystem: IfaceDecl :: !Name -> Schema -> !Bool -> [Pragma] -> Bool -> Maybe Fixity -> Maybe Text -> IfaceDecl
- Cryptol.ModuleSystem: IfaceDecls :: Map Name IfaceTySyn -> Map Name IfaceNewtype -> Map Name IfaceAbstractType -> Map Name IfaceDecl -> !Map Name (IfaceG Name) -> IfaceDecls
+ Cryptol.ModuleSystem: IfaceDecls :: Map Name TySyn -> Map Name Newtype -> Map Name AbstractType -> Map Name IfaceDecl -> !Map Name (IfaceNames Name) -> !Map Name ModParamNames -> !Map Name (IfaceG Name) -> IfaceDecls
- Cryptol.ModuleSystem: [ifAbstractTypes] :: IfaceDecls -> Map Name IfaceAbstractType
+ Cryptol.ModuleSystem: [ifAbstractTypes] :: IfaceDecls -> Map Name AbstractType
- Cryptol.ModuleSystem: [ifModules] :: IfaceDecls -> !Map Name (IfaceG Name)
+ Cryptol.ModuleSystem: [ifModules] :: IfaceDecls -> !Map Name (IfaceNames Name)
- Cryptol.ModuleSystem: [ifNewtypes] :: IfaceDecls -> Map Name IfaceNewtype
+ Cryptol.ModuleSystem: [ifNewtypes] :: IfaceDecls -> Map Name Newtype
- Cryptol.ModuleSystem: [ifParams] :: IfaceG mname -> IfaceParams
+ Cryptol.ModuleSystem: [ifParams] :: IfaceG name -> FunctorParams
- Cryptol.ModuleSystem: [ifTySyns] :: IfaceDecls -> Map Name IfaceTySyn
+ Cryptol.ModuleSystem: [ifTySyns] :: IfaceDecls -> Map Name TySyn
- Cryptol.ModuleSystem: data IfaceG mname
+ Cryptol.ModuleSystem: data IfaceG name
- Cryptol.ModuleSystem: genIface :: ModuleG mname -> IfaceG mname
+ Cryptol.ModuleSystem: genIface :: ModuleG name -> IfaceG name
- Cryptol.ModuleSystem: loadModuleByName :: ModName -> ModuleCmd (ModulePath, Module)
+ Cryptol.ModuleSystem: loadModuleByName :: ModName -> ModuleCmd (ModulePath, TCTopEntity)
- Cryptol.ModuleSystem: loadModuleByPath :: FilePath -> ModuleCmd (ModulePath, Module)
+ Cryptol.ModuleSystem: loadModuleByPath :: FilePath -> ModuleCmd (ModulePath, TCTopEntity)
- Cryptol.ModuleSystem.Base: checkModule :: ImportSource -> Module PName -> ModuleM (NamingEnv, Module)
+ Cryptol.ModuleSystem.Base: checkModule :: ImportSource -> Module PName -> ModuleM (NamingEnv, TCTopEntity)
- Cryptol.ModuleSystem.Base: doLoadModule :: Bool -> ImportSource -> ModulePath -> Fingerprint -> Module PName -> ModuleM Module
+ Cryptol.ModuleSystem.Base: doLoadModule :: Bool -> Bool -> ImportSource -> ModulePath -> Fingerprint -> Set FilePath -> Module PName -> ModuleM TCTopEntity
- Cryptol.ModuleSystem.Base: genInferInput :: Range -> PrimMap -> IfaceParams -> IfaceDecls -> ModuleM InferInput
+ Cryptol.ModuleSystem.Base: genInferInput :: Range -> PrimMap -> ModContextParams -> IfaceDecls -> ModuleM InferInput
- Cryptol.ModuleSystem.Base: loadDeps :: Module name -> ModuleM ()
+ Cryptol.ModuleSystem.Base: loadDeps :: ModuleG mname name -> ModuleM (Set ModName)
- Cryptol.ModuleSystem.Base: loadModuleByPath :: FilePath -> ModuleM Module
+ Cryptol.ModuleSystem.Base: loadModuleByPath :: Bool -> FilePath -> ModuleM TCTopEntity
- Cryptol.ModuleSystem.Base: loadModuleFrom :: Bool -> ImportSource -> ModuleM (ModulePath, Module)
+ Cryptol.ModuleSystem.Base: loadModuleFrom :: Bool -> ImportSource -> ModuleM (ModulePath, TCTopEntity)
- Cryptol.ModuleSystem.Base: parseModule :: ModulePath -> ModuleM (Fingerprint, Module PName)
+ Cryptol.ModuleSystem.Base: parseModule :: ModulePath -> ModuleM (Fingerprint, Set FilePath, [Module PName])
- Cryptol.ModuleSystem.Base: typecheck :: (Show i, Show o, HasLoc i) => TCAction i o -> i -> IfaceParams -> IfaceDecls -> ModuleM o
+ Cryptol.ModuleSystem.Base: typecheck :: (Show i, Show o, HasLoc i) => TCAction i o -> i -> ModContextParams -> IfaceDecls -> ModuleM o
- Cryptol.ModuleSystem.Env: LoadedModule :: ModName -> ModulePath -> String -> !NamingEnv -> Iface -> Module -> Fingerprint -> LoadedModule
+ Cryptol.ModuleSystem.Env: LoadedModule :: ModName -> ModulePath -> String -> !NamingEnv -> !FileInfo -> a -> LoadedModuleG a
- Cryptol.ModuleSystem.Env: LoadedModules :: [LoadedModule] -> [LoadedModule] -> LoadedModules
+ Cryptol.ModuleSystem.Env: LoadedModules :: [LoadedModule] -> [LoadedModule] -> ![LoadedSignature] -> LoadedModules
- Cryptol.ModuleSystem.Env: ModContext :: IfaceParams -> Set Name -> IfaceDecls -> NamingEnv -> NameDisp -> ModContext
+ Cryptol.ModuleSystem.Env: ModContext :: ModContextParams -> Set Name -> IfaceDecls -> NamingEnv -> NameDisp -> ModContext
- Cryptol.ModuleSystem.Env: [lmFilePath] :: LoadedModule -> ModulePath
+ Cryptol.ModuleSystem.Env: [lmFilePath] :: LoadedModuleG a -> ModulePath
- Cryptol.ModuleSystem.Env: [lmModuleId] :: LoadedModule -> String
+ Cryptol.ModuleSystem.Env: [lmModuleId] :: LoadedModuleG a -> String
- Cryptol.ModuleSystem.Env: [lmName] :: LoadedModule -> ModName
+ Cryptol.ModuleSystem.Env: [lmName] :: LoadedModuleG a -> ModName
- Cryptol.ModuleSystem.Env: [lmNamingEnv] :: LoadedModule -> !NamingEnv
+ Cryptol.ModuleSystem.Env: [lmNamingEnv] :: LoadedModuleG a -> !NamingEnv
- Cryptol.ModuleSystem.Env: [mctxParams] :: ModContext -> IfaceParams
+ Cryptol.ModuleSystem.Env: [mctxParams] :: ModContext -> ModContextParams
- Cryptol.ModuleSystem.Env: addLoadedModule :: ModulePath -> String -> Fingerprint -> NamingEnv -> Module -> LoadedModules -> LoadedModules
+ Cryptol.ModuleSystem.Env: addLoadedModule :: ModulePath -> String -> FileInfo -> NamingEnv -> Maybe ForeignSrc -> Module -> LoadedModules -> LoadedModules
- Cryptol.ModuleSystem.Env: loadedNewtypes :: ModuleEnv -> Map Name IfaceNewtype
+ Cryptol.ModuleSystem.Env: loadedNewtypes :: ModuleEnv -> Map Name Newtype
- Cryptol.ModuleSystem.Env: removeLoadedModule :: (LoadedModule -> Bool) -> LoadedModules -> LoadedModules
+ Cryptol.ModuleSystem.Env: removeLoadedModule :: (forall a. LoadedModuleG a -> Bool) -> LoadedModules -> LoadedModules
- Cryptol.ModuleSystem.Env: resetModuleEnv :: ModuleEnv -> ModuleEnv
+ Cryptol.ModuleSystem.Env: resetModuleEnv :: ModuleEnv -> IO ModuleEnv
- Cryptol.ModuleSystem.Interface: Iface :: !mname -> IfaceDecls -> IfaceDecls -> IfaceParams -> IfaceG mname
+ Cryptol.ModuleSystem.Interface: Iface :: IfaceNames name -> FunctorParams -> IfaceDecls -> IfaceG name
- Cryptol.ModuleSystem.Interface: IfaceDecl :: !Name -> Schema -> [Pragma] -> Bool -> Maybe Fixity -> Maybe Text -> IfaceDecl
+ Cryptol.ModuleSystem.Interface: IfaceDecl :: !Name -> Schema -> !Bool -> [Pragma] -> Bool -> Maybe Fixity -> Maybe Text -> IfaceDecl
- Cryptol.ModuleSystem.Interface: IfaceDecls :: Map Name IfaceTySyn -> Map Name IfaceNewtype -> Map Name IfaceAbstractType -> Map Name IfaceDecl -> !Map Name (IfaceG Name) -> IfaceDecls
+ Cryptol.ModuleSystem.Interface: IfaceDecls :: Map Name TySyn -> Map Name Newtype -> Map Name AbstractType -> Map Name IfaceDecl -> !Map Name (IfaceNames Name) -> !Map Name ModParamNames -> !Map Name (IfaceG Name) -> IfaceDecls
- Cryptol.ModuleSystem.Interface: [ifAbstractTypes] :: IfaceDecls -> Map Name IfaceAbstractType
+ Cryptol.ModuleSystem.Interface: [ifAbstractTypes] :: IfaceDecls -> Map Name AbstractType
- Cryptol.ModuleSystem.Interface: [ifModules] :: IfaceDecls -> !Map Name (IfaceG Name)
+ Cryptol.ModuleSystem.Interface: [ifModules] :: IfaceDecls -> !Map Name (IfaceNames Name)
- Cryptol.ModuleSystem.Interface: [ifNewtypes] :: IfaceDecls -> Map Name IfaceNewtype
+ Cryptol.ModuleSystem.Interface: [ifNewtypes] :: IfaceDecls -> Map Name Newtype
- Cryptol.ModuleSystem.Interface: [ifParams] :: IfaceG mname -> IfaceParams
+ Cryptol.ModuleSystem.Interface: [ifParams] :: IfaceG name -> FunctorParams
- Cryptol.ModuleSystem.Interface: [ifTySyns] :: IfaceDecls -> Map Name IfaceTySyn
+ Cryptol.ModuleSystem.Interface: [ifTySyns] :: IfaceDecls -> Map Name TySyn
- Cryptol.ModuleSystem.Interface: data IfaceG mname
+ Cryptol.ModuleSystem.Interface: data IfaceG name
- Cryptol.ModuleSystem.Interface: emptyIface :: mname -> IfaceG mname
+ Cryptol.ModuleSystem.Interface: emptyIface :: ModName -> Iface
- Cryptol.ModuleSystem.Interface: ifaceIsFunctor :: IfaceG mname -> Bool
+ Cryptol.ModuleSystem.Interface: ifaceIsFunctor :: IfaceG name -> Bool
- Cryptol.ModuleSystem.Monad: getIfaces :: ModuleM (ModName -> Iface)
+ Cryptol.ModuleSystem.Monad: getIfaces :: ModuleM (Map ModName (Either ModParamNames Iface))
- Cryptol.ModuleSystem.Monad: getLoadedMaybe :: ModName -> ModuleM (Maybe LoadedModule)
+ Cryptol.ModuleSystem.Monad: getLoadedMaybe :: ModName -> ModuleM (Maybe (LoadedModuleG TCTopEntity))
- Cryptol.ModuleSystem.Monad: loadedModule :: ModulePath -> Fingerprint -> NamingEnv -> Module -> ModuleM ()
+ Cryptol.ModuleSystem.Monad: loadedModule :: ModulePath -> FileInfo -> NamingEnv -> Maybe ForeignSrc -> TCTopEntity -> ModuleM ()
- Cryptol.ModuleSystem.Monad: unloadModule :: (LoadedModule -> Bool) -> ModuleM ()
+ Cryptol.ModuleSystem.Monad: unloadModule :: (forall a. LoadedModuleG a -> Bool) -> ModuleM ()
- Cryptol.ModuleSystem.NamingEnv: NamingEnv :: Map Namespace (Map PName [Name]) -> NamingEnv
+ Cryptol.ModuleSystem.NamingEnv: NamingEnv :: Map Namespace (Map PName Names) -> NamingEnv
- Cryptol.ModuleSystem.NamingEnv: lookupNS :: Namespace -> PName -> NamingEnv -> [Name]
+ Cryptol.ModuleSystem.NamingEnv: lookupNS :: Namespace -> PName -> NamingEnv -> Maybe Names
- Cryptol.ModuleSystem.NamingEnv: modParamsNamingEnv :: IfaceParams -> NamingEnv
+ Cryptol.ModuleSystem.NamingEnv: modParamsNamingEnv :: ModParamNames -> NamingEnv
- Cryptol.ModuleSystem.NamingEnv: namespaceMap :: Namespace -> NamingEnv -> Map PName [Name]
+ Cryptol.ModuleSystem.NamingEnv: namespaceMap :: Namespace -> NamingEnv -> Map PName Names
- Cryptol.ModuleSystem.Renamer: RenamerInfo :: Supply -> ModPath -> NamingEnv -> (ModName -> Iface) -> RenamerInfo
+ Cryptol.ModuleSystem.Renamer: RenamerInfo :: Supply -> ModPath -> NamingEnv -> Map ModName (Either ModParamNames Iface) -> RenamerInfo
- Cryptol.ModuleSystem.Renamer: [renIfaces] :: RenamerInfo -> ModName -> Iface
+ Cryptol.ModuleSystem.Renamer: [renIfaces] :: RenamerInfo -> Map ModName (Either ModParamNames Iface)
- Cryptol.ModuleSystem.Renamer.Error: depNameLoc :: DepName -> Range
+ Cryptol.ModuleSystem.Renamer.Error: depNameLoc :: DepName -> Maybe Range
- Cryptol.ModuleSystem.Renamer.Monad: RO :: Range -> NamingEnv -> (ModName -> Iface) -> ModPath -> Map ModPath Name -> RO
+ Cryptol.ModuleSystem.Renamer.Monad: RO :: Range -> NamingEnv -> Map ModName (Maybe Iface, Map (ImpName Name) (Mod ())) -> ModPath -> Map ModPath Name -> Map (ImpName Name) ResolvedLocal -> Map Ident RenModParam -> Map Name DepName -> RO
- Cryptol.ModuleSystem.Renamer.Monad: RW :: ![RenamerWarning] -> !Seq RenamerError -> !Supply -> !Map Name Int -> Set Name -> Map DepName (Set Name) -> !IfaceDecls -> RW
+ Cryptol.ModuleSystem.Renamer.Monad: RW :: ![RenamerWarning] -> !Set RenamerError -> !Supply -> !Map Name Int -> Set Name -> Map DepName (Set Name) -> !IfaceDecls -> RW
- Cryptol.ModuleSystem.Renamer.Monad: RenamerInfo :: Supply -> ModPath -> NamingEnv -> (ModName -> Iface) -> RenamerInfo
+ Cryptol.ModuleSystem.Renamer.Monad: RenamerInfo :: Supply -> ModPath -> NamingEnv -> Map ModName (Either ModParamNames Iface) -> RenamerInfo
- Cryptol.ModuleSystem.Renamer.Monad: [renIfaces] :: RenamerInfo -> ModName -> Iface
+ Cryptol.ModuleSystem.Renamer.Monad: [renIfaces] :: RenamerInfo -> Map ModName (Either ModParamNames Iface)
- Cryptol.ModuleSystem.Renamer.Monad: [rwErrors] :: RW -> !Seq RenamerError
+ Cryptol.ModuleSystem.Renamer.Monad: [rwErrors] :: RW -> !Set RenamerError
- Cryptol.Parser: parseModule :: Config -> Text -> Either ParseError (Module PName)
+ Cryptol.Parser: parseModule :: Config -> Text -> Either ParseError [Module PName]
- Cryptol.Parser.AST: DParameterConstraint :: [Located (Prop name)] -> TopDecl name
+ Cryptol.Parser.AST: DParameterConstraint :: [Located (Prop name)] -> ParamDecl name
- Cryptol.Parser.AST: DParameterFun :: ParameterFun name -> TopDecl name
+ Cryptol.Parser.AST: DParameterFun :: ParameterFun name -> ParamDecl name
- Cryptol.Parser.AST: DParameterType :: ParameterType name -> TopDecl name
+ Cryptol.Parser.AST: DParameterType :: ParameterType name -> ParamDecl name
- Cryptol.Parser.AST: Import :: !mname -> Maybe ModName -> Maybe ImportSpec -> ImportG mname
+ Cryptol.Parser.AST: Import :: !mname -> Maybe ModName -> Maybe ImportSpec -> !Maybe (ModuleInstanceArgs PName) -> ImportG mname
- Cryptol.Parser.AST: Module :: Located mname -> !Maybe (Located ModName) -> [TopDecl name] -> ModuleG mname name
+ Cryptol.Parser.AST: Module :: Located mname -> ModuleDefinition name -> ModuleG mname name
- Cryptol.Parser.AST: Newtype :: Located name -> [TParam name] -> Rec (Type name) -> Newtype name
+ Cryptol.Parser.AST: Newtype :: Located name -> [TParam name] -> !name -> Rec (Type name) -> Newtype name
- Cryptol.Parser.AST: TParens :: Type n -> Type n
+ Cryptol.Parser.AST: TParens :: Type n -> Maybe Kind -> Type n
- Cryptol.Parser.NoInclude: removeIncludesModule :: (FilePath -> IO ByteString) -> FilePath -> Module PName -> IO (Either [IncludeError] (Module PName))
+ Cryptol.Parser.NoInclude: removeIncludesModule :: (FilePath -> IO ByteString) -> FilePath -> Module PName -> IO (Either [IncludeError] (Module PName, Set FilePath))
- Cryptol.PrimeEC: bigNatToInteger :: BigNat -> Integer
+ Cryptol.PrimeEC: bigNatToInteger :: BigNat# -> Integer
- Cryptol.REPL.Monad: EvalInParamModule :: [Name] -> REPLException
+ Cryptol.REPL.Monad: EvalInParamModule :: [TParam] -> [Name] -> REPLException
- Cryptol.TypeCheck: InferInput :: Range -> Map Name Schema -> Map Name TySyn -> Map Name Newtype -> Map Name AbstractType -> !Map Name ModTParam -> ![Located Prop] -> !Map Name ModVParam -> NameSeeds -> Bool -> Bool -> [FilePath] -> !PrimMap -> !Supply -> Solver -> InferInput
+ Cryptol.TypeCheck: InferInput :: Range -> Map Name Schema -> Map Name TySyn -> Map Name Newtype -> Map Name AbstractType -> !Map Name ModParamNames -> (ModName -> Maybe (ModuleG (), IfaceG ())) -> (ModName -> Maybe ModParamNames) -> !ModParamNames -> NameSeeds -> Bool -> Bool -> [FilePath] -> !PrimMap -> !Supply -> Solver -> InferInput
- Cryptol.TypeCheck: tcModule :: Module Name -> InferInput -> IO (InferOutput Module)
+ Cryptol.TypeCheck: tcModule :: Module Name -> InferInput -> IO (InferOutput TCTopEntity)
- Cryptol.TypeCheck.AST: Import :: !mname -> Maybe ModName -> Maybe ImportSpec -> ImportG mname
+ Cryptol.TypeCheck.AST: Import :: !mname -> Maybe ModName -> Maybe ImportSpec -> !Maybe (ModuleInstanceArgs PName) -> ImportG mname
- Cryptol.TypeCheck.AST: Module :: !mname -> ExportSpec Name -> [Import] -> Map Name (IfaceG Name) -> Map Name ModTParam -> [Located Prop] -> Map Name ModVParam -> Map Name TySyn -> Map Name Newtype -> Map Name AbstractType -> [DeclGroup] -> Map Name (ModuleG Name) -> ModuleG mname
+ Cryptol.TypeCheck.AST: Module :: !mname -> !Maybe Text -> ExportSpec Name -> Map Name ModTParam -> Map Name ModVParam -> [Located Prop] -> FunctorParams -> Map Name (ModuleG Name) -> !Set Name -> Map Name TySyn -> Map Name Newtype -> Map Name AbstractType -> [DeclGroup] -> Map Name (IfaceNames Name) -> !Map Name ModParamNames -> ModuleG mname
- Cryptol.TypeCheck.InferTypes: CtModuleInstance :: ModName -> ConstraintSource
+ Cryptol.TypeCheck.InferTypes: CtModuleInstance :: Range -> ConstraintSource
- Cryptol.TypeCheck.Interface: genIface :: ModuleG mname -> IfaceG mname
+ Cryptol.TypeCheck.Interface: genIface :: ModuleG name -> IfaceG name
- Cryptol.TypeCheck.Kind: checkParameterType :: ParameterType Name -> Maybe Text -> InferM ModTParam
+ Cryptol.TypeCheck.Kind: checkParameterType :: ParameterType Name -> InferM ModTParam
- Cryptol.TypeCheck.Monad: IM :: ReaderT RO (StateT RW IO) a -> InferM a
+ Cryptol.TypeCheck.Monad: IM :: ReaderT RO (StateT RW (ExceptionT [(Range, Error)] IO)) a -> InferM a
- Cryptol.TypeCheck.Monad: InferInput :: Range -> Map Name Schema -> Map Name TySyn -> Map Name Newtype -> Map Name AbstractType -> !Map Name ModTParam -> ![Located Prop] -> !Map Name ModVParam -> NameSeeds -> Bool -> Bool -> [FilePath] -> !PrimMap -> !Supply -> Solver -> InferInput
+ Cryptol.TypeCheck.Monad: InferInput :: Range -> Map Name Schema -> Map Name TySyn -> Map Name Newtype -> Map Name AbstractType -> !Map Name ModParamNames -> (ModName -> Maybe (ModuleG (), IfaceG ())) -> (ModName -> Maybe ModParamNames) -> !ModParamNames -> NameSeeds -> Bool -> Bool -> [FilePath] -> !PrimMap -> !Supply -> Solver -> InferInput
- Cryptol.TypeCheck.Monad: RO :: Range -> Map Name VarType -> [TParam] -> ModuleG ScopeName -> Map Int HasGoalSln -> Bool -> Bool -> Solver -> !PrimMap -> !IORef Int -> RO
+ Cryptol.TypeCheck.Monad: RO :: Range -> Map Name VarType -> [TParam] -> (ModName -> Maybe (ModuleG (), IfaceG ())) -> (ModName -> Maybe ModParamNames) -> ModuleG ScopeName -> Map Int HasGoalSln -> Bool -> Bool -> Solver -> !PrimMap -> !IORef Int -> RO
- Cryptol.TypeCheck.Monad: RW :: ![(Range, Error)] -> ![(Range, Warning)] -> !Subst -> [Map Name Type] -> Map Int HasGoalSln -> !NameSeeds -> !Goals -> ![HasGoal] -> ![ModuleG ScopeName] -> !Map Name Schema -> !Supply -> RW
+ Cryptol.TypeCheck.Monad: RW :: ![(Range, Error)] -> ![(Range, Warning)] -> !Subst -> [Map Name Type] -> Map Int HasGoalSln -> !NameSeeds -> !Goals -> ![[HasGoal]] -> ![ModuleG ScopeName] -> !Map Name Schema -> !Supply -> RW
- Cryptol.TypeCheck.Monad: [iHasCts] :: RW -> ![HasGoal]
+ Cryptol.TypeCheck.Monad: [iHasCts] :: RW -> ![[HasGoal]]
- Cryptol.TypeCheck.Monad: [unIM] :: InferM a -> ReaderT RO (StateT RW IO) a
+ Cryptol.TypeCheck.Monad: [unIM] :: InferM a -> ReaderT RO (StateT RW (ExceptionT [(Range, Error)] IO)) a
- Cryptol.TypeCheck.Monad: endModule :: InferM Module
+ Cryptol.TypeCheck.Monad: endModule :: InferM TCTopEntity
- Cryptol.TypeCheck.Monad: newModuleScope :: ModName -> [Import] -> ExportSpec Name -> InferM ()
+ Cryptol.TypeCheck.Monad: newModuleScope :: ModName -> ExportSpec Name -> InferM ()
- Cryptol.TypeCheck.Monad: newSubmoduleScope :: Name -> [Import] -> ExportSpec Name -> InferM ()
+ Cryptol.TypeCheck.Monad: newSubmoduleScope :: Name -> Maybe Text -> ExportSpec Name -> InferM ()
- Cryptol.TypeCheck.Sanity: same :: Same a => a -> a -> Bool
+ Cryptol.TypeCheck.Sanity: same :: Same a => a -> a -> AreSame
- Cryptol.TypeCheck.Solve: proveImplication :: Maybe Name -> [TParam] -> [Prop] -> [Goal] -> InferM Subst
+ Cryptol.TypeCheck.Solve: proveImplication :: Bool -> Maybe Name -> [TParam] -> [Prop] -> [Goal] -> InferM Subst
- Cryptol.TypeCheck.Type: ModTParam :: Name -> Kind -> !Int -> Maybe Text -> ModTParam
+ Cryptol.TypeCheck.Type: ModTParam :: Name -> Kind -> Maybe Text -> ModTParam
- Cryptol.TypeCheck.Type: Newtype :: Name -> [TParam] -> [Prop] -> RecordMap Ident Type -> Maybe Text -> Newtype
+ Cryptol.TypeCheck.Type: Newtype :: Name -> [TParam] -> [Prop] -> !Name -> RecordMap Ident Type -> Maybe Text -> Newtype
- Cryptol.Utils.Ident: OrigName :: Namespace -> ModPath -> Ident -> OrigName
+ Cryptol.Utils.Ident: OrigName :: Namespace -> ModPath -> OrigSource -> Ident -> OrigName
- Cryptol.Utils.PP: Doc :: (NameDisp -> Doc Void) -> Doc
+ Cryptol.Utils.PP: Doc :: (PPCfg -> Doc Void) -> Doc

Files

CHANGES.md view
@@ -1,3 +1,103 @@+# 3.0.0 -- 2023-06-26++## Language changes++* Cryptol now includes a redesigned module system that is significantly more+  expressive than in previous releases. The new module system includes the+  following features:++  * Nested modules: Modules may now be defined within other modules.++  * Named interfaces: An interface specifies the parameters to a module.+    Separating the interface from the parameter declarations makes it possible+    to have different parameters that use the same interface.++  * Top-level module constraints: These are useful to specify constraints+    between different module parameters (i.e., ones that come from different+    interfaces or multiple copies of the same interface).++  See the+  [manual section](https://galoisinc.github.io/cryptol/master/Modules.html#instantiation-by-parametrizing-declarations)+  for more information.++* Declarations may now use *numeric constraint guards*.   This is a feature+  that allows a function to behave differently depending on its numeric+  type parameters.  See the [manual section](https://galoisinc.github.io/cryptol/master/BasicSyntax.html#numeric-constraint-guards))+  for more information.++* The foreign function interface (FFI) has been added, which allows Cryptol to+  call functions written in C. See the [manual section](https://galoisinc.github.io/cryptol/master/FFI.html)+  for more information.++* The unary `-` operator now has the same precedence as binary `-`, meaning+  expressions like `-x^^2` will now parse as `-(x^^2)` instead of `(-x)^^2`.+  **This is a breaking change.** A warning has been added in cases where the+  behavior has changed, and can be disabled with `:set warnPrefixAssoc=off`.++* Infix operators are now allowed in import lists: `import M ((<+>))` will+  import only the operator `<+>` from module `M`.++* `lib/Array.cry` now contains an `arrayEq` primitive. Like the other+  array-related primitives, this has no computational interpretation (and+  therefore cannot be used in the Cryptol interpreter), but it is useful for+  stating specifications that are used in SAW.++## New features++* Add a `:time` command to benchmark the evaluation time of expressions.++* Add support for literate Cryptol using reStructuredText.  Cryptol code+  is extracted from `.. code-block:: cryptol` and `.. sourcecode:: cryptol`+  directives.++* Add a syntax highlight file for Vim,+  available in `syntax-highlight/cryptol.vim`++* Add `:new-seed` and `:set-seed` commands to the REPL.+  These affect random test generation,+  and help write reproducable Cryptol scripts.++* Add support for the CVC5 solver, which can be selected with+  `:set prover=cvc5`. If you want to specify a What4 or SBV backend, you can+  use `:set prover=w4-cvc5` or `:set prover=sbv-cvc5`, respectively. (Note that+  `sbv-cvc5` is non-functional on Windows at this time due to a downstream issue+  with CVC5 1.0.4 and earlier.)++* Add `:file-deps` commands to the REPL and Python API.+  It shows information about the source files and dependencies of+  modules or Cryptol files.++## Bug fixes++* Fix a bug in the What4 backend that could cause applications of `(@)` with+  symbolic `Integer` indices to become out of bounds (#1359).++* Fix a bug that caused finite bitvector enumerations to panic when used in+  combination with `(#)` (e.g., `[0..1] # 0`).++* Cryptol's markdown parser is slightly more permissive and will now parse code+  blocks with whitespace in between the backticks and `cryptol`. This sort of+  whitespace is often inserted by markdown generation tools such as `pandoc`.++* Improve documentation for `fromInteger` (#1465)++* Closed issues #812, #977, #1090, #1140, #1147, #1253, #1322, #1324, #1329,+  #1344, #1347, #1351, #1354, #1355, #1359, #1366, #1368, #1370, #1371, #1372,+  #1373, #1378, #1383, #1385, #1386, #1391, #1394, #1395, #1396, #1398, #1399,+  #1404, #1415, #1423, #1435, #1439, #1440, #1441, #1442, #1444, #1445, #1448,+  #1449, #1450, #1451, #1452, #1456, #1457, #1458, #1462, #1465, #1466, #1470,+  #1475, #1480, #1483, #1484, #1485, #1487, #1488, #1491, #1496, #1497, #1501,+  #1503, #1510, #1511, #1513, and #1514.++* Merged pull requests #1184, #1205, #1279, #1356, #1357, #1358, #1361, #1363,+  #1365, #1367, #1376, #1379, #1380, #1384, #1387, #1388, #1393, #1401, #1402,+  #1403, #1406, #1408, #1409, #1410, #1411, #1412, #1413, #1414, #1416, #1417,+  #1418, #1419, #1420, #1422, #1424, #1429, #1430, #1431, #1432, #1436, #1438,+  #1443, #1447, #1453, #1454, #1459, #1460, #1461, #1463, #1464, #1467, #1468,+  #1472, #1473, #1474, #1476, #1477, #1478, #1481, #1493, #1499, #1502, #1504,+  #1506, #1509, #1512, #1516, #1518, #1519, #1520, #1521, #1523, #1527, and+  #1528.+ # 2.13.0  ## Language changes
bench/Main.hs view
@@ -26,7 +26,6 @@ import qualified Cryptol.ModuleSystem.Env       as M import qualified Cryptol.ModuleSystem.Monad     as M import qualified Cryptol.ModuleSystem.NamingEnv as M-import           Cryptol.ModuleSystem.Interface (noIfaceParams)  import qualified Cryptol.Parser           as P import qualified Cryptol.Parser.AST       as P@@ -130,7 +129,7 @@                            , M.tcLinter = M.moduleLinter (P.thing (P.mName scm))                            , M.tcPrims  = prims                            }-      M.typecheck act scm noIfaceParams tcEnv+      M.typecheck act scm mempty tcEnv  ceval :: String -> String -> FilePath -> T.Text -> Benchmark ceval cd name path expr =
cryptol.cabal view
@@ -1,6 +1,6 @@ Cabal-version:       2.4 Name:                cryptol-Version:             2.13.0+Version:             3.0.0 Synopsis:            Cryptol: The Language of Cryptography Description: Cryptol is a domain-specific language for specifying cryptographic algorithms. A Cryptol implementation of an algorithm resembles its mathematical specification more closely than an implementation in a general purpose language. For more, see <http://www.cryptol.net/>. License:             BSD-3-Clause@@ -9,11 +9,12 @@ Maintainer:          cryptol@galois.com Homepage:            http://www.cryptol.net/ Bug-reports:         https://github.com/GaloisInc/cryptol/issues-Copyright:           2013-2021 Galois Inc.+Copyright:           2013-2022 Galois Inc. Category:            Language Build-type:          Simple extra-source-files:  bench/data/*.cry                      CHANGES.md+                     lib/*.cry lib/*.z3  data-files:          **/*.cry **/*.z3 data-dir:            lib@@ -26,7 +27,7 @@   type:     git   location: https://github.com/GaloisInc/cryptol.git   -- add a tag on release branches-  tag:      2.13.0+  tag:      3.0.0   flag static@@ -37,6 +38,10 @@   default: True   description: Don't use the Cabal-provided data directory for looking up Cryptol libraries. This is useful when the data directory can't be known ahead of time, like for a relocatable distribution. +flag ffi+  default: True+  description: Enable the foreign function interface+ library   Default-language:     Haskell2010@@ -48,6 +53,7 @@                        bytestring        >= 0.10,                        array             >= 0.4,                        containers        >= 0.5,+                       criterion-measurement,                        cryptohash-sha1   >= 0.11 && < 0.12,                        deepseq           >= 1.3,                        directory         >= 1.2.2.0,@@ -57,30 +63,44 @@                        ghc-prim,                        GraphSCC          >= 1.0.4,                        heredoc           >= 0.2,+                       language-c99,+                       language-c99-simple,                        libBF             >= 0.6 && < 0.7,                        MemoTrie          >= 0.6 && < 0.7,                        monad-control     >= 1.0,                        monadLib          >= 3.7.2,                        parameterized-utils >= 2.0.2,+                       pretty,                        prettyprinter     >= 1.7.0,+                       pretty-show,                        process           >= 1.2,-                       sbv               >= 8.10 && < 9.1,+                       sbv               >= 9.1 && < 10.2,                        simple-smt        >= 0.9.7,                        stm               >= 2.4,                        strict,                        text              >= 1.1,                        tf-random         >= 0.5,                        transformers-base >= 0.4,+                       vector,                        mtl               >= 2.2.1,                        time              >= 1.6.0.1,                        panic             >= 0.3,-                       what4             >= 1.3 && < 1.4+                       what4             >= 1.4 && < 1.5    if impl(ghc >= 9.0)-    build-depends:     ghc-bignum        >= 1.0 && < 1.3+    build-depends:     ghc-bignum        >= 1.0 && < 1.4   else     build-depends:     integer-gmp       >= 1.0 && < 1.1 +  if flag(ffi)+    build-depends:     hgmp,+                       libffi            >= 0.2+    if os(windows)+      build-depends:   Win32+    else+      build-depends:   unix+    cpp-options:       -DFFI_ENABLED+   Build-tool-depends:  alex:alex, happy:happy   hs-source-dirs:      src @@ -93,6 +113,7 @@                        Cryptol.Parser.Names,                        Cryptol.Parser.Name,                        Cryptol.Parser.NoPat,+                       Cryptol.Parser.ExpandPropGuards,                        Cryptol.Parser.NoInclude,                        Cryptol.Parser.Selector,                        Cryptol.Parser.Utils,@@ -107,6 +128,8 @@                        Cryptol.Utils.Misc,                        Cryptol.Utils.Patterns,                        Cryptol.Utils.Logger,+                       Cryptol.Utils.Benchmark,+                       Cryptol.Utils.Types,                        Cryptol.Version,                         Cryptol.ModuleSystem,@@ -116,10 +139,13 @@                        Cryptol.ModuleSystem.Interface,                        Cryptol.ModuleSystem.Monad,                        Cryptol.ModuleSystem.Name,+                       Cryptol.ModuleSystem.Names,                        Cryptol.ModuleSystem.NamingEnv,+                       Cryptol.ModuleSystem.Binds                        Cryptol.ModuleSystem.Exports,-                       Cryptol.ModuleSystem.InstantiateModule,                        Cryptol.ModuleSystem.Renamer,+                       Cryptol.ModuleSystem.Renamer.Imports,+                       Cryptol.ModuleSystem.Renamer.ImplicitImports,                        Cryptol.ModuleSystem.Renamer.Monad,                        Cryptol.ModuleSystem.Renamer.Error, @@ -132,7 +158,6 @@                        Cryptol.TypeCheck.Parseable,                        Cryptol.TypeCheck.Monad,                        Cryptol.TypeCheck.Infer,-                       Cryptol.TypeCheck.CheckModuleInstance,                        Cryptol.TypeCheck.InferTypes,                        Cryptol.TypeCheck.Interface,                        Cryptol.TypeCheck.Error,@@ -147,6 +172,12 @@                        Cryptol.TypeCheck.TypeMap,                        Cryptol.TypeCheck.TypeOf,                        Cryptol.TypeCheck.Sanity,+                       Cryptol.TypeCheck.FFI,+                       Cryptol.TypeCheck.FFI.Error,+                       Cryptol.TypeCheck.FFI.FFIType,+                       Cryptol.TypeCheck.Module,+                       Cryptol.TypeCheck.ModuleInstance,+                       Cryptol.TypeCheck.ModuleBacktickInstance,                         Cryptol.TypeCheck.Solver.Types,                        Cryptol.TypeCheck.Solver.SMT,@@ -162,13 +193,15 @@                         Cryptol.Transform.MonoValues,                        Cryptol.Transform.Specialize,-                       Cryptol.Transform.AddModParams,                         Cryptol.IR.FreeVars,+                       Cryptol.IR.TraverseNames,                         Cryptol.Backend,                        Cryptol.Backend.Arch,                        Cryptol.Backend.Concrete,+                       Cryptol.Backend.FFI,+                       Cryptol.Backend.FFI.Error,                        Cryptol.Backend.FloatHelpers,                        Cryptol.Backend.Monad,                        Cryptol.Backend.SeqMap,@@ -179,6 +212,8 @@                        Cryptol.Eval,                        Cryptol.Eval.Concrete,                        Cryptol.Eval.Env,+                       Cryptol.Eval.FFI,+                       Cryptol.Eval.FFI.GenHeader,                        Cryptol.Eval.Generic,                        Cryptol.Eval.Prims,                        Cryptol.Eval.Reference,@@ -199,6 +234,7 @@                        Cryptol.Symbolic.What4,                         Cryptol.REPL.Command,+                       Cryptol.REPL.Help,                        Cryptol.REPL.Browse,                        Cryptol.REPL.Monad,                        Cryptol.REPL.Trie
cryptol/CheckExercises.hs view
@@ -291,7 +291,7 @@      if Seq.null (rdReplout rd)       then do let cryCmd = (P.shell (exe ++ " --interactive-batch " ++ inFile ++ " -e"))-              (cryEC, cryOut, _) <- P.readCreateProcessWithExitCode cryCmd ""+              (cryEC, cryOut, cryErr) <- P.readCreateProcessWithExitCode cryCmd ""                 Line lnReplinStart _ Seq.:<| _ <- return $ rdReplin rd@@ -301,6 +301,7 @@                   putStrLn $ "REPL error (replin lines " ++                     show lnReplinStart ++ "-" ++ show lnReplinEnd ++ ")."                   putStr cryOut+                  putStr cryErr                   exitFailure                 ExitSuccess -> do                   -- remove temporary input file
cryptol/Main.hs view
@@ -200,7 +200,7 @@             , "via the `:edit` command"             ]           )-        , ( "SBV_{ABC,BOOLECTOR,CVC4,MATHSAT,YICES,Z3}_OPTIONS"+        , ( "SBV_{ABC,BOOLECTOR,CVC4,CVC5,MATHSAT,YICES,Z3}_OPTIONS"           , [ "A string of command-line arguments to be passed to the"             , "corresponding solver invoked for `:sat` and `:prove`"             , "when using a prover via SBV"
lib/Array.cry view
@@ -10,6 +10,7 @@ primitive arrayConstant : {a, b} b -> (Array a b) primitive arrayLookup : {a, b} (Array a b) -> a -> b primitive arrayUpdate : {a, b} (Array a b) -> a -> b -> (Array a b)+primitive arrayEq : {n, a} (Array [n] a) -> (Array [n] a) -> Bool  /**  * Copy elements from the source array to the destination array.
lib/Cryptol.cry view
@@ -339,11 +339,21 @@ primitive type Ring : * -> Prop  /**- * Converts an unbounded integer to a value in a Ring. When converting- * to the bitvector type [n], the value is reduced modulo 2^^n. Likewise,- * when converting to Z n, the value is reduced modulo n.  When converting- * to a floating-point value, the value is rounded to the nearest- * representable value.+ * Converts an unbounded integer to a value in a Ring using the following rules:+ *   * to bitvector type [n]:+ *     the value is reduced modulo 2^^n,+ *   * to Z n:+ *     the value is reduced modulo n,+ *   * floating point types:+ *     the value is rounded to the nearest representable value,+ *   * sequences other than bitvectors:+ *     elements are computed by using `fromInteger` pointwise+ *     Example: (fromInteger 2 : [3][8]) === [ 0x02, 0x02, 0x02 ]+ *   * tuples and records:+ *     elements are computed by using `fromInteger` pointwise+ *     Example: (fromInteger 2 : (Integer,[3][8])) === (2, [ 0x2, 0x2, 0x2 ])+ *   * functions:+ *     a constant function returning `fromInteger` on the result type  */ primitive fromInteger : {a} (Ring a) => Integer -> a 
+ src/Cryptol/Backend/FFI.hs view
@@ -0,0 +1,276 @@+{-# LANGUAGE BlockArguments            #-}+{-# LANGUAGE CPP                       #-}+{-# LANGUAGE DeriveAnyClass            #-}+{-# LANGUAGE DeriveGeneric             #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE LambdaCase                #-}+{-# LANGUAGE RecordWildCards           #-}+{-# LANGUAGE ScopedTypeVariables       #-}+{-# LANGUAGE TypeApplications          #-}++-- | The implementation of loading and calling external functions from shared+-- libraries.+module Cryptol.Backend.FFI+  ( ForeignSrc+  , getForeignSrcPath+  , loadForeignSrc+  , unloadForeignSrc+  , foreignLibPath+#ifdef FFI_ENABLED+  , ForeignImpl+  , loadForeignImpl+  , FFIArg+  , FFIRet+  , SomeFFIArg (..)+  , callForeignImpl+#endif+  )+  where++import           Control.DeepSeq++import           Cryptol.Backend.FFI.Error++#ifdef FFI_ENABLED++import           Control.Concurrent.MVar+import           Control.Exception+import           Control.Monad+import           Data.Bifunctor+import           Data.Word+import           Foreign                    hiding (newForeignPtr)+import           Foreign.C.Types+import           Foreign.Concurrent+import           Foreign.LibFFI+import           System.FilePath            ((-<.>))+import           System.Directory(doesFileExist)+import           System.IO.Error+import           System.Info(os)++#if defined(mingw32_HOST_OS)+import           System.Win32.DLL+#else+import           System.Posix.DynamicLinker+#endif++import           Cryptol.Utils.Panic++#else++import           GHC.Generics++#endif++#ifdef FFI_ENABLED++-- | A source from which we can retrieve implementations of foreign functions.+data ForeignSrc = ForeignSrc+  { -- | The file path of the 'ForeignSrc'.+    foreignSrcPath   :: FilePath+    -- | The 'ForeignPtr' wraps the pointer returned by 'dlopen', where the+    -- finalizer calls 'dlclose' when the library is no longer needed. We keep+    -- references to the 'ForeignPtr' in each foreign function that is in the+    -- evaluation environment, so that the shared library will stay open as long+    -- as there are references to it.+  , foreignSrcFPtr   :: ForeignPtr ()+    -- | We support explicit unloading of the shared library so we keep track of+    -- if it has already been unloaded, and if so the finalizer does nothing.+    -- This is updated atomically when the library is unloaded.+  , foreignSrcLoaded :: MVar Bool }++instance Show ForeignSrc where+  show = show . foreignSrcFPtr++instance NFData ForeignSrc where+  rnf ForeignSrc {..} = foreignSrcFPtr `seq` foreignSrcLoaded `deepseq` ()++-- | Get the file path of the 'ForeignSrc'.+getForeignSrcPath :: ForeignSrc -> Maybe FilePath+getForeignSrcPath = Just . foreignSrcPath++-- | Load a 'ForeignSrc' for the given __Cryptol__ file path. The file path of+-- the shared library that we try to load is the same as the Cryptol file path+-- except with a platform specific extension.+loadForeignSrc :: FilePath -> IO (Either FFILoadError ForeignSrc)+loadForeignSrc = loadForeignLib >=> traverse \(foreignSrcPath, ptr) -> do+  foreignSrcLoaded <- newMVar True+  foreignSrcFPtr <- newForeignPtr ptr (unloadForeignSrc' foreignSrcLoaded ptr)+  pure ForeignSrc {..}+++-- | Given the path to a Cryptol module, compute the location of+-- the shared library we'd like to load.+foreignLibPath :: FilePath -> IO (Maybe FilePath)+foreignLibPath path =+  search+    case os of+      "mingw32" -> ["dll"]+      "darwin"  -> ["dylib","so"]+      _         -> ["so"]++  where+  search es =+    case es of+      [] -> pure Nothing+      e : more ->+        do let p = path -<.> e+           yes <- doesFileExist p+           if yes then pure (Just p) else search more+++loadForeignLib :: FilePath -> IO (Either FFILoadError (FilePath, Ptr ()))+loadForeignLib path =+  do mb <- foreignLibPath path+     case mb of+       Nothing      -> pure (Left (CantLoadFFISrc path "File not found"))+       Just libPath -> tryLoad (CantLoadFFISrc path) (open libPath)++  where open libPath = do+#if defined(mingw32_HOST_OS)+          ptr <- loadLibrary libPath+#else+          -- RTLD_NOW so we can make sure that the symbols actually exist at+          -- module loading time+          ptr <- undl <$> dlopen libPath [RTLD_NOW]+#endif+          pure (libPath, ptr)++-- | Explicitly unload a 'ForeignSrc' immediately instead of waiting for the+-- garbage collector to do it. This can be useful if you want to immediately+-- load the same library again to pick up new changes.+--+-- The 'ForeignSrc' __must not__ be used in any way after this is called,+-- including calling 'ForeignImpl's loaded from it.+unloadForeignSrc :: ForeignSrc -> IO ()+unloadForeignSrc ForeignSrc {..} = withForeignPtr foreignSrcFPtr $+  unloadForeignSrc' foreignSrcLoaded++unloadForeignSrc' :: MVar Bool -> Ptr () -> IO ()+unloadForeignSrc' loaded lib = modifyMVar_ loaded \l -> do+  when l $ unloadForeignLib lib+  pure False++unloadForeignLib :: Ptr () -> IO ()+#if defined(mingw32_HOST_OS)+unloadForeignLib = freeLibrary+#else+unloadForeignLib = dlclose . DLHandle+#endif++withForeignSrc :: ForeignSrc -> (Ptr () -> IO a) -> IO a+withForeignSrc ForeignSrc {..} f = withMVar foreignSrcLoaded+  \case+    True -> withForeignPtr foreignSrcFPtr f+    False ->+      panic "[FFI] withForeignSrc" ["Use of foreign library after unload"]++-- | An implementation of a foreign function.+data ForeignImpl = ForeignImpl+  { foreignImplFun :: FunPtr ()+    -- | We don't need this to call the function but we want to keep the library+    -- around as long as we still have a function from it so that it isn't+    -- unloaded too early.+  , foreignImplSrc :: ForeignSrc+  }++-- | Load a 'ForeignImpl' with the given name from the given 'ForeignSrc'.+loadForeignImpl :: ForeignSrc -> String -> IO (Either FFILoadError ForeignImpl)+loadForeignImpl foreignImplSrc name =+  withForeignSrc foreignImplSrc \lib ->+    tryLoad (CantLoadFFIImpl name) do+      foreignImplFun <- loadForeignFunPtr lib name+      pure ForeignImpl {..}++loadForeignFunPtr :: Ptr () -> String -> IO (FunPtr ())+#if defined(mingw32_HOST_OS)+loadForeignFunPtr source symbol = do+  addr <- getProcAddress source symbol+  pure $ castPtrToFunPtr addr+#else+loadForeignFunPtr = dlsym . DLHandle+#endif++tryLoad :: (String -> FFILoadError) -> IO a -> IO (Either FFILoadError a)+tryLoad err = fmap (first $ err . displayException) . tryIOError++-- | Types which can be converted into libffi arguments.+--+-- The Storable constraint is so that we can put them in arrays.+class Storable a => FFIArg a where+  ffiArg :: a -> Arg++instance FFIArg Word8 where+  ffiArg = argWord8++instance FFIArg Word16 where+  ffiArg = argWord16++instance FFIArg Word32 where+  ffiArg = argWord32++instance FFIArg Word64 where+  ffiArg = argWord64++instance FFIArg CFloat where+  ffiArg = argCFloat++instance FFIArg CDouble where+  ffiArg = argCDouble++instance FFIArg (Ptr a) where+  ffiArg = argPtr++instance FFIArg CSize where+  ffiArg = argCSize++-- | Types which can be returned from libffi.+--+-- The Storable constraint is so that we can put them in arrays.+class Storable a => FFIRet a where+  ffiRet :: RetType a++instance FFIRet Word8 where+  ffiRet = retWord8++instance FFIRet Word16 where+  ffiRet = retWord16++instance FFIRet Word32 where+  ffiRet = retWord32++instance FFIRet Word64 where+  ffiRet = retWord64++instance FFIRet CFloat where+  ffiRet = retCFloat++instance FFIRet CDouble where+  ffiRet = retCDouble++instance FFIRet () where+  ffiRet = retVoid++-- | Existential wrapper around a 'FFIArg'.+data SomeFFIArg = forall a. FFIArg a => SomeFFIArg a++-- | Call a 'ForeignImpl' with the given arguments. The type parameter decides+-- how the return value should be converted into a Haskell value.+callForeignImpl :: forall a. FFIRet a => ForeignImpl -> [SomeFFIArg] -> IO a+callForeignImpl ForeignImpl {..} xs = withForeignSrc foreignImplSrc \_ ->+  callFFI foreignImplFun (ffiRet @a) $ map toArg xs+  where toArg (SomeFFIArg x) = ffiArg x++#else++data ForeignSrc = ForeignSrc deriving (Show, Generic, NFData)++getForeignSrcPath :: ForeignSrc -> Maybe FilePath+getForeignSrcPath _ = Nothing++loadForeignSrc :: FilePath -> IO (Either FFILoadError ForeignSrc)+loadForeignSrc _ = pure $ Right ForeignSrc++unloadForeignSrc :: ForeignSrc -> IO ()+unloadForeignSrc _ = pure ()++#endif
+ src/Cryptol/Backend/FFI/Error.hs view
@@ -0,0 +1,44 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric  #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE Safe  #-}++-- | Errors from dynamic loading of shared libraries for FFI.+module Cryptol.Backend.FFI.Error where++import           Control.DeepSeq+import           GHC.Generics++import           Cryptol.Utils.PP+import           Cryptol.ModuleSystem.Name++data FFILoadError+  = CantLoadFFISrc+    FilePath -- ^ Path to cryptol module+    String   -- ^ Error message+  | CantLoadFFIImpl+    String   -- ^ Function name+    String   -- ^ Error message+  | FFIDuplicates [Name]+  | FFIInFunctor  Name+  deriving (Show, Generic, NFData)++instance PP FFILoadError where+  ppPrec _ e =+    case e of+      CantLoadFFISrc path msg ->+        hang ("Could not load foreign source for module located at"+              <+> text path <.> colon)+          4 (text msg)+      CantLoadFFIImpl name msg ->+        hang ("Could not load foreign implementation for binding"+              <+> text name <.> colon)+          4 (text msg)+      FFIDuplicates xs ->+        hang "Multiple foreign declarations with the same name:"+           4 (backticks (pp (nameIdent (head xs))) <+>+                 "defined at" <+> align (vcat (map (pp . nameLoc) xs)))+      FFIInFunctor x ->+        hang (pp (nameLoc x) <.> ":")+          4 "Foreign declaration" <+> backticks (pp (nameIdent x)) <+>+                "may not appear in a parameterized module."
src/Cryptol/Backend/FloatHelpers.hs view
@@ -8,6 +8,7 @@  import Cryptol.Utils.PP import Cryptol.Utils.Panic(panic)+import Cryptol.Utils.Types import Cryptol.Backend.Monad( EvalError(..) )  @@ -176,3 +177,8 @@ -- (most significant bit in the significand is set, the rest of it is 0) floatToBits :: Integer -> Integer -> BigFloat -> Integer floatToBits e p bf = bfToBits (fpOpts e p NearEven) bf+++-- | Create a 64-bit IEEE-754 float.+floatFromDouble :: Double -> BF+floatFromDouble = uncurry BF float64ExpPrec . bfFromDouble
src/Cryptol/Backend/Monad.hs view
@@ -54,7 +54,7 @@ import Cryptol.Parser.Position import Cryptol.Utils.Panic import Cryptol.Utils.PP-import Cryptol.TypeCheck.AST(Name)+import Cryptol.TypeCheck.AST(Name, TParam)  -- | A computation that returns an already-evaluated value. ready :: a -> Eval a@@ -412,16 +412,20 @@  -- | Data type describing errors that can occur during evaluation. data EvalError-  = InvalidIndex (Maybe Integer)  -- ^ Out-of-bounds index-  | DivideByZero                  -- ^ Division or modulus by 0-  | NegativeExponent              -- ^ Exponentiation by negative integer-  | LogNegative                   -- ^ Logarithm of a negative integer-  | UserError String              -- ^ Call to the Cryptol @error@ primitive-  | LoopError String              -- ^ Detectable nontermination-  | NoPrim Name                   -- ^ Primitive with no implementation-  | BadRoundingMode Integer       -- ^ Invalid rounding mode-  | BadValue String               -- ^ Value outside the domain of a partial function.-    deriving Typeable+  = InvalidIndex (Maybe Integer)         -- ^ Out-of-bounds index+  | DivideByZero                         -- ^ Division or modulus by 0+  | NegativeExponent                     -- ^ Exponentiation by negative integer+  | LogNegative                          -- ^ Logarithm of a negative integer+  | UserError String                     -- ^ Call to the Cryptol @error@ primitive+  | LoopError String                     -- ^ Detectable nontermination+  | NoPrim Name                          -- ^ Primitive with no implementation+  | BadRoundingMode Integer              -- ^ Invalid rounding mode+  | BadValue String                      -- ^ Value outside the domain of a partial function.+  | NoMatchingPropGuardCase String    -- ^ No prop guard holds for the given type variables.+  | FFINotSupported Name                 -- ^ Foreign function cannot be called+  | FFITypeNumTooBig Name TParam Integer -- ^ Number passed to foreign function+                                         --   as a type argument is too large+  deriving Typeable  instance PP EvalError where   ppPrec _ e = case e of@@ -440,6 +444,18 @@     BadRoundingMode r -> "invalid rounding mode" <+> integer r     BadValue x -> "invalid input for" <+> backticks (text x)     NoPrim x -> text "unimplemented primitive:" <+> pp x+    NoMatchingPropGuardCase msg -> text $ "No matching constraint guard; " ++ msg+    FFINotSupported x -> vcat+      [ text "cannot call foreign function" <+> pp x+      , text "FFI calls are not supported in this context"+      , text "If you are trying to evaluate an expression, try rebuilding"+      , text "  Cryptol with FFI support enabled."+      ]+    FFITypeNumTooBig f p n -> vcat+      [ text "numeric type argument to foreign function is too large:"+        <+> integer n+      , text "in type parameter" <+> pp p <+> "of function" <+> pp f+      , text "type arguments must fit in a C `size_t`" ]  instance Show EvalError where   show = show . pp
src/Cryptol/Backend/What4.hs view
@@ -11,6 +11,7 @@ {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-} {-# LANGUAGE ViewPatterns #-} module Cryptol.Backend.What4 where 
src/Cryptol/Eval.hs view
@@ -15,6 +15,7 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE PatternGuards #-} {-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE NamedFieldPuns #-}  module Cryptol.Eval (     moduleEnv@@ -35,6 +36,7 @@   , Unsupported(..)   , WordTooWide(..)   , forceValue+  , checkProp   ) where  import Cryptol.Backend@@ -63,6 +65,7 @@ import qualified Data.IntMap.Strict as IntMap import qualified Data.Map.Strict as Map import           Data.Semigroup+import           Control.Applicative  import Prelude () import Prelude.Compat@@ -171,8 +174,9 @@       Just (Right val)         | ?callStacks ->             case nameInfo n of-              Declared{} -> sPushFrame sym n ?range (cacheCallStack sym =<< val)-              Parameter  -> cacheCallStack sym =<< val+              GlobalName {} ->+                 sPushFrame sym n ?range (cacheCallStack sym =<< val)+              LocalName {} -> cacheCallStack sym =<< val         | otherwise -> val       Nothing  -> do         envdoc <- ppEnv sym defaultPPOpts env@@ -215,13 +219,59 @@      env' <- evalDecls sym ds env      evalExpr sym env' e +  EPropGuards guards _ -> {-# SCC "evalExpr->EPropGuards" #-} do+    let checkedGuards = [ e | (ps,e) <- guards, all (checkProp . evalProp env) ps ]+    case checkedGuards of+      (e:_) -> eval e+      [] -> raiseError sym (NoMatchingPropGuardCase $ "Among constraint guards: " ++ show (fmap pp . fst <$> guards))+   where    {-# INLINE eval #-}   eval = evalExpr sym env   ppV = ppValue sym defaultPPOpts +-- | Checks whether an evaluated `Prop` holds+checkProp :: Prop -> Bool+checkProp = \case+  TCon tcon ts ->+    let ns = toNat' <$> ts in+    case tcon of+      PC PEqual | [n1, n2] <- ns -> n1 == n2+      PC PNeq | [n1, n2] <- ns -> n1 /= n2+      PC PGeq | [n1, n2] <- ns -> n1 >= n2+      PC PFin | [n] <- ns -> n /= Inf+      -- TODO: instantiate UniqueFactorization for Nat'?+      -- PC PPrime | [n] <- ns -> isJust (isPrime n) +      PC PTrue -> True+      TError {} -> False+      _ -> evalPanic "evalProp" ["cannot use this as a guarding constraint: ", show . pp $ TCon tcon ts ]+  prop -> evalPanic "evalProp" ["cannot use this as a guarding constraint: ", show . pp $ prop ]+  where+    toNat' :: Type -> Nat'+    toNat' = \case+      TCon (TC (TCNum n)) [] -> Nat n+      TCon (TC TCInf) [] -> Inf+      prop -> panic "checkProp" ["Expected `" ++ pretty prop ++ "` to be an evaluated numeric type"] ++-- | Evaluates a `Prop` in an `EvalEnv` by substituting all variables according+-- to `envTypes` and expanding all type synonyms via `tNoUser`.+evalProp :: GenEvalEnv sym -> Prop -> Prop+evalProp env@EvalEnv { envTypes } = \case+  TCon tc tys+    | TError KProp <- tc, [p] <- tys ->+      case evalProp env p of+        x@(TCon (TError KProp) _) -> x+        _                         -> TCon (TError KProp) [evalProp env p]+    | otherwise -> TCon tc (toType . evalType envTypes <$> tys)+  TVar tv | Just (toType -> ty) <- lookupTypeVar tv envTypes -> ty+  prop@TUser {} -> evalProp env (tNoUser prop)+  TVar tv | Nothing <- lookupTypeVar tv envTypes -> panic "evalProp" ["Could not find type variable `" ++ pretty tv ++ "` in the type evaluation environment"]+  prop -> panic "evalProp" ["Cannot use the following as a type constraint: `" ++ pretty prop ++ "`"]+  where+    toType = either tNumTy tValTy+ -- | Capure the current call stack from the evaluation monad and --   annotate function values.  When arguments are later applied --   to the function, the call stacks will be combined together.@@ -269,7 +319,7 @@   Newtype ->   GenEvalEnv sym ->   SEval sym (GenEvalEnv sym)-evalNewtypeDecl _sym nt = pure . bindVarDirect (ntName nt) (foldr tabs con (ntParams nt))+evalNewtypeDecl _sym nt = pure . bindVarDirect (ntConName nt) (foldr tabs con (ntParams nt))   where   con           = PFun PPrim @@ -382,9 +432,11 @@   sym -> Decl -> SEval sym (Name, Schema, SEval sym (GenValue sym), SEval sym (GenValue sym) -> SEval sym ()) declHole sym d =   case dDefinition d of-    DPrim   -> evalPanic "Unexpected primitive declaration in recursive group"-                         [show (ppLocName nm)]-    DExpr _ -> do+    DPrim      -> evalPanic "Unexpected primitive declaration in recursive group"+                            [show (ppLocName nm)]+    DForeign _ -> evalPanic "Unexpected foreign declaration in recursive group"+                            [show (ppLocName nm)]+    DExpr _    -> do       (hole, fill) <- sDeclareHole sym msg       return (nm, sch, hole, fill)   where@@ -407,8 +459,10 @@   GenEvalEnv sym  {- ^ An evaluation environment to extend with the given declaration -} ->   Decl            {- ^ The declaration to evaluate -} ->   SEval sym (GenEvalEnv sym)-evalDecl sym renv env d =-  let ?range = nameLoc (dName d) in+-- evalDecl sym renv env d =+--   let ?range = nameLoc (dName d) in+evalDecl sym renv env d = do+  let ?range = nameLoc (dName d)   case dDefinition d of     DPrim ->       case ?evalPrim =<< asPrim (dName d) of@@ -416,6 +470,18 @@         Just (Left ex) -> bindVar sym (dName d) (evalExpr sym renv ex) env         Nothing        -> bindVar sym (dName d) (cryNoPrimError sym (dName d)) env +    DForeign _ -> do+      -- Foreign declarations should have been handled by the previous+      -- Cryptol.Eval.FFI.evalForeignDecls pass already, so they should already+      -- be in the environment. If not, then either Cryptol was not compiled+      -- with FFI support enabled, or we are in a non-Concrete backend. In that+      -- case, we just bind the name to an error computation which will raise an+      -- error if we try to evaluate it.+      case lookupVar (dName d) env of+        Just _  -> pure env+        Nothing -> bindVar sym (dName d)+          (raiseError sym $ FFINotSupported $ dName d) env+     DExpr e -> bindVar sym (dName d) (evalExpr sym renv e) env  @@ -689,5 +755,6 @@     where       f env =           case dDefinition d of-            DPrim   -> evalPanic "evalMatch" ["Unexpected local primitive"]-            DExpr e -> evalExpr sym env e+            DPrim      -> evalPanic "evalMatch" ["Unexpected local primitive"]+            DForeign _ -> evalPanic "evalMatch" ["Unexpected local foreign"]+            DExpr e    -> evalExpr sym env e
src/Cryptol/Eval/Concrete.hs view
@@ -8,16 +8,10 @@  {-# LANGUAGE BangPatterns #-} {-# LANGUAGE BlockArguments #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE PatternGuards #-} {-# LANGUAGE Rank2Types #-}-{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE ViewPatterns #-} module Cryptol.Eval.Concrete   ( module Cryptol.Backend.Concrete   , Value@@ -87,7 +81,7 @@            case res of              Left _ -> mismatch -- different fields              Right efs ->-               let f = foldl (\x t -> ETApp x (tNumValTy t)) (EVar (ntName nt)) ts+               let f = foldl (\x t -> ETApp x (tNumValTy t)) (EVar (ntConName nt)) ts                 in pure (EApp f (ERec efs))        (TVTuple ts, VTuple tvs) ->
+ src/Cryptol/Eval/FFI.hs view
@@ -0,0 +1,430 @@+{-# LANGUAGE BangPatterns        #-}+{-# LANGUAGE BlockArguments      #-}+{-# LANGUAGE CPP                 #-}+{-# LANGUAGE LambdaCase          #-}+{-# LANGUAGE NamedFieldPuns      #-}+{-# LANGUAGE PatternSynonyms     #-}+{-# LANGUAGE RankNTypes          #-}+{-# LANGUAGE RecordWildCards     #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TupleSections       #-}+{-# LANGUAGE TypeApplications    #-}+{-# LANGUAGE ViewPatterns        #-}++-- | Evaluation of foreign functions.+module Cryptol.Eval.FFI+  ( findForeignDecls+  , evalForeignDecls+  ) where++import           Cryptol.Backend.FFI+import           Cryptol.Backend.FFI.Error+import           Cryptol.Eval+import           Cryptol.TypeCheck.AST+import           Cryptol.TypeCheck.FFI.FFIType++#ifdef FFI_ENABLED++import           Control.Exception(bracket_)+import           Data.Either+import           Data.Foldable+import           Data.IORef+import           Data.Proxy+import           Data.Ratio+import           Data.Traversable+import           Data.Word+import           Foreign+import           Foreign.C.Types+import           GHC.Float+import           LibBF                         (bfFromDouble, bfToDouble,+                                                pattern NearEven)+import           Numeric.GMP.Raw.Unsafe+import           Numeric.GMP.Utils++import           Cryptol.Backend+import           Cryptol.Backend.Concrete+import           Cryptol.Backend.FloatHelpers+import           Cryptol.Backend.Monad+import           Cryptol.Backend.SeqMap+import           Cryptol.Eval.Env+import           Cryptol.Eval.Prims+import           Cryptol.Eval.Type+import           Cryptol.Eval.Value+import           Cryptol.ModuleSystem.Name+import           Cryptol.Utils.Ident+import           Cryptol.Utils.RecordMap++#endif++#ifdef FFI_ENABLED++-- | Add the given foreign declarations to the environment, loading their+-- implementations from the given 'ForeignSrc'. This is a separate pass from the+-- main evaluation functions in "Cryptol.Eval" since it only works for the+-- Concrete backend.+evalForeignDecls :: ForeignSrc -> [(Name, FFIFunType)] -> EvalEnv ->+  Eval (Either [FFILoadError] EvalEnv)+evalForeignDecls fsrc decls env = io do+  ePrims <- for decls \(name, ffiFunType) ->+    fmap ((name,) . foreignPrimPoly name ffiFunType) <$>+      loadForeignImpl fsrc (unpackIdent $ nameIdent name)+  pure case partitionEithers ePrims of+    ([], prims) -> Right $ foldr (uncurry bindVarDirect) env prims+    (errs, _)   -> Left errs++-- | Generate a 'Prim' value representing the given foreign function, containing+-- all the code necessary to marshal arguments and return values and do the+-- actual FFI call.+foreignPrimPoly :: Name -> FFIFunType -> ForeignImpl -> Prim Concrete+foreignPrimPoly name fft impl = buildNumPoly (ffiTParams fft) mempty+  where -- Add type lambdas for the type parameters and build a type environment+        -- that we can look up later to compute e.g. array sizes.+        --+        -- Given [p1, p2, ..., pk] {}, returns+        -- PNumPoly \n1 -> PNumPoly \n2 -> ... PNumPoly \nk ->+        --   foreignPrim name fft impl {p1 = n1, p2 = n2, ..., pk = nk}+        buildNumPoly (tp:tps) tenv = PNumPoly \n ->+          buildNumPoly tps $ bindTypeVar (TVBound tp) (Left n) tenv+        buildNumPoly [] tenv = foreignPrim name fft impl tenv++-- | Methods for obtaining a return value. The producer of this type must supply+-- both 1) a polymorphic IO object directly containing a return value that the+-- consumer can instantiate at any 'FFIRet' type, and 2) an effectful function+-- that takes some output arguments and modifies what they are pointing at to+-- store a return value. The consumer can choose which one to use.+data GetRet = GetRet+  { getRetAsValue   :: forall a. FFIRet a => IO a+  , getRetAsOutArgs :: [SomeFFIArg] -> IO () }++-- | Operations needed for returning a basic reference type.+data BasicRefRet a = BasicRefRet+  { -- | Initialize the object before passing to foreign function.+    initBasicRefRet    :: Ptr a -> IO ()+    -- | Free the object after returning from foreign function and obtaining+    -- return value.+  , clearBasicRefRet   :: Ptr a -> IO ()+    -- | Convert the object to a Cryptol value.+  , marshalBasicRefRet :: a -> Eval (GenValue Concrete) }++-- | Generate the monomorphic part of the foreign 'Prim', given a 'TypeEnv'+-- containing all the type arguments we have already received.+foreignPrim :: Name -> FFIFunType -> ForeignImpl -> TypeEnv -> Prim Concrete+foreignPrim name FFIFunType {..} impl tenv = buildFun ffiArgTypes []+  where++  -- Build up the 'Prim' function for the FFI call.+  --+  -- Given [t1, t2 ... tm] we return+  -- PStrict \v1 -> PStrict \v2 -> ... PStrict \vm -> PPrim $+  --   marshalArg t1 v1 \a1 ->+  --     marshalArg t2 v2 \a2 -> ... marshalArg tm vm \am ->+  --       marshalRet ffiRetType GetRet+  --         { getRetAsValue = callForeignImpl impl [n1, ..., nk, a1, ..., am]+  --         , getRetAsOutArgs = \[o1, ..., ol] ->+  --             callForeignImpl impl [n1, ..., nk, a1, ..., am, o1, ..., ol] }+  buildFun :: [FFIType] -> [(FFIType, GenValue Concrete)] -> Prim Concrete+  buildFun (argType:argTypes) typesAndVals = PStrict \val ->+    buildFun argTypes $ typesAndVals ++ [(argType, val)]+  buildFun [] typesAndVals = PPrim $+    marshalArgs typesAndVals \inArgs -> do+      tyArgs <- traverse marshalTyArg ffiTParams+      let tyInArgs = tyArgs ++ inArgs+      marshalRet ffiRetType GetRet+        { getRetAsValue = callForeignImpl impl tyInArgs+        , getRetAsOutArgs = callForeignImpl impl . (tyInArgs ++) }++  -- Look up the value of a type parameter in the type environment and marshal+  -- it.+  marshalTyArg :: TParam -> Eval SomeFFIArg+  marshalTyArg tp+    | n <= toInteger (maxBound :: CSize) =+      pure $ SomeFFIArg @CSize $ fromInteger n+    | otherwise = raiseError Concrete $ FFITypeNumTooBig name tp n+    where n = evalFinType $ TVar $ TVBound tp++  -- Marshal the given value as the given FFIType and call the given function+  -- with the results. A single Cryptol argument may correspond to any number of+  -- C arguments, so the callback takes a list.+  --+  -- NOTE: the result must be used only in the callback since it may have a+  -- limited lifetime (e.g. pointer returned by alloca).+  marshalArg ::+    FFIType ->+    GenValue Concrete ->+    ([SomeFFIArg] -> Eval a) ->+    Eval a++  marshalArg FFIBool val f = f [SomeFFIArg @Word8 (fromBool (fromVBit val))]++  marshalArg (FFIBasic (FFIBasicVal t)) val f =+    getMarshalBasicValArg t \doExport ->+    do arg <- doExport val+       f [SomeFFIArg arg]++  marshalArg (FFIBasic (FFIBasicRef t)) val f =+    getMarshalBasicRefArg t \doExport  ->+    -- Since we need to do Eval actions in an IO callback, we need to manually+    -- unwrap and wrap the Eval datatype+    Eval \stk ->+      doExport val \arg ->+        with arg \ptr ->+          runEval stk (f [SomeFFIArg ptr])++  marshalArg (FFIArray (map evalFinType -> sizes) bt) val f =+    case bt of++      FFIBasicVal t ->+        getMarshalBasicValArg t \doExport  ->+          -- Since we need to do Eval actions in an IO callback,+          -- we need to manually unwrap and wrap the Eval datatype+          Eval \stk ->+            marshalArrayArg stk \v k ->+              k =<< runEval stk (doExport v)++      FFIBasicRef t -> Eval \stk ->+        getMarshalBasicRefArg t \doExport ->+        marshalArrayArg stk doExport++    where marshalArrayArg stk doExport =+            allocaArray (fromInteger (product sizes)) \ptr -> do+              -- Traverse the nested sequences and write the elements to the+              -- array in order.+              -- ns is the dimensions of the values we are currently+              -- processing.+              -- vs is the values we are currently processing.+              -- nvss is the stack of previous ns and vs that we keep track of+              -- that we push onto when we start processing a nested sequence+              -- and pop off when we finish processing the current ones.+              -- i is the index into the array.++              let+                  -- write next element of multi-dimensional array+                  write (n:ns) (v:vs) nvss !i =+                    do vs' <- traverse (runEval stk)+                                       (enumerateSeqMap n (fromVSeq v))+                       write ns vs' ((n, vs):nvss) i++                  -- write next element in flat array+                  write [] (v:vs) nvss !i =+                    doExport v \rep ->+                      do pokeElemOff ptr i rep+                         write [] vs nvss (i + 1)++                  -- finished with flat array, do next element of multi-d array+                  write ns [] ((n, vs):nvss) !i = write (n:ns) vs nvss i++                  -- done+                  write _ _ [] _ = pure ()+++              write sizes [val] [] 0+              runEval stk $ f [SomeFFIArg ptr]++  marshalArg (FFITuple types) val f =+    do vals <- sequence (fromVTuple val)+       marshalArgs (types `zip` vals) f++  marshalArg (FFIRecord typeMap) val f =+    do vals <- traverse (`lookupRecord` val) (displayOrder typeMap)+       marshalArgs (displayElements typeMap `zip` vals) f++  -- Call marshalArg on a bunch of arguments and collect the results together+  -- (in the order of the arguments).+  marshalArgs ::+    [(FFIType, GenValue Concrete)] ->+    ([SomeFFIArg] -> Eval a) ->+    Eval a+  marshalArgs typesAndVals f = go typesAndVals []+    where+    go [] args = f (concat (reverse args))+    go ((t, v):tvs) prevArgs =+      marshalArg t v \currArgs ->+      go tvs (currArgs : prevArgs)++  -- Given an FFIType and a GetRet, obtain a return value and convert it to a+  -- Cryptol value. The return value is obtained differently depending on the+  -- FFIType.+  marshalRet :: FFIType -> GetRet -> Eval (GenValue Concrete)+  marshalRet FFIBool gr =+    do rep <- io (getRetAsValue gr @Word8)+       pure (VBit (toBool rep))++  marshalRet (FFIBasic (FFIBasicVal t)) gr =+    getMarshalBasicValRet t \doImport ->+      do rep <- io (getRetAsValue gr)+         doImport rep++  marshalRet (FFIBasic (FFIBasicRef t)) gr =+    getBasicRefRet t \how ->+    Eval             \stk ->+    alloca           \ptr ->+    bracket_ (initBasicRefRet how ptr) (clearBasicRefRet how ptr)+      do getRetAsOutArgs gr [SomeFFIArg ptr]+         rep <- peek ptr+         runEval stk (marshalBasicRefRet how rep)++  marshalRet (FFIArray (map evalFinType -> sizes) bt) gr =+    Eval \stk -> do+    let totalSize = fromInteger (product sizes)+        getResult marshal ptr = do+          getRetAsOutArgs gr [SomeFFIArg ptr]++          let build (n:ns) !i = do+                -- We need to be careful to actually run this here and not just+                -- stick the IO action into the sequence with io, or else we+                -- will read from the array after it is deallocated.+                vs <- for [0 .. fromInteger n - 1] \j ->+                  build ns (i * fromInteger n + j)+                pure (VSeq n (finiteSeqMap Concrete (map pure vs)))+              build [] !i = peekElemOff ptr i >>= runEval stk . marshal++          build sizes 0++    case bt of++      FFIBasicVal t ->+        getMarshalBasicValRet t \doImport ->+        allocaArray totalSize (getResult doImport)++      FFIBasicRef t ->+        getBasicRefRet t      \how ->+        allocaArray totalSize \ptr ->+          do let forEach f = for_ [0 .. totalSize - 1] (f . advancePtr ptr)+             bracket_ (forEach (initBasicRefRet how))+                      (forEach (clearBasicRefRet how))+                      (getResult (marshalBasicRefRet how) ptr)++  marshalRet (FFITuple types) gr = VTuple <$> marshalMultiRet types gr++  marshalRet (FFIRecord typeMap) gr =+    VRecord . recordFromFields . zip (displayOrder typeMap) <$>+      marshalMultiRet (displayElements typeMap) gr++  -- Obtain multiple return values as output arguments for a composite return+  -- type. Each return value is fully evaluated but put back in an Eval since+  -- VTuple and VRecord expect it.+  marshalMultiRet :: [FFIType] -> GetRet -> Eval [Eval (GenValue Concrete)]+  -- Since IO callbacks are involved we just do the whole thing in IO and wrap+  -- it in an Eval at the end. This should be fine since we are not changing+  -- the (Cryptol) call stack.+  marshalMultiRet types gr = Eval \stk -> do+    -- We use this IORef hack here since we are calling marshalRet recursively+    -- but marshalRet doesn't let us return any extra information from the+    -- callback through to the result of the function. So we remember the result+    -- as a side effect.+    vals <- newIORef []+    let go [] args = getRetAsOutArgs gr args+        go (t:ts) prevArgs = do+          val <- runEval stk $ marshalRet t $ getRetFromAsOutArgs \currArgs ->+            go ts (prevArgs ++ currArgs)+          modifyIORef' vals (val :)+    go types []+    map pure <$> readIORef vals++  -- | Call the callback with a 'BasicRefRet' for the given type.+  getBasicRefRet :: FFIBasicRefType ->+    (forall a. Storable a => BasicRefRet a -> b) -> b+  getBasicRefRet (FFIInteger mbMod) f = f BasicRefRet+    { initBasicRefRet = mpz_init+    , clearBasicRefRet = mpz_clear+    , marshalBasicRefRet = \mpz -> do+        n <- io $ peekInteger' mpz+        VInteger <$>+          case mbMod of+            Nothing -> pure n+            Just m  -> intToZn Concrete (evalFinType m) n }+  getBasicRefRet FFIRational f = f BasicRefRet+    { initBasicRefRet = mpq_init+    , clearBasicRefRet = mpq_clear+    , marshalBasicRefRet = \mpq -> do+        r <- io $ peekRational' mpq+        pure $ VRational $ SRational (numerator r) (denominator r) }++  -- Evaluate a finite numeric type expression.+  evalFinType :: Type -> Integer+  evalFinType = finNat' . evalNumType tenv++-- | Given a way to 'getRetAsOutArgs', create a 'GetRet', where the+-- 'getRetAsValue' simply allocates a temporary space to call 'getRetAsOutArgs'+-- on. This is useful for return types that we know how to obtain directly as a+-- value but need to obtain as an output argument when multiple return values+-- are involved.+getRetFromAsOutArgs :: ([SomeFFIArg] -> IO ()) -> GetRet+getRetFromAsOutArgs f = GetRet+  { getRetAsValue = alloca \ptr -> do+      f [SomeFFIArg ptr]+      peek ptr+  , getRetAsOutArgs = f }++-- | Given a 'FFIBasicValType', call the callback with a marshalling function+-- that marshals values to the 'FFIArg' type corresponding to the+-- 'FFIBasicValType'. The callback must be able to handle marshalling functions+-- that marshal to any 'FFIArg' type.+getMarshalBasicValArg ::+  FFIBasicValType ->+  (forall rep.+      FFIArg rep =>+      (GenValue Concrete -> Eval rep) ->+      result) ->+  result++getMarshalBasicValArg (FFIWord _ s) f = withWordType s \(_ :: p t) ->+  f @t $ fmap (fromInteger . bvVal) . fromVWord Concrete "getMarshalBasicValArg"++getMarshalBasicValArg (FFIFloat _ _ s) f =+  case s of+    -- LibBF can only convert to 'Double' directly, so we do that first then+    -- convert to 'Float', which should not result in any loss of precision if+    -- the original data was 32-bit anyways.+    FFIFloat32 -> f $ pure . CFloat . double2Float . toDouble+    FFIFloat64 -> f $ pure . CDouble . toDouble+  where+  toDouble = fst . bfToDouble NearEven . bfValue . fromVFloat++-- | Given a 'FFIBasicValType', call the callback with an unmarshalling function+-- from the 'FFIRet' type corresponding to the 'FFIBasicValType' to Cryptol+-- values. The callback must be able to handle unmarshalling functions from any+-- 'FFIRet' type.+getMarshalBasicValRet :: FFIBasicValType ->+  (forall a. FFIRet a => (a -> Eval (GenValue Concrete)) -> b) -> b+getMarshalBasicValRet (FFIWord n s) f = withWordType s \(_ :: p t) ->+  f @t $ word Concrete n . toInteger+getMarshalBasicValRet (FFIFloat e p s) f =+  case s of+    FFIFloat32 -> f $ toValue . \case CFloat x -> float2Double x+    FFIFloat64 -> f $ toValue . \case CDouble x -> x+  where toValue = pure . VFloat . BF e p . bfFromDouble++-- | Call the callback with the Word type corresponding to the given+-- 'FFIWordSize'.+withWordType :: FFIWordSize ->+  (forall a. (FFIArg a, FFIRet a, Integral a) => Proxy a -> b) -> b+withWordType FFIWord8  f = f $ Proxy @Word8+withWordType FFIWord16 f = f $ Proxy @Word16+withWordType FFIWord32 f = f $ Proxy @Word32+withWordType FFIWord64 f = f $ Proxy @Word64++-- | Given a 'FFIBasicRefType', call the callback with a marshalling function+-- that takes a Cryptol value and calls its callback with the 'Storable' type+-- corresponding to the 'FFIBasicRefType'.+getMarshalBasicRefArg :: FFIBasicRefType ->+  (forall rep.+      Storable rep =>+      (GenValue Concrete -> (rep -> IO val) -> IO val) ->+      result) ->+  result+getMarshalBasicRefArg (FFIInteger _) f = f \val g ->+  withInInteger' (fromVInteger val) g+getMarshalBasicRefArg FFIRational f = f \val g -> do+  let SRational {..} = fromVRational val+  withInRational' (sNum % sDenom) g++#else++-- | Dummy implementation for when FFI is disabled. Does not add anything to+-- the environment.+evalForeignDecls :: ForeignSrc -> [(Name, FFIFunType)] -> EvalEnv ->+  Eval (Either [FFILoadError] EvalEnv)+evalForeignDecls _ _ env = pure $ Right env++#endif
+ src/Cryptol/Eval/FFI/GenHeader.hs view
@@ -0,0 +1,196 @@+{-# LANGUAGE BlockArguments   #-}+{-# LANGUAGE LambdaCase       #-}+{-# LANGUAGE RecordWildCards  #-}+{-# LANGUAGE TypeApplications #-}++-- | Generate C header files from foreign declarations.+module Cryptol.Eval.FFI.GenHeader+  ( generateForeignHeader+  ) where++import           Control.Monad.Writer.Strict+import           Data.Functor+import           Data.Char(isAlphaNum)+import           Data.List+import           Data.Set                      (Set)+import qualified Data.Set                      as Set+import           Language.C99.Pretty           as C+import qualified Language.C99.Simple           as C+import qualified Text.PrettyPrint              as Pretty++import           Cryptol.ModuleSystem.Name+import           Cryptol.TypeCheck.FFI.FFIType+import           Cryptol.TypeCheck.Type+import           Cryptol.Utils.Ident+import           Cryptol.Utils.RecordMap++-- | @Include foo@ represents an include statement @#include <foo>@+newtype Include = Include String deriving (Eq, Ord)++-- | The monad for generating headers. We keep track of which headers we need to+-- include and add them to the output at the end.+type GenHeaderM = Writer (Set Include)++-- | Generate a C header file from the given foreign declarations.+generateForeignHeader :: [(Name, FFIFunType)] -> String+generateForeignHeader decls =+  unlines (map renderInclude $ Set.toAscList incs)+  ++ Pretty.render (C.pretty $ C.translate (C.TransUnit cdecls []))+  where (cdecls, incs) = runWriter $ traverse convertFun decls++renderInclude :: Include -> String+renderInclude (Include inc) = "#include <" ++ inc ++ ">"++-- | The "direction" of a parameter (input or output).+data ParamDir = In | Out++-- | The result of converting a Cryptol type into its C representation.+data ConvertResult+  = Direct C.Type -- ^ A type that can be directly returned if it is a return+                  -- type and passed as a single parameter if it is a Cryptol+                  -- parameter type.+  | Params [C.Param] -- ^ A type that is turned into a number of parameters,+                     -- for both Cryptol parameter and return type cases.++-- | Convert a Cryptol foreign declaration into a C function declaration.+convertFun :: (Name, FFIFunType) -> GenHeaderM C.Decln+convertFun (fName, FFIFunType {..}) = do+  let tpIdent = fmap nameIdent . tpName+  typeParams <- traverse convertTypeParam (pickNames (map tpIdent ffiTParams))+  -- Name the input args in0, in1, etc+  let inPrefixes =+        case ffiArgTypes of+          [_] -> ["in"]+          _   -> ["in" ++ show @Integer i | i <- [0..]]+  inParams <- convertMultiType In $ zip inPrefixes ffiArgTypes+  (retType, outParams) <- convertType Out ffiRetType+    <&> \case+      Direct u  -> (u, [])+      -- Name the output arg out+      Params ps -> (C.TypeSpec C.Void, map (prefixParam "out") ps)+  -- Avoid possible name collisions+  let params = snd $ mapAccumL renameParam Set.empty $+        typeParams ++ inParams ++ outParams+      renameParam names (C.Param u name) =+        (Set.insert name' names, C.Param u name')+        where name' = until (`Set.notMember` names) (++ "_") name+  pure $ C.FunDecln Nothing retType (unpackIdent $ nameIdent fName) params+++-- | Convert a Cryptol type parameter to a C value parameter.+convertTypeParam :: String -> GenHeaderM C.Param+convertTypeParam name = (`C.Param` name) <$> sizeT++-- | Convert a Cryptol parameter or return type to C.+convertType :: ParamDir -> FFIType -> GenHeaderM ConvertResult+convertType _ FFIBool = Direct <$> uint8T+convertType _ (FFIBasic t) = convertBasicType t+convertType _ (FFIArray _ t) = do+  u <- convertBasicTypeInArray t+  pure $ Params [C.Param (C.Ptr u) ""]+convertType dir (FFITuple ts) = Params <$> convertMultiType dir+  -- We name the tuple components using their indices+  (zip (map (componentSuffix . show @Integer) [0..]) ts)+convertType dir (FFIRecord tMap) =+  Params <$> convertMultiType dir (zip names ts)+  where+  (fs,ts) = unzip (displayFields tMap)+  names   = map componentSuffix (pickNames (map Just fs))++-- | Convert many Cryptol types, each associated with a prefix, to C parameters+-- named with their prefixes.+convertMultiType :: ParamDir -> [(C.Ident, FFIType)] -> GenHeaderM [C.Param]+convertMultiType dir = fmap concat . traverse \(prefix, t) ->+  convertType dir t+    <&> \case+      Direct u -> [C.Param u' prefix]+        where u' = case dir of+                In  -> u+                -- Turn direct return types into pointer out parameters+                Out -> C.Ptr u+      Params ps -> map (prefixParam prefix) ps++{- | Convert a basic Cryptol FFI type to a C type with its corresponding+calling convention.  At present all value types use the same calling+convention no matter if they are inputs or outputs, so we don't+need the 'ParamDir'. -}+convertBasicType :: FFIBasicType -> GenHeaderM ConvertResult+convertBasicType bt =+  case bt of+    FFIBasicVal bvt -> Direct <$> convertBasicValType bvt+    FFIBasicRef brt -> do t <- convertBasicRefType brt+                          pure (Params [C.Param t ""])++-- | Convert a basic Cryptol FFI type to a C type.+-- This is used when the type is stored in array.+convertBasicTypeInArray :: FFIBasicType -> GenHeaderM C.Type+convertBasicTypeInArray bt =+  case bt of+    FFIBasicVal bvt -> convertBasicValType bvt+    FFIBasicRef brt -> convertBasicRefType brt++-- | Convert a basic Cryptol FFI type to a value C type.+convertBasicValType :: FFIBasicValType -> GenHeaderM C.Type+convertBasicValType (FFIWord _ s) =+  case s of+    FFIWord8  -> uint8T+    FFIWord16 -> uint16T+    FFIWord32 -> uint32T+    FFIWord64 -> uint64T+convertBasicValType (FFIFloat _ _ s) =+  case s of+    FFIFloat32 -> pure $ C.TypeSpec C.Float+    FFIFloat64 -> pure $ C.TypeSpec C.Double++-- | Convert a basic Cryptol FFI type to a reference C type.+convertBasicRefType :: FFIBasicRefType -> GenHeaderM C.Type+convertBasicRefType brt =+  case brt of+    FFIInteger {} -> mpzT+    FFIRational   -> mpqT++prefixParam :: C.Ident -> C.Param -> C.Param+prefixParam pre (C.Param u name) = C.Param u (pre ++ name)++-- | Create a suffix corresponding to some component name of some larger type.+componentSuffix :: String -> C.Ident+componentSuffix = ('_' :)++sizeT, uint8T, uint16T, uint32T, uint64T, mpzT, mpqT :: GenHeaderM C.Type+sizeT = typedefFromInclude stddefH "size_t"+uint8T = typedefFromInclude stdintH "uint8_t"+uint16T = typedefFromInclude stdintH "uint16_t"+uint32T = typedefFromInclude stdintH "uint32_t"+uint64T = typedefFromInclude stdintH "uint64_t"+mpzT = typedefFromInclude gmpH "mpz_t"+mpqT = typedefFromInclude gmpH "mpq_t"++stddefH, stdintH, gmpH :: Include+stddefH = Include "stddef.h"+stdintH = Include "stdint.h"+gmpH = Include "gmp.h"+++-- | Return a type with the given name, included from some header file.+typedefFromInclude :: Include -> C.Ident -> GenHeaderM C.Type+typedefFromInclude inc u = do+  tell $ Set.singleton inc+  pure $ C.TypeSpec $ C.TypedefName u++-- | Given some Cryptol identifiers (normal ones, not operators)+-- pick suitable unique C names for them+pickNames :: [Maybe Ident] -> [String]+pickNames xs = snd (mapAccumL add Set.empty xs)+  where+  add known x =+    let y      = simplify x+        ys     = y : [ y ++ show i | i <- [ 0 :: Int .. ] ]+        y' : _ = dropWhile (`Set.member` known) ys+    in (Set.insert y' known, y')++  simplify x = case x of+                 Just i | let y = filter ok (unpackIdent i), not (null y) -> y+                 _ -> "zz"++  ok x     = x == '_' || isAlphaNum x+
src/Cryptol/Eval/Generic.hs view
@@ -1452,12 +1452,12 @@   PNumPoly \first ->   PNumPoly \lst ->   PTyPoly  \ty ->-  PVal+  PPrim     let !f = mkLit sym ty in     case (first, lst) of       (Nat first', Nat lst') ->         let len = 1 + (lst' - first')-        in VSeq len $ indexSeqMap $ \i -> f (first' + i)+        in mkSeq sym (Nat len) ty $ indexSeqMap $ \i -> f (first' + i)       _ -> evalPanic "fromToV" ["invalid arguments"]  {-# INLINE fromThenToV #-}@@ -1469,12 +1469,12 @@   PNumPoly \lst   ->   PTyPoly  \ty    ->   PNumPoly \len   ->-  PVal+  PPrim     let !f = mkLit sym ty in     case (first, next, lst, len) of       (Nat first', Nat next', Nat _lst', Nat len') ->         let diff = next' - first'-        in VSeq len' $ indexSeqMap $ \i -> f (first' + i*diff)+        in mkSeq sym (Nat len') ty $ indexSeqMap $ \i -> f (first' + i*diff)       _ -> evalPanic "fromThenToV" ["invalid arguments"]  {-# INLINE fromToLessThanV #-}@@ -1484,12 +1484,12 @@   PFinPoly \first ->   PNumPoly \bound ->   PTyPoly  \ty ->-  PVal+  PPrim     let !f = mkLit sym ty         ss = indexSeqMap $ \i -> f (first + i)     in case bound of-         Inf        -> VStream ss-         Nat bound' -> VSeq (bound' - first) ss+         Inf        -> return $ VStream ss+         Nat bound' -> mkSeq sym (Nat (bound' - first)) ty ss  {-# INLINE fromToByV #-} -- @[ 0 .. 10 by 2 ]@@@ -1499,10 +1499,10 @@   PFinPoly \lst ->   PFinPoly \stride ->   PTyPoly  \ty ->-  PVal+  PPrim     let !f = mkLit sym ty         ss = indexSeqMap $ \i -> f (first + i*stride)-     in VSeq (1 + ((lst - first) `div` stride)) ss+     in mkSeq sym (Nat (1 + ((lst - first) `div` stride))) ty ss  {-# INLINE fromToByLessThanV #-} -- @[ 0 .. <10 by 2 ]@@@ -1512,12 +1512,12 @@   PNumPoly \bound ->   PFinPoly \stride ->   PTyPoly  \ty ->-  PVal+  PPrim     let !f = mkLit sym ty         ss = indexSeqMap $ \i -> f (first + i*stride)      in case bound of-          Inf -> VStream ss-          Nat bound' -> VSeq ((bound' - first + stride - 1) `div` stride) ss+          Inf -> return $ VStream ss+          Nat bound' -> mkSeq sym (Nat ((bound' - first + stride - 1) `div` stride)) ty ss   {-# INLINE fromToDownByV #-}@@ -1528,10 +1528,10 @@   PFinPoly \lst ->   PFinPoly \stride ->   PTyPoly  \ty ->-  PVal+  PPrim     let !f = mkLit sym ty         ss = indexSeqMap $ \i -> f (first - i*stride)-     in VSeq (1 + ((first - lst) `div` stride)) ss+     in mkSeq sym (Nat (1 + ((first - lst) `div` stride))) ty ss  {-# INLINE fromToDownByGreaterThanV #-} -- @[ 10 .. >0 down by 2 ]@@@ -1541,10 +1541,10 @@   PFinPoly \bound ->   PFinPoly \stride ->   PTyPoly  \ty ->-  PVal+  PPrim     let !f = mkLit sym ty         ss = indexSeqMap $ \i -> f (first - i*stride)-     in VSeq ((first - bound + stride - 1) `div` stride) ss+     in mkSeq sym (Nat ((first - bound + stride - 1) `div` stride)) ty ss  {-# INLINE infFromV #-} infFromV :: Backend sym => sym -> Prim sym
src/Cryptol/Eval/Reference.lhs view
@@ -10,6 +10,8 @@ > {-# LANGUAGE BlockArguments #-} > {-# LANGUAGE PatternGuards #-} > {-# LANGUAGE LambdaCase #-}+> {-# LANGUAGE NamedFieldPuns #-}+> {-# LANGUAGE ViewPatterns #-} > > module Cryptol.Eval.Reference >   ( Value(..)@@ -32,6 +34,7 @@ > import LibBF (BigFloat) > import qualified LibBF as FP > import qualified GHC.Num.Compat as Integer+> import qualified Data.List as List > > import Cryptol.ModuleSystem.Name (asPrim) > import Cryptol.TypeCheck.Solver.InfNat (Nat'(..), nAdd, nMin, nMul)@@ -46,6 +49,8 @@ > import Cryptol.Utils.Panic (panic) > import Cryptol.Utils.PP > import Cryptol.Utils.RecordMap+> import Cryptol.Eval (checkProp)+> import Cryptol.Eval.Type (evalType, lookupTypeVar, tNumTy, tValTy) > > import qualified Cryptol.ModuleSystem as M > import qualified Cryptol.ModuleSystem.Env as M (loadedModules,loadedNewtypes)@@ -332,12 +337,28 @@ >     EProofAbs _ e  -> evalExpr env e >     EProofApp e    -> evalExpr env e >     EWhere e dgs   -> evalExpr (foldl evalDeclGroup env dgs) e-+>+>     EPropGuards guards _ty -> +>       case List.find (all (checkProp . evalProp env) . fst) guards of+>         Just (_, e) -> evalExpr env e+>         Nothing -> evalPanic "fromVBit" ["No guard constraint was satisfied"]  > appFun :: E Value -> E Value -> E Value > appFun f v = f >>= \f' -> fromVFun f' v +> -- | Evaluates a `Prop` in an `EvalEnv` by substituting all variables +> -- according to `envTypes` and expanding all type synonyms via `tNoUser`.+> evalProp :: Env -> Prop -> Prop+> evalProp env@Env { envTypes } = \case+>   TCon tc tys -> TCon tc (toType . evalType envTypes <$> tys)+>   TVar tv | Just (toType -> ty) <- lookupTypeVar tv envTypes -> ty+>   prop@TUser {} -> evalProp env (tNoUser prop)+>   TVar tv | Nothing <- lookupTypeVar tv envTypes -> panic "evalProp" ["Could not find type variable `" ++ pretty tv ++ "` in the type evaluation environment"]+>   prop -> panic "evalProp" ["Cannot use the following as a type constraint: `" ++ pretty prop ++ "`"]+>   where +>     toType = either tNumTy tValTy + Selectors --------- @@ -510,8 +531,9 @@ > evalDecl :: Env -> Decl -> (Name, E Value) > evalDecl env d = >   case dDefinition d of->     DPrim   -> (dName d, pure (evalPrim (dName d)))->     DExpr e -> (dName d, evalExpr env e)+>     DPrim      -> (dName d, pure (evalPrim (dName d)))+>     DForeign _ -> (dName d, cryError $ FFINotSupported $ dName d)+>     DExpr e    -> (dName d, evalExpr env e) >  Newtypes@@ -523,7 +545,7 @@ that consumes and ignores its type arguments.  > evalNewtypeDecl :: Env -> Newtype -> Env-> evalNewtypeDecl env nt = bindVar (ntName nt, pure val) env+> evalNewtypeDecl env nt = bindVar (ntConName nt, pure val) env >   where >     val = foldr tabs con (ntParams nt) >     con = VFun (\x -> x)
src/Cryptol/Eval/SBV.hs view
@@ -8,6 +8,7 @@  {-# LANGUAGE BlockArguments #-} {-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE LambdaCase #-}
src/Cryptol/Eval/Type.hs view
@@ -18,6 +18,7 @@ import Cryptol.Utils.Panic (panic) import Cryptol.Utils.Ident (Ident) import Cryptol.Utils.RecordMap+import Cryptol.Utils.Types  import Data.Maybe(fromMaybe) import qualified Data.IntMap.Strict as IntMap@@ -27,7 +28,7 @@ -- | An evaluated type of kind *. -- These types do not contain type variables, type synonyms, or type functions. data TValue-  = TVBit                     -- ^ @ Bit @+  = TVBit                     -- ^ @ Bit @     | TVInteger                 -- ^ @ Integer @   | TVFloat Integer Integer   -- ^ @ Float e p @   | TVIntMod Integer          -- ^ @ Z n @@@ -86,6 +87,10 @@ tvSeq (Nat n) t = TVSeq n t tvSeq Inf     t = TVStream t +-- | The Cryptol @Float64@ type.+tvFloat64 :: TValue+tvFloat64 = uncurry TVFloat float64ExpPrec+ -- | Coerce an extended natural into an integer, --   for values known to be finite finNat' :: Nat' -> Integer@@ -100,6 +105,7 @@ newtype TypeEnv =   TypeEnv   { envTypeMap  :: IntMap.IntMap (Either Nat' TValue) }+  deriving (Show)  instance Monoid TypeEnv where   mempty = TypeEnv mempty
src/Cryptol/Eval/What4.hs view
@@ -6,6 +6,7 @@  {-# LANGUAGE BlockArguments #-} {-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE MultiWayIf #-}@@ -505,7 +506,7 @@   TValue ->   SInteger (What4 sym) ->   SEval (What4 sym) (Value sym)-indexFront_int sym mblen _a xs ix idx+indexFront_int sym mblen _a xs _ix idx   | Just i <- W4.asInteger idx   = lookupSeqMap xs i @@ -535,16 +536,13 @@           _                        -> Nothing       ) -    -- Maximum possible in-bounds index given `Z m`-    -- type information and the length-    -- of the sequence. If the sequences is infinite and the-    -- integer is unbounded, there isn't much we can do.+    -- Maximum possible in-bounds index given the length+    -- of the sequence. If the sequence is infinite, there+    -- isn't much we can do.     maxIdx =-      case (mblen, ix) of-        (Nat n, TVIntMod m)  -> Just (min (toInteger n) (toInteger m))-        (Nat n, _)           -> Just n-        (_    , TVIntMod m)  -> Just m-        _                    -> Nothing+      case mblen of+        Nat n -> Just (n - 1)+        Inf   -> Nothing indexFront_segs ::   W4.IsSymExprBuilder sym =>   What4 sym ->
src/Cryptol/IR/FreeVars.hs view
@@ -93,6 +93,7 @@ instance FreeVars DeclDef where   freeVars d = case d of                  DPrim -> mempty+                 DForeign _ -> mempty                  DExpr e -> freeVars e  @@ -116,6 +117,7 @@       EProofAbs p e     -> freeVars p <> freeVars e       EProofApp e       -> freeVars e       EWhere e ds       -> foldFree ds <> rmVals (defs ds) (freeVars e)+      EPropGuards guards _ -> mconcat [ freeVars e | (_, e) <- guards ]     where       foldFree :: (FreeVars a, Defs a) => [a] -> Deps       foldFree = foldr updateFree mempty
+ src/Cryptol/IR/TraverseNames.hs view
@@ -0,0 +1,267 @@+{-# Language ImplicitParams #-}+module Cryptol.IR.TraverseNames where++import Data.Set(Set)+import qualified Data.Set as Set+import Data.Functor.Identity++import Cryptol.ModuleSystem.Name(nameUnique)+import Cryptol.Utils.RecordMap(traverseRecordMap)+import Cryptol.Parser.Position(Located(..))+import Cryptol.TypeCheck.AST+import Cryptol.TypeCheck.FFI.FFIType++traverseNames ::+  (TraverseNames t, Applicative f) => (Name -> f Name) -> (t -> f t)+traverseNames f = let ?name = f in traverseNamesIP++mapNames :: (TraverseNames t) => (Name -> Name) -> t -> t+mapNames f x = result+  where+  Identity result = let ?name = pure . f+                    in traverseNamesIP x++class TraverseNames t where+  traverseNamesIP :: (Applicative f, ?name :: Name -> f Name) => t -> f t++instance TraverseNames a => TraverseNames [a] where+  traverseNamesIP = traverse traverseNamesIP++instance TraverseNames a => TraverseNames (Maybe a) where+  traverseNamesIP = traverse traverseNamesIP++instance (Ord a, TraverseNames a) => TraverseNames (Set a) where+  traverseNamesIP = fmap Set.fromList . traverseNamesIP . Set.toList++instance TraverseNames a => TraverseNames (Located a) where+  traverseNamesIP (Located r a) = Located r <$> traverseNamesIP a++instance TraverseNames Name where+  traverseNamesIP = ?name++instance (Ord a, TraverseNames a) => TraverseNames (ExportSpec a) where+  traverseNamesIP (ExportSpec mp) = ExportSpec <$> traverse traverseNamesIP mp++instance TraverseNames Expr where+  traverseNamesIP expr =+    case expr of+      EList es t        -> EList  <$> traverseNamesIP es <*> traverseNamesIP t++      ETuple es         -> ETuple <$> traverseNamesIP es++      ERec mp           -> ERec <$> traverseRecordMap (\_ -> traverseNamesIP) mp++      ESel e l          -> (`ESel` l) <$> traverseNamesIP e++      ESet t e1 l e2    -> ESet <$> traverseNamesIP t+                                <*> traverseNamesIP e1+                                <*> pure l+                                <*> traverseNamesIP e2++      EIf e1 e2 e3      -> EIf <$> traverseNamesIP e1+                               <*> traverseNamesIP e2+                               <*> traverseNamesIP e3++      EComp t1 t2 e mss -> EComp <$> traverseNamesIP t1+                                 <*> traverseNamesIP t2+                                 <*> traverseNamesIP e+                                 <*> traverseNamesIP mss++      EVar x            -> EVar <$> traverseNamesIP x+      ETAbs tp e        -> ETAbs <$> traverseNamesIP tp <*> traverseNamesIP e+      ETApp e t         -> ETApp <$> traverseNamesIP e <*> traverseNamesIP t+      EApp e1 e2        -> EApp <$> traverseNamesIP e1 <*> traverseNamesIP e2+      EAbs x t e        -> EAbs <$> traverseNamesIP x+                                <*> traverseNamesIP t+                                <*> traverseNamesIP e+      ELocated r e      -> ELocated r <$> traverseNamesIP e+      EProofAbs p e     -> EProofAbs <$> traverseNamesIP p <*> traverseNamesIP e+      EProofApp e       -> EProofApp <$> traverseNamesIP e+      EWhere e ds       -> EWhere <$> traverseNamesIP e <*> traverseNamesIP ds++      EPropGuards gs t  -> EPropGuards <$> traverse doG gs <*> traverseNamesIP t+        where doG (xs, e) = (,) <$> traverseNamesIP xs <*> traverseNamesIP e++instance TraverseNames Match where+  traverseNamesIP mat =+    case mat of+      From x t1 t2 e -> From <$> traverseNamesIP x+                             <*> traverseNamesIP t1+                             <*> traverseNamesIP t2+                             <*> traverseNamesIP e+      Let d          -> Let <$> traverseNamesIP d++instance TraverseNames DeclGroup where+  traverseNamesIP dg =+    case dg of+      NonRecursive d -> NonRecursive <$> traverseNamesIP d+      Recursive ds   -> Recursive    <$> traverseNamesIP ds++instance TraverseNames Decl where+  traverseNamesIP decl = mk <$> traverseNamesIP (dName decl)+                            <*> traverseNamesIP (dSignature decl)+                            <*> traverseNamesIP (dDefinition decl)+    where mk nm sig def = decl { dName = nm+                               , dSignature = sig+                               , dDefinition = def+                               }++instance TraverseNames DeclDef where+  traverseNamesIP d =+    case d of+      DPrim   -> pure d+      DForeign t -> DForeign <$> traverseNamesIP t+      DExpr e -> DExpr <$> traverseNamesIP e++instance TraverseNames Schema where+  traverseNamesIP (Forall as ps t) =+    Forall <$> traverseNamesIP as+           <*> traverseNamesIP ps+           <*> traverseNamesIP t++instance TraverseNames TParam where+  traverseNamesIP tp = mk <$> traverseNamesIP (tpFlav tp)+                          <*> traverseNamesIP (tpInfo tp)+    -- XXX: module parameters should probably be represented directly+    -- as (abstract) user-defined types, rather than type variables.+    where mk f i = case f of+                     TPModParam x ->+                      tp { tpUnique = nameUnique x, tpFlav = f, tpInfo = i }+                     _ -> tp { tpFlav = f, tpInfo = i }+++instance TraverseNames TPFlavor where+  traverseNamesIP tpf =+    case tpf of+      TPModParam x      -> TPModParam     <$> traverseNamesIP x+      TPUnifyVar        -> pure tpf+      TPSchemaParam x   -> TPSchemaParam  <$> traverseNamesIP x+      TPTySynParam x    -> TPTySynParam   <$> traverseNamesIP x+      TPPropSynParam x  -> TPPropSynParam <$> traverseNamesIP x+      TPNewtypeParam x  -> TPNewtypeParam <$> traverseNamesIP x+      TPPrimParam x     -> TPPrimParam    <$> traverseNamesIP x++instance TraverseNames TVarInfo where+  traverseNamesIP (TVarInfo r s) = TVarInfo r <$> traverseNamesIP s++instance TraverseNames TypeSource where+  traverseNamesIP src =+    case src of+      TVFromModParam x            -> TVFromModParam <$> traverseNamesIP x+      TVFromSignature x           -> TVFromSignature <$> traverseNamesIP x+      TypeWildCard                -> pure src+      TypeOfRecordField {}        -> pure src+      TypeOfTupleField {}         -> pure src+      TypeOfSeqElement            -> pure src+      LenOfSeq                    -> pure src+      TypeParamInstNamed x i      -> TypeParamInstNamed <$> traverseNamesIP x+                                                        <*> pure i+      TypeParamInstPos   x i      -> TypeParamInstPos   <$> traverseNamesIP x+                                                        <*> pure i+      DefinitionOf x              -> DefinitionOf <$> traverseNamesIP x+      LenOfCompGen                -> pure src+      TypeOfArg arg               -> TypeOfArg <$> traverseNamesIP arg+      TypeOfRes                   -> pure src+      FunApp                      -> pure src+      TypeOfIfCondExpr            -> pure src+      TypeFromUserAnnotation      -> pure src+      GeneratorOfListComp         -> pure src+      TypeErrorPlaceHolder        -> pure src++instance TraverseNames ArgDescr where+  traverseNamesIP arg = mk <$> traverseNamesIP (argDescrFun arg)+    where mk n = arg { argDescrFun = n }++instance TraverseNames Type where+  traverseNamesIP ty =+    case ty of+      TCon tc ts    -> TCon <$> traverseNamesIP tc <*> traverseNamesIP ts+      TVar x        -> TVar <$> traverseNamesIP x+      TUser x ts t  -> TUser <$> traverseNamesIP x+                             <*> traverseNamesIP ts+                             <*> traverseNamesIP t+      TRec rm       -> TRec <$> traverseRecordMap (\_ -> traverseNamesIP) rm+      TNewtype nt ts -> TNewtype <$> traverseNamesIP nt <*> traverseNamesIP ts+++instance TraverseNames TCon where+  traverseNamesIP tcon =+    case tcon of+      TC tc -> TC <$> traverseNamesIP tc+      _     -> pure tcon++instance TraverseNames TC where+  traverseNamesIP tc =+    case tc of+      TCAbstract ut -> TCAbstract <$> traverseNamesIP ut+      _             -> pure tc++instance TraverseNames UserTC where+  traverseNamesIP (UserTC x k) = UserTC <$> traverseNamesIP x <*> pure k++instance TraverseNames TVar where+  traverseNamesIP tvar =+    case tvar of+      TVFree x k ys i -> TVFree x k <$> traverseNamesIP ys <*> traverseNamesIP i+      TVBound x       -> TVBound <$> traverseNamesIP x++instance TraverseNames Newtype where+  traverseNamesIP nt = mk <$> traverseNamesIP (ntName nt)+                          <*> traverseNamesIP (ntParams nt)+                          <*> traverseNamesIP (ntConstraints nt)+                          <*> traverseNamesIP (ntConName nt)+                          <*> traverseRecordMap (\_ -> traverseNamesIP)+                                                (ntFields nt)+    where+    mk a b c d e = nt { ntName = a+                      , ntParams = b+                      , ntConstraints = c+                      , ntConName = d+                      , ntFields = e+                      }++instance TraverseNames ModTParam where+  traverseNamesIP nt = mk <$> traverseNamesIP (mtpName nt)+    where+    mk x = nt { mtpName = x }++instance TraverseNames ModVParam where+  traverseNamesIP nt = mk <$> traverseNamesIP (mvpName nt)+                          <*> traverseNamesIP (mvpType nt)+    where+    mk x t = nt { mvpName = x, mvpType = t }++instance TraverseNames FFIFunType where+  traverseNamesIP fi = mk <$> traverseNamesIP (ffiArgTypes fi)+                          <*> traverseNamesIP (ffiRetType fi)+    where+    mk as b =+      FFIFunType+        { ffiTParams  = ffiTParams fi+        , ffiArgTypes = as+        , ffiRetType  = b+        }++instance TraverseNames FFIType where+  traverseNamesIP ft =+    case ft of+      FFIBool       -> pure ft+      FFIBasic _    -> pure ft   -- assumes no names here+      FFIArray sz t -> (`FFIArray` t) <$> traverseNamesIP sz+      FFITuple ts   -> FFITuple  <$> traverseNamesIP ts+      FFIRecord mp  -> FFIRecord <$> traverseRecordMap+                                                (\_ -> traverseNamesIP) mp+instance TraverseNames TySyn where+  traverseNamesIP ts = mk <$> traverseNamesIP (tsName ts)+                          <*> traverseNamesIP (tsParams ts)+                          <*> traverseNamesIP (tsConstraints ts)+                          <*> traverseNamesIP (tsDef ts)+    where mk n ps cs t =+            TySyn  { tsName        = n+                   , tsParams      = ps+                   , tsConstraints = cs+                   , tsDef         = t+                   , tsDoc         = tsDoc ts+                   }++
src/Cryptol/ModuleSystem.hs view
@@ -7,6 +7,7 @@ -- Portability :  portable  {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE BlockArguments #-}  module Cryptol.ModuleSystem (     -- * Module System@@ -18,8 +19,10 @@   , findModule   , loadModuleByPath   , loadModuleByName+  , checkModuleByPath   , checkExpr   , evalExpr+  , benchmarkExpr   , checkDecls   , evalDecls   , noPat@@ -29,8 +32,11 @@   , renameType      -- * Interfaces-  , Iface, IfaceG(..), IfaceParams(..), IfaceDecls(..), T.genIface-  , IfaceTySyn, IfaceDecl(..)+  , Iface, IfaceG(..), IfaceDecls(..), T.genIface, IfaceDecl(..)++    -- * Dependencies+  , getFileDependencies+  , getModuleDependencies   ) where  import Data.Map (Map)@@ -47,6 +53,7 @@ import           Cryptol.Parser.NoPat (RemovePatterns) import qualified Cryptol.TypeCheck.AST     as T import qualified Cryptol.TypeCheck.Interface as T+import           Cryptol.Utils.Benchmark (BenchmarkStats) import qualified Cryptol.Utils.Ident as M  -- Public Interface ------------------------------------------------------------@@ -63,23 +70,34 @@ findModule n env = runModuleM env (Base.findModule n)  -- | Load the module contained in the given file.-loadModuleByPath :: FilePath -> ModuleCmd (ModulePath,T.Module)-loadModuleByPath path minp =-  runModuleM minp{ minpModuleEnv = resetModuleEnv (minpModuleEnv minp) } $ do+loadModuleByPath :: FilePath -> ModuleCmd (ModulePath,T.TCTopEntity)+loadModuleByPath path minp = do+  moduleEnv' <- resetModuleEnv $ minpModuleEnv minp+  runModuleM minp{ minpModuleEnv = moduleEnv' } $ do     unloadModule ((InFile path ==) . lmFilePath)-    m <- Base.loadModuleByPath path-    setFocusedModule (T.mName m)+    m <- Base.loadModuleByPath True path+    setFocusedModule (T.tcTopEntitytName m)     return (InFile path,m)  -- | Load the given parsed module.-loadModuleByName :: P.ModName -> ModuleCmd (ModulePath,T.Module)-loadModuleByName n minp =-  runModuleM minp{ minpModuleEnv = resetModuleEnv (minpModuleEnv minp) } $ do+loadModuleByName :: P.ModName -> ModuleCmd (ModulePath,T.TCTopEntity)+loadModuleByName n minp = do+  moduleEnv' <- resetModuleEnv $ minpModuleEnv minp+  runModuleM minp{ minpModuleEnv = moduleEnv' } $ do     unloadModule ((n ==) . lmName)     (path,m') <- Base.loadModuleFrom False (FromModule n)-    setFocusedModule (T.mName m')+    setFocusedModule (T.tcTopEntitytName m')     return (path,m') +-- | Parse and typecheck a module, but don't evaluate or change the environment.+checkModuleByPath :: FilePath -> ModuleCmd (ModulePath, T.TCTopEntity)+checkModuleByPath path minp = do+  (res, warns) <- runModuleM minp $ Base.loadModuleByPath False path+  -- restore the old environment+  let res1 = do (x,_newEnv) <- res+                pure ((InFile path, x), minpModuleEnv minp)+  pure (res1, warns)+ -- Extended Environments -------------------------------------------------------  -- These functions are particularly useful for interactive modes, as@@ -95,6 +113,11 @@ evalExpr :: T.Expr -> ModuleCmd Concrete.Value evalExpr e env = runModuleM env (interactive (Base.evalExpr e)) +-- | Benchmark an expression.+benchmarkExpr :: Double -> T.Expr -> ModuleCmd BenchmarkStats+benchmarkExpr period e env =+  runModuleM env (interactive (Base.benchmarkExpr period e))+ -- | Typecheck top-level declarations. checkDecls :: [P.TopDecl PName] -> ModuleCmd (R.NamingEnv,[T.DeclGroup], Map Name T.TySyn) checkDecls ds env = runModuleM env@@ -119,3 +142,16 @@ renameType :: R.NamingEnv -> PName -> ModuleCmd Name renameType names n env = runModuleM env $ interactive $   Base.rename M.interactiveName names (R.renameType R.NameUse n)++--------------------------------------------------------------------------------+-- Dependencies+++-- | Get information about the dependencies of a file.+getFileDependencies :: FilePath -> ModuleCmd (ModulePath, FileInfo)+getFileDependencies f env = runModuleM env (Base.findDepsOf (InFile f))++-- | Get information about the dependencies of a module.+getModuleDependencies :: M.ModName -> ModuleCmd (ModulePath, FileInfo)+getModuleDependencies m env = runModuleM env (Base.findDepsOfModule m)+
src/Cryptol/ModuleSystem/Base.hs view
@@ -11,17 +11,22 @@  {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ImplicitParams #-}+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE BlockArguments #-}  module Cryptol.ModuleSystem.Base where  import qualified Control.Exception as X-import Control.Monad (unless,when)+import Control.Monad (unless,forM)+import Data.Set(Set)+import qualified Data.Set as Set import Data.Maybe (fromMaybe)-import Data.Monoid ((<>))+import Data.List(sortBy,groupBy)+import Data.Function(on)+import Data.Monoid ((<>),Endo(..), Any(..)) import Data.Text.Encoding (decodeUtf8')-import Data.IORef(newIORef,readIORef) import System.Directory (doesFileExist, canonicalizePath) import System.FilePath ( addExtension                        , isAbsolute@@ -39,39 +44,45 @@   -import Cryptol.ModuleSystem.Env (DynamicEnv(..)) import Cryptol.ModuleSystem.Fingerprint import Cryptol.ModuleSystem.Interface import Cryptol.ModuleSystem.Monad-import Cryptol.ModuleSystem.Name (Name,liftSupply,PrimMap,ModPath(..))-import Cryptol.ModuleSystem.Env (lookupModule-                                , LoadedModule(..)+import Cryptol.ModuleSystem.Name (Name,liftSupply,PrimMap,ModPath(..),nameIdent)+import Cryptol.ModuleSystem.Env ( DynamicEnv(..),FileInfo(..),fileInfo+                                , lookupModule+                                , lookupTCEntity+                                , LoadedModuleG(..), lmInterface                                 , meCoreLint, CoreLint(..)-                                , ModContext(..)+                                , ModContext(..), ModContextParams(..)                                 , ModulePath(..), modulePathLabel)+import           Cryptol.Backend.FFI import qualified Cryptol.Eval                 as E import qualified Cryptol.Eval.Concrete as Concrete import           Cryptol.Eval.Concrete (Concrete(..))+import           Cryptol.Eval.FFI import qualified Cryptol.ModuleSystem.NamingEnv as R import qualified Cryptol.ModuleSystem.Renamer as R import qualified Cryptol.Parser               as P import qualified Cryptol.Parser.Unlit         as P import Cryptol.Parser.AST as P import Cryptol.Parser.NoPat (RemovePatterns(removePatterns))+import qualified Cryptol.Parser.ExpandPropGuards as ExpandPropGuards +  ( expandPropGuards, runExpandPropGuardsM ) import Cryptol.Parser.NoInclude (removeIncludesModule) import Cryptol.Parser.Position (HasLoc(..), Range, emptyRange) import qualified Cryptol.TypeCheck     as T import qualified Cryptol.TypeCheck.AST as T import qualified Cryptol.TypeCheck.PP as T import qualified Cryptol.TypeCheck.Sanity as TcSanity+import qualified Cryptol.Backend.FFI.Error as FFI -import Cryptol.Transform.AddModParams (addModParams) import Cryptol.Utils.Ident ( preludeName, floatName, arrayName, suiteBName, primeECName                            , preludeReferenceName, interactiveName, modNameChunks-                           , notParamInstModName, isParamInstModName )+                           , modNameToNormalModName ) import Cryptol.Utils.PP (pretty) import Cryptol.Utils.Panic (panic) import Cryptol.Utils.Logger(logPutStrLn, logPrint)+import Cryptol.Utils.Benchmark  import Cryptol.Prelude ( preludeContents, floatContents, arrayContents                        , suiteBContents, primeECContents, preludeReferenceContents )@@ -114,11 +125,22 @@   unless (null errs) (noPatErrors errs)   return a' +-- ExpandPropGuards ------------------------------------------------------------ +-- | Run the expandPropGuards pass.+expandPropGuards :: Module PName -> ModuleM (Module PName)+expandPropGuards a =+  case ExpandPropGuards.runExpandPropGuardsM $ ExpandPropGuards.expandPropGuards a of+    Left err -> expandPropGuardsError err+    Right a' -> pure a'+ -- Parsing ---------------------------------------------------------------------  -- | Parse a module and expand includes-parseModule :: ModulePath -> ModuleM (Fingerprint, P.Module PName)+-- Returns a fingerprint of the module, and a set of dependencies due+-- to `include` directives.+parseModule ::+  ModulePath -> ModuleM (Fingerprint, Set FilePath, [P.Module PName]) parseModule path = do   getBytes <- getByteReader @@ -150,111 +172,167 @@               }    case P.parseModule cfg txt of-    Right pm ->+    Right pms ->       do let fp = fingerprint bytes-         pm1 <- case path of-                  InFile p ->-                    do r <- getByteReader-                       mb <- io (removeIncludesModule r p pm)+         (pm1,deps) <-+           case path of+             InFile p ->+               do r <- getByteReader+                  (mo,d) <- unzip <$>+                    forM pms \pm ->+                    do mb <- io (removeIncludesModule r p pm)                        case mb of                          Right ok -> pure ok                          Left err -> noIncludeErrors err+                  pure (mo, Set.unions d) -                  {- We don't do "include" resolution for in-memory files-                     because at the moment the include resolution pass requires-                     the path to the file to be known---this is used when-                     looking for other inlcude files.  This could be-                     generalized, but we can do it once we have a concrete use-                     case as it would help guide the design. -}-                  InMem {} -> pure pm+             {- We don't do "include" resolution for in-memory files+                because at the moment the include resolution pass requires+                the path to the file to be known---this is used when+                looking for other inlcude files.  This could be+                generalized, but we can do it once we have a concrete use+                case as it would help guide the design. -}+             InMem {} -> pure (pms, Set.empty) -         fp `seq` return (fp, pm1)+{-+         case path of+           InFile {} -> io $ print (T.vcat (map T.pp pm1))+           InMem {} -> pure ()+--}+         fp `seq` return (fp, deps, pm1)      Left err -> moduleParseError path err  --- Modules ---------------------------------------------------------------------+-- Top Level Modules and Signatures -------------------------------------------- + -- | Load a module by its path.-loadModuleByPath :: FilePath -> ModuleM T.Module-loadModuleByPath path = withPrependedSearchPath [ takeDirectory path ] $ do+loadModuleByPath ::+  Bool {- ^ evaluate declarations in the module -} ->+  FilePath -> ModuleM T.TCTopEntity+loadModuleByPath eval path = withPrependedSearchPath [ takeDirectory path ] $ do   let fileName = takeFileName path   foundPath <- findFile fileName-  (fp, pm) <- parseModule (InFile foundPath)-  let n = thing (P.mName pm)+  (fp, deps, pms) <- parseModule (InFile foundPath)+  last <$>+    forM pms \pm ->+    do let n = thing (P.mName pm) -  -- Check whether this module name has already been loaded from a different file-  env <- getModuleEnv-  -- path' is the resolved, absolute path, used only for checking-  -- whether it's already been loaded-  path' <- io (canonicalizePath foundPath)+       -- Check whether this module name has already been loaded from a+       -- different file+       env <- getModuleEnv+       -- path' is the resolved, absolute path, used only for checking+       -- whether it's already been loaded+       path' <- io (canonicalizePath foundPath) -  case lookupModule n env of-    -- loadModule will calculate the canonical path again-    Nothing -> doLoadModule False (FromModule n) (InFile foundPath) fp pm-    Just lm-     | path' == loaded -> return (lmModule lm)-     | otherwise       -> duplicateModuleName n path' loaded-     where loaded = lmModuleId lm+       case lookupTCEntity n env of+         -- loadModule will calculate the canonical path again+         Nothing ->+           doLoadModule eval False (FromModule n) (InFile foundPath) fp deps pm+         Just lm+          | path' == loaded -> return (lmData lm)+          | otherwise       -> duplicateModuleName n path' loaded+          where loaded = lmModuleId lm   -- | Load a module, unless it was previously loaded.-loadModuleFrom :: Bool {- ^ quiet mode -} -> ImportSource -> ModuleM (ModulePath,T.Module)+loadModuleFrom ::+  Bool {- ^ quiet mode -} -> ImportSource -> ModuleM (ModulePath,T.TCTopEntity) loadModuleFrom quiet isrc =   do let n = importedModule isrc      mb <- getLoadedMaybe n      case mb of-       Just m -> return (lmFilePath m, lmModule m)+       Just m -> return (lmFilePath m, lmData m)        Nothing ->          do path <- findModule n             errorInFile path $-              do (fp, pm) <- parseModule path-                 m        <- doLoadModule quiet isrc path fp pm-                 return (path,m)+              do (fp, deps, pms) <- parseModule path+                 ms <- mapM (doLoadModule True quiet isrc path fp deps) pms+                 return (path,last ms)  -- | Load dependencies, typecheck, and add to the eval environment. doLoadModule ::+  Bool {- ^ evaluate declarations in the module -} ->   Bool {- ^ quiet mode: true suppresses the "loading module" message -} ->   ImportSource ->   ModulePath ->   Fingerprint ->+  Set FilePath {- ^ `include` dependencies -} ->   P.Module PName ->-  ModuleM T.Module-doLoadModule quiet isrc path fp pm0 =+  ModuleM T.TCTopEntity+doLoadModule eval quiet isrc path fp incDeps pm0 =   loading isrc $   do let pm = addPrelude pm0-     loadDeps pm+     impDeps <- loadDeps pm +     let what = case P.mDef pm of+                  P.InterfaceModule {} -> "interface module"+                  _                    -> "module"+      unless quiet $ withLogger logPutStrLn-       ("Loading module " ++ pretty (P.thing (P.mName pm)))+       ("Loading " ++ what ++ " " ++ pretty (P.thing (P.mName pm)))  -     (nameEnv,tcmod) <- checkModule isrc pm-     tcm <- optionalInstantiate tcmod+     (nameEnv,tcm) <- checkModule isrc pm       -- extend the eval env, unless a functor.      tbl <- Concrete.primTable <$> getEvalOptsAction      let ?evalPrim = \i -> Right <$> Map.lookup i tbl      callStacks <- getCallStacks      let ?callStacks = callStacks-     unless (T.isParametrizedModule tcm) $ modifyEvalEnv (E.moduleEnv Concrete tcm)-     loadedModule path fp nameEnv tcm+     let shouldEval =+           case tcm of+             T.TCTopModule m | eval && not (T.isParametrizedModule m) -> Just m+             _ -> Nothing +     foreignSrc <- case shouldEval of+                      Just m ->+                        do fsrc <- evalForeign m+                           modifyEvalEnv (E.moduleEnv Concrete m)+                           pure fsrc+                      Nothing -> pure Nothing++     let fi = fileInfo fp incDeps impDeps foreignSrc+     loadedModule path fi nameEnv foreignSrc tcm+      return tcm+   where-  optionalInstantiate tcm-    | isParamInstModName (importedModule isrc) =-      if T.isParametrizedModule tcm then-        case addModParams tcm of-          Right tcm1 -> return tcm1-          Left xs    -> failedToParameterizeModDefs (T.mName tcm) xs-      else notAParameterizedModule (T.mName tcm)-    | otherwise = return tcm+  evalForeign tcm+    | not (null foreignFs) =+      ffiLoadErrors (T.mName tcm) (map FFI.FFIInFunctor foreignFs)+    | not (null dups) =+      ffiLoadErrors (T.mName tcm) (map FFI.FFIDuplicates dups)+    | null foreigns = pure Nothing+    | otherwise =+      case path of+        InFile p -> io (canonicalizePath p >>= loadForeignSrc) >>=+          \case +            Right fsrc -> do+              unless quiet $+                case getForeignSrcPath fsrc of+                  Just fpath -> withLogger logPutStrLn $+                    "Loading dynamic library " ++ takeFileName fpath+                  Nothing -> pure ()+              modifyEvalEnvM (evalForeignDecls fsrc foreigns) >>=+                \case+                  Right () -> pure $ Just fsrc+                  Left errs -> ffiLoadErrors (T.mName tcm) errs +            Left err -> ffiLoadErrors (T.mName tcm) [err] +        InMem m _ -> panic "doLoadModule"+          ["Can't find foreign source of in-memory module", m] +    where foreigns  = findForeignDecls tcm+          foreignFs = T.findForeignDeclsInFunctors tcm+          dups      = [ d | d@(_ : _ : _) <- groupBy ((==) `on` nameIdent)+                                           $ sortBy (compare `on` nameIdent)+                                           $ map fst foreigns ] + -- | Rewrite an import declaration to be of the form: -- -- > import foo as foo [ [hiding] (a,b,c) ]@@ -298,51 +376,149 @@ -- | Discover a file. This is distinct from 'findModule' in that we -- assume we've already been given a particular file name. findFile :: FilePath -> ModuleM FilePath-findFile path | isAbsolute path = do-  -- No search path checking for absolute paths-  b <- io (doesFileExist path)-  if b then return path else cantFindFile path-findFile path = do-  paths <- getSearchPath-  loop (possibleFiles paths)-  where-  loop paths = case paths of-    path':rest -> do-      b <- io (doesFileExist path')-      if b then return (normalise path') else loop rest-    [] -> cantFindFile path-  possibleFiles paths = map (</> path) paths+findFile path+  | isAbsolute path =+    do -- No search path checking for absolute paths+       b <- io (doesFileExist path)+       if b then return path else cantFindFile path+  | otherwise =+    do paths <- getSearchPath+       loop (possibleFiles paths)+       where+       loop paths = case paths of+                      path' : rest ->+                        do b <- io (doesFileExist path')+                           if b then return (normalise path') else loop rest+                      [] -> cantFindFile path+       possibleFiles paths = map (</> path) paths  -- | Add the prelude to the import list if it's not already mentioned. addPrelude :: P.Module PName -> P.Module PName addPrelude m   | preludeName == P.thing (P.mName m) = m   | preludeName `elem` importedMods    = m-  | otherwise                          = m { mDecls = importPrelude : mDecls m }+  | otherwise                          = m { mDef = newDef }   where+  newDef =+    case mDef m of+      NormalModule ds -> NormalModule (P.DImport prel : ds)+      FunctorInstance f as ins -> FunctorInstance f as ins+      InterfaceModule s -> InterfaceModule s { sigImports = prel+                                             : sigImports s }+   importedMods  = map (P.iModule . P.thing) (P.mImports m)-  importPrelude = P.DImport P.Located+  prel = P.Located     { P.srcRange = emptyRange     , P.thing    = P.Import-      { iModule    = P.ImpTop preludeName-      , iAs        = Nothing-      , iSpec      = Nothing+      { iModule  = P.ImpTop preludeName+      , iAs      = Nothing+      , iSpec    = Nothing+      , iInst    = Nothing       }     }  -- | Load the dependencies of a module into the environment.-loadDeps :: P.Module name -> ModuleM ()+loadDeps :: P.ModuleG mname name -> ModuleM (Set ModName) loadDeps m =-  do mapM_ loadI (P.mImports m)-     mapM_ loadF (P.mInstance m)+  do let ds = findDeps m+     mapM_ (loadModuleFrom False) ds+     pure (Set.fromList (map importedModule ds))++-- | Find all imports in a module.+findDeps :: P.ModuleG mname name -> [ImportSource]+findDeps m = appEndo (snd (findDeps' m)) []++findDepsOfModule :: ModName -> ModuleM (ModulePath, FileInfo)+findDepsOfModule m =+  do mpath <- findModule m+     findDepsOf mpath++findDepsOf :: ModulePath -> ModuleM (ModulePath, FileInfo)+findDepsOf mpath' =+  do mpath <- case mpath' of+                InFile file -> InFile <$> io (canonicalizePath file)+                InMem {}    -> pure mpath'+     (fp, incs, ms) <- parseModule mpath+     let (anyF,imps) = mconcat (map (findDeps' . addPrelude) ms)+     fpath <- if getAny anyF+                then do mb <- io case mpath of+                                   InFile can -> foreignLibPath can+                                   InMem {}   -> pure Nothing+                        pure case mb of+                               Nothing -> Set.empty+                               Just f  -> Set.singleton f+                else pure Set.empty+     pure+       ( mpath+       , FileInfo+           { fiFingerprint = fp+           , fiIncludeDeps = incs+           , fiImportDeps  = Set.fromList (map importedModule (appEndo imps []))+           , fiForeignDeps = fpath+           }+       )++-- | Find the set of top-level modules imported by a module.+findModuleDeps :: P.ModuleG mname name -> Set P.ModName+findModuleDeps = Set.fromList . map importedModule . findDeps++-- | A helper `findDeps` and `findModuleDeps` that actually does the searching.+findDeps' :: P.ModuleG mname name -> (Any, Endo [ImportSource])+findDeps' m =+  case mDef m of+    NormalModule ds -> mconcat (map depsOfDecl ds)+    FunctorInstance f as _ ->+      let fds = loadImpName FromModuleInstance f+          ads = case as of+                  DefaultInstArg a -> loadInstArg a+                  DefaultInstAnonArg ds -> mconcat (map depsOfDecl ds)+                  NamedInstArgs args -> mconcat (map loadNamedInstArg args)+      in fds <> ads+    InterfaceModule s -> mconcat (map loadImpD (sigImports s))   where-  loadI i = do (_,m1)  <- loadModuleFrom False (FromImport i)-               when (T.isParametrizedModule m1) $ importParamModule $ T.mName m1-  loadF f = do _ <- loadModuleFrom False (FromModuleInstance f)-               return ()+  loadI i = (mempty, Endo (i:)) +  loadImpName src l =+    case thing l of+      ImpTop f -> loadI (src l { thing = f })+      _        -> mempty +  loadImpD li = loadImpName (FromImport . new) (iModule <$> li)+    where new i = i { thing = (thing li) { iModule = thing i } } +  loadNamedInstArg (ModuleInstanceNamedArg _ f) = loadInstArg f+  loadInstArg f =+    case thing f of+      ModuleArg mo -> loadImpName FromModuleInstance f { thing = mo }+      _            -> mempty++  depsOfDecl d =+    case d of+      DImport li -> loadImpD li++      DModule TopLevel { tlValue = NestedModule nm } -> findDeps' nm++      DModParam mo -> loadImpName FromSigImport s+        where s = mpSignature mo++      Decl dd -> depsOfDecl' (tlValue dd)++      _ -> mempty++  depsOfDecl' d =+    case d of+      DLocated d' _ -> depsOfDecl' d'+      DBind b ->+        case thing (bDef b) of+          DForeign {} -> (Any True, mempty)+          _ -> mempty+      _ -> mempty++++++ -- Type Checking ---------------------------------------------------------------  -- | Typecheck a single expression, yielding a renamed parsed expression,@@ -405,46 +581,38 @@        Nothing -> panic "Cryptol.ModuleSystem.Base.getPrimMap"                   [ "Unable to find the prelude" ] --- | Load a module, be it a normal module or a functor instantiation.-checkModule :: ImportSource -> P.Module PName -> ModuleM (R.NamingEnv, T.Module)-checkModule isrc m =-  case P.mInstance m of-    Nothing -> checkSingleModule T.tcModule isrc m-    Just fmName ->-      do mbtf <- getLoadedMaybe (thing fmName)-         case mbtf of-           Just tf ->-             do renThis <- io $ newIORef (lmNamingEnv tf)-                let how = T.tcModuleInst renThis (lmModule tf)-                (_,m') <- checkSingleModule how isrc m-                newEnv <- io $ readIORef renThis-                pure (newEnv,m')-           Nothing -> panic "checkModule"-                        [ "Functor of module instantiation not loaded" ]----- | Typecheck a single module.  If the module is an instantiation--- of a functor, then this just type-checks the instantiating parameters.--- See 'checkModule'+-- | Typecheck a single module. -- Note: we assume that @include@s have already been processed-checkSingleModule ::-  Act (P.Module Name) T.Module {- ^ how to check -} ->-  ImportSource                 {- ^ why are we loading this -} ->-  P.Module PName               {- ^ module to check -} ->-  ModuleM (R.NamingEnv,T.Module)-checkSingleModule how isrc m = do+checkModule ::+  ImportSource                      {- ^ why are we loading this -} ->+  P.Module PName                    {- ^ module to check -} ->+  ModuleM (R.NamingEnv,T.TCTopEntity)+checkModule isrc m = do    -- check that the name of the module matches expectations   let nm = importedModule isrc-  unless (notParamInstModName nm == thing (P.mName m))+  unless (modNameToNormalModName nm ==+                                  modNameToNormalModName (thing (P.mName m)))          (moduleNameMismatch nm (mName m))    -- remove pattern bindings   npm <- noPat m +  -- run expandPropGuards+  epgm <- expandPropGuards npm+   -- rename everything-  renMod <- renameModule npm+  renMod <- renameModule epgm ++{-+  -- dump renamed+  unless (thing (mName (R.rmModule renMod)) == preludeName)+       do (io $ print (T.pp renMod))+          -- io $ exitSuccess+--}++   -- when generating the prim map for the typechecker, if we're checking the   -- prelude, we have to generate the map from the renaming environment, as we   -- don't have the interface yet.@@ -453,21 +621,22 @@               else getPrimMap    -- typecheck-  let act = TCAction { tcAction = how-                     , tcLinter = moduleLinter (P.thing (P.mName m))+  let act = TCAction { tcAction = T.tcModule+                     , tcLinter = tcTopEntitytLinter (P.thing (P.mName m))                      , tcPrims  = prims }  -  tcm0 <- typecheck act (R.rmModule renMod) noIfaceParams (R.rmImported renMod)--  let tcm = tcm0 -- fromMaybe tcm0 (addModParams tcm0)+  tcm <- typecheck act (R.rmModule renMod) NoParams (R.rmImported renMod) -  rewMod <- liftSupply (`rewModule` tcm)+  rewMod <- case tcm of+              T.TCTopModule mo -> T.TCTopModule <$> liftSupply (`rewModule` mo)+              T.TCTopSignature {} -> pure tcm   pure (R.rmInScope renMod,rewMod)  data TCLinter o = TCLinter   { lintCheck ::-      o -> T.InferInput -> Either (Range, TcSanity.Error) [TcSanity.ProofObligation]+      o -> T.InferInput ->+                    Either (Range, TcSanity.Error) [TcSanity.ProofObligation]   , lintModule :: Maybe P.ModName   } @@ -478,7 +647,8 @@       case TcSanity.tcExpr i e' of         Left err     -> Left err         Right (s1,os)-          | TcSanity.same s s1  -> Right os+          | TcSanity.SameIf os' <- TcSanity.same s s1 ->+                                        Right (map T.tMono os' ++ os)           | otherwise -> Left ( fromMaybe emptyRange (getLoc e')                               , TcSanity.TypeMismatch "exprLinter" s s1                               )@@ -502,6 +672,17 @@   , lintModule  = Just m   } +tcTopEntitytLinter :: P.ModName -> TCLinter T.TCTopEntity+tcTopEntitytLinter m = TCLinter+  { lintCheck   = \m' i -> case m' of+                             T.TCTopModule mo ->+                               lintCheck (moduleLinter m) mo i+                             T.TCTopSignature {} -> Right []+                                -- XXX: what can we lint about module interfaces+  , lintModule  = Just m+  }++ type Act i o = i -> T.InferInput -> IO (T.InferOutput o)  data TCAction i o = TCAction@@ -511,8 +692,8 @@   }  typecheck ::-  (Show i, Show o, HasLoc i) => TCAction i o -> i ->-                                  IfaceParams -> IfaceDecls -> ModuleM o+  (Show i, Show o, HasLoc i) =>+  TCAction i o -> i -> ModContextParams -> IfaceDecls -> ModuleM o typecheck act i params env = do    let range = fromMaybe emptyRange (getLoc i)@@ -531,8 +712,12 @@            CoreLint   -> case lintCheck (tcLinter act) o input of                            Right as ->                              let ppIt l = mapM_ (logPrint l . T.pp)-                             in withLogger ppIt as-                           Left err -> panic "Core lint failed:" [show err]+                             in withLogger ppIt (TcSanity.onlyNonTrivial as)+                           Left (loc,err) ->+                            panic "Core lint failed:"+                              [ "Location: " ++ show (T.pp loc)+                              , show (T.pp err)+                              ]          return o      T.InferFailed nameMap warns errs ->@@ -540,8 +725,9 @@          typeCheckingFailed nameMap errs  -- | Generate input for the typechecker.-genInferInput :: Range -> PrimMap -> IfaceParams -> IfaceDecls -> ModuleM T.InferInput-genInferInput r prims params env' = do+genInferInput :: Range -> PrimMap -> ModContextParams -> IfaceDecls ->+                                                          ModuleM T.InferInput+genInferInput r prims params env = do   seeds <- getNameSeeds   monoBinds <- getMonoBinds   solver <- getTCSolver@@ -549,25 +735,29 @@   searchPath <- getSearchPath   callStacks <- getCallStacks -  -- TODO: include the environment needed by the module-  let env = flatPublicDecls env'-            -- XXX: we should really just pass this directly+  topMods <- getAllLoaded+  topSigs <- getAllLoadedSignatures+   return T.InferInput-    { T.inpRange     = r-    , T.inpVars      = Map.map ifDeclSig (ifDecls env)-    , T.inpTSyns     = ifTySyns env-    , T.inpNewtypes  = ifNewtypes env-    , T.inpAbstractTypes = ifAbstractTypes env-    , T.inpNameSeeds = seeds-    , T.inpMonoBinds = monoBinds-    , T.inpCallStacks = callStacks-    , T.inpSearchPath = searchPath-    , T.inpSupply    = supply-    , T.inpPrimNames = prims-    , T.inpParamTypes       = ifParamTypes params-    , T.inpParamConstraints = ifParamConstraints params-    , T.inpParamFuns        = ifParamFuns params+    { T.inpRange            = r+    , T.inpVars             = Map.map ifDeclSig (ifDecls env)+    , T.inpTSyns            = ifTySyns env+    , T.inpNewtypes         = ifNewtypes env+    , T.inpAbstractTypes    = ifAbstractTypes env+    , T.inpSignatures       = ifSignatures env+    , T.inpNameSeeds        = seeds+    , T.inpMonoBinds        = monoBinds+    , T.inpCallStacks       = callStacks+    , T.inpSearchPath       = searchPath+    , T.inpSupply           = supply+    , T.inpParams           = case params of+                                NoParams -> T.allParamNames mempty+                                FunctorParams ps -> T.allParamNames ps+                                InterfaceParams ps -> ps+    , T.inpPrimNames        = prims     , T.inpSolver           = solver+    , T.inpTopModules       = topMods+    , T.inpTopSignatures    = topSigs     }  @@ -585,6 +775,22 @@   let ?callStacks = callStacks    io $ E.runEval mempty (E.evalExpr Concrete (env <> deEnv denv) e)++benchmarkExpr :: Double -> T.Expr -> ModuleM BenchmarkStats+benchmarkExpr period e = do+  env <- getEvalEnv+  denv <- getDynEnv+  evopts <- getEvalOptsAction+  let env' = env <> deEnv denv+  let tbl = Concrete.primTable evopts+  let ?evalPrim = \i -> Right <$> Map.lookup i tbl+  let ?range = emptyRange+  callStacks <- getCallStacks+  let ?callStacks = callStacks++  let eval expr = E.runEval mempty $+        E.evalExpr Concrete env' expr >>= E.forceValue+  io $ benchmark period eval e  evalDecls :: [T.DeclGroup] -> ModuleM () evalDecls dgs = do
+ src/Cryptol/ModuleSystem/Binds.hs view
@@ -0,0 +1,434 @@+{-# Language BlockArguments #-}+{-# Language RecordWildCards #-}+{-# Language FlexibleInstances #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveTraversable #-}+module Cryptol.ModuleSystem.Binds+  ( BindsNames+  , TopDef(..)+  , Mod(..)+  , ModKind(..)+  , modNested+  , modBuilder+  , topModuleDefs+  , topDeclsDefs+  , newModParam+  , InModule(..)+  , ifaceToMod+  , ifaceSigToMod+  , modToMap+  , defsOf+  ) where++import Data.Map(Map)+import qualified Data.Map as Map+import Data.Set(Set)+import qualified Data.Set as Set+import Data.Maybe(fromMaybe)+import Control.Monad(foldM)+import qualified MonadLib as M++import Cryptol.Utils.Panic (panic)+import Cryptol.Utils.Ident(allNamespaces)+import Cryptol.Parser.Position+import Cryptol.Parser.Name(isGeneratedName)+import Cryptol.Parser.AST+import Cryptol.ModuleSystem.Exports(exportedDecls,exported)+import Cryptol.ModuleSystem.Renamer.Error+import Cryptol.ModuleSystem.Name+import Cryptol.ModuleSystem.Names+import Cryptol.ModuleSystem.NamingEnv+import Cryptol.ModuleSystem.Interface+import Cryptol.TypeCheck.Type(ModParamNames(..))++++data TopDef = TopMod ModName (Mod ())+            | TopInst ModName (ImpName PName) (ModuleInstanceArgs PName)++-- | Things defined by a module+data Mod a = Mod+  { modImports   :: [ ImportG (ImpName PName) ]+  , modKind      :: ModKind+  , modInstances :: Map Name (ImpName PName, ModuleInstanceArgs PName)+  , modMods      :: Map Name (Mod a) -- ^ this includes signatures++  , modDefines   :: NamingEnv+    {- ^ Things defined by this module.  Note the for normal modules we+    really just need the public names, however for things within+    functors we need all defined names, so that we can generate fresh+    names in instantiations -}++  , modPublic    :: !(Set Name)+    -- ^ These are the exported names++  , modState     :: a+    {- ^ Used in the import loop to track the current state of processing.+         The reason this is here, rather than just having a pair in the+         other algorithm is because this type is recursive (for nested modules)+         and it is conveninet to keep track for all modules at once -}+  }++modNested :: Mod a -> Set Name+modNested m = Set.unions [ Map.keysSet (modInstances m)+                         , Map.keysSet (modMods m)+                         ]++instance Functor Mod where+  fmap f m = m { modState = f (modState m)+               , modMods  = fmap f <$> modMods m+               }++-- | Generate a map from this module and all modules nested in it.+modToMap ::+  ImpName Name -> Mod () ->+  Map (ImpName Name) (Mod ()) -> Map (ImpName Name) (Mod ())+modToMap x m mp = Map.insert x m (Map.foldrWithKey add mp (modMods m))+  where+  add n = modToMap (ImpNested n)++-- | Make a `Mod` from the public declarations in an interface.+-- This is used to handle imports.+ifaceToMod :: IfaceG name -> Mod ()+ifaceToMod iface = ifaceNamesToMod iface (ifaceIsFunctor iface) (ifNames iface)++ifaceNamesToMod :: IfaceG topname -> Bool -> IfaceNames name -> Mod ()+ifaceNamesToMod iface params names =+  Mod+    { modKind    = if params then AFunctor else AModule+    , modMods    = (ifaceNamesToMod iface False <$> ifModules decls)+                   `Map.union`+                   (ifaceToMod <$> ifFunctors decls)+                   `Map.union`+                   (ifaceSigToMod <$> ifSignatures decls)+    , modDefines = namingEnvFromNames defs+    , modPublic  = ifsPublic names++    , modImports   = []+    , modInstances = mempty+    , modState     = ()+    }+  where+  defs      = ifsDefines names+  isLocal x = x `Set.member` defs+  decls     = filterIfaceDecls isLocal (ifDefines iface)+++ifaceSigToMod :: ModParamNames -> Mod ()+ifaceSigToMod ps = Mod+  { modImports   = []+  , modKind      = ASignature+  , modInstances = mempty+  , modMods      = mempty+  , modDefines   = env+  , modPublic    = namingEnvNames env+  , modState     = ()+  }+  where+  env = modParamsNamingEnv ps+++++++type ModBuilder = SupplyT (M.StateT [RenamerError] M.Id)++modBuilder :: ModBuilder a -> Supply -> ((a, [RenamerError]),Supply)+modBuilder m s = ((a,errs),s1)+  where ((a,s1),errs) = M.runId (M.runStateT [] (runSupplyT s m))++defErr :: RenamerError -> ModBuilder ()+defErr a = M.lift (M.sets_ (a:))++defNames :: BuildNamingEnv -> ModBuilder NamingEnv+defNames b = liftSupply \s -> M.runId (runSupplyT s (runBuild b))+++topModuleDefs :: Module PName -> ModBuilder TopDef+topModuleDefs m =+  case mDef m of+    NormalModule ds -> TopMod mname <$> declsToMod (Just (TopModule mname)) ds+    FunctorInstance f as _ -> pure (TopInst mname (thing f) as)+    InterfaceModule s -> TopMod mname <$> sigToMod (TopModule mname) s+  where+  mname = thing (mName m)++topDeclsDefs :: ModPath -> [TopDecl PName] -> ModBuilder (Mod ())+topDeclsDefs = declsToMod . Just++sigToMod :: ModPath -> Signature PName -> ModBuilder (Mod ())+sigToMod mp sig =+  do env <- defNames (signatureDefs mp sig)+     pure Mod { modImports   = map thing (sigImports sig)+              , modKind      = ASignature+              , modInstances = mempty+              , modMods      = mempty+              , modDefines   = env+              , modPublic    = namingEnvNames env+              , modState     = ()+              }++++declsToMod :: Maybe ModPath -> [TopDecl PName] -> ModBuilder (Mod ())+declsToMod mbPath ds =+  do defs <- defNames (foldMap (namingEnv . InModule mbPath) ds)+     let expSpec = exportedDecls ds+     let pub     = Set.fromList+                     [ name+                     | ns    <- allNamespaces+                     , pname <- Set.toList (exported ns expSpec)+                     , name  <- lookupListNS ns pname defs+                     ]++     case findAmbig defs of+       bad@(_ : _) : _ ->+         -- defErr (MultipleDefinitions mbPath (nameIdent f) (map nameLoc bad))+         defErr (OverlappingSyms bad)+       _ -> pure ()++     let mo = Mod { modImports      = [ thing i | DImport i <- ds ]+                  , modKind         = if any isParamDecl ds+                                         then AFunctor else AModule+                  , modInstances    = mempty+                  , modMods         = mempty+                  , modDefines      = defs+                  , modPublic       = pub+                  , modState        = ()+                  }++     foldM (checkNest defs) mo ds++  where+  checkNest defs mo d =+    case d of+      DModule tl ->+        do let NestedModule nmod = tlValue tl+               pname = thing (mName nmod)+               name  = case lookupNS NSModule pname defs of+                         Just xs -> anyOne xs+                         _ -> panic "declsToMod" ["undefined name", show pname]+           case mbPath of+             Nothing ->+               do defErr (UnexpectedNest (srcRange (mName nmod)) pname)+                  pure mo+             Just path ->+                case mDef nmod of++                   NormalModule xs ->+                     do m <- declsToMod (Just (Nested path (nameIdent name))) xs+                        pure mo { modMods = Map.insert name m (modMods mo) }++                   FunctorInstance f args _ ->+                      pure mo { modInstances = Map.insert name (thing f, args)+                                                    (modInstances mo) }++                   InterfaceModule sig ->+                      do m <- sigToMod (Nested path (nameIdent name)) sig+                         pure mo { modMods = Map.insert name m (modMods mo) }+++      _ -> pure mo++++-- | These are the names "owned" by the signature.  These names are+-- used when resolving the signature.  They are also used to figure out what+-- names to instantuate when the signature is used.+signatureDefs :: ModPath -> Signature PName -> BuildNamingEnv+signatureDefs m sig =+     mconcat [ namingEnv (InModule loc p) | p <- sigTypeParams sig ]+  <> mconcat [ namingEnv (InModule loc p) | p <- sigFunParams sig ]+  <> mconcat [ namingEnv (InModule loc p) | p <- sigDecls sig ]+  where+  loc = Just m+--------------------------------------------------------------------------------+++++--------------------------------------------------------------------------------+-- Computes the names introduced by various declarations.++-- | Things that define exported names.+class BindsNames a where+  namingEnv :: a -> BuildNamingEnv++newtype BuildNamingEnv = BuildNamingEnv { runBuild :: SupplyT M.Id NamingEnv }++buildNamingEnv :: BuildNamingEnv -> Supply -> (NamingEnv,Supply)+buildNamingEnv b supply = M.runId $ runSupplyT supply $ runBuild b++-- | Generate a 'NamingEnv' using an explicit supply.+defsOf :: BindsNames a => a -> Supply -> (NamingEnv,Supply)+defsOf = buildNamingEnv . namingEnv++instance Semigroup BuildNamingEnv where+  BuildNamingEnv a <> BuildNamingEnv b = BuildNamingEnv $+    do x <- a+       y <- b+       return (mappend x y)++instance Monoid BuildNamingEnv where+  mempty = BuildNamingEnv (pure mempty)++  mappend = (<>)++  mconcat bs = BuildNamingEnv $+    do ns <- sequence (map runBuild bs)+       return (mconcat ns)++instance BindsNames NamingEnv where+  namingEnv env = BuildNamingEnv (return env)+  {-# INLINE namingEnv #-}++instance BindsNames a => BindsNames (Maybe a) where+  namingEnv = foldMap namingEnv+  {-# INLINE namingEnv #-}++instance BindsNames a => BindsNames [a] where+  namingEnv = foldMap namingEnv+  {-# INLINE namingEnv #-}++-- | Generate a type renaming environment from the parameters that are bound by+-- this schema.+instance BindsNames (Schema PName) where+  namingEnv (Forall ps _ _ _) = foldMap namingEnv ps+  {-# INLINE namingEnv #-}++++-- | Introduce the name+instance BindsNames (InModule (Bind PName)) where+  namingEnv (InModule mb b) = BuildNamingEnv $+    do let Located { .. } = bName b+       n <- case mb of+              Just m  -> newTop NSValue m thing (bFixity b) srcRange+              Nothing -> newLocal NSValue thing srcRange -- local fixitiies?++       return (singletonNS NSValue thing n)++-- | Generate the naming environment for a type parameter.+instance BindsNames (TParam PName) where+  namingEnv TParam { .. } = BuildNamingEnv $+    do let range = fromMaybe emptyRange tpRange+       n <- newLocal NSType tpName range+       return (singletonNS NSType tpName n)+++instance BindsNames (InModule (TopDecl PName)) where+  namingEnv (InModule ns td) =+    case td of+      Decl d           -> namingEnv (InModule ns (tlValue d))+      DPrimType d      -> namingEnv (InModule ns (tlValue d))+      TDNewtype d      -> namingEnv (InModule ns (tlValue d))+      DParamDecl {}    -> mempty+      Include _        -> mempty+      DImport {}       -> mempty -- see 'openLoop' in the renamer+      DModule m        -> namingEnv (InModule ns (tlValue m))+      DModParam {}     -> mempty -- shouldn't happen+      DInterfaceConstraint {} -> mempty+        -- handled in the renamer as we need to resolve+        -- the signature name first (similar to import)+++instance BindsNames (InModule (NestedModule PName)) where+  namingEnv (InModule ~(Just m) (NestedModule mdef)) = BuildNamingEnv $+    do let pnmame = mName mdef+       nm   <- newTop NSModule m (thing pnmame) Nothing (srcRange pnmame)+       pure (singletonNS NSModule (thing pnmame) nm)++instance BindsNames (InModule (PrimType PName)) where+  namingEnv (InModule ~(Just m) PrimType { .. }) =+    BuildNamingEnv $+      do let Located { .. } = primTName+         nm <- newTop NSType m thing primTFixity srcRange+         pure (singletonNS NSType thing nm)++instance BindsNames (InModule (ParameterFun PName)) where+  namingEnv (InModule ~(Just ns) ParameterFun { .. }) = BuildNamingEnv $+    do let Located { .. } = pfName+       ntName <- newTop NSValue ns thing pfFixity srcRange+       return (singletonNS NSValue thing ntName)++instance BindsNames (InModule (ParameterType PName)) where+  namingEnv (InModule ~(Just ns) ParameterType { .. }) = BuildNamingEnv $+    -- XXX: we don't seem to have a fixity environment at the type level+    do let Located { .. } = ptName+       ntName <- newTop NSType ns thing Nothing srcRange+       return (singletonNS NSType thing ntName)++instance BindsNames (InModule (Newtype PName)) where+  namingEnv (InModule ~(Just ns) Newtype { .. }) = BuildNamingEnv $+    do let Located { .. } = nName+       ntName    <- newTop NSType  ns thing Nothing srcRange+       ntConName <- newTop NSValue ns thing Nothing srcRange+       return (singletonNS NSType thing ntName `mappend`+               singletonNS NSValue thing ntConName)++-- | The naming environment for a single declaration.+instance BindsNames (InModule (Decl PName)) where+  namingEnv (InModule pfx d) = case d of+    DBind b                 -> namingEnv (InModule pfx b)+    DSignature ns _sig      -> foldMap qualBind ns+    DPragma ns _p           -> foldMap qualBind ns+    DType syn               -> qualType (tsName syn) (tsFixity syn)+    DProp syn               -> qualType (psName syn) (psFixity syn)+    DLocated d' _           -> namingEnv (InModule pfx d')+    DRec {}                 -> panic "namingEnv" [ "DRec" ]+    DPatBind _pat _e        -> panic "namingEnv" ["Unexpected pattern binding"]+    DFixity{}               -> panic "namingEnv" ["Unexpected fixity declaration"]++    where++    mkName ns ln fx = case pfx of+                        Just m  -> newTop ns m (thing ln) fx (srcRange ln)+                        Nothing -> newLocal ns (thing ln) (srcRange ln)++    qualBind ln = BuildNamingEnv $+      do n <- mkName NSValue ln Nothing+         return (singletonNS NSValue (thing ln) n)++    qualType ln f = BuildNamingEnv $+      do n <- mkName NSType ln f+         return (singletonNS NSType (thing ln) n)++instance BindsNames (InModule (SigDecl PName)) where+  namingEnv (InModule m d) =+    case d of+      SigTySyn ts _    -> namingEnv (InModule m (DType ts))+      SigPropSyn ps _  -> namingEnv (InModule m (DProp ps))+++++--------------------------------------------------------------------------------+-- Helpers++newTop ::+  FreshM m => Namespace -> ModPath -> PName -> Maybe Fixity -> Range -> m Name+newTop ns m thing fx rng =+  liftSupply (mkDeclared ns m src (getIdent thing) fx rng)+  where src = if isGeneratedName thing then SystemName else UserName++newLocal :: FreshM m => Namespace -> PName -> Range -> m Name+newLocal ns thing rng = liftSupply (mkLocal ns (getIdent thing) rng)++-- | Given a name in a signature, make a name for the parameter corresponding+-- to the signature.+newModParam :: FreshM m => ModPath -> Ident -> Range -> Name -> m Name+newModParam m i rng n = liftSupply (mkModParam m i rng n)+++{- | Do something in the context of a module.+If `Nothing` than we are working with a local declaration.+Otherwise we are at the top-level of the given module.++By wrapping types with this, we can pass the module path+to methods that need the extra information. -}+data InModule a = InModule (Maybe ModPath) a+                  deriving (Functor,Traversable,Foldable,Show)+++
src/Cryptol/ModuleSystem/Env.hs view
@@ -7,17 +7,20 @@ -- Portability :  portable  {-# LANGUAGE CPP #-}+{-# LANGUAGE BlockArguments #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE PatternGuards #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-} module Cryptol.ModuleSystem.Env where  #ifndef RELOCATABLE import Paths_cryptol (getDataDir) #endif +import Cryptol.Backend.FFI (ForeignSrc, unloadForeignSrc, getForeignSrcPath) import Cryptol.Eval (EvalEnv) import Cryptol.ModuleSystem.Fingerprint import Cryptol.ModuleSystem.Interface@@ -34,13 +37,16 @@ import qualified Control.Exception as X import Data.Function (on) import Data.Set(Set)+import qualified Data.Set as Set import Data.Map (Map) import qualified Data.Map as Map import Data.Semigroup+import Data.Maybe(fromMaybe) import System.Directory (getAppUserDataDirectory, getCurrentDirectory) import System.Environment(getExecutablePath) import System.FilePath ((</>), normalise, joinPath, splitPath, takeDirectory) import qualified Data.List as List+import Data.Foldable  import GHC.Generics (Generic) import Control.DeepSeq@@ -99,14 +105,19 @@               | CoreLint          -- ^ Run core lint   deriving (Generic, NFData) -resetModuleEnv :: ModuleEnv -> ModuleEnv-resetModuleEnv env = env-  { meLoadedModules = mempty-  , meNameSeeds     = T.nameSeeds-  , meEvalEnv       = mempty-  , meFocusedModule = Nothing-  , meDynEnv        = mempty-  }+resetModuleEnv :: ModuleEnv -> IO ModuleEnv+resetModuleEnv env = do+  for_ (getLoadedModules $ meLoadedModules env) $ \lm ->+    case lmForeignSrc (lmData lm) of+      Just fsrc -> unloadForeignSrc fsrc+      _         -> pure ()+  pure env+    { meLoadedModules = mempty+    , meNameSeeds     = T.nameSeeds+    , meEvalEnv       = mempty+    , meFocusedModule = Nothing+    , meDynEnv        = mempty+    }  initialModuleEnv :: IO ModuleEnv initialModuleEnv = do@@ -171,9 +182,9 @@ loadedNonParamModules :: ModuleEnv -> [T.Module] loadedNonParamModules = map lmModule . lmLoadedModules . meLoadedModules -loadedNewtypes :: ModuleEnv -> Map Name IfaceNewtype+loadedNewtypes :: ModuleEnv -> Map Name T.Newtype loadedNewtypes menv = Map.unions-   [ ifNewtypes (ifPublic i) <> ifNewtypes (ifPrivate i)+   [ ifNewtypes (ifDefines i) <> ifNewtypes (ifDefines i)    | i <- map lmInterface (getLoadedModules (meLoadedModules menv))    ] @@ -184,10 +195,22 @@ allDeclGroups :: ModuleEnv -> [T.DeclGroup] allDeclGroups = concatMap T.mDecls . loadedNonParamModules +data ModContextParams =+    InterfaceParams T.ModParamNames+  | FunctorParams T.FunctorParams+  | NoParams++modContextParamNames :: ModContextParams -> T.ModParamNames+modContextParamNames mp =+  case mp of+    InterfaceParams ps -> ps+    FunctorParams ps   -> T.allParamNames ps+    NoParams           -> T.allParamNames mempty+ -- | Contains enough information to browse what's in scope, -- or type check new expressions. data ModContext = ModContext-  { mctxParams          :: IfaceParams+  { mctxParams          :: ModContextParams -- T.FunctorParams   , mctxExported        :: Set Name   , mctxDecls           :: IfaceDecls     -- ^ Should contain at least names in NamingEnv, but may have more@@ -199,7 +222,7 @@ -- This instance is a bit bogus.  It is mostly used to add the dynamic -- environemnt to an existing module, and it makes sense for that use case. instance Semigroup ModContext where-  x <> y = ModContext { mctxParams   = jnParams (mctxParams x) (mctxParams y)+  x <> y = ModContext { mctxParams   = jnPs (mctxParams x) (mctxParams y)                       , mctxExported = mctxExported x <> mctxExported y                       , mctxDecls    = mctxDecls x  <> mctxDecls  y                       , mctxNames    = names@@ -208,14 +231,15 @@        where       names = mctxNames x `R.shadowing` mctxNames y-      jnParams a b-        | isEmptyIfaceParams a = b-        | isEmptyIfaceParams b = a-        | otherwise =-          panic "ModContext" [ "Cannot combined 2 parameterized contexts" ]+      jnPs as bs =+        case (as,bs) of+          (NoParams,_) -> bs+          (_,NoParams) -> as+          (FunctorParams xs, FunctorParams ys) -> FunctorParams (xs <> ys)+          _ -> panic "(<>) @ ModContext" ["Can't combine parameters"]  instance Monoid ModContext where-  mempty = ModContext { mctxParams   = noIfaceParams+  mempty = ModContext { mctxParams   = NoParams                       , mctxDecls    = mempty                       , mctxExported = mempty                       , mctxNames    = mempty@@ -229,16 +253,36 @@   do lm <- lookupModule mname me      let localIface  = lmInterface lm          localNames  = lmNamingEnv lm-         loadedDecls = map (ifPublic . lmInterface)++         -- XXX: do we want only public ones here?+         loadedDecls = map (ifDefines . lmInterface)                      $ getLoadedModules (meLoadedModules me)++         params = ifParams localIface      pure ModContext-       { mctxParams   = ifParams localIface-       , mctxExported = ifaceDeclsNames (ifPublic localIface)-       , mctxDecls    = mconcat (ifPrivate localIface : loadedDecls)+       { mctxParams   = if Map.null params then NoParams+                                           else FunctorParams params+       , mctxExported = ifsPublic (ifNames localIface)+       , mctxDecls    = mconcat (ifDefines localIface : loadedDecls)        , mctxNames    = localNames        , mctxNameDisp = R.toNameDisp localNames        }+  `mplus`+  do lm <- lookupSignature mname me+     let localNames  = lmNamingEnv lm+         -- XXX: do we want only public ones here?+         loadedDecls = map (ifDefines . lmInterface)+                     $ getLoadedModules (meLoadedModules me)+     pure ModContext+       { mctxParams   = InterfaceParams (lmData lm)+       , mctxExported = Set.empty+       , mctxDecls    = mconcat loadedDecls+       , mctxNames    = localNames+       , mctxNameDisp = R.toNameDisp localNames+       } ++ dynModContext :: ModuleEnv -> ModContext dynModContext me = mempty { mctxNames    = dynNames                           , mctxNameDisp = R.toNameDisp dynNames@@ -277,6 +321,17 @@       (InMem a _, InMem b _) -> a == b       _ -> False +-- | In-memory things are compared by label.+instance Ord ModulePath where+  compare p1 p2 =+    case (p1,p2) of+      (InFile x, InFile y)   -> compare x y+      (InMem a _, InMem b _) -> compare a b+      (InMem {}, InFile {})  -> LT+      (InFile {}, InMem {})  -> GT+++ instance PP ModulePath where   ppPrec _ e =     case e of@@ -303,24 +358,49 @@   , lmLoadedParamModules :: [LoadedModule]     -- ^ Loaded parameterized modules. +  , lmLoadedSignatures :: ![LoadedSignature]+   } deriving (Show, Generic, NFData) +data LoadedEntity =+    ALoadedModule LoadedModule+  | ALoadedFunctor LoadedModule+  | ALoadedInterface LoadedSignature++getLoadedEntities ::+  LoadedModules -> Map ModName LoadedEntity+getLoadedEntities lm =+  Map.fromList $ [ (lmName x, ALoadedModule x) | x <- lmLoadedModules lm ] +++                 [ (lmName x, ALoadedFunctor x) | x <- lmLoadedParamModules lm ] +++                 [ (lmName x, ALoadedInterface x) | x <- lmLoadedSignatures lm ]+ getLoadedModules :: LoadedModules -> [LoadedModule] getLoadedModules x = lmLoadedParamModules x ++ lmLoadedModules x +getLoadedNames :: LoadedModules -> Set ModName+getLoadedNames lm = Set.fromList+                  $ map lmName (lmLoadedModules lm)+                 ++ map lmName (lmLoadedParamModules lm)+                 ++ map lmName (lmLoadedSignatures lm)+ instance Semigroup LoadedModules where   l <> r = LoadedModules     { lmLoadedModules = List.unionBy ((==) `on` lmName)                                       (lmLoadedModules l) (lmLoadedModules r)-    , lmLoadedParamModules = lmLoadedParamModules l ++ lmLoadedParamModules r }+    , lmLoadedParamModules = lmLoadedParamModules l ++ lmLoadedParamModules r+    , lmLoadedSignatures   = lmLoadedSignatures l ++ lmLoadedSignatures r+    }  instance Monoid LoadedModules where   mempty = LoadedModules { lmLoadedModules = []                          , lmLoadedParamModules = []+                         , lmLoadedSignatures = []                          }   mappend = (<>) -data LoadedModule = LoadedModule+-- | A generic type for loaded things.+-- The things can be either modules or signatures.+data LoadedModuleG a = LoadedModule   { lmName              :: ModName     -- ^ The name of this module.  Should match what's in 'lmModule' @@ -335,36 +415,94 @@   , lmNamingEnv         :: !R.NamingEnv     -- ^ What's in scope in this module -  , lmInterface         :: Iface+  , lmFileInfo          :: !FileInfo++  , lmData              :: a+  } deriving (Show, Generic, NFData)++type LoadedModule = LoadedModuleG LoadedModuleData++lmModule :: LoadedModule -> T.Module+lmModule = lmdModule . lmData++lmInterface :: LoadedModule -> Iface+lmInterface = lmdInterface . lmData++data LoadedModuleData = LoadedModuleData+  { lmdInterface         :: Iface     -- ^ The module's interface. -  , lmModule            :: T.Module+  , lmdModule            :: T.Module     -- ^ The actual type-checked module -  , lmFingerprint       :: Fingerprint+  , lmForeignSrc        :: Maybe ForeignSrc+    -- ^ The dynamically loaded source for any foreign functions in the module   } deriving (Show, Generic, NFData) +type LoadedSignature = LoadedModuleG T.ModParamNames++ -- | Has this module been loaded already. isLoaded :: ModName -> LoadedModules -> Bool-isLoaded mn lm = any ((mn ==) . lmName) (getLoadedModules lm)+isLoaded mn lm = mn `Set.member` getLoadedNames lm  -- | Is this a loaded parameterized module. isLoadedParamMod :: ModName -> LoadedModules -> Bool isLoadedParamMod mn ln = any ((mn ==) . lmName) (lmLoadedParamModules ln) +-- | Is this a loaded interface module.+isLoadedInterface :: ModName -> LoadedModules -> Bool+isLoadedInterface mn ln = any ((mn ==) . lmName) (lmLoadedSignatures ln)++++lookupTCEntity :: ModName -> ModuleEnv -> Maybe (LoadedModuleG T.TCTopEntity)+lookupTCEntity m env =+  case lookupModule m env of+    Just lm -> pure lm { lmData = T.TCTopModule (lmModule lm) }+    Nothing ->+      do lm <- lookupSignature m env+         pure lm { lmData = T.TCTopSignature m (lmData lm) }+ -- | Try to find a previously loaded module lookupModule :: ModName -> ModuleEnv -> Maybe LoadedModule lookupModule mn me = search lmLoadedModules `mplus` search lmLoadedParamModules   where   search how = List.find ((mn ==) . lmName) (how (meLoadedModules me)) +lookupSignature :: ModName -> ModuleEnv -> Maybe LoadedSignature+lookupSignature mn me =+  List.find ((mn ==) . lmName) (lmLoadedSignatures (meLoadedModules me)) +addLoadedSignature ::+  ModulePath -> String ->+  FileInfo ->+  R.NamingEnv ->+  ModName -> T.ModParamNames ->+  LoadedModules -> LoadedModules+addLoadedSignature path ident fi nameEnv nm si lm+  | isLoaded nm lm = lm+  | otherwise = lm { lmLoadedSignatures = loaded : lmLoadedSignatures lm }+  where+  loaded = LoadedModule+            { lmName        = nm+            , lmFilePath    = path+            , lmModuleId    = ident+            , lmNamingEnv   = nameEnv+            , lmData        = si+            , lmFileInfo    = fi+            }+ -- | Add a freshly loaded module.  If it was previously loaded, then -- the new version is ignored. addLoadedModule ::-  ModulePath -> String -> Fingerprint -> R.NamingEnv -> T.Module ->-  LoadedModules -> LoadedModules-addLoadedModule path ident fp nameEnv tm lm+  ModulePath ->+  String ->+  FileInfo ->+  R.NamingEnv ->+  Maybe ForeignSrc ->+  T.Module -> LoadedModules -> LoadedModules+addLoadedModule path ident fi nameEnv fsrc tm lm   | isLoaded (T.mName tm) lm  = lm   | T.isParametrizedModule tm = lm { lmLoadedParamModules = loaded :                                                 lmLoadedParamModules lm }@@ -376,21 +514,53 @@     , lmFilePath        = path     , lmModuleId        = ident     , lmNamingEnv       = nameEnv-    , lmInterface       = T.genIface tm-    , lmModule          = tm-    , lmFingerprint     = fp+    , lmData            = LoadedModuleData+                             { lmdInterface = T.genIface tm+                             , lmdModule    = tm+                             , lmForeignSrc = fsrc+                             }+    , lmFileInfo        = fi     }  -- | Remove a previously loaded module. -- Note that this removes exactly the modules specified by the predicate. -- One should be carfule to preserve the invariant on 'LoadedModules'.-removeLoadedModule :: (LoadedModule -> Bool) -> LoadedModules -> LoadedModules+removeLoadedModule ::+  (forall a. LoadedModuleG a -> Bool) -> LoadedModules -> LoadedModules removeLoadedModule rm lm =   LoadedModules-    { lmLoadedModules = filter (not . rm) (lmLoadedModules lm)-    , lmLoadedParamModules = filter (not . rm) (lmLoadedParamModules lm)+    { lmLoadedModules       = filter (not . rm) (lmLoadedModules lm)+    , lmLoadedParamModules  = filter (not . rm) (lmLoadedParamModules lm)+    , lmLoadedSignatures    = filter (not . rm) (lmLoadedSignatures lm)     } +-- FileInfo --------------------------------------------------------------------++data FileInfo = FileInfo+  { fiFingerprint :: Fingerprint+  , fiIncludeDeps :: Set FilePath+  , fiImportDeps  :: Set ModName+  , fiForeignDeps :: Set FilePath+  } deriving (Show,Generic,NFData)+++fileInfo ::+  Fingerprint ->+  Set FilePath ->+  Set ModName ->+  Maybe ForeignSrc ->+  FileInfo+fileInfo fp incDeps impDeps fsrc =+  FileInfo+    { fiFingerprint = fp+    , fiIncludeDeps = incDeps+    , fiImportDeps  = impDeps+    , fiForeignDeps = fromMaybe Set.empty+                      do src <- fsrc+                         Set.singleton <$> getForeignSrcPath src+    }++ -- Dynamic Environments --------------------------------------------------------  -- | Extra information we need to carry around to dynamically extend@@ -433,6 +603,8 @@                , ifAbstractTypes = Map.empty                , ifDecls = decls                , ifModules = Map.empty+               , ifFunctors = Map.empty+               , ifSignatures = Map.empty                }   where     decls = mconcat
src/Cryptol/ModuleSystem/Exports.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE Safe #-} module Cryptol.ModuleSystem.Exports where  import Data.Set(Set)@@ -10,30 +11,32 @@ import GHC.Generics (Generic)  import Cryptol.Parser.AST-import Cryptol.Parser.Names(namesD,tnamesD,tnamesNT)+import Cryptol.Parser.Names(namesD,tnamesD,namesNT,tnamesNT) import Cryptol.ModuleSystem.Name -modExports :: Ord name => ModuleG mname name -> ExportSpec name-modExports m = fold (concat [ exportedNames d | d <- mDecls m ])-+exportedDecls :: Ord name => [TopDecl name] -> ExportSpec name+exportedDecls ds = fold (concat [ exportedNames d | d <- ds ])  exportedNames :: Ord name => TopDecl name -> [ExportSpec name]-exportedNames (Decl td) = map exportBind  (names namesD td)-                       ++ map exportType (names tnamesD td)-exportedNames (DPrimType t) = [ exportType (thing . primTName <$> t) ]-exportedNames (TDNewtype nt) = map exportType (names tnamesNT nt)-exportedNames (Include {})  = []-exportedNames (DImport {}) = []-exportedNames (DParameterFun {}) = []-exportedNames (DParameterType {}) = []-exportedNames (DParameterConstraint {}) = []-exportedNames (DModule nested) =-  case tlValue nested of-    NestedModule x ->-      [exportName NSModule nested { tlValue = thing (mName x) }]+exportedNames decl =+    case decl of+      Decl td -> map exportBind  (names  namesD td)+              ++ map exportType (names tnamesD td)+      DPrimType t -> [ exportType (thing . primTName <$> t) ]+      TDNewtype nt -> map exportType (names tnamesNT nt) +++                      map exportBind (names namesNT nt)+      Include {}  -> []+      DImport {} -> []+      DParamDecl {} -> []+      DInterfaceConstraint {} -> []+      DModule nested ->+        case tlValue nested of+          NestedModule x ->+            [exportName NSModule nested { tlValue = thing (mName x) }]+      DModParam {} -> []+  where+  names by td = [ td { tlValue = thing n } | n <- fst (by (tlValue td)) ] -names :: (a -> ([Located a'], b)) -> TopLevel a -> [TopLevel a']-names by td = [ td { tlValue = thing n } | n <- fst (by (tlValue td)) ]   newtype ExportSpec name = ExportSpec (Map Namespace (Set name))@@ -53,6 +56,9 @@                          $ Map.singleton ns                          $ Set.singleton (tlValue n)   | otherwise = mempty++allExported :: Ord name => ExportSpec name -> Set name+allExported (ExportSpec mp) = Set.unions (Map.elems mp)  exported :: Namespace -> ExportSpec name -> Set name exported ns (ExportSpec mp) = Map.findWithDefault Set.empty ns mp
src/Cryptol/ModuleSystem/Fingerprint.hs view
@@ -10,6 +10,7 @@   ( Fingerprint   , fingerprint   , fingerprintFile+  , fingerprintHexString   ) where  import Control.DeepSeq          (NFData (rnf))@@ -17,6 +18,7 @@ import Data.ByteString          (ByteString) import Control.Exception        (try) import qualified Data.ByteString as B+import qualified Data.Vector as Vector  newtype Fingerprint = Fingerprint ByteString   deriving (Eq, Show)@@ -37,3 +39,13 @@        case res :: Either IOError ByteString of          Left{}  -> Nothing          Right b -> Just $! fingerprint b++fingerprintHexString :: Fingerprint -> String+fingerprintHexString (Fingerprint bs) = B.foldr hex "" bs+  where+  digits   = Vector.fromList "0123456789ABCDEF"+  digit x  = digits Vector.! fromIntegral x+  hex b cs = let (x,y) = divMod b 16+             in digit x : digit y : cs++
− src/Cryptol/ModuleSystem/InstantiateModule.hs
@@ -1,325 +0,0 @@-{-# Language FlexibleInstances, PatternGuards #-}-{-# Language BlockArguments #-}--- | Assumes that local names do not shadow top level names.-module Cryptol.ModuleSystem.InstantiateModule-  ( instantiateModule-  ) where--import           Data.Set (Set)-import qualified Data.Set as Set-import           Data.Map (Map)-import qualified Data.Map as Map-import           MonadLib(ReaderT,runReaderT,ask)--import Cryptol.Utils.Panic(panic)-import Cryptol.Utils.Ident(ModName,modParamIdent)-import Cryptol.Parser.Position(Located(..))-import Cryptol.ModuleSystem.Name-import Cryptol.TypeCheck.AST-import Cryptol.TypeCheck.Subst(listParamSubst, apSubst)-import Cryptol.TypeCheck.SimpType(tRebuild)--{--XXX: Should we simplify constraints in the instantiated modules?--If so, we also need to adjust the constraint parameters on terms appropriately,-especially when working with dictionaries.--}----- | Convert a module instantiation into a partial module.--- The resulting module is incomplete because it is missing the definitions--- from the instantiation.-instantiateModule :: FreshM m =>-                     Module           {- ^ Parametrized module -} ->-                     ModName          {- ^ Name of the new module -} ->-                     Map TParam Type  {- ^ Type params -} ->-                     Map Name Expr    {- ^ Value parameters -} ->-                     m (Name -> Name, [Located Prop], Module)-                     -- ^ Renaming, instantiated constraints, fresh module, new supply-instantiateModule func newName tpMap vpMap-  | not (null (mSubModules func)) =-      panic "instantiateModule"-        [ "XXX: we don't support functors with nested moduels yet." ]-  | otherwise  =-  runReaderT (TopModule newName) $-    do let oldVpNames = Map.keys vpMap-       newVpNames <- mapM freshParamName (Map.keys vpMap)-       let vpNames = Map.fromList (zip oldVpNames newVpNames)--       env <- computeEnv func tpMap vpNames-       let ren x = case nameNamespace x of-                     NSValue -> Map.findWithDefault x x (funNameMap env)-                     NSType  -> Map.findWithDefault x x (tyNameMap env)-                     NSModule -> x--       let rnMp :: Inst a => (a -> Name) -> Map Name a -> Map Name a-           rnMp f m = Map.fromList [ (f x, x) | a <- Map.elems m-                                              , let x = inst env a ]--           renamedExports  = inst env (mExports func)-           renamedTySyns   = rnMp tsName (mTySyns func)-           renamedNewtypes = rnMp ntName (mNewtypes func)-           renamedPrimTys  = rnMp atName (mPrimTypes func)--           su = listParamSubst (Map.toList (tyParamMap env))--           goals = map (fmap (apSubst su)) (mParamConstraints func)-           -- Constraints to discharge about the type instances--       let renamedDecls = inst env (mDecls func)-           paramDecls = map (mkParamDecl su vpNames) (Map.toList vpMap)--       return ( ren-              , goals-              , Module-                 { mName              = newName-                 , mExports           = renamedExports-                 , mImports           = mImports func-                 , mTySyns            = renamedTySyns-                 , mNewtypes          = renamedNewtypes-                 , mPrimTypes         = renamedPrimTys-                 , mParamTypes        = Map.empty-                 , mParamConstraints  = []-                 , mParamFuns         = Map.empty-                 , mDecls             = paramDecls ++ renamedDecls--                 , mSubModules        = mempty-                 , mFunctors          = mempty-                 } )--  where-  mkParamDecl su vpNames (x,e) =-      NonRecursive Decl-        { dName        = Map.findWithDefault (error "OOPS") x vpNames-        , dSignature   = apSubst su-                       $ mvpType-                       $ Map.findWithDefault (error "UUPS") x (mParamFuns func)-        , dDefinition  = DExpr e-        , dPragmas     = []      -- XXX: which if any pragmas?-        , dInfix       = False   -- XXX: get from parameter?-        , dFixity      = Nothing -- XXX: get from parameter-        , dDoc         = Nothing -- XXX: get from parametr(or instance?)-        }-------------------------------------------------------------------------------------- Things that need to be renamed--class Defines t where-  defines :: t -> Set Name--instance Defines t => Defines [t] where-  defines = Set.unions . map defines--instance Defines Decl where-  defines = Set.singleton . dName--instance Defines DeclGroup where-  defines d =-    case d of-      NonRecursive x -> defines x-      Recursive x    -> defines x-------------------------------------------------------------------------------------type InstM = ReaderT ModPath---- | Generate a new instance of a declared name.-freshenName :: FreshM m => Name -> InstM m Name-freshenName x =-  do m <- ask-     let sys = case nameInfo x of-                 Declared _ s -> s-                 _            -> UserName-     liftSupply (mkDeclared (nameNamespace x)-                             m sys (nameIdent x) (nameFixity x) (nameLoc x))--freshParamName :: FreshM m => Name -> InstM m Name-freshParamName x =-  do m <- ask-     let newName = modParamIdent (nameIdent x)-     liftSupply (mkDeclared (nameNamespace x)-                          m UserName newName (nameFixity x) (nameLoc x))------- | Compute renaming environment from a module instantiation.--- computeEnv :: ModInst -> InstM Env-computeEnv :: FreshM m =>-              Module {- ^ Functor being instantiated -} ->-              Map TParam Type {- replace type params by type -} ->-              Map Name Name {- replace value parameters by other names -} ->-              InstM m Env-computeEnv m tpMap vpMap =-  do tss <- mapM freshTy (Map.toList (mTySyns m))-     nts <- mapM freshTy (Map.toList (mNewtypes m))-     let tnMap = Map.fromList (tss ++ nts)--     defHere <- mapM mkVParam (Set.toList (defines (mDecls m)))-     let fnMap = Map.union vpMap (Map.fromList defHere)--     return Env { funNameMap  = fnMap-                , tyNameMap   = tnMap-                , tyParamMap  = tpMap-                }-  where-  freshTy (x,_) = do y <- freshenName x-                     return (x,y)--  mkVParam x = do y <- freshenName x-                  return (x,y)--------------------------------------------------------------------------------------- Do the renaming--data Env = Env-  { funNameMap  :: Map Name Name-  , tyNameMap   :: Map Name Name-  , tyParamMap  :: Map TParam Type-  } deriving Show---class Inst t where-  inst :: Env -> t -> t--instance Inst a => Inst [a] where-  inst env = map (inst env)--instance Inst Expr where-  inst env = go-    where-    go expr =-      case expr of-        EVar x -> case Map.lookup x (funNameMap env) of-                    Just y -> EVar y-                    _      -> expr--        ELocated r e              -> ELocated r (inst env e)-        EList xs t                -> EList (inst env xs) (inst env t)-        ETuple es                 -> ETuple (inst env es)-        ERec xs                   -> ERec (fmap go xs)-        ESel e s                  -> ESel (go e) s-        ESet ty e x v             -> ESet (inst env ty) (go e) x (go v)-        EIf e1 e2 e3              -> EIf (go e1) (go e2) (go e3)-        EComp t1 t2 e mss         -> EComp (inst env t1) (inst env t2)-                                           (go e)-                                           (inst env mss)-        ETAbs t e                 -> ETAbs t (go e)-        ETApp e t                 -> ETApp (go e) (inst env t)-        EApp e1 e2                -> EApp (go e1) (go e2)-        EAbs x t e                -> EAbs x (inst env t) (go e)-        EProofAbs p e             -> EProofAbs (inst env p) (go e)-        EProofApp e               -> EProofApp (go e)-        EWhere e ds               -> EWhere (go e) (inst env ds)---instance Inst DeclGroup where-  inst env dg =-    case dg of-      NonRecursive d -> NonRecursive (inst env d)-      Recursive ds   -> Recursive (inst env ds)--instance Inst DeclDef where-  inst env d =-    case d of-      DPrim   -> DPrim-      DExpr e -> DExpr (inst env e)--instance Inst Decl where-  inst env d = d { dSignature = inst env (dSignature d)-                 , dDefinition = inst env (dDefinition d)-                 , dName = Map.findWithDefault (dName d) (dName d)-                                                         (funNameMap env)-                 }--instance Inst Match where-  inst env m =-    case m of-      From x t1 t2 e -> From x (inst env t1) (inst env t2) (inst env e)-      Let d          -> Let (inst env d)--instance Inst Schema where-  inst env s = s { sProps = inst env (sProps s)-                 , sType  = inst env (sType s)-                 }--instance Inst Type where-  inst env ty =-    tRebuild $-    case ty of-      TCon tc ts    -> TCon (inst env tc) (inst env ts)-      TVar tv       ->-        case tv of-          TVBound tp | Just t <- Map.lookup tp (tyParamMap env) -> t-          _ -> ty-      TUser x ts t  -> TUser y (inst env ts) (inst env t)-        where y = Map.findWithDefault x x (tyNameMap env)-      TRec fs       -> TRec (fmap (inst env) fs)-      TNewtype nt ts -> TNewtype (inst env nt) (inst env ts)--instance Inst TCon where-  inst env tc =-    case tc of-      TC x -> TC (inst env x)-      _    -> tc--instance Inst TC where-  inst env tc =-    case tc of-      TCAbstract x -> TCAbstract (inst env x)-      _            -> tc--instance Inst UserTC where-  inst env (UserTC x t) = UserTC y t-    where y = Map.findWithDefault x x (tyNameMap env)--instance Inst (ExportSpec Name) where-  inst env (ExportSpec spec) = ExportSpec (Map.mapWithKey doNS spec)-    where-    doNS ns =-      case ns of-        NSType  -> Set.map \x -> Map.findWithDefault x x (tyNameMap env)-        NSValue -> Set.map \x -> Map.findWithDefault x x (funNameMap env)-        NSModule -> id---instance Inst TySyn where-  inst env ts = TySyn { tsName = instTyName env x-                      , tsParams = tsParams ts-                      , tsConstraints = inst env (tsConstraints ts)-                      , tsDef = inst env (tsDef ts)-                      , tsDoc = tsDoc ts-                      }-    where x = tsName ts--instance Inst Newtype where-  inst env nt = Newtype { ntName = instTyName env x-                        , ntParams = ntParams nt-                        , ntConstraints = inst env (ntConstraints nt)-                        , ntFields = fmap (inst env) (ntFields nt)-                        , ntDoc = ntDoc nt-                        }-    where x = ntName nt--instance Inst AbstractType where-  inst env a = AbstractType { atName    = instTyName env (atName a)-                            , atKind    = atKind a-                            , atCtrs    = case atCtrs a of-                                            (xs,ps) -> (xs, inst env ps)-                            , atFixitiy = atFixitiy a-                            , atDoc     = atDoc a-                            }--instTyName :: Env -> Name -> Name-instTyName env x = Map.findWithDefault x x (tyNameMap env)------
src/Cryptol/ModuleSystem/Interface.hs view
@@ -9,30 +9,28 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE PatternGuards #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE Safe #-} module Cryptol.ModuleSystem.Interface (     Iface   , IfaceG(..)   , IfaceDecls(..)-  , IfaceTySyn, ifTySynName-  , IfaceNewtype   , IfaceDecl(..)-  , IfaceParams(..)+  , IfaceNames(..)+  , ifModName    , emptyIface   , ifacePrimMap-  , noIfaceParams-  , isEmptyIfaceParams+  , ifaceForgetName   , ifaceIsFunctor-  , flatPublicIface-  , flatPublicDecls   , filterIfaceDecls   , ifaceDeclsNames+  , ifaceOrigNameMap   ) where  import           Data.Set(Set) import qualified Data.Set as Set+import           Data.Map (Map) import qualified Data.Map as Map import           Data.Semigroup import           Data.Text (Text)@@ -44,74 +42,76 @@ import Prelude.Compat  import Cryptol.ModuleSystem.Name-import Cryptol.Utils.Ident (ModName)+import Cryptol.Utils.Ident (ModName, OrigName(..)) import Cryptol.Utils.Panic(panic) import Cryptol.Utils.Fixity(Fixity) import Cryptol.Parser.AST(Pragma)-import Cryptol.Parser.Position(Located) import Cryptol.TypeCheck.Type +type Iface = IfaceG ModName --- | The resulting interface generated by a module that has been typechecked.-data IfaceG mname = Iface-  { ifModName   :: !mname       -- ^ Module name-  , ifPublic    :: IfaceDecls   -- ^ Exported definitions-  , ifPrivate   :: IfaceDecls   -- ^ Private defintiions-  , ifParams    :: IfaceParams  -- ^ Uninterpreted constants (aka module params)+-- | The interface repersenting a typecheck top-level module.+data IfaceG name = Iface+  { ifNames     :: IfaceNames name    -- ^ Info about names in this module+  , ifParams    :: FunctorParams      -- ^ Module parameters, if any+  , ifDefines   :: IfaceDecls         -- ^ All things defines in the module+                                      -- (includes nested definitions)   } deriving (Show, Generic, NFData) -ifaceIsFunctor :: IfaceG mname -> Bool-ifaceIsFunctor = not . isEmptyIfaceParams . ifParams---- | The public declarations in all modules, including nested--- The modules field contains public functors--- Assumes that we are not a functor.-flatPublicIface :: IfaceG mname -> IfaceDecls-flatPublicIface iface = flatPublicDecls (ifPublic iface)---flatPublicDecls :: IfaceDecls -> IfaceDecls-flatPublicDecls ifs = mconcat ( ifs { ifModules = fun }-                              : map flatPublicIface (Map.elems nofun)-                              )+-- | Remove the name of a module.  This is useful for dealing with collections+-- of modules, as in `Map (ImpName Name) (IfaceG ())`.+ifaceForgetName :: IfaceG name -> IfaceG ()+ifaceForgetName i = i { ifNames = newNames }+  where newNames = (ifNames i) { ifsName = () } -  where-  (fun,nofun) = Map.partition ifaceIsFunctor (ifModules ifs)+-- | Access the name of a module.+ifModName :: IfaceG name -> name+ifModName = ifsName . ifNames +-- | Information about the names in a module.+data IfaceNames name = IfaceNames+  { ifsName     :: name       -- ^ Name of this submodule+  , ifsNested   :: Set Name   -- ^ Things nested in this module+  , ifsDefines  :: Set Name   -- ^ Things defined in this module+  , ifsPublic   :: Set Name   -- ^ Subset of `ifsDefines` that is public+  , ifsDoc      :: !(Maybe Text) -- ^ Documentation+  } deriving (Show, Generic, NFData) -type Iface = IfaceG ModName+-- | Is this interface for a functor.+ifaceIsFunctor :: IfaceG name -> Bool+ifaceIsFunctor = not . Map.null . ifParams -emptyIface :: mname -> IfaceG mname+emptyIface :: ModName -> Iface emptyIface nm = Iface-  { ifModName = nm-  , ifPublic  = mempty-  , ifPrivate = mempty-  , ifParams  = noIfaceParams-  }--data IfaceParams = IfaceParams-  { ifParamTypes       :: Map.Map Name ModTParam-  , ifParamConstraints :: [Located Prop] -- ^ Constraints on param. types-  , ifParamFuns        :: Map.Map Name ModVParam-  } deriving (Show, Generic, NFData)--noIfaceParams :: IfaceParams-noIfaceParams = IfaceParams-  { ifParamTypes = Map.empty-  , ifParamConstraints = []-  , ifParamFuns = Map.empty+  { ifNames   = IfaceNames { ifsName    = nm+                           , ifsDefines = mempty+                           , ifsPublic  = mempty+                           , ifsNested  = mempty+                           , ifsDoc     = Nothing+                           }+  , ifParams  = mempty+  , ifDefines = mempty   } -isEmptyIfaceParams :: IfaceParams -> Bool-isEmptyIfaceParams IfaceParams { .. } =-  Map.null ifParamTypes && null ifParamConstraints && Map.null ifParamFuns-+-- | Declarations in a module.  Note that this includes things from nested+-- modules, but not things from nested functors, which are in `ifFunctors`. data IfaceDecls = IfaceDecls-  { ifTySyns        :: Map.Map Name IfaceTySyn-  , ifNewtypes      :: Map.Map Name IfaceNewtype-  , ifAbstractTypes :: Map.Map Name IfaceAbstractType+  { ifTySyns        :: Map.Map Name TySyn+  , ifNewtypes      :: Map.Map Name Newtype+  , ifAbstractTypes :: Map.Map Name AbstractType   , ifDecls         :: Map.Map Name IfaceDecl-  , ifModules       :: !(Map.Map Name (IfaceG Name))+  , ifModules       :: !(Map.Map Name (IfaceNames Name))+  , ifSignatures    :: !(Map.Map Name ModParamNames)+  , ifFunctors      :: !(Map.Map Name (IfaceG Name))+    {- ^ XXX: Maybe arg info?+    Also, with the current implementation we aim to complete remove functors+    by essentially inlining them.  To achieve this with just interfaces+    we'd have to store here the entire module, not just its interface.+    At the moment we work around this by passing all loaded modules to the+    type checker, so it looks up functors there, instead of in the interfaces,+    but we'd need to change this if we want better support for separate+    compilation. -}+   } deriving (Show, Generic, NFData)  filterIfaceDecls :: (Name -> Bool) -> IfaceDecls -> IfaceDecls@@ -121,6 +121,8 @@   , ifAbstractTypes = filterMap (ifAbstractTypes ifs)   , ifDecls         = filterMap (ifDecls ifs)   , ifModules       = filterMap (ifModules ifs)+  , ifFunctors      = filterMap (ifFunctors ifs)+  , ifSignatures    = filterMap (ifSignatures ifs)   }   where   filterMap :: Map.Map Name a -> Map.Map Name a@@ -132,6 +134,8 @@                                , Map.keysSet (ifAbstractTypes i)                                , Map.keysSet (ifDecls i)                                , Map.keysSet (ifModules i)+                               , Map.keysSet (ifFunctors i)+                               , Map.keysSet (ifSignatures i)                                ]  @@ -142,30 +146,35 @@     , ifAbstractTypes = Map.union (ifAbstractTypes l) (ifAbstractTypes r)     , ifDecls    = Map.union (ifDecls l)    (ifDecls r)     , ifModules  = Map.union (ifModules l)  (ifModules r)+    , ifFunctors = Map.union (ifFunctors l) (ifFunctors r)+    , ifSignatures = ifSignatures l <> ifSignatures r     }  instance Monoid IfaceDecls where-  mempty      = IfaceDecls Map.empty Map.empty Map.empty Map.empty Map.empty-  mappend     = (<>)+  mempty      = IfaceDecls+                  { ifTySyns = mempty+                  , ifNewtypes = mempty+                  , ifAbstractTypes = mempty+                  , ifDecls = mempty+                  , ifModules = mempty+                  , ifFunctors = mempty+                  , ifSignatures = mempty+                  }+  mappend = (<>)   mconcat ds  = IfaceDecls     { ifTySyns   = Map.unions (map ifTySyns   ds)     , ifNewtypes = Map.unions (map ifNewtypes ds)     , ifAbstractTypes = Map.unions (map ifAbstractTypes ds)     , ifDecls    = Map.unions (map ifDecls    ds)     , ifModules  = Map.unions (map ifModules ds)+    , ifFunctors = Map.unions (map ifFunctors ds)+    , ifSignatures = Map.unions (map ifSignatures ds)     } -type IfaceTySyn = TySyn--ifTySynName :: TySyn -> Name-ifTySynName = tsName--type IfaceNewtype = Newtype-type IfaceAbstractType = AbstractType- data IfaceDecl = IfaceDecl   { ifDeclName    :: !Name          -- ^ Name of thing   , ifDeclSig     :: Schema         -- ^ Type+  , ifDeclIsPrim   :: !Bool   , ifDeclPragmas :: [Pragma]       -- ^ Pragmas   , ifDeclInfix   :: Bool           -- ^ Is this an infix thing   , ifDeclFixity  :: Maybe Fixity   -- ^ Fixity information@@ -176,15 +185,12 @@ -- | Produce a PrimMap from an interface. -- -- NOTE: the map will expose /both/ public and private names.+-- NOTE: this is a bit misnamed, as it is used to resolve known names+-- that Cryptol introduces (e.g., during type checking).  These+-- names need not be primitives.   A better way to do this in the future+-- might be to use original names instead (see #1522). ifacePrimMap :: Iface -> PrimMap-ifacePrimMap Iface { .. } =-  PrimMap { primDecls = merge primDecls-          , primTypes = merge primTypes }-  where-  merge f = Map.union (f public) (f private)--  public  = ifaceDeclsPrimMap ifPublic-  private = ifaceDeclsPrimMap ifPrivate+ifacePrimMap = ifaceDeclsPrimMap . ifDefines  ifaceDeclsPrimMap :: IfaceDecls -> PrimMap ifaceDeclsPrimMap IfaceDecls { .. } =@@ -199,6 +205,36 @@                           [ "Top level name not declared in a module?"                           , show n ] -  exprs    = map entry (Map.keys ifDecls)   newtypes = map entry (Map.keys ifNewtypes)+  exprs    = map entry (Map.keys ifDecls)   types    = map entry (Map.keys ifTySyns)+++-- | Given an interface computing a map from original names to actual names,+-- grouped by namespace.+ifaceOrigNameMap :: IfaceG name -> Map Namespace (Map OrigName Name)+ifaceOrigNameMap ifa = Map.unionsWith Map.union (here : nested)+  where+  here        = Map.fromList $+                  [ (NSValue, toMap vaNames) | not (Set.null vaNames) ] +++                  [ (NSType,  toMap tyNames) | not (Set.null tyNames) ] +++                  [ (NSValue, toMap moNames) | not (Set.null moNames) ]++  nested      = map ifaceOrigNameMap (Map.elems (ifFunctors decls))++  toMap names = Map.fromList+                  [ (og,x) | x <- Set.toList names, Just og <- [ asOrigName x ] ]++  decls       = ifDefines ifa+  from f      = Map.keysSet (f decls)+  tyNames     = Set.unions [ from ifTySyns, from ifNewtypes, from ifAbstractTypes ]+  moNames     = Set.unions [ from ifModules, from ifSignatures, from ifFunctors ]+  vaNames     = Set.unions [ newtypeCons, from ifDecls ]+  newtypeCons = Set.fromList (map ntConName (Map.elems (ifNewtypes decls)))+++++++
src/Cryptol/ModuleSystem/Monad.hs view
@@ -10,29 +10,33 @@ {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE BlockArguments #-} module Cryptol.ModuleSystem.Monad where  import           Cryptol.Eval (EvalEnv,EvalOpts(..)) +import           Cryptol.Backend.FFI (ForeignSrc)+import           Cryptol.Backend.FFI.Error import qualified Cryptol.Backend.Monad           as E  import           Cryptol.ModuleSystem.Env-import           Cryptol.ModuleSystem.Fingerprint+import qualified Cryptol.ModuleSystem.Env as MEnv import           Cryptol.ModuleSystem.Interface import           Cryptol.ModuleSystem.Name (FreshM(..),Supply) import           Cryptol.ModuleSystem.Renamer (RenamerError(),RenamerWarning()) import           Cryptol.ModuleSystem.NamingEnv(NamingEnv) import qualified Cryptol.Parser     as Parser import qualified Cryptol.Parser.AST as P-import           Cryptol.Parser.Position (Located) import           Cryptol.Utils.Panic (panic) import qualified Cryptol.Parser.NoPat as NoPat+import qualified Cryptol.Parser.ExpandPropGuards as ExpandPropGuards import qualified Cryptol.Parser.NoInclude as NoInc import qualified Cryptol.TypeCheck as T import qualified Cryptol.TypeCheck.AST as T import qualified Cryptol.TypeCheck.Solver.SMT as SMT -import           Cryptol.Parser.Position (Range)+import           Cryptol.Parser.Position (Range, Located) import           Cryptol.Utils.Ident (interactiveName, noModuleName) import           Cryptol.Utils.PP import           Cryptol.Utils.Logger(Logger)@@ -42,9 +46,10 @@ import Control.Exception (IOException) import Data.ByteString (ByteString) import Data.Function (on)+import Data.Functor.Identity import Data.Map (Map)-import Data.Maybe (isJust) import Data.Text.Encoding.Error (UnicodeException)+import Data.Traversable import MonadLib import System.Directory (canonicalizePath) @@ -60,6 +65,7 @@ data ImportSource   = FromModule P.ModName   | FromImport (Located P.Import)+  | FromSigImport (Located P.ModName)   | FromModuleInstance (Located P.ModName)     deriving (Show, Generic, NFData) @@ -70,6 +76,7 @@   ppPrec _ is = case is of     FromModule n  -> text "module name" <+> pp n     FromImport li -> text "import of module" <+> pp (P.iModule (P.thing li))+    FromSigImport l -> text "import of interface" <+> pp (P.thing l)     FromModuleInstance l ->       text "instantiation of module" <+> pp (P.thing l) @@ -79,6 +86,7 @@     FromModule n          -> n     FromImport li         -> P.iModule (P.thing li)     FromModuleInstance l  -> P.thing l+    FromSigImport l       -> P.thing l   data ModuleError@@ -98,6 +106,8 @@     -- ^ Problems during the renaming phase   | NoPatErrors ImportSource [NoPat.Error]     -- ^ Problems during the NoPat phase+  | ExpandPropGuardsError ImportSource ExpandPropGuards.Error+    -- ^ Problems during the ExpandPropGuards phase   | NoIncludeErrors ImportSource [NoInc.IncludeError]     -- ^ Problems during the NoInclude phase   | TypeCheckingFailed ImportSource T.NameMap [(Range,T.Error)]@@ -108,11 +118,8 @@     -- ^ Module loaded by 'import' statement has the wrong module name   | DuplicateModuleName P.ModName FilePath FilePath     -- ^ Two modules loaded from different files have the same module name-  | ImportedParamModule P.ModName-    -- ^ Attempt to import a parametrized module that was not instantiated.-  | FailedToParameterizeModDefs P.ModName [T.Name]-    -- ^ Failed to add the module parameters to all definitions in a module.-  | NotAParameterizedModule P.ModName+  | FFILoadErrors P.ModName [FFILoadError]+    -- ^ Errors loading foreign function implementations    | ErrorInFile ModulePath ModuleError     -- ^ This is just a tag on the error, indicating the file containing it.@@ -131,6 +138,7 @@     RecursiveModules mods                -> mods `deepseq` ()     RenamerErrors src errs               -> src `deepseq` errs `deepseq` ()     NoPatErrors src errs                 -> src `deepseq` errs `deepseq` ()+    ExpandPropGuardsError src err        -> src `deepseq` err `deepseq` ()     NoIncludeErrors src errs             -> src `deepseq` errs `deepseq` ()     TypeCheckingFailed nm src errs       -> nm `deepseq` src `deepseq` errs `deepseq` ()     ModuleNameMismatch expected found    ->@@ -138,9 +146,7 @@     DuplicateModuleName name path1 path2 ->       name `deepseq` path1 `deepseq` path2 `deepseq` ()     OtherFailure x                       -> x `deepseq` ()-    ImportedParamModule x                -> x `deepseq` ()-    FailedToParameterizeModDefs x xs     -> x `deepseq` xs `deepseq` ()-    NotAParameterizedModule x            -> x `deepseq` ()+    FFILoadErrors x errs                 -> x `deepseq` errs `deepseq` ()     ErrorInFile x y                      -> x `deepseq` y `deepseq` ()  instance PP ModuleError where@@ -178,6 +184,8 @@      NoPatErrors _src errs -> vcat (map pp errs) +    ExpandPropGuardsError _src err -> pp err+     NoIncludeErrors _src errs -> vcat (map NoInc.ppIncludeError errs)      TypeCheckingFailed _src nm errs -> vcat (map (T.ppNamedError nm) errs)@@ -185,7 +193,7 @@     ModuleNameMismatch expected found ->       hang (text "[error]" <+> pp (P.srcRange found) <.> char ':')          4 (vcat [ text "File name does not match module name:"-                 , text "Saw:"      <+> pp (P.thing found)+                 , text "  Actual:" <+> pp (P.thing found)                  , text "Expected:" <+> pp expected                  ]) @@ -196,16 +204,10 @@      OtherFailure x -> text x -    ImportedParamModule p ->-      text "[error] Import of a non-instantiated parameterized module:" <+> pp p--    FailedToParameterizeModDefs x xs ->-      hang (text "[error] Parameterized module" <+> pp x <+>-            text "has polymorphic parameters:")-         4 (commaSep (map pp xs))--    NotAParameterizedModule x ->-      text "[error] Module" <+> pp x <+> text "does not have parameters."+    FFILoadErrors x errs ->+      hang (text "[error] Failed to load foreign implementations for module"+            <+> pp x <.> colon)+         4 (vcat $ map pp errs)      ErrorInFile _ x -> ppPrec prec x @@ -238,6 +240,11 @@   src <- getImportSource   ModuleT (raise (NoPatErrors src errs)) +expandPropGuardsError :: ExpandPropGuards.Error -> ModuleM a+expandPropGuardsError err = do+  src <- getImportSource+  ModuleT (raise (ExpandPropGuardsError src err))+ noIncludeErrors :: [NoInc.IncludeError] -> ModuleM a noIncludeErrors errs = do   src <- getImportSource@@ -256,15 +263,8 @@ duplicateModuleName name path1 path2 =   ModuleT (raise (DuplicateModuleName name path1 path2)) -importParamModule :: P.ModName -> ModuleM a-importParamModule x = ModuleT (raise (ImportedParamModule x))--failedToParameterizeModDefs :: P.ModName -> [T.Name] -> ModuleM a-failedToParameterizeModDefs x xs =-  ModuleT (raise (FailedToParameterizeModDefs x xs))--notAParameterizedModule :: P.ModName -> ModuleM a-notAParameterizedModule x = ModuleT (raise (NotAParameterizedModule x))+ffiLoadErrors :: P.ModName -> [FFILoadError] -> ModuleM a+ffiLoadErrors x errs = ModuleT (raise (FFILoadErrors x errs))  -- | Run the computation, and if it caused and error, tag the error -- with the given file.@@ -423,13 +423,17 @@   env <- get   set $! f env -getLoadedMaybe :: P.ModName -> ModuleM (Maybe LoadedModule)+getLoadedMaybe :: P.ModName -> ModuleM (Maybe (LoadedModuleG T.TCTopEntity)) getLoadedMaybe mn = ModuleT $   do env <- get-     return (lookupModule mn env)+     return (lookupTCEntity mn env) +-- | This checks if the given name is loaded---it might refer to either+-- a module or a signature. isLoaded :: P.ModName -> ModuleM Bool-isLoaded mn = isJust <$> getLoadedMaybe mn+isLoaded mn =+  do env <- ModuleT get+     pure (MEnv.isLoaded mn (meLoadedModules env))  loadingImport :: Located P.Import -> ModuleM a -> ModuleM a loadingImport  = loading . FromImport@@ -448,12 +452,12 @@ loading :: ImportSource -> ModuleM a -> ModuleM a loading src m = ModuleT $ do   ro <- ask-  let ro'  = ro { roLoading = src : roLoading ro }+  let new = src : roLoading ro    -- check for recursive modules-  when (src `elem` roLoading ro) (raise (RecursiveModules (roLoading ro')))+  when (src `elem` roLoading ro) (raise (RecursiveModules new)) -  local ro' (unModuleT m)+  local ro { roLoading = new } (unModuleT m)  -- | Get the currently focused import source. getImportSource :: ModuleM ImportSource@@ -463,17 +467,17 @@     is : _ -> return is     _      -> return (FromModule noModuleName) -getIface :: P.ModName -> ModuleM Iface-getIface mn = ($ mn) <$> getIfaces--getIfaces :: ModuleM (P.ModName -> Iface)-getIfaces = doLookup <$> ModuleT get+getIfaces :: ModuleM (Map P.ModName (Either T.ModParamNames Iface))+getIfaces = toMap <$> ModuleT get   where-  doLookup env mn =-    case lookupModule mn env of-      Just lm -> lmInterface lm-      Nothing -> panic "ModuleSystem" ["Interface not available", show (pp mn)]+  toMap env = cvt <$> getLoadedEntities (meLoadedModules env) +  cvt ent =+    case ent of+      ALoadedInterface ifa -> Left (lmData ifa)+      ALoadedFunctor mo -> Right (lmdInterface (lmData mo))+      ALoadedModule mo -> Right (lmdInterface (lmData mo))+ getLoaded :: P.ModName -> ModuleM T.Module getLoaded mn = ModuleT $   do env <- get@@ -481,6 +485,20 @@        Just lm -> return (lmModule lm)        Nothing -> panic "ModuleSystem" ["Module not available", show (pp mn) ] +getAllLoaded :: ModuleM (P.ModName -> Maybe (T.ModuleG (), IfaceG ()))+getAllLoaded = ModuleT+  do env <- get+     pure \nm -> do lm <- lookupModule nm env+                    pure ( (lmModule lm) { T.mName = () }+                         , ifaceForgetName (lmInterface lm)+                         )++getAllLoadedSignatures :: ModuleM (P.ModName -> Maybe T.ModParamNames)+getAllLoadedSignatures = ModuleT+  do env <- get+     pure \nm -> lmData <$> lookupSignature nm env++ getNameSeeds :: ModuleM T.NameSeeds getNameSeeds  = ModuleT (meNameSeeds `fmap` get) @@ -505,28 +523,42 @@   do env <- get      set $! env { meSupply = supply } -unloadModule :: (LoadedModule -> Bool) -> ModuleM ()+unloadModule :: (forall a. LoadedModuleG a -> Bool) -> ModuleM () unloadModule rm = ModuleT $ do   env <- get   set $! env { meLoadedModules = removeLoadedModule rm (meLoadedModules env) }  loadedModule ::-  ModulePath -> Fingerprint -> NamingEnv -> T.Module -> ModuleM ()-loadedModule path fp nameEnv m = ModuleT $ do+  ModulePath ->+  FileInfo ->+  NamingEnv ->+  Maybe ForeignSrc ->+  T.TCTopEntity ->+  ModuleM ()+loadedModule path fi nameEnv fsrc m = ModuleT $ do   env <- get   ident <- case path of              InFile p  -> unModuleT $ io (canonicalizePath p)              InMem l _ -> pure l -  set $! env { meLoadedModules = addLoadedModule path ident fp nameEnv m-                                                        (meLoadedModules env) }+  let newLM =+        case m of+          T.TCTopModule mo -> addLoadedModule path ident fi nameEnv fsrc mo+          T.TCTopSignature x s -> addLoadedSignature path ident fi nameEnv x s -modifyEvalEnv :: (EvalEnv -> E.Eval EvalEnv) -> ModuleM ()-modifyEvalEnv f = ModuleT $ do+  set $! env { meLoadedModules = newLM (meLoadedModules env) }+++modifyEvalEnvM :: Traversable t =>+  (EvalEnv -> E.Eval (t EvalEnv)) -> ModuleM (t ())+modifyEvalEnvM f = ModuleT $ do   env <- get   let evalEnv = meEvalEnv env-  evalEnv' <- inBase $ E.runEval mempty (f evalEnv)-  set $! env { meEvalEnv = evalEnv' }+  tenv <- inBase (E.runEval mempty (f evalEnv))+  traverse (\evalEnv' -> set $! env { meEvalEnv = evalEnv' }) tenv++modifyEvalEnv :: (EvalEnv -> E.Eval EvalEnv) -> ModuleM ()+modifyEvalEnv = fmap runIdentity . modifyEvalEnvM . (fmap Identity .)  getEvalEnv :: ModuleM EvalEnv getEvalEnv  = ModuleT (meEvalEnv `fmap` get)
src/Cryptol/ModuleSystem/Name.hs view
@@ -6,16 +6,15 @@ -- Stability   :  provisional -- Portability :  portable -{-# LANGUAGE Trustworthy #-}- {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE BlockArguments #-}+{-# LANGUAGE RankNTypes #-} -- for the instances of RunM and BaseM {-# LANGUAGE UndecidableInstances #-} @@ -25,12 +24,17 @@   , NameSource(..)   , nameUnique   , nameIdent+  , mapNameIdent   , nameInfo   , nameLoc   , nameFixity   , nameNamespace   , asPrim   , asOrigName+  , nameModPath+  , nameModPathMaybe+  , nameTopModule+  , nameTopModuleMaybe   , ppLocName   , Namespace(..)   , ModPath(..)@@ -38,15 +42,15 @@      -- ** Creation   , mkDeclared-  , mkParameter-  , toParamInstName-  , asParamName-  , paramModRecParam+  , mkLocal+  , asLocal+  , mkModParam      -- ** Unique Supply   , FreshM(..), nextUniqueM-  , SupplyT(), runSupplyT+  , SupplyT(), runSupplyT, runSupply   , Supply(), emptySupply, nextUnique+  , freshNameFor      -- ** PrimMap   , PrimMap(..)@@ -57,6 +61,7 @@ import           Control.DeepSeq import qualified Data.Map as Map import qualified Data.Monoid as M+import           Data.Functor.Identity(runIdentity) import           GHC.Generics (Generic) import           MonadLib import           Prelude ()@@ -66,36 +71,24 @@   -import           Cryptol.Parser.Position (Range,Located(..),emptyRange)+import           Cryptol.Parser.Position (Range,Located(..)) import           Cryptol.Utils.Fixity import           Cryptol.Utils.Ident import           Cryptol.Utils.Panic import           Cryptol.Utils.PP -+data NameInfo = GlobalName NameSource OrigName+              | LocalName Namespace Ident+                deriving (Generic, NFData, Show)  -- Names -------------------------------------------------------------------------- | Information about the binding site of the name.-data NameInfo = Declared !ModPath !NameSource-                -- ^ This name refers to a declaration from this module-              | Parameter-                -- ^ This name is a parameter (function or type)-                deriving (Eq, Show, Generic, NFData)-- data Name = Name { nUnique :: {-# UNPACK #-} !Int                    -- ^ INVARIANT: this field uniquely identifies a name for one                    -- session with the Cryptol library. Names are unique to                    -- their binding site.                   , nInfo :: !NameInfo-                   -- ^ Information about the origin of this name. -                 , nNamespace :: !Namespace--                 , nIdent :: !Ident-                   -- ^ The name of the identifier-                  , nFixity :: !(Maybe Fixity)                    -- ^ The associativity and precedence level of                    --   infix operators.  'Nothing' indicates an@@ -150,7 +143,12 @@   fmtPref og = case getNameFormat og disp of                  UnQualified -> ""                  Qualified q -> modNameToText q-                 NotInScope  -> Text.pack $ show $ pp (ogModule og)+                 NotInScope  ->+                    let m = Text.pack (show (pp (ogModule og)))+                    in+                    case ogSource og of+                      FromModParam q  -> m <> "::" <> Text.pack (show (pp q))+                      _ -> m    -- Note that this assumes that `xs` is `l` and `ys` is `r`   cmpText xs ys =@@ -173,10 +171,13 @@ -- the need for parentheses. ppName :: Name -> Doc ppName nm =-  case asOrigName nm of-    Just og -> pp og-    Nothing -> pp (nameIdent nm)-+  case nInfo nm of+    GlobalName _ og -> pp og+    LocalName _ i   -> pp i+  <.>+  withPPCfg \cfg ->+    if ppcfgShowNameUniques cfg then "_" <.> int (nameUnique nm)+                                else mempty  instance PP Name where   ppPrec _ = ppPrefixName@@ -184,12 +185,12 @@ instance PPName Name where   ppNameFixity n = nameFixity n -  ppInfixName n@Name { .. }-    | isInfixIdent nIdent = ppName n+  ppInfixName n+    | isInfixIdent (nameIdent n) = ppName n     | otherwise           = panic "Name" [ "Non-infix name used infix"-                                         , show nIdent ]+                                         , show (nameIdent n) ] -  ppPrefixName n@Name { .. } = optParens (isInfixIdent nIdent) (ppName n)+  ppPrefixName n = optParens (isInfixIdent (nameIdent n)) (ppName n)   -- | Pretty-print a name with its source location information.@@ -199,14 +200,26 @@ nameUnique :: Name -> Int nameUnique  = nUnique +nameInfo :: Name -> NameInfo+nameInfo = nInfo+ nameIdent :: Name -> Ident-nameIdent  = nIdent+nameIdent n = case nInfo n of+                GlobalName _ og -> ogName og+                LocalName _ i   -> i -nameNamespace :: Name -> Namespace-nameNamespace = nNamespace+mapNameIdent :: (Ident -> Ident) -> Name -> Name+mapNameIdent f n =+  n { nInfo =+        case nInfo n of+          GlobalName x og -> GlobalName x og { ogName = f (ogName og) }+          LocalName x i   -> LocalName x (f i)+    } -nameInfo :: Name -> NameInfo-nameInfo  = nInfo+nameNamespace :: Name -> Namespace+nameNamespace n = case nInfo n of+                    GlobalName _ og -> ogNamespace og+                    LocalName ns _  -> ns  nameLoc :: Name -> Range nameLoc  = nLoc@@ -216,31 +229,43 @@  -- | Primtiives must be in a top level module, at least for now. asPrim :: Name -> Maybe PrimIdent-asPrim Name { .. } =-  case nInfo of-    Declared (TopModule m) _ -> Just $ PrimIdent m $ identText nIdent-    _                        -> Nothing--toParamInstName :: Name -> Name-toParamInstName n =+asPrim n =   case nInfo n of-    Declared m s -> n { nInfo = Declared (apPathRoot paramInstModName m) s }-    Parameter   -> n+    GlobalName _ og+      | TopModule m <- ogModule og, not (ogFromModParam og) ->+        Just $ PrimIdent m $ identText $ ogName og -asParamName :: Name -> Name-asParamName n = n { nInfo = Parameter }+    _ -> Nothing  asOrigName :: Name -> Maybe OrigName-asOrigName nm =-  case nInfo nm of-    Declared p _ ->-      Just OrigName { ogModule    = apPathRoot notParamInstModName  p-                    , ogNamespace = nNamespace nm-                    , ogName      = nIdent nm-                    }-    Parameter    -> Nothing+asOrigName n =+  case nInfo n of+    GlobalName _ og -> Just og+    LocalName {}    -> Nothing +-- | Get the module path for the given name.+nameModPathMaybe :: Name -> Maybe ModPath+nameModPathMaybe n = ogModule <$> asOrigName n +-- | Get the module path for the given name.+-- The name should be a top-level name.+nameModPath :: Name -> ModPath+nameModPath n =+  case nameModPathMaybe n of+    Just p  -> p+    Nothing -> panic "nameModPath" [ "Not a top-level name: ", show n ]+++-- | Get the name of the top-level module that introduced this name.+nameTopModuleMaybe :: Name -> Maybe ModName+nameTopModuleMaybe = fmap topModuleFor . nameModPathMaybe++-- | Get the name of the top-level module that introduced this name.+-- Works only for top-level names (i.e., that have original names)+nameTopModule :: Name -> ModName+nameTopModule = topModuleFor . nameModPath++ -- Name Supply -----------------------------------------------------------------  class Monad m => FreshM m where@@ -271,6 +296,9 @@ runSupplyT :: Monad m => Supply -> SupplyT m a -> m (a,Supply) runSupplyT s (SupplyT m) = runStateT s m +runSupply :: Supply -> (forall m. FreshM m => m a) -> (a,Supply)+runSupply s m = runIdentity (runSupplyT s m)+ instance Monad m => Functor (SupplyT m) where   fmap f (SupplyT m) = SupplyT (fmap f m)   {-# INLINE fmap #-}@@ -315,8 +343,8 @@ emptySupply :: Supply emptySupply  = Supply 0x1000 -- For one such name, see paramModRecParam--- XXX: perhaps we should simply not have such things, but that's the way--- for now.+-- XXX: perhaps we should simply not have such things+-- XXX: do we have these anymore?  nextUnique :: Supply -> (Int,Supply) nextUnique (Supply n) = s' `seq` (n,s')@@ -330,26 +358,77 @@ mkDeclared ::   Namespace -> ModPath -> NameSource -> Ident -> Maybe Fixity -> Range ->   Supply -> (Name,Supply)-mkDeclared nNamespace m sys nIdent nFixity nLoc s =-  let (nUnique,s') = nextUnique s-      nInfo        = Declared m sys-   in (Name { .. }, s')+mkDeclared ns m sys ident fixity loc s = (name, s')+  where+  (u,s') = nextUnique s+  name = Name { nUnique   = u+              , nFixity   = fixity+              , nLoc      = loc+              , nInfo     = GlobalName+                              sys+                              OrigName+                                { ogNamespace = ns+                                , ogModule    = m+                                , ogName      = ident+                                , ogSource    = FromDefinition+                                }+              }  -- | Make a new parameter name.-mkParameter :: Namespace -> Ident -> Range -> Supply -> (Name,Supply)-mkParameter nNamespace nIdent nLoc s =-  let (nUnique,s') = nextUnique s-      nFixity      = Nothing-   in (Name { nInfo = Parameter, .. }, s')+mkLocal :: Namespace -> Ident -> Range -> Supply -> (Name,Supply)+mkLocal ns ident loc s = (name, s')+  where+  (u,s')  = nextUnique s+  name    = Name { nUnique = u+                 , nLoc    = loc+                 , nFixity = Nothing+                 , nInfo   = LocalName ns ident+                 } -paramModRecParam :: Name-paramModRecParam = Name { nInfo = Parameter-                        , nFixity = Nothing-                        , nIdent  = packIdent "$modParams"-                        , nLoc    = emptyRange-                        , nUnique = 0x01-                        , nNamespace = NSValue-                        }+{- | Make a local name derived from the given name.+This is a bit questionable,+but it is used by the translation to SAW Core -}+asLocal :: Namespace -> Name -> Name+asLocal ns x =+  case nameInfo x of+    GlobalName _ og -> x { nInfo = LocalName ns (ogName og) }+    LocalName {}    -> x++mkModParam ::+  ModPath {- ^ Module containing the parameter -} ->+  Ident   {- ^ Name of the module parameter    -} ->+  Range   {- ^ Location                        -} ->+  Name    {- ^ Name in the signature           -} ->+  Supply -> (Name, Supply)+mkModParam own pname rng n s = (name, s')+  where+  (u,s') = nextUnique s+  name = Name { nUnique = u+              , nInfo   = GlobalName+                            UserName+                            OrigName+                              { ogModule    = own+                              , ogName      = nameIdent n+                              , ogNamespace = nameNamespace n+                              , ogSource    = FromModParam pname+                              }+              , nFixity = nFixity n+              , nLoc    = rng+              }++-- | This is used when instantiating functors+freshNameFor :: ModPath -> Name -> Supply -> (Name,Supply)+freshNameFor mpath x s = (newName, s1)+  where+  (u,s1) = nextUnique s+  newName =+    x { nUnique = u+      , nInfo =+          case nInfo x of+            GlobalName src og -> GlobalName src og { ogModule = mpath+                                                   , ogSource = FromFunctorInst }+            LocalName {} -> panic "freshNameFor" ["Unexpected local",show x]+      }  -- Prim Maps ------------------------------------------------------------------- 
+ src/Cryptol/ModuleSystem/Names.hs view
@@ -0,0 +1,88 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE BlockArguments #-}+module Cryptol.ModuleSystem.Names where++import Data.Set(Set)+import qualified Data.Set as Set+import Control.DeepSeq(NFData)+import GHC.Generics (Generic)++import Cryptol.Utils.Panic (panic)+import Cryptol.ModuleSystem.Name+++-- | A non-empty collection of names used by the renamer.+data Names = One Name | Ambig (Set Name) -- ^ Non-empty+  deriving (Show,Generic,NFData)++namesToList :: Names -> [Name]+namesToList xs =+  case xs of+    One x -> [x]+    Ambig ns -> Set.toList ns++anyOne :: Names -> Name+anyOne = head . namesToList++instance Semigroup Names where+  xs <> ys =+    case (xs,ys) of+      (One x, One y)+        | x == y           -> One x+        | otherwise        -> Ambig $! Set.fromList [x,y]+      (One x, Ambig as)    -> Ambig $! Set.insert x as+      (Ambig as, One x)    -> Ambig $! Set.insert x as+      (Ambig as, Ambig bs) -> Ambig $! Set.union as bs++namesFromSet :: Set Name {- ^ Non-empty -} -> Names+namesFromSet xs =+  case Set.minView xs of+    Just (a,ys) -> if Set.null ys then One a else Ambig xs+    Nothing     -> panic "namesFromSet" ["empty set"]++unionManyNames :: [Names] -> Maybe Names+unionManyNames xs =+  case xs of+    [] -> Nothing+    _  -> Just (foldr1 (<>) xs)++mapNames :: (Name -> Name) -> Names -> Names+mapNames f xs =+  case xs of+    One x -> One (f x)+    Ambig as -> namesFromSet (Set.map f as)++filterNames :: (Name -> Bool) -> Names -> Maybe Names+filterNames p names =+  case names of+    One x -> if p x then Just (One x) else Nothing+    Ambig xs -> do let ys = Set.filter p xs+                   (y,zs) <- Set.minView ys+                   if Set.null zs then Just (One y) else Just (Ambig ys)++travNames :: Applicative f => (Name -> f Name) -> Names -> f Names+travNames f xs =+  case xs of+    One x -> One <$> f x+    Ambig as -> namesFromSet . Set.fromList <$> traverse f (Set.toList as)+++-- Names that are in the first but not the second+diffNames :: Names -> Names -> Maybe Names+diffNames x y =+  case x of+    One a ->+      case y of+        One b -> if a == b then Nothing+                           else Just (One a)+        Ambig xs -> if a `Set.member` xs then Nothing else Just (One a)+    Ambig xs ->+      do (a,rest) <- Set.minView ys+         pure if Set.null rest then One a else Ambig xs++      where+      ys = case y of+             One z    -> Set.delete z xs+             Ambig zs -> Set.difference xs zs+
src/Cryptol/ModuleSystem/NamingEnv.hs view
@@ -7,112 +7,119 @@ -- Portability :  portable  {-# LANGUAGE DeriveAnyClass #-}-{-# LANGUAGE DeriveFoldable #-}-{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveTraversable #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE PatternGuards #-}-{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE BlockArguments #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-} -- See Note [-Wincomplete-uni-patterns and irrefutable patterns] in Cryptol.TypeCheck.TypePat {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module Cryptol.ModuleSystem.NamingEnv where -import Data.List (nub)-import Data.Maybe (fromMaybe,mapMaybe,maybeToList)+import Data.Maybe (mapMaybe,maybeToList) import           Data.Map.Strict (Map) import qualified Data.Map.Strict as Map import           Data.Set (Set) import qualified Data.Set as Set-import Data.Semigroup-import MonadLib (runId,Id,StateT,runStateT,lift,sets_,forM_)+import           Data.Foldable(foldl')  import GHC.Generics (Generic)-import Control.DeepSeq--import Prelude ()-import Prelude.Compat+import Control.DeepSeq(NFData)  import Cryptol.Utils.PP import Cryptol.Utils.Panic (panic)+import Cryptol.Utils.Ident(allNamespaces) import Cryptol.Parser.AST-import Cryptol.Parser.Name(isGeneratedName)-import Cryptol.Parser.Position import qualified Cryptol.TypeCheck.AST as T-import Cryptol.ModuleSystem.Interface import Cryptol.ModuleSystem.Name+import Cryptol.ModuleSystem.Names+import Cryptol.ModuleSystem.Interface  --- Naming Environment ----------------------------------------------------------- -- | The 'NamingEnv' is used by the renamer to determine what -- identifiers refer to.-newtype NamingEnv = NamingEnv (Map Namespace (Map PName [Name]))+newtype NamingEnv = NamingEnv (Map Namespace (Map PName Names))   deriving (Show,Generic,NFData) --- | All names mentioned in the environment-namingEnvNames :: NamingEnv -> Set Name-namingEnvNames (NamingEnv xs) =-  Set.fromList $ concatMap (concat . Map.elems) $ Map.elems xs+instance Monoid NamingEnv where+  mempty = NamingEnv Map.empty+  {-# INLINE mempty #-} +instance Semigroup NamingEnv where+  NamingEnv l <> NamingEnv r =+    NamingEnv (Map.unionWith (Map.unionWith (<>)) l r) --- | Get the names in a given namespace-namespaceMap :: Namespace -> NamingEnv -> Map PName [Name]-namespaceMap ns (NamingEnv env) = Map.findWithDefault Map.empty ns env+instance PP NamingEnv where+  ppPrec _ (NamingEnv mps)   = vcat $ map ppNS $ Map.toList mps+    where ppNS (ns,xs) = nest 2 (vcat (pp ns : map ppNm (Map.toList xs)))+          ppNm (x,as)  = pp x <+> "->" <+> commaSep (map pp (namesToList as)) --- | Resolve a name in the given namespace.-lookupNS :: Namespace -> PName -> NamingEnv -> [Name]-lookupNS ns x = Map.findWithDefault [] x . namespaceMap ns --- | Return a list of value-level names to which this parsed name may refer.-lookupValNames :: PName -> NamingEnv -> [Name]-lookupValNames = lookupNS NSValue---- | Return a list of type-level names to which this parsed name may refer.-lookupTypeNames :: PName -> NamingEnv -> [Name]-lookupTypeNames = lookupNS NSType+{- | This "joins" two naming environments by matching the text name.+The result maps the unique names from the first environment with the+matching names in the second.  This is used to compute the naming for+an instantiated functor:+  * if the left environment has the defined names of the functor, and+  * the right one has the defined names of the instantiation, then+  * the result maps functor names to instance names.+-}+zipByTextName :: NamingEnv -> NamingEnv -> Map Name Name+zipByTextName (NamingEnv k) (NamingEnv v) = Map.fromList $ doInter doNS k v+  where+  doInter :: Ord k => (a -> b -> [c]) -> Map k a -> Map k b -> [c]+  doInter f a b = concat (Map.elems (Map.intersectionWith f a b)) --- | Singleton renaming environment for the given namespace.-singletonNS :: Namespace -> PName -> Name -> NamingEnv-singletonNS ns pn n = NamingEnv (Map.singleton ns (Map.singleton pn [n]))+  doNS :: Map PName Names -> Map PName Names -> [(Name,Name)]+  doNS as bs = doInter doPName as bs --- | Singleton expression renaming environment.-singletonE :: PName -> Name -> NamingEnv-singletonE = singletonNS NSValue+  doPName :: Names -> Names -> [(Name,Name)]+  doPName xs ys = [ (x,y) | x <- namesToList xs, y <- namesToList ys ]+  -- NOTE: we'd exepct that there are no ambiguities in the environments. --- | Singleton type renaming environment.-singletonT :: PName -> Name -> NamingEnv-singletonT = singletonNS NSType+-- | Keep only the bindings in the 1st environment that are *NOT* in the second.+without :: NamingEnv -> NamingEnv -> NamingEnv+NamingEnv keep `without` NamingEnv remove = NamingEnv result+  where+  result     = Map.differenceWith rmInNS keep remove+  rmInNS a b = let c = Map.differenceWith diffNames a b+               in if Map.null c then Nothing else Just c +-- | All names mentioned in the environment+namingEnvNames :: NamingEnv -> Set Name+namingEnvNames (NamingEnv xs) =+  case unionManyNames (mapMaybe (unionManyNames . Map.elems) (Map.elems xs)) of+    Nothing -> Set.empty+    Just (One x) -> Set.singleton x+    Just (Ambig as) -> as -namingEnvRename :: (Name -> Name) -> NamingEnv -> NamingEnv-namingEnvRename f (NamingEnv mp) = NamingEnv (ren <$> mp)+-- | Get a unqualified naming environment for the given names+namingEnvFromNames :: Set Name -> NamingEnv+namingEnvFromNames xs = NamingEnv (foldl' add mempty xs)   where-  ren nsm = map f <$> nsm+  add mp x = let ns = nameNamespace x+                 txt = nameIdent x+             in Map.insertWith (Map.unionWith (<>))+                               ns (Map.singleton (mkUnqual txt) (One x))+                               mp  -instance Semigroup NamingEnv where-  NamingEnv l <> NamingEnv r =-      NamingEnv (Map.unionWith (Map.unionWith merge) l r)--instance Monoid NamingEnv where-  mempty = NamingEnv Map.empty-  {-# INLINE mempty #-}+-- | Get the names in a given namespace+namespaceMap :: Namespace -> NamingEnv -> Map PName Names+namespaceMap ns (NamingEnv env) = Map.findWithDefault Map.empty ns env +-- | Resolve a name in the given namespace.+lookupNS :: Namespace -> PName -> NamingEnv -> Maybe Names+lookupNS ns x env = Map.lookup x (namespaceMap ns env) --- | Merge two name maps, collapsing cases where the entries are the same, and--- producing conflicts otherwise.-merge :: [Name] -> [Name] -> [Name]-merge xs ys | xs == ys  = xs-            | otherwise = nub (xs ++ ys)+-- | Resolve a name in the given namespace.+lookupListNS :: Namespace -> PName -> NamingEnv -> [Name]+lookupListNS ns x env =+  case lookupNS ns x env of+    Nothing -> []+    Just as -> namesToList as -instance PP NamingEnv where-  ppPrec _ (NamingEnv mps)   = vcat $ map ppNS $ Map.toList mps-    where ppNS (ns,xs) = pp ns $$ nest 2 (vcat (map ppNm (Map.toList xs)))-          ppNm (x,as)  = pp x <+> "->" <+> commaSep (map pp as)+-- | Singleton renaming environment for the given namespace.+singletonNS :: Namespace -> PName -> Name -> NamingEnv+singletonNS ns pn n = NamingEnv (Map.singleton ns (Map.singleton pn (One n)))  -- | Generate a mapping from 'PrimIdent' to 'Name' for a -- given naming environment.@@ -124,7 +131,8 @@     }   where   fromNS ns = Map.fromList-                [ entry x | xs <- Map.elems (namespaceMap ns env), x <- xs ]+                [ entry x | xs <- Map.elems (namespaceMap ns env)+                          , x <- namesToList xs ]    entry n = case asPrim n of               Just p  -> (p,n)@@ -139,9 +147,9 @@   where   names = Map.fromList             [ (og, qn)-              | ns            <- [ NSValue, NSType, NSModule ]+              | ns            <- allNamespaces               , (pn,xs)       <- Map.toList (namespaceMap ns env)-              , x             <- xs+              , x             <- namesToList xs               , og            <- maybeToList (asOrigName x)               , let qn = case getModName pn of                           Just q  -> Qualified q@@ -154,145 +162,127 @@ -- NOTE: if entries in the NamingEnv would have produced a name clash, -- they will be omitted from the resulting sets. visibleNames :: NamingEnv -> Map Namespace (Set Name)-visibleNames (NamingEnv env) = Set.fromList . mapMaybe check . Map.elems <$> env-  where-  check names =-    case names of-      [name] -> Just name-      _      -> Nothing+visibleNames (NamingEnv env) = check <$> env+  where check mp = Set.fromList [ a | One a <- Map.elems mp ]  -- | Qualify all symbols in a 'NamingEnv' with the given prefix. qualify :: ModName -> NamingEnv -> NamingEnv qualify pfx (NamingEnv env) = NamingEnv (Map.mapKeys toQual <$> env)   where-  -- XXX we don't currently qualify fresh names+  -- We don't qualify fresh names, because they should not be directly+  -- visible to the end users (i.e., they shouldn't really be exported)   toQual (Qual _ n)  = Qual pfx n   toQual (UnQual n)  = Qual pfx n   toQual n@NewName{} = n -filterNames :: (PName -> Bool) -> NamingEnv -> NamingEnv-filterNames p (NamingEnv env) = NamingEnv (Map.filterWithKey check <$> env)-  where check n _ = p n----- | Like mappend, but when merging, prefer values on the lhs.-shadowing :: NamingEnv -> NamingEnv -> NamingEnv-shadowing (NamingEnv l) (NamingEnv r) = NamingEnv (Map.unionWith Map.union l r)+filterPNames :: (PName -> Bool) -> NamingEnv -> NamingEnv+filterPNames p (NamingEnv env) = NamingEnv (Map.mapMaybe checkNS env)+  where+  checkNS nsMap = let new = Map.filterWithKey (\n _ -> p n) nsMap+                  in if Map.null new then Nothing else Just new -travNamingEnv :: Applicative f => (Name -> f Name) -> NamingEnv -> f NamingEnv-travNamingEnv f (NamingEnv mp) =-  NamingEnv <$> traverse (traverse (traverse f)) mp+filterUNames :: (Name -> Bool) -> NamingEnv -> NamingEnv+filterUNames p (NamingEnv env) = NamingEnv (Map.mapMaybe check env)+  where+  check nsMap = let new = Map.mapMaybe (filterNames p) nsMap+                in if Map.null new then Nothing else Just new  -{- | Do somethign in context.  If `Nothing` than we are working with-a local declaration. Otherwise we are at the top-level of the-given module. -}-data InModule a = InModule (Maybe ModPath) a-                  deriving (Functor,Traversable,Foldable,Show)-+-- | Find the ambiguous entries in an environmet.+-- A name is ambiguous if it might refer to multiple entities.+findAmbig :: NamingEnv -> [ [Name] ]+findAmbig (NamingEnv ns) =+  [ Set.toList xs+  | mp <- Map.elems ns+  , Ambig xs <- Map.elems mp+  ] -newTop ::-  FreshM m => Namespace -> ModPath -> PName -> Maybe Fixity -> Range -> m Name-newTop ns m thing fx rng =-  liftSupply (mkDeclared ns m src (getIdent thing) fx rng)-  where src = if isGeneratedName thing then SystemName else UserName+-- | Get the subset of the first environment that shadows something+-- in the second one.+findShadowing :: NamingEnv -> NamingEnv -> [ (PName,Name,[Name]) ]+findShadowing (NamingEnv lhs) rhs =+  [ (p, anyOne xs, namesToList ys)+  | (ns,mp) <- Map.toList lhs+  , (p,xs) <- Map.toList mp+  , Just ys <- [ lookupNS ns p rhs ]+  ] -newLocal :: FreshM m => Namespace -> PName -> Range -> m Name-newLocal ns thing rng = liftSupply (mkParameter ns (getIdent thing) rng)+-- | Do an arbitrary choice for ambiguous names.+-- We do this to continue checking afetr we've reported an ambiguity error.+forceUnambig :: NamingEnv -> NamingEnv+forceUnambig (NamingEnv mp) = NamingEnv (fmap (One . anyOne) <$> mp) -newtype BuildNamingEnv = BuildNamingEnv { runBuild :: SupplyT Id NamingEnv }+-- | Like mappend, but when merging, prefer values on the lhs.+shadowing :: NamingEnv -> NamingEnv -> NamingEnv+shadowing (NamingEnv l) (NamingEnv r) = NamingEnv (Map.unionWith Map.union l r) +mapNamingEnv :: (Name -> Name) -> NamingEnv -> NamingEnv+mapNamingEnv f (NamingEnv mp) = NamingEnv (fmap (mapNames f) <$> mp) -buildNamingEnv :: BuildNamingEnv -> Supply -> (NamingEnv,Supply)-buildNamingEnv b supply = runId $ runSupplyT supply $ runBuild b+travNamingEnv :: Applicative f => (Name -> f Name) -> NamingEnv -> f NamingEnv+travNamingEnv f (NamingEnv mp) =+  NamingEnv <$> traverse (traverse (travNames f)) mp --- | Generate a 'NamingEnv' using an explicit supply.-defsOf :: BindsNames a => a -> Supply -> (NamingEnv,Supply)-defsOf = buildNamingEnv . namingEnv+isEmptyNamingEnv :: NamingEnv -> Bool+isEmptyNamingEnv (NamingEnv mp) = Map.null mp+-- This assumes that we've been normalizing away empty maps, hopefully+-- we've been doing it everywhere.  ------------------------------------------------------------------------------------ Collect definitions of nested modules--type NestedMods = Map Name NamingEnv-type CollectM   = StateT NestedMods (SupplyT Id)--collectNestedModules ::-  NamingEnv -> Module PName -> Supply -> (NestedMods, Supply)-collectNestedModules env m =-  collectNestedModulesDecls env (thing (mName m)) (mDecls m)--collectNestedModulesDecls ::-  NamingEnv -> ModName -> [TopDecl PName] -> Supply -> (NestedMods, Supply)-collectNestedModulesDecls env m ds sup = (mp,newS)+-- | Compute an unqualified naming environment, containing the various module+-- parameters.+modParamsNamingEnv :: T.ModParamNames -> NamingEnv+modParamsNamingEnv T.ModParamNames { .. } =+  NamingEnv $ Map.fromList+    [ (NSValue, Map.fromList $ map fromFu $ Map.keys mpnFuns)+    , (NSType,  Map.fromList $ map fromTS (Map.elems mpnTySyn) +++                               map fromTy (Map.elems mpnTypes))+    ]   where-  s0            = Map.empty-  mpath         = TopModule m-  ((_,mp),newS) = runId $ runSupplyT sup $ runStateT s0 $-                  collectNestedModulesDs mpath env ds--collectNestedModulesDs :: ModPath -> NamingEnv -> [TopDecl PName] -> CollectM ()-collectNestedModulesDs mpath env ds =-  forM_ [ tlValue nm | DModule nm <- ds ] \(NestedModule nested) ->-    do let pname = thing (mName nested)-           name  = case lookupNS NSModule pname env of-                     n : _ -> n -- if a name is ambiguous we may get-                                -- multiple answers, but we just pick one.-                                -- This should be OK, as the error should be-                                -- caught during actual renaming.-                     _   -> panic "collectedNestedModulesDs"-                             [ "Missing definition for " ++ show pname ]-       newEnv <- lift (runBuild (moduleDefs (Nested mpath (nameIdent name)) nested))-       sets_ (Map.insert name newEnv)-       let newMPath = Nested mpath (nameIdent name)-       collectNestedModulesDs newMPath newEnv (mDecls nested)+  toPName n = mkUnqual (nameIdent n) ---------------------------------------------------------------------------------+  fromTy tp = let nm = T.mtpName tp+              in (toPName nm, One nm) +  fromFu f  = (toPName f, One f) +  fromTS ts = (toPName (T.tsName ts), One (T.tsName ts))  -instance Semigroup BuildNamingEnv where-  BuildNamingEnv a <> BuildNamingEnv b = BuildNamingEnv $-    do x <- a-       y <- b-       return (mappend x y)--instance Monoid BuildNamingEnv where-  mempty = BuildNamingEnv (pure mempty)--  mappend = (<>)--  mconcat bs = BuildNamingEnv $-    do ns <- sequence (map runBuild bs)-       return (mconcat ns)-----------------------------------------------------------------------------------+-- | Generate a naming environment from a declaration interface, where none of+-- the names are qualified.+unqualifiedEnv :: IfaceDecls -> NamingEnv+unqualifiedEnv IfaceDecls { .. } =+  mconcat [ exprs, tySyns, ntTypes, absTys, ntExprs, mods, sigs ]+  where+  toPName n = mkUnqual (nameIdent n) +  exprs   = mconcat [ singletonNS NSValue (toPName n) n+                    | n <- Map.keys ifDecls ] --- | Things that define exported names.-class BindsNames a where-  namingEnv :: a -> BuildNamingEnv+  tySyns  = mconcat [ singletonNS NSType (toPName n) n+                    | n <- Map.keys ifTySyns ] -instance BindsNames NamingEnv where-  namingEnv env = BuildNamingEnv (return env)-  {-# INLINE namingEnv #-}+  ntTypes = mconcat [ n+                    | nt <- Map.elems ifNewtypes+                    , let tname = T.ntName nt+                          cname = T.ntConName nt+                    , n  <- [ singletonNS NSType (toPName tname) tname+                            , singletonNS NSValue (toPName cname) cname+                            ]+                    ] -instance BindsNames a => BindsNames (Maybe a) where-  namingEnv = foldMap namingEnv-  {-# INLINE namingEnv #-}+  absTys  = mconcat [ singletonNS NSType (toPName n) n+                    | n <- Map.keys ifAbstractTypes ] -instance BindsNames a => BindsNames [a] where-  namingEnv = foldMap namingEnv-  {-# INLINE namingEnv #-}+  ntExprs = mconcat [ singletonNS NSValue (toPName n) n+                    | n <- Map.keys ifNewtypes ] --- | Generate a type renaming environment from the parameters that are bound by--- this schema.-instance BindsNames (Schema PName) where-  namingEnv (Forall ps _ _ _) = foldMap namingEnv ps-  {-# INLINE namingEnv #-}+  mods    = mconcat [ singletonNS NSModule (toPName n) n+                    | n <- Map.keys ifModules ] +  sigs    = mconcat [ singletonNS NSModule (toPName n) n+                    | n <- Map.keys ifSignatures ]   -- | Adapt the things exported by something to the specific import/open.@@ -309,166 +299,12 @@   -- restrict or hide imported symbols   restricted     | Just (Hiding ns) <- iSpec imp =-       filterNames (\qn -> not (getIdent qn `elem` ns)) public+       filterPNames (\qn -> not (getIdent qn `elem` ns)) public      | Just (Only ns) <- iSpec imp =-       filterNames (\qn -> getIdent qn `elem` ns) public+       filterPNames (\qn -> getIdent qn `elem` ns) public      | otherwise = public   --- | Interpret an import in the context of an interface, to produce a name--- environment for the renamer, and a 'NameDisp' for pretty-printing.-interpImportIface :: Import     {- ^ The import declarations -} ->-                IfaceDecls {- ^ Declarations of imported module -} ->-                NamingEnv-interpImportIface imp = interpImportEnv imp . unqualifiedEnv----- | Generate a naming environment from a declaration interface, where none of--- the names are qualified.-unqualifiedEnv :: IfaceDecls -> NamingEnv-unqualifiedEnv IfaceDecls { .. } =-  mconcat [ exprs, tySyns, ntTypes, absTys, ntExprs, mods ]-  where-  toPName n = mkUnqual (nameIdent n)--  exprs   = mconcat [ singletonE (toPName n) n | n <- Map.keys ifDecls ]-  tySyns  = mconcat [ singletonT (toPName n) n | n <- Map.keys ifTySyns ]-  ntTypes = mconcat [ singletonT (toPName n) n | n <- Map.keys ifNewtypes ]-  absTys  = mconcat [ singletonT (toPName n) n | n <- Map.keys ifAbstractTypes ]-  ntExprs = mconcat [ singletonE (toPName n) n | n <- Map.keys ifNewtypes ]-  mods    = mconcat [ singletonNS NSModule (toPName n) n-                                                | n <- Map.keys ifModules ]---- | Compute an unqualified naming environment, containing the various module--- parameters.-modParamsNamingEnv :: IfaceParams -> NamingEnv-modParamsNamingEnv IfaceParams { .. } =-  NamingEnv $ Map.fromList-    [ (NSValue, Map.fromList $ map fromFu $ Map.keys ifParamFuns)-    , (NSType,  Map.fromList $ map fromTy $ Map.elems ifParamTypes)-    ]-  where-  toPName n = mkUnqual (nameIdent n)--  fromTy tp = let nm = T.mtpName tp-              in (toPName nm, [nm])--  fromFu f  = (toPName f, [f])----data ImportIface = ImportIface Import Iface---- | Produce a naming environment from an interface file, that contains a--- mapping only from unqualified names to qualified ones.-instance BindsNames ImportIface where-  namingEnv (ImportIface imp Iface { .. }) = BuildNamingEnv $-    return (interpImportIface imp ifPublic)-  {-# INLINE namingEnv #-}---- | Introduce the name-instance BindsNames (InModule (Bind PName)) where-  namingEnv (InModule mb b) = BuildNamingEnv $-    do let Located { .. } = bName b-       n <- case mb of-              Just m  -> newTop NSValue m thing (bFixity b) srcRange-              Nothing -> newLocal NSValue thing srcRange -- local fixitiies?--       return (singletonE thing n)---- | Generate the naming environment for a type parameter.-instance BindsNames (TParam PName) where-  namingEnv TParam { .. } = BuildNamingEnv $-    do let range = fromMaybe emptyRange tpRange-       n <- newLocal NSType tpName range-       return (singletonT tpName n)---- | The naming environment for a single module.  This is the mapping from--- unqualified names to fully qualified names with uniques.-instance BindsNames (Module PName) where-  namingEnv m = moduleDefs (TopModule (thing (mName m))) m---moduleDefs :: ModPath -> ModuleG mname PName -> BuildNamingEnv-moduleDefs m Module { .. } = foldMap (namingEnv . InModule (Just m)) mDecls---instance BindsNames (InModule (TopDecl PName)) where-  namingEnv (InModule ns td) =-    case td of-      Decl d           -> namingEnv (InModule ns (tlValue d))-      DPrimType d      -> namingEnv (InModule ns (tlValue d))-      TDNewtype d      -> namingEnv (InModule ns (tlValue d))-      DParameterType d -> namingEnv (InModule ns d)-      DParameterConstraint {} -> mempty-      DParameterFun  d -> namingEnv (InModule ns d)-      Include _        -> mempty-      DImport {}       -> mempty -- see 'openLoop' in the renamer-      DModule m        -> namingEnv (InModule ns (tlValue m))---instance BindsNames (InModule (NestedModule PName)) where-  namingEnv (InModule ~(Just m) (NestedModule mdef)) = BuildNamingEnv $-    do let pnmame = mName mdef-       nm   <- newTop NSModule m (thing pnmame) Nothing (srcRange pnmame)-       pure (singletonNS NSModule (thing pnmame) nm)--instance BindsNames (InModule (PrimType PName)) where-  namingEnv (InModule ~(Just m) PrimType { .. }) =-    BuildNamingEnv $-      do let Located { .. } = primTName-         nm <- newTop NSType m thing primTFixity srcRange-         pure (singletonT thing nm)--instance BindsNames (InModule (ParameterFun PName)) where-  namingEnv (InModule ~(Just ns) ParameterFun { .. }) = BuildNamingEnv $-    do let Located { .. } = pfName-       ntName <- newTop NSValue ns thing pfFixity srcRange-       return (singletonE thing ntName)--instance BindsNames (InModule (ParameterType PName)) where-  namingEnv (InModule ~(Just ns) ParameterType { .. }) = BuildNamingEnv $-    -- XXX: we don't seem to have a fixity environment at the type level-    do let Located { .. } = ptName-       ntName <- newTop NSType ns thing Nothing srcRange-       return (singletonT thing ntName)---- NOTE: we use the same name at the type and expression level, as there's only--- ever one name introduced in the declaration. The names are only ever used in--- different namespaces, so there's no ambiguity.-instance BindsNames (InModule (Newtype PName)) where-  namingEnv (InModule ~(Just ns) Newtype { .. }) = BuildNamingEnv $-    do let Located { .. } = nName-       ntName <- newTop NSType ns thing Nothing srcRange-       -- XXX: the name reuse here is sketchy-       return (singletonT thing ntName `mappend` singletonE thing ntName)---- | The naming environment for a single declaration.-instance BindsNames (InModule (Decl PName)) where-  namingEnv (InModule pfx d) = case d of-    DBind b                 -> namingEnv (InModule pfx b)-    DSignature ns _sig      -> foldMap qualBind ns-    DPragma ns _p           -> foldMap qualBind ns-    DType syn               -> qualType (tsName syn) (tsFixity syn)-    DProp syn               -> qualType (psName syn) (psFixity syn)-    DLocated d' _           -> namingEnv (InModule pfx d')-    DRec {}                 -> panic "namingEnv" [ "DRec" ]-    DPatBind _pat _e        -> panic "namingEnv" ["Unexpected pattern binding"]-    DFixity{}               -> panic "namingEnv" ["Unexpected fixity declaration"]--    where--    mkName ns ln fx = case pfx of-                        Just m  -> newTop ns m (thing ln) fx (srcRange ln)-                        Nothing -> newLocal ns (thing ln) (srcRange ln)--    qualBind ln = BuildNamingEnv $-      do n <- mkName NSValue ln Nothing-         return (singletonE (thing ln) n)--    qualType ln f = BuildNamingEnv $-      do n <- mkName NSType ln f-         return (singletonT (thing ln) n)
src/Cryptol/ModuleSystem/Renamer.hs view
@@ -10,9 +10,10 @@ {-# Language FlexibleInstances #-} {-# Language FlexibleContexts #-} {-# Language BlockArguments #-}+{-# Language OverloadedStrings #-} module Cryptol.ModuleSystem.Renamer (     NamingEnv(), shadowing-  , BindsNames(..), InModule(..)+  , BindsNames, InModule(..)   , shadowNames   , Rename(..), runRenamer, RenameM()   , RenamerError(..)@@ -30,154 +31,301 @@ import Prelude.Compat  import Data.Either(partitionEithers)-import Data.Maybe(fromJust)-import Data.List(find,foldl')+import Data.Maybe(mapMaybe)+import Data.List(find,groupBy,sortBy)+import Data.Function(on) import Data.Foldable(toList)-import Data.Map.Strict(Map)+import Data.Map(Map) import qualified Data.Map.Strict as Map import qualified Data.Set as Set import Data.Graph(SCC(..)) import Data.Graph.SCC(stronglyConnComp)-import           MonadLib hiding (mapM, mapM_)+import MonadLib hiding (mapM, mapM_)   import Cryptol.ModuleSystem.Name+import Cryptol.ModuleSystem.Names import Cryptol.ModuleSystem.NamingEnv import Cryptol.ModuleSystem.Exports-import Cryptol.Parser.Position(getLoc)+import Cryptol.Parser.Position(Range) import Cryptol.Parser.AST import Cryptol.Parser.Selector(selName) import Cryptol.Utils.Panic (panic) import Cryptol.Utils.RecordMap-import Cryptol.Utils.Ident(allNamespaces,packModName)+import Cryptol.Utils.Ident(allNamespaces,OrigName(..),modPathCommon,+                              undefinedModName)+import Cryptol.Utils.PP  import Cryptol.ModuleSystem.Interface import Cryptol.ModuleSystem.Renamer.Error+import Cryptol.ModuleSystem.Binds import Cryptol.ModuleSystem.Renamer.Monad+import Cryptol.ModuleSystem.Renamer.Imports+import Cryptol.ModuleSystem.Renamer.ImplicitImports  +{-+The Renamer Algorithm+=====================++1. Add implicit imports for visible nested modules++2. Compute what each module defines   (see "Cryptol.ModuleSystem.Binds")+  - This assigns unique names to names introduces by various declarations+  - Here we detect repeated top-level definitions in a module.+  - Module instantiations also get a name, but are not yet resolved, so+    we don't know what's defined by them.+  - We do not generate unique names for functor parameters---those will+    be matched textually to the arguments when applied.+  - We *do* generate unique names for declarations in "signatures"+    * those are only really needed when renaming the signature (step 4)+      (e.g., to determine if a name refers to something declared in the+      signature or something else).+    * when validating a module against a signature the names of the declarations+      are matched textually, *not* using the unique names+      (e.g., `x` in a signature is matched with the thing named `x` in a module,+       even though these two `x`s will have different unique `id`s)+++3. Resolve imports and instantiations (see "Cryptol.ModuleSystem.Imports")+  - Resolves names in submodule imports+  - Resolves functor instantiations:+    * generate new names for declarations in the functors.+    * this includes any nested modules, and things nested within them.+  - At this point we have enough information to know what's exported by+    each module.++4. Do the renaming (this module)+  - Using step 3 we compute the scoping environment for each module/signature+  - We traverse all declarations and replace the parser names with the+    corresponding names in scope:+    * Here we detect ambiguity and undefined errors+    * During this pass is also where we keep track of information of what+      names are used by declarations:+      - this is used to compute the dependencies between declarations+      - which are in turn used to order the declarations in dependency order+        * this is assumed by the TC+        * here we also report errors about invalid recursive dependencies+    * During this stage we also issue warning about unused type names+      (and we should probably do unused value names too one day)+  - During the rewriting we also do:+    - rebalance expression trees using the operator fixities+    - desugar record update notation+-}+++-- | The result of renaming a module data RenamedModule = RenamedModule   { rmModule   :: Module Name     -- ^ The renamed module   , rmDefines  :: NamingEnv       -- ^ What this module defines   , rmInScope  :: NamingEnv       -- ^ What's in scope in this module-  , rmImported :: IfaceDecls      -- ^ Imported declarations+  , rmImported :: IfaceDecls+    -- ^ Imported declarations.  This provides the types for external+    -- names (used by the type-checker).   } +-- | Entry point. This is used for renaming a top-level module. renameModule :: Module PName -> RenameM RenamedModule renameModule m0 =-  do let m = m0 { mDecls = snd (addImplicitNestedImports (mDecls m0)) }-     env      <- liftSupply (defsOf m)-     nested   <- liftSupply (collectNestedModules env m)-     setNestedModule (nestedModuleNames nested)-       do (ifs,(inScope,m1)) <- collectIfaceDeps-                 $ renameModule' nested env (TopModule (thing (mName m))) m+  do -- Step 1: add implicit imports+     let m = m0 { mDef =+                    case mDef m0 of+                      NormalModule ds ->+                        NormalModule (addImplicitNestedImports ds)+                      FunctorInstance f as i -> FunctorInstance f as i+                      InterfaceModule s -> InterfaceModule s+                 }++     -- Step 2: compute what's defined+     (defs,errs) <- liftSupply (modBuilder (topModuleDefs m))+     mapM_ recordError errs++     -- Step 3: resolve imports+     extern       <- getExternal+     resolvedMods <- liftSupply (resolveImports extern defs)++     let pathToName = Map.fromList [ (Nested (nameModPath x) (nameIdent x), x)+                                   | ImpNested x <- Map.keys resolvedMods ]+++     let mname = ImpTop (thing (mName m))++     setResolvedLocals resolvedMods $+       setNestedModule pathToName+       do (ifs,(inScope,m1)) <- collectIfaceDeps (renameModule' mname m)+          env <- rmodDefines <$> lookupResolved mname           pure RenamedModule                  { rmModule = m1                  , rmDefines = env                  , rmInScope = inScope                  , rmImported = ifs-                -- XXX: maybe we should keep the nested defines too?+                  -- XXX: maybe we should keep the nested defines too?                  } +++++{- | Entry point. Rename a list of top-level declarations.+This is used for declaration that don't live in a module+(e.g., define on the command line.)++We assume that these declarations do not contain any nested modules.+-} renameTopDecls ::   ModName -> [TopDecl PName] -> RenameM (NamingEnv,[TopDecl Name]) renameTopDecls m ds0 =-  do let ds = snd (addImplicitNestedImports ds0)-     let mpath = TopModule m-     env    <- liftSupply (defsOf (map (InModule (Just mpath)) ds))-     nested <- liftSupply (collectNestedModulesDecls env m ds) -     setNestedModule (nestedModuleNames nested)-       do ds1 <- shadowNames' CheckOverlap env-                                        (renameTopDecls' (nested,mpath) ds)-          -- record a use of top-level names to avoid-          -- unused name warnings-          let exports = concatMap exportedNames ds1-          mapM_ recordUse (foldMap (exported NSType) exports)+  do -- Step 1: add implicit imports+     let ds = addImplicitNestedImports ds0 -          pure (env,ds1)+     -- Step 2: compute what's defined+     (defs,errs) <- liftSupply (modBuilder (topDeclsDefs (TopModule m) ds))+     mapM_ recordError errs --- | Returns declarations with additional imports and the public module names--- of this module and its children-addImplicitNestedImports ::-  [TopDecl PName] -> ([[Ident]], [TopDecl PName])-addImplicitNestedImports decls = (concat exportedMods, concat newDecls ++ other)-  where-  (mods,other)            = foldr classify ([], []) decls-  (newDecls,exportedMods) = unzip (map processModule mods)-  processModule m =-    let NestedModule m1 = tlValue m-        (childExs, ds1) = addImplicitNestedImports (mDecls m1)-        mname           = getIdent (thing (mName m1))-        imps            = map (mname :) ([] : childExs)-        isToName is     = case is of-                            [i] -> mkUnqual i-                            _   -> mkQual (isToQual (init is)) (last is)-        isToQual is     = packModName (map identText is)-        mkImp xs        = DImport-                          Located-                            { srcRange = srcRange (mName m1)-                            , thing = Import-                                        { iModule = ImpNested (isToName xs)-                                        , iAs     = Just (isToQual xs)-                                        , iSpec   = Nothing-                                        }-                            }-    in ( DModule m { tlValue = NestedModule m1 { mDecls = ds1 } }-       : map mkImp imps-       , case tlExport m of-           Public  -> imps-           Private -> []-       )+     -- Step 3: resolve imports+     extern       <- getExternal+     resolvedMods <- liftSupply (resolveImports extern (TopMod m defs)) +     let pathToName = Map.fromList [ (Nested (nameModPath x) (nameIdent x), x)+                                   | ImpNested x <- Map.keys resolvedMods ] -  classify d (ms,ds) =-    case d of-      DModule tl -> (tl : ms, ds)-      _          -> (ms, d : ds) +     setResolvedLocals resolvedMods $+      setNestedModule pathToName+      do env    <- rmodDefines <$> lookupResolved (ImpTop m) -nestedModuleNames :: NestedMods -> Map ModPath Name-nestedModuleNames mp = Map.fromList (map entry (Map.keys mp))-  where-  entry n = case nameInfo n of-              Declared p _ -> (Nested p (nameIdent n),n)-              _ -> panic "nestedModuleName" [ "Not a top-level name" ]+         -- we already checked for duplicates in Step 2+         ds1 <- shadowNames' CheckNone env (renameTopDecls' ds)+         -- record a use of top-level names to avoid+         -- unused name warnings+         let exports = exportedDecls ds1+         mapM_ recordUse (exported NSType exports) +         pure (env,ds1) +--------------------------------------------------------------------------------+-- Stuff below is related to Step 4 of the algorithm.++ class Rename f where   rename :: f PName -> RenameM (f Name)  --- | Returns:+-- | This is used for both top-level and nested modules.+-- Returns: -----    * Interfaces for imported things,---    * Things defines in the module+--    * Things defined in the module --    * Renamed module renameModule' ::-  NestedMods -> NamingEnv -> ModPath -> ModuleG mname PName ->+  ImpName Name {- ^ Resolved name for this module -} ->+  ModuleG mname PName ->   RenameM (NamingEnv, ModuleG mname Name)-renameModule' thisNested env mpath m =-  setCurMod mpath-  do (moreNested,imps) <- mconcat <$> mapM doImport (mImports m)-     let allNested = Map.union moreNested thisNested-         openDs    = map thing (mSubmoduleImports m)-         allImps   = openLoop allNested env openDs imps+renameModule' mname m =+  setCurMod+    case mname of+      ImpTop r    -> TopModule r+      ImpNested r -> Nested (nameModPath r) (nameIdent r) -     (inScope,decls') <--        shadowNames' CheckNone allImps $-        shadowNames' CheckOverlap env $-                          -- maybe we should allow for a warning-                          -- if a local name shadows an imported one?-        do inScope <- getNamingEnv-           ds      <- renameTopDecls' (allNested,mpath) (mDecls m)-           pure (inScope, ds)-     let m1      = m { mDecls = decls' }-         exports = modExports m1-     mapM_ recordUse (exported NSType exports)-     return (inScope, m1)+  do resolved <- lookupResolved mname+     shadowNames' CheckNone (rmodImports resolved) +       case mDef m of +         NormalModule ds ->+            do let env = rmodDefines resolved+               (paramEnv,params) <-+                   shadowNames' CheckNone env+                      (doModParams (mModParams m))++               -- we check that defined names and ones that came+               -- from parameters do not clash, as this would be+               -- very confusing.+               shadowNames' CheckOverlap (env <> paramEnv) $+                  setModParams params+                  do ds1 <- renameTopDecls' ds+                     let exports = exportedDecls ds1+                     mapM_ recordUse (exported NSType exports)+                     inScope <- getNamingEnv+                     pure (inScope, m { mDef = NormalModule ds1 })++         -- The things defined by this module are the *results*+         -- of the instantiation, so we should *not* add them+         -- in scope when resolving.+         FunctorInstance f as _ ->+           do f'  <- rnLocated rename f+              as' <- rename as+              checkFunctorArgs as'++              let l = Just (srcRange f')+              imap <- mkInstMap l mempty (thing f') mname++              {- Now we need to compute what's "in scope" of the instantiated+              module.  This is used when the module is loaded at the command+              line and users want to evalute things in the context of the+              module -}+              fuEnv <- if isFakeName (thing f')+                          then pure mempty+                          else lookupDefines (thing f')+              let ren x = Map.findWithDefault x x imap++              -- XXX: This is not quite right as it only considers the things+              -- defined in the module to be in scope.  It misses things+              -- that are *imported* by the functor, in particular the Cryptol+              -- library+              -- is missing.  See #1455.+              inScope <- shadowNames' CheckNone (mapNamingEnv ren fuEnv)+                         getNamingEnv++              pure (inScope, m { mDef = FunctorInstance f' as' imap })++         InterfaceModule s ->+           shadowNames' CheckNone (rmodDefines resolved)+             do d <- InterfaceModule <$> renameIfaceModule mname s+                inScope <- getNamingEnv+                pure (inScope, m { mDef = d })+++checkFunctorArgs :: ModuleInstanceArgs Name -> RenameM ()+checkFunctorArgs args =+  case args of+    DefaultInstAnonArg {} ->+      panic "checkFunctorArgs" ["Nested DefaultInstAnonArg"]+    DefaultInstArg l -> checkArg l+    NamedInstArgs as -> mapM_ checkNamedArg as+  where+  checkNamedArg (ModuleInstanceNamedArg _ l) = checkArg l++  checkArg l =+      case thing l of+        ModuleArg m+          | isFakeName m -> pure ()+          | otherwise    -> checkIsModule (srcRange l) m AModule+        ParameterArg {} -> pure () -- we check these in the type checker+        AddParams -> pure ()++mkInstMap :: Maybe Range -> Map Name Name -> ImpName Name -> ImpName Name ->+  RenameM (Map Name Name)+mkInstMap checkFun acc0 ogname iname+  | isFakeName ogname = pure Map.empty+  | otherwise =+  do case checkFun of+       Nothing -> pure ()+       Just r  -> checkIsModule r ogname AFunctor+     (onames,osubs) <- lookupDefinesAndSubs ogname+     inames         <- lookupDefines iname+     let mp   = zipByTextName onames inames+         subs = [ (ImpNested k, ImpNested v)+                | k <- Set.toList osubs, Just v <- [Map.lookup k mp]+                ]+     foldM doSub (Map.union mp acc0) subs++  where+  doSub acc (k,v) = mkInstMap Nothing acc k v++++-- | This is used to rename local declarations (e.g. `where`) renameDecls :: [Decl PName] -> RenameM [Decl Name] renameDecls ds =   do (ds1,deps) <- depGroup (traverse rename ds)@@ -192,14 +340,37 @@              CyclicSCC ds_xs ->                let (rds,xs) = unzip ds_xs                in case mapM validRecursiveD rds of-                    Nothing -> do record (InvalidDependency xs)+                    Nothing -> do recordError (InvalidDependency xs)                                   pure rds                     Just bs ->                       do checkSameModule xs                          pure [DRec bs]      concat <$> mapM fromSCC ordered +-- | Rename declarations in a signature (i.e., type/prop synonyms)+renameSigDecls :: [SigDecl PName] -> RenameM [SigDecl Name]+renameSigDecls ds =+  do (ds1,deps) <- depGroup (traverse rename ds)+     let toNode d = let nm = case d of+                               SigTySyn ts _   -> thing (tsName ts)+                               SigPropSyn ps _ -> thing (psName ps)+                        x = NamedThing nm+                    in ((d,x), x, map NamedThing+                            $ Set.toList+                            $ Map.findWithDefault Set.empty x deps)+         ordered = toList (stronglyConnComp (map toNode ds1))+         fromSCC x =+           case x of+             AcyclicSCC (d,_) -> pure [d]+             CyclicSCC ds_xs ->+               do let (rds,xs) = unzip ds_xs+                  recordError (InvalidDependency xs)+                  pure rds +     concat <$> mapM fromSCC ordered+++ validRecursiveD :: Decl name -> Maybe (Bind name) validRecursiveD d =   case d of@@ -212,24 +383,128 @@   case ms of     a : as | let bad = [ fst b | b <- as, snd a /= snd b ]            , not (null bad) ->-              record $ InvalidDependency $ map NamedThing $ fst a : bad+              recordError (InvalidDependency $ map NamedThing $ fst a : bad)     _ -> pure ()   where-  ms = [ (x,p) | NamedThing x <- xs, Declared p _ <- [ nameInfo x ] ]+  ms = [ (x,ogModule og)+       | NamedThing x <- xs, GlobalName _ og <- [ nameInfo x ]+       ]  -renameTopDecls' ::-  (NestedMods,ModPath) -> [TopDecl PName] -> RenameM [TopDecl Name]-renameTopDecls' info ds =-  do (ds1,deps) <- depGroup (traverse (renameWithMods info) ds) +{- NOTE: Dependencies on Top Level Constraints+   =========================================== -     let (noNameDs,nameDs) = partitionEithers (map topDeclName ds1)-         ctrs = [ nm | (_,nm@(ConstratintAt {})) <- nameDs ]-         toNode (d,x) = ((d,x),x, (if usesCtrs d then ctrs else []) ++-                               map NamedThing-                             ( Set.toList-                             ( Map.findWithDefault Set.empty x deps) ))+For the new module system, things using a parameter depend on the parameter+declaration (i.e., `import signature`), which depends on the signature,+so dependencies on constraints in there should be OK.++However, we'd like to have a mechanism for declaring top level constraints in+a functor, that can impose constraints across types from *different*+parameters.  For the moment, we reuse `parameter type constraint C` for this.++Such constraints need to be:+  1. After the signature import+  2. After any type synonyms/newtypes using the parameters+  3. Before any value or type declarations that need to use the parameters.++Note that type declarations used by a constraint cannot use the constraint,+so they need to be well formed without it.++For other types, we use the following rule to determine if they use a+constraint:++  If:+    1. We have a constraint and type declaration+    2. They both mention the same type parameter+    3. There is no explicit dependency of the constraint on the DECL+  Then:+    The type declaration depends on the constraint.++Example:++  type T = 10             // Does not depend on anything so can go first++  signature A where+    type n : #++  import signature A     // Depends on A, so need to be after A++  parameter type constraint n > T+                        // Depends on the import (for @n@) and T++  type Q = [n-T]        // Depends on the top-level constraint+-}++++-- This assumes imports have already been processed+renameTopDecls' :: [TopDecl PName] -> RenameM [TopDecl Name]+renameTopDecls' ds =+  do -- rename and compute what names we depend on+     (ds1,deps) <- depGroup (traverse rename ds)++     fromParams <- getNamesFromModParams+     localParams <- getLocalModParamDeps++     let rawDepsFor x = Map.findWithDefault Set.empty x deps++         isTyParam x = nameNamespace x == NSType && x `Map.member` fromParams+++         (noNameDs,nameDs) = partitionEithers (map topDeclName ds1)+         ctrs = [ nm | (_,nm@(ConstratintAt {}),_) <- nameDs ]+         indirect = Map.fromList [ (y,x)+                                 | (_,x,ys) <- nameDs, y <- ys ]+         mkDepName x = case Map.lookup x fromParams of+                         Just dn -> dn+                         Nothing -> NamedThing x+         depsFor x =+           [ Map.findWithDefault (mkDepName y) (NamedThing y) indirect+           | y <- Set.toList (Map.findWithDefault Set.empty x deps)+           ]++         {- See [NOTE: Dependencies on Top Level Constraints] -}+         addCtr nm ctr =+            case nm of+              NamedThing x+                | nameNamespace x == NSType+                , let ctrDeps = rawDepsFor ctr+                      tyDeps  = rawDepsFor nm+                , not (x `Set.member` ctrDeps)+                , not (Set.null (Set.intersection+                                      (Set.filter isTyParam ctrDeps)+                                      (Set.filter isTyParam tyDeps)))+                  -> Just ctr+              _ -> Nothing++         addCtrs (d,x)+          | usesCtrs d = ctrs+          | otherwise  = mapMaybe (addCtr x) ctrs++         addModParams d =+           case d of+             DModule tl | NestedModule m <- tlValue tl+                        , FunctorInstance _ as _ <- mDef m ->+               case as of+                  DefaultInstArg arg -> depsOfArg arg+                  NamedInstArgs args -> concatMap depsOfNamedArg args+                  DefaultInstAnonArg {} -> []++               where depsOfNamedArg (ModuleInstanceNamedArg _ a) = depsOfArg a+                     depsOfArg a = case thing a of+                                     AddParams -> []+                                     ModuleArg {} -> []+                                     ParameterArg p ->+                                       case Map.lookup p localParams of+                                         Just i -> [i]+                                         Nothing -> []+             _ -> []++         toNode (d,x,_) = ((d,x),x, addCtrs (d,x) +++                                    addModParams d +++                                    depsFor x)+          ordered = stronglyConnComp (map toNode nameDs)          fromSCC x =             case x of@@ -237,7 +512,7 @@               CyclicSCC ds_xs ->                 let (rds,xs) = unzip ds_xs                 in case mapM valid rds of-                     Nothing -> do record (InvalidDependency xs)+                     Nothing -> do recordError (InvalidDependency xs)                                    pure rds                      Just bs ->                        do checkSameModule xs@@ -253,36 +528,49 @@      rds <- mapM fromSCC ordered      pure (concat (noNameDs:rds))   where++  -- This indicates if a declaration might depend on the constraints in scope.+  -- Since uses of constraints are not implicitly named, value declarations+  -- are assumed to potentially use the constraints.++  -- XXX: This is inaccurate, and *I think* it amounts to checking that something+  -- is in the value namespace.   Perhaps the rule should be that a value+  -- depends on a parameter constraint if it mentions at least one+  -- type parameter somewhere.++  -- XXX: Besides, types might need constraints for well-formedness...+  -- This is just bogus+  -- Although not that type/prop synonyms may be defined wherever as they+  -- keep the validity constraints they need and emit them at the *use* sites.   usesCtrs td =     case td of       Decl tl                 -> isValDecl (tlValue tl)       DPrimType {}            -> False       TDNewtype {}            -> False-      DParameterType {}       -> False-      DParameterConstraint {} -> False--      DParameterFun {}        -> True-      -- Here we may need the constraints to validate the type-      -- (e.g., if the parameter is of type `Z a`)+      DParamDecl {}           -> False+      DInterfaceConstraint {} -> False         DModule tl              -> any usesCtrs (mDecls m)         where NestedModule m = tlValue tl       DImport {}              -> False+      DModParam {}            -> False    -- no definitions here       Include {}              -> bad "Include"    isValDecl d =     case d of       DLocated d' _ -> isValDecl d'       DBind {}      -> True+      DRec {}       -> True+       DType {}      -> False       DProp {}      -> False-      DRec {}       -> True-      DSignature {} -> bad "DSignature"-      DFixity {}    -> bad "DFixity"-      DPragma {}    -> bad "DPragma"-      DPatBind {}   -> bad "DPatBind" +      DSignature {}       -> bad "DSignature"+      DFixity {}          -> bad "DFixity"+      DPragma {}          -> bad "DPragma"+      DPatBind {}         -> bad "DPatBind"+   bad msg = panic "renameTopDecls'" [msg]  @@ -302,172 +590,243 @@   where   bad x = panic "declName" [x] -topDeclName :: TopDecl Name -> Either (TopDecl Name) (TopDecl Name, DepName)+topDeclName ::+  TopDecl Name ->+  Either (TopDecl Name) (TopDecl Name, DepName, [DepName]) topDeclName topDecl =   case topDecl of     Decl d                  -> hasName (declName (tlValue d))     DPrimType d             -> hasName (thing (primTName (tlValue d)))-    TDNewtype d             -> hasName (thing (nName (tlValue d)))-    DParameterType d        -> hasName (thing (ptName d))-    DParameterFun d         -> hasName (thing (pfName d))+    TDNewtype d             -> hasName' (thing (nName (tlValue d)))+                                        [ nConName (tlValue d) ]     DModule d               -> hasName (thing (mName m))       where NestedModule m = tlValue d -    DParameterConstraint ds ->-      case ds of-        []  -> noName-        _   -> Right (topDecl, ConstratintAt (fromJust (getLoc ds)))+    DInterfaceConstraint _ ds -> special (ConstratintAt (srcRange ds))+     DImport {}              -> noName +    DModParam m             -> special (ModParamName (srcRange (mpSignature m))+                                                     (mpName m))+     Include {}              -> bad "Include"+    DParamDecl {}           -> bad "DParamDecl"   where   noName    = Left topDecl-  hasName n = Right (topDecl, NamedThing n)+  hasName n = hasName' n []+  hasName' n ms = Right (topDecl, NamedThing n, map NamedThing ms)+  special x = Right (topDecl, x, [])   bad x     = panic "topDeclName" [x]  --- | Returns:---  * The public interface of the imported module---  * Infromation about nested modules in this module---  * New names introduced through this import-doImport :: Located Import -> RenameM (NestedMods, NamingEnv)-doImport li =-  do let i = thing li-     decls <- lookupImport i-     let declsOf = unqualifiedEnv . ifPublic-         nested  = declsOf <$> ifModules decls-     pure (nested, interpImportIface i decls)  +{- | Compute the names introduced by a module parameter.+This should be run in a context containing everything that's in scope+except for the module parameters.  We don't need to compute a fixed point here+because the signatures (and hence module parameters) cannot contain signatures. ------------------------------------------------------------------------------------ Compute names coming through `open` statements.+The resulting naming environment contains the new names introduced by this+parameter.+-}+doModParam ::+  ModParam PName ->+  RenameM (NamingEnv, RenModParam)+doModParam mp =+  do let sigName = mpSignature mp+         loc     = srcRange sigName+     withLoc loc+       do me <- getCurMod -data OpenLoopState = OpenLoopState-  { unresolvedOpen  :: [ImportG PName]-  , scopeImports    :: NamingEnv    -- names from open/impot-  , scopeDefs       :: NamingEnv    -- names defined in this module-  , scopingRel      :: NamingEnv    -- defs + imports with shadowing-                                    -- (just a cache)-  , openLoopChange  :: Bool-  }+          (sigName',isFake) <-+             case thing sigName of+               ImpTop t -> pure (ImpTop t, False)+                -- XXX: should we record a dependency here?+                -- Not sure what the dependencies are for.. --- | Processing of a single @open@ declaration-processOpen :: NestedMods -> OpenLoopState -> ImportG PName -> OpenLoopState-processOpen modEnvs s o =-  case lookupNS NSModule (iModule o) (scopingRel s) of-    []  -> s { unresolvedOpen = o : unresolvedOpen s }-    [n] ->-      case Map.lookup n modEnvs of-        Nothing  -> panic "openLoop" [ "Missing defintion for module", show n ]-        Just def ->-          let new = interpImportEnv o def-              newImps = new <> scopeImports s-          in s { scopeImports   = newImps-               , scopingRel     = scopeDefs s `shadowing` newImps-               , openLoopChange = True-               }-    _ -> s-    {- Notes:-       * ambiguity will be reported later when we do the renaming-       * assumes scoping only grows, which should be true-       * we are not adding the names from *either* of the imports-         so this may give rise to undefined names, so we may want to-         suppress reporing undefined names if there ambiguities for-         module names.  Alternatively we could add the defitions from-         *all* options, but that might lead to spurious ambiguity errors.-    -}+               ImpNested n ->+                 do mb <- resolveNameMaybe NameUse NSModule n+                    (nm,isFake) <- case mb of+                                     Just rnm -> pure (rnm,False)+                                     Nothing ->+                                       do rnm <- reportUnboundName NSModule n+                                          pure (rnm,True)+                    case modPathCommon me (nameModPath nm) of+                      Just (_,[],_) ->+                        recordError+                           (InvalidDependency [ModPath me, NamedThing nm])+                      _ -> pure ()+                    pure (ImpNested nm, isFake) -{- | Complete the set of import using @open@ declarations.-This should terminate because on each iteration either @unresolvedOpen@-decreases or @openLoopChange@ remians @False@. We don't report errors-here, as they will be reported during renaming anyway. -}-openLoop ::-  NestedMods      {- ^ Definitions of all known nested modules  -} ->-  NamingEnv       {- ^ Definitions of the module (these shadow) -} ->-  [ImportG PName] {- ^ Open declarations                        -} ->-  NamingEnv       {- ^ Imported declarations                    -} ->-  NamingEnv       {- ^ Completed imports                        -}-openLoop modEnvs defs os imps =-  scopingRel $ loop OpenLoopState-                      { unresolvedOpen = os-                      , scopeImports   = imps-                      , scopeDefs      = defs-                      , scopingRel     = defs `shadowing` imps-                      , openLoopChange = True-                      }-  where-  loop s-    | openLoopChange s =-      loop $ foldl' (processOpen modEnvs)-                    s { unresolvedOpen = [], openLoopChange = False }-                    (unresolvedOpen s)-    | otherwise = s+          unless isFake+            (checkIsModule (srcRange sigName) sigName' ASignature)+          sigEnv <- if isFake then pure mempty else lookupDefines sigName'  +          {- XXX: It seems a bit odd to use "newModParam" for the names to+             be used for the instantiated type synonyms,+             but what other name could we use? -}+          let newP x = do y <- lift (newModParam me (mpName mp) loc x)+                          sets_ (Map.insert y x)+                          pure y+          (newEnv',nameMap) <- runStateT Map.empty (travNamingEnv newP sigEnv)+          let paramName = mpAs mp+          let newEnv = case paramName of+                         Nothing -> newEnv'+                         Just q  -> qualify q newEnv'+          pure ( newEnv+               , RenModParam+                 { renModParamName     = mpName mp+                 , renModParamRange    = loc+                 , renModParamSig      = sigName'+                 , renModParamInstance = nameMap+                 }+               )++{- | Process the parameters of a module.+Should be executed in a context where everything's already in the context,+except the module parameters.+-}+doModParams :: [ModParam PName] -> RenameM (NamingEnv, [RenModParam])+doModParams srcParams =+  do (paramEnvs,params) <- unzip <$> mapM doModParam  srcParams++     let repeated = groupBy ((==) `on` renModParamName)+                  $ sortBy (compare `on` renModParamName) params++     forM_ repeated \ps ->+       case ps of+         [_]      -> pure ()+         ~(p : _) -> recordError (MultipleModParams (renModParamName p)+                                                    (map renModParamRange ps))++     pure (mconcat paramEnvs,params)++++ -------------------------------------------------------------------------------- +rnLocated :: (a -> RenameM b) -> Located a -> RenameM (Located b)+rnLocated f loc = withLoc loc $+  do a' <- f (thing loc)+     return loc { thing = a' } -data WithMods f n = WithMods (NestedMods,ModPath) (f n) -forgetMods :: WithMods f n -> f n-forgetMods (WithMods _ td) = td -renameWithMods ::-  Rename (WithMods f) => (NestedMods,ModPath) -> f PName -> RenameM (f Name)-renameWithMods info m = forgetMods <$> rename (WithMods info m)  -instance Rename (WithMods TopDecl) where-  rename (WithMods info td) = WithMods info <$>++instance Rename TopDecl where+  rename td =     case td of-      Decl d      -> Decl      <$> traverse rename d-      DPrimType d -> DPrimType <$> traverse rename d-      TDNewtype n -> TDNewtype <$> traverse rename n-      Include n   -> return (Include n)-      DParameterFun f  -> DParameterFun  <$> rename f-      DParameterType f -> DParameterType <$> rename f+      Decl d            -> Decl      <$> traverse rename d+      DPrimType d       -> DPrimType <$> traverse rename d+      TDNewtype n       -> TDNewtype <$> traverse rename n+      Include n         -> return (Include n)+      DModule m  -> DModule <$> traverse rename m+      DImport li -> DImport <$> renI li+      DModParam mp -> DModParam <$> rename mp+      DInterfaceConstraint d ds ->+        depsOf (ConstratintAt (srcRange ds))+        (DInterfaceConstraint d <$> rnLocated (mapM rename) ds)+      DParamDecl {} -> panic "rename" ["DParamDecl"] -      DParameterConstraint ds ->-        case ds of-          [] -> pure (DParameterConstraint [])-          _  -> depsOf (ConstratintAt (fromJust (getLoc ds)))-              $ DParameterConstraint <$> mapM renameLocated ds-      DModule m -> DModule <$> traverse (renameWithMods info) m-      DImport li -> DImport <$> traverse renI li-        where-        renI i = do m <- rename (iModule i)-                    pure i { iModule = m } ++renI :: Located (ImportG (ImpName PName)) ->+        RenameM (Located (ImportG (ImpName Name)))+renI li =+  withLoc (srcRange li)+  do m <- rename (iModule i)+     unless (isFakeName m) (recordImport (srcRange li) m)+     pure li { thing = i { iModule = m } }+  where+  i = thing li+++instance Rename ModParam where+  rename mp =+    do x   <- rnLocated rename (mpSignature mp)+       depsOf (ModParamName (srcRange (mpSignature mp)) (mpName mp))+         do ren <- renModParamInstance <$> getModParam (mpName mp)++            {- Here we add 2 "uses" to all type-level names introduced,+               so that we don't get unused warnings for type parameters.+             -}+            mapM_ recordUse [ s | t <- Map.keys ren, nameNamespace t == NSType+                                , s <- [t,t] ]++            pure mp { mpSignature = x, mpRenaming = ren }+++renameIfaceModule :: ImpName Name -> Signature PName -> RenameM (Signature Name)+renameIfaceModule nm sig =+  do env <- rmodDefines <$> lookupResolved nm+     let depName = case nm of+                     ImpNested n -> NamedThing n+                     ImpTop t    -> ModPath (TopModule t)+     shadowNames' CheckOverlap env $+        depsOf depName+        do imps <- traverse renI (sigImports sig)+           tps <- traverse rename (sigTypeParams sig)++           ds  <- renameSigDecls (sigDecls sig)+           cts <- traverse (rnLocated rename) (sigConstraints sig)+           fun <- traverse rename (sigFunParams sig)++           -- we record a use here to avoid getting a warning in interfaces+           -- that declare only types, and so appear "unused".+           forM_ tps \tp -> recordUse (thing (ptName tp))+           forM_ ds  \d  -> recordUse $ case d of+                                          SigTySyn ts _ -> thing (tsName ts)+                                          SigPropSyn ps _ -> thing (psName ps)++           pure Signature+                  { sigImports      = imps+                  , sigTypeParams   = tps+                  , sigDecls        = ds+                  , sigConstraints  = cts+                  , sigFunParams    = fun+                  }+ instance Rename ImpName where   rename i =     case i of       ImpTop m -> pure (ImpTop m)       ImpNested m -> ImpNested <$> resolveName NameUse NSModule m -instance Rename (WithMods NestedModule) where-  rename (WithMods info (NestedModule m)) = WithMods info <$>-    do let (nested,mpath) = info-           lnm            = mName m+instance Rename ModuleInstanceArgs where+  rename args =+    case args of+      DefaultInstArg a -> DefaultInstArg <$> rnLocated rename a+      NamedInstArgs xs -> NamedInstArgs  <$> traverse rename xs+      DefaultInstAnonArg {} -> panic "rename" ["DefaultInstAnonArg"]++instance Rename ModuleInstanceNamedArg where+  rename (ModuleInstanceNamedArg x m) =+    ModuleInstanceNamedArg x <$> rnLocated rename m++instance Rename ModuleInstanceArg where+  rename arg =+    case arg of+      ModuleArg m -> ModuleArg <$> rename m+      ParameterArg a -> pure (ParameterArg a)+      AddParams -> pure AddParams++instance Rename NestedModule where+  rename (NestedModule m) =+    do let lnm            = mName m            nm             = thing lnm-           newMPath       = Nested mpath (getIdent nm)        n   <- resolveName NameBind NSModule nm        depsOf (NamedThing n)-         do let env = case Map.lookup n (fst info) of-                        Just defs -> defs-                        Nothing -> panic "rename"-                           [ "Missing environment for nested module", show n ]-            -- XXX: we should store in scope somehwere if we want to browse+         do -- XXX: we should store in scope somewhere if we want to browse             -- nested modules properly-            (_inScope,m1) <- renameModule' nested env newMPath m+            let m' = m { mName = ImpNested <$> mName m }+            (_inScope,m1) <- renameModule' (ImpNested n) m'             pure (NestedModule m1 { mName = lnm { thing = n } })  -renameLocated :: Rename f => Located (f PName) -> RenameM (Located (f Name))-renameLocated x =-  do y <- rename (thing x)-     return x { thing = y }- instance Rename PrimType where   rename pt =     do x <- rnLocated (renameType NameBind) (primTName pt)@@ -477,7 +836,7 @@              -- Record an additional use for each parameter since we checked             -- earlier that all the parameters are used exactly once in the-            -- body of the signature.  This prevents incorret warnings+            -- body of the signature.  This prevents incorrect warnings             -- about unused names.             mapM_ (recordUse . tpName) (fst cts) @@ -495,10 +854,11 @@          do sig' <- renameSchema (pfSchema a)             return a { pfName = n', pfSchema = snd sig' } -rnLocated :: (a -> RenameM b) -> Located a -> RenameM (Located b)-rnLocated f loc = withLoc loc $-  do a' <- f (thing loc)-     return loc { thing = a' }+instance Rename SigDecl where+  rename decl =+    case decl of+      SigTySyn ts mb   -> SigTySyn      <$> rename ts <*> pure mb+      SigPropSyn ps mb -> SigPropSyn    <$> rename ps <*> pure mb  instance Rename Decl where   rename d      = case d of@@ -509,7 +869,7 @@     DLocated d' r     -> withLoc r                        $ DLocated      <$> rename d'  <*> pure r -    DFixity{}         -> panic "renaem" [ "DFixity" ]+    DFixity{}         -> panic "rename" [ "DFixity" ]     DSignature {}     -> panic "rename" [ "DSignature" ]     DPragma  {}       -> panic "rename" [ "DPragma" ]     DPatBind {}       -> panic "rename" [ "DPatBind " ]@@ -520,11 +880,16 @@ instance Rename Newtype where   rename n      =     shadowNames (nParams n) $-    do name' <- rnLocated (renameType NameBind) (nName n)-       depsOf (NamedThing (thing name')) $+    do nameT <- rnLocated (renameType NameBind) (nName n)+       nameC <- renameVar  NameBind (nConName n)++       depsOf (NamedThing nameC) (addDep (thing nameT))++       depsOf (NamedThing (thing nameT)) $          do ps'   <- traverse rename (nParams n)             body' <- traverse (traverse rename) (nBody n)-            return Newtype { nName   = name'+            return Newtype { nName   = nameT+                           , nConName = nameC                            , nParams = ps'                            , nBody   = body' } @@ -539,42 +904,57 @@                  NSType -> recordUse                  _      -> const (pure ())      case lkpIn expected of-       Just [n]  ->-          do case nt of-               NameBind -> pure ()-               NameUse  -> addDep n-             use n    -- for warning-             return (Just n)-       Just []   -> panic "Renamer" ["Invalid expression renaming environment"]-       Just syms ->-         do mapM_ use syms    -- mark as used to avoid unused warnings-            n <- located qn-            record (MultipleSyms n syms)-            return (Just (head syms))+       Just xs ->+         case xs of+          One n ->+            do case nt of+                 NameBind -> pure ()+                 NameUse  -> addDep n+               use n    -- for warning+               return (Just n)+          Ambig symSet ->+            do let syms = Set.toList symSet+               mapM_ use syms    -- mark as used to avoid unused warnings+               n <- located qn+               recordError (MultipleSyms n syms)+               return (Just (head syms))         Nothing -> pure Nothing +reportUnboundName :: Namespace -> PName -> RenameM Name+reportUnboundName expected qn =+  do ro <- RenameM ask+     let lkpIn here = Map.lookup qn (namespaceMap here (roNames ro))+         others     = [ ns | ns <- allNamespaces+                           , ns /= expected+                           , Just _ <- [lkpIn ns] ]+     nm <- located qn+     case others of+       -- name exists in a different namespace+       actual : _ -> recordError (WrongNamespace expected actual nm)++       -- the value is just missing+       [] -> recordError (UnboundName expected nm)++     mkFakeName expected qn++isFakeName :: ImpName Name -> Bool+isFakeName m =+  case m of+    ImpTop x -> x == undefinedModName+    ImpNested x ->+      case nameTopModuleMaybe x of+        Just y  -> y == undefinedModName+        Nothing -> False++ -- | Resolve a name, and report error on failure resolveName :: NameType -> Namespace -> PName -> RenameM Name resolveName nt expected qn =   do mb <- resolveNameMaybe nt expected qn      case mb of        Just n -> pure n-       Nothing ->-         do ro <- RenameM ask-            let lkpIn here = Map.lookup qn (namespaceMap here (roNames ro))-                others     = [ ns | ns <- allNamespaces-                                  , ns /= expected-                                  , Just _ <- [lkpIn ns] ]-            nm <- located qn-            case others of-              -- name exists in a different namespace-              actual : _ -> record (WrongNamespace expected actual nm)--              -- the value is just missing-              [] -> record (UnboundName expected nm)--            mkFakeName expected qn+       Nothing -> reportUnboundName expected qn   renameVar :: NameType -> PName -> RenameM Name@@ -590,7 +970,8 @@ mkFakeName :: Namespace -> PName -> RenameM Name mkFakeName ns pn =   do ro <- RenameM ask-     liftSupply (mkParameter ns (getIdent pn) (roLoc ro))+     liftSupply (mkDeclared ns (TopModule undefinedModName)+                               SystemName (getIdent pn) Nothing (roLoc ro))  -- | Rename a schema, assuming that none of its type variables are already in -- scope.@@ -639,7 +1020,7 @@       TTuple fs      -> TTuple   <$> traverse rename fs       TWild          -> return TWild       TLocated t' r  -> withLoc r (TLocated <$> rename t' <*> pure r)-      TParens t'     -> TParens <$> rename t'+      TParens t' k   -> (`TParens` k) <$> rename t'       TInfix a o _ b -> do o' <- renameTypeOp o                            a' <- rename a                            b' <- rename b@@ -653,7 +1034,7 @@     FCLeft  -> return (TInfix t o2 f2 z)     FCRight -> do r <- mkTInfix y op z                   return (TInfix x o1 f1 r)-    FCError -> do record (FixityError o1 f1 o2 f2)+    FCError -> do recordError (FixityError o1 f1 o2 f2)                   return (TInfix t o2 f2 z)  mkTInfix (TLocated t' _) op z =@@ -683,8 +1064,14 @@  instance Rename BindDef where   rename DPrim     = return DPrim+  rename DForeign  = return DForeign   rename (DExpr e) = DExpr <$> rename e+  rename (DPropGuards cases) = DPropGuards <$> traverse rename cases +instance Rename PropGuardCase where+  rename g = PropGuardCase <$> traverse (rnLocated rename) (pgcProps g)+                           <*> rename (pgcExpr g)+ -- NOTE: this only renames types within the pattern. instance Rename Pattern where   rename p      = case p of@@ -712,7 +1099,8 @@        case more of          [] -> case h of                  UpdSet -> UpdField UpdSet [l] <$> rename e-                 UpdFun -> UpdField UpdFun [l] <$> rename (EFun emptyFunDesc [PVar p] e)+                 UpdFun -> UpdField UpdFun [l] <$>+                                        rename (EFun emptyFunDesc [PVar p] e)                        where                        p = UnQual . selName <$> last ls          _ -> UpdField UpdFun [l] <$> rename (EUpd Nothing [ UpdField h more e])@@ -728,9 +1116,6 @@   rename expr = case expr of     EVar n          -> EVar <$> renameVar NameUse n     ELit l          -> return (ELit l)-    ENeg e          -> ENeg    <$> rename e-    EComplement e   -> EComplement-                               <$> rename e     EGenerate e     -> EGenerate                                <$> rename e     ETuple es       -> ETuple  <$> traverse rename es@@ -786,6 +1171,7 @@                           x' <- rename x                           z' <- rename z                           mkEInfix x' op z'+    EPrefix op e    -> EPrefix op <$> rename e   checkLabels :: [UpdField PName] -> RenameM ()@@ -795,7 +1181,7 @@    check done l =     do case find (overlap l) done of-         Just l' -> record (OverlappingRecordUpdate (reLoc l) (reLoc l'))+         Just l' -> recordError (OverlappingRecordUpdate (reLoc l) (reLoc l'))          Nothing -> pure ()        pure (l : done) @@ -827,9 +1213,25 @@      FCRight -> do r <- mkEInfix y op z                    return (EInfix x o1 f1 r) -     FCError -> do record (FixityError o1 f1 o2 f2)+     FCError -> do recordError (FixityError o1 f1 o2 f2)                    return (EInfix e o2 f2 z) +mkEInfix e@(EPrefix o1 x) op@(o2, f2) y =+  case compareFixity (prefixFixity o1) f2 of+    FCRight -> do+      let warning = PrefixAssocChanged o1 x o2 f2 y+      RenameM $ sets_ (\rw -> rw {rwWarnings = warning : rwWarnings rw})+      r <- mkEInfix x op y+      return (EPrefix o1 r)++    -- Even if the fixities conflict, we make the prefix operator take+    -- precedence.+    _ -> return (EInfix e o2 f2 y)++-- Note that for prefix operator on RHS of infix operator we make the prefix+-- operator always have precedence, so we allow a * -b instead of requiring+-- a * (-b).+ mkEInfix (ELocated e' _) op z =      mkEInfix e' op z @@ -921,9 +1323,9 @@ patternEnv  = go   where   go (PVar Located { .. }) =-    do n <- liftSupply (mkParameter NSValue (getIdent thing) srcRange)+    do n <- liftSupply (mkLocal NSValue (getIdent thing) srcRange)        -- XXX: for deps, we should record a use-       return (singletonE thing n)+       return (singletonNS NSValue thing n)    go PWild            = return mempty   go (PTuple ps)      = bindVars ps@@ -961,23 +1363,23 @@            -- of the type of the pattern.            | null ps ->              do loc <- curLoc-                n   <- liftSupply (mkParameter NSType (getIdent pn) loc)-                return (singletonT pn n)+                n   <- liftSupply (mkLocal NSType (getIdent pn) loc)+                return (singletonNS NSType pn n)             -- This references a type synonym that's not in scope. Record an            -- error and continue with a made up name.            | otherwise ->              do loc <- curLoc-                record (UnboundName NSType (Located loc pn))-                n   <- liftSupply (mkParameter NSType (getIdent pn) loc)-                return (singletonT pn n)+                recordError (UnboundName NSType (Located loc pn))+                n   <- liftSupply (mkLocal NSType (getIdent pn) loc)+                return (singletonNS NSType pn n)    typeEnv (TRecord fs)      = bindTypes (map snd (recordElements fs))   typeEnv (TTyApp fs)       = bindTypes (map value fs)   typeEnv (TTuple ts)       = bindTypes ts   typeEnv TWild             = return mempty   typeEnv (TLocated ty loc) = withLoc loc (typeEnv ty)-  typeEnv (TParens ty)      = typeEnv ty+  typeEnv (TParens ty _)    = typeEnv ty   typeEnv (TInfix a _ _ b)  = bindTypes [a,b]    bindTypes [] = return mempty@@ -1005,3 +1407,20 @@     shadowNames ps     do n' <- rnLocated (renameType NameBind) n        PropSyn n' <$> pure f <*> traverse rename ps <*> traverse rename cs++--------------------------------------------------------------------------------++instance PP RenamedModule where+  ppPrec _ rn = updPPCfg (\cfg -> cfg { ppcfgShowNameUniques = True }) doc+    where+    doc =+      vcat [ "// --- Defines -----------------------------"+           , pp (rmDefines rn)+           , "// --- In scope ----------------------------"+           , pp (rmInScope rn)+           , "// -- Module -------------------------------"+           , pp (rmModule rn)+           , "// -----------------------------------------"+           ]++
src/Cryptol/ModuleSystem/Renamer/Error.hs view
@@ -10,11 +10,14 @@ {-# Language OverloadedStrings #-} module Cryptol.ModuleSystem.Renamer.Error where +import Data.List(intersperse)+ import Cryptol.ModuleSystem.Name import Cryptol.Parser.AST import Cryptol.Parser.Position import Cryptol.Parser.Selector(ppNestedSels) import Cryptol.Utils.PP+import Cryptol.Utils.Ident(modPathSplit)  import GHC.Generics (Generic) import Control.DeepSeq@@ -41,35 +44,65 @@   | FixityError (Located Name) Fixity (Located Name) Fixity     -- ^ When the fixity of two operators conflict -  | InvalidConstraint (Type PName)-    -- ^ When it's not possible to produce a Prop from a Type.--  | MalformedBuiltin (Type PName) PName-    -- ^ When a builtin type/type-function is used incorrectly.--  | BoundReservedType PName (Maybe Range) Doc-    -- ^ When a builtin type is named in a binder.-   | OverlappingRecordUpdate (Located [Selector]) (Located [Selector])     -- ^ When record updates overlap (e.g., @{ r | x = e1, x.y = e2 }@)    | InvalidDependency [DepName]-    deriving (Show, Generic, NFData)+    -- ^ Things that can't depend on each other +  | MultipleModParams Ident [Range]+    -- ^ Module parameters with the same name --- We use this because parameter constrstaints have no names+  | InvalidFunctorImport (ImpName Name)+    -- ^ Can't import functors directly++  | UnexpectedNest Range PName+    -- ^ Nested modules were not supposed to appear here++  | ModuleKindMismatch Range (ImpName Name) ModKind ModKind+    -- ^ Exepcted one kind (first one) but found the other (second one)++    deriving (Show, Generic, NFData, Eq, Ord)+++{- | We use this to name dependencies.+In addition to normal names we have a way to refer to module parameters+and top-level module constraints, which have no explicit names -} data DepName = NamedThing Name-             | ConstratintAt Range -- ^ identifed by location in source+               -- ^ Something with a name++             | ModPath ModPath+               -- ^ The module at this path++             | ModParamName Range Ident+               {- ^ Note that the range is important not just for error+                    reporting but to distinguish module parameters with+                    the same name (e.g., in nested functors) -}+             | ConstratintAt Range+               -- ^ Identifed by location in source                deriving (Eq,Ord,Show,Generic,NFData) -depNameLoc :: DepName -> Range+depNameLoc :: DepName -> Maybe Range depNameLoc x =   case x of-    NamedThing n -> nameLoc n-    ConstratintAt r -> r-  +    NamedThing n -> Just (nameLoc n)+    ConstratintAt r -> Just r+    ModParamName r _ -> Just r+    ModPath {} -> Nothing  +data ModKind = AFunctor | ASignature | AModule+    deriving (Show, Generic, NFData, Eq, Ord)++instance PP ModKind where+  ppPrec _ e =+    case e of+      AFunctor   -> "a functor"+      ASignature -> "an interface"+      AModule    -> "a module"+++ instance PP RenamerError where   ppPrec _ e = case e of @@ -119,19 +152,6 @@                  , text "are not compatible."                  , text "You may use explicit parentheses to disambiguate." ]) -    InvalidConstraint ty ->-      hang (hsep $ [text "[error]"] ++ maybe [] (\r -> [text "at" <+> pp r]) (getLoc ty))-         4 (fsep [ pp ty, text "is not a valid constraint" ])--    MalformedBuiltin ty pn ->-      hang (hsep $ [text "[error]"] ++ maybe [] (\r -> [text "at" <+> pp r]) (getLoc ty))-         4 (fsep [ text "invalid use of built-in type", pp pn-                 , text "in type", pp ty ])--    BoundReservedType n loc src ->-      hang (hsep $ [text "[error]"] ++ maybe [] (\r -> [text "at" <+> pp r]) loc)-         4 (fsep [ text "built-in type", quotes (pp n), text "shadowed in", src ])-     OverlappingRecordUpdate xs ys ->       hang "[error] Overlapping record updates:"          4 (vcat [ ppLab xs, ppLab ys ])@@ -140,10 +160,32 @@      InvalidDependency ds ->       hang "[error] Invalid recursive dependency:"-         4 (vcat [ "•" <+> pp x <.> ", defined at" <+> ppR (depNameLoc x)+         4 (vcat [ "•" <+> pp x <.>+                    case depNameLoc x of+                      Just r -> ", defined at" <+> ppR r+                      Nothing -> mempty                  | x <- ds ])       where ppR r = pp (from r) <.> "--" <.> pp (to r) +    MultipleModParams x rs ->+      hang ("[error] Multiple parameters with name" <+> backticks (pp x))+         4 (vcat [ "•" <+> pp r | r <- rs ])++    InvalidFunctorImport x ->+      hang ("[error] Invalid import of functor" <+> backticks (pp x))+        4 "• Functors need to be instantiated before they can be imported."++    UnexpectedNest s x ->+      hang ("[error] at" <+> pp s)+        4 ("submodule" <+> backticks (pp x) <+> "may not be defined here.")++    ModuleKindMismatch r x expected actual ->+      hang ("[error] at" <+> pp r)+        4 (vcat [ "• Expected" <+> pp expected+                , "•" <+> backticks (pp x) <+> "is" <+> pp actual+                ])++ instance PP DepName where   ppPrec _ d =     case d of@@ -153,6 +195,11 @@           NSModule -> "submodule" <+> pp n           NSType   -> "type" <+> pp n           NSValue  -> pp n+      ModParamName _r i -> "module parameter" <+> pp i+      ModPath mp ->+        case modPathSplit mp of+          (m,[]) -> "module" <+> pp m+          (_,is) -> "submodule" <+> hcat (intersperse "::" (map pp is))   @@ -161,27 +208,29 @@ data RenamerWarning   = SymbolShadowed PName Name [Name]   | UnusedName Name+  | PrefixAssocChanged PrefixOp (Expr Name) (Located Name) Fixity (Expr Name)     deriving (Show, Generic, NFData)  instance Eq RenamerWarning where   x == y = compare x y == EQ --- used to determine in what order ot show things+-- used to determine in what order to show things instance Ord RenamerWarning where   compare w1 w2 =-    case w1 of-      SymbolShadowed x y _ ->-        case w2 of-          SymbolShadowed x' y' _ -> compare (byStart y,x) (byStart y',x')-          _                      -> LT-      UnusedName x ->-        case w2 of-          UnusedName y -> compare (byStart x) (byStart y)-          _            -> GT+    case (w1, w2) of+      (SymbolShadowed x y _, SymbolShadowed x' y' _) ->+        compare (byStart y, x) (byStart y', x')+      (UnusedName x, UnusedName x') ->+        compare (byStart x) (byStart x')+      (PrefixAssocChanged _ _ op _ _, PrefixAssocChanged _ _ op' _ _) ->+        compare (from $ srcRange op) (from $ srcRange op')+      _ -> compare (priority w1) (priority w2)        where       byStart = from . nameLoc-+      priority SymbolShadowed {}     = 0 :: Int+      priority UnusedName {}         = 1+      priority PrefixAssocChanged {} = 2  instance PP RenamerWarning where   ppPrec _ (SymbolShadowed k x os) =@@ -201,5 +250,12 @@     hang (text "[warning] at" <+> pp (nameLoc x))        4 (text "Unused name:" <+> pp x) -+  ppPrec _ (PrefixAssocChanged prefixOp x infixOp infixFixity y) =+    hang (text "[warning] at" <+> pp (srcRange infixOp))+       4 $ fsep [ backticks (pp old)+                , "is now parsed as"+                , backticks (pp new) ] +    where+    old = EInfix (EPrefix prefixOp x) infixOp infixFixity y+    new = EPrefix prefixOp (EInfix x infixOp infixFixity y)
+ src/Cryptol/ModuleSystem/Renamer/ImplicitImports.hs view
@@ -0,0 +1,114 @@+{- |+We add implicit imports are for public nested modules.  This allows+using definitions from nested modules without having to explicitly import+them, for example:++module A where++  submodule B where+    x = 0x20++  y = x     // This works because of the implicit import of `B`++Restriction:+============++We only add impicit imports of modules that are syntactically visiable+in the source code.  Consider the following example:++module A where+  submodule M = F {X}   -- F,X are external modules (e.g., top-level)++We will add an implicit import for `M`, but *NO* implicit imports for+any modules imported vial `M` as those are not sytnactically visible+in the source (i.e., we have to know what `F` refers to).++This restriction allows us to add implicit imports before doing the+`Imports` pass.+-}++module Cryptol.ModuleSystem.Renamer.ImplicitImports+  ( addImplicitNestedImports+  ) where++import Data.List(partition)++import Cryptol.Parser.Position(Range)+import Cryptol.Utils.Ident(packModName)+import Cryptol.Parser.AST++{- | Add additional imports for modules nested withing this one -}+addImplicitNestedImports :: [TopDecl PName] -> [TopDecl PName]+addImplicitNestedImports = snd . addImplicitNestedImports'++{- | Returns:++  * declarations with additional imports and+  * the public module names of this module and its children.+-}+addImplicitNestedImports' ::+  [TopDecl PName] -> ([[Ident]], [TopDecl PName])+addImplicitNestedImports' decls =+  (concat exportedMods, concat newDecls ++ other)+  where+  (mods,other)            = partition isNestedMod decls+  (newDecls,exportedMods) = unzip (map processModule mods)+++processModule :: TopDecl PName -> ([TopDecl PName], [[Ident]])+processModule ~dcl@(DModule m) =+  let NestedModule m1 = tlValue m+  in+  case mDef m1 of+    NormalModule ds ->+      let (childExs, ds1) = addImplicitNestedImports' ds+          mname           = getIdent (thing (mName m1))+          imps            = map (mname :) ([] : childExs) -- this & nested+          loc             = srcRange (mName m1)+      in ( DModule m { tlValue = NestedModule m1 { mDef = NormalModule ds1 } }+         : map (mkImp loc) imps+         , case tlExport m of+             Public  -> imps+             Private -> []+         )++    FunctorInstance {} -> ([dcl], [])+    InterfaceModule {} -> ([dcl], [])+++++isNestedMod :: TopDecl name -> Bool+isNestedMod d =+  case d of+    DModule tl -> case tlValue tl of+                    NestedModule m -> not (mIsFunctor m)+    _          -> False++-- | Make a name qualifier out of a list of identifiers.+isToQual :: [Ident] -> ModName+isToQual is = packModName (map identText is)++-- | Make a module name out of a list of identifier.+-- This is the name of the module we are implicitly importing.+isToName :: [Ident] -> PName+isToName is = case is of+                [i] -> mkUnqual i+                _   -> mkQual (isToQual (init is)) (last is)++-- | Make an implicit import declaration.+mkImp :: Range -> [Ident] -> TopDecl PName+mkImp loc xs =+  DImport+    Located+      { srcRange = loc+      , thing    = Import+                     { iModule = ImpNested (isToName xs)+                     , iAs     = Just (isToQual xs)+                     , iSpec   = Nothing+                     , iInst   = Nothing+                     }+      }+++
+ src/Cryptol/ModuleSystem/Renamer/Imports.hs view
@@ -0,0 +1,576 @@+{- |++This module deals with imports of nested modules (@import submodule@).+This is more complex than it might seem at first because to resolve a+declaration like @import submodule X@ we need to resolve what @X@+referes to before we know what it will import.++Even triciker is the case for functor instantiations:++  module M = F { X }+  import M++In this case, even if we know what `M` referes to, we first need to+resolve `F`, so that we can generate the instantiation and generate+fresh names for names defined by `M`.++If we want to support applicative semantics, then before instantiation+`M` we also need to resolve `X` so that we know if this instantiation has+already been generated.++An overall guiding principle of the design is that we assume that declarations+can be ordered in dependency order, and submodules can be processed one+at a time. In particular, this does not allow recursion across modules,+or functor instantiations depending on their arguments.++Thus, the following is OK:++module A where+  x = 0x2++  submodule B where+    y = x++  z = B::y+++However, this is not OK:++  submodule A = F X+  submodule F where+    import A+-}++{-# Language BlockArguments #-}+{-# Language TypeSynonymInstances, FlexibleInstances #-}+module Cryptol.ModuleSystem.Renamer.Imports+  ( resolveImports+  , ResolvedModule(..)+  , ModKind(..)+  , ResolvedLocal+  , ResolvedExt+  )+  where++import Data.Maybe(fromMaybe)+import Data.Set(Set)+import qualified Data.Set as Set+import Data.Map (Map)+import qualified Data.Map as Map+import Data.List(foldl')+import Control.Monad(when)+import qualified MonadLib as M++import Cryptol.Utils.PP(pp)+import Cryptol.Utils.Panic(panic)+import Cryptol.Utils.Ident(ModName,ModPath(..),Namespace(..),OrigName(..))++import Cryptol.Parser.AST+  ( ImportG(..),PName, ModuleInstanceArgs(..), ImpName(..) )+import Cryptol.ModuleSystem.Binds (Mod(..), TopDef(..), modNested, ModKind(..))+import Cryptol.ModuleSystem.Name+          ( Name, Supply, SupplyT, runSupplyT, liftSupply, freshNameFor+          , asOrigName, nameIdent, nameTopModule )+import Cryptol.ModuleSystem.Names(Names(..))+import Cryptol.ModuleSystem.NamingEnv+          ( NamingEnv(..), lookupNS, shadowing, travNamingEnv+          , interpImportEnv, zipByTextName, filterUNames )+++{- | This represents a resolved module or signaure.+The type parameter helps us distinguish between two types of resolved modules:++  1. Resolved modules that are *inputs* to the algorithm (i.e., they are+     defined outside the current module).  For such modules the type+     parameter is @imps@ is ()++  2. Resolved modules that are *outputs* of the algorithm (i.e., they+     are defined within the current module).  For such modules the type+     parameter @imps@ contains the naming environment for things+     that came in through the import.++Note that signaures are never "imported", however we do need to keep them+here so that signatures in a functor are properly instantiated when+the functor is instantiated.+-}+data ResolvedModule imps = ResolvedModule+  { rmodDefines   :: NamingEnv    -- ^ Things defined by the module/signature.+  , rmodPublic    :: !(Set Name)  -- ^ Exported names+  , rmodKind      :: ModKind      -- ^ What sort of thing are we+  , rmodNested    :: Set Name     -- ^ Modules and signatures nested in this one+  , rmodImports   :: imps+    {- ^ Resolved imports. External modules need not specify this field,+    it is just part of the thing we compute for local modules. -}+  }+++-- | A resolved module that's defined in (or is) the current top-level module+type ResolvedLocal = ResolvedModule NamingEnv++-- | A resolved module that's not defined in the current top-level module+type ResolvedExt   = ResolvedModule ()+++resolveImports ::+  (ImpName Name -> Mod ()) ->+  TopDef ->+  Supply ->+  (Map (ImpName Name) ResolvedLocal, Supply)+resolveImports ext def su =+  case def of++    TopMod m mo ->+      do let cur  = todoModule mo+             newS = doModuleStep CurState+                                   { curMod = cur+                                   , curTop = m+                                   , externalModules = ext+                                   , doneModules = mempty+                                   , nameSupply = su+                                   , changes = False+                                   }+++         case tryFinishCurMod cur newS of+           Just r  -> add m r newS+           Nothing -> add m r s1+              where (r,s1) = forceFinish newS++    TopInst m f as ->+      do let s = CurState+                   { curMod = ()+                   , curTop = m+                   , externalModules = ext+                   , doneModules = mempty+                   , nameSupply = su+                   , changes = False+                   }++         case tryInstanceMaybe s (ImpTop m) (f,as) of+           Just (r,newS) -> add m r newS+           Nothing -> (Map.singleton (ImpTop m) forceResolveInst, su)++  where+  toNest m = Map.fromList [ (ImpNested k, v) | (k,v) <- Map.toList m ]+  add m r s  = ( Map.insert (ImpTop m) r (toNest (doneModules s))+               , nameSupply s+               )+++++--------------------------------------------------------------------------------+++-- | This keeps track of the current state of resolution of a module.+type Todo = Mod ModState++data ModState = ModState+  { modOuter        :: NamingEnv+    -- ^ Things which come in scope from outer modules++  , modImported     :: NamingEnv+    -- ^ Things which come in scope via imports.  These shadow outer names.+  }+++-- | Initial state of a module that needs processing.+todoModule :: Mod () -> Todo+todoModule = fmap (const emptyModState)+  where+  emptyModState =+    ModState+      { modOuter    = mempty+      , modImported = mempty+      }++{- | A module is fully processed when we are done with all its:++  * submodule imports+  * instantiations+  * nested things (signatures and modules)+-}+isDone :: Todo -> Bool+isDone m = null     (modImports m)   &&+           Map.null (modInstances m) &&+           Map.null (modMods m)+++-- | Finish up all unfinished modules as best as we can+forceFinish :: CurState -> (ResolvedLocal,CurState)+forceFinish s0 =+  let this  = curMod s0+      add k v s = s { doneModules = Map.insert k v (doneModules s) }+      s1        = foldl' (\s k -> add k forceResolveInst s) s0+                         (Map.keys (modInstances this))++      doNestMod s (k,m) =+        let (r,s') = forceFinish s { curMod = m }+        in add k r s'++  in ( forceResolveMod this+     , foldl' doNestMod s1 (Map.toList (modMods this))+     )+++-- | A place-holder entry for instnatitations we couldn't resolve.+forceResolveInst :: ResolvedLocal+forceResolveInst =+  ResolvedModule+    { rmodDefines = mempty+    , rmodPublic  = mempty+    , rmodKind    = AModule+    , rmodNested  = Set.empty+    , rmodImports = mempty+    }++-- | Finish up unresolved modules as well as we can, in situations where+-- the program contains an error.+forceResolveMod :: Todo -> ResolvedLocal+forceResolveMod todo =+  ResolvedModule+    { rmodDefines   = modDefines todo+    , rmodPublic    = modPublic todo+    , rmodKind      = modKind todo+    , rmodNested    = Map.keysSet (modMods todo)+    , rmodImports   = modImported (modState todo)+    }++++++pushImport :: ImportG (ImpName PName) -> Todo -> Todo+pushImport i m = m { modImports = i : modImports m }++pushInst :: Name -> (ImpName PName, ModuleInstanceArgs PName) -> Todo -> Todo+pushInst k v m = m { modInstances = Map.insert k v (modInstances m) }++pushMod :: Name -> Todo -> Todo -> Todo+pushMod k v m = m { modMods = Map.insert k v (modMods m) }++updMS :: (ModState -> ModState) -> Todo -> Todo+updMS f m = m { modState = f (modState m) }+--------------------------------------------------------------------------------++++externalMod :: Mod () -> ResolvedExt+externalMod m = ResolvedModule+  { rmodDefines  = modDefines m+  , rmodPublic   = modPublic m+  , rmodKind     = modKind m+  , rmodNested   = modNested m+  , rmodImports  = ()+  }++{- | This is used when we need to use a local resolved module as an input+     to another module. -}+forget :: ResolvedLocal -> ResolvedExt+forget r = r { rmodImports = () }++type CurState = CurState' Todo++data CurState' a = CurState+  { curMod      :: a+    -- ^ This is what needs to be done++  , curTop      :: !ModName+    {- ^ The top-level module we are working on.  This does not change+       throught the algorithm, it is just convenient to pass it here with +       all the other stuff. -}++  , externalModules :: ImpName Name -> Mod ()+    -- ^ Modules defined outside the current top-level modules++  , doneModules :: Map Name ResolvedLocal+    {- ^ Nested modules/signatures in the current top-level modules.+         These may be either defined locally, or be the result of+         instantiating a functor.  Note that the functor itself may be+         either local or external.+    -}++  , nameSupply :: Supply+    -- ^ Use this to instantiate functors++  , changes :: Bool+    -- ^ True if something changed on the last iteration+  }++updCur :: CurState -> (Todo -> Todo) -> CurState+updCur m f = m { curMod = f (curMod m) }++updCurMS :: CurState -> (ModState -> ModState) -> CurState+updCurMS s f = updCur s (updMS f)++class HasCurScope a where+  curScope :: CurState' a -> NamingEnv++instance HasCurScope () where+  curScope _ = mempty++instance HasCurScope Todo where+  curScope s = modDefines m `shadowing` modImported ms `shadowing` modOuter ms+    where+    m   = curMod s+    ms  = modState m+++-- | Keep applying a transformation while things are changing+doStep :: (CurState -> CurState) -> (CurState -> CurState)+doStep f s0 = go (changes s0) s0+  where+  go ch s = let s1 = f s { changes = False }+            in if changes s1+                then go True s1+                else s { changes = ch }++-- | Is this a known name for a module in the current scope?+knownPName :: HasCurScope a => CurState' a -> PName -> Maybe Name+knownPName s x =+  do ns <- lookupNS NSModule x (curScope s)+     case ns of+       One n    -> pure n+       {- NOTE: since we build up what's in scope incrementally,+          it is possible that this would eventually be ambiguous,+          which we'll detect during actual renaming. -}++       Ambig {} -> Nothing+       {- We treat ambiguous imports as undefined, which may lead to+          spurious "undefined X" errors.  To avoid this we should prioritize+          reporting "ambiguous X" errors. -}++-- | Is the module mentioned in this import known in the current scope?+knownImpName ::+  HasCurScope a => CurState' a -> ImpName PName -> Maybe (ImpName Name)+knownImpName s i =+  case i of+    ImpTop m    -> pure (ImpTop m)+    ImpNested m -> ImpNested <$> knownPName s m++-- | Is the module mentioned in the import already resolved?+knownModule ::+  HasCurScope a => CurState' a -> ImpName Name -> Maybe ResolvedExt+knownModule s x+  | root == curTop s =+    case x of+      ImpNested y -> forget <$> Map.lookup y (doneModules s)+      ImpTop {}   -> Nothing   -- or panic? recursive import++  | otherwise = Just (externalMod (externalModules s x))++  where+  root = case x of+           ImpTop r    -> r+           ImpNested n -> nameTopModule n++--------------------------------------------------------------------------------+++{- | Try to resolve an import. If the imported module can be resolved,+and it refers to a module that's already been resolved, then we do the+import and extend the current scoping environment.  Otherwise, we just+queue the import back on the @modImports@ of the current module to be tried+again later.-}+tryImport :: CurState -> ImportG (ImpName PName) -> CurState+tryImport s imp =+  fromMaybe (updCur s (pushImport imp))   -- not ready, put it back on the q+  do let srcName = iModule imp+     mname <- knownImpName s srcName+     ext   <- knownModule s mname++     let isPub x = x `Set.member` rmodPublic ext+         new = case rmodKind ext of+                 AModule    -> interpImportEnv imp+                                 (filterUNames isPub (rmodDefines ext))+                 AFunctor   -> mempty+                 ASignature -> mempty++     pure $ updCurMS s { changes = True }+            \ms -> ms { modImported = new <> modImported ms }++-- | Resolve all imports in the current modules+doImportStep :: CurState -> CurState+doImportStep s = foldl' tryImport s1 (modImports (curMod s))+  where+  s1 = updCur s \m -> m { modImports = [] }+++{- | Try to instantiate a functor.  This succeeds if we can resolve the functor+and the arguments and the both refer to already resolved names.+Note: at the moment we ignore the arguments, but we'd have to do that in+order to implment applicative behavior with caching. -}+tryInstanceMaybe ::+  HasCurScope a =>+  CurState' a ->+  ImpName Name ->+  (ImpName PName, ModuleInstanceArgs PName)+  {- ^ Functor and arguments -}  ->+  Maybe (ResolvedLocal,CurState' a)+tryInstanceMaybe s mn (f,_xs) =+  do fn <- knownImpName s f+     let path = case mn of+                  ImpTop m    -> TopModule m+                  ImpNested m ->+                    case asOrigName m of+                      Just og -> Nested (ogModule og) (ogName og)+                      Nothing ->+                        panic "tryInstanceMaybe" [ "Not a top-level name" ]+     doInstantiateByName False path fn s++{- | Try to instantiate a functor.  If successful, then the newly instantiated+module (and all things nested in it) are going to be added to the+@doneModules@ field.  Otherwise, we queue up the instantiatation in+@curMod@ for later processing -}+tryInstance ::+  CurState ->+  Name ->+  (ImpName PName, ModuleInstanceArgs PName) ->+  CurState+tryInstance s mn (f,xs) =+  case tryInstanceMaybe s (ImpNested mn) (f,xs) of+    Nothing       -> updCur s (pushInst mn (f,xs))+    Just (def,s1) -> s1 { changes = True+                        , doneModules = Map.insert mn def (doneModules s1)+                        }++{- | Generate a fresh instance for the functor with the given name. -}+doInstantiateByName ::+  HasCurScope a =>+  Bool+  {- ^ This indicates if the result is a functor or not.  When instantiating+    a functor applied to some arguments the result is not a functor.  However,+    if we are instantiating a functor nested within some functor that's being+    instantiated, then the result is still a functor. -} ->+  ModPath {- ^ Path for instantiated names -} ->+  ImpName Name {- ^ Name of the functor/module being instantiated -} ->+  CurState' a -> Maybe (ResolvedLocal,CurState' a)++doInstantiateByName keepArgs mpath fname s =+  do def <- knownModule s fname+     pure (doInstantiate keepArgs mpath def s)++++{- | Generate a new instantiation of the given module/signature.+Note that the module might not be a functor itself (e.g., if we are+instantiating something nested in a functor -}+doInstantiate ::+  HasCurScope a =>+  Bool               {- ^ See `doInstantiateByName` -} ->+  ModPath            {- ^ Path for instantiated names -} ->+  ResolvedExt        {- ^ The thing being instantiated -} ->+  CurState' a -> (ResolvedLocal,CurState' a)+doInstantiate keepArgs mpath def s = (newDef, Set.foldl' doSub newS nestedToDo)+  where+  ((newEnv,newNameSupply),nestedToDo) =+      M.runId+    $ M.runStateT Set.empty+    $ runSupplyT (nameSupply s)+    $ travNamingEnv instName+    $ rmodDefines def++  newS = s { nameSupply = newNameSupply }++  pub = let inst = zipByTextName (rmodDefines def) newEnv+        in Set.fromList [ case Map.lookup og inst of+                            Just newN -> newN+                            Nothing -> panic "doInstantiate.pub"+                                           [ "Lost a name", show og ]+                        | og <- Set.toList (rmodPublic def)+                        ]+++  newDef = ResolvedModule { rmodDefines   = newEnv+                          , rmodPublic    = pub+                          , rmodKind      = case rmodKind def of+                                              AFunctor ->+                                                 if keepArgs then AFunctor+                                                             else AModule+                                              ASignature -> ASignature+                                              AModule -> AModule++                          , rmodNested    = Set.map snd nestedToDo+                          , rmodImports   = mempty+                            {- we don't do name resolution on the instantiation+                               the usual way: instead the functor and the+                               arguments are renamed separately, then we+                               we do a pass where we replace:+                                  defined names of functor by instantiations+                                  parameter by actual names in arguments.+                            -}+                          }++  doSub st (oldSubName,newSubName) =+    case doInstantiateByName True (Nested mpath (nameIdent newSubName))+                                  (ImpNested oldSubName) st of+      Just (idef,st1) -> st1 { doneModules = Map.insert newSubName idef+                                                        (doneModules st1) }+      Nothing  -> panic "doInstantiate.doSub"+                    [ "Missing nested module:", show (pp oldSubName) ]++  instName :: Name -> SupplyT (M.StateT (Set (Name,Name)) M.Id) Name+  instName x =+    do y <- liftSupply (freshNameFor mpath x)+       when (x `Set.member` rmodNested def)+            (M.lift (M.sets_ (Set.insert (x,y))))+       pure y+++-- | Try to make progress on all instantiations.+doInstancesStep :: CurState -> CurState+doInstancesStep s = Map.foldlWithKey' tryInstance s0 (modInstances (curMod s))+  where+  s0 = updCur s \m' -> m' { modInstances = Map.empty }++tryFinishCurMod :: Todo -> CurState -> Maybe ResolvedLocal+tryFinishCurMod m newS+  | isDone newM =+    Just ResolvedModule+           { rmodDefines = modDefines m+           , rmodPublic  = modPublic m+           , rmodKind    = modKind m+           , rmodNested  = Set.unions+                             [ Map.keysSet (modInstances m)+                             , Map.keysSet (modMods m)+                             ]+           , rmodImports  = modImported (modState newM)+           }++  | otherwise = Nothing+  where newM = curMod newS+++-- | Try to resolve the "normal" module with the given name.+tryModule :: CurState -> Name -> Todo -> CurState+tryModule s nm m =+  case tryFinishCurMod m newS of+    Just rMod ->+      newS { curMod      = curMod s+           , doneModules = Map.insert nm rMod (doneModules newS)+           , changes     = True+           }+    Nothing -> newS { curMod = pushMod nm newM (curMod s) }+  where+  s1     = updCur s \_ -> updMS (\ms -> ms { modOuter = curScope s }) m+  newS   = doModuleStep s1+  newM   = curMod newS++-- | Process all submodules of a module.+doModulesStep :: CurState -> CurState+doModulesStep s = Map.foldlWithKey' tryModule s0 (modMods m)+  where+  m  = curMod s+  s0 = s { curMod = m { modMods = mempty } }++++-- | All steps involved in processing a module.+doModuleStep :: CurState -> CurState+doModuleStep = doStep step+  where+  step = doStep doModulesStep+       . doStep doInstancesStep+       . doStep doImportStep++
src/Cryptol/ModuleSystem/Renamer/Monad.hs view
@@ -9,30 +9,34 @@ {-# Language RecordWildCards #-} {-# Language FlexibleContexts #-} {-# Language BlockArguments #-}+{-# Language OverloadedStrings #-} module Cryptol.ModuleSystem.Renamer.Monad where -import Data.List(sort)+import Data.List(sort,foldl') import           Data.Set(Set) import qualified Data.Set as Set-import qualified Data.Foldable as F import           Data.Map.Strict ( Map ) import qualified Data.Map.Strict as Map-import qualified Data.Sequence as Seq import qualified Data.Semigroup as S import           MonadLib hiding (mapM, mapM_)  import Prelude () import Prelude.Compat +import Cryptol.Utils.PP(pp)+import Cryptol.Utils.Panic(panic)+import Cryptol.Utils.Ident(modPathCommon,OrigName(..),OrigSource(..)) import Cryptol.ModuleSystem.Name import Cryptol.ModuleSystem.NamingEnv+import Cryptol.ModuleSystem.Binds import Cryptol.ModuleSystem.Interface import Cryptol.Parser.AST+import Cryptol.TypeCheck.AST(ModParamNames) import Cryptol.Parser.Position-import Cryptol.Utils.Panic (panic)-import Cryptol.Utils.Ident(modPathCommon)  import Cryptol.ModuleSystem.Renamer.Error+import Cryptol.ModuleSystem.Renamer.Imports+  (ResolvedLocal,rmodKind,rmodDefines,rmodNested)  -- | Indicates if a name is in a binding poisition or a use site data NameType = NameBind | NameUse@@ -42,22 +46,41 @@   { renSupply   :: Supply     -- ^ Use to make new names   , renContext  :: ModPath    -- ^ We are renaming things in here   , renEnv      :: NamingEnv  -- ^ This is what's in scope-  , renIfaces   :: ModName -> Iface+  , renIfaces   :: Map ModName (Either ModParamNames Iface)+    -- ^ External modules   }  newtype RenameM a = RenameM { unRenameM :: ReaderT RO (StateT RW Lift) a }  data RO = RO-  { roLoc    :: Range-  , roNames  :: NamingEnv-  , roIfaces :: ModName -> Iface-  , roCurMod :: ModPath           -- ^ Current module we are working on+  { roLoc       :: Range+  , roNames     :: NamingEnv+  , roExternal  :: Map ModName (Maybe Iface, Map (ImpName Name) (Mod ()))+    -- ^ Externally loaded modules. `Mod` is defined in 'Cryptol.Renamer.Binds'.++  , roCurMod    :: ModPath               -- ^ Current module we are working on+   , roNestedMods :: Map ModPath Name+    {- ^ Maps module paths to the actual name for it.   This is used+         for dependency tracking, to find the name of a containing module.+         See the note on `addDep`. -}++  , roResolvedModules :: Map (ImpName Name) ResolvedLocal+    -- ^ Info about locally defined modules++  , roModParams :: Map Ident RenModParam+    {- ^ Module parameters.  These are used when rename the module parameters,+       and only refer to the parameters of the current module (i.e., no+       outer parameters as those are not needed) -}++  , roFromModParam :: Map Name DepName+    -- ^ Keeps track of which names were introduce by module parameters+    -- and which one.  The `DepName` is always a `ModParamName`.   }  data RW = RW   { rwWarnings      :: ![RenamerWarning]-  , rwErrors        :: !(Seq.Seq RenamerError)+  , rwErrors        :: !(Set RenamerError)   , rwSupply        :: !Supply   , rwNameUseCount  :: !(Map Name Int)     -- ^ How many times did we refer to each name.@@ -72,11 +95,24 @@     -- see 'depsOf'    , rwExternalDeps  :: !IfaceDecls-    -- ^ Info about imported things+    -- ^ Info about imported things, from external modules   }   +data RenModParam = RenModParam+  { renModParamName      :: Ident+  , renModParamRange     :: Range+  , renModParamSig       :: ImpName Name+  , renModParamInstance  :: Map Name Name+    {- ^ Maps names that come into scope through this parameter+         to the names in the *module interface*.+         This is for functors, NOT functor instantantiations. -}+  }++++ instance S.Semigroup a => S.Semigroup (RenameM a) where   {-# INLINE (<>) #-}   a <> b =@@ -125,7 +161,7 @@   warns = sort (rwWarnings rw ++ warnUnused (renContext info) (renEnv info) rw)    (a,rw) = runM (unRenameM m) ro-                              RW { rwErrors   = Seq.empty+                              RW { rwErrors   = Set.empty                                  , rwWarnings = []                                  , rwSupply   = renSupply info                                  , rwNameUseCount = Map.empty@@ -136,15 +172,24 @@    ro = RO { roLoc   = emptyRange           , roNames = renEnv info-          , roIfaces = renIfaces info+          , roExternal = Map.mapWithKey toModMap (renIfaces info)           , roCurMod = renContext info           , roNestedMods = Map.empty+          , roResolvedModules = mempty+          , roModParams = mempty+          , roFromModParam = mempty           } -  res | Seq.null (rwErrors rw) = Right (a,rwSupply rw)-      | otherwise              = Left (F.toList (rwErrors rw))+  res | Set.null (rwErrors rw) = Right (a,rwSupply rw)+      | otherwise              = Left (Set.toList (rwErrors rw)) +  toModMap t ent =+    case ent of+      Left ps -> (Nothing, Map.singleton (ImpTop t) (ifaceSigToMod ps))+      Right i -> (Just i, modToMap (ImpTop t) (ifaceToMod i) mempty) ++ setCurMod :: ModPath -> RenameM a -> RenameM a setCurMod mpath (RenameM m) =   RenameM $ mapReader (\ro -> ro { roCurMod = mpath }) m@@ -155,7 +200,57 @@ getNamingEnv :: RenameM NamingEnv getNamingEnv = RenameM (asks roNames) +setResolvedLocals :: Map (ImpName Name) ResolvedLocal -> RenameM a -> RenameM a+setResolvedLocals mp (RenameM m) =+  RenameM $ mapReader (\ro -> ro { roResolvedModules = mp }) m +lookupResolved :: ImpName Name -> RenameM ResolvedLocal+lookupResolved nm =+  do mp <- RenameM (roResolvedModules <$> ask)+     pure case Map.lookup nm mp of+            Just r  -> r++            -- XXX: could this happen because we couldn't resolve a module?+            Nothing -> panic "lookupResolved"+                        [ "Missing module: " ++ show nm ]++setModParams :: [RenModParam] -> RenameM a -> RenameM a+setModParams ps (RenameM m) =+  do let pmap = Map.fromList [ (renModParamName p, p) | p <- ps ]++         newFrom =+           foldLoop ps mempty \p mp ->+             let nm = ModParamName (renModParamRange p) (renModParamName p)+             in foldLoop (Map.keys (renModParamInstance p)) mp \x ->+                  Map.insert x nm++         upd ro = ro { roModParams    = pmap+                     , roFromModParam = newFrom <> roFromModParam ro+                     }++     RenameM (mapReader upd m)+++foldLoop :: [a] -> b -> (a -> b -> b) -> b+foldLoop xs b f = foldl' (flip f) b xs++getModParam :: Ident -> RenameM RenModParam+getModParam p =+  do ps <- RenameM (roModParams <$> ask)+     case Map.lookup p ps of+       Just r  -> pure r+       Nothing -> panic "getModParam" [ "Missing module paramter", show p ]++getNamesFromModParams :: RenameM (Map Name DepName)+getNamesFromModParams = RenameM (roFromModParam <$> ask)++getLocalModParamDeps :: RenameM (Map Ident DepName)+getLocalModParamDeps =+  do ps <- RenameM (roModParams <$> ask)+     let toName mp = ModParamName (renModParamRange mp) (renModParamName mp)+     pure (toName <$> ps)++ setNestedModule :: Map ModPath Name -> RenameM a -> RenameM a setNestedModule mp (RenameM m) =   RenameM $ mapReader (\ro -> ro { roNestedMods = mp }) m@@ -164,12 +259,16 @@ nestedModuleOrig x = RenameM (asks (Map.lookup x . roNestedMods))  --- | Record an error.  XXX: use a better name-record :: RenamerError -> RenameM ()-record f = RenameM $+-- | Record an error.+recordError :: RenamerError -> RenameM ()+recordError f = RenameM $   do RW { .. } <- get-     set RW { rwErrors = rwErrors Seq.|> f, .. }+     set RW { rwErrors = Set.insert f rwErrors, .. } +recordWarning :: RenamerWarning -> RenameM ()+recordWarning w =+  RenameM $ sets_ \rw -> rw { rwWarnings = w : rwWarnings rw }+ collectIfaceDeps :: RenameM a -> RenameM (IfaceDecls,a) collectIfaceDeps (RenameM m) =   RenameM@@ -191,7 +290,7 @@      pure a  -- | This is used when renaming a group of things.  The result contains--- dependencies between names defines and the group, and is intended to+-- dependencies between names defined in the group, and is intended to -- be used to order the group members in dependency order. depGroup :: RenameM a -> RenameM (a, Map DepName (Set Name)) depGroup (RenameM m) = RenameM@@ -230,58 +329,39 @@               | CheckNone    -- ^ Don't check the environment                 deriving (Eq,Show) +-- | Report errors if the given naming environemnt contains multiple+-- definitions for the same symbol+checkOverlap :: NamingEnv -> RenameM NamingEnv+checkOverlap env =+  case findAmbig env of+    []    -> pure env+    ambig -> do mapM_ recordError [ OverlappingSyms xs | xs <- ambig ]+                pure (forceUnambig env)++-- | Issue warnings if entries in the first environment would+-- shadow something in the second.+checkShadowing :: NamingEnv -> NamingEnv -> RenameM ()+checkShadowing envNew envOld =+  mapM_ recordWarning+    [ SymbolShadowed p x xs | (p,x,xs) <- findShadowing envNew envOld ]++ -- | Shadow the current naming environment with some more names.+-- XXX: The checks are really confusing shadowNames' :: BindsNames env => EnvCheck -> env -> RenameM a -> RenameM a shadowNames' check names m = do-  do env <- liftSupply (defsOf names)-     RenameM $+  do env    <- liftSupply (defsOf names)+     envOld <- RenameM (roNames <$> ask)+     env1   <- case check of+                 CheckNone    -> pure env+                 CheckOverlap -> checkOverlap env+                 CheckAll     -> do checkShadowing env envOld+                                    checkOverlap env+     RenameM        do ro  <- ask-          env' <- sets (checkEnv check env (roNames ro))-          let ro' = ro { roNames = env' `shadowing` roNames ro }+          let ro' = ro { roNames = env1 `shadowing` envOld }           local ro' (unRenameM m) --- | Generate warnings when the left environment shadows things defined in--- the right.  Additionally, generate errors when two names overlap in the--- left environment.-checkEnv :: EnvCheck -> NamingEnv -> NamingEnv -> RW -> (NamingEnv,RW)-checkEnv check (NamingEnv lenv) r rw0-  | check == CheckNone = (newEnv,rw0)-  | otherwise          = (newEnv,rwFin)--  where-  newEnv         = NamingEnv newMap-  (rwFin,newMap) = Map.mapAccumWithKey doNS rw0 lenv  -- lenv 1 ns at a time-  doNS rw ns     = Map.mapAccumWithKey (step ns) rw--  -- namespace, current state, k : parse name, xs : possible entities for k-  step ns acc k xs = (acc', case check of-                              CheckNone -> xs-                              _         -> [head xs]-                              -- we've already reported an overlap error,-                              -- so resolve arbitrarily to  the first entry-                      )-    where-    acc' = acc-      { rwWarnings =-          if check == CheckAll-             then case Map.lookup k (namespaceMap ns r) of-                    Just os | [x] <- xs-                            , let os' = filter (/=x) os-                            , not (null os') ->-                              SymbolShadowed k x os' : rwWarnings acc-                    _ -> rwWarnings acc--             else rwWarnings acc-      , rwErrors   = rwErrors acc Seq.>< containsOverlap xs-      }---- | Check the RHS of a single name rewrite for conflicting sources.-containsOverlap :: [Name] -> Seq.Seq RenamerError-containsOverlap [_] = Seq.empty-containsOverlap []  = panic "Renamer" ["Invalid naming environment"]-containsOverlap ns  = Seq.singleton (OverlappingSyms ns)-- recordUse :: Name -> RenameM () recordUse x = RenameM $ sets_ $ \rw ->   rw { rwNameUseCount = Map.insertWith (+) x 1 (rwNameUseCount rw) }@@ -306,7 +386,8 @@ addDep x =   do cur  <- getCurMod      deps <- case nameInfo x of-               Declared m _ | Just (c,_,i:_) <- modPathCommon cur m ->+               GlobalName _ OrigName { ogModule = m }+                 | Just (c,_,i:_) <- modPathCommon cur m ->                  do mb <- nestedModuleOrig (Nested c i)                     pure case mb of                            Just y  -> Set.fromList [x,y]@@ -318,25 +399,111 @@  warnUnused :: ModPath -> NamingEnv -> RW -> [RenamerWarning] warnUnused m0 env rw =-  map warn+  map UnusedName   $ Map.keys   $ Map.filterWithKey keep   $ rwNameUseCount rw   where-  warn x   = UnusedName x   keep nm count = count == 1 && isLocal nm   oldNames = Map.findWithDefault Set.empty NSType (visibleNames env)++  -- returns true iff the name comes from a definition in a nested module,+  -- including the current module+  isNestd og = case modPathCommon m0 (ogModule og) of+                 Just (_,[],_) | FromDefinition <- ogSource og -> True+                 _ -> False+   isLocal nm = case nameInfo nm of-                 Declared m sys -> sys == UserName &&-                                   m == m0 && nm `Set.notMember` oldNames-                 Parameter  -> True+                 GlobalName sys og ->+                   sys == UserName && isNestd og && nm `Set.notMember` oldNames+                 LocalName {} -> True --- | Get the exported declarations in a module-lookupImport :: Import -> RenameM IfaceDecls-lookupImport imp = RenameM $-  do getIf <- roIfaces <$> ask-     let ifs = ifPublic (getIf (iModule imp))-     sets_ \s -> s { rwExternalDeps = ifs <> rwExternalDeps s }-     pure ifs +getExternal :: RenameM (ImpName Name -> Mod ())+getExternal =+  do mp <- roExternal <$> RenameM ask+     pure \nm -> let mb = do t   <- case nm of+                                      ImpTop t  -> pure t+                                      ImpNested x -> nameTopModuleMaybe x+                             (_,mp1) <- Map.lookup t mp+                             Map.lookup nm mp1+                 in case mb of+                      Just m -> m+                      Nothing -> panic "getExternal"+                                    ["Missing external name", show (pp nm) ]++getExternalMod :: ImpName Name -> RenameM (Mod ())+getExternalMod nm = ($ nm) <$> getExternal++-- | Returns `Nothing` if the name does not refer to a module (i.e., it is a sig)+getTopModuleIface :: ImpName Name -> RenameM (Maybe Iface)+getTopModuleIface nm =+  do mp <- roExternal <$> RenameM ask+     let t = case nm of+               ImpTop t' -> t'+               ImpNested x -> nameTopModule x+     case Map.lookup t mp of+       Just (mb, _) -> pure mb+       Nothing -> panic "getTopModuleIface"+                                ["Missing external module", show (pp nm) ]++{- | Record an import:+      * record external dependency if the name refers to an external import+      * record an error if the imported thing is a functor+-}+recordImport :: Range -> ImpName Name -> RenameM ()+recordImport r i =+  do ro <- RenameM ask+     case Map.lookup i (roResolvedModules ro) of+       Just loc ->+         case rmodKind loc of+           AModule -> pure ()+           k       -> recordError (ModuleKindMismatch r i AModule k)+       Nothing ->+        do mb <- getTopModuleIface i+           case mb of+             Nothing -> recordError (ModuleKindMismatch r i AModule ASignature)+             Just iface+               | ifaceIsFunctor iface ->+                       recordError (ModuleKindMismatch r i AModule AFunctor)+               | otherwise ->+                 RenameM $ sets_ \s -> s { rwExternalDeps = ifDefines iface <>+                                                            rwExternalDeps s }+++-- | Lookup a name either in the locally resolved thing or in an external module+lookupModuleThing :: ImpName Name -> RenameM (Either ResolvedLocal (Mod ()))+lookupModuleThing nm =+  do ro <- RenameM ask+     case Map.lookup nm (roResolvedModules ro) of+       Just loc -> pure (Left loc)+       Nothing  -> Right <$> getExternalMod nm++lookupDefines :: ImpName Name -> RenameM NamingEnv+lookupDefines nm =+  do thing <- lookupModuleThing nm+     pure case thing of+            Left loc -> rmodDefines loc+            Right e  -> modDefines e++checkIsModule :: Range -> ImpName Name -> ModKind -> RenameM ()+checkIsModule r nm expect =+  do thing <- lookupModuleThing nm+     let actual = case thing of+                    Left rmod -> rmodKind rmod+                    Right mo  -> modKind mo+     unless (actual == expect)+        (recordError (ModuleKindMismatch r nm expect actual))++lookupDefinesAndSubs :: ImpName Name -> RenameM (NamingEnv, Set Name)+lookupDefinesAndSubs nm =+  do thing <- lookupModuleThing nm+     pure case thing of+            Left rmod -> ( rmodDefines rmod, rmodNested rmod)+            Right m ->+              ( modDefines m+              , Set.unions [ Map.keysSet (modMods m)+                           , Map.keysSet (modInstances m)+                           ]+              ) 
src/Cryptol/Parser.y view
@@ -38,7 +38,6 @@ import Cryptol.Parser.Token import Cryptol.Parser.ParserUtils import Cryptol.Parser.Unlit(PreProc(..), guessPreProc)-import Cryptol.Utils.Ident(paramInstModName) import Cryptol.Utils.RecordMap(RecordMap)  import Paths_cryptol@@ -84,12 +83,14 @@   'if'        { Located $$ (Token (KW KW_if     ) _)}   'then'      { Located $$ (Token (KW KW_then   ) _)}   'else'      { Located $$ (Token (KW KW_else   ) _)}+  'interface' { Located $$ (Token (KW KW_interface) _)}   'x'         { Located $$ (Token (KW KW_x)       _)}   'down'      { Located $$ (Token (KW KW_down)    _)}   'by'        { Located $$ (Token (KW KW_by)      _)}    'primitive' { Located $$ (Token (KW KW_primitive) _)}   'constraint'{ Located $$ (Token (KW KW_constraint) _)}+  'foreign'   { Located $$ (Token (KW KW_foreign) _)}   'Prop'      { Located $$ (Token (KW KW_Prop) _)}    '['         { Located $$ (Token (Sym BracketL) _)}@@ -140,7 +141,7 @@    DOC         { $$@(Located _ (Token (White DocStr) _)) } -%name vmodule vmodule+%name top_module top_module %name program program %name programLayout program_layout %name expr    expr@@ -164,44 +165,78 @@ %%  -vmodule :: { Module PName }-  : 'module' module_def       { $2 }-  | 'v{' vmod_body 'v}'       { mkAnonymousModule $2 }-+top_module :: { [Module PName] }+  : 'module' module_def       {% mkTopMods $2 }+  | 'v{' vmod_body 'v}'       {% mkAnonymousModule $2 }+  | 'interface' 'module' modName 'where' 'v{' sig_body 'v}'+                              { mkTopSig $3 $6 }  module_def :: { Module PName }    : modName 'where'-      'v{' vmod_body 'v}'                 { mkModule $1 $4 }+      'v{' vmod_body 'v}'                     { mkModule $1 $4 } -  | modName '=' modName 'where'-      'v{' vmod_body 'v}'                 { mkModuleInstance $1 $3 $6 }+  | modName '=' impName 'where'+      'v{' vmod_body 'v}'                     { mkModuleInstanceAnon $1 $3 $6 } +  | modName '=' impName '{' modInstParams '}' { mkModuleInstance $1 $3 $5 }+++modInstParams            :: { ModuleInstanceArgs PName }+  : modInstParam            { DefaultInstArg $1 }+  | namedModInstParams      { NamedInstArgs $1 }++namedModInstParams                       :: { [ ModuleInstanceNamedArg PName ] }+  : namedModInstParam                         { [$1] }+  | namedModInstParams ',' namedModInstParam  { $3 : $1 }++namedModInstParam          :: { ModuleInstanceNamedArg PName }+  : ident '=' modInstParam    { ModuleInstanceNamedArg $1 $3 }++modInstParam               :: { Located (ModuleInstanceArg PName) }+  : impName                   { fmap ModuleArg $1 }+  | 'interface' ident         { fmap ParameterArg $2 }+  | '_'                       { Located { thing    = AddParams+                                        , srcRange = $1 } }+ vmod_body                  :: { [TopDecl PName] }   : vtop_decls                { reverse $1 }   | {- empty -}               { [] }  --- XXX replace rComb with uses of at++-- inverted+imports1                  :: { [ Located (ImportG (ImpName PName)) ] }+  : imports1 'v;' import     { $3 : $1 }+  | imports1 ';'  import     { $3 : $1 }+  | import                   { [$1] }++ import                          :: { Located (ImportG (ImpName PName)) }-  : 'import' impName mbAs mbImportSpec-                              { Located { srcRange = rComb $1-                                                   $ fromMaybe (srcRange $2)-                                                   $ msum [ fmap srcRange $4-                                                          , fmap srcRange $3-                                                          ]-                                        , thing    = Import-                                          { iModule    = thing $2-                                          , iAs        = fmap thing $3-                                          , iSpec      = fmap thing $4-                                          }-                                        } }+  : 'import' impName optInst mbAs mbImportSpec optImportWhere+                              {% mkImport $1 $2 $3 $4 $5 $6 }+  | 'import' impNameBT mbAs mbImportSpec {% mkBacktickImport $1 $2 $3 $4 } +optImportWhere             :: { Maybe (Located [Decl PName]) }+  : 'where' whereClause       { Just $2 }+  | {- empty -}               { Nothing }++optInst                    :: { Maybe (ModuleInstanceArgs PName) }+  : '{' modInstParams '}'     { Just $2 }+  | {- empty -}               { Nothing }++ impName                    :: { Located (ImpName PName) }   : 'submodule' qname         { ImpNested `fmap` $2 }   | modName                   { ImpTop `fmap` $1 } +impNameBT                  :: { Located (ImpName PName) }+  : 'submodule' '`' qname     { ImpNested `fmap` $3 }+  | '`' modName               { ImpTop `fmap` $2 } +++ mbAs                       :: { Maybe (Located ModName) }   : 'as' modName              { Just $2 }   | {- empty -}               { Nothing }@@ -216,9 +251,9 @@   | {- empty -}               { Nothing }  name_list                  :: { [LIdent] }-  : name_list ',' ident       { $3 : $1 }-  | ident                     { [$1]    }-  | {- empty -}               { []      }+  : name_list ',' var         { fmap getIdent $3 : $1 }+  | var                       { [fmap getIdent $1]    }+  | {- empty -}               { []                    }  mbHiding                   :: { [Ident] -> ImportSpec }   : 'hiding'                  { Hiding }@@ -251,12 +286,40 @@                            { [exportDecl $1 Public (mkProperty $3 [] $5)]     }   | mbDoc newtype          { [exportNewtype Public $1 $2]                     }   | prim_bind              { $1                                               }+  | foreign_bind           { $1                                               }   | private_decls          { $1                                               }-  | parameter_decls        { $1                                               }+  | mbDoc 'interface' 'constraint' type {% mkInterfaceConstraint $1 $4 }+  | parameter_decls        { [ $1 ]                                       }   | mbDoc 'submodule'     module_def             {% ((:[]) . exportModule $1) `fmap` mkNested $3 }-  | import                 { [DImport $1] } +  | mbDoc sig_def          { [mkSigDecl $1 $2]  }+  | mod_param_decl         { [DModParam $1] }+  | mbDoc import           { [DImport $2] }+    -- we allow for documentation here to avoid conflicts with module paramaters+    -- currently that odcumentation is just discarded+++sig_def ::                 { (Located PName, Signature PName) }+  : 'interface' 'submodule' name 'where' 'v{' sig_body 'v}'+                           { ($3, $6) }++sig_body                 :: { Signature PName }+  : par_decls               {% mkInterface [] $1 }+  | imports1 'v;' par_decls {% mkInterface (reverse $1) $3 }+  | imports1 ';'  par_decls {% mkInterface (reverse $1) $3 }+++mod_param_decl ::          { ModParam PName }+  : mbDoc+   'import' 'interface'+    impName mbAs           { ModParam { mpSignature = $4+                                      , mpAs        = fmap thing $5+                                      , mpName      = mkModParamName $4 $5+                                      , mpDoc       = $1+                                      , mpRenaming  = mempty } }++ top_decl                :: { [TopDecl PName] }   : decl                   { [Decl (TopLevel {tlExport = Public, tlValue = $1 })] }   | 'include' STRLIT       {% (return . Include) `fmap` fromStrLit $2             }@@ -273,22 +336,24 @@   | mbDoc 'primitive' '(' op ')' ':' schema  { mkPrimDecl $1 $4 $7 }   | mbDoc 'primitive' 'type' schema ':' kind {% mkPrimTypeDecl $1 $4 $6 } +foreign_bind            :: { [TopDecl PName] }+  : mbDoc 'foreign' name ':' schema          {% mkForeignDecl $1 $3 $5 } -parameter_decls                      :: { [TopDecl PName] }-  :     'parameter' 'v{' par_decls 'v}' { reverse $3 }-  | doc 'parameter' 'v{' par_decls 'v}' { reverse $4 }+parameter_decls                      :: { TopDecl PName }+  :     'parameter' 'v{' par_decls 'v}' { mkParDecls (reverse $3) }+  | doc 'parameter' 'v{' par_decls 'v}' { mkParDecls (reverse $4) }  -- Reversed-par_decls                            :: { [TopDecl PName] }+par_decls                            :: { [ParamDecl PName] }   : par_decl                            { [$1] }   | par_decls ';'  par_decl             { $3 : $1 }   | par_decls 'v;' par_decl             { $3 : $1 } -par_decl                         :: { TopDecl PName }+par_decl                         :: { ParamDecl PName }   : mbDoc        name ':' schema    { mkParFun $1 $2 $4 }   | mbDoc 'type' name ':' kind      {% mkParType $1 $3 $5 }-  | mbDoc 'type' 'constraint' type  {% fmap (DParameterConstraint . distrLoc)-                                            (mkProp $4) }+  | mbDoc typeOrPropSyn             { mkIfacePropSyn (thing `fmap` $1) $2 }+  | mbDoc topTypeConstraint         { DParameterConstraint (distrLoc $2) }   doc                     :: { Located Text }@@ -298,11 +363,14 @@   : doc                    { Just $1 }   | {- empty -}            { Nothing } - decl                    :: { Decl PName }   : vars_comma ':' schema  { at (head $1,$3) $ DSignature (reverse $1) $3   }   | ipat '=' expr          { at ($1,$3) $ DPatBind $1 $3                    }   | '(' op ')' '=' expr    { at ($1,$5) $ DPatBind (PVar $2) $5             }+  | var apats_indices propguards_cases+                           {% mkPropGuardsDecl $1 $2 $3 }+  | var propguards_cases+                           {% mkConstantPropGuardsDecl $1 $2 }   | var apats_indices '=' expr                            { at ($1,$4) $ mkIndexedDecl $1 $2 $4 } @@ -320,18 +388,7 @@                                           , bExport    = Public                                           } } -  | 'type' name '=' type   {% at ($1,$4) `fmap` mkTySyn $2 [] $4 }-  | 'type' name tysyn_params '=' type-                           {% at ($1,$5) `fmap` mkTySyn $2 (reverse $3) $5  }-  | 'type' tysyn_param op tysyn_param '=' type-                           {% at ($1,$6) `fmap` mkTySyn $3 [$2, $4] $6 }--  | 'type' 'constraint' name '=' type-                           {% at ($2,$5) `fmap` mkPropSyn $3 [] $5 }-  | 'type' 'constraint' name tysyn_params '=' type-                           {% at ($2,$6) `fmap` mkPropSyn $3 (reverse $4) $6 }-  | 'type' 'constraint' tysyn_param op tysyn_param '=' type-                           {% at ($2,$7) `fmap` mkPropSyn $4 [$3, $5] $7 }+  | typeOrPropSyn          { $1 }    | 'infixl' NUM ops       {% mkFixity LeftAssoc  $2 (reverse $3) }   | 'infixr' NUM ops       {% mkFixity RightAssoc $2 (reverse $3) }@@ -363,30 +420,35 @@    | 'let' vars_comma ':' schema  { at (head $2,$4) $ DSignature (reverse $2) $4   } -  | 'type' name '=' type   {% at ($1,$4) `fmap` mkTySyn $2 [] $4 }-  | 'type' name tysyn_params '=' type-                           {% at ($1,$5) `fmap` mkTySyn $2 (reverse $3) $5  }-  | 'type' tysyn_param op tysyn_param '=' type-                           {% at ($1,$6) `fmap` mkTySyn $3 [$2, $4] $6 }--  | 'type' 'constraint' name '=' type-                           {% at ($2,$5) `fmap` mkPropSyn $3 [] $5 }-  | 'type' 'constraint' name tysyn_params '=' type-                           {% at ($2,$6) `fmap` mkPropSyn $3 (reverse $4) $6 }-  | 'type' 'constraint' tysyn_param op tysyn_param '=' type-                           {% at ($2,$7) `fmap` mkPropSyn $4 [$3, $5] $7 }+  | typeOrPropSyn          { $1 }    | 'infixl' NUM ops       {% mkFixity LeftAssoc  $2 (reverse $3) }   | 'infixr' NUM ops       {% mkFixity RightAssoc $2 (reverse $3) }   | 'infix'  NUM ops       {% mkFixity NonAssoc   $2 (reverse $3) }  -newtype                 :: { Newtype PName }-  : 'newtype' qname '=' newtype_body-                           { Newtype $2 [] (thing $4) }-  | 'newtype' qname tysyn_params '=' newtype_body-                           { Newtype $2 (reverse $3) (thing $5) }+typeOrPropSyn                      :: { Decl PName }+  : 'type' 'constraint' type '=' type {% mkPropSyn $3 $5 }+  | 'type'              type '=' type {% mkTySyn   $2 $4 } +topTypeConstraint                  :: { Located [Prop PName] }+  : 'type' 'constraint' type          {% mkProp $3 }+++propguards_cases                   :: { [PropGuardCase PName] }+  : propguards_cases propguards_case  { $2 : $1 }+  | propguards_case                   { [$1] }++propguards_case                    :: { PropGuardCase PName }+  : '|' propguards_quals '=>' expr    { PropGuardCase $2 $4 }++propguards_quals                   :: { [Located (Prop PName)] }+  : type                              {% mkPropGuards $1 }+++newtype                            :: { Newtype PName }+  : 'newtype' type '=' newtype_body   {% mkNewtype $2 $4 }+ newtype_body            :: { Located (RecordMap Ident (Range, Type PName)) }   : '{' '}'                {% mkRecord (rComb $1 $2) (Located emptyRange) [] }   | '{' field_types '}'    {% mkRecord (rComb $1 $3) (Located emptyRange) $2 }@@ -516,13 +578,13 @@   : expr 'then' expr              { ($1, $3) }  simpleRHS                      :: { Expr PName }-  : '-' simpleApp                 { at ($1,$2) (ENeg $2) }-  | '~' simpleApp                 { at ($1,$2) (EComplement $2) }+  : '-' simpleApp                 { at ($1,$2) (EPrefix PrefixNeg $2) }+  | '~' simpleApp                 { at ($1,$2) (EPrefix PrefixComplement $2) }   | simpleApp                     { $1 }  longRHS                        :: { Expr PName }-  : '-' longApp                   { at ($1,$2) (ENeg $2) }-  | '~' longApp                   { at ($1,$2) (EComplement $2) }+  : '-' longApp                   { at ($1,$2) (EPrefix PrefixNeg $2) }+  | '~' longApp                   { at ($1,$2) (EPrefix PrefixComplement $2) }   | longApp                       { $1 }  @@ -720,14 +782,6 @@   : schema_param                    { [$1] }   | schema_params ',' schema_param  { $3 : $1 } -tysyn_param                   :: { TParam PName }-  : ident                        {% mkTParam $1 Nothing }-  | '(' ident ':' kind ')'       {% mkTParam (at ($1,$5) $2) (Just (thing $4)) }--tysyn_params                  :: { [TParam PName]  }-  : tysyn_param                  { [$1]      }-  | tysyn_params tysyn_param     { $2 : $1   }- type                           :: { Type PName              }   : infix_type '->' type          { at ($1,$3) $ TFun $1 $3 }   | infix_type                    { $1                      }@@ -748,13 +802,17 @@   | NUM                           { at $1 $ TNum  (getNum $1)          }   | CHARLIT                       { at $1 $ TChar (getChr $1)          }   | '[' type ']'                  { at ($1,$3) $ TSeq $2 TBit          }-  | '(' type ')'                  { at ($1,$3) $ TParens $2            }+  | '(' ktype ')'                 { at ($1,$3) $2                      }   | '(' ')'                       { at ($1,$2) $ TTuple []             }   | '(' tuple_types ')'           { at ($1,$3) $ TTuple  (reverse $2)  }   | '{' '}'                       {% mkRecord (rComb $1 $2) TRecord [] }   | '{' field_types '}'           {% mkRecord (rComb $1 $3) TRecord $2 }   | '_'                           { at $1 TWild                        } +ktype                          :: { Type PName }+  : type ':' kind                 { TParens $1 (Just (thing $3)) }+  | type                          { TParens $1 Nothing }+ atypes                         :: { [ Type PName ] }   : atype                         { [ $1 ]    }   | atypes atype                  { $2 : $1   }@@ -795,8 +853,7 @@  modName                        :: { Located ModName }   : smodName                      { $1 }-  | '`' smodName                  { fmap paramInstModName $2 }-+  | 'module' smodName             { $2 }  qname                          :: { Located PName }   : name                          { $1 }@@ -860,8 +917,8 @@                       Layout   -> programLayout                       NoLayout -> program -parseModule :: Config -> Text -> Either ParseError (Module PName)-parseModule cfg = parse cfg { cfgModuleScope = True } vmodule+parseModule :: Config -> Text -> Either ParseError [Module PName]+parseModule cfg = parse cfg { cfgModuleScope = True } top_module  parseProgram :: Layout -> Text -> Either ParseError (Program PName) parseProgram l = parseProgramWith defaultConfig { cfgLayout = l }
src/Cryptol/Parser/AST.hs view
@@ -16,6 +16,8 @@ {-# LANGUAGE PatternGuards #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE BlockArguments #-}+{-# LANGUAGE FlexibleInstances #-} module Cryptol.Parser.AST   ( -- * Names     Ident, mkIdent, mkInfix, isInfixIdent, nullIdent, identText@@ -39,8 +41,20 @@     -- * Declarations   , Module   , ModuleG(..)+  , mDecls        -- XXX: Temporary+   , mImports-  , mSubmoduleImports+  , mModParams+  , mIsFunctor+  , isParamDecl++  , ModuleDefinition(..)+  , ModuleInstanceArgs(..)+  , ModuleInstanceNamedArg(..)+  , ModuleInstanceArg(..)+  , ModuleInstance+  , emptyModuleInstance+   , Program(..)   , TopDecl(..)   , Decl(..)@@ -59,6 +73,11 @@   , ParameterType(..)   , ParameterFun(..)   , NestedModule(..)+  , Signature(..)+  , SigDecl(..)+  , ModParam(..)+  , ParamDecl(..)+  , PropGuardCase(..)      -- * Interactive   , ReplInput(..)@@ -74,6 +93,9 @@   , UpdHow(..)   , FunDesc(..)   , emptyFunDesc+  , PrefixOp(..)+  , prefixFixity+  , asEApps      -- * Positions   , Located(..)@@ -92,9 +114,11 @@ import Cryptol.Utils.RecordMap import Cryptol.Utils.PP +import           Data.Map(Map)+import qualified Data.Map as Map import           Data.List(intersperse) import           Data.Bits(shiftR)-import           Data.Maybe (catMaybes)+import           Data.Maybe (catMaybes,mapMaybe) import           Data.Ratio(numerator,denominator) import           Data.Text (Text) import           Numeric(showIntAtBase,showFloat,showHFloat)@@ -122,36 +146,85 @@ newtype Program name = Program [TopDecl name]                        deriving (Show) --- | A parsed module.+{- | A module for the pre-typechecker phasese. The two parameters are:++  * @mname@ the type of module names. This is because top-level and nested+    modules use differnt types to identify a module.++  * @name@ the type of identifiers used by declarations.+    In the parser this starts off as `PName` and after resolving names+    in the renamer, this becomes `Name`.+-} data ModuleG mname name = Module   { mName     :: Located mname              -- ^ Name of the module-  , mInstance :: !(Maybe (Located ModName)) -- ^ Functor to instantiate-                                            -- (if this is a functor instnaces)-  -- , mImports  :: [Located Import]           -- ^ Imports for the module-  , mDecls    :: [TopDecl name]             -- ^ Declartions for the module+  , mDef      :: ModuleDefinition name   } deriving (Show, Generic, NFData) ++-- | Different flavours of module we have.+data ModuleDefinition name =+    NormalModule [TopDecl name]++  | FunctorInstance (Located (ImpName name))+                    (ModuleInstanceArgs name)+                    (ModuleInstance name)+    -- ^ The instance is filled in by the renamer++  | InterfaceModule (Signature name)+    deriving (Show, Generic, NFData)++{- | Maps names in the original functor with names in the instnace.+Does *NOT* include the parameters, just names for the definitions.+This *DOES* include entrirs for all the name in the instantiated functor,+including names in modules nested inside the functor. -}+type ModuleInstance name = Map name name++emptyModuleInstance :: Ord name => ModuleInstance name+emptyModuleInstance = mempty+++-- XXX: Review all places this is used, that it actually makes sense+-- Probably shouldn't exist+mDecls :: ModuleG mname name -> [TopDecl name]+mDecls m =+  case mDef m of+    NormalModule ds         -> ds+    FunctorInstance _ _ _   -> []+    InterfaceModule {}      -> []++-- | Imports of top-level (i.e. "file" based) modules. mImports :: ModuleG mname name -> [ Located Import ] mImports m =-  [ li { thing = i { iModule = n } }-  | DImport li <- mDecls m-  , let i = thing li-  , ImpTop n  <- [iModule i]-  ]+  case mDef m of+    NormalModule ds     -> mapMaybe topImp [ li | DImport li <- ds ]+    FunctorInstance {}  -> []+    InterfaceModule sig -> mapMaybe topImp (sigImports sig)+  where+  topImp li = case iModule i of+               ImpTop n -> Just li { thing = i { iModule = n } }+               _        -> Nothing+    where i = thing li -mSubmoduleImports :: ModuleG mname name -> [ Located (ImportG name) ]-mSubmoduleImports m =-  [ li { thing = i { iModule = n } }-  | DImport li <- mDecls m-  , let i = thing li-  , ImpNested n  <- [iModule i]-  ] +-- | Get the module parameters of a module (new module system)+mModParams :: ModuleG mname name -> [ ModParam name ]+mModParams m = [ p | DModParam p <- mDecls m ] +mIsFunctor :: ModuleG mname nmae -> Bool+mIsFunctor m = any isParamDecl (mDecls m) -type Module = ModuleG ModName+isParamDecl :: TopDecl a -> Bool+isParamDecl d =+  case d of+    DModParam {} -> True+    DParamDecl {} -> True+    _ -> False  +-- | A top-level module+type Module = ModuleG ModName++-- | A nested module. newtype NestedModule name = NestedModule (ModuleG name name)   deriving (Show,Generic,NFData) @@ -164,39 +237,110 @@     , Just (Range { from = start, to = start, source = "" })     ] -+-- | A declaration that may only appear at the top level of a module.+-- The module may be nested, however. data TopDecl name =     Decl (TopLevel (Decl name))   | DPrimType (TopLevel (PrimType name))   | TDNewtype (TopLevel (Newtype name)) -- ^ @newtype T as = t-  | Include (Located FilePath)          -- ^ @include File@-  | DParameterType (ParameterType name) -- ^ @parameter type T : #@-  | DParameterConstraint [Located (Prop name)]-                                        -- ^ @parameter type constraint (fin T)@+  | Include (Located FilePath)          -- ^ @include File@ (until NoInclude)++  | DParamDecl Range (Signature name)   -- ^ @parameter ...@ (parser only)++  | DModule (TopLevel (NestedModule name))      -- ^ @submodule M where ...@+  | DImport (Located (ImportG (ImpName name)))  -- ^ @import X@+  | DModParam (ModParam name)                   -- ^ @import interface X ...@+  | DInterfaceConstraint (Maybe Text) (Located [Prop name])+    -- ^ @interface constraint@+    deriving (Show, Generic, NFData)+++-- | Things that maybe appear in an interface/parameter block.+-- These only exist during parsering.+data ParamDecl name =++    DParameterType (ParameterType name) -- ^ @parameter type T : #@ (parser only)   | DParameterFun  (ParameterFun name)  -- ^ @parameter someVal : [256]@-  | DModule (TopLevel (NestedModule name))  -- ^ Nested module-  | DImport (Located (ImportG (ImpName name)))  -- ^ An import declaration-                    deriving (Show, Generic, NFData)+                                        -- (parser only) -data ImpName name =-    ImpTop    ModName-  | ImpNested name+  | DParameterDecl (SigDecl name)       -- ^ A delcaration in an interface++  | DParameterConstraint [Located (Prop name)]+    -- ^ @parameter type constraint (fin T)@+     deriving (Show, Generic, NFData) ++-- | All arguments in a functor instantiation+data ModuleInstanceArgs name =+    DefaultInstArg (Located (ModuleInstanceArg name))+    -- ^ Single parameter instantitaion++  | DefaultInstAnonArg [TopDecl name]+    -- ^ Single parameter instantitaion using this anonymous module.+    -- (parser only)++  | NamedInstArgs  [ModuleInstanceNamedArg name]++    deriving (Show, Generic, NFData)++-- | A named argument in a functor instantiation+data ModuleInstanceNamedArg name =+  ModuleInstanceNamedArg (Located Ident) (Located (ModuleInstanceArg name))+  deriving (Show, Generic, NFData)++-- | An argument in a functor instantiation+data ModuleInstanceArg name =+    ModuleArg (ImpName name)  -- ^ An argument that is a module+  | ParameterArg Ident        -- ^ An argument that is a parameter+  | AddParams                 -- ^ Arguments adds extra parameters to decls.+                              -- ("backtick" import)+    deriving (Show, Generic, NFData)+++-- | The name of an imported module+data ImpName name =+    ImpTop    ModName           -- ^ A top-level module+  | ImpNested name              -- ^ The module in scope with the given name+    deriving (Show, Generic, NFData, Eq, Ord)++-- | A simple declaration.  Generally these are things that can appear+-- both at the top-level of a module and in `where` clauses. data Decl name = DSignature [Located name] (Schema name)+                 -- ^ A type signature.  Eliminated in NoPat--after NoPat+                 -- signatures are in their associated Bind+                | DFixity !Fixity [Located name]+                 -- ^ A fixity declaration. Eliminated in NoPat---after NoPat+                 -- fixities are in their associated Bind+                | DPragma [Located name] Pragma+                 -- ^ A pragma declaration. Eliminated in NoPat---after NoPat+                 -- fixities are in their associated Bind+                | DBind (Bind name)+                -- ^ A non-recursive binding.+                | DRec [Bind name]-                 -- ^ A group of recursive bindings, introduced by the renamer.+                 -- ^ A group of recursive bindings. Introduced by the renamer.+                | DPatBind (Pattern name) (Expr name)+                 -- ^ A pattern binding. Eliminated in NoPat---after NoPat+                 -- fixities are in their associated Bind+                | DType (TySyn name)+                 -- ^ A type synonym.+                | DProp (PropSyn name)+                 -- ^ A constraint synonym.+                | DLocated (Decl name) Range+                 -- ^ Keeps track of the location of a declaration.+                  deriving (Eq, Show, Generic, NFData, Functor)  --- | A type parameter+-- | A type parameter for a module. data ParameterType name = ParameterType   { ptName    :: Located name     -- ^ name of type parameter   , ptKind    :: Kind             -- ^ kind of parameter@@ -205,7 +349,7 @@   , ptNumber  :: !Int             -- ^ number of the parameter   } deriving (Eq,Show,Generic,NFData) --- | A value parameter+-- | A value parameter for a module. data ParameterFun name = ParameterFun   { pfName   :: Located name      -- ^ name of value parameter   , pfSchema :: Schema name       -- ^ schema for parameter@@ -214,12 +358,67 @@   } deriving (Eq,Show,Generic,NFData)  +{- | Interface Modules (aka types of functor arguments)++IMPORTANT: Interface Modules are a language construct and are different from+the notion of "interface" in the Cryptol implementation.++Note that the names *defined* in an interface module are only really used in the+other members of the interface module.  When an interface module  is "imported"+as a functor parameter these names are instantiated to new names,+because there could be multiple paramers using the same interface. -}+data Signature name = Signature+  { sigImports      :: ![Located (ImportG (ImpName name))]+    -- ^ Add things in scope+  , sigTypeParams   :: [ParameterType name]     -- ^ Type parameters+  , sigConstraints  :: [Located (Prop name)]+    -- ^ Constraints on the type parameters and type synonyms.+  , sigDecls        :: [SigDecl name]+    -- ^ Type and constraint synonyms+  , sigFunParams    :: [ParameterFun name]      -- ^ Value parameters+  } deriving (Show,Generic,NFData)++-- | A constraint or type synonym declared in an interface.+data SigDecl name =+    SigTySyn (TySyn name) (Maybe Text)+  | SigPropSyn (PropSyn name) (Maybe Text)+    deriving (Show,Generic,NFData)++{- | A module parameter declaration.++> import interface A+> import interface A as B++The name of the parameter is derived from the `as` clause.  If there+is no `as` clause then it is derived from the name of the interface module.++If there is no `as` clause, then the type/value parameters are unqualified,+and otherwise they are qualified.+-}+data ModParam name = ModParam+  { mpSignature     :: Located (ImpName name)  -- ^ Signature for parameter+  , mpAs            :: Maybe ModName        -- ^ Qualified for actual params+  , mpName          :: !Ident+    {- ^ Parameter name (for inst.)+    Note that this is not resolved in the renamer, and is only used+    when instantiating a functor. -}++  , mpDoc           :: Maybe (Located Text) -- ^ Optional documentation+  , mpRenaming      :: !(Map name name)+    {- ^ Filled in by the renamer.+      Maps the actual (value/type) parameter names to the names in the+      interface module. -}+  } deriving (Eq,Show,Generic,NFData)++ -- | An import declaration. data ImportG mname = Import   { iModule    :: !mname   , iAs        :: Maybe ModName   , iSpec      :: Maybe ImportSpec-  } deriving (Eq, Show, Generic, NFData)+  , iInst      :: !(Maybe (ModuleInstanceArgs PName))+    -- ^ `iInst' exists only during parsing+  } deriving (Show, Generic, NFData)  type Import = ImportG ModName @@ -276,17 +475,27 @@ type LBindDef = Located (BindDef PName)  data BindDef name = DPrim+                  | DForeign                   | DExpr (Expr name)+                  | DPropGuards [PropGuardCase name]                     deriving (Eq, Show, Generic, NFData, Functor) +data PropGuardCase name = PropGuardCase+  { pgcProps :: [Located (Prop name)]+  , pgcExpr  :: Expr name+  }+  deriving (Eq,Generic,NFData,Functor,Show)+ data Pragma   = PragmaNote String               | PragmaProperty                 deriving (Eq, Show, Generic, NFData) -data Newtype name = Newtype { nName   :: Located name        -- ^ Type name-                            , nParams :: [TParam name]       -- ^ Type params-                            , nBody   :: Rec (Type name)     -- ^ Body-                            } deriving (Eq, Show, Generic, NFData)+data Newtype name = Newtype+  { nName     :: Located name        -- ^ Type name+  , nParams   :: [TParam name]       -- ^ Type params+  , nConName  :: !name               -- ^ Constructor function name+  , nBody     :: Rec (Type name)     -- ^ Body+  } deriving (Eq, Show, Generic, NFData)  -- | A declaration for a type with no implementation. data PrimType name = PrimType { primTName :: Located name@@ -341,8 +550,6 @@  data Expr n   = EVar n                          -- ^ @ x @               | ELit Literal                    -- ^ @ 0x10 @-              | ENeg (Expr n)                   -- ^ @ -1 @-              | EComplement (Expr n)            -- ^ @ ~1 @               | EGenerate (Expr n)              -- ^ @ generate f @               | ETuple [Expr n]                 -- ^ @ (1,2,3) @               | ERecord (Rec (Expr n))          -- ^ @ { x = 1, y = 2 } @@@ -373,8 +580,20 @@               | ESplit (Expr n)                 -- ^ @ splitAt x @ (Introduced by NoPat)               | EParens (Expr n)                -- ^ @ (e)   @ (Removed by Fixity)               | EInfix (Expr n) (Located n) Fixity (Expr n)-- ^ @ a + b @ (Removed by Fixity)+              | EPrefix PrefixOp (Expr n)       -- ^ @ -1, ~1 @                 deriving (Eq, Show, Generic, NFData, Functor) +-- | Prefix operator.+data PrefixOp = PrefixNeg -- ^ @ - @+              | PrefixComplement -- ^ @ ~ @+                deriving (Eq, Show, Generic, NFData)++prefixFixity :: PrefixOp -> Fixity+prefixFixity op = Fixity { fAssoc = LeftAssoc, .. }+  where fLevel = case op of+          PrefixNeg        -> 80+          PrefixComplement -> 100+ -- | Description of functions.  Only trivial information is provided here --   by the parser.  The NoPat pass fills this in as required. data FunDesc n =@@ -439,7 +658,7 @@             | TTuple [Type n]         -- ^ @([8], [32])@             | TWild                   -- ^ @_@, just some type.             | TLocated (Type n) Range -- ^ Location information-            | TParens (Type n)        -- ^ @ (ty) @+            | TParens (Type n) (Maybe Kind)       -- ^ @ (ty) @             | TInfix (Type n) (Located n) Fixity (Type n) -- ^ @ ty + ty @               deriving (Eq, Show, Generic, NFData, Functor) @@ -530,12 +749,29 @@       DPrimType pt -> getLoc pt       TDNewtype n -> getLoc n       Include lfp -> getLoc lfp+      DModule d -> getLoc d+      DImport d -> getLoc d+      DModParam d -> getLoc d+      DParamDecl r _ -> Just r+      DInterfaceConstraint _ ds -> getLoc ds++instance HasLoc (ParamDecl name) where+  getLoc pd =+    case pd of       DParameterType d -> getLoc d       DParameterFun d  -> getLoc d+      DParameterDecl d -> getLoc d       DParameterConstraint d -> getLoc d-      DModule d -> getLoc d-      DImport d -> getLoc d +instance HasLoc (SigDecl name) where+  getLoc decl =+    case decl of+      SigTySyn ts _    -> getLoc ts+      SigPropSyn ps _  -> getLoc ps++instance HasLoc (ModParam name) where+  getLoc mp = getLoc (mpSignature mp)+ instance HasLoc (PrimType name) where   getLoc pt = Just (rComb (srcRange (primTName pt)) (srcRange (primTKind pt))) @@ -565,7 +801,14 @@     where     locs = catMaybes ([ getLoc (nName n)] ++ map (Just . fst . snd) (displayFields (nBody n))) +instance HasLoc (TySyn name) where+  getLoc (TySyn x _ _ _) = getLoc x +instance HasLoc (PropSyn name) where+  getLoc (PropSyn x _ _ _) = getLoc x+++ --------------------------------------------------------------------------------  @@ -588,22 +831,56 @@   instance (Show name, PPName mname, PPName name) => PP (ModuleG mname name) where-  ppPrec _ = ppModule 0+  ppPrec _ = ppModule "module" +instance (Show name, PPName name) => PP (NestedModule name) where+  ppPrec _ (NestedModule m) = ppModule "submodule" m+ ppModule :: (Show name, PPName mname, PPName name) =>-  Int -> ModuleG mname name -> Doc-ppModule n m =-  text "module" <+> ppL (mName m) <+> text "where" $$ nest n body+  Doc -> ModuleG mname name -> Doc+ppModule kw m = kw' <+> ppL (mName m) <+> pp (mDef m)   where-  body = vcat (map ppL (mImports m))-      $$ vcat (map pp (mDecls m))+  kw' = case mDef m of+          InterfaceModule {} -> "interface" <+> kw+          _                  -> kw  +instance (Show name, PPName name) => PP (ModuleDefinition name) where+  ppPrec _ def =+    case def of+      NormalModule ds -> "where" $$ indent 2 (vcat (map pp ds))+      FunctorInstance f as inst -> vcat ( ("=" <+> pp (thing f) <+> pp as)+                                        : ppInst+                                        )+        where+        ppInst    = if null inst then [] else [ indent 2+                                                  (vcat ("/* Instance:" :+                                                        instLines ++ [" */"]))+                                              ]+        instLines = [ " *" <+> pp k <+> "->" <+> pp v+                    | (k,v) <- Map.toList inst ]+      InterfaceModule s -> ppInterface "where" s -instance (Show name, PPName name) => PP (NestedModule name) where-  ppPrec _ (NestedModule m) = ppModule 2 m +instance (Show name, PPName name) => PP (ModuleInstanceArgs name) where+  ppPrec _ arg =+    case arg of+      DefaultInstArg x -> braces (pp (thing x))+      DefaultInstAnonArg ds -> "where" $$ indent 2 (vcat (map pp ds))+      NamedInstArgs xs -> braces (commaSep (map pp xs)) +instance (Show name, PPName name) => PP (ModuleInstanceNamedArg name) where+  ppPrec _ (ModuleInstanceNamedArg x y) = pp (thing x) <+> "=" <+> pp (thing y)+++instance (Show name, PPName name) => PP (ModuleInstanceArg name) where+  ppPrec _ arg =+    case arg of+      ModuleArg x    -> pp x+      ParameterArg i -> "parameter" <+> pp i+      AddParams      -> "{}"++ instance (Show name, PPName name) => PP (Program name) where   ppPrec _ (Program ds) = vcat (map pp ds) @@ -614,27 +891,77 @@       DPrimType p -> pp p       TDNewtype n -> pp n       Include l   -> text "include" <+> text (show (thing l))+      DModule d -> pp d+      DImport i -> pp (thing i)+      DModParam s -> pp s+      DParamDecl _ ds -> ppInterface "parameter" ds+      DInterfaceConstraint _ ds ->+        "interface constraint" <+>+        case map pp (thing ds) of+          [x] -> x+          []  -> "()"+          xs  -> nest 1 (parens (commaSepFill xs))++instance (Show name, PPName name) => PP (ParamDecl name) where+  ppPrec _ pd =+    case pd of       DParameterFun d -> pp d       DParameterType d -> pp d+      DParameterDecl d -> pp d       DParameterConstraint d ->-        "parameter" <+> "type" <+> "constraint" <+> prop-        where prop = case map (pp . thing) d of-                       [x] -> x-                       []  -> "()"-                       xs  -> nest 1 (parens (commaSepFill xs))-      DModule d -> pp d-      DImport i -> pp (thing i)+        "type constraint" <+> parens (commaSep (map (pp . thing) d)) +ppInterface :: (Show name, PPName name) => Doc -> Signature name -> Doc+ppInterface kw sig = kw $$ indent 2 (vcat (is ++ ds))+    where+    is = map pp (sigImports sig)+    cs = case sigConstraints sig of+           []  -> []+           cs' -> ["type constraint" <+>+                       parens (commaSep (map (pp . thing) cs'))]+    ds = map pp (sigTypeParams sig)+      ++ map pp (sigDecls sig)+      ++ cs+      ++ map pp (sigFunParams sig)++instance (Show name, PPName name) => PP (SigDecl name) where+  ppPrec p decl =+    case decl of+      SigTySyn ts _   -> ppPrec p ts+      SigPropSyn ps _ -> ppPrec p ps+++instance (Show name, PPName name) => PP (ModParam name) where+  ppPrec _ mp = vcat ( mbDoc+                  ++ [ "import interface" <+>+                                    pp (thing (mpSignature mp)) <+> mbAs ]+                  ++ mbRen+                     )+    where+    mbDoc = case mpDoc mp of+              Nothing -> []+              Just d  -> [pp d]+    mbAs  = case mpAs mp of+              Nothing -> mempty+              Just d  -> "as" <+> pp d+    mbRen+      | Map.null (mpRenaming mp) = []+      | otherwise =+        [ indent 2 $ vcat $ "/* Parameters"+                          : [ " *" <+> pp x <+> "->" <+> pp y+                            | (x,y) <- Map.toList (mpRenaming mp) ]+                         ++ [" */"] ]+ instance (Show name, PPName name) => PP (PrimType name) where   ppPrec _ pt =     "primitive" <+> "type" <+> pp (primTName pt) <+> ":" <+> pp (primTKind pt)  instance (Show name, PPName name) => PP (ParameterType name) where-  ppPrec _ a = text "parameter" <+> text "type" <+>+  ppPrec _ a = text "type" <+>                ppPrefixName (ptName a) <+> text ":" <+> pp (ptKind a)  instance (Show name, PPName name) => PP (ParameterFun name) where-  ppPrec _ a = text "parameter" <+> ppPrefixName (pfName a) <+> text ":"+  ppPrec _ a = ppPrefixName (pfName a) <+> text ":"                   <+> pp (pfSchema a)  @@ -662,11 +989,23 @@     , ppRecord (map (ppNamed' ":") (displayFields (nBody nt)))     ] -instance PP mname => PP (ImportG mname) where-  ppPrec _ d = text "import" <+> sep ([pp (iModule d)] ++ mbAs ++ mbSpec)+instance (PP mname) => PP (ImportG mname) where+  ppPrec _ d = vcat [ text "import" <+> sep ([pp (iModule d)] ++ mbInst +++                                                      mbAs ++ mbSpec)+                    , indent 2 mbWhere+                    ]     where     mbAs   = maybe [] (\ name -> [text "as" <+> pp name]) (iAs d)     mbSpec = maybe [] (\x -> [pp x]) (iSpec d)+    mbInst = case iInst d of+                Just (DefaultInstArg x) -> [ braces (pp (thing x)) ]+                Just (NamedInstArgs xs) -> [ braces (commaSep (map pp xs)) ]+                _ -> []+    mbWhere = case iInst d of+                Just (DefaultInstAnonArg ds) ->+                  "where" $$ vcat (map pp ds)+                _ -> mempty+   instance PP name => PP (ImpName name) where   ppPrec _ nm =@@ -713,7 +1052,9 @@  instance (Show name, PPName name) => PP (BindDef name) where   ppPrec _ DPrim     = text "<primitive>"+  ppPrec _ DForeign  = text "<foreign>"   ppPrec p (DExpr e) = ppPrec p e+  ppPrec _p (DPropGuards _guards) = text "propguards"   instance PPName name => PP (TySyn name) where@@ -816,8 +1157,6 @@       EVar x        -> ppPrefixName x       ELit x        -> pp x -      ENeg x        -> wrap n 3 (text "-" <.> ppPrec 4 x)-      EComplement x -> wrap n 3 (text "~" <.> ppPrec 4 x)       EGenerate x   -> wrap n 3 (text "generate" <+> ppPrec 4 x)        ETuple es     -> parens (commaSep (map pp es))@@ -877,12 +1216,19 @@        EParens e -> parens (pp e) +      -- NOTE: these don't produce correctly parenthesized expressions without+      -- explicit EParens nodes when necessary, since we don't check the actual+      -- fixities of the operators.       EInfix e1 op _ e2 -> wrap n 0 (pp e1 <+> ppInfixName (thing op) <+> pp e2)++      EPrefix op e  -> wrap n 3 (text (prefixText op) <.> ppPrec 4 e)    where    isInfix (EApp (EApp (EVar ieOp) ieLeft) ieRight) = do      ieFixity <- ppNameFixity ieOp      return Infix { .. }    isInfix _ = Nothing+   prefixText PrefixNeg        = "-"+   prefixText PrefixComplement = "~"  instance (Show name, PPName name) => PP (UpdField name) where   ppPrec _ (UpdField h xs e) = ppNestedSels (map thing xs) <+> pp h <+> pp e@@ -963,7 +1309,10 @@        TLocated t _   -> ppPrec n t -      TParens t      -> parens (pp t)+      TParens t mb   -> parens+                          case mb of+                            Nothing -> pp t+                            Just k  -> pp t <+> ":" <+> pp k        TInfix t1 o _ t2 -> optParens (n > 2)                         $ sep [ppPrec 2 t1 <+> ppInfixName o, ppPrec 3 t2]@@ -972,6 +1321,8 @@ instance PPName name => PP (Prop name) where   ppPrec n (CType t) = ppPrec n t +instance PPName name => PP [Prop name] where+  ppPrec n props = parens . commaSep . fmap (ppPrec n) $ props  -------------------------------------------------------------------------------- -- Drop all position information, so equality reflects program structure@@ -1000,10 +1351,27 @@  instance NoPos (ModuleG mname name) where   noPos m = Module { mName      = mName m-                   , mInstance  = mInstance m-                   , mDecls     = noPos (mDecls m)+                   , mDef       = noPos (mDef m)                    } +instance NoPos (ModuleDefinition name) where+  noPos m =+    case m of+      NormalModule ds         -> NormalModule (noPos ds)+      FunctorInstance f as ds -> FunctorInstance (noPos f) (noPos as) ds+      InterfaceModule s       -> InterfaceModule (noPos s)++instance NoPos (ModuleInstanceArgs name) where+  noPos as =+    case as of+      DefaultInstArg a      -> DefaultInstArg (noPos a)+      DefaultInstAnonArg ds -> DefaultInstAnonArg (noPos ds)+      NamedInstArgs xs      -> NamedInstArgs (noPos xs)++instance NoPos (ModuleInstanceNamedArg name) where+  noPos (ModuleInstanceNamedArg x y) =+    ModuleInstanceNamedArg (noPos x) (noPos y)+ instance NoPos (NestedModule name) where   noPos (NestedModule m) = NestedModule (noPos m) @@ -1014,13 +1382,43 @@       DPrimType t -> DPrimType (noPos t)       TDNewtype n -> TDNewtype(noPos n)       Include x   -> Include  (noPos x)+      DModule d -> DModule (noPos d)+      DImport d -> DImport (noPos d)+      DModParam d -> DModParam (noPos d)+      DParamDecl _ ds -> DParamDecl rng (noPos ds)+        where rng = Range { from = Position 0 0, to = Position 0 0, source = "" }+      DInterfaceConstraint d ds -> DInterfaceConstraint d (noPos (noPos <$> ds))++instance NoPos (ParamDecl name) where+  noPos pd =+    case pd of       DParameterFun d  -> DParameterFun (noPos d)       DParameterType d -> DParameterType (noPos d)+      DParameterDecl d -> DParameterDecl (noPos d)       DParameterConstraint d -> DParameterConstraint (noPos d)-      DModule d -> DModule (noPos d)-      DImport d -> DImport (noPos d) +instance NoPos (Signature name) where+  noPos sig = Signature { sigImports = sigImports sig+                        , sigTypeParams = map noPos (sigTypeParams sig)+                        , sigDecls = map noPos (sigDecls sig)+                        , sigConstraints = map noPos (sigConstraints sig)+                        , sigFunParams = map noPos (sigFunParams sig)+                        } +instance NoPos (SigDecl name) where+  noPos decl =+    case decl of+      SigTySyn ts mb   -> SigTySyn (noPos ts) mb+      SigPropSyn ps mb -> SigPropSyn (noPos ps) mb++instance NoPos (ModParam name) where+  noPos mp = ModParam { mpSignature = noPos (mpSignature mp)+                      , mpAs        = mpAs mp+                      , mpName      = mpName mp+                      , mpDoc       = noPos <$> mpDoc mp+                      , mpRenaming  = mpRenaming mp+                      }+ instance NoPos (PrimType name) where   noPos x = x @@ -1047,9 +1445,10 @@       DLocated   x _   -> noPos x  instance NoPos (Newtype name) where-  noPos n = Newtype { nName   = noPos (nName n)-                    , nParams = nParams n-                    , nBody   = fmap noPos (nBody n)+  noPos n = Newtype { nName     = noPos (nName n)+                    , nParams   = nParams n+                    , nConName  = nConName n+                    , nBody     = fmap noPos (nBody n)                     }  instance NoPos (Bind name) where@@ -1082,8 +1481,6 @@     case expr of       EVar x          -> EVar     x       ELit x          -> ELit     x-      ENeg x          -> ENeg     (noPos x)-      EComplement x   -> EComplement (noPos x)       EGenerate x     -> EGenerate (noPos x)       ETuple x        -> ETuple   (noPos x)       ERecord x       -> ERecord  (fmap noPos x)@@ -1110,6 +1507,7 @@       ESplit x        -> ESplit (noPos x)       EParens e       -> EParens (noPos e)       EInfix x y f z  -> EInfix (noPos x) y f (noPos z)+      EPrefix op x    -> EPrefix op (noPos x)  instance NoPos (UpdField name) where   noPos (UpdField h xs e) = UpdField h xs (noPos e)@@ -1154,7 +1552,7 @@       TNum n        -> TNum n       TChar n       -> TChar n       TLocated x _  -> noPos x-      TParens x     -> TParens (noPos x)+      TParens x k   -> TParens (noPos x) k       TInfix x y f z-> TInfix (noPos x) y f (noPos z)  instance NoPos (Prop name) where
+ src/Cryptol/Parser/ExpandPropGuards.hs view
@@ -0,0 +1,137 @@+{-# LANGUAGE BlockArguments #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE LambdaCase #-}++-- |+-- Module      :  Cryptol.Parser.PropGuards+-- Copyright   :  (c) 2022 Galois, Inc.+-- License     :  BSD3+-- Maintainer  :  cryptol@galois.com+-- Stability   :  provisional+-- Portability :  portable+--+-- Expands PropGuards into a top-level definition for each case, and rewrites+-- the body of each case to be an appropriate call to the respectively generated+-- function.+module Cryptol.Parser.ExpandPropGuards where++import Control.DeepSeq+import Cryptol.Parser.AST+import Cryptol.Utils.PP+import Cryptol.Utils.Panic (panic)+import Data.Text (pack)+import GHC.Generics (Generic)++-- | Monad+type ExpandPropGuardsM a = Either Error a++runExpandPropGuardsM :: ExpandPropGuardsM a -> Either Error a+runExpandPropGuardsM m = m++-- | Error+data Error = NoSignature (Located PName)+  deriving (Show, Generic, NFData)++instance PP Error where+  ppPrec _ err = case err of+    NoSignature x ->+      text "At" <+> pp (srcRange x) <.> colon+        <+> text "Declarations using constraint guards require an explicit type signature."++expandPropGuards :: ModuleG mname PName -> ExpandPropGuardsM (ModuleG mname PName)+expandPropGuards m =+  do def <- expandModuleDef (mDef m)+     pure m { mDef = def }++expandModuleDef :: ModuleDefinition PName -> ExpandPropGuardsM (ModuleDefinition PName)+expandModuleDef m =+  case m of+    NormalModule ds    -> NormalModule . concat <$> mapM expandTopDecl ds+    FunctorInstance {} -> pure m+    InterfaceModule {} -> pure m++expandTopDecl :: TopDecl PName -> ExpandPropGuardsM [TopDecl PName]+expandTopDecl topDecl =+  case topDecl of+    Decl topLevelDecl ->+      do ds <- expandDecl (tlValue topLevelDecl)+         pure [ Decl topLevelDecl { tlValue = d } | d <- ds ]++    DModule tl | NestedModule m <- tlValue tl ->+      do m1 <- expandPropGuards m+         pure [DModule tl { tlValue = NestedModule m1 }]++    _ -> pure [topDecl]++expandDecl :: Decl PName -> ExpandPropGuardsM [Decl PName]+expandDecl decl =+  case decl of+    DBind bind -> do bs <- expandBind bind+                     pure (map DBind bs)+    _          -> pure [decl]++expandBind :: Bind PName -> ExpandPropGuardsM [Bind PName]+expandBind bind =+  case thing (bDef bind) of+    DPropGuards guards -> do+      Forall params props t rng <-+        case bSignature bind of+          Just schema -> pure schema+          Nothing -> Left . NoSignature $ bName bind+      let goGuard ::+            PropGuardCase PName ->+            ExpandPropGuardsM (PropGuardCase PName, Bind PName)+          goGuard (PropGuardCase props' e) = do+            bName' <- newName (bName bind) (thing <$> props')+            -- call to generated function+            tParams <- case bSignature bind of+              Just (Forall tps _ _ _) -> pure tps+              Nothing -> Left $ NoSignature (bName bind)+            typeInsts <-+              (\(TParam n _ _) -> Right . PosInst $ TUser n [])+                `traverse` tParams+            let e' = foldl EApp (EAppT (EVar $ thing bName') typeInsts) (patternToExpr <$> bParams bind)+            pure+              ( PropGuardCase props' e',+                bind+                  { bName = bName',+                    -- include guarded props in signature+                    bSignature = Just (Forall params+                                         (props <> map thing props')+                                         t rng),+                    -- keeps same location at original bind+                    -- i.e. "on top of" original bind+                    bDef = (bDef bind) {thing = DExpr e}+                  }+              )+      (guards', binds') <- unzip <$> mapM goGuard guards+      pure $+        bind {bDef = DPropGuards guards' <$ bDef bind} :+        binds'+    _ -> pure [bind]++patternToExpr :: Pattern PName -> Expr PName+patternToExpr (PVar locName) = EVar (thing locName)+patternToExpr _ =+  panic "patternToExpr"+    ["Unimplemented: patternToExpr of anything other than PVar"]++newName :: Located PName -> [Prop PName] -> ExpandPropGuardsM (Located PName)+newName locName props =+  pure case thing locName of+    Qual modName ident ->+      let txt = identText ident+          txt' = pack $ show $ pp props+       in Qual modName (mkIdent $ txt <> txt') <$ locName+    UnQual ident ->+      let txt = identText ident+          txt' = pack $ show $ pp props+       in UnQual (mkIdent $ txt <> txt') <$ locName+    NewName _ _ ->+      panic "mkName"+        [ "During expanding prop guards"+        , "tried to make new name from NewName case of PName"+        ]
src/Cryptol/Parser/Layout.hs view
@@ -64,7 +64,11 @@   | let t         = head ts0         rng       = srcRange t         blockCol  = max 1 (col (from rng)) -- see startImplicitBlock-  , isMod && tokenType (thing t) /= KW KW_module =+        implictMod = case map (tokenType . thing) ts0 of+                       KW KW_module : _                   -> False+                       KW KW_interface : KW KW_module : _ -> False+                       _                                  -> True+  , isMod && implictMod =     virt rng VCurlyL : go [ Virtual blockCol ] blockCol True ts0    | otherwise =
src/Cryptol/Parser/Lexer.x view
@@ -98,12 +98,12 @@  -- Please update the docs, if you add new entries. "else"                    { emit $ KW KW_else }-"extern"                  { emit $ KW KW_extern } "if"                      { emit $ KW KW_if } "private"                 { emit $ KW KW_private } "include"                 { emit $ KW KW_include } "module"                  { emit $ KW KW_module } "submodule"               { emit $ KW KW_submodule }+"interface"               { emit $ KW KW_interface } "newtype"                 { emit $ KW KW_newtype } "pragma"                  { emit $ KW KW_pragma } "property"                { emit $ KW KW_property }@@ -115,7 +115,6 @@ "import"                  { emit $ KW KW_import } "as"                      { emit $ KW KW_as } "hiding"                  { emit $ KW KW_hiding }-"newtype"                 { emit $ KW KW_newtype } "down"                    { emit $ KW KW_down } "by"                      { emit $ KW KW_by } @@ -126,6 +125,7 @@ "primitive"               { emit $ KW KW_primitive } "parameter"               { emit $ KW KW_parameter } "constraint"              { emit $ KW KW_constraint }+"foreign"                 { emit $ KW KW_foreign }  "Prop"                    { emit $ KW KW_Prop } 
src/Cryptol/Parser/Name.hs view
@@ -7,6 +7,7 @@ -- Portability :  portable  {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE Safe #-}  module Cryptol.Parser.Name where @@ -33,6 +34,7 @@ -- | Passes that can generate fresh names. data Pass = NoPat           | MonoValues+          | ExpandPropGuards String             deriving (Eq,Ord,Show,Generic)  instance NFData PName@@ -54,8 +56,9 @@ getIdent (NewName p i) = packIdent ("__" ++ pass ++ show i)   where   pass = case p of-           NoPat      -> "p"-           MonoValues -> "mv"+           NoPat              -> "p"+           MonoValues         -> "mv"+           ExpandPropGuards _ -> "epg"  isGeneratedName :: PName -> Bool isGeneratedName x =
src/Cryptol/Parser/Names.hs view
@@ -9,6 +9,8 @@ -- This module defines the scoping rules for value- and type-level -- names in Cryptol. +{-# LANGUAGE Safe #-}+ module Cryptol.Parser.Names   ( tnamesNT   , tnamesT@@ -18,6 +20,7 @@   , tnamesD   , namesB   , namesP+  , namesNT    , boundNames   , boundNamesSet@@ -33,6 +36,9 @@ tnamesNT :: Newtype name -> ([Located name], ()) tnamesNT x = ([ nName x ], ()) +namesNT :: Newtype name -> ([Located name], ())+namesNT x = ([ (nName x) { thing = nConName x } ], ())+ -- | The names defined and used by a group of mutually recursive declarations. namesDs :: Ord name => [Decl name] -> ([Located name], Set name) namesDs ds = (defs, boundLNames defs (Set.unions frees))@@ -63,7 +69,9 @@  namesDef :: Ord name => BindDef name -> Set name namesDef DPrim     = Set.empty+namesDef DForeign  = Set.empty namesDef (DExpr e) = namesE e+namesDef (DPropGuards guards) = Set.unions (map (namesE . pgcExpr) guards)   -- | The names used by an expression.@@ -72,8 +80,6 @@   case expr of     EVar x        -> Set.singleton x     ELit _        -> Set.empty-    ENeg e        -> namesE e-    EComplement e -> namesE e     EGenerate e   -> namesE e     ETuple es     -> Set.unions (map namesE es)     ERecord fs    -> Set.unions (map (namesE . snd) (recordElements fs))@@ -102,6 +108,7 @@     ESplit e      -> namesE e     EParens e     -> namesE e     EInfix a o _ b-> Set.insert (thing o) (Set.union (namesE a) (namesE b))+    EPrefix _ e   -> namesE e  namesUF :: Ord name => UpdField name -> Set name namesUF (UpdField _ _ e) = namesE e@@ -184,16 +191,20 @@  tnamesDef :: Ord name => BindDef name -> Set name tnamesDef DPrim     = Set.empty+tnamesDef DForeign  = Set.empty tnamesDef (DExpr e) = tnamesE e+tnamesDef (DPropGuards guards) = Set.unions (map tnamesPropGuardCase guards) +tnamesPropGuardCase :: Ord name => PropGuardCase name -> Set name+tnamesPropGuardCase c =+  Set.unions (tnamesE (pgcExpr c) : map (tnamesC . thing) (pgcProps c))+ -- | The type names used by an expression. tnamesE :: Ord name => Expr name -> Set name tnamesE expr =   case expr of     EVar _          -> Set.empty     ELit _          -> Set.empty-    ENeg e          -> tnamesE e-    EComplement e   -> tnamesE e     EGenerate e     -> tnamesE e     ETuple es       -> Set.unions (map tnamesE es)     ERecord fs      -> Set.unions (map (tnamesE . snd) (recordElements fs))@@ -224,6 +235,7 @@     ESplit e        -> tnamesE e     EParens e       -> tnamesE e     EInfix a _ _ b  -> Set.union (tnamesE a) (tnamesE b)+    EPrefix _ e     -> tnamesE e  tnamesUF :: Ord name => UpdField name -> Set name tnamesUF (UpdField _ _ e) = tnamesE e@@ -277,6 +289,6 @@     TTyApp fs     -> Set.unions (map (tnamesT . value) fs)     TLocated t _  -> tnamesT t     TUser x ts    -> Set.insert x (Set.unions (map tnamesT ts))-    TParens t     -> tnamesT t+    TParens t _   -> tnamesT t     TInfix a x _ c-> Set.insert (thing x)                                 (Set.union (tnamesT a) (tnamesT c))
src/Cryptol/Parser/NoInclude.hs view
@@ -9,6 +9,7 @@ {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE BlockArguments #-} module Cryptol.Parser.NoInclude   ( removeIncludesModule   , IncludeError(..), ppIncludeError@@ -19,6 +20,8 @@ import qualified Control.Exception as X import qualified Control.Monad.Fail as Fail +import Data.Set(Set)+import qualified Data.Set as Set import Data.ByteString (ByteString) import Data.Either (partitionEithers) import Data.Text(Text)@@ -29,19 +32,20 @@ import System.Directory (makeAbsolute) import System.FilePath (takeDirectory,(</>),isAbsolute) +import Cryptol.Utils.PP hiding ((</>)) import Cryptol.Parser (parseProgramWith) import Cryptol.Parser.AST import Cryptol.Parser.LexerUtils (Config(..),defaultConfig) import Cryptol.Parser.ParserUtils import Cryptol.Parser.Unlit (guessPreProc)-import Cryptol.Utils.PP hiding ((</>))  removeIncludesModule ::   (FilePath -> IO ByteString) ->   FilePath ->   Module PName ->-  IO (Either [IncludeError] (Module PName))-removeIncludesModule reader modPath m = runNoIncM reader modPath (noIncludeModule m)+  IO (Either [IncludeError] (Module PName, Set FilePath))+removeIncludesModule reader modPath m =+  runNoIncM reader modPath (noIncludeModule m)  data IncludeError   = IncludeFailed (Located FilePath)@@ -72,20 +76,40 @@   newtype NoIncM a = M-  { unM :: ReaderT Env (ExceptionT [IncludeError] IO) a }+  { unM :: ReaderT Env+         ( ExceptionT [IncludeError]+         ( StateT Deps+           IO+         )) a } +type Deps = Set FilePath+ data Env = Env { envSeen       :: [Located FilePath]                  -- ^ Files that have been loaded+                , envIncPath    :: FilePath                  -- ^ The path that includes are relative to+                , envFileReader :: FilePath -> IO ByteString                  -- ^ How to load files                } -runNoIncM :: (FilePath -> IO ByteString) -> FilePath -> NoIncM a -> IO (Either [IncludeError] a)++runNoIncM ::+  (FilePath -> IO ByteString) ->+  FilePath ->+  NoIncM a -> IO (Either [IncludeError] (a,Deps)) runNoIncM reader sourcePath m =   do incPath <- getIncPath sourcePath-     runM (unM m) Env { envSeen = [], envIncPath = incPath, envFileReader = reader }+     (mb,s) <- runM (unM m)+                  Env { envSeen = []+                      , envIncPath = incPath+                      , envFileReader = reader+                      }+                  Set.empty+     pure+       do ok <- mb+          pure (ok,s)  tryNoIncM :: NoIncM a -> NoIncM (Either [IncludeError] a) tryNoIncM m = M (try (unM m))@@ -107,11 +131,17 @@ fromIncPath :: FilePath -> NoIncM FilePath fromIncPath path   | isAbsolute path = return path-  | otherwise       = M $+  | otherwise       = M     do Env { .. } <- ask        return (envIncPath </> path) +addDep :: FilePath -> NoIncM ()+addDep path = M+  do s <- get+     let s1 = Set.insert path s+     s1 `seq` set s1 + instance Functor NoIncM where   fmap = liftM @@ -161,9 +191,14 @@  -- | Remove includes from a module. noIncludeModule :: ModuleG mname PName -> NoIncM (ModuleG mname PName)-noIncludeModule m = update `fmap` collectErrors noIncTopDecl (mDecls m)+noIncludeModule m =+  do newDef <- case mDef m of+                 NormalModule ds         -> NormalModule <$> doDecls ds+                 FunctorInstance f as is -> pure (FunctorInstance f as is)+                 InterfaceModule s       -> pure (InterfaceModule s)+     pure m { mDef = newDef }   where-  update tds = m { mDecls = concat tds }+  doDecls    = fmap concat . collectErrors noIncTopDecl  -- | Remove includes from a program. noIncludeProgram :: Program PName -> NoIncM (Program PName)@@ -177,9 +212,8 @@   Decl _     -> pure [td]   DPrimType {} -> pure [td]   TDNewtype _-> pure [td]-  DParameterType {} -> pure [td]-  DParameterConstraint {} -> pure [td]-  DParameterFun {} -> pure [td]+  DParamDecl {} -> pure [td]+  DInterfaceConstraint {} -> pure [td]   Include lf -> resolveInclude lf   DModule tl ->     case tlValue tl of@@ -187,13 +221,17 @@         do m1 <- noIncludeModule m            pure [ DModule tl { tlValue = NestedModule m1 } ]   DImport {} -> pure [td]+  DModParam {} -> pure [td]  -- | Resolve the file referenced by a include into a list of top-level -- declarations. resolveInclude :: Located FilePath -> NoIncM [TopDecl PName] resolveInclude lf = pushPath lf $ do   source <- readInclude lf-  case parseProgramWith (defaultConfig { cfgSource = thing lf, cfgPreProc = guessPreProc (thing lf) }) source of+  let cfg = defaultConfig { cfgSource = thing lf+                          , cfgPreProc = guessPreProc (thing lf)+                          }+  case parseProgramWith cfg source of      Right prog -> do       Program ds <-@@ -206,8 +244,9 @@ -- | Read a file referenced by an include. readInclude :: Located FilePath -> NoIncM Text readInclude path = do-  readBytes    <- envFileReader <$> M ask+  readBytes   <- envFileReader <$> M ask   file        <- fromIncPath (thing path)+  addDep file   sourceBytes <- readBytes file `failsWith` handler   sourceText  <- X.evaluate (T.decodeUtf8' sourceBytes) `failsWith` handler   case sourceText of
src/Cryptol/Parser/NoPat.hs view
@@ -8,8 +8,8 @@ -- -- The purpose of this module is to convert all patterns to variable -- patterns.  It also eliminates pattern bindings by de-sugaring them--- into `Bind`.  Furthermore, here we associate signatures and pragmas--- with the names to which they belong.+-- into `Bind`.  Furthermore, here we associate signatures, fixities,+-- and pragmas with the names to which they belong.  {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-}@@ -17,6 +17,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PatternGuards #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE BlockArguments #-} module Cryptol.Parser.NoPat (RemovePatterns(..),Error(..)) where  import Cryptol.Parser.AST@@ -150,8 +151,6 @@   case expr of     EVar {}       -> return expr     ELit {}       -> return expr-    ENeg e        -> ENeg    <$> noPatE e-    EComplement e -> EComplement <$> noPatE e     EGenerate e   -> EGenerate <$> noPatE e     ETuple es     -> ETuple  <$> mapM noPatE es     ERecord es    -> ERecord <$> traverse (traverse noPatE) es@@ -176,6 +175,7 @@     ESplit e      -> ESplit  <$> noPatE e     EParens e     -> EParens <$> noPatE e     EInfix x y f z-> EInfix  <$> noPatE x <*> pure y <*> pure f <*> noPatE z+    EPrefix op e  -> EPrefix op <$> noPatE e   noPatUF :: UpdField PName -> NoPatM (UpdField PName)@@ -220,10 +220,29 @@           | otherwise        -> panic "NoPat" [ "noMatchB: primitive with params"                                               , show b ] +    DForeign+      | null (bParams b) -> return b+      | otherwise        -> panic "NoPat" [ "noMatchB: foreign with params"+                                          , show b ]+     DExpr e ->       do e' <- noPatFun (Just (thing (bName b))) 0 (bParams b) e          return b { bParams = [], bDef = DExpr e' <$ bDef b } +    DPropGuards guards ->+      do let nm = thing (bName b)+             ps = bParams b+         gs <- mapM (noPatPropGuardCase nm ps) guards+         pure b { bParams = [], bDef = DPropGuards gs <$ bDef b }++noPatPropGuardCase ::+  PName ->+  [Pattern PName] ->+  PropGuardCase PName -> NoPatM (PropGuardCase PName)+noPatPropGuardCase f xs pc =+  do e <- noPatFun (Just f) 0 xs (pgcExpr pc)+     pure pc { pgcExpr = e }+ noMatchD :: Decl PName -> NoPatM [Decl PName] noMatchD decl =   case decl of@@ -334,8 +353,12 @@  noPatModule :: ModuleG mname PName -> NoPatM (ModuleG mname PName) noPatModule m =-  do ds1 <- noPatTopDs (mDecls m)-     return m { mDecls = ds1 }+  do def <-+       case mDef m of+         NormalModule ds -> NormalModule <$> noPatTopDs ds+         FunctorInstance f as i -> pure (FunctorInstance f as i)+         InterfaceModule s -> pure (InterfaceModule s)+     pure m { mDef = def }  -------------------------------------------------------------------------------- @@ -372,23 +395,8 @@              let d1 = DPrimType tl { tlValue = pt }              (d1 :) <$> annotTopDs ds -        DParameterType p ->-          do p1 <- annotParameterType p-             (DParameterType p1 :) <$> annotTopDs ds--        DParameterConstraint {} -> (d :) <$> annotTopDs ds--        DParameterFun p ->-          do AnnotMap { .. } <- get-             let rm _ _ = Nothing-                 name = thing (pfName p)-             case Map.updateLookupWithKey rm name annValueFs of-               (Nothing,_)  -> (d :) <$> annotTopDs ds-               (Just f,fs1) ->-                 do mbF <- lift (checkFixs name f)-                    set AnnotMap { annValueFs = fs1, .. }-                    let p1 = p { pfFixity = mbF }-                    (DParameterFun p1 :) <$> annotTopDs ds+        DParamDecl {} -> (d :) <$> annotTopDs ds+        DInterfaceConstraint {} -> (d :) <$> annotTopDs ds          -- XXX: we may want to add pragmas to newtypes?         TDNewtype {} -> (d :) <$> annotTopDs ds@@ -401,6 +409,8 @@          DImport {} -> (d :) <$> annotTopDs ds +        DModParam {} -> (d :) <$> annotTopDs ds+     [] -> return []  @@ -482,15 +492,6 @@ annotPrimType pt =   do f <- annotTyThing (thing (primTName pt))      pure pt { primTFixity = f }---- | Annotate a module's type parameter.-annotParameterType :: Annotates (ParameterType PName)-annotParameterType pt =-  do f <- annotTyThing (thing (ptName pt))-     pure pt { ptFixity = f }---  -- | Check for multiple signatures. checkSigs :: PName -> [Located (Schema PName)] -> NoPatM (Maybe (Schema PName))
src/Cryptol/Parser/ParserUtils.hs view
@@ -12,16 +12,21 @@ {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE PatternGuards #-}+{-# LANGUAGE BlockArguments #-} {-# LANGUAGE OverloadedStrings #-} -- See Note [-Wincomplete-uni-patterns and irrefutable patterns] in Cryptol.TypeCheck.TypePat {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module Cryptol.Parser.ParserUtils where +import qualified Data.Text as Text+import Data.Char(isAlphaNum) import Data.Maybe(fromMaybe) import Data.Bits(testBit,setBit)+import Data.Maybe(mapMaybe)+import Data.List(foldl') import Data.List.NonEmpty ( NonEmpty(..) ) import qualified Data.List.NonEmpty as NE-import Control.Monad(liftM,ap,unless,guard)+import Control.Monad(liftM,ap,unless,guard,msum) import qualified Control.Monad.Fail as Fail import           Data.Text(Text) import qualified Data.Text as T@@ -40,7 +45,13 @@ import Cryptol.Parser.Token(SelectorType(..)) import Cryptol.Parser.Position import Cryptol.Parser.Utils (translateExprToNumT,widthIdent)-import Cryptol.Utils.Ident(packModName,packIdent,modNameChunks)+import Cryptol.Utils.Ident( packModName,packIdent,modNameChunks+                          , identAnonArg, identAnonIfaceMod+                          , modNameArg, modNameIfaceMod+                          , modNameToText, modNameIsNormal+                          , modNameToNormalModName+                          , unpackIdent+                          ) import Cryptol.Utils.PP import Cryptol.Utils.Panic import Cryptol.Utils.RecordMap@@ -193,6 +204,27 @@ mkModName :: [Text] -> ModName mkModName = packModName +-- | This is how we derive the name of a module parameter from the+-- @import source@ declaration.+mkModParamName :: Located (ImpName PName) -> Maybe (Located ModName) -> Ident+mkModParamName lsig qual =+  case qual of+    Nothing ->+      case thing lsig of+        ImpTop t+          | modNameIsNormal t -> packIdent (last (modNameChunks t))+          | otherwise         -> identAnonIfaceMod+                               $ packIdent+                               $ last+                               $ modNameChunks+                               $ modNameToNormalModName t+        ImpNested nm ->+          case nm of+            UnQual i -> i+            Qual _ i -> i+            NewName {} -> panic "mkModParamName" ["Unexpected NewName",show lsig]+    Just m -> packIdent (last (modNameChunks (thing m)))+ -- Note that type variables are not resolved at this point: they are tcons. mkSchema :: [TParam PName] -> [Prop PName] -> Type PName -> Schema PName mkSchema xs ps t = Forall xs ps t Nothing@@ -272,7 +304,9 @@     TWild        -> bad "Wildcard types"     TUser {}     -> ok -    TParens t    -> validDemotedType rng t+    TParens t mb -> case mb of+                      Nothing -> validDemotedType rng t+                      Just _  -> bad "kind annotation"     TInfix{}     -> ok    where bad x = errorMessage rng [x ++ " cannot be demoted."]@@ -486,7 +520,7 @@ mkParFun :: Maybe (Located Text) ->             Located PName ->             Schema PName ->-            TopDecl PName+            ParamDecl PName mkParFun mbDoc n s = DParameterFun ParameterFun { pfName = n                                                 , pfSchema = s                                                 , pfDoc = thing <$> mbDoc@@ -496,7 +530,7 @@ mkParType :: Maybe (Located Text) ->              Located PName ->              Located Kind ->-             ParseM (TopDecl PName)+             ParseM (ParamDecl PName) mkParType mbDoc n k =   do num <- P $ \_ _ s -> let nu = sNextTyParamNum s                           in Right (nu, s { sNextTyParamNum = nu + 1 })@@ -511,16 +545,17 @@ changeExport :: ExportType -> [TopDecl PName] -> [TopDecl PName] changeExport e = map change   where-  change (Decl d)      = Decl      d { tlExport = e }-  change (DPrimType t) = DPrimType t { tlExport = e }-  change (TDNewtype n) = TDNewtype n { tlExport = e }-  change (DModule m)   = DModule   m { tlExport = e }-  change td@Include{}  = td-  change td@DImport{}  = td-  change (DParameterType {}) = panic "changeExport" ["private type parameter?"]-  change (DParameterFun {})  = panic "changeExport" ["private value parameter?"]-  change (DParameterConstraint {}) =-    panic "changeExport" ["private type constraint parameter?"]+  change decl =+    case decl of+      Decl d                  -> Decl      d { tlExport = e }+      DPrimType t             -> DPrimType t { tlExport = e }+      TDNewtype n             -> TDNewtype n { tlExport = e }+      DModule m               -> DModule   m { tlExport = e }+      DModParam {}            -> decl+      Include{}               -> decl+      DImport{}               -> decl+      DParamDecl{}            -> decl+      DInterfaceConstraint {} -> decl  mkTypeInst :: Named (Type PName) -> TypeInst PName mkTypeInst x | nullIdent (thing (name x)) = PosInst (value x)@@ -532,22 +567,99 @@   | n == widthIdent = errorMessage rng ["`width` is not a valid type parameter name."]   | otherwise       = return (TParam (mkUnqual n) k (Just rng)) -mkTySyn :: Located PName -> [TParam PName] -> Type PName -> ParseM (Decl PName)-mkTySyn ln ps b-  | getIdent (thing ln) == widthIdent =-    errorMessage (srcRange ln) ["`width` is not a valid type synonym name."] -  | otherwise =-    return $ DType $ TySyn ln Nothing ps b+mkTySyn :: Type PName -> Type PName -> ParseM (Decl PName)+mkTySyn thead tdef =+  do (nm,params) <- typeToDecl thead+     pure (DType (TySyn nm Nothing params tdef)) -mkPropSyn :: Located PName -> [TParam PName] -> Type PName -> ParseM (Decl PName)-mkPropSyn ln ps b-  | getIdent (thing ln) == widthIdent =-    errorMessage (srcRange ln) ["`width` is not a valid constraint synonym name."]+mkPropSyn :: Type PName -> Type PName -> ParseM (Decl PName)+mkPropSyn thead tdef =+  do (nm,params) <- typeToDecl thead+     ps          <- thing <$> mkProp tdef+     pure (DProp (PropSyn nm Nothing params ps)) -  | otherwise =-    DProp . PropSyn ln Nothing ps . thing <$> mkProp b+mkNewtype ::+  Type PName ->+  Located (RecordMap Ident (Range, Type PName)) ->+  ParseM (Newtype PName)+mkNewtype thead def =+  do (nm,params) <- typeToDecl thead+     pure (Newtype nm params (thing nm) (thing def)) +typeToDecl :: Type PName -> ParseM (Located PName, [TParam PName])+typeToDecl ty0 =+  case ty0 of+    TLocated ty loc -> goD loc ty+    _ -> panic "typeToDecl" ["Type location is missing."]++  where+  bad loc  = errorMessage loc ["Invalid type declaration"]+  badP loc = errorMessage loc ["Invalid declaration parameter"]+++  goN loc n =+    case n of+      UnQual {} -> pure ()+      _         -> errorMessage loc ["Invalid declaration name"]++  goP loc ty =+    case ty of+      TLocated ty1 loc1 -> goP loc1 ty1++      TUser f [] ->+        do goN loc f+           pure TParam { tpName = f, tpKind = Nothing, tpRange = Just loc }++      TParens t mb ->+        case mb of+          Nothing -> badP loc+          Just k  ->+            do p <- goP loc t+               case tpKind p of+                 Nothing -> pure p { tpKind = Just k }+                 Just {} -> badP loc++      TInfix {}     -> badP loc+      TUser {}      -> badP loc+      TFun {}       -> badP loc+      TSeq {}       -> badP loc+      TBit {}       -> badP loc+      TNum {}       -> badP loc+      TChar {}      -> badP loc+      TRecord {}    -> badP loc+      TWild {}      -> badP loc+      TTyApp {}     -> badP loc+      TTuple {}     -> badP loc+++  goD loc ty =+    case ty of++      TLocated ty1 loc1 -> goD loc1 ty1++      TUser f ts ->+        do goN loc f+           ps <- mapM (goP loc) ts+           pure (Located { thing = f, srcRange = loc },ps)++      TInfix l f _ r ->+        do goN (srcRange f) (thing f)+           a  <- goP loc l+           b  <- goP loc r+           pure (f,[a,b])++      TFun {}       -> bad loc+      TSeq {}       -> bad loc+      TBit {}       -> bad loc+      TNum {}       -> bad loc+      TChar {}      -> bad loc+      TRecord {}    -> bad loc+      TWild {}      -> bad loc+      TTyApp {}     -> bad loc+      TTuple {}     -> bad loc+      TParens {}    -> bad loc+ polyTerm :: Range -> Integer -> Integer -> ParseM (Bool, Integer) polyTerm rng k p   | k == 0          = return (False, p)@@ -610,6 +722,35 @@     rhs = mkGenerate (reverse ixs) e  -- NOTE: The lists of patterns are reversed!+mkPropGuardsDecl ::+  LPName ->+  ([Pattern PName], [Pattern PName]) ->+  [PropGuardCase PName] ->+  ParseM (Decl PName)+mkPropGuardsDecl f (ps, ixs) guards =+  do unless (null ixs) $+      errorMessage (srcRange f)+                  ["Indexed sequence definitions may not use constraint guards"]+     let gs  = reverse guards+     pure $+       DBind Bind { bName       = f+                  , bParams     = reverse ps+                  , bDef        = Located (srcRange f) (DPropGuards gs)+                  , bSignature  = Nothing+                  , bPragmas    = []+                  , bMono       = False+                  , bInfix      = False+                  , bFixity     = Nothing+                  , bDoc        = Nothing+                  , bExport     = Public+                  }++mkConstantPropGuardsDecl ::+  LPName -> [PropGuardCase PName] -> ParseM (Decl PName)+mkConstantPropGuardsDecl f guards =+  mkPropGuardsDecl f ([],[]) guards++-- NOTE: The lists of patterns are reversed! mkIndexedExpr :: ([Pattern PName], [Pattern PName]) -> Expr PName -> Expr PName mkIndexedExpr (ps, ixs) body   | null ps = mkGenerate (reverse ixs) body@@ -624,19 +765,36 @@     where     addIfThen (cond, doexpr) elseExpr = EIf cond doexpr elseExpr --- | Generate a signature and a primitive binding.  The reason for generating--- both instead of just adding the signature at this point is that it means the--- primitive declarations don't need to be treated differently in the noPat+mkPrimDecl :: Maybe (Located Text) -> LPName -> Schema PName -> [TopDecl PName]+mkPrimDecl = mkNoImplDecl DPrim++mkForeignDecl ::+  Maybe (Located Text) -> LPName -> Schema PName -> ParseM [TopDecl PName]+mkForeignDecl mbDoc nm ty =+  do let txt = unpackIdent (getIdent (thing nm))+     unless (all isOk txt)+       (errorMessage (srcRange nm)+            [ "`" ++ txt ++ "` is not a valid foreign name."+            , "The name should contain only alpha-numeric characters or '_'."+            ])+     pure (mkNoImplDecl DForeign mbDoc nm ty)+  where+  isOk c = c == '_' || isAlphaNum c++-- | Generate a signature and a binding for value declarations with no+-- implementation (i.e. primitive or foreign declarations).  The reason for+-- generating both instead of just adding the signature at this point is that it+-- means the declarations don't need to be treated differently in the noPat -- pass.  This is also the reason we add the doc to the TopLevel constructor, -- instead of just place it on the binding directly.  A better solution might be--- to just have a different constructor for primitives.-mkPrimDecl ::-  Maybe (Located Text) -> LPName -> Schema PName -> [TopDecl PName]-mkPrimDecl mbDoc ln sig =+-- to just have a different constructor for primitives and foreigns.+mkNoImplDecl :: BindDef PName+  -> Maybe (Located Text) -> LPName -> Schema PName -> [TopDecl PName]+mkNoImplDecl def mbDoc ln sig =   [ exportDecl mbDoc Public     $ DBind Bind { bName      = ln                  , bParams    = []-                 , bDef       = at sig (Located emptyRange DPrim)+                 , bDef       = at sig (Located emptyRange def)                  , bSignature = Nothing                  , bPragmas   = []                  , bMono      = False@@ -761,6 +919,10 @@ distrLoc x = [ Located { srcRange = r, thing = a } | a <- thing x ]   where r = srcRange x +mkPropGuards :: Type PName -> ParseM [Located (Prop PName)]+mkPropGuards ty =+  do lp <- mkProp ty+     pure [ lp { thing = p } | p <- thing lp ]  mkProp :: Type PName -> ParseM (Located [Prop PName]) mkProp ty =@@ -777,7 +939,10 @@       TInfix{}       -> return [CType t]       TUser{}        -> return [CType t]       TTuple ts      -> concat `fmap` mapM (props r) ts-      TParens t'     -> props r  t'+      TParens t' mb  -> case mb of+                          Nothing -> props r t'+                          Just _  -> err+       TLocated t' r' -> props r' t'        TFun{}    -> err@@ -795,8 +960,7 @@ -- | Make an ordinary module mkModule :: Located ModName -> [TopDecl PName] -> Module PName mkModule nm ds = Module { mName = nm-                        , mInstance = Nothing-                        , mDecls = ds+                        , mDef = NormalModule ds                         }  mkNested :: Module PName -> ParseM (NestedModule PName)@@ -809,23 +973,103 @@   nm = mName m   r = srcRange nm +mkSigDecl :: Maybe (Located Text) -> (Located PName,Signature PName) -> TopDecl PName+mkSigDecl doc (nm,sig) =+  DModule+  TopLevel { tlExport = Public+           , tlDoc    = doc+           , tlValue  = NestedModule+                        Module { mName = nm+                               , mDef  = InterfaceModule sig+                               }+           }++mkInterfaceConstraint ::+  Maybe (Located Text) -> Type PName -> ParseM [TopDecl PName]+mkInterfaceConstraint mbDoc ty =+  do ps <- mkProp ty+     pure [DInterfaceConstraint (thing <$> mbDoc) ps]++mkParDecls :: [ParamDecl PName] -> TopDecl PName+mkParDecls ds = DParamDecl loc (mkInterface' [] ds)+  where loc = rCombs (mapMaybe getLoc ds)++onlySimpleImports :: [Located (ImportG (ImpName PName))] -> ParseM ()+onlySimpleImports = mapM_ check+  where+  check i =+    case iInst (thing i) of+      Nothing -> pure ()+      Just _  ->+        errorMessage (srcRange i)+          [ "Functor instantiations are not supported in this context."+          , "The imported entity needs to be just the name of a module."+          , "A workaround would be to do the instantion in the outer context."+          ]++mkInterface' :: [Located (ImportG (ImpName PName))] ->+             [ParamDecl PName] -> Signature PName+mkInterface' is =+  foldl' add+    Signature { sigImports     = is+              , sigTypeParams  = []+              , sigDecls       = []+              , sigConstraints = []+              , sigFunParams   = []+              }+  where+  add s d =+    case d of+      DParameterType pt       -> s { sigTypeParams  = pt  : sigTypeParams s  }+      DParameterConstraint ps -> s { sigConstraints = ps ++ sigConstraints s }+      DParameterDecl pd       -> s { sigDecls       = pd  : sigDecls s       }+      DParameterFun pf        -> s { sigFunParams   = pf  : sigFunParams s   }++++mkInterface :: [Located (ImportG (ImpName PName))] ->+             [ParamDecl PName] -> ParseM (Signature PName)+mkInterface is ps =+  do onlySimpleImports is+     pure (mkInterface' is ps)++mkIfacePropSyn :: Maybe Text -> Decl PName -> ParamDecl PName+mkIfacePropSyn mbDoc d =+  case d of+    DLocated d1 _ -> mkIfacePropSyn mbDoc d1+    DType ts    -> DParameterDecl (SigTySyn ts mbDoc)+    DProp ps    -> DParameterDecl (SigPropSyn ps mbDoc)+    _ -> panic "mkIfacePropSyn" [ "Unexpected declaration", show (pp d) ]++ -- | Make an unnamed module---gets the name @Main@.-mkAnonymousModule :: [TopDecl PName] -> Module PName-mkAnonymousModule = mkModule Located { srcRange = emptyRange+mkAnonymousModule :: [TopDecl PName] -> ParseM [Module PName]+mkAnonymousModule = mkTopMods+                  . mkModule Located { srcRange = emptyRange                                      , thing    = mkModName [T.pack "Main"]                                      }  -- | Make a module which defines a functor instance.-mkModuleInstance :: Located ModName ->-                    Located ModName ->-                    [TopDecl PName] ->-                    Module PName-mkModuleInstance nm fun ds =-  Module { mName     = nm-         , mInstance = Just fun-         , mDecls    = ds+mkModuleInstanceAnon :: Located ModName ->+                      Located (ImpName PName) ->+                      [TopDecl PName] ->+                      Module PName+mkModuleInstanceAnon nm fun ds =+  Module { mName  = nm+         , mDef   = FunctorInstance fun (DefaultInstAnonArg ds) mempty          } +mkModuleInstance ::+  Located ModName ->+  Located (ImpName PName) ->+  ModuleInstanceArgs PName ->+  Module PName+mkModuleInstance m f as =+  Module { mName = m+         , mDef  = FunctorInstance f as emptyModuleInstance+         }++ ufToNamed :: UpdField PName -> ParseM (Named (Expr PName)) ufToNamed (UpdField h ls e) =   case (h,ls) of@@ -876,5 +1120,237 @@   case tokenType tok of     Selector (TupleSelectorTok n) -> TupleSel n Nothing     Selector (RecordSelectorTok t) -> RecordSel (mkIdent t) Nothing-    _ -> panic "mkSelector"-          [ "Unexpected selector token", show tok ]+    _ -> panic "mkSelector" [ "Unexpected selector token", show tok ]++mkBacktickImport ::+  Range ->+  Located (ImpName PName) ->+  Maybe (Located ModName) ->+  Maybe (Located ImportSpec) ->+  ParseM (Located (ImportG (ImpName PName)))+mkBacktickImport loc impName mbAs mbImportSpec =+  mkImport loc impName (Just inst) mbAs mbImportSpec Nothing+  where+  inst = DefaultInstArg (fmap (const AddParams) impName)+++mkImport ::+  Range ->+  Located (ImpName PName) ->+  Maybe (ModuleInstanceArgs PName) ->+  Maybe (Located ModName) ->+  Maybe (Located ImportSpec) ->+  Maybe (Located [Decl PName]) ->+  ParseM (Located (ImportG (ImpName PName)))++mkImport loc impName optInst mbAs mbImportSpec optImportWhere =+  do i <- getInst+     let end = fromMaybe (srcRange impName)+             $ msum [ srcRange <$> optImportWhere+                    , srcRange <$> mbImportSpec+                    , srcRange <$> mbAs+                    ]++     pure Located { srcRange = rComb loc end+                  , thing    = Import+                                 { iModule    = thing impName+                                 , iAs        = thing <$> mbAs+                                 , iSpec      = thing <$> mbImportSpec+                                 , iInst      = i+                                 }+                  }+  where+  getInst =+    case (optInst,optImportWhere) of+      (Just _, Just _) ->+         errorMessage loc [ "Invalid instantiating import."+                          , "Import should have at most one of:"+                          , "  * { } instantiation, or"+                          , "  * where instantiation"+                          ]+      (Just a, Nothing)  -> pure (Just a)+      (Nothing, Just a)  ->+        pure (Just (DefaultInstAnonArg (map instTop (thing a))))+         where+         instTop d = Decl TopLevel+                            { tlExport = Public+                            , tlDoc    = Nothing+                            , tlValue  = d+                            }+      (Nothing, Nothing) -> pure Nothing++++++mkTopMods :: Module PName -> ParseM [Module PName]+mkTopMods = desugarMod++mkTopSig :: Located ModName -> Signature PName -> [Module PName]+mkTopSig nm sig =+  [ Module { mName = nm+           , mDef  = InterfaceModule sig+           }+  ]+++class MkAnon t where+  mkAnon    :: AnonThing -> t -> t+  toImpName :: t -> ImpName PName++data AnonThing = AnonArg | AnonIfaceMod++instance MkAnon ModName where+  mkAnon what   = case what of+                    AnonArg      -> modNameArg+                    AnonIfaceMod -> modNameIfaceMod+  toImpName     = ImpTop++instance MkAnon PName where+  mkAnon what   = mkUnqual+                . case what of+                    AnonArg      -> identAnonArg+                    AnonIfaceMod -> identAnonIfaceMod+                . getIdent+  toImpName     = ImpNested+++desugarMod :: MkAnon name => ModuleG name PName -> ParseM [ModuleG name PName]+desugarMod mo =+  case mDef mo of++    FunctorInstance f as _ | DefaultInstAnonArg lds <- as ->+      do (ms,lds') <- desugarTopDs (mName mo) lds+         case ms of+           m : _ | InterfaceModule si <- mDef m+                 , l : _ <- map (srcRange . ptName) (sigTypeParams si) +++                            map (srcRange . pfName) (sigFunParams si) +++                            [ srcRange (mName mo) ] ->+              errorMessage l+                [ "Instantiation of a parameterized module may not itself be "+                  ++ "parameterized" ]+           _ -> pure ()+         let i      = mkAnon AnonArg (thing (mName mo))+             nm     = Located { srcRange = srcRange (mName mo), thing = i }+             as'    = DefaultInstArg (ModuleArg . toImpName <$> nm)+         pure [ Module { mName = nm, mDef  = NormalModule lds' }+              , mo { mDef = FunctorInstance f as' mempty }+              ]++    NormalModule ds ->+      do (newMs, newDs) <- desugarTopDs (mName mo) ds+         pure (newMs ++ [ mo { mDef = NormalModule newDs } ])++    _ -> pure [mo]+++desugarTopDs ::+  MkAnon name =>+  Located name ->+  [TopDecl PName] ->+  ParseM ([ModuleG name PName], [TopDecl PName])+desugarTopDs ownerName = go emptySig+  where+  isEmpty s =+    null (sigTypeParams s) && null (sigConstraints s) && null (sigFunParams s)++  emptySig = Signature+    { sigImports      = []+    , sigTypeParams   = []+    , sigDecls        = []+    , sigConstraints  = []+    , sigFunParams    = []+    }++  jnSig s1 s2 = Signature { sigImports      = j sigImports+                          , sigTypeParams   = j sigTypeParams+                          , sigDecls        = j sigDecls+                          , sigConstraints  = j sigConstraints+                          , sigFunParams    = j sigFunParams+                          }++      where+      j f = f s1 ++ f s2++  addI i s = s { sigImports = i : sigImports s }++  go sig ds =+    case ds of++      []+        | isEmpty sig -> pure ([],[])+        | otherwise ->+          do let nm = mkAnon AnonIfaceMod <$> ownerName+             pure ( [ Module { mName = nm+                             , mDef = InterfaceModule sig+                             }+                     ]+                  , [ DModParam+                      ModParam+                        { mpSignature = toImpName <$> nm+                        , mpAs        = Nothing+                        , mpName      = mkModParamName (toImpName <$> nm)+                                                                        Nothing+                        , mpDoc       = Nothing+                        , mpRenaming  = mempty+                        }+                      ]+                  )++      d : more ->+        let cont emit sig' =+              do (ms,ds') <- go sig' more+                 pure (ms, emit ++ ds')+        in+        case d of++          DImport i | ImpTop _ <- iModule (thing i)+                    , Nothing  <- iInst (thing i) ->+            cont [d] (addI i sig)++          DImport i | Just inst <- iInst (thing i) ->+            do newDs <- desugarInstImport i inst+               cont newDs sig++          DParamDecl _ ds' -> cont [] (jnSig ds' sig)++          DModule tl | NestedModule mo <- tlValue tl ->+            do ms <- desugarMod mo+               cont [ DModule tl { tlValue = NestedModule m } | m <- ms ] sig++          _ -> cont [d] sig++desugarInstImport ::+  Located (ImportG (ImpName PName)) {- ^ The import -} ->+  ModuleInstanceArgs PName          {- ^ The insantiation -} ->+  ParseM [TopDecl PName]+desugarInstImport i inst =+  do ms <- desugarMod+           Module { mName = i { thing = iname }+                  , mDef  = FunctorInstance+                              (iModule <$> i) inst emptyModuleInstance+                  }+     pure (DImport (newImp <$> i) : map modTop ms)++  where+  imp = thing i+  iname = mkUnqual+        $ mkIdent+        $ "import of " <> nm <> " at " <> Text.pack (show (pp (srcRange i)))+    where+    nm = case iModule imp of+           ImpTop f    -> modNameToText f+           ImpNested n -> "submodule " <> Text.pack (show (pp n))++  newImp d = d { iModule = ImpNested iname+               , iInst   = Nothing+               }++  modTop m = DModule TopLevel+                       { tlExport = Private+                       , tlDoc    = Nothing+                       , tlValue  = NestedModule m+                       }+++
src/Cryptol/Parser/Position.hs view
@@ -37,6 +37,11 @@                         , source :: FilePath }                   deriving (Eq, Ord, Show, Generic, NFData) +-- | Returns `True` if the first range is contained in the second one.+rangeWithin :: Range -> Range -> Bool+a `rangeWithin` b =+  source a == source b && from a >= from b && to a <= to b+ -- | An empty range. -- -- Caution: using this on the LHS of a use of rComb will cause the empty source
src/Cryptol/Parser/Token.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE Safe #-} module Cryptol.Parser.Token where  import Data.Text(Text)@@ -20,7 +21,6 @@                 deriving (Eq, Show, Generic, NFData)  data TokenKW  = KW_else-              | KW_extern               | KW_fin               | KW_if               | KW_private@@ -50,6 +50,8 @@               | KW_primitive               | KW_parameter               | KW_constraint+              | KW_interface+              | KW_foreign               | KW_Prop               | KW_by               | KW_down
src/Cryptol/Parser/Unlit.hs view
@@ -20,7 +20,7 @@  import           Cryptol.Utils.Panic -data PreProc = None | Markdown | LaTeX+data PreProc = None | Markdown | LaTeX | RST  knownExts :: [String] knownExts  =@@ -28,6 +28,7 @@   , "tex"   , "markdown"   , "md"+  , "rst"   ]  guessPreProc :: FilePath -> PreProc@@ -35,6 +36,7 @@                       ".tex"      -> LaTeX                       ".markdown" -> Markdown                       ".md"       -> Markdown+                      ".rst"      -> RST                       _           -> None  unLit :: PreProc -> Text -> Text@@ -47,6 +49,7 @@     None     -> return . Code     Markdown -> markdown     LaTeX    -> latex+    RST      -> rst   data Block = Code [Text] | Comment [Text]@@ -102,7 +105,7 @@    isOpenFence l     | "```" `Text.isPrefixOf` l' =-      Just $ case Text.drop 3 l' of+      Just $ case Text.dropWhile isSpace (Text.drop 3 l') of                l'' | "cryptol" `Text.isPrefixOf` l'' -> Code                    | isBlank l''                     -> Code                    | otherwise                       -> Comment@@ -134,6 +137,35 @@   isBeginCode l = "\\begin{code}" `Text.isPrefixOf` l   isEndCode l   = "\\end{code}"   `Text.isPrefixOf` l +rst :: [Text] -> [Block]+rst = comment []+  where+  isBeginCode l = case filter (not . Text.null) (Text.split isSpace l) of+                    ["..", dir, "cryptol"] -> dir == "code-block::" ||+                                              dir == "sourcecode::"+                    _ -> False +  isEmpty       = Text.all isSpace+  isCode l      = case Text.uncons l of+                    Just (c, _) -> isSpace c+                    Nothing     -> True++  comment acc ls =+    case ls of+      [] -> mk Comment acc+      l : ls1 | isBeginCode l -> codeOptions (l : acc) ls1+              | otherwise     -> comment (l : acc) ls1++  codeOptions acc ls =+    case ls of+      [] -> mk Comment acc+      l : ls1 | isEmpty l -> mk Comment (l : acc) ++ code [] ls1+              | otherwise -> codeOptions (l : acc) ls1++  code acc ls =+    case ls of+      [] -> mk Code acc+      l : ls1 | isCode l   -> code (l : acc) ls1+              | otherwise  -> mk Code acc ++ comment [] ls  
src/Cryptol/Parser/Utils.hs view
@@ -10,6 +10,7 @@ -- from previous Cryptol versions.  {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE Safe #-}  module Cryptol.Parser.Utils   ( translateExprToNumT@@ -41,7 +42,7 @@                          return (TInfix e1 o f e2)      EParens e    -> do t <- translateExprToNumT e-                       return (TParens t)+                       return (TParens t Nothing)      _            -> Nothing 
src/Cryptol/REPL/Browse.hs view
@@ -13,7 +13,9 @@ import qualified Cryptol.TypeCheck.Type as T  import Cryptol.Utils.PP-import Cryptol.ModuleSystem.Env(ModContext(..))+import Cryptol.Utils.Ident (OrigName(..), modPathIsNormal, identIsNormal)++import Cryptol.ModuleSystem.Env(ModContext(..),ModContextParams(..)) import Cryptol.ModuleSystem.NamingEnv(namingEnvNames) import Cryptol.ModuleSystem.Name import Cryptol.ModuleSystem.Interface@@ -21,11 +23,14 @@ data BrowseHow = BrowseExported | BrowseInScope  browseModContext :: BrowseHow -> ModContext -> PP.Doc Void-browseModContext how mc = runDoc (env disp) (vcat sections)+browseModContext how mc =+  runDoc (env disp) (vcat sections)   where   sections = concat     [ browseMParams (env disp) (mctxParams mc)+    , browseSignatures disp decls     , browseMods disp decls+    , browseFunctors disp decls     , browseTSyns disp decls     , browsePrimTys disp decls     , browseNewtypes disp decls@@ -35,7 +40,12 @@   disp     = DispInfo { dispHow = how, env = mctxNameDisp mc }   decls    = filterIfaceDecls (`Set.member` visNames) (mctxDecls mc)   allNames = namingEnvNames (mctxNames mc)-  visNames = case how of+  notAnon nm = identIsNormal (nameIdent nm) &&+               case nameModPathMaybe nm of+                  Just p -> modPathIsNormal p+                  _      -> True    -- shouldn't happen?+  visNames = Set.filter notAnon+             case how of                BrowseInScope  -> allNames                BrowseExported -> mctxExported mc @@ -44,33 +54,52 @@ --------------------------------------------------------------------------------  -browseMParams :: NameDisp -> IfaceParams -> [Doc]-browseMParams disp params =-  ppSectionHeading "Module Parameters"-  $ addEmpty-  $ map ppParamTy (sortByName disp (Map.toList (ifParamTypes params))) ++-    map ppParamFu (sortByName disp (Map.toList (ifParamFuns  params)))+browseMParams :: NameDisp -> ModContextParams -> [Doc]+browseMParams disp pars =+  case pars of+    NoParams -> []+    FunctorParams params ->+      ppSectionHeading "Module Parameters"+      $ [ "parameter" <+> pp (T.mpName p) <+> ":" <+>+          "interface" <+> pp (T.mpIface p) $$+           indent 2 (vcat $+            map ppParamTy (sortByName disp (Map.toList (T.mpnTypes names))) +++            map ppParamFu (sortByName disp (Map.toList (T.mpnFuns  names)))+           )+        | p <- Map.elems params+        , let names = T.mpParameters p+        ] +++        ["   "]+    InterfaceParams ps -> [pp ps] -- XXX   where   ppParamTy p = nest 2 (sep ["type", pp (T.mtpName p) <+> ":", pp (T.mtpKind p)])   ppParamFu p = nest 2 (sep [pp (T.mvpName p) <+> ":", pp (T.mvpType p)])   -- XXX: should we print the constraints somewhere too? -  addEmpty xs = case xs of-                  [] -> []-                  _  -> xs ++ ["    "] - browseMods :: DispInfo -> IfaceDecls -> [Doc] browseMods disp decls =-  ppSection disp "Modules" ppM (ifModules decls)+  ppSection disp "Submodules" ppM (ifModules decls)   where-  ppM m = "submodule" <+> pp (ifModName m)-  -- XXX: can print a lot more information about the moduels, but-  -- might be better to do that with a separate command+  ppM m = pp (ifsName m) +browseFunctors :: DispInfo -> IfaceDecls -> [Doc]+browseFunctors disp decls =+  ppSection disp "Parameterized Submodules" ppM (ifFunctors decls)+  where+  ppM m = pp (ifModName m)   ++browseSignatures :: DispInfo -> IfaceDecls -> [Doc]+browseSignatures disp decls =+  ppSection disp "Interface Submodules"+    ppS (Map.mapWithKey (,) (ifSignatures decls))+  where+  ppS (x,s) = pp x++ browseTSyns :: DispInfo -> IfaceDecls -> [Doc] browseTSyns disp decls =      ppSection disp "Type Synonyms" pp tss@@ -142,8 +171,8 @@   where   toEntry (n,a) =     case nameInfo n of-      Declared m _ -> Just (m,[(n,a)])-      _            -> Nothing+      GlobalName _ og -> Just (ogModule og,[(n,a)])+      _               -> Nothing   sortByName :: NameDisp -> [(Name,a)] -> [a]
src/Cryptol/REPL/Command.hs view
@@ -59,19 +59,25 @@ import Cryptol.REPL.Monad import Cryptol.REPL.Trie import Cryptol.REPL.Browse+import Cryptol.REPL.Help  import qualified Cryptol.ModuleSystem as M import qualified Cryptol.ModuleSystem.Name as M import qualified Cryptol.ModuleSystem.NamingEnv as M-import qualified Cryptol.ModuleSystem.Renamer as M (RenamerWarning(SymbolShadowed))+import qualified Cryptol.ModuleSystem.Renamer as M+    (RenamerWarning(SymbolShadowed, PrefixAssocChanged)) import qualified Cryptol.Utils.Ident as M import qualified Cryptol.ModuleSystem.Env as M+import Cryptol.ModuleSystem.Fingerprint(fingerprintHexString) +import           Cryptol.Backend.FloatHelpers as FP import qualified Cryptol.Backend.Monad as E import qualified Cryptol.Backend.SeqMap as E import           Cryptol.Eval.Concrete( Concrete(..) ) import qualified Cryptol.Eval.Concrete as Concrete import qualified Cryptol.Eval.Env as E+import           Cryptol.Eval.FFI+import           Cryptol.Eval.FFI.GenHeader import qualified Cryptol.Eval.Type as E import qualified Cryptol.Eval.Value as E import qualified Cryptol.Eval.Reference as R@@ -86,7 +92,8 @@ import qualified Cryptol.TypeCheck.Parseable as T import qualified Cryptol.TypeCheck.Subst as T import           Cryptol.TypeCheck.Solve(defaultReplExpr)-import           Cryptol.TypeCheck.PP (dump,ppWithNames,emptyNameMap)+import           Cryptol.TypeCheck.PP (dump)+import qualified Cryptol.Utils.Benchmark as Bench import           Cryptol.Utils.PP hiding ((</>)) import           Cryptol.Utils.Panic(panic) import           Cryptol.Utils.RecordMap@@ -104,28 +111,30 @@ import Control.Monad hiding (mapM, mapM) import qualified Control.Monad.Catch as Ex import Control.Monad.IO.Class(liftIO)+import Text.Read (readMaybe)+import Control.Applicative ((<|>))+import qualified Data.Set as Set import Data.ByteString (ByteString) import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BS8 import Data.Bits (shiftL, (.&.), (.|.)) import Data.Char (isSpace,isPunctuation,isSymbol,isAlphaNum,isAscii) import Data.Function (on)-import Data.List (intercalate, nub, isPrefixOf,intersperse)+import Data.List (intercalate, nub, isPrefixOf) import Data.Maybe (fromMaybe,mapMaybe,isNothing) import System.Environment (lookupEnv) import System.Exit (ExitCode(ExitSuccess)) import System.Process (shell,createProcess,waitForProcess) import qualified System.Process as Process(runCommand)-import System.FilePath((</>), isPathSeparator)+import System.FilePath((</>), (-<.>), isPathSeparator) import System.Directory(getHomeDirectory,setCurrentDirectory,doesDirectoryExist                        ,getTemporaryDirectory,setPermissions,removeFile                        ,emptyPermissions,setOwnerReadable)-import qualified Data.Map as Map-import qualified Data.Set as Set import System.IO          (Handle,hFlush,stdout,openTempFile,hClose,openFile          ,IOMode(..),hGetContents,hSeek,SeekMode(..))-import System.Random.TF(newTFGen)+import qualified System.Random.TF as TF+import qualified System.Random.TF.Instances as TFI import Numeric (showFFloat) import qualified Data.Text as T import Data.IORef(newIORef,readIORef,writeIORef)@@ -137,6 +146,8 @@  import qualified Data.SBV.Internals as SBV (showTDiff) ++ -- Commands --------------------------------------------------------------------  -- | Commands.@@ -251,6 +262,33 @@   , CommandDescr [ ":extract-coq" ] [] (NoArg allTerms)     "Print out the post-typechecked AST of all currently defined terms,\nin a Coq-parseable format."     ""+  , CommandDescr [ ":time" ] ["EXPR"] (ExprArg timeCmd)+    "Measure the time it takes to evaluate the given expression."+    (unlines+      [ "The expression will be evaluated many times to get accurate results."+      , "Note that the first evaluation of a binding may take longer due to"+      , "  laziness, and this may affect the reported time. If this is not"+      , "  desired then make sure to evaluate the expression once first before"+      , "  running :time."+      , "The amount of time to spend collecting measurements can be changed"+      , "  with the timeMeasurementPeriod option."+      , "Reports the average wall clock time, CPU time, and cycles."+      , "  (Cycles are in unspecified units that may be CPU cycles.)"+      , "Binds the result to"+      , "  it : { avgTime : Float64"+      , "       , avgCpuTime : Float64"+      , "       , avgCycles : Integer }" ])++  , CommandDescr [ ":set-seed" ] ["SEED"] (OptionArg seedCmd)+      "Seed the random number generator for operations using randomness"+      (unlines+        [ "A seed takes the form of either a single integer or a 4-tuple"+        , "of unsigned 64-bit integers.  Examples of commands using randomness"+        , "are dumpTests and check."+        ])+  , CommandDescr [ ":new-seed"] [] (NoArg newSeedCmd)+      "Randomly generate and set a new seed for the random number generator"+      ""   ]  commandList :: [CommandDescr]@@ -290,6 +328,23 @@              , "number of tests is determined by the \"tests\" option."              ])     ""+  , CommandDescr [ ":generate-foreign-header" ] ["FILE"] (FilenameArg genHeaderCmd)+    "Generate a C header file from foreign declarations in a Cryptol file."+    (unlines+      [ "Converts all foreign declarations in the given Cryptol file into C"+      , "function declarations, and writes them to a file with the same name"+      , "but with a .h extension." ])+++  , CommandDescr [ ":file-deps" ] [ "FILE" ]+    (FilenameArg (moduleInfoCmd True))+    "Show information about the dependencies of a file"+    ""++  , CommandDescr [ ":module-deps" ] [ "MODULE" ]+    (ModNameArg (moduleInfoCmd False))+    "Show information about the dependencies of a module"+    ""   ]  genHelp :: [CommandDescr] -> [String]@@ -368,14 +423,13 @@      (val, ty) <- replEvalExpr expr      ppopts <- getPPValOpts      testNum <- getKnownUser "tests" :: REPL Int-     g <- io newTFGen      tenv <- E.envTypes . M.deEnv <$> getDynEnv      let tyv = E.evalValType tenv ty      gens <-        case TestR.dumpableType tyv of          Nothing -> raise (TypeNotTestable ty)          Just gens -> return gens-     tests <- io $ TestR.returnTests g gens val testNum+     tests <- withRandomGen (\g -> io $ TestR.returnTests' g gens val testNum)      out <- forM tests $             \(args, x) ->               do argOut <- mapM (rEval . E.ppValue Concrete ppopts) args@@ -431,10 +485,17 @@   T.Schema ->   REPL TestReport qcExpr qcMode exprDoc texpr schema =-  do (val,ty) <- replEvalCheckedExpr texpr schema+  do (val,ty) <- replEvalCheckedExpr texpr schema >>= \mb_res -> case mb_res of+       Just res -> pure res+       -- If instance is not found, doesn't necessarily mean that there is no instance.+       -- And due to nondeterminism in result from the solver (for finding solution to +       -- numeric type constraints), `:check` can get to this exception sometimes, but+       -- successfully find an instance and test with it other times.+       Nothing -> raise (InstantiationsNotFound schema)      testNum <- (toInteger :: Int -> Integer) <$> getKnownUser "tests"      tenv <- E.envTypes . M.deEnv <$> getDynEnv      let tyv = E.evalValType tenv ty+     -- tv has already had polymorphism instantiated       percentRef <- io $ newIORef Nothing      testsRef <- io $ newIORef 0 @@ -460,11 +521,11 @@        Just (sz,tys,_,gens) | qcMode == QCRandom -> do             rPutStrLn "Using random testing."             prt testingMsg-            g <- io newTFGen             (res,num) <--                  Ex.catch (randomTests (\n -> ppProgress percentRef testsRef n testNum)-                                        testNum val gens g)-                         (\ex -> do rPutStrLn "\nTest interrupted..."+              withRandomGen+                (randomTests' (\n -> ppProgress percentRef testsRef n testNum)+                                      testNum val gens)+              `Ex.catch` (\ex -> do rPutStrLn "\nTest interrupted..."                                     num <- io $ readIORef testsRef                                     let report = TestReport exprDoc Pass num sz                                     ppReport tys False report@@ -801,7 +862,9 @@ printSafetyViolation :: T.Expr -> T.Schema -> [E.GenValue Concrete] -> REPL () printSafetyViolation texpr schema vs =     catch-      (do (fn,_) <- replEvalCheckedExpr texpr schema+      (do fn <- replEvalCheckedExpr texpr schema >>= \mb_res -> case mb_res of +            Just (fn, _) -> pure fn+            Nothing -> raise (EvalPolyError schema)           rEval (E.forceValue =<< foldM (\f v -> E.fromVFun Concrete f (pure v)) fn vs))       (\case           EvalError eex -> rPutStrLn (show (pp eex))@@ -989,6 +1052,32 @@   rPrint $ runDoc fDisp $ group $ hang     (ppPrec 2 expr <+> text ":") 2 (pp sig) +timeCmd :: String -> (Int, Int) -> Maybe FilePath -> REPL ()+timeCmd str pos fnm = do+  period <- getKnownUser "timeMeasurementPeriod" :: REPL Int+  quiet <- getKnownUser "timeQuiet"+  unless quiet $+    rPutStrLn $ "Measuring for " ++ show period ++ " seconds"+  pExpr <- replParseExpr str pos fnm+  (_, def, sig) <- replCheckExpr pExpr+  replPrepareCheckedExpr def sig >>= \case+    Nothing -> raise (EvalPolyError sig)+    Just (_, expr) -> do+      Bench.BenchmarkStats {..} <- liftModuleCmd+        (rethrowEvalError . M.benchmarkExpr (fromIntegral period) expr)+      unless quiet $+        rPutStrLn $ "Avg time: " ++ Bench.secs benchAvgTime+             ++ "    Avg CPU time: " ++ Bench.secs benchAvgCpuTime+             ++ "    Avg cycles: " ++ show benchAvgCycles+      let mkStatsRec time cpuTime cycles = recordFromFields+            [("avgTime", time), ("avgCpuTime", cpuTime), ("avgCycles", cycles)]+          itType = E.TVRec $ mkStatsRec E.tvFloat64 E.tvFloat64 E.TVInteger+          itVal = E.VRecord $ mkStatsRec+            (pure $ E.VFloat $ FP.floatFromDouble benchAvgTime)+            (pure $ E.VFloat $ FP.floatFromDouble benchAvgCpuTime)+            (pure $ E.VInteger $ toInteger benchAvgCycles)+      bindItVariableVal itType itVal+ readFileCmd :: FilePath -> REPL () readFileCmd fp = do   bytes <- replReadFile fp (\err -> rPutStrLn (show err) >> return Nothing)@@ -1062,11 +1151,9 @@   mb <- getLoadedMod   case mb of     Just lm  ->-      case lName lm of-        Just m | M.isParamInstModName m -> loadHelper (M.loadModuleByName m)-        _ -> case lPath lm of-               M.InFile f -> loadCmd f-               _ -> return ()+      case lPath lm of+        M.InFile f -> loadCmd f+        _ -> return ()     Nothing -> return ()  @@ -1127,16 +1214,14 @@   | null modString = return ()   | otherwise      = do     case parseModName modString of-      Just m-        | M.isParamInstModName m -> loadHelper (M.loadModuleByName m)-        | otherwise  ->-          do mpath <- liftModuleCmd (M.findModule m)-             case mpath of-               M.InFile file ->-                 do setEditPath file-                    setLoadedMod LoadedModule { lName = Just m, lPath = mpath }-                    loadHelper (M.loadModuleByPath file)-               M.InMem {} -> loadHelper (M.loadModuleByName m)+      Just m ->+        do mpath <- liftModuleCmd (M.findModule m)+           case mpath of+             M.InFile file ->+               do setEditPath file+                  setLoadedMod LoadedModule { lName = Just m, lPath = mpath }+                  loadHelper (M.loadModuleByPath file)+             M.InMem {} -> loadHelper (M.loadModuleByName m)       Nothing -> rPutStrLn "Invalid module name."  loadPrelude :: REPL ()@@ -1153,13 +1238,14 @@                                              }                    loadHelper (M.loadModuleByPath path) -loadHelper :: M.ModuleCmd (M.ModulePath,T.Module) -> REPL ()+loadHelper :: M.ModuleCmd (M.ModulePath,T.TCTopEntity) -> REPL () loadHelper how =   do clearLoadedMod-     (path,m) <- liftModuleCmd how-     whenDebug (rPutStrLn (dump m))+     (path,ent) <- liftModuleCmd how++     whenDebug (rPutStrLn (dump ent))      setLoadedMod LoadedModule-        { lName = Just (T.mName m)+        { lName = Just (T.tcTopEntitytName ent)         , lPath = path         }      -- after a successful load, the current module becomes the edit target@@ -1168,6 +1254,25 @@        M.InMem {} -> clearEditPath      setDynEnv mempty +genHeaderCmd :: FilePath -> REPL ()+genHeaderCmd path+  | null path = pure ()+  | otherwise = do+    (mPath, m) <- liftModuleCmd $ M.checkModuleByPath path+    let decls = case m of+                   T.TCTopModule mo -> findForeignDecls mo+                   T.TCTopSignature {} -> []+    if null decls+      then rPutStrLn $ "No foreign declarations in " ++ pretty mPath+      else do+        let header = generateForeignHeader decls+        case mPath of+          M.InFile p -> do+            let hPath = p -<.> "h"+            rPutStrLn $ "Writing header to " ++ hPath+            replWriteFileString hPath header (rPutStrLn . show)+          M.InMem _ _ -> rPutStrLn header+ versionCmd :: REPL () versionCmd = displayVersion rPutStrLn @@ -1230,153 +1335,10 @@       cs  -> void $ runCommand 1 Nothing (Ambiguous cmd0 (concatMap cNames cs))   | otherwise =     case parseHelpName cmd of-      Just qname ->-        do fe <- getFocusedEnv-           let params = M.mctxParams fe-               env    = M.mctxDecls  fe-               rnEnv  = M.mctxNames  fe-               disp   = M.mctxNameDisp fe--               vNames = M.lookupValNames  qname rnEnv-               tNames = M.lookupTypeNames qname rnEnv-               mNames = M.lookupNS M.NSModule qname rnEnv--           let helps = map (showTypeHelp params env disp) tNames ++-                       map (showValHelp params env disp qname) vNames ++-                       map (showModHelp env disp) mNames--               separ = rPutStrLn "            ---------"-           sequence_ (intersperse separ helps)--           when (null (vNames ++ tNames ++ mNames)) $-             rPrint $ "Undefined name:" <+> pp qname-      Nothing ->-           rPutStrLn ("Unable to parse name: " ++ cmd)+      Just qname -> helpForNamed qname+      Nothing    -> rPutStrLn ("Unable to parse name: " ++ cmd)    where-  noInfo nameEnv name =-    case M.nameInfo name of-      M.Declared m _ ->-                      rPrint $ runDoc nameEnv ("Name defined in module" <+> pp m)-      M.Parameter  -> rPutStrLn "// No documentation is available."---  showModHelp _env disp x =-    rPrint $ runDoc disp $ vcat [ "`" <> pp x <> "` is a module." ]-    -- XXX: show doc. if any--  showTypeHelp params env nameEnv name =-    fromMaybe (noInfo nameEnv name) $-    msum [ fromTySyn, fromPrimType, fromNewtype, fromTyParam ]--    where-    fromTySyn =-      do ts <- Map.lookup name (M.ifTySyns env)-         return (doShowTyHelp nameEnv (pp ts) (T.tsDoc ts))--    fromNewtype =-      do nt <- Map.lookup name (M.ifNewtypes env)-         let decl = pp nt $$ (pp name <+> text ":" <+> pp (T.newtypeConType nt))-         return $ doShowTyHelp nameEnv decl (T.ntDoc nt)--    fromPrimType =-      do a <- Map.lookup name (M.ifAbstractTypes env)-         pure $ do rPutStrLn ""-                   rPrint $ runDoc nameEnv $ nest 4-                          $ "primitive type" <+> pp (T.atName a)-                                     <+> ":" <+> pp (T.atKind a)--                   let (vs,cs) = T.atCtrs a-                   unless (null cs) $-                     do let example = T.TCon (T.abstractTypeTC a)-                                             (map (T.TVar . T.tpVar) vs)-                            ns = T.addTNames vs emptyNameMap-                            rs = [ "•" <+> ppWithNames ns c | c <- cs ]-                        rPutStrLn ""-                        rPrint $ runDoc nameEnv $ indent 4 $-                                    backticks (ppWithNames ns example) <+>-                                    "requires:" $$ indent 2 (vcat rs)--                   doShowFix (T.atFixitiy a)-                   doShowDocString (T.atDoc a)--    fromTyParam =-      do p <- Map.lookup name (M.ifParamTypes params)-         let uses c = T.TVBound (T.mtpParam p) `Set.member` T.fvs c-             ctrs = filter uses (map P.thing (M.ifParamConstraints params))-             ctrDoc = case ctrs of-                        []  -> []-                        [x] -> [pp x]-                        xs  -> [parens $ commaSep $ map pp xs]-             decl = vcat $-                      [ text "parameter" <+> pp name <+> text ":"-                        <+> pp (T.mtpKind p) ]-                      ++ ctrDoc-         return $ doShowTyHelp nameEnv decl (T.mtpDoc p)--  doShowTyHelp nameEnv decl doc =-    do rPutStrLn ""-       rPrint (runDoc nameEnv (nest 4 decl))-       doShowDocString doc--  doShowFix fx =-    case fx of-      Just f  ->-        let msg = "Precedence " ++ show (P.fLevel f) ++ ", " ++-                   (case P.fAssoc f of-                      P.LeftAssoc   -> "associates to the left."-                      P.RightAssoc  -> "associates to the right."-                      P.NonAssoc    -> "does not associate.")--        in rPutStrLn ('\n' : msg)--      Nothing -> return ()--  showValHelp params env nameEnv qname name =-    fromMaybe (noInfo nameEnv name)-              (msum [ fromDecl, fromNewtype, fromParameter ])-    where-    fromDecl =-      do M.IfaceDecl { .. } <- Map.lookup name (M.ifDecls env)-         return $-           do rPutStrLn ""--              let property-                    | P.PragmaProperty `elem` ifDeclPragmas = [text "property"]-                    | otherwise                             = []-              rPrint $ runDoc nameEnv-                     $ indent 4-                     $ hsep--                     $ property ++ [pp qname, colon, pp (ifDeclSig)]--              doShowFix $ ifDeclFixity `mplus`-                          (guard ifDeclInfix >> return P.defaultFixity)--              doShowDocString ifDeclDoc--    fromNewtype =-      do _ <- Map.lookup name (M.ifNewtypes env)-         return $ return ()--    fromParameter =-      do p <- Map.lookup name (M.ifParamFuns params)-         return $-           do rPutStrLn ""-              rPrint $ runDoc nameEnv-                     $ indent 4-                     $ text "parameter" <+> pp qname-                                        <+> colon-                                        <+> pp (T.mvpType p)--              doShowFix (T.mvpFixity p)-              doShowDocString (T.mvpDoc p)--  doShowDocString doc =-    case doc of-      Nothing -> pure ()-      Just d  -> rPutStrLn ('\n' : T.unpack d)-   showCmdHelp c [arg] | ":set" `elem` cNames c = showOptionHelp arg   showCmdHelp c _args =     do rPutStrLn ("\n    " ++ intercalate ", " (cNames c) ++ " " ++ intercalate " " (cArgs c))@@ -1482,32 +1444,46 @@                 }      moduleCmdResult =<< io (cmd minp) +-- TODO: add filter for my exhaustie prop guards warning here+ moduleCmdResult :: M.ModuleRes a -> REPL a moduleCmdResult (res,ws0) = do-  warnDefaulting <- getKnownUser "warnDefaulting"-  warnShadowing  <- getKnownUser "warnShadowing"+  warnDefaulting  <- getKnownUser "warnDefaulting"+  warnShadowing   <- getKnownUser "warnShadowing"+  warnPrefixAssoc <- getKnownUser "warnPrefixAssoc"+  warnNonExhConGrds <- getKnownUser "warnNonExhaustiveConstraintGuards"   -- XXX: let's generalize this pattern-  let isDefaultWarn (T.DefaultingTo _ _) = True-      isDefaultWarn _ = False--      filterDefaults w | warnDefaulting = Just w-      filterDefaults (M.TypeCheckWarnings nameMap xs) =-        case filter (not . isDefaultWarn . snd) xs of-          [] -> Nothing-          ys -> Just (M.TypeCheckWarnings nameMap ys)-      filterDefaults w = Just w--      isShadowWarn (M.SymbolShadowed {}) = True+  let isShadowWarn (M.SymbolShadowed {}) = True       isShadowWarn _                     = False -      filterShadowing w | warnShadowing = Just w-      filterShadowing (M.RenamerWarnings xs) =-        case filter (not . isShadowWarn) xs of+      isPrefixAssocWarn (M.PrefixAssocChanged {}) = True+      isPrefixAssocWarn _                         = False++      filterRenamer True _ w = Just w+      filterRenamer _ check (M.RenamerWarnings xs) =+        case filter (not . check) xs of           [] -> Nothing           ys -> Just (M.RenamerWarnings ys)-      filterShadowing w = Just w+      filterRenamer _ _ w = Just w -  let ws = mapMaybe filterDefaults . mapMaybe filterShadowing $ ws0+      -- ignore certain warnings during typechecking+      filterTypecheck :: M.ModuleWarning -> Maybe M.ModuleWarning+      filterTypecheck (M.TypeCheckWarnings nameMap xs) = +        case filter (allow . snd) xs of +          [] -> Nothing+          ys -> Just (M.TypeCheckWarnings nameMap ys)+          where+            allow :: T.Warning -> Bool +            allow = \case+              T.DefaultingTo _ _ | not warnDefaulting -> False+              T.NonExhaustivePropGuards _ | not warnNonExhConGrds -> False+              _ -> True+      filterTypecheck w = Just w++  let ws = mapMaybe (filterRenamer warnShadowing isShadowWarn)+         . mapMaybe (filterRenamer warnPrefixAssoc isPrefixAssocWarn)+         . mapMaybe filterTypecheck+         $ ws0   names <- M.mctxNameDisp <$> getFocusedEnv   mapM_ (rPrint . runDoc names . pp) ws   case res of@@ -1552,39 +1528,47 @@ replEvalExpr :: P.Expr P.PName -> REPL (Concrete.Value, T.Type) replEvalExpr expr =   do (_,def,sig) <- replCheckExpr expr-     replEvalCheckedExpr def sig+     replEvalCheckedExpr def sig >>= \case+       Just res -> pure res+       Nothing -> raise (EvalPolyError sig) -replEvalCheckedExpr :: T.Expr -> T.Schema -> REPL (Concrete.Value, T.Type)+replEvalCheckedExpr :: T.Expr -> T.Schema -> REPL (Maybe (Concrete.Value, T.Type)) replEvalCheckedExpr def sig =-  do validEvalContext def-     validEvalContext sig+  replPrepareCheckedExpr def sig >>=+    traverse \(tys, def1) -> do+      let su = T.listParamSubst tys+      let ty = T.apSubst su (T.sType sig)+      whenDebug (rPutStrLn (dump def1)) -     s <- getTCSolver-     mbDef <- io (defaultReplExpr s def sig)+      tenv <- E.envTypes . M.deEnv <$> getDynEnv+      let tyv = E.evalValType tenv ty -     (def1,ty) <--        case mbDef of-          Nothing -> raise (EvalPolyError sig)-          Just (tys,def1) ->-            do warnDefaults tys-               let su = T.listParamSubst tys-               return (def1, T.apSubst su (T.sType sig))+      -- add "it" to the namespace via a new declaration+      itVar <- bindItVariable tyv def1 -     whenDebug (rPutStrLn (dump def1))+      let itExpr = case getLoc def of+                      Nothing  -> T.EVar itVar+                      Just rng -> T.ELocated rng (T.EVar itVar) -     tenv <- E.envTypes . M.deEnv <$> getDynEnv-     let tyv = E.evalValType tenv ty+      -- evaluate the it variable+      val <- liftModuleCmd (rethrowEvalError . M.evalExpr itExpr)+      return (val,ty) -     -- add "it" to the namespace via a new declaration-     itVar <- bindItVariable tyv def1+-- | Check that we are in a valid evaluation context and apply defaulting.+replPrepareCheckedExpr :: T.Expr -> T.Schema ->+  REPL (Maybe ([(T.TParam, T.Type)], T.Expr))+replPrepareCheckedExpr def sig = do+  validEvalContext def+  validEvalContext sig -     let itExpr = case getLoc def of-                    Nothing  -> T.EVar itVar-                    Just rng -> T.ELocated rng (T.EVar itVar)+  s <- getTCSolver+  mbDef <- io (defaultReplExpr s def sig) -     -- evaluate the it variable-     val <- liftModuleCmd (rethrowEvalError . M.evalExpr itExpr)-     return (val,ty)+  case mbDef of+    Nothing -> pure Nothing+    Just (tys, def1) -> do+      warnDefaults tys+      pure $ Just (tys, def1)   where   warnDefaults ts =     case ts of@@ -1600,8 +1584,15 @@ itIdent  = M.packIdent "it"  replWriteFile :: FilePath -> BS.ByteString -> (X.SomeException -> REPL ()) -> REPL ()-replWriteFile fp bytes handler =- do x <- io $ X.catch (BS.writeFile fp bytes >> return Nothing) (return . Just)+replWriteFile = replWriteFileWith BS.writeFile++replWriteFileString :: FilePath -> String -> (X.SomeException -> REPL ()) -> REPL ()+replWriteFileString = replWriteFileWith writeFile++replWriteFileWith :: (FilePath -> a -> IO ()) -> FilePath -> a ->+  (X.SomeException -> REPL ()) -> REPL ()+replWriteFileWith write fp contents handler =+ do x <- io $ X.catch (write fp contents >> return Nothing) (return . Just)     maybe (return ()) handler x  replReadFile :: FilePath -> (X.SomeException -> REPL (Maybe BS.ByteString)) -> REPL (Maybe BS.ByteString)@@ -1629,7 +1620,7 @@                     }   liftModuleCmd (M.evalDecls [T.NonRecursive decl])   denv <- getDynEnv-  let nenv' = M.singletonE (P.UnQual itIdent) freshIt+  let nenv' = M.singletonNS M.NSValue (P.UnQual itIdent) freshIt                            `M.shadowing` M.deNames denv   setDynEnv $ denv { M.deNames = nenv' }   return freshIt@@ -1675,7 +1666,32 @@  type CommandMap = Trie CommandDescr +newSeedCmd :: REPL ()+newSeedCmd =+  do  seed <- createAndSetSeed+      rPutStrLn "Seed initialized to:"+      rPutStrLn (show seed)+  where+    createAndSetSeed =+      withRandomGen $ \g0 ->+        let (s1, g1) = TFI.random g0+            (s2, g2) = TFI.random g1+            (s3, g3) = TFI.random g2+            (s4, _)  = TFI.random g3+            seed = (s1, s2, s3, s4)+        in  pure (seed, TF.seedTFGen seed) +seedCmd :: String -> REPL ()+seedCmd s =+  case mbGen of+    Nothing -> rPutStrLn "Could not parse seed argument - expecting an integer or 4-tuple of integers."+    Just gen -> setRandomGen gen++  where+    mbGen =+          (TF.mkTFGen <$> readMaybe s)+      <|> (TF.seedTFGen <$> readMaybe s)+ -- Command Parsing -------------------------------------------------------------  -- | Strip leading space.@@ -1774,3 +1790,42 @@         '"':rest  -> Just $ quoted '"' rest         _         -> let (a,b) = break isSpace ipt in                      if null a then Nothing else Just (length a, a, b)++++moduleInfoCmd :: Bool -> String -> REPL ()+moduleInfoCmd isFile name+  | isFile = showInfo =<< liftModuleCmd (M.getFileDependencies name)+  | otherwise =+    case parseModName name of+      Just m  -> showInfo =<< liftModuleCmd (M.getModuleDependencies m)+      Nothing -> rPutStrLn "Invalid module name."++  where+  showInfo (p,fi) =+    do rPutStr "{ \"source\": "+       case p of+         M.InFile f  -> rPutStrLn (show f)+         M.InMem l _ -> rPutStrLn ("{ \"internal\": " ++ show l ++ " }")++       rPutStrLn (", \"fingerprint\": \"0x" +++                       fingerprintHexString (M.fiFingerprint fi) ++ "\"")++       let depList f x ys =+             do rPutStr (", " ++ show (x :: String) ++ ":")+                case ys of+                  [] -> rPutStrLn " []"+                  i : is ->+                    do rPutStrLn ""+                       rPutStrLn ("     [ " ++ f i)+                       mapM_ (\j -> rPutStrLn ("     , " ++ f j)) is+                       rPutStrLn "     ]"++       depList show               "includes" (Set.toList (M.fiIncludeDeps fi))+       depList (show . show . pp) "imports"  (Set.toList (M.fiImportDeps  fi))+       depList show               "foreign"  (Set.toList (M.fiForeignDeps fi))++       rPutStrLn "}"+++
+ src/Cryptol/REPL/Help.hs view
@@ -0,0 +1,379 @@+{-# Language BlockArguments #-}+{-# Language OverloadedStrings #-}+{-# Language RecordWildCards #-}+module Cryptol.REPL.Help (helpForNamed) where++import Data.Text (Text)+import qualified Data.Text as Text+import Data.Map (Map)+import qualified Data.Map as Map+import qualified Data.Set as Set+import Data.Maybe(fromMaybe)+import Data.List(intersperse)+import Control.Monad(when,guard,unless,msum,mplus)++import Cryptol.Utils.PP+import Cryptol.Utils.Ident(OrigName(..),identIsNormal)+import qualified Cryptol.Parser.AST as P+import qualified Cryptol.ModuleSystem as M+import qualified Cryptol.ModuleSystem.Name as M+import qualified Cryptol.ModuleSystem.NamingEnv as M+import qualified Cryptol.ModuleSystem.Env as M+import qualified Cryptol.ModuleSystem.Interface as M+import qualified Cryptol.ModuleSystem.Renamer.Error as M (ModKind(..))+import qualified Cryptol.TypeCheck.AST as T+import Cryptol.TypeCheck.PP(emptyNameMap,ppWithNames)++import Cryptol.REPL.Monad++helpForNamed :: P.PName -> REPL ()+helpForNamed qname =+  do fe <- getFocusedEnv+     let params = M.mctxParams fe+         env    = M.mctxDecls  fe+         rnEnv  = M.mctxNames  fe+         disp   = M.mctxNameDisp fe++         vNames = M.lookupListNS M.NSValue  qname rnEnv+         tNames = M.lookupListNS M.NSType   qname rnEnv+         mNames = M.lookupListNS M.NSModule qname rnEnv++     let helps = map (showTypeHelp params env disp) tNames +++                 map (showValHelp params env disp qname) vNames +++                 map (showModHelp env disp) mNames++         separ = rPutStrLn "            ---------"+     sequence_ (intersperse separ helps)++     when (null (vNames ++ tNames ++ mNames)) $+       rPrint $ "Undefined name:" <+> pp qname+++noInfo :: NameDisp -> M.Name -> REPL ()+noInfo nameEnv name =+  case M.nameInfo name of+    M.GlobalName _ og ->+      rPrint (runDoc nameEnv ("Name defined in module" <+> pp (ogModule og)))+    M.LocalName {} -> rPutStrLn "// No documentation is available."+++-- | Show help for something in the module namespace.+showModHelp :: M.IfaceDecls -> NameDisp -> M.Name -> REPL ()+showModHelp env nameEnv name =+  fromMaybe (noInfo nameEnv name) $+    msum [ attempt M.ifModules showModuleHelp+         , attempt M.ifFunctors showFunctorHelp+         , attempt M.ifSignatures showSigHelp+         ]++  where+  attempt :: (M.IfaceDecls -> Map M.Name a) ->+             (M.IfaceDecls -> NameDisp -> M.Name -> a -> REPL ()) ->+             Maybe (REPL ())+  attempt inMap doShow =+    do th <- Map.lookup name (inMap env)+       pure (doShow env nameEnv name th)++showModuleHelp ::+  M.IfaceDecls -> NameDisp -> M.Name -> M.IfaceNames M.Name -> REPL ()+showModuleHelp env _nameEnv name info =+  showSummary M.AModule name (M.ifsDoc info) (ifaceSummary env info)++ifaceSummary :: M.IfaceDecls -> M.IfaceNames M.Name -> ModSummary+ifaceSummary env info =+    foldr addName emptySummary (Set.toList (M.ifsPublic info))+  where+  addName x ns = fromMaybe ns+               $ msum [ addT <$> msum [fromTS, fromNT, fromAT]+                      , addV <$> fromD+                      , addM <$> msum [ fromM, fromS, fromF ]+                      ]+    where+    addT (k,d) = ns { msTypes = T.ModTParam { T.mtpName = x+                                            , T.mtpKind = k+                                            , T.mtpDoc  = d+                                            } : msTypes ns }++    addV (t,d,f) = ns { msVals = T.ModVParam { T.mvpName = x+                                             , T.mvpType = t+                                             , T.mvpDoc  = d+                                             , T.mvpFixity = f+                                             } : msVals ns }++    addM (k,d)= ns { msMods = (x, k, d) : msMods ns }+++    fromTS = do def <- Map.lookup x (M.ifTySyns env)+                pure (T.kindOf def, T.tsDoc def)++    fromNT = do def <- Map.lookup x (M.ifNewtypes env)+                pure (T.kindOf def, T.ntDoc def)++    fromAT = do def <- Map.lookup x (M.ifAbstractTypes env)+                pure (T.kindOf def, T.atDoc def)++    fromD = do def <- Map.lookup x (M.ifDecls env)+               pure (M.ifDeclSig def, M.ifDeclDoc def, M.ifDeclFixity def)++    fromM = do def <- Map.lookup x (M.ifModules env)+               pure (M.AModule, M.ifsDoc def)++    fromF = do def <- Map.lookup x (M.ifFunctors env)+               pure (M.AFunctor, M.ifsDoc (M.ifNames def))++    fromS = do def <- Map.lookup x (M.ifSignatures env)+               pure (M.ASignature, T.mpnDoc def)++++showFunctorHelp ::+  M.IfaceDecls -> NameDisp -> M.Name -> M.IfaceG M.Name -> REPL ()+showFunctorHelp _env _nameEnv name info =+  showSummary M.AFunctor name (M.ifsDoc ns) summary+  where+  ns      = M.ifNames info+  summary = (ifaceSummary (M.ifDefines info) ns)+                { msParams = [ (T.mpName p, T.mpIface p)+                             | p <- Map.elems (M.ifParams info)+                             ]+                }+++showSigHelp ::+  M.IfaceDecls -> NameDisp -> M.Name -> T.ModParamNames -> REPL ()+showSigHelp _env _nameEnv name info =+  showSummary M.ASignature name (T.mpnDoc info)+    emptySummary+      { msTypes = Map.elems (T.mpnTypes info)+      , msVals  = Map.elems (T.mpnFuns info)+      , msConstraints = map P.thing (T.mpnConstraints info)+      }++--------------------------------------------------------------------------------+data ModSummary = ModSummary+  { msParams      :: [(P.Ident, P.ImpName M.Name)]+  , msConstraints :: [T.Prop]+  , msTypes       :: [T.ModTParam]+  , msVals        :: [T.ModVParam]+  , msMods        :: [ (M.Name, M.ModKind, Maybe Text) ]+  }++emptySummary :: ModSummary+emptySummary = ModSummary+  { msParams      = []+  , msConstraints = []+  , msTypes       = []+  , msVals        = []+  , msMods        = []+  }++showSummary :: M.ModKind -> M.Name -> Maybe Text -> ModSummary -> REPL ()+showSummary k name doc info =+  do rPutStrLn ""++     rPrint $ runDoc disp+        case k of+          M.AModule    ->+            vcat [ "Module" <+> pp name <+> "exports:"+                 , indent 2 $ vcat [ ppTPs, ppFPs ]+                 ]+          M.ASignature ->+            vcat [ "Interface" <+> pp name <+> "requires:"+                 , indent 2 $ vcat [ ppTPs, ppCtrs, ppFPs ]+                 ]+          M.AFunctor ->+            vcat [ "Parameterized module" <+> pp name <+> "requires:"+                 , indent 2 $ ppPs+                 , " ", "and exports:"+                 , indent 2 $ vcat [ ppTPs, ppFPs ]+                 ]++     doShowDocString doc++  where+  -- qualifying stuff is too noisy+  disp        = NameDisp \_ -> Just UnQualified++  withMaybeNest mb x =+    case mb of+      Nothing -> x+      Just d  -> vcat [x, indent 2 d]++  withDoc mb = withMaybeNest (pp <$> mb)+  withFix mb = withMaybeNest (text . ppFixity <$> mb)+  ppMany xs  = case xs of+                 [] -> mempty+                 _  -> vcat (" " : xs)++  ppPs = ppMany (map ppP (msParams info))+  ppP (x,y)+    | identIsNormal x = pp x <+> ": interface" <+> pp y+    | otherwise = "(anonymous parameter)"+++  ppTPs  = ppMany (map ppTP (msTypes info))+  ppTP x = withDoc (T.mtpDoc x)+         $ hsep ["type", pp (T.mtpName x), ":", pp (T.mtpKind x)]++  ppCtrs = ppMany (map pp (msConstraints info))++  ppFPs  = ppMany (map ppFP (msVals info))+  ppFP x = withFix (T.mvpFixity x)+         $ withDoc (T.mvpDoc x)+         $ hsep [pp (T.mvpName x), ":" <+> pp (T.mvpType x) ]+--------------------------------------------------------------------------------+++++showTypeHelp ::+  M.ModContextParams -> M.IfaceDecls -> NameDisp -> T.Name -> REPL ()+showTypeHelp ctxparams env nameEnv name =+  fromMaybe (noInfo nameEnv name) $+  msum [ fromTySyn, fromPrimType, fromNewtype, fromTyParam ]++  where+  fromTySyn =+    do ts <- msum [ Map.lookup name (M.ifTySyns env)+                  , Map.lookup name+                      (T.mpnTySyn (M.modContextParamNames ctxparams))+                  ]+       return (doShowTyHelp nameEnv (pp ts) (T.tsDoc ts))++  fromNewtype =+    do nt <- Map.lookup name (M.ifNewtypes env)+       let decl = pp nt $$ (pp name <+> text ":" <+> pp (T.newtypeConType nt))+       return $ doShowTyHelp nameEnv decl (T.ntDoc nt)++  fromPrimType =+    do a <- Map.lookup name (M.ifAbstractTypes env)+       pure $ do rPutStrLn ""+                 rPrint $ runDoc nameEnv $ nest 4+                        $ "primitive type" <+> pp (T.atName a)+                                   <+> ":" <+> pp (T.atKind a)++                 let (vs,cs) = T.atCtrs a+                 unless (null cs) $+                   do let example = T.TCon (T.abstractTypeTC a)+                                           (map (T.TVar . T.tpVar) vs)+                          ns = T.addTNames vs emptyNameMap+                          rs = [ "•" <+> ppWithNames ns c | c <- cs ]+                      rPutStrLn ""+                      rPrint $ runDoc nameEnv $ indent 4 $+                                  backticks (ppWithNames ns example) <+>+                                  "requires:" $$ indent 2 (vcat rs)++                 doShowFix (T.atFixitiy a)+                 doShowDocString (T.atDoc a)++  allParamNames =+    case ctxparams of+      M.NoParams -> mempty+      M.FunctorParams fparams ->+        Map.unions+          [ (\x -> (Just p,x)) <$> T.mpnTypes (T.mpParameters ps)+          | (p, ps) <- Map.toList fparams+          ]+      M.InterfaceParams ps -> (\x -> (Nothing ,x)) <$> T.mpnTypes ps++  fromTyParam =+    do (x,p) <- Map.lookup name allParamNames+       pure do rPutStrLn ""+               case x of+                  Just src -> doShowParameterSource src+                  Nothing  -> pure ()+               let ty = "type" <+> pp name <+> ":" <+> pp (T.mtpKind p)+               rPrint (runDoc nameEnv (indent 4 ty))+               doShowDocString (T.mtpDoc p)+++doShowTyHelp :: NameDisp -> Doc -> Maybe Text -> REPL ()+doShowTyHelp nameEnv decl doc =+  do rPutStrLn ""+     rPrint (runDoc nameEnv (nest 4 decl))+     doShowDocString doc++++showValHelp ::+  M.ModContextParams -> M.IfaceDecls -> NameDisp -> P.PName -> T.Name -> REPL ()++showValHelp ctxparams env nameEnv qname name =+  fromMaybe (noInfo nameEnv name)+            (msum [ fromDecl, fromNewtype, fromParameter ])+  where+  fromDecl =+    do M.IfaceDecl { .. } <- Map.lookup name (M.ifDecls env)+       return $+         do rPutStrLn ""++            let property +                  | P.PragmaProperty `elem` ifDeclPragmas = [text "property"]+                  | otherwise                             = []+            rPrint $ runDoc nameEnv+                   $ indent 4+                   $ hsep++                   $ property ++ [pp qname, colon, pp (ifDeclSig)]++            doShowFix $ ifDeclFixity `mplus`+                        (guard ifDeclInfix >> return P.defaultFixity)++            doShowDocString ifDeclDoc++  fromNewtype =+    do _ <- Map.lookup name (M.ifNewtypes env)+       return $ return ()++  allParamNames =+    case ctxparams of+      M.NoParams -> mempty+      M.FunctorParams fparams ->+        Map.unions+          [ (\x -> (Just p,x)) <$> T.mpnFuns (T.mpParameters ps)+          | (p, ps) <- Map.toList fparams+          ]+      M.InterfaceParams ps -> (\x -> (Nothing,x)) <$> T.mpnFuns ps++  fromParameter =+    do (x,p) <- Map.lookup name allParamNames+       pure do rPutStrLn ""+               case x of+                 Just src -> doShowParameterSource src+                 Nothing -> pure ()+               let ty = pp name <+> ":" <+> pp (T.mvpType p)+               rPrint (runDoc nameEnv (indent 4 ty))+               doShowFix (T.mvpFixity p)+               doShowDocString (T.mvpDoc p)+++doShowParameterSource :: P.Ident -> REPL ()+doShowParameterSource i =+  do rPutStrLn (Text.unpack msg)+     rPutStrLn ""+  where+  msg+    | identIsNormal i = "Provided by module parameter " <> P.identText i <> "."+    | otherwise       = "Provided by `parameters` declaration."+++doShowDocString :: Maybe Text -> REPL ()+doShowDocString doc =+  case doc of+    Nothing -> pure ()+    Just d  -> rPutStrLn ('\n' : Text.unpack d)++ppFixity :: T.Fixity -> String+ppFixity f = "Precedence " ++ show (P.fLevel f) ++ ", " +++               case P.fAssoc f of+                 P.LeftAssoc   -> "associates to the left."+                 P.RightAssoc  -> "associates to the right."+                 P.NonAssoc    -> "does not associate."++doShowFix :: Maybe T.Fixity -> REPL ()+doShowFix fx =+  case fx of+    Just f  -> rPutStrLn ('\n' : ppFixity f)+    Nothing -> return ()++
src/Cryptol/REPL/Monad.hs view
@@ -15,6 +15,7 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}  module Cryptol.REPL.Monad (     -- * REPL Monad@@ -57,6 +58,9 @@   , validEvalContext   , updateREPLTitle   , setUpdateREPLTitle+  , withRandomGen+  , setRandomGen+  , getRandomGen      -- ** Config Options   , EnvVal(..)@@ -131,6 +135,7 @@ import Text.Read (readMaybe)  import Data.SBV (SBVException)+import qualified System.Random.TF as TF  import Prelude () import Prelude.Compat@@ -186,6 +191,9 @@     -- Used as a kind of id for the current solver, which helps avoid     -- a race condition where the callback of a dead solver runs after     -- a new one has been started.++  , eRandomGen :: TF.TFGen+    -- ^ Random number generator for things like QC and dumpTests   }  @@ -193,6 +201,7 @@ defaultRW :: Bool -> Bool -> Logger -> IO RW defaultRW isBatch callStacks l = do   env <- M.initialModuleEnv+  rng <- TF.newTFGen   let searchPath = M.meSearchPath env   let solverConfig = T.defaultSolverConfig searchPath   return RW@@ -209,6 +218,7 @@     , eTCConfig    = solverConfig     , eTCSolver    = Nothing     , eTCSolverRestarts = 0+    , eRandomGen = rng     }  -- | Build up the prompt for the REPL.@@ -224,10 +234,11 @@     case lName =<< eLoadedMod rw of       Nothing -> show (pp I.preludeName)       Just m-        | M.isLoadedParamMod m (M.meLoadedModules (eModuleEnv rw)) ->-                 modName ++ "(parameterized)"+        | M.isLoadedParamMod m loaded -> modName ++ "(parameterized)"+        | M.isLoadedInterface m loaded -> modName ++ "(interface)"         | otherwise -> modName         where modName = pretty m+              loaded = M.meLoadedModules (eModuleEnv rw)    withFocus =     case eLoadedMod rw of@@ -329,8 +340,9 @@   | Unsupported Unsupported   | ModuleSystemError NameDisp M.ModuleError   | EvalPolyError T.Schema+  | InstantiationsNotFound T.Schema   | TypeNotTestable T.Type-  | EvalInParamModule [M.Name]+  | EvalInParamModule [T.TParam] [M.Name]   | SBVError String   | SBVException SBVException   | SBVPortfolioException SBVPortfolioException@@ -358,10 +370,13 @@     TooWide e            -> pp e     EvalPolyError s      -> text "Cannot evaluate polymorphic value."                          $$ text "Type:" <+> pp s+    InstantiationsNotFound s -> text "Cannot find instantiations for some type variables."+                             $$ text "Type:" <+> pp s     TypeNotTestable t    -> text "The expression is not of a testable type."                          $$ text "Type:" <+> pp t-    EvalInParamModule xs -> nest 2 $ vsep $+    EvalInParamModule as xs -> nest 2 $ vsep $       [ text "Expression depends on definitions from a parameterized module:" ]+      ++ map pp as       ++ map pp xs     SBVError s           -> text "SBV error:" $$ text s     SBVException e       -> text "SBV exception:" $$ text (show e)@@ -552,17 +567,20 @@      let ds      = T.freeVars a          badVals = foldr badName Set.empty (T.valDeps ds)          bad     = foldr badName badVals (T.tyDeps ds)+         badTs   = T.tyParams ds           badName nm bs =            case M.nameInfo nm of-             M.Declared (M.TopModule m) _   -- XXX: can we focus nested modules?-               | M.isLoadedParamMod m (M.meLoadedModules me) -> Set.insert nm bs-             _ -> bs -     unless (Set.null bad) $-       raise (EvalInParamModule (Set.toList bad))+             -- XXX: Changes if focusing on nested modules+             M.GlobalName _ I.OrigName { ogModule = I.TopModule m }+               | M.isLoadedParamMod m (M.meLoadedModules me) -> Set.insert nm bs+               | M.isLoadedInterface m (M.meLoadedModules me) -> Set.insert nm bs +             _ -> bs +     unless (Set.null bad && Set.null badTs) $+       raise (EvalInParamModule (Set.toList badTs) (Set.toList bad))  -- | Update the title updateREPLTitle :: REPL ()@@ -649,7 +667,19 @@   me <- getModuleEnv   setModuleEnv (me { M.meDynEnv = denv }) +getRandomGen :: REPL TF.TFGen+getRandomGen = eRandomGen <$> getRW +setRandomGen :: TF.TFGen -> REPL ()+setRandomGen rng = modifyRW_ (\s -> s { eRandomGen = rng })++withRandomGen :: (TF.TFGen -> REPL (a, TF.TFGen)) -> REPL a+withRandomGen repl =+  do  g <- getRandomGen+      (result, g') <- repl g+      setRandomGen g'+      pure result+ -- | Given an existing qualified name, prefix it with a -- relatively-unique string. We make it unique by prefixing with a -- character @#@ that is not lexically valid in a module name.@@ -657,11 +687,12 @@  uniqify name =   case M.nameInfo name of-    M.Declared ns s ->+    M.GlobalName s og ->       M.liftSupply (M.mkDeclared (M.nameNamespace name)-                  ns s (M.nameIdent name) (M.nameFixity name) (M.nameLoc name))+                  (I.ogModule og) s+                  (M.nameIdent name) (M.nameFixity name) (M.nameLoc name)) -    M.Parameter ->+    M.LocalName {} ->       panic "[REPL] uniqify" ["tried to uniqify a parameter: " ++ pretty name]  @@ -895,8 +926,12 @@     "Choose whether to display warnings when defaulting."   , simpleOpt "warnShadowing" ["warn-shadowing"] (EnvBool True) noCheck     "Choose whether to display warnings when shadowing symbols."+  , simpleOpt "warnPrefixAssoc" ["warn-prefix-assoc"] (EnvBool True) noCheck+    "Choose whether to display warnings when expression association has changed due to new prefix operator fixities."   , simpleOpt "warnUninterp" ["warn-uninterp"] (EnvBool True) noCheck     "Choose whether to issue a warning when uninterpreted functions are used to implement primitives in the symbolic simulator."+  , simpleOpt "warnNonExhaustiveConstraintGuards" ["warn-nonexhaustive-constraintguards"] (EnvBool True) noCheck+    "Choose whether to issue a warning when a use of constraint guards is not determined to be exhaustive."   , simpleOpt "smtFile" ["smt-file"] (EnvString "-") noCheck     "The file to use for SMT-Lib scripts (for debugging or offline proving).\nUse \"-\" for stdout."   , OptionDescr "path" [] (EnvString "") noCheck@@ -978,6 +1013,18 @@     , "  * display      try to match the order they were written in the source code"     , "  * canonical    use a predictable, canonical order"     ]++  , simpleOpt "timeMeasurementPeriod" ["time-measurement-period"] (EnvNum 10)+    checkTimeMeasurementPeriod+    $ unlines+    [ "The period of time in seconds to spend collecting measurements when"+    , "  running :time."+    , "This is a lower bound and the actual time taken might be higher if the"+    , "  evaluation takes a long time."+    ]++  , simpleOpt "timeQuiet" ["time-quiet"] (EnvBool False) noCheck+    "Suppress output of :time command and only bind result to `it`."   ]  @@ -1072,6 +1119,14 @@     _ | Just n <- readMaybe s -> return (SomeSat n)     _                         -> panic "REPL.Monad.getUserSatNum"                                    [ "invalid satNum option" ]++checkTimeMeasurementPeriod :: Checker+checkTimeMeasurementPeriod (EnvNum n)+  | n >= 1 = noWarns Nothing+  | otherwise = noWarns $+    Just "timeMeasurementPeriod must be a positive integer"+checkTimeMeasurementPeriod _ = noWarns $+  Just "unable to parse value for timeMeasurementPeriod"  -- Environment Utilities ------------------------------------------------------- 
src/Cryptol/Symbolic.hs view
@@ -349,7 +349,7 @@          in case res of               Left _ -> mismatch -- different fields               Right efs ->-                let f = foldl (\x t -> ETApp x (tNumValTy t)) (EVar (ntName nt)) ts+                let f = foldl (\x t -> ETApp x (tNumValTy t)) (EVar (ntConName nt)) ts                  in EApp f (ERec efs)        (FTRecord tfs, VarRecord vfs) ->
src/Cryptol/Symbolic/SBV.hs view
@@ -81,6 +81,7 @@ proverConfigs :: [(String, SBV.SMTConfig)] proverConfigs =   [ ("cvc4"     , SBV.cvc4     )+  , ("cvc5"     , SBV.cvc5     )   , ("yices"    , SBV.yices    )   , ("z3"       , SBV.z3       )   , ("boolector", SBV.boolector)@@ -90,6 +91,7 @@   , ("any"      , SBV.defaultSMTCfg )    , ("sbv-cvc4"     , SBV.cvc4     )+  , ("sbv-cvc5"     , SBV.cvc5     )   , ("sbv-yices"    , SBV.yices    )   , ("sbv-z3"       , SBV.z3       )   , ("sbv-boolector", SBV.boolector)@@ -298,9 +300,11 @@   ProverCommand ->   M.ModuleT IO (Either String ([FinType], SBV.Symbolic SBV.SVal)) prepareQuery evo ProverCommand{..} =-  do ds <- do (_mp, m) <- M.loadModuleFrom True (M.FromModule preludeReferenceName)+  do ds <- do (_mp, ent) <- M.loadModuleFrom True (M.FromModule preludeReferenceName)+              let m = tcTopEntityToModule ent+               let decls = mDecls m-              let nms = fst <$> Map.toList (M.ifDecls (M.ifPublic (M.genIface m)))+              let nms = fst <$> Map.toList (M.ifDecls (M.ifDefines (M.genIface m)))               let ds = Map.fromList [ (prelPrim (identText (M.nameIdent nm)), EWhere (EVar nm) decls) | nm <- nms ]               pure ds @@ -409,7 +413,10 @@         -- otherwise something is wrong        _ -> return $ ProverError (rshow results)-#if MIN_VERSION_sbv(8,8,0)+#if MIN_VERSION_sbv(10,0,0)+              where rshow | isSat = show . (SBV.AllSatResult False False False)+                    -- sbv-10.0.0 removes the `allSatHasPrefixExistentials` field+#elif MIN_VERSION_sbv(8,8,0)               where rshow | isSat = show . (SBV.AllSatResult False False False False) #else               where rshow | isSat = show .  SBV.AllSatResult . (False,False,False,)@@ -464,11 +471,19 @@               ProveQuery -> False               SafetyQuery -> False               SatQuery _ -> True++#if MIN_VERSION_sbv(10,0,0)+            generateSMTBenchmark+              | isSat     = SBV.generateSMTBenchmarkSat+              | otherwise = SBV.generateSMTBenchmarkProof+#else+            generateSMTBenchmark = SBV.generateSMTBenchmark isSat+#endif         evo <- liftIO (M.minpEvalOpts minp)          prepareQuery evo pc >>= \case           Left msg -> return (Left msg)-          Right (_ts, q) -> Right <$> M.io (SBV.generateSMTBenchmark isSat q)+          Right (_ts, q) -> Right <$> M.io (generateSMTBenchmark q)  protectStack :: (String -> M.ModuleCmd a)              -> M.ModuleCmd a
src/Cryptol/Symbolic/What4.hs view
@@ -18,6 +18,7 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ViewPatterns #-} @@ -37,7 +38,7 @@ import Control.Monad.IO.Class import Control.Monad (when, foldM, forM_, void) import qualified Control.Exception as X-import System.IO (Handle)+import System.IO (Handle, IOMode(..), withFile) import Data.Time import Data.IORef import Data.List (intercalate, tails, inits)@@ -82,6 +83,7 @@ import           What4.Solver import qualified What4.Solver.Boolector as W4 import qualified What4.Solver.CVC4 as W4+import qualified What4.Solver.CVC5 as W4 import qualified What4.Solver.ExternalABC as W4 import qualified What4.Solver.Yices as W4 import qualified What4.Solver.Z3 as W4@@ -160,6 +162,7 @@ proverConfigs :: [(String, W4ProverConfig)] proverConfigs =   [ ("w4-cvc4"      , W4ProverConfig cvc4OnlineAdapter)+  , ("w4-cvc5"      , W4ProverConfig cvc5OnlineAdapter)   , ("w4-yices"     , W4ProverConfig yicesOnlineAdapter)   , ("w4-z3"        , W4ProverConfig z3OnlineAdapter)   , ("w4-boolector" , W4ProverConfig boolectorOnlineAdapter)@@ -185,6 +188,11 @@   AnOnlineAdapter "CVC4" W4.cvc4Features W4.cvc4Options          (Proxy :: Proxy (W4.Writer W4.CVC4)) +cvc5OnlineAdapter :: AnAdapter+cvc5OnlineAdapter =+  AnOnlineAdapter "CVC5" W4.cvc5Features W4.cvc5Options+         (Proxy :: Proxy (W4.Writer W4.CVC5))+ boolectorOnlineAdapter :: AnAdapter boolectorOnlineAdapter =   AnOnlineAdapter "Boolector" W4.boolectorFeatures W4.boolectorOptions@@ -194,6 +202,7 @@ allSolvers = W4Portfolio   $ z3OnlineAdapter :|   [ cvc4OnlineAdapter+  , cvc5OnlineAdapter   , boolectorOnlineAdapter   , yicesOnlineAdapter   , AnAdapter W4.externalABCAdapter@@ -333,9 +342,10 @@     do let lPutStrLn = M.withLogger logPutStrLn        when pcVerbose (lPutStrLn "Simulating...") -       ds <- do (_mp, m) <- M.loadModuleFrom True (M.FromModule preludeReferenceName)+       ds <- do (_mp, ent) <- M.loadModuleFrom True (M.FromModule preludeReferenceName)+                let m = tcTopEntityToModule ent                 let decls = mDecls m-                let nms = fst <$> Map.toList (M.ifDecls (M.ifPublic (M.genIface m)))+                let nms = fst <$> Map.toList (M.ifDecls (M.ifDefines (M.genIface m)))                 let ds = Map.fromList [ (prelPrim (identText (M.nameIdent nm)), EWhere (EVar nm) decls) | nm <- nms ]                 pure ds @@ -373,7 +383,7 @@   ProverCommand ->   M.ModuleCmd (Maybe String, ProverResult) -satProve solverCfg hashConsing warnUninterp ProverCommand {..} =+satProve solverCfg hashConsing warnUninterp pc@ProverCommand {..} =   protectStack proverError \modIn ->   M.runModuleM modIn   do w4sym   <- liftIO makeSym@@ -414,13 +424,13 @@       Right (ts,args,safety,query) ->         case pcQueryType of           ProveQuery ->-            singleQuery sym solverCfg primMap logData ts args (Just safety) query+            singleQuery sym solverCfg pc primMap logData ts args (Just safety) query            SafetyQuery ->-            singleQuery sym solverCfg primMap logData ts args (Just safety) query+            singleQuery sym solverCfg pc primMap logData ts args (Just safety) query            SatQuery num ->-            multiSATQuery sym solverCfg primMap logData ts args query num+            multiSATQuery sym solverCfg pc primMap logData ts args query num  printUninterpWarn :: Logger -> Set Text -> IO () printUninterpWarn lg uninterpWarns =@@ -477,6 +487,7 @@   sym ~ W4.ExprBuilder t CryptolState fm =>   What4 sym ->   W4ProverConfig ->+  ProverCommand ->   PrimMap ->   W4.LogData ->   [FinType] ->@@ -485,23 +496,24 @@   SatNum ->   IO (Maybe String, ProverResult) -multiSATQuery sym solverCfg primMap logData ts args query (SomeSat n) | n <= 1 =-  singleQuery sym solverCfg primMap logData ts args Nothing query+multiSATQuery sym solverCfg pc primMap logData ts args query (SomeSat n) | n <= 1 =+  singleQuery sym solverCfg pc primMap logData ts args Nothing query -multiSATQuery _sym W4OfflineConfig _primMap _logData _ts _args _query _satNum =+multiSATQuery _sym W4OfflineConfig _pc _primMap _logData _ts _args _query _satNum =   fail "What4 offline solver cannot be used for multi-SAT queries" -multiSATQuery _sym (W4Portfolio _) _primMap _logData _ts _args _query _satNum =+multiSATQuery _sym (W4Portfolio _) _pc _primMap _logData _ts _args _query _satNum =   fail "What4 portfolio solver cannot be used for multi-SAT queries" -multiSATQuery _sym (W4ProverConfig (AnAdapter adpt)) _primMap _logData _ts _args _query _satNum =+multiSATQuery _sym (W4ProverConfig (AnAdapter adpt)) _pc _primMap _logData _ts _args _query _satNum =   fail ("Solver " ++ solver_adapter_name adpt ++ " does not support incremental solving and " ++         "cannot be used for multi-SAT queries.")  multiSATQuery sym (W4ProverConfig (AnOnlineAdapter nm fs _opts (_ :: Proxy s)))-               primMap _logData ts args query satNum0 =+               ProverCommand{..} primMap _logData ts args query satNum0 =+    withMaybeFile pcSmtFile WriteMode $ \smtFileHdl ->     X.bracket-      (W4.startSolverProcess fs Nothing (w4 sym))+      (W4.startSolverProcess fs smtFileHdl (w4 sym))       (void . W4.shutdownSolverProcess)       (\ (proc :: W4.SolverProcess t s) ->         do W4.assume (W4.solverConn proc) query@@ -627,6 +639,7 @@   sym ~ W4.ExprBuilder t CryptolState fm =>   What4 sym ->   W4ProverConfig ->+  ProverCommand ->   PrimMap ->   W4.LogData ->   [FinType] ->@@ -635,12 +648,12 @@   W4.Pred sym ->   IO (Maybe String, ProverResult) -singleQuery _ W4OfflineConfig _primMap _logData _ts _args _msafe _query =+singleQuery _ W4OfflineConfig _pc _primMap _logData _ts _args _msafe _query =   -- this shouldn't happen...   fail "What4 offline solver cannot be used for direct queries" -singleQuery sym (W4Portfolio ps) primMap logData ts args msafe query =-  do as <- mapM async [ singleQuery sym (W4ProverConfig p) primMap logData ts args msafe query+singleQuery sym (W4Portfolio ps) pc primMap logData ts args msafe query =+  do as <- mapM async [ singleQuery sym (W4ProverConfig p) pc primMap logData ts args msafe query                       | p <- NE.toList ps                       ]      waitForResults [] as@@ -659,7 +672,7 @@           do forM_ others (\a -> X.throwTo (asyncThreadId a) ExitSuccess)              return r -singleQuery sym (W4ProverConfig (AnAdapter adpt)) primMap logData ts args msafe query =+singleQuery sym (W4ProverConfig (AnAdapter adpt)) _pc primMap logData ts args msafe query =   do pres <- W4.solver_adapter_check_sat adpt (w4 sym) logData [query] $ \res ->          case res of            W4.Unknown -> return (ProverError "Solver returned UNKNOWN")@@ -677,9 +690,10 @@      return (Just (W4.solver_adapter_name adpt), pres)  singleQuery sym (W4ProverConfig (AnOnlineAdapter nm fs _opts (_ :: Proxy s)))-              primMap _logData ts args msafe query =+              ProverCommand{..} primMap _logData ts args msafe query =+  withMaybeFile pcSmtFile WriteMode $ \smtFileHdl ->   X.bracket-    (W4.startSolverProcess fs Nothing (w4 sym))+    (W4.startSolverProcess fs smtFileHdl (w4 sym))     (void . W4.shutdownSolverProcess)     (\ (proc :: W4.SolverProcess t s) ->         do W4.assume (W4.solverConn proc) query@@ -698,6 +712,13 @@                     Nothing -> return (Just nm, AllSatResult [ model ])     ) ++-- | Like 'withFile', but lifted to work over 'Maybe'.+withMaybeFile :: Maybe FilePath -> IOMode -> (Maybe Handle -> IO r) -> IO r+withMaybeFile mbFP mode action =+  case mbFP of+    Just fp -> withFile fp mode (action . Just)+    Nothing -> action Nothing  computeModelPred ::   sym ~ W4.ExprBuilder t CryptolState fm =>
src/Cryptol/Testing/Random.hs view
@@ -23,8 +23,10 @@ , TestResult(..) , isPass , returnTests+, returnTests' , exhaustiveTests , randomTests+, randomTests' ) where  import qualified Control.Exception as X@@ -96,23 +98,32 @@      go _ (_ : _) = panic "Cryptol.Testing.Random" ["Too many arguments to function while generating tests"]      go v [] = return v ---- | Return a collection of random tests. returnTests :: RandomGen g          => g -- ^ The random generator state          -> [Gen g Concrete] -- ^ Generators for the function arguments          -> Value -- ^ The function itself          -> Int -- ^ How many tests?          -> IO [([Value], Value)] -- ^ A list of pairs of random arguments and computed outputs-returnTests g gens fun num = go gens g 0+                                       --   as well as the new state of the RNG+returnTests g gens fun num = fst <$> returnTests' g gens fun num++-- | Return a collection of random tests.+returnTests' :: RandomGen g+         => g -- ^ The random generator state+         -> [Gen g Concrete] -- ^ Generators for the function arguments+         -> Value -- ^ The function itself+         -> Int -- ^ How many tests?+         -> IO ([([Value], Value)], g) -- ^ A list of pairs of random arguments and computed outputs+                                       --   as well as the new state of the RNG+returnTests' g gens fun num = go gens g 0   where     go args g0 n-      | n >= num = return []+      | n >= num = return ([], g0)       | otherwise =         do let sz = toInteger (div (100 * (1 + n)) num)            (inputs, output, g1) <- returnOneTest fun args sz g0-           more <- go args g1 (n + 1)-           return ((inputs, output) : more)+           (more, g2) <- go args g1 (n + 1)+           return ((inputs, output) : more, g2)  {- | Given a (function) type, compute generators for the function's arguments. -}@@ -447,14 +458,23 @@   [Gen g Concrete] {- ^ input value generators -} ->   g {- ^ Inital random generator -} ->   m (TestResult, Integer)-randomTests ppProgress maxTests val gens = go 0+randomTests ppProgress maxTests val gens g = fst <$> randomTests' ppProgress maxTests val gens g++randomTests' :: (MonadIO m, RandomGen g) =>+  (Integer -> m ()) {- ^ progress callback -} ->+  Integer {- ^ Maximum number of tests to run -} ->+  Value {- ^ function under test -} ->+  [Gen g Concrete] {- ^ input value generators -} ->+  g {- ^ Inital random generator -} ->+  m ((TestResult, Integer), g)+randomTests' ppProgress maxTests val gens = go 0   where   go !testNum g-    | testNum >= maxTests = return (Pass, testNum)+    | testNum >= maxTests = return ((Pass, testNum), g)     | otherwise =       do ppProgress testNum          let sz' = div (100 * (1 + testNum)) maxTests          (res, g') <- liftIO (runOneTest val gens sz' g)          case res of            Pass -> go (testNum+1) g'-           failure -> return (failure, testNum)+           failure -> return ((failure, testNum), g)
− src/Cryptol/Transform/AddModParams.hs
@@ -1,314 +0,0 @@--- | Transformed a parametrized module into an ordinary module--- where everything is parameterized by the module's parameters.--- Note that this reuses the names from the original parameterized module.-module Cryptol.Transform.AddModParams (addModParams) where--import           Data.Map ( Map )-import qualified Data.Map as Map-import           Data.Set ( Set )-import qualified Data.Set as Set-import           Data.Either(partitionEithers)-import           Data.List(find,sortBy)-import           Data.Ord(comparing)--import Cryptol.TypeCheck.AST-import Cryptol.Parser.Position(thing)-import Cryptol.ModuleSystem.Name(toParamInstName,asParamName,nameIdent-                                ,paramModRecParam)-import Cryptol.Utils.Ident(paramInstModName)-import Cryptol.Utils.RecordMap(recordFromFields)--{--Note that we have to be careful when doing this transformation on-polyomorphic values.  In particular,---Consider type parameters AS, with constraints CS, and value-parameters (xs : TS).--    f : {as} PS => t-    f = f`{as} (<> ..)--    ~~>--    f : {AS ++ as} (CS ++ PS) => { TS } -> t-    f = /\ (AS ++ as) ->-        \\ (CS ++ PS) ->-        \r -> f`{AS ++ as} (<> ...) r--The tricky bit is that we can't just replace `f` with-a new version of `f` with some arguments, instead ew have-to modify the whole instantiation of `f` : f`{as} (<>...)---}---addModParams :: Module -> Either [Name] Module-addModParams m =-  case getParams m of-    Left errs -> Left errs-    Right ps ->-     let toInst = Set.unions ( Map.keysSet (mTySyns m)-                             : Map.keysSet (mNewtypes m)-                             : map defs (mDecls m)-                             )-         inp = (toInst, ps { pTypeConstraints = inst inp (pTypeConstraints ps) })--     in Right m { mName = paramInstModName (mName m)-                , mTySyns = fixMap inp (mTySyns m)-                , mNewtypes = fixMap inp (mNewtypes m)-                , mDecls = fixUp inp (mDecls m)-                , mParamTypes = Map.empty-                , mParamConstraints = []-                , mParamFuns = Map.empty-                }--defs :: DeclGroup -> Set Name-defs dg =-  case dg of-    Recursive ds -> Set.fromList (map dName ds)-    NonRecursive d -> Set.singleton (dName d)--fixUp :: (AddParams a, Inst a) => Inp -> a -> a-fixUp i = addParams (snd i) . inst i--fixMap :: (AddParams a, Inst a) => Inp -> Map Name a -> Map Name a-fixMap i m =-  Map.fromList [ (toParamInstName x, fixUp i a) | (x,a) <- Map.toList m ]------------------------------------------------------------------------------------data Params = Params-  { pTypes            :: [TParam]-  , pTypeConstraints  :: [Prop]-  , pFuns             :: [(Name,Type)]-  }---getParams :: Module -> Either [Name] Params-getParams m-  | null errs =-     let ps = Params { pTypes = map rnTP-                              $ sortBy (comparing mtpNumber)-                              $ Map.elems-                              $ mParamTypes m-                     , pTypeConstraints = map thing (mParamConstraints m)-                     , pFuns = oks-                     }-     in Right ps-  | otherwise = Left errs-  where-  (errs,oks) = partitionEithers (map checkFunP (Map.toList (mParamFuns m)))--  checkFunP (x,s) = case isMono (mvpType s) of-                      Just t  -> Right (asParamName x, t)-                      Nothing -> Left x--  rnTP tp = mtpParam tp { mtpName = asParamName (mtpName tp) }------------------------------------------------------------------------------------class AddParams a where-  addParams :: Params -> a -> a--instance AddParams a => AddParams [a] where-  addParams ps = map (addParams ps)--instance AddParams Schema where-  addParams ps s = s { sVars  = pTypes ps ++ sVars s-                     , sProps = pTypeConstraints ps ++ sProps s-                     , sType  = addParams ps (sType s)-                     }--instance AddParams Type where-  addParams ps t-    | null (pFuns ps) = t-    | otherwise       = tFun (paramRecTy ps) t---instance AddParams Expr where-  addParams ps e = foldr ETAbs withProps (pTypes ps ++ as)-    where (as,rest1) = splitWhile splitTAbs e-          (bs,rest2) = splitWhile splitProofAbs rest1-          withProps = foldr EProofAbs withArgs (pTypeConstraints ps ++ bs)-          withArgs-            | null (pFuns ps) = rest2-            | otherwise       = EAbs paramModRecParam (paramRecTy ps) rest2----instance AddParams DeclGroup where-  addParams ps dg =-    case dg of-      Recursive ds -> Recursive (addParams ps ds)-      NonRecursive d -> NonRecursive (addParams ps d)--instance AddParams Decl where-  addParams ps d =-    case dDefinition d of-      DPrim   -> d-      DExpr e -> d { dSignature = addParams ps (dSignature d)-                   , dDefinition = DExpr (addParams ps e)-                   , dName = toParamInstName (dName d)-                   }--instance AddParams TySyn where-  addParams ps ts = ts { tsParams = pTypes ps ++ tsParams ts-                       , tsConstraints = pTypeConstraints ps ++ tsConstraints ts-                          --  do we need these here ^ ?-                       , tsName = toParamInstName (tsName ts)-                       }--instance AddParams Newtype where-  addParams ps nt = nt { ntParams = pTypes ps ++ ntParams nt-                       , ntConstraints = pTypeConstraints ps ++ ntConstraints nt-                       , ntName = toParamInstName (ntName nt)-                       }-------------------------------------------------------------------------------------------- | Adjust uses of names to account for the new parameters.--- Assumes unique names---no capture or shadowing.-class Inst a where-  inst :: Inp -> a -> a---- | Set of top-level names which need to be instantiate, and module parameters.-type Inp = (Set Name, Params)---paramRecTy :: Params -> Type-paramRecTy ps = tRec (recordFromFields [ (nameIdent x, t) | (x,t) <- pFuns ps ])---nameInst :: Inp -> Name -> [Type] -> Int -> Expr-nameInst (_,ps) x ts prfs-  | null (pFuns ps) = withProofs-  | otherwise       = EApp withProofs (EVar paramModRecParam)-  where-  withProofs = iterate EProofApp withTys !!-                                        (length (pTypeConstraints ps) + prfs)--  withTys    = foldl ETApp (EVar (toParamInstName x))-                           (map (TVar . tpVar) (pTypes ps) ++ ts)----- | Extra parameters to dd when instantiating a type-instTyParams :: Inp -> [Type]-instTyParams (_,ps) = map (TVar . tpVar) (pTypes ps)---needsInst :: Inp -> Name -> Bool-needsInst (xs,_) x = Set.member x xs--isVParam :: Inp -> Name -> Bool-isVParam (_,ps) x = x `elem` map fst (pFuns ps)--isTParam :: Inp -> TVar -> Maybe TParam-isTParam (_,ps) x =-  case x of-    TVBound tp -> find thisName (pTypes ps)-      where thisName y = tpName tp == tpName y-    _ -> Nothing---instance Inst a => Inst [a] where-  inst ps = map (inst ps)--instance Inst Expr where-  inst ps expr =-    case expr of-     EVar x-      | needsInst ps x -> nameInst ps x [] 0-      | isVParam ps x ->-        let sh = map (nameIdent . fst) (pFuns (snd ps))-        in ESel (EVar paramModRecParam) (RecordSel (nameIdent x) (Just sh))-      | otherwise -> EVar x--     ELocated r t -> ELocated r (inst ps t)-     EList es t -> EList (inst ps es) (inst ps t)-     ETuple es -> ETuple (inst ps es)-     ERec fs   -> ERec (fmap (inst ps) fs)-     ESel e s  -> ESel (inst ps e) s-     ESet ty e s v -> ESet (inst ps ty) (inst ps e) s (inst ps v)--     EIf e1 e2 e3 -> EIf (inst ps e1) (inst ps e2) (inst ps e3)-     EComp t1 t2 e ms -> EComp (inst ps t1) (inst ps t2)-                               (inst ps e) (inst ps ms)--     ETAbs x e -> ETAbs x (inst ps e)-     ETApp e1 t ->-      case splitExprInst expr of-         (EVar x, ts, prfs) | needsInst ps x -> nameInst ps x ts prfs-         _ -> ETApp (inst ps e1) t--     EApp e1 e2 -> EApp (inst ps e1) (inst ps e2)-     EAbs x t e -> EAbs x (inst ps t) (inst ps e)--     EProofAbs p e -> EProofAbs (inst ps p) (inst ps e)-     EProofApp e1 ->-       case splitExprInst expr of-         (EVar x, ts, prfs) | needsInst ps x -> nameInst ps x ts prfs-         _ -> EProofApp (inst ps e1)--     EWhere e dgs  -> EWhere (inst ps e) (inst ps dgs)---instance Inst Match where-  inst ps m =-    case m of-      From x t1 t2 e -> From x (inst ps t1) (inst ps t2) (inst ps e)-      Let d          -> Let (inst ps d)--instance Inst DeclGroup where-  inst ps dg =-    case dg of-      Recursive ds -> Recursive (inst ps ds)-      NonRecursive d -> NonRecursive (inst ps d)--instance Inst Decl where-  inst ps d = d { dDefinition = inst ps (dDefinition d) }--instance Inst DeclDef where-  inst ps d =-    case d of-      DPrim -> DPrim-      DExpr e -> DExpr (inst ps e)--instance Inst Type where-  inst ps ty =-    case ty of-      TUser x ts t-        | needsInst ps x -> TUser x (instTyParams ps ++ ts1) t1-        | otherwise      -> TUser x ts1 t1-        where ts1 = inst ps ts-              t1  = inst ps t--      TNewtype nt ts-        | needsInst ps (ntName nt) -> TNewtype (inst ps nt) (instTyParams ps ++ ts1)-        | otherwise -> TNewtype nt ts1-        where ts1 = inst ps ts--      TCon tc ts -> TCon tc (inst ps ts)--      TVar x | Just x' <- isTParam ps x -> TVar (TVBound x')-             | otherwise  -> ty--      TRec xs -> TRec (fmap (inst ps) xs)--instance Inst TySyn where-  inst ps ts = ts { tsConstraints = inst ps (tsConstraints ts)-                  , tsDef = inst ps (tsDef ts)-                  }--instance Inst Newtype where-  inst ps nt = nt { ntConstraints = inst ps (ntConstraints nt)-                  , ntFields = fmap (inst ps) (ntFields nt)-                  }--
src/Cryptol/Transform/MonoValues.hs view
@@ -201,7 +201,9 @@       EWhere e dgs    -> EWhere      <$> go e <*> inLocal                                                   (mapM (rewDeclGroup rews) dgs) +      EPropGuards guards ty -> EPropGuards <$> (\(props, e) -> (,) <$> pure props <*> go e) `traverse` guards <*> pure ty + rewM :: RewMap -> Match -> M Match rewM rews ma =   case ma of@@ -216,8 +218,9 @@                  return d { dDefinition = e }  rewDef :: RewMap -> DeclDef -> M DeclDef-rewDef rews (DExpr e) = DExpr <$> rewE rews e-rewDef _    DPrim     = return DPrim+rewDef rews (DExpr e)    = DExpr <$> rewE rews e+rewDef _    DPrim        = return DPrim+rewDef _    (DForeign t) = return $ DForeign t  rewDeclGroup :: RewMap -> DeclGroup -> M DeclGroup rewDeclGroup rews dg =@@ -237,11 +240,12 @@    consider d   =     case dDefinition d of-      DPrim   -> Left d-      DExpr e -> let (tps,props,e') = splitTParams e-                 in if not (null tps) && notFun e'-                     then Right (d, tps, props, e')-                     else Left d+      DPrim      -> Left d+      DForeign _ -> Left d+      DExpr e    -> let (tps,props,e') = splitTParams e+                    in if not (null tps) && notFun e'+                        then Right (d, tps, props, e')+                        else Left d    rewSame ds =      do new <- forM (NE.toList ds) $ \(d,_,_,e) ->
src/Cryptol/Transform/Specialize.hs view
@@ -19,13 +19,18 @@ import qualified Cryptol.ModuleSystem.Env as M import qualified Cryptol.ModuleSystem.Monad as M import Cryptol.ModuleSystem.Name+import Cryptol.Utils.Ident(OrigName(..))+import Cryptol.Eval (checkProp)  import           Data.Map (Map) import qualified Data.Map as Map import Data.Maybe (catMaybes)+import qualified Data.List as List  import MonadLib hiding (mapM)+import Cryptol.ModuleSystem.Base (getPrimMap) + -- Specializer Monad -----------------------------------------------------------  -- | A 'Name' should have an entry in the 'SpecCache' iff it is@@ -102,7 +107,17 @@     EProofAbs p e -> EProofAbs p <$> specializeExpr e     EProofApp {}  -> specializeConst expr     EWhere e dgs  -> specializeEWhere e dgs+    -- The type should be monomorphic, and the guarded expressions should+    -- already be normalized, so we just need to choose the first expression+    -- that's true.+    EPropGuards guards ty -> +      case List.find (all checkProp . fst) guards of+        Just (_, e) -> specializeExpr e+        Nothing -> do+          pm <- liftSpecT getPrimMap+          pure $ eError pm ty "no constraint guard was satisfied" + specializeMatch :: Match -> SpecM Match specializeMatch (From qn l t e) = From qn l t <$> specializeExpr e specializeMatch (Let decl)@@ -187,9 +202,10 @@                  sig' <- instantiateSchema ts n (dSignature decl)                  modifySpecCache (Map.adjust (fmap (insertTM ts (qname', Nothing))) qname)                  rhs' <- case dDefinition decl of-                           DExpr e -> do e' <- specializeExpr =<< instantiateExpr ts n e-                                         return (DExpr e')-                           DPrim   -> return DPrim+                           DExpr e    -> do e' <- specializeExpr =<< instantiateExpr ts n e+                                            return (DExpr e')+                           DPrim      -> return DPrim+                           DForeign t -> return $ DForeign t                  let decl' = decl { dName = qname', dSignature = sig', dDefinition = rhs' }                  modifySpecCache (Map.adjust (fmap (insertTM ts (qname', Just decl'))) qname)                  return (EVar qname')@@ -245,8 +261,8 @@ freshName :: Name -> [Type] -> SpecM Name freshName n _ =   case nameInfo n of-    Declared m s  -> liftSupply (mkDeclared ns m s ident fx loc)-    Parameter     -> liftSupply (mkParameter ns ident loc)+    GlobalName s og -> liftSupply (mkDeclared ns (ogModule og) s ident fx loc)+    LocalName {}    -> liftSupply (mkLocal ns ident loc)   where   ns    = nameNamespace n   fx    = nameFixity n
src/Cryptol/TypeCheck.hs view
@@ -9,7 +9,6 @@  module Cryptol.TypeCheck   ( tcModule-  , tcModuleInst   , tcExpr   , tcDecls   , InferInput(..)@@ -28,12 +27,10 @@   , ppNamedError   ) where -import Data.IORef(IORef,modifyIORef') import Data.Map(Map)  import           Cryptol.ModuleSystem.Name                     (liftSupply,mkDeclared,NameSource(..),ModPath(..))-import Cryptol.ModuleSystem.NamingEnv(NamingEnv,namingEnvRename) import qualified Cryptol.Parser.AST as P import           Cryptol.Parser.Position(Range,emptyRange) import           Cryptol.TypeCheck.AST@@ -46,14 +43,10 @@                    , nameSeeds                    , lookupVar                    , newLocalScope, endLocalScope-                   , newModuleScope, addParamType, addParameterConstraints-                   , endModuleInstance-                   , io                    )-import Cryptol.TypeCheck.Infer (inferModule, inferBinds, checkTopDecls)+import Cryptol.TypeCheck.Infer (inferTopModule, inferBinds, checkTopDecls) import Cryptol.TypeCheck.InferTypes(VarType(..), SolverConfig(..), defaultSolverConfig) import Cryptol.TypeCheck.Solve(proveModuleTopLevel)-import Cryptol.TypeCheck.CheckModuleInstance(checkModuleInstance) -- import Cryptol.TypeCheck.Monad(withParamType,withParameterConstraints) import Cryptol.TypeCheck.PP(WithNames(..),NameMap) import Cryptol.Utils.Ident (exprModName,packIdent,Namespace(..))@@ -62,27 +55,8 @@   -tcModule :: P.Module Name -> InferInput -> IO (InferOutput Module)-tcModule m inp = runInferM inp (inferModule m)---- | Check a module instantiation, assuming that the functor has already--- been checked.--- XXX: This will change-tcModuleInst :: IORef NamingEnv {- ^ renaming environment of functor -} ->-                Module                  {- ^ functor -} ->-                P.Module Name           {- ^ params -} ->-                InferInput              {- ^ TC settings -} ->-                IO (InferOutput Module) {- ^ new version of instance -}-tcModuleInst renThis func m inp = runInferM inp $-  do x <- inferModule m-     newModuleScope (mName func) [] mempty-     mapM_ addParamType (mParamTypes x)-     addParameterConstraints (mParamConstraints x)-     (ren,y) <- checkModuleInstance func x-     io $ modifyIORef' renThis (namingEnvRename ren)-     proveModuleTopLevel-     endModuleInstance-     pure y+tcModule :: P.Module Name -> InferInput -> IO (InferOutput TCTopEntity)+tcModule m inp = runInferM inp (inferTopModule m)  tcExpr :: P.Expr Name -> InferInput -> IO (InferOutput (Expr,Schema)) tcExpr e0 inp = runInferM inp
src/Cryptol/TypeCheck/AST.hs view
@@ -13,12 +13,14 @@ {-# LANGUAGE FlexibleInstances, FlexibleContexts #-} {-# LANGUAGE DeriveAnyClass, DeriveGeneric       #-} {-# LANGUAGE OverloadedStrings                   #-}+{-# LANGUAGE NamedFieldPuns                      #-}+{-# LANGUAGE ViewPatterns                        #-} module Cryptol.TypeCheck.AST   ( module Cryptol.TypeCheck.AST   , Name()   , TFun(..)   , Selector(..)-  , Import, ImportG(..)+  , Import, ImportG(..), ImpName(..)   , ImportSpec(..)   , ExportType(..)   , ExportSpec(..), isExportedBind, isExportedType, isExported@@ -28,6 +30,10 @@   , module Cryptol.TypeCheck.Type   ) where +import Data.Maybe(mapMaybe)++import Cryptol.Utils.Panic(panic)+import Cryptol.Utils.Ident (Ident,isInfixIdent,ModName,PrimIdent,prelPrim) import Cryptol.Parser.Position(Located,Range,HasLoc(..)) import Cryptol.ModuleSystem.Name import Cryptol.ModuleSystem.Interface@@ -36,72 +42,124 @@ import Cryptol.Parser.AST ( Selector(..),Pragma(..)                           , Import                           , ImportG(..), ImportSpec(..), ExportType(..)-                          , Fixity(..))-import Cryptol.Utils.Ident (Ident,isInfixIdent,ModName,PrimIdent,prelPrim)+                          , Fixity(..)+                          , ImpName(..)+                          ) import Cryptol.Utils.RecordMap+import Cryptol.TypeCheck.FFI.FFIType import Cryptol.TypeCheck.PP import Cryptol.TypeCheck.Type  import GHC.Generics (Generic) import Control.DeepSeq ++import           Data.Set    (Set) import           Data.Map    (Map) import qualified Data.Map    as Map import qualified Data.IntMap as IntMap import           Data.Text (Text)  +data TCTopEntity =+    TCTopModule (ModuleG ModName)+  | TCTopSignature ModName ModParamNames+    deriving (Show, Generic, NFData)++tcTopEntitytName :: TCTopEntity -> ModName+tcTopEntitytName ent =+  case ent of+    TCTopModule m -> mName m+    TCTopSignature m _ -> m++-- | Panics if the entity is not a module+tcTopEntityToModule :: TCTopEntity -> Module+tcTopEntityToModule ent =+  case ent of+    TCTopModule m -> m+    TCTopSignature {} -> panic "tcTopEntityToModule" [ "Not a module" ]++ -- | A Cryptol module. data ModuleG mname =               Module { mName             :: !mname+                     , mDoc              :: !(Maybe Text)                      , mExports          :: ExportSpec Name-                     , mImports          :: [Import] -                       {-| Interfaces of submodules, including functors.-                           This is only the directly nested modules.-                           Info about more nested modules is in the-                           corresponding interface. -}-                     , mSubModules       :: Map Name (IfaceG Name)--                     -- params, if functor+                     -- Functors:                      , mParamTypes       :: Map Name ModTParam-                     , mParamConstraints :: [Located Prop]                      , mParamFuns        :: Map Name ModVParam+                     , mParamConstraints :: [Located Prop] +                     , mParams           :: FunctorParams+                       -- ^ Parameters grouped by "import". -                      -- Declarations, including everything from non-functor-                      -- submodules+                     , mFunctors         :: Map Name (ModuleG Name)+                       -- ^ Functors directly nested in this module.+                       -- Things further nested are in the modules in the+                       -- elements of the map.+++                     , mNested           :: !(Set Name)+                       -- ^ Submodules, functors, and interfaces nested directly+                       -- in this module++                      -- These have everything from this module and all submodules                      , mTySyns           :: Map Name TySyn                      , mNewtypes         :: Map Name Newtype                      , mPrimTypes        :: Map Name AbstractType                      , mDecls            :: [DeclGroup]-                     , mFunctors         :: Map Name (ModuleG Name)+                     , mSubmodules       :: Map Name (IfaceNames Name)+                     , mSignatures       :: !(Map Name ModParamNames)                      } deriving (Show, Generic, NFData)  emptyModule :: mname -> ModuleG mname emptyModule nm =   Module     { mName             = nm+    , mDoc              = Nothing     , mExports          = mempty-    , mImports          = []-    , mSubModules       = mempty +    , mParams           = mempty     , mParamTypes       = mempty     , mParamConstraints = mempty     , mParamFuns        = mempty +    , mNested           = mempty+     , mTySyns           = mempty     , mNewtypes         = mempty     , mPrimTypes        = mempty     , mDecls            = mempty     , mFunctors         = mempty+    , mSubmodules       = mempty+    , mSignatures       = mempty     } +-- | Find all the foreign declarations in the module and return their names and FFIFunTypes.+findForeignDecls :: ModuleG mname -> [(Name, FFIFunType)]+findForeignDecls = mapMaybe getForeign . mDecls+  where getForeign (NonRecursive Decl { dName, dDefinition = DForeign ffiType })+          = Just (dName, ffiType)+        -- Recursive DeclGroups can't have foreign decls+        getForeign _ = Nothing++-- | Find all the foreign declarations that are in functors.+-- This is used to report an error+findForeignDeclsInFunctors :: ModuleG mname -> [Name]+findForeignDeclsInFunctors = concatMap fromM . Map.elems . mFunctors+  where+  fromM m = map fst (findForeignDecls m) ++ findForeignDeclsInFunctors m++++ type Module = ModuleG ModName  -- | Is this a parameterized module? isParametrizedModule :: ModuleG mname -> Bool-isParametrizedModule m = not (null (mParamTypes m) &&+isParametrizedModule m = not (null (mParams m) &&+                              null (mParamTypes m) &&                               null (mParamConstraints m) &&                               null (mParamFuns m)) @@ -149,6 +207,8 @@              | EWhere Expr [DeclGroup] +            | EPropGuards [([Prop], Expr)] Type+               deriving (Show, Generic, NFData)  @@ -178,6 +238,7 @@                        } deriving (Generic, NFData, Show)  data DeclDef    = DPrim+                | DForeign FFIFunType                 | DExpr Expr                   deriving (Show, Generic, NFData) @@ -202,7 +263,14 @@   where v = fromEnum c         w = 8 :: Int +instance PP TCTopEntity where+  ppPrec _ te =+    case te of+      TCTopModule m -> pp m+      TCTopSignature x p ->+        ("interface" <+> pp x <+> "where") $$ nest 2 (pp p) + instance PP (WithNames Expr) where   ppPrec prec (WithNames expr nm) =     case expr of@@ -266,6 +334,12 @@                          , hang "where" 2 (vcat (map ppW ds))                          ] +      EPropGuards guards _ -> +        parens (text "propguards" <+> vsep (ppGuard <$> guards))+        where ppGuard (props, e) = indent 1+                                 $ pipe <+> commaSep (ppW <$> props)+                               <+> text "=>" <+> ppW e+     where     ppW x   = ppWithNames nm x     ppWP x  = ppWithNamesPrec nm x@@ -296,24 +370,38 @@                    Just (x,e1) -> let (xs,e2) = splitWhile f e1                                   in (x:xs,e2) +splitLoc :: Expr -> Maybe (Range, Expr)+splitLoc expr =+  case expr of+    ELocated r e -> Just (r,e)+    _            -> Nothing++-- | Remove outermost locations+dropLocs :: Expr -> Expr+dropLocs = snd . splitWhile splitLoc+ splitAbs :: Expr -> Maybe ((Name,Type), Expr)-splitAbs (EAbs x t e)         = Just ((x,t), e)-splitAbs _                    = Nothing+splitAbs (dropLocs -> EAbs x t e) = Just ((x,t), e)+splitAbs _                        = Nothing +splitApp :: Expr -> Maybe (Expr,Expr)+splitApp (dropLocs -> EApp f a) = Just (a, f)+splitApp _                      = Nothing+ splitTAbs :: Expr -> Maybe (TParam, Expr)-splitTAbs (ETAbs t e)         = Just (t, e)-splitTAbs _                   = Nothing+splitTAbs (dropLocs -> ETAbs t e)   = Just (t, e)+splitTAbs _                         = Nothing  splitProofAbs :: Expr -> Maybe (Prop, Expr)-splitProofAbs (EProofAbs p e) = Just (p,e)-splitProofAbs _               = Nothing+splitProofAbs (dropLocs -> EProofAbs p e) = Just (p,e)+splitProofAbs _                           = Nothing  splitTApp :: Expr -> Maybe (Type,Expr)-splitTApp (ETApp e t) = Just (t, e)-splitTApp _           = Nothing+splitTApp (dropLocs -> ETApp e t) = Just (t, e)+splitTApp _                       = Nothing  splitProofApp :: Expr -> Maybe ((), Expr)-splitProofApp (EProofApp e) = Just ((), e)+splitProofApp (dropLocs -> EProofApp e) = Just ((), e) splitProofApp _ = Nothing  -- | Deconstruct an expression, typically polymorphic, into@@ -368,8 +456,9 @@       ++ [ nest 2 (sep [pp dName <+> text "=", ppWithNames nm dDefinition]) ]  instance PP (WithNames DeclDef) where-  ppPrec _ (WithNames DPrim _)      = text "<primitive>"-  ppPrec _ (WithNames (DExpr e) nm) = ppWithNames nm e+  ppPrec _ (WithNames DPrim _)        = text "<primitive>"+  ppPrec _ (WithNames (DForeign _) _) = text "<foreign>"+  ppPrec _ (WithNames (DExpr e) nm)   = ppWithNames nm e  instance PP Decl where   ppPrec = ppWithNamesPrec IntMap.empty@@ -379,10 +468,21 @@  instance PP n => PP (WithNames (ModuleG n)) where   ppPrec _ (WithNames Module { .. } nm) =-    text "module" <+> pp mName $$-    -- XXX: Print exports?-    vcat (map pp mImports) $$-    -- XXX: Print tysyns-    -- XXX: Print abstarct types/functions-    vcat (map (ppWithNames (addTNames mps nm)) mDecls)+    vcat [ text "module" <+> pp mName+         -- XXX: Print exports?+         , vcat (map pp' (Map.elems mTySyns))+         -- XXX: Print abstarct types/functions+         , vcat (map pp' mDecls)++         , vcat (map pp (Map.elems mFunctors))+         ]     where mps = map mtpParam (Map.elems mParamTypes)+          pp' :: PP (WithNames a) => a -> Doc+          pp' = ppWithNames (addTNames mps nm)++instance PP (WithNames TCTopEntity) where+  ppPrec _ (WithNames ent nm) =+    case ent of+     TCTopModule m -> ppWithNames nm m+     TCTopSignature n ps ->+        hang ("interface module" <+> pp n <+> "where") 2 (pp ps)
− src/Cryptol/TypeCheck/CheckModuleInstance.hs
@@ -1,201 +0,0 @@-{-# Language OverloadedStrings #-}--- See Note [-Wincomplete-uni-patterns and irrefutable patterns] in Cryptol.TypeCheck.TypePat-{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}-module Cryptol.TypeCheck.CheckModuleInstance (checkModuleInstance) where--import           Data.Map ( Map )-import qualified Data.Map as Map-import           Control.Monad(unless)--import Cryptol.Parser.Position(Located(..))-import qualified Cryptol.Parser.AST as P-import Cryptol.ModuleSystem.Name (nameIdent, nameLoc)-import Cryptol.ModuleSystem.InstantiateModule(instantiateModule)-import Cryptol.TypeCheck.AST-import Cryptol.TypeCheck.Monad-import Cryptol.TypeCheck.Infer-import Cryptol.TypeCheck.Subst-import Cryptol.TypeCheck.Error-import Cryptol.Utils.Panic----- | Check that the instance provides what the functor needs.-checkModuleInstance :: Module {- ^ type-checked functor -} ->-                       Module {- ^ type-checked instance -} ->-                       InferM (Name->Name,Module)-                       -- ^ Renaming,Instantiated module-checkModuleInstance func inst-  | not (null (mSubModules func) && null (mSubModules inst)) =-    do recordError $ TemporaryError-         "Cannot combine nested modules with old-style parameterized modules"-       pure (id,func) -- doesn't matter?-  | otherwise =-  do tMap <- checkTyParams func inst-     vMap <- checkValParams func tMap inst-     (ren, ctrs, m) <- instantiateModule func (mName inst) tMap vMap-     let toG p = Goal { goal = thing p-                      , goalRange = srcRange p-                      , goalSource = CtModuleInstance (mName inst)-                      }-     addGoals (map toG ctrs)-     return ( ren-            , Module { mName = mName m-                   , mExports = mExports m-                   , mImports = mImports inst ++ mImports m-                                -- Note that this is just here to record-                                -- the full dependencies, the actual imports-                                -- might be ambiguous, but that shouldn't-                                -- matters as names have been already resolved-                   , mTySyns      = Map.union (mTySyns inst) (mTySyns m)-                   , mNewtypes    = Map.union (mNewtypes inst) (mNewtypes m)-                   , mPrimTypes   = Map.union (mPrimTypes inst) (mPrimTypes m)-                   , mParamTypes       = mParamTypes inst-                   , mParamConstraints = mParamConstraints inst-                   , mParamFuns        = mParamFuns inst-                   , mDecls            = mDecls inst ++ mDecls m--                   , mSubModules = mempty-                   , mFunctors   = mempty-                   }-              )---- | Check that the type parameters of the functors all have appropriate--- definitions.-checkTyParams :: Module -> Module -> InferM (Map TParam Type)-checkTyParams func inst =-  Map.fromList <$> mapM checkTParamDefined (Map.elems (mParamTypes func))--  where-  -- Maps to lookup things by identifier (i.e., lexical name)-  -- rather than using the name unique.-  identMap f m = Map.fromList [ (f x, ts) | (x,ts) <- Map.toList m ]-  tySyns       = identMap nameIdent (mTySyns inst)-  newTys       = identMap nameIdent (mNewtypes inst)-  tParams      = Map.fromList [ (tpId x, x) | x0 <- Map.elems (mParamTypes inst)-                                            , let x = mtpParam x0 ]--  tpName' x    = case tpName x of-                   Just n -> n-                   Nothing -> panic "inferModuleInstance.tpId" ["Missing name"]--  tpId         = nameIdent . tpName'--  -- Find a definition for a given type parameter-  checkTParamDefined tp0 =-    let tp = mtpParam tp0-        x = tpId tp-    in case Map.lookup x tySyns of-         Just ts -> checkTySynDef tp ts-         Nothing ->-           case Map.lookup x newTys of-             Just nt -> checkNewTyDef tp nt-             Nothing ->-               case Map.lookup x tParams of-                 Just tp1 -> checkTP tp tp1-                 Nothing ->-                   do let x' = Located { thing = x,-                                         srcRange = nameLoc (tpName' tp) }-                      recordError (MissingModTParam x')-                      return (tp, TVar (TVBound tp)) -- hm, maybe just stop!--  -- Check that a type parameter defined as a type synonym is OK-  checkTySynDef tp ts =-    do let k1 = kindOf tp-           k2 = kindOf ts-       unless (k1 == k2) (recordError (KindMismatch Nothing k1 k2))--       let nm  = tsName ts-           src = CtPartialTypeFun nm-       mapM_ (newGoal src) (tsConstraints ts)--       return (tp, TUser nm [] (tsDef ts))--  -- Check that a type parameter defined a newtype is OK-  -- This one is a bit weird: since the newtype is deinfed in the-  -- instantiation, it will not be exported, and so won't be usable-  -- in type signatures, directly.   This could be worked around-  -- if the parametrized module explictly exported a parameter via-  -- a type synonym like this: `type T = p`, where `p` is one of-  -- the parametersm and the declartion for `T` is public.-  checkNewTyDef tp nt =-    do let k1 = kindOf tp-           k2 = kindOf nt-       unless (k1 == k2) (recordError (KindMismatch Nothing k1 k2))--       let nm = ntName nt-           src = CtPartialTypeFun nm-       mapM_ (newGoal src) (ntConstraints nt)--       return (tp, TNewtype nt [])--  -- Check that a type parameter defined as another type parameter is OK-  checkTP tp tp1 =-    do let k1 = kindOf tp-           k2 = kindOf tp1-       unless (k1 == k2) (recordError (KindMismatch Nothing k1 k2))--       return (tp, TVar (TVBound tp1))-----checkValParams :: Module          {- ^ Parameterized module -} ->-                  Map TParam Type {- ^ Type instantiations -} ->-                  Module          {- ^ Instantiation module -} ->-                  InferM (Map Name Expr)-                  -- ^ Definitions for the parameters-checkValParams func tMap inst =-  Map.fromList <$> mapM checkParam (Map.elems (mParamFuns func))-  where-  valMap = Map.fromList (defByParam ++ defByDef)--  defByDef = [ (nameIdent (dName d), (dName d, dSignature d))-                          | dg <- mDecls inst, d <- groupDecls dg ]--  defByParam = [ (nameIdent x, (x, mvpType s)) |-                                    (x,s) <- Map.toList (mParamFuns inst) ]--  su = listParamSubst (Map.toList tMap)--  checkParam pr =-    let x = mvpName pr-        sP = mvpType pr-    in-    case Map.lookup (nameIdent x) valMap of-      Just (n,sD) -> do e <- makeValParamDef n sD (apSubst su sP)-                        return (x,e)-      Nothing -> do recordError (MissingModVParam-                                 Located { thing = nameIdent x-                                         , srcRange = nameLoc x })-                    return (x, panic "checkValParams" ["Should not use this"])------ | Given a parameter definition, compute an appropriate instantiation--- that will match the actual schema for the parameter.-makeValParamDef :: Name   {- ^ Definition of parameter -} ->-                   Schema {- ^ Schema for parameter definition -} ->-                   Schema {- ^ Schema for parameter -} ->-                   InferM Expr {- ^ Expression to use for param definition -}--makeValParamDef x sDef pDef =-  withVar x sDef $ do ~(DExpr e) <- dDefinition <$> checkSigB bnd (pDef,[])-                      return e-  where-  bnd = P.Bind { P.bName      = loc x-               , P.bParams    = []-               , P.bDef       = loc (P.DExpr (P.EVar x))--                -- unused-               , P.bSignature = Nothing-               , P.bInfix     = False-               , P.bFixity    = Nothing-               , P.bPragmas   = []-               , P.bMono      = False-               , P.bDoc       = Nothing-               , P.bExport    = Public-               }-  loc a = P.Located { P.srcRange = nameLoc x, P.thing = a }---
src/Cryptol/TypeCheck/Default.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE Safe #-}+ module Cryptol.TypeCheck.Default where  import qualified Data.Set as Set
src/Cryptol/TypeCheck/Error.hs view
@@ -12,15 +12,16 @@ import Data.List((\\),sortBy,groupBy,partition) import Data.Function(on) +import Cryptol.Utils.Ident(Ident,Namespace(..)) import qualified Cryptol.Parser.AST as P-import Cryptol.Parser.Position(Located(..), Range(..))+import Cryptol.Parser.Position(Located(..), Range(..), rangeWithin) import Cryptol.TypeCheck.PP import Cryptol.TypeCheck.Type import Cryptol.TypeCheck.InferTypes import Cryptol.TypeCheck.Subst import Cryptol.TypeCheck.Unify(Path,isRootPath)+import Cryptol.TypeCheck.FFI.Error import Cryptol.ModuleSystem.Name(Name)-import Cryptol.Utils.Ident(Ident) import Cryptol.Utils.RecordMap  cleanupErrors :: [(Range,Error)] -> [(Range,Error)]@@ -56,6 +57,8 @@ -- | Should the first error suppress the next one. subsumes :: (Range,Error) -> (Range,Error) -> Bool subsumes (_,NotForAll _ _ x _) (_,NotForAll _ _ y _) = x == y+subsumes (r1,UnexpectedTypeWildCard) (r2,UnsupportedFFIType{}) =+  r1 `rangeWithin` r2 subsumes (r1,KindMismatch {}) (r2,err) =   case err of     KindMismatch {} -> r1 == r2@@ -65,6 +68,7 @@ data Warning  = DefaultingKind (P.TParam Name) P.Kind               | DefaultingWildType P.Kind               | DefaultingTo !TVarInfo Type+              | NonExhaustivePropGuards Name                 deriving (Show, Generic, NFData)  -- | Various errors that might happen during type checking/inference@@ -90,6 +94,10 @@               | TypeMismatch TypeSource Path Type Type                 -- ^ Expected type, inferred type +              | SchemaMismatch Ident Schema Schema+                -- ^ Name of module parameter, expected scehema, actual schema.+                -- This may happen when instantiating modules.+               | RecursiveType TypeSource Path Type Type                 -- ^ Unification results in a recursive type @@ -142,7 +150,28 @@               | TypeShadowing String Name String               | MissingModTParam (Located Ident)               | MissingModVParam (Located Ident)+              | MissingModParam Ident +              | FunctorInstanceMissingArgument Ident+              | FunctorInstanceBadArgument Ident+              | FunctorInstanceMissingName Namespace Ident+              | FunctorInstanceBadBacktick BadBacktickInstance++              | UnsupportedFFIKind TypeSource TParam Kind+                -- ^ Kind is not supported for FFI+              | UnsupportedFFIType TypeSource FFITypeError+                -- ^ Type is not supported for FFI++              | NestedConstraintGuard Ident+                -- ^ Constraint guards may only apper at the top-level++              | DeclarationRequiresSignatureCtrGrd Ident+                -- ^ All declarataions in a recursive group involving+                -- constraint guards should have signatures++              | InvalidConstraintGuard Prop+                -- ^ The given constraint may not be used as a constraint guard+               | TemporaryError Doc                 -- ^ This is for errors that don't fit other cateogories.                 -- We should not use it much, and is generally to be used@@ -150,6 +179,15 @@                 -- implementation.                 deriving (Show, Generic, NFData) +data BadBacktickInstance =+    BIPolymorphicArgument Ident Ident+  | BINested [(BIWhat, Name)]+  | BIMultipleParams Ident+    deriving (Show, Generic, NFData)++data BIWhat = BIFunctor | BIInterface | BIPrimitive | BIForeign | BIAbstractType+    deriving (Show, Generic, NFData)+ -- | When we have multiple errors on the same location, we show only the -- ones with the has highest rating according to this function. errorImportance :: Error -> Int@@ -159,10 +197,17 @@     TemporaryError {}                                -> 11     -- show these as usually means the user used something that doesn't work +    FunctorInstanceMissingArgument {}                 -> 10+    MissingModParam {}                                -> 10+    FunctorInstanceBadArgument {}                     -> 10+    FunctorInstanceMissingName {}                     ->  9+    FunctorInstanceBadBacktick {}                     ->  9 +     KindMismatch {}                                  -> 10     TyVarWithParams {}                               -> 9     TypeMismatch {}                                  -> 8+    SchemaMismatch {}                                -> 7     RecursiveType {}                                 -> 7     NotForAll {}                                     -> 6     TypeVariableEscaped {}                           -> 5@@ -199,7 +244,13 @@      AmbiguousSize {}                                 -> 2 +    UnsupportedFFIKind {}                            -> 10+    UnsupportedFFIType {}                            -> 7+    -- less than UnexpectedTypeWildCard +    NestedConstraintGuard {}                         -> 10+    DeclarationRequiresSignatureCtrGrd {}            -> 9+    InvalidConstraintGuard {}                        -> 5   instance TVars Warning where@@ -208,6 +259,7 @@       DefaultingKind {}     -> warn       DefaultingWildType {} -> warn       DefaultingTo d ty     -> DefaultingTo d $! (apSubst su ty)+      NonExhaustivePropGuards {} -> warn  instance FVS Warning where   fvs warn =@@ -215,6 +267,7 @@       DefaultingKind {}     -> Set.empty       DefaultingWildType {} -> Set.empty       DefaultingTo _ ty     -> fvs ty+      NonExhaustivePropGuards {} -> Set.empty  instance TVars Error where   apSubst su err =@@ -225,6 +278,8 @@       TooManyTySynParams {}     -> err       TooFewTyParams {}         -> err       RecursiveTypeDecls {}     -> err+      SchemaMismatch i t1 t2  ->+        SchemaMismatch i !$ (apSubst su t1) !$ (apSubst su t2)       TypeMismatch src pa t1 t2 -> TypeMismatch src pa !$ (apSubst su t1) !$ (apSubst su t2)       RecursiveType src pa t1 t2   -> RecursiveType src pa !$ (apSubst su t1) !$ (apSubst su t2)       UnsolvedGoals gs          -> UnsolvedGoals !$ apSubst su gs@@ -248,7 +303,20 @@       TypeShadowing {}     -> err       MissingModTParam {}  -> err       MissingModVParam {}  -> err+      MissingModParam {}   -> err +      FunctorInstanceMissingArgument {} -> err+      FunctorInstanceBadArgument {} -> err+      FunctorInstanceMissingName {} -> err+      FunctorInstanceBadBacktick {} -> err++      UnsupportedFFIKind {}    -> err+      UnsupportedFFIType src e -> UnsupportedFFIType src !$ apSubst su e++      NestedConstraintGuard {} -> err+      DeclarationRequiresSignatureCtrGrd {} -> err+      InvalidConstraintGuard p -> InvalidConstraintGuard $! apSubst su p+       TemporaryError {} -> err  @@ -261,6 +329,7 @@       TooManyTySynParams {}     -> Set.empty       TooFewTyParams {}         -> Set.empty       RecursiveTypeDecls {}     -> Set.empty+      SchemaMismatch _ t1 t2    -> fvs (t1,t2)       TypeMismatch _ _ t1 t2    -> fvs (t1,t2)       RecursiveType _ _ t1 t2   -> fvs (t1,t2)       UnsolvedGoals gs          -> fvs gs@@ -283,7 +352,20 @@       TypeShadowing {}     -> Set.empty       MissingModTParam {}  -> Set.empty       MissingModVParam {}  -> Set.empty+      MissingModParam {}   -> Set.empty +      FunctorInstanceMissingArgument {} -> Set.empty+      FunctorInstanceBadArgument {} -> Set.empty+      FunctorInstanceMissingName {} -> Set.empty+      FunctorInstanceBadBacktick {} -> Set.empty++      UnsupportedFFIKind {}  -> Set.empty+      UnsupportedFFIType _ t -> fvs t++      NestedConstraintGuard {} -> Set.empty+      DeclarationRequiresSignatureCtrGrd {} -> Set.empty+      InvalidConstraintGuard p -> fvs p+       TemporaryError {} -> Set.empty  instance PP Warning where@@ -307,6 +389,10 @@         text "Defaulting" <+> pp (tvarDesc d) <+> text "to"                                               <+> ppWithNames names ty +      NonExhaustivePropGuards n ->+        text "Could not prove that the constraint guards used in defining" <+> +        pp n <+> text "were exhaustive."+ instance PP (WithNames Error) where   ppPrec _ (WithNames err names) =     case err of@@ -321,8 +407,13 @@        UnexpectedTypeWildCard ->         addTVarsDescsAfter names err $-        nested "Wild card types are not allowed in this context"-          "(e.g., they cannot be used in type synonyms)."+        nested "Wild card types are not allowed in this context" $+          vcat [ "They cannot be used in:"+               , bullets [ "type synonyms"+                         , "FFI declarations"+                         , "declarations with constraint guards"+                         ]+               ]        KindMismatch mbsrc k1 k2 ->         addTVarsDescsAfter names err $@@ -370,6 +461,14 @@             ++ ppCtxt pa             ++ ["When checking" <+> pp src] +      SchemaMismatch i t1 t2 ->+          addTVarsDescsAfter names err $+          nested ("Type mismatch in module parameter" <+> quotes (pp i)) $+          vcat $+            [ "Expected type:" <+> ppWithNames names t1+            , "Actual type:"   <+> ppWithNames names t2+            ]+       UnsolvableGoals gs -> explainUnsolvable names gs        UnsolvedGoals gs@@ -456,6 +555,91 @@         "Missing definition for type parameter" <+> quotes (pp (thing x))       MissingModVParam x ->         "Missing definition for value parameter" <+> quotes (pp (thing x))++      MissingModParam x ->+        "Missing module parameter" <+> quotes (pp x)++      FunctorInstanceMissingArgument i ->+        "Missing functor argument" <+> quotes (pp i)++      FunctorInstanceBadArgument i ->+        "Functor does not have parameter" <+> quotes (pp i)++      FunctorInstanceMissingName ns i ->+        "Functor argument does not define" <+> sayNS <+> "parameter" <+>+            quotes (pp i)+        where+        sayNS =+          case ns of+              NSValue     -> "value"+              NSType      -> "type"+              NSModule    -> "module"++      FunctorInstanceBadBacktick bad ->+        case bad of+          BIPolymorphicArgument i x ->+            nested "Value parameter may not have a polymorphic type:" $+              bullets+                [ "Module parameter:" <+> pp i+                , "Value parameter:" <+> pp x+                , "When instantiatiating a functor using parameterization,"+                  $$ "the value parameters need to have a simple type."+                ]++          BINested what ->+            nested "Invalid declarations in parameterized instantiation:" $+              bullets $+                [ it <+> pp n+                | (w,n) <- what+                , let it = case w of+                             BIFunctor -> "functor"+                             BIInterface -> "interface"+                             BIPrimitive -> "primitive"+                             BIAbstractType -> "abstract type"+                             BIForeign -> "foreign import"+                ] +++                [ "A functor instantiated using parameterization," $$+                  "may not contain nested functors, interfaces, or primitives."+                ]+          BIMultipleParams x ->+            nested "Repeated parameter name in parameterized instantiation:" $+              bullets+                [ "Parameter name:" <+> pp x+                , "Parameterized instantiation requires distinct parameter names"+                ]+                ++      UnsupportedFFIKind src param k ->+        nested "Kind of type variable unsupported for FFI: " $+        vcat+          [ pp param <+> colon <+> pp k+          , "Only type variables of kind" <+> pp KNum <+> "are supported"+          , "When checking" <+> pp src ]++      UnsupportedFFIType src t -> vcat+        [ ppWithNames names t+        , "When checking" <+> pp src ]++      NestedConstraintGuard d ->+        vcat [ "Local declaration" <+> backticks (pp d)+                                   <+> "may not use constraint guards."+             , "Constraint guards may only appear at the top-level of a module."+             ]++      DeclarationRequiresSignatureCtrGrd d ->+        vcat [ "The declaration of" <+> backticks (pp d) <+>+                                            "requires a full type signature,"+             , "because it is part of a recursive group with constraint guards."+             ]++      InvalidConstraintGuard p ->+        let d = case tNoUser p of+                  TCon tc _ -> pp tc+                  _         -> ppWithNames names p+        in+        vcat [ backticks d <+> "may not be used in a constraint guard."+             , "Constraint guards support only numeric comparisons and `fin`."+             ]        TemporaryError doc -> doc     where
+ src/Cryptol/TypeCheck/FFI.hs view
@@ -0,0 +1,112 @@+{-# LANGUAGE BlockArguments  #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns    #-}+{-# LANGUAGE Safe    #-}++-- | Checking and conversion of 'Type's to 'FFIType's.+module Cryptol.TypeCheck.FFI+  ( toFFIFunType+  ) where++import           Data.Bifunctor+import           Data.Containers.ListUtils+import           Data.Either++import           Cryptol.TypeCheck.FFI.Error+import           Cryptol.TypeCheck.FFI.FFIType+import           Cryptol.TypeCheck.SimpType+import           Cryptol.TypeCheck.Type+import           Cryptol.Utils.RecordMap+import           Cryptol.Utils.Types++-- | Convert a 'Schema' to a 'FFIFunType', along with any 'Prop's that must be+-- satisfied for the 'FFIFunType' to be valid.+toFFIFunType :: Schema -> Either FFITypeError ([Prop], FFIFunType)+toFFIFunType (Forall params _ t) =+  -- Remove all type synonyms and simplify the type before processing it+  case go $ tRebuild' False t of+    Just (Right (props, fft)) -> Right+      -- Remove duplicate constraints+      (nubOrd $ map (fin . TVar . TVBound) params ++ props, fft)+    Just (Left errs) -> Left $ FFITypeError t $ FFIBadComponentTypes errs+    Nothing -> Left $ FFITypeError t FFINotFunction+  where go (TCon (TC TCFun) [argType, retType]) = Just+          case toFFIType argType of+            Right (ps, ffiArgType) ->+              case go retType of+                Just (Right (ps', ffiFunType)) -> Right+                  ( ps ++ ps'+                  , ffiFunType+                      { ffiArgTypes = ffiArgType : ffiArgTypes ffiFunType } )+                Just (Left errs) -> Left errs+                Nothing ->+                  case toFFIType retType of+                    Right (ps', ffiRetType) -> Right+                      ( ps ++ ps'+                      , FFIFunType+                          { ffiTParams = params+                          , ffiArgTypes = [ffiArgType], .. } )+                    Left err -> Left [err]+            Left err -> Left+              case go retType of+                Just (Right _) -> [err]+                Just (Left errs) -> err : errs+                Nothing ->+                  case toFFIType retType of+                    Right _   -> [err]+                    Left err' -> [err, err']+        go _ = Nothing++-- | Convert a 'Type' to a 'FFIType', along with any 'Prop's that must be+-- satisfied for the 'FFIType' to be valid.+toFFIType :: Type -> Either FFITypeError ([Prop], FFIType)+toFFIType t =+  case t of+    TCon (TC TCBit) [] -> Right ([], FFIBool)+    (toFFIBasicType -> Just r) -> (\fbt -> ([], FFIBasic fbt)) <$> r+    TCon (TC TCSeq) _ ->+      (\(szs, fbt) -> (map fin szs, FFIArray szs fbt)) <$> go t+      where go (toFFIBasicType -> Just r) =+              case r of+                Right fbt -> Right ([], fbt)+                Left err  -> Left $ FFITypeError t $ FFIBadComponentTypes [err]+            go (TCon (TC TCSeq) [sz, ty]) = first (sz:) <$> go ty+            go _ = Left $ FFITypeError t FFIBadArrayType+    TCon (TC (TCTuple _)) ts ->+      case partitionEithers $ map toFFIType ts of+        ([], unzip -> (pss, fts)) -> Right (concat pss, FFITuple fts)+        (errs, _) -> Left $ FFITypeError t $ FFIBadComponentTypes errs+    TRec tMap ->+      case sequence resMap of+        Right resMap' -> Right $ FFIRecord <$>+          recordMapAccum (\ps (ps', ft) -> (ps' ++ ps, ft)) [] resMap'+        Left _ -> Left $ FFITypeError t $+          FFIBadComponentTypes $ lefts $ displayElements resMap+      where resMap = fmap toFFIType tMap+    _ -> Left $ FFITypeError t FFIBadType++-- | Convert a 'Type' to a 'FFIBasicType', returning 'Nothing' if it isn't a+-- basic type and 'Left' if it is but there was some other issue with it.+toFFIBasicType :: Type -> Maybe (Either FFITypeError FFIBasicType)+toFFIBasicType t =+  case t of+    TCon (TC TCSeq) [TCon (TC (TCNum n)) [], TCon (TC TCBit) []]+      | n <= 8 -> word FFIWord8+      | n <= 16 -> word FFIWord16+      | n <= 32 -> word FFIWord32+      | n <= 64 -> word FFIWord64+      | otherwise -> Just $ Left $ FFITypeError t FFIBadWordSize+      where word = Just . Right . FFIBasicVal . FFIWord n+    TCon (TC TCFloat) [TCon (TC (TCNum e)) [], TCon (TC (TCNum p)) []]+      | (e, p) == float32ExpPrec -> float FFIFloat32+      | (e, p) == float64ExpPrec -> float FFIFloat64+      | otherwise -> Just $ Left $ FFITypeError t FFIBadFloatSize+      where float = Just . Right . FFIBasicVal . FFIFloat e p+    TCon (TC TCInteger) [] -> integer Nothing+    TCon (TC TCIntMod) [n] -> integer $ Just n+    TCon (TC TCRational) [] -> Just $ Right $ FFIBasicRef FFIRational+    _ -> Nothing+  where integer = Just . Right . FFIBasicRef . FFIInteger++fin :: Type -> Prop+fin t = TCon (PC PFin) [t]
+ src/Cryptol/TypeCheck/FFI/Error.hs view
@@ -0,0 +1,83 @@+{-# LANGUAGE DeriveAnyClass    #-}+{-# LANGUAGE DeriveGeneric     #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE Safe #-}++-- | Errors from typechecking foreign functions.+module Cryptol.TypeCheck.FFI.Error where++import           Control.DeepSeq+import           GHC.Generics++import           Cryptol.TypeCheck.PP+import           Cryptol.TypeCheck.Subst+import           Cryptol.TypeCheck.Type++data FFITypeError = FFITypeError Type FFITypeErrorReason+  deriving (Show, Generic, NFData)++data FFITypeErrorReason+  = FFIBadWordSize+  | FFIBadFloatSize+  | FFIBadArrayType+  | FFIBadComponentTypes [FFITypeError]+  | FFIBadType+  | FFINotFunction+  deriving (Show, Generic, NFData)++instance TVars FFITypeError where+  apSubst su (FFITypeError t r) = FFITypeError !$ apSubst su t !$ apSubst su r++instance TVars FFITypeErrorReason where+  apSubst su r =+    case r of+      FFIBadWordSize            -> r+      FFIBadFloatSize           -> r+      FFIBadArrayType           -> r+      FFIBadComponentTypes errs -> FFIBadComponentTypes !$ apSubst su errs+      FFIBadType                -> r+      FFINotFunction            -> r++instance FVS FFITypeError where+  fvs (FFITypeError t r) = fvs (t, r)++instance FVS FFITypeErrorReason where+  fvs r =+    case r of+      FFIBadWordSize            -> mempty+      FFIBadFloatSize           -> mempty+      FFIBadArrayType           -> mempty+      FFIBadComponentTypes errs -> fvs errs+      FFIBadType                -> mempty+      FFINotFunction            -> mempty++instance PP (WithNames FFITypeError) where+  ppPrec _ (WithNames (FFITypeError t r) names) =+    nest 2 $ "Type unsupported for FFI:" $$+      vcat+        [ ppWithNames names t+        , "Due to:"+        , ppWithNames names r ]++instance PP (WithNames FFITypeErrorReason) where+  ppPrec _ (WithNames r names) =+    case r of+      FFIBadWordSize -> vcat+        [ "Unsupported word size"+        , "Only words of up to 64 bits are supported" ]+      FFIBadFloatSize -> vcat+        [ "Unsupported Float format"+        , "Only Float32 and Float64 are supported" ]+      FFIBadArrayType -> vcat+        [ "Unsupported sequence element type"+        , "Only words or floats are supported as the element type of"+        , "(possibly multidimensional) sequences"+        ]+      FFIBadComponentTypes errs ->+        indent 2 $ vcat $ map (ppWithNames names) errs+      FFIBadType -> vcat+        [ "Only Bit, words, floats, Integer, Z, Rational, sequences, or structs"+        , "or tuples of the above are supported as FFI argument or return types"+        ]+      FFINotFunction -> "FFI binding must be a function"
+ src/Cryptol/TypeCheck/FFI/FFIType.hs view
@@ -0,0 +1,70 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric  #-}+{-# LANGUAGE Safe #-}++-- | This module defines a nicer intermediate representation of Cryptol types+-- allowed for the FFI, which the typechecker generates then stores in the AST.+-- This way the FFI evaluation code does not have to examine the raw type+-- signatures again.+module Cryptol.TypeCheck.FFI.FFIType where++import           Control.DeepSeq+import           GHC.Generics++import           Cryptol.TypeCheck.Type+import           Cryptol.Utils.Ident+import           Cryptol.Utils.RecordMap++-- | Type of a foreign function.+data FFIFunType = FFIFunType+  { -- | Note: any type variables within this function type must be bound here.+    ffiTParams  :: [TParam]+  , ffiArgTypes :: [FFIType]+  , ffiRetType  :: FFIType }+  deriving (Show, Generic, NFData)++-- | Type of a value that can be passed to or returned from a foreign function.+data FFIType+  = FFIBool+  | FFIBasic FFIBasicType+  -- | [n][m][p]T --> FFIArray [n, m, p] T+  | FFIArray [Type] FFIBasicType+  | FFITuple [FFIType]+  | FFIRecord (RecordMap Ident FFIType)+  deriving (Show, Generic, NFData)++-- | Types which can be elements of FFI arrays.+data FFIBasicType+  = FFIBasicVal FFIBasicValType+  | FFIBasicRef FFIBasicRefType+  deriving (Show, Generic, NFData)++-- | Basic type which is passed and returned directly by value.+data FFIBasicValType+  = FFIWord+      Integer     -- ^ The size of the Cryptol type+      FFIWordSize -- ^ The machine word size that it corresponds to+  | FFIFloat+      Integer      -- ^ Exponent+      Integer      -- ^ Precision+      FFIFloatSize -- ^ The machine float size that it corresponds to+  deriving (Show, Generic, NFData)++data FFIWordSize+  = FFIWord8+  | FFIWord16+  | FFIWord32+  | FFIWord64+  deriving (Show, Generic, NFData)++data FFIFloatSize+  = FFIFloat32+  | FFIFloat64+  deriving (Show, Generic, NFData)++-- | Basic type which is passed and returned by reference through a parameter.+data FFIBasicRefType+  = FFIInteger+      (Maybe Type) -- ^ Modulus (Just for Z, Nothing for Integer)+  | FFIRational+  deriving (Show, Generic, NFData)
src/Cryptol/TypeCheck/Infer.hs view
@@ -14,13 +14,16 @@ {-# LANGUAGE RecursiveDo #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE BlockArguments #-}-{-# LANGUAGE Safe #-} -- See Note [-Wincomplete-uni-patterns and irrefutable patterns] in Cryptol.TypeCheck.TypePat {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}+{-# LANGUAGE LambdaCase #-}+{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}+{-# HLINT ignore "Redundant <$>" #-}+{-# HLINT ignore "Redundant <&>" #-} module Cryptol.TypeCheck.Infer   ( checkE   , checkSigB-  , inferModule+  , inferTopModule   , inferBinds   , checkTopDecls   )@@ -30,7 +33,7 @@ import qualified Data.Text as Text  -import           Cryptol.ModuleSystem.Name (lookupPrimDecl,nameLoc)+import           Cryptol.ModuleSystem.Name (lookupPrimDecl,nameLoc, nameIdent) import           Cryptol.Parser.Position import qualified Cryptol.Parser.AST as P import qualified Cryptol.ModuleSystem.Exports as P@@ -43,36 +46,58 @@                                         checkPropSyn,checkNewtype,                                         checkParameterType,                                         checkPrimType,-                                        checkParameterConstraints)+                                        checkParameterConstraints,+                                        checkPropGuards) import           Cryptol.TypeCheck.Instantiate import           Cryptol.TypeCheck.Subst (listSubst,apSubst,(@@),isEmptySubst) import           Cryptol.TypeCheck.Unify(rootPath)+import           Cryptol.TypeCheck.Module+import           Cryptol.TypeCheck.FFI+import           Cryptol.TypeCheck.FFI.FFIType import           Cryptol.Utils.Ident import           Cryptol.Utils.Panic(panic) import           Cryptol.Utils.RecordMap+import           Cryptol.IR.TraverseNames(mapNames)+import           Cryptol.Utils.PP (pp)  import qualified Data.Map as Map import           Data.Map (Map) import qualified Data.Set as Set-import           Data.List(foldl',sortBy,groupBy)+import           Data.List(foldl', sortBy, groupBy, partition) import           Data.Either(partitionEithers) import           Data.Maybe(isJust, fromMaybe, mapMaybe)-import           Data.List(partition) import           Data.Ratio(numerator,denominator) import           Data.Traversable(forM) import           Data.Function(on)-import           Control.Monad(zipWithM,unless,foldM,forM_,mplus)+import           Control.Monad(zipWithM, unless, foldM, forM_, mplus, zipWithM,+                               unless, foldM, forM_, mplus, when) +-- import Debug.Trace+-- import Cryptol.TypeCheck.PP +inferTopModule :: P.Module Name -> InferM TCTopEntity+inferTopModule m =+  case P.mDef m of+    P.NormalModule ds ->+      do newModuleScope (thing (P.mName m)) (P.exportedDecls ds)+         checkTopDecls ds+         proveModuleTopLevel+         endModule -inferModule :: P.Module Name -> InferM Module-inferModule m =-  do newModuleScope (thing (P.mName m)) (map thing (P.mImports m))-                                        (P.modExports m)-     checkTopDecls (P.mDecls m)-     proveModuleTopLevel-     endModule+    P.FunctorInstance f as inst ->+      do mb <- doFunctorInst (P.ImpTop <$> P.mName m) f as inst Nothing+         case mb of+           Just mo -> pure mo+           Nothing -> panic "inferModule" ["Didnt' get a module"] +    P.InterfaceModule sig ->+      do newTopSignatureScope (thing (P.mName m))+         checkSignature sig+         endTopSignature++++ -- | Construct a Prelude primitive in the parsed AST. mkPrim :: String -> InferM (P.Expr Name) mkPrim str =@@ -157,8 +182,6 @@          cs <- getCallStacks          if cs then pure (ELocated r e') else pure e' -    P.ENeg        {} -> mono-    P.EComplement {} -> mono     P.EGenerate   {} -> mono      P.ETuple    {} -> mono@@ -178,6 +201,7 @@     P.ETypeVal  {} -> mono     P.EFun      {} -> mono     P.ESplit    {} -> mono+    P.EPrefix   {} -> mono      P.EParens e       -> appTys e ts tGoal     P.EInfix a op _ b -> appTys (P.EVar (thing op) `P.EApp` a `P.EApp` b) ts tGoal@@ -221,14 +245,6 @@          checkHasType t tGoal          return e' -    P.ENeg e ->-      do prim <- mkPrim "negate"-         checkE (P.EApp prim e) tGoal--    P.EComplement e ->-      do prim <- mkPrim "complement"-         checkE (P.EApp prim e) tGoal-     P.EGenerate e ->       do prim <- mkPrim "generate"          checkE (P.EApp prim e) tGoal@@ -454,6 +470,12 @@      P.EInfix a op _ b -> checkE (P.EVar (thing op) `P.EApp` a `P.EApp` b) tGoal +    P.EPrefix op e ->+      do prim <- mkPrim case op of+           P.PrefixNeg        -> "negate"+           P.PrefixComplement -> "complement"+         checkE (P.EApp prim e) tGoal+     P.EParens e -> checkE e tGoal  @@ -464,7 +486,7 @@      -- { _ | fs } ~~>  \r -> { r | fs }     Nothing ->-      do r <- newParamName NSValue (packIdent "r")+      do r <- newLocalName NSValue (packIdent "r")          let p  = P.PVar Located { srcRange = nameLoc r, thing = r }              fe = P.EFun P.emptyFunDesc [p] (P.EUpd (Just (P.EVar r)) fs)          checkE fe tGoal@@ -490,7 +512,7 @@                 v1 <- checkE v (WithSource (tFun ft ft) src eloc)                 -- XXX: ^ may be used a different src?                 d  <- newHasGoal s (twsType tGoal) ft-                tmp <- newParamName NSValue (packIdent "rf")+                tmp <- newLocalName NSValue (packIdent "rf")                 let e' = EVar tmp                 pure ( hasDoSet d e' (EApp v1 (hasDoSelect d e'))                        `EWhere`@@ -734,15 +756,18 @@      newGoals CtComprehension [ pFin n' ]      return (m1 : ms', Map.insertWith (\_ old -> old) x t ds, tMul n n') --- | @inferBinds isTopLevel isRec binds@ performs inference for a--- strongly-connected component of 'P.Bind's.--- If any of the members of the recursive group are already marked--- as monomorphic, then we don't do generalization.--- If @isTopLevel@ is true,--- any bindings without type signatures will be generalized. If it is--- false, and the mono-binds flag is enabled, no bindings without type--- signatures will be generalized, but bindings with signatures will--- be unaffected.+{- | @inferBinds isTopLevel isRec binds@ performs inference for a+strongly-connected component of 'P.Bind's.+If any of the members of the recursive group are already marked+as monomorphic, then we don't do generalization.+If @isTopLevel@ is true,+any bindings without type signatures will be generalized. If it is+false, and the mono-binds flag is enabled, no bindings without type+signatures will be generalized, but bindings with signatures will+be unaffected.++-}+ inferBinds :: Bool -> Bool -> [P.Bind Name] -> InferM [Decl] inferBinds isTopLevel isRec binds =   do -- when mono-binds is enabled, and we're not checking top-level@@ -790,6 +815,8 @@                      genCs     <- generalize bs1 cs                      return (done,genCs) +     checkNumericConstraintGuardsOK isTopLevel sigs noSigs+      rec        let exprMap = Map.fromList (map monoUse genBs)        (doneBs, genBs) <- check exprMap@@ -817,9 +844,40 @@     withQs   = foldl' appP withTys  qs  +{-+Here we also check that:+  * Numeric constraint guards appear only at the top level+  * All definitions in a recursive groups with numberic constraint guards+    have signatures +The reason is to avoid interference between local constraints coming+from the guards and type inference.  It might be possible to+relex these requirements, but this requires some more careful thought on+the interaction between the two, and the effects on pricniple types.+-}+checkNumericConstraintGuardsOK ::+  Bool -> [P.Bind Name] -> [P.Bind Name] -> InferM ()+checkNumericConstraintGuardsOK isTopLevel haveSig noSig =+  do unless isTopLevel+            (mapM_ (mkErr NestedConstraintGuard) withGuards)+     unless (null withGuards)+            (mapM_ (mkErr DeclarationRequiresSignatureCtrGrd) noSig)+  where+  mkErr f b =+    do let nm = P.bName b+       inRange (srcRange nm) (recordError (f (nameIdent (thing nm)))) +  withGuards = filter hasConstraintGuards haveSig+  -- When desugaring constraint guards we check that they have signatures,+  -- so no need to look at noSig +  hasConstraintGuards b =+    case thing (P.bDef b) of+      P.DPropGuards {} -> True+      _                -> False+++ {- | Come up with a type for recursive calls to a function, and decide      how we are going to be checking the binding.      Returns: (Name, type or schema, computation to check binding)@@ -836,7 +894,12 @@   case bSignature of      Just s ->-      do s1 <- checkSchema AllowWildCards s+      do let wildOk = case thing bDef of+                        P.DForeign {}    -> NoWildCards+                        P.DPrim          -> NoWildCards+                        P.DExpr {}       -> AllowWildCards+                        P.DPropGuards {} -> NoWildCards+         s1 <- checkSchema wildOk s          return ((name, ExtVar (fst s1)), Left (checkSigB b s1))      Nothing@@ -930,8 +993,9 @@           genE e = foldr ETAbs (foldr EProofAbs (apSubst su e) qs) asPs          genB d = d { dDefinition = case dDefinition d of-                                      DExpr e -> DExpr (genE e)-                                      DPrim   -> DPrim+                                      DExpr e    -> DExpr (genE e)+                                      DPrim      -> DPrim+                                      DForeign t -> DForeign t                     , dSignature  = Forall asPs qs                                   $ apSubst su $ sType $ dSignature d                     }@@ -953,6 +1017,8 @@      P.DPrim -> panic "checkMonoB" ["Primitive with no signature?"] +    P.DForeign -> panic "checkMonoB" ["Foreign with no signature?"]+     P.DExpr e ->       do let nm = thing (P.bName b)          let tGoal = WithSource t (DefinitionOf nm) (getLoc b)@@ -967,70 +1033,253 @@                      , dDoc = P.bDoc b                      } +    P.DPropGuards _ ->+      tcPanic "checkMonoB"+        [ "Used constraint guards without a signature at "+        , show . pp $ P.bName b ]+ -- XXX: Do we really need to do the defaulting business in two different places? checkSigB :: P.Bind Name -> (Schema,[Goal]) -> InferM Decl-checkSigB b (Forall as asmps0 t0, validSchema) = case thing (P.bDef b) of+checkSigB b (Forall as asmps0 t0, validSchema) =+  let name = thing (P.bName b) in+  case thing (P.bDef b) of - -- XXX what should we do with validSchema in this case?- P.DPrim ->-   do return Decl { dName       = thing (P.bName b)-                  , dSignature  = Forall as asmps0 t0-                  , dDefinition = DPrim-                  , dPragmas    = P.bPragmas b-                  , dInfix      = P.bInfix b-                  , dFixity     = P.bFixity b-                  , dDoc        = P.bDoc b-                  }+    -- XXX what should we do with validSchema in this case?+    P.DPrim ->+      return Decl+        { dName       = name+        , dSignature  = Forall as asmps0 t0+        , dDefinition = DPrim+        , dPragmas    = P.bPragmas b+        , dInfix      = P.bInfix b+        , dFixity     = P.bFixity b+        , dDoc        = P.bDoc b+        } - P.DExpr e0 ->-  inRangeMb (getLoc b) $-  withTParams as $-  do (e1,cs0) <- collectGoals $-                do let nm = thing (P.bName b)-                       tGoal = WithSource t0 (DefinitionOf nm) (getLoc b)-                   e1 <- checkFun (P.FunDesc (Just nm) 0) (P.bParams b) e0 tGoal-                   addGoals validSchema-                   () <- simplifyAllConstraints  -- XXX: using `asmps` also?-                   return e1+    P.DForeign -> do+      let loc = getLoc b+          name' = thing $ P.bName b+          src = DefinitionOf name'+      inRangeMb loc do+        -- Ensure all type params are of kind #+        forM_ as \a ->+          when (tpKind a /= KNum) $+            recordErrorLoc loc $ UnsupportedFFIKind src a $ tpKind a+        withTParams as do+          ffiFunType <-+            case toFFIFunType (Forall as asmps0 t0) of+              Right (props, ffiFunType) -> ffiFunType <$ do+                ffiGoals <- traverse (newGoal (CtFFI name')) props+                proveImplication True (Just name') as asmps0 $+                  validSchema ++ ffiGoals+              Left err -> do+                recordErrorLoc loc $ UnsupportedFFIType src err+                -- Just a placeholder type+                pure FFIFunType+                  { ffiTParams = as, ffiArgTypes = []+                  , ffiRetType = FFITuple [] }+          pure Decl { dName       = thing (P.bName b)+                    , dSignature  = Forall as asmps0 t0+                    , dDefinition = DForeign ffiFunType+                    , dPragmas    = P.bPragmas b+                    , dInfix      = P.bInfix b+                    , dFixity     = P.bFixity b+                    , dDoc        = P.bDoc b+                    } -     asmps1 <- applySubstPreds asmps0-     cs     <- applySubstGoals cs0+    P.DExpr e0 ->+      inRangeMb (getLoc b) $+      withTParams as $ do+        (t, asmps, e2) <- checkBindDefExpr [] asmps0 e0 -     let findKeep vs keep todo =-          let stays (_,cvs)    = not $ Set.null $ Set.intersection vs cvs-              (yes,perhaps)    = partition stays todo-              (stayPs,newVars) = unzip yes-          in case stayPs of-               [] -> (keep,map fst todo)-               _  -> findKeep (Set.unions (vs:newVars)) (stayPs ++ keep) perhaps+        return Decl+          { dName       = name+          , dSignature  = Forall as asmps t+          , dDefinition = DExpr (foldr ETAbs (foldr EProofAbs e2 asmps) as)+          , dPragmas    = P.bPragmas b+          , dInfix      = P.bInfix b+          , dFixity     = P.bFixity b+          , dDoc        = P.bDoc b+          } -     let -- if a goal mentions any of these variables, we'll commit to-         -- solving it now.-         stickyVars = Set.fromList (map tpVar as) `Set.union` fvs asmps1-         (stay,leave) = findKeep stickyVars []-                            [ (c, fvs c) | c <- cs ]+    P.DPropGuards cases0 ->+      inRangeMb (getLoc b) $+        withTParams as $ do+          asmps1 <- applySubstPreds asmps0+          t1     <- applySubst t0+          cases1 <- mapM checkPropGuardCase cases0 -     addGoals leave+          exh <- checkExhaustive (P.bName b) as asmps1 (map fst cases1)+          unless exh $+              -- didn't prove exhaustive i.e. none of the guarding props+              -- necessarily hold+              recordWarning (NonExhaustivePropGuards name) +          let schema = Forall as asmps1 t1 -     su <- proveImplication (Just (thing (P.bName b))) as asmps1 stay-     extendSubst su+          return Decl+            { dName       = name+            , dSignature  = schema+            , dDefinition = DExpr+                              (foldr ETAbs+                                (foldr EProofAbs+                                  (EPropGuards cases1 t1)+                                asmps1)+                              as)+            , dPragmas    = P.bPragmas b+            , dInfix      = P.bInfix b+            , dFixity     = P.bFixity b+            , dDoc        = P.bDoc b+            } -     let asmps  = concatMap pSplitAnd (apSubst su asmps1)-     t      <- applySubst t0-     e2     <- applySubst e1 -     return Decl-        { dName       = thing (P.bName b)-        , dSignature  = Forall as asmps t-        , dDefinition = DExpr (foldr ETAbs (foldr EProofAbs e2 asmps) as)-        , dPragmas    = P.bPragmas b-        , dInfix      = P.bInfix b-        , dFixity     = P.bFixity b-        , dDoc        = P.bDoc b-        }+  where +    checkBindDefExpr ::+      [Prop] -> [Prop] -> P.Expr Name -> InferM (Type, [Prop], Expr)+    checkBindDefExpr asmpsSign asmps1 e0 = do +      (e1,cs0) <- collectGoals $ do+        let nm = thing (P.bName b)+            tGoal = WithSource t0 (DefinitionOf nm) (getLoc b)+        e1 <- checkFun (P.FunDesc (Just nm) 0) (P.bParams b) e0 tGoal+        addGoals validSchema+        () <- simplifyAllConstraints  -- XXX: using `asmps` also?+        return e1+      asmps2 <- applySubstPreds asmps1+      cs     <- applySubstGoals cs0++      let findKeep vs keep todo =+            let stays (_,cvs)    = not $ Set.null $ Set.intersection vs cvs+                (yes,perhaps)    = partition stays todo+                (stayPs,newVars) = unzip yes+            in case stayPs of+                [] -> (keep,map fst todo)+                _  -> findKeep (Set.unions (vs:newVars)) (stayPs ++ keep) perhaps++      let -- if a goal mentions any of these variables, we'll commit to+          -- solving it now.+          stickyVars = Set.fromList (map tpVar as) `Set.union` fvs asmps2+          (stay,leave) = findKeep stickyVars []+                              [ (c, fvs c) | c <- cs ]++      addGoals leave++      -- includes asmpsSign for the sake of implication, but doesn't actually+      -- include them in the resulting asmps+      su <- proveImplication True (Just (thing (P.bName b))) as (asmpsSign <> asmps2) stay+      extendSubst su++      let asmps  = concatMap pSplitAnd (apSubst su asmps2)+      t      <- applySubst t0+      e2     <- applySubst e1++      pure (t, asmps, e2)++++{- |+Given a DPropGuards of the form++@+f : {...} A+f | (B1, B2) => ... +  | (C1, C2, C2) => ... +@++we check that it is exhaustive by trying to prove the following+implications:++@+  A /\ ~B1 => C1 /\ C2 /\ C3+  A /\ ~B2 => C1 /\ C2 /\ C3+@++The implications were derive by the following general algorithm:+- Find that @(C1, C2, C3)@ is the guard that has the most conjuncts, so we+  will keep it on the RHS of the generated implications in order to minimize+  the number of implications we need to check.+- Negate @(B1, B2)@ which yields @(~B1) \/ (~B2)@. This is a disjunction, so+  we need to consider a branch for each disjunct --- one branch gets the+  assumption @~B1@ and another branch gets the assumption @~B2@. Each+  branch's implications need to be proven independently.++-}+checkExhaustive :: Located Name -> [TParam] -> [Prop] -> [[Prop]] -> InferM Bool+checkExhaustive name as asmps guards =+  case sortBy cmpByLonger guards of+    [] -> pure False -- XXX: we should check the asmps are unsatisfiable+    longest : rest -> doGoals (theAlts rest) (map toGoal longest)++  where+  cmpByLonger props1 props2 = compare (length props2) (length props1)+                                          -- reversed, so that longets is first++  theAlts :: [[Prop]] -> [[Prop]]+  theAlts = map concat . sequence . map chooseNeg++  -- Choose one of the things to negate+  chooseNeg ps =+    case ps of+      []     -> []+      p : qs -> (pNegNumeric p ++ qs) : [ p : alts | alts <- chooseNeg qs ]++++  -- Try to validate all cases+  doGoals todo gs =+    case todo of+      []     -> pure True+      alt : more ->+        do ok <- canProve (asmps ++ alt) gs+           if ok then doGoals more gs+                 else pure False++  toGoal :: Prop -> Goal+  toGoal prop =+    Goal+      { goalSource = CtPropGuardsExhaustive (thing name)+      , goalRange  = srcRange name+      , goal       = prop+      }++  canProve :: [Prop] -> [Goal] -> InferM Bool+  canProve asmps' goals =+    tryProveImplication (Just (thing name)) as asmps' goals++{- | This function does not validate anything---it just translates into+the type-checkd syntax.  The actual validation of the guard will happen+when the (automatically generated) function corresponding to the guard is+checked, assuming 'ExpandpropGuards' did its job correctly.++-}+checkPropGuardCase :: P.PropGuardCase Name -> InferM ([Prop],Expr)+checkPropGuardCase (P.PropGuardCase guards e0) =+  do ps <- checkPropGuards guards+     tys <- mapM (`checkType` Nothing) ts+     let rhsTs = foldl ETApp                  (getV eV) tys+         rhsPs = foldl (\e _p -> EProofApp e) rhsTs     ps+         rhs   = foldl EApp                   rhsPs     (map getV es)+     pure (ps,rhs)++  where+  (e1,es) = P.asEApps e0+  (eV,ts) = case e1 of+              P.EAppT ex1 tis -> (ex1, map getT tis)+              _               -> (e1, [])++  getV ex =+    case ex of+      P.EVar x -> EVar x+      _        -> bad "Expression is not a variable."++  getT ti =+    case ti of+      P.PosInst t    -> t+      P.NamedInst {} -> bad "Unexpeceted NamedInst"++  bad msg = panic "checkPropGuardCase" [msg]+ -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- @@ -1059,29 +1308,115 @@         do t <- checkPrimType (P.tlValue tl) (thing <$> P.tlDoc tl)            addPrimType t -      P.DParameterType ty ->-        do t <- checkParameterType ty (P.ptDoc ty)-           addParamType t -      P.DParameterConstraint cs ->-        do cs1 <- checkParameterConstraints cs+      P.DInterfaceConstraint _ cs ->+        inRange (srcRange cs)+        do cs1 <- checkParameterConstraints [ cs { thing = c } | c <- thing cs ]            addParameterConstraints cs1 -      P.DParameterFun pf ->-        do x <- checkParameterFun pf-           addParamFun x-       P.DModule tl ->-         do let P.NestedModule m = P.tlValue tl-            newSubmoduleScope (thing (P.mName m)) (map thing (P.mImports m))-                                                  (P.modExports m)-            checkTopDecls (P.mDecls m)-            endSubmodule+         selectorScope+         case P.mDef m of -      P.DImport {} -> pure ()-      P.Include {} -> panic "checkTopDecl" [ "Unexpected `inlude`" ]+           P.NormalModule ds ->+             do newSubmoduleScope (thing (P.mName m))+                                  (thing <$> P.tlDoc tl)+                                  (P.exportedDecls ds)+                checkTopDecls ds+                proveModuleTopLevel+                endSubmodule +           P.FunctorInstance f as inst ->+             do let doc = thing <$> P.tlDoc tl+                _ <- doFunctorInst (P.ImpNested <$> P.mName m) f as inst doc+                pure () +           P.InterfaceModule sig ->+              do let doc = P.thing <$> P.tlDoc tl+                 inRange (srcRange (P.mName m))+                   do newSignatureScope (thing (P.mName m)) doc+                      checkSignature sig+                      endSignature+++        where P.NestedModule m = P.tlValue tl++      P.DModParam p ->+        inRange (srcRange (P.mpSignature p))+        do let binds = P.mpRenaming p+               suMap = Map.fromList [ (y,x) | (x,y) <- Map.toList binds ]+               actualName x = Map.findWithDefault x x suMap++           ips <- lookupSignature (thing (P.mpSignature p))+           let actualTys  = [ mapNames actualName mp+                            | mp <- Map.elems (mpnTypes ips) ]+               actualTS   = [ mapNames actualName ts+                            | ts <- Map.elems (mpnTySyn ips)+                            ]+               actualCtrs = [ mapNames actualName prop+                            | prop <- mpnConstraints ips ]+               actualVals = [ mapNames actualName vp+                            | vp <- Map.elems (mpnFuns ips) ]++               param =+                 ModParam+                   { mpName = P.mpName p+                   , mpIface = thing (P.mpSignature p)+                   , mpQual = P.mpAs p+                   , mpParameters =+                        ModParamNames+                          { mpnTypes = Map.fromList [ (mtpName tp, tp)+                                                    | tp <- actualTys ]+                          , mpnTySyn = Map.fromList [ (tsName ts, ts)+                                                    | ts <- actualTS ]+                          , mpnConstraints = actualCtrs+                          , mpnFuns = Map.fromList [ (mvpName vp, vp)+                                                   | vp <- actualVals ]+                          , mpnDoc = thing <$> P.mpDoc p+                          }+                   }++           mapM_ addParamType actualTys+           addParameterConstraints actualCtrs+           mapM_ addParamFun actualVals+           mapM_ addTySyn actualTS+           addModParam param++      P.DImport {}        -> pure ()+      P.Include {}        -> bad "Include"+      P.DParamDecl {}     -> bad "DParamDecl"+++  bad x = panic "checkTopDecl" [ x ]+++checkSignature :: P.Signature Name -> InferM ()+checkSignature sig =+  do forM_ (P.sigTypeParams sig) \pt ->+       addParamType =<< checkParameterType pt++     mapM_ checkSigDecl (P.sigDecls sig)++     addParameterConstraints =<<+        checkParameterConstraints (P.sigConstraints sig)++     forM_ (P.sigFunParams sig) \f ->+       addParamFun =<< checkParameterFun f++     proveModuleTopLevel++checkSigDecl :: P.SigDecl Name -> InferM ()+checkSigDecl decl =+  case decl of++    P.SigTySyn ts mbD ->+      addTySyn =<< checkTySyn ts mbD++    P.SigPropSyn ps mbD ->+      addTySyn =<< checkPropSyn ps mbD+++ checkDecl :: Bool -> P.Decl Name -> Maybe Text -> InferM () checkDecl isTopLevel d mbDoc =   case d of@@ -1116,8 +1451,8 @@ checkParameterFun :: P.ParameterFun Name -> InferM ModVParam checkParameterFun x =   do (s,gs) <- checkSchema NoWildCards (P.pfSchema x)-     su <- proveImplication (Just (thing (P.pfName x)))-                            (sVars s) (sProps s) gs+     su <- proveImplication False (Just (thing (P.pfName x)))+                                  (sVars s) (sProps s) gs      unless (isEmptySubst su) $        panic "checkParameterFun" ["Subst not empty??"]      let n = thing (P.pfName x)
src/Cryptol/TypeCheck/InferTypes.hs view
@@ -27,7 +27,7 @@ import           Cryptol.TypeCheck.Subst import           Cryptol.TypeCheck.TypePat import           Cryptol.TypeCheck.SimpType(tMax)-import           Cryptol.Utils.Ident (ModName, PrimIdent(..), preludeName)+import           Cryptol.Utils.Ident (PrimIdent(..), preludeName) import           Cryptol.Utils.Panic(panic) import           Cryptol.Utils.Misc(anyJust) @@ -182,7 +182,8 @@   compare x y = compare (goal x) (goal y)  data HasGoal = HasGoal-  { hasName :: !Int+  { hasName :: !Int -- ^ This is the "name" of the constraint,+                    -- used to find the solution for ellaboration.   , hasGoal :: Goal   } deriving Show @@ -219,7 +220,10 @@   | CtPartialTypeFun Name -- ^ Use of a partial type function.   | CtImprovement   | CtPattern TypeSource  -- ^ Constraints arising from type-checking patterns-  | CtModuleInstance ModName -- ^ Instantiating a parametrized module+  | CtModuleInstance Range -- ^ Instantiating a parametrized module+  | CtPropGuardsExhaustive Name -- ^ Checking that a use of prop guards is exhastive+  | CtFFI Name            -- ^ Constraints on a foreign declaration required+                          --   by the FFI (e.g. sequences must be finite)     deriving (Show, Generic, NFData)  selSrc :: Selector -> TypeSource@@ -247,6 +251,8 @@       CtImprovement    -> src       CtPattern _      -> src       CtModuleInstance _ -> src+      CtPropGuardsExhaustive _ -> src+      CtFFI _          -> src   instance FVS Goal where@@ -352,7 +358,9 @@       CtPartialTypeFun f -> "use of partial type function" <+> pp f       CtImprovement   -> "examination of collected goals"       CtPattern ad    -> "checking a pattern:" <+> pp ad-      CtModuleInstance n -> "module instantiation" <+> pp n+      CtModuleInstance r -> "module instantiation at" <+> pp r+      CtPropGuardsExhaustive n -> "exhaustion check for prop guards used in defining" <+> pp n+      CtFFI f         -> "declaration of foreign function" <+> pp f  ppUse :: Expr -> Doc ppUse expr =
src/Cryptol/TypeCheck/Interface.hs view
@@ -1,73 +1,83 @@+{-# LANGUAGE Safe #-}+ module Cryptol.TypeCheck.Interface where  import qualified Data.Map as Map+import Data.Set(Set)+import qualified Data.Set as Set -import Cryptol.Utils.Ident(Namespace(..)) import Cryptol.ModuleSystem.Interface+import Cryptol.ModuleSystem.Exports(allExported) import Cryptol.TypeCheck.AST  +-- | Information about a declaration to be stored an in interface. mkIfaceDecl :: Decl -> IfaceDecl mkIfaceDecl d = IfaceDecl   { ifDeclName    = dName d   , ifDeclSig     = dSignature d+  , ifDeclIsPrim  = case dDefinition d of+                      DPrim {} -> True+                      _        -> False   , ifDeclPragmas = dPragmas d   , ifDeclInfix   = dInfix d   , ifDeclFixity  = dFixity d   , ifDeclDoc     = dDoc d   } --- | Generate an Iface from a typechecked module.-genIface :: ModuleG mname -> IfaceG mname-genIface m = Iface-  { ifModName = mName m--  , ifPublic      = IfaceDecls-    { ifTySyns    = tsPub-    , ifNewtypes  = ntPub-    , ifAbstractTypes = atPub-    , ifDecls     = dPub-    , ifModules   = mPub-    }--  , ifPrivate = IfaceDecls-    { ifTySyns    = tsPriv-    , ifNewtypes  = ntPriv-    , ifAbstractTypes = atPriv-    , ifDecls     = dPriv-    , ifModules   = mPriv-    }--  , ifParams = IfaceParams-    { ifParamTypes = mParamTypes m-    , ifParamConstraints = mParamConstraints m-    , ifParamFuns  = mParamFuns m-    }+-- | Compute information about the names in a module.+genIfaceNames :: ModuleG name -> IfaceNames name+genIfaceNames m = IfaceNames+  { ifsName     = mName m+  , ifsNested   = mNested m+  , ifsDefines  = genModDefines m+  , ifsPublic   = allExported (mExports m)+  , ifsDoc      = mDoc m   }-  where -  (tsPub,tsPriv) =-      Map.partitionWithKey (\ qn _ -> qn `isExportedType` mExports m )-                          (mTySyns m)-  (ntPub,ntPriv) =-      Map.partitionWithKey (\ qn _ -> qn `isExportedType` mExports m )-                           (mNewtypes m)--  (atPub,atPriv) =-    Map.partitionWithKey (\qn _ -> qn `isExportedType` mExports m)-                         (mPrimTypes m)+-- | Things defines by a module+genModDefines :: ModuleG name -> Set Name+genModDefines m =+  Set.unions+    [ Map.keysSet  (mTySyns m)+    , Map.keysSet  (mNewtypes m)+    , Set.fromList (map ntConName (Map.elems (mNewtypes m)))+    , Map.keysSet  (mPrimTypes m)+    , Set.fromList (map dName (concatMap groupDecls (mDecls m)))+    , Map.keysSet  (mSubmodules m)+    , Map.keysSet  (mFunctors m)+    , Map.keysSet  (mSignatures m)+    ] `Set.difference` nestedInSet (mNested m)+  where+  nestedInSet = Set.unions . map inNested . Set.toList+  inNested x  = case Map.lookup x (mSubmodules m) of+                  Just y  -> ifsDefines y `Set.union` nestedInSet (ifsNested y)+                  Nothing -> Set.empty -- must be signature or a functor -  (dPub,dPriv) =-      Map.partitionWithKey (\ qn _ -> qn `isExportedBind` mExports m)-      $ Map.fromList [ (qn,mkIfaceDecl d) | dg <- mDecls m-                                          , d  <- groupDecls dg-                                          , let qn = dName d-                                          ]+genIface :: ModuleG name -> IfaceG name+genIface m = genIfaceWithNames (genIfaceNames m) m -  (mPub,mPriv) =-      Map.partitionWithKey (\ qn _ -> isExported NSModule qn (mExports m))-      $ mSubModules m+-- | Generate an Iface from a typechecked module.+genIfaceWithNames :: IfaceNames name -> ModuleG ignored -> IfaceG name+genIfaceWithNames names m =+  Iface+  { ifNames       = names +  , ifDefines = IfaceDecls+    { ifTySyns          = mTySyns m+    , ifNewtypes        = mNewtypes m+    , ifAbstractTypes   = mPrimTypes m+    , ifDecls           = Map.fromList [ (qn,mkIfaceDecl d)+                                       | dg <- mDecls m+                                       , d  <- groupDecls dg+                                       , let qn = dName d+                                       ]+    , ifModules         = mSubmodules m+    , ifSignatures      = mSignatures m+    , ifFunctors        = genIface <$> mFunctors m+    } +  , ifParams = mParams m+  }  
src/Cryptol/TypeCheck/Kind.hs view
@@ -7,7 +7,7 @@ -- Portability :  portable  {-# LANGUAGE RecursiveDo #-}-{-# LANGUAGE Safe #-}+{-# LANGUAGE BlockArguments #-} -- See Note [-Wincomplete-uni-patterns and irrefutable patterns] in Cryptol.TypeCheck.TypePat {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module Cryptol.TypeCheck.Kind@@ -19,6 +19,7 @@   , checkPropSyn   , checkParameterType   , checkParameterConstraints+  , checkPropGuards   ) where  import qualified Cryptol.Parser.AST as P@@ -38,9 +39,7 @@ import           Data.Maybe(fromMaybe) import           Data.Function(on) import           Data.Text (Text)-import           Control.Monad(unless,when)--+import           Control.Monad(unless,when,mplus)  -- | Check a type signature.  Returns validated schema, and any implicit -- constraints that we inferred.@@ -66,14 +65,38 @@           Nothing -> id           Just r  -> inRange r +{- | Validate parsed propositions that appear in the guard of a PropGuard.++  * Note that we don't validate the well-formedness constraints here---instead,+    they'd be validated when the signature for the auto generated+    function corresponding guard is checked.++  * We also check that there are no wild-cards in the constraints.+-}+checkPropGuards :: [Located (P.Prop Name)] -> InferM [Prop]+checkPropGuards props =+  do (newPs,_gs) <- collectGoals (mapM check props)+     pure newPs+  where+  check lp =+    inRange (srcRange lp)+    do let p = thing lp+       (_,ps) <- withTParams NoWildCards schemaParam [] (checkProp p)+       case tNoUser ps of+         TCon (PC x) _ | x `elem` [PEqual,PNeq,PGeq,PFin,PTrue] -> pure ()+         _ -> recordError (InvalidConstraintGuard ps)+       pure ps+++ -- | Check a module parameter declarations.  Nothing much to check, -- we just translate from one syntax to another.-checkParameterType :: P.ParameterType Name -> Maybe Text -> InferM ModTParam-checkParameterType a mbDoc =-  do let k = cvtK (P.ptKind a)+checkParameterType :: P.ParameterType Name -> InferM ModTParam+checkParameterType a =+  do let mbDoc = P.ptDoc a+         k = cvtK (P.ptKind a)          n = thing (P.ptName a)-     return ModTParam { mtpKind = k, mtpName = n, mtpDoc = mbDoc-                      , mtpNumber = P.ptNumber a }+     return ModTParam { mtpKind = k, mtpName = n, mtpDoc = mbDoc }   -- | Check a type-synonym declaration.@@ -111,7 +134,7 @@ -- | Check a newtype declaration. -- XXX: Do something with constraints. checkNewtype :: P.Newtype Name -> Maybe Text -> InferM Newtype-checkNewtype (P.Newtype x as fs) mbD =+checkNewtype (P.Newtype x as con fs) mbD =   do ((as1,fs1),gs) <- collectGoals $        inRange (srcRange x) $        do r <- withTParams NoWildCards newtypeParam as $@@ -123,6 +146,7 @@      return Newtype { ntName   = thing x                     , ntParams = as1                     , ntConstraints = map goal gs+                    , ntConName = con                     , ntFields = fs1                     , ntDoc = mbD                     }@@ -386,8 +410,16 @@      P.TUser x ts    -> checkTUser x ts k -    P.TParens t     -> doCheckType t k+    P.TParens t mb  ->+      do newK <- case (k, cvtK <$> mb) of+                   (Just a, Just b) ->+                      do unless (a == b)+                           (kRecordError (KindMismatch Nothing a b))+                         pure (Just b)+                   (a,b) -> pure (mplus a b) +         doCheckType t newK+     P.TInfix t x _ u-> doCheckType (P.TUser (thing x) [t, u]) k      P.TTyApp _fs    -> do kRecordError BareTypeApp@@ -398,7 +430,7 @@  -- | Validate a parsed proposition. checkProp :: P.Prop Name      -- ^ Proposition that need to be checked-          -> KindM Type       -- ^ Checked representation+          -> KindM Prop -- ^ Checked representation checkProp (P.CType t) = doCheckType t (Just KProp)  @@ -411,5 +443,3 @@   | k1 /= k2    = do kRecordError (KindMismatch Nothing k1 k2)                      kNewType TypeErrorPlaceHolder k1 checkKind t _ _ = return t--
+ src/Cryptol/TypeCheck/Module.hs view
@@ -0,0 +1,376 @@+{-# Language BlockArguments, ImplicitParams #-}+module Cryptol.TypeCheck.Module (doFunctorInst) where++import Data.List(partition)+import Data.Text(Text)+import Data.Map(Map)+import qualified Data.Map as Map+import Data.Set (Set)+import qualified Data.Set as Set+import Control.Monad(unless,forM_)+++import Cryptol.Utils.Panic(panic)+import Cryptol.Utils.Ident(Ident,Namespace(..),isInfixIdent)+import Cryptol.Parser.Position (Range,Located(..), thing)+import qualified Cryptol.Parser.AST as P+import Cryptol.ModuleSystem.Name(nameIdent)+import Cryptol.ModuleSystem.Interface+          ( IfaceG(..), IfaceDecls(..), IfaceNames(..), IfaceDecl(..)+          , filterIfaceDecls+          )+import Cryptol.TypeCheck.AST+import Cryptol.TypeCheck.Error+import Cryptol.TypeCheck.Subst(Subst,listParamSubst,apSubst,mergeDistinctSubst)+import Cryptol.TypeCheck.Solve(proveImplication)+import Cryptol.TypeCheck.Monad+import Cryptol.TypeCheck.Instantiate(instantiateWith)+import Cryptol.TypeCheck.ModuleInstance+import Cryptol.TypeCheck.ModuleBacktickInstance(MBQual, doBacktickInstance)++doFunctorInst ::+  Located (P.ImpName Name)    {- ^ Name for the new module -} ->+  Located (P.ImpName Name)    {- ^ Functor being instantiated -} ->+  P.ModuleInstanceArgs Name   {- ^ Instance arguments -} ->+  Map Name Name+  {- ^ Instantitation.  These is the renaming for the functor that arises from+       generativity (i.e., it is something that will make the names "fresh").+  -} ->+  Maybe Text                  {- ^ Documentation -} ->+  InferM (Maybe TCTopEntity)+doFunctorInst m f as inst doc =+  inRange (srcRange m)+  do mf    <- lookupFunctor (thing f)+     argIs <- checkArity (srcRange f) mf as+     m2 <- do as2 <- mapM checkArg argIs+              let (tySus,decls) = unzip [ (su,ds) | DefinedInst su ds <- as2 ]+              let ?tSu = mergeDistinctSubst tySus+                  ?vSu = inst+              let m1   = moduleInstance mf+                  m2   = m1 { mName             = m+                            , mDoc              = Nothing+                            , mParamTypes       = mempty+                            , mParamFuns        = mempty+                            , mParamConstraints = mempty+                            , mParams           = mempty+                            , mDecls = map NonRecursive (concat decls) +++                                      mDecls m1+                            }+              let (tps,tcs,vps) =+                      unzip3 [ (xs,cs,fs) | ParamInst xs cs fs <- as2 ]+                  tpSet  = Set.unions tps+                  tpSet' = Set.map snd (Set.unions tps)+                  emit p = Set.null (freeParams (thing p)+                                                `Set.intersection` tpSet')++                  (emitPs,delayPs) = partition emit (mParamConstraints m1)++              forM_ emitPs \lp ->+                newGoals (CtModuleInstance (srcRange lp)) [thing lp]++              doBacktickInstance tpSet+                                 (map thing delayPs ++ concat tcs)+                                 (Map.unions vps)+                                 m2++     case thing m of+       P.ImpTop mn    -> newModuleScope mn (mExports m2)+       P.ImpNested mn -> newSubmoduleScope mn doc (mExports m2)++     mapM_ addTySyn     (Map.elems (mTySyns m2))+     mapM_ addNewtype   (Map.elems (mNewtypes m2))+     mapM_ addPrimType  (Map.elems (mPrimTypes m2))+     addSignatures      (mSignatures m2)+     addSubmodules      (mSubmodules m2)+     addFunctors        (mFunctors m2)+     mapM_ addDecls     (mDecls m2)++     case thing m of+       P.ImpTop {}    -> Just <$> endModule+       P.ImpNested {} -> endSubmodule >> pure Nothing+++data ActualArg =+    UseParameter ModParam     -- ^ Instantiate using this parameter+  | UseModule (IfaceG ())     -- ^ Instantiate using this module+  | AddDeclParams             -- ^ Instantiate by adding parameters+++++{- | Validate a functor application, just checking the argument names.+The result associates a module parameter with the concrete way it should+be instantiated, which could be:++  * `Left` instanciate using another parameter that is in scope+  * `Right` instanciate using a module, with the given interface+-}+checkArity ::+  Range             {- ^ Location for reporting errors -} ->+  ModuleG ()        {- ^ The functor being instantiated -} ->+  P.ModuleInstanceArgs Name {- ^ The arguments -} ->+  InferM [(Range, ModParam, ActualArg)]+  {- ^ Associates functor parameters with the interfaces of the+       instantiating modules -}+checkArity r mf args =+  case args of++    P.DefaultInstArg arg ->+      let i = Located { srcRange = srcRange arg+                      , thing    = head (Map.keys ps0)+                      }+      in checkArgs [] ps0 [ P.ModuleInstanceNamedArg i arg ]++    P.NamedInstArgs as -> checkArgs [] ps0 as++    P.DefaultInstAnonArg {} -> panic "checkArity" [ "DefaultInstAnonArg" ]+  where+  ps0 = mParams mf++  checkArgs done ps as =+    case as of++      [] -> do forM_ (Map.keys ps) \p ->+                 recordErrorLoc (Just r) (FunctorInstanceMissingArgument p)+               pure done++      P.ModuleInstanceNamedArg ll lm : more ->+        case Map.lookup (thing ll) ps of+          Just i ->+            do arg <- case thing lm of+                        P.ModuleArg m -> Just . UseModule <$> lookupModule m+                        P.ParameterArg p ->+                           do mb <- lookupModParam p+                              case mb of+                                Nothing ->+                                   do inRange (srcRange lm)+                                              (recordError (MissingModParam p))+                                      pure Nothing+                                Just a -> pure (Just (UseParameter a))+                        P.AddParams -> pure (Just AddDeclParams)+               let next = case arg of+                            Nothing -> done+                            Just a  -> (srcRange lm, i, a) : done+               checkArgs next (Map.delete (thing ll) ps) more++          Nothing ->+            do recordErrorLoc (Just (srcRange ll))+                              (FunctorInstanceBadArgument (thing ll))+               checkArgs done ps more+++data ArgInst = DefinedInst Subst [Decl] -- ^ Argument that defines the params+             | ParamInst (Set (MBQual TParam)) [Prop] (Map (MBQual Name) Type)+               -- ^ Argument that add parameters+               -- The type parameters are in their module type parameter+               -- form (i.e., tpFlav is TPModParam)++++{- | Check the argument to a functor parameter.+Returns:++  * A substitution which will replace the parameter types with+    the concrete types that were provided++  * Some declarations that define the parameters in terms of the provided+    values.++  * XXX: Extra parameters for instantiation by adding params+-}+checkArg ::+  (Range, ModParam, ActualArg) -> InferM ArgInst+checkArg (r,expect,actual') =+  case actual' of+    AddDeclParams   -> paramInst+    UseParameter {} -> definedInst+    UseModule {}    -> definedInst++  where+  paramInst =+    do let as = Set.fromList+                   (map (qual . mtpParam) (Map.elems (mpnTypes params)))+           cs = map thing (mpnConstraints params)+           check = checkSimpleParameterValue r (mpName expect)+           qual a = (mpQual expect, a)+       fs <- Map.mapMaybeWithKey (\_ v -> v) <$> mapM check (mpnFuns params)+       pure (ParamInst as cs (Map.mapKeys qual fs))++  definedInst =+    do tRens <- mapM (checkParamType r tyMap) (Map.toList (mpnTypes params))+       let renSu = listParamSubst (concat tRens)++       {- Note: the constraints from the signature are already added to the+          constraints for the functor and they are checked all at once in+          doFunctorInst -}+++       vDecls <- concat <$>+                  mapM (checkParamValue r vMap)+                       [ s { mvpType = apSubst renSu (mvpType s) }+                       | s <- Map.elems (mpnFuns params) ]++       pure (DefinedInst renSu vDecls)+++  params = mpParameters expect++  -- Things provided by the argument module+  tyMap :: Map Ident (Kind, Type)+  vMap  :: Map Ident (Name, Schema)+  (tyMap,vMap) =+    case actual' of+      UseParameter mp ->+        ( nameMapToIdentMap fromTP (mpnTypes ps)+        , nameMapToIdentMap fromVP (mpnFuns ps)+        )+        where+        ps        = mpParameters mp+        fromTP tp = (mtpKind tp, TVar (TVBound (mtpParam tp)))+        fromVP vp = (mvpName vp, mvpType vp)++      UseModule actual ->+        ( Map.unions [ nameMapToIdentMap fromTS      (ifTySyns decls)+                     , nameMapToIdentMap fromNewtype (ifNewtypes decls)+                     , nameMapToIdentMap fromPrimT   (ifAbstractTypes decls)+                     ]++        , nameMapToIdentMap fromD (ifDecls decls)+        )++        where+        localNames      = ifsPublic (ifNames actual)+        isLocal x       = x `Set.member` localNames++        -- Things defined by the argument module+        decls           = filterIfaceDecls isLocal (ifDefines actual)++        fromD d         = (ifDeclName d, ifDeclSig d)+        fromTS ts       = (kindOf ts, tsDef ts)+        fromNewtype nt  = (kindOf nt, TNewtype nt [])+        fromPrimT pt    = (kindOf pt, TCon (abstractTypeTC pt) [])++      AddDeclParams -> panic "checkArg" ["AddDeclParams"]++++nameMapToIdentMap :: (a -> b) -> Map Name a -> Map Ident b+nameMapToIdentMap f m =+  Map.fromList [ (nameIdent n, f v) | (n,v) <- Map.toList m ]+++++-- | Check a type parameter to a module.+checkParamType ::+  Range                 {- ^ Location for error reporting -} ->+  Map Ident (Kind,Type) {- ^ Actual types -} ->+  (Name,ModTParam)      {- ^ Type parameter -} ->+  InferM [(TParam,Type)]  {- ^ Mapping from parameter name to actual type -}+checkParamType r tyMap (name,mp) =+  let i       = nameIdent name+      expectK = mtpKind mp+  in+  case Map.lookup i tyMap of+    Nothing ->+      do recordErrorLoc (Just r) (FunctorInstanceMissingName NSType i)+         pure []+    Just (actualK,actualT) ->+      do unless (expectK == actualK)+           (recordErrorLoc (Just r)+                           (KindMismatch (Just (TVFromModParam name))+                                                  expectK actualK))+         pure [(mtpParam mp, actualT)]++-- | Check a value parameter to a module.+checkParamValue ::+  Range                   {- ^ Location for error reporting -} ->+  Map Ident (Name,Schema) {- ^ Actual values -} ->+  ModVParam               {- ^ The parameter we are checking -} ->+  InferM [Decl]           {- ^ Mapping from parameter name to definition -}+checkParamValue r vMap mp =+  let name     = mvpName mp+      i        = nameIdent name+      expectT  = mvpType mp+  in case Map.lookup i vMap of+       Nothing ->+         do recordErrorLoc (Just r) (FunctorInstanceMissingName NSValue i)+            pure []+       Just actual ->+         do e <- mkParamDef r (name,expectT) actual+            let d = Decl { dName        = name+                         , dSignature   = expectT+                         , dDefinition  = DExpr e+                         , dPragmas     = []+                         , dInfix       = isInfixIdent (nameIdent name)+                         , dFixity      = mvpFixity mp+                         , dDoc         = mvpDoc mp+                         }++            pure [d]++++checkSimpleParameterValue ::+  Range                       {- ^ Location for error reporting -} ->+  Ident                       {- ^ Name of functor parameter -} ->+  ModVParam                   {- ^ Module parameter -} ->+  InferM (Maybe Type)  {- ^ Type to add to things, `Nothing` on err -}+checkSimpleParameterValue r i mp =+  case (sVars sch, sProps sch) of+    ([],[]) -> pure (Just (sType sch))+    _ ->+      do recordErrorLoc (Just r)+            (FunctorInstanceBadBacktick+               (BIPolymorphicArgument i (nameIdent (mvpName mp))))+         pure Nothing+  where+  sch = mvpType mp+++{- | Make an "adaptor" that instantiates the paramter into the form expected+by the functor.  If the actual type is:++> {x} P => t++and the provided type is:++> f : {y} Q => s++The result, if successful would be:++  /\x \{P}. f @a {Q}++To do this we need to find types `a` to instantiate `y`, and prove that:+  {x} P => Q[a/y] /\ s = t+-}++mkParamDef ::+  Range           {- ^ Location of instantiation for error reporting -} ->+  (Name,Schema)   {- ^ Name and type of parameter -} ->+  (Name,Schema)   {- ^ Name and type of actual argument -} ->+  InferM Expr+mkParamDef r (pname,wantedS) (arg,actualS) =+  do (e,todo) <- collectGoals+          $ withTParams (sVars wantedS)+            do (e,t) <- instantiateWith pname(EVar arg) actualS []+               props <- unify WithSource { twsType   = sType wantedS+                                         , twsSource = TVFromModParam arg+                                         , twsRange  = Just r+                                         }+                        t+               newGoals (CtModuleInstance r) props+               pure e+     su <- proveImplication False+                            (Just pname)+                            (sVars wantedS)+                            (sProps wantedS)+                            todo+     let res  = foldr ETAbs     res1            (sVars wantedS)+         res1 = foldr EProofAbs (apSubst su e)  (sProps wantedS)++     applySubst res++++
+ src/Cryptol/TypeCheck/ModuleBacktickInstance.hs view
@@ -0,0 +1,408 @@+{-# Language ImplicitParams #-}+{-# Language FlexibleInstances #-}+{-# Language RecursiveDo #-}+{-# Language BlockArguments #-}+{-# Language RankNTypes #-}+{-# Language OverloadedStrings #-}+module Cryptol.TypeCheck.ModuleBacktickInstance+  ( MBQual+  , doBacktickInstance+  ) where++import Data.Set(Set)+import qualified Data.Set as Set+import Data.Map(Map)+import qualified Data.Map as Map+import MonadLib+import Data.List(group,sort)+import Data.Maybe(mapMaybe)+import qualified Data.Text as Text++import Cryptol.Utils.Ident(ModPath(..), modPathIsOrContains,Namespace(..)+                          , Ident, mkIdent, identText+                          , ModName, modNameChunksText )+import Cryptol.Utils.PP(pp)+import Cryptol.Utils.Panic(panic)+import Cryptol.Utils.RecordMap(RecordMap,recordFromFields,recordFromFieldsErr)+import Cryptol.Parser.Position+import Cryptol.ModuleSystem.Name(+  nameModPath, nameModPathMaybe, nameIdent, mapNameIdent)+import Cryptol.TypeCheck.AST+import Cryptol.TypeCheck.Error+import qualified Cryptol.TypeCheck.Monad as TC+++type MBQual a = (Maybe ModName, a)++{- | Rewrite declarations to add the given module parameters.+Assumes the renaming due to the instantiation has already happened.+The module being rewritten should not contain any nested functors+(or module with only top-level constraints) because it is not clear+how to parameterize the parameters.+-}+doBacktickInstance ::+  Set (MBQual TParam) ->+  [Prop] ->+  Map (MBQual Name) Type ->+  ModuleG (Located (ImpName Name)) ->+  TC.InferM (ModuleG (Located (ImpName Name)))+doBacktickInstance as ps mp m+  | null as && null ps && Map.null mp = pure m+  | otherwise =+    runReaderT+      RO { isOurs = \x -> case nameModPathMaybe x of+                            Nothing -> False+                            Just y  -> ourPath `modPathIsOrContains` y+         , tparams = Set.toList as+         , constraints = ps+         , vparams = mp+         , newNewtypes = Map.empty+         }++    do unless (null bad)+              (recordError (FunctorInstanceBadBacktick (BINested bad)))++       rec+         ts <- doAddParams nt mTySyns+         nt <- doAddParams nt mNewtypes+         ds <- doAddParams nt mDecls++       pure m+         { mTySyns   = ts+         , mNewtypes = nt+         , mDecls    = ds+         }++    where+    bad = mkBad mFunctors BIFunctor+       ++ mkBad mPrimTypes BIAbstractType+       ++ mkBad mSignatures BIInterface++    mkBad sel a = [ (a,k) | k <- Map.keys (sel m) ]++    ourPath = case thing (mName m) of+                ImpTop mo    -> TopModule mo+                ImpNested mo -> Nested (nameModPath mo) (nameIdent mo)++    doAddParams nt sel =+      mapReader (\ro -> ro { newNewtypes = nt }) (addParams (sel m))+++type RewM = ReaderT RO TC.InferM++recordError :: Error -> RewM ()+recordError e = lift (TC.recordError e)++data RO = RO+  { isOurs       :: Name -> Bool+  , tparams      :: [MBQual TParam]+  , constraints  :: [Prop]+  , vparams      :: Map (MBQual Name) Type+  , newNewtypes  :: Map Name Newtype+  }+++class AddParams t where+  addParams :: t -> RewM t++instance AddParams a => AddParams (Map Name a) where+  addParams = mapM addParams++instance AddParams a => AddParams [a] where+  addParams = mapM addParams++instance AddParams Newtype where+  addParams nt =+    do (tps,cs) <- newTypeParams TPNewtypeParam+       rProps   <- rewTypeM tps (ntConstraints nt)+       rFields  <- rewTypeM tps (ntFields nt)+       pure nt+         { ntParams       = pDecl tps ++ ntParams nt+         , ntConstraints  = cs ++ rProps+         , ntFields       = rFields+         }++instance AddParams TySyn where+  addParams ts =+    do (tps,cs) <- newTypeParams TPTySynParam+       rProps   <- rewTypeM tps (tsConstraints ts)+       rDef     <- rewTypeM tps (tsDef ts)+       pure ts+         { tsParams      = pDecl tps ++ tsParams ts+         , tsConstraints = cs ++ rProps+         , tsDef         = rDef+         }++instance AddParams DeclGroup where+  addParams dg =+    case dg of+      Recursive ds   -> Recursive <$> addParams ds+      NonRecursive d -> NonRecursive <$> addParams d++instance AddParams Decl where+  addParams d =+    case dDefinition d of+      DPrim       -> bad BIPrimitive+      DForeign {} -> bad BIForeign+      DExpr e ->+        do (tps,cs) <- newTypeParams TPSchemaParam+           (vps,bs) <- newValParams tps+           let s = dSignature d++           ty1 <- rewTypeM tps (sType s)+           ps1 <- rewTypeM tps (sProps s)+           let ty2 = foldr tFun ty1 (map snd bs)++           e1 <- rewValM tps (length cs) vps e+           let (das,e2) = splitWhile splitTAbs     e1+               (dcs,e3) = splitWhile splitProofAbs e2+               e4 = foldr (uncurry EAbs) e3 bs+               e5 = foldr EProofAbs e4 (cs ++ dcs)+               e6 = foldr ETAbs     e5 (pDecl tps ++ das)++               s1 = Forall+                      { sVars  = pDecl tps ++ sVars s+                      , sProps = cs ++ ps1+                      , sType  = ty2+                      }++           pure d { dDefinition = DExpr e6+                  , dSignature  = s1+                  }+    where+    bad w =+      do recordError (FunctorInstanceBadBacktick (BINested [(w,dName d)]))+         pure d++data Params decl use = Params+  { pDecl   :: [decl]+  , pUse    :: [use]+  , pSubst  :: Map decl use+  }++noParams :: Params decl use+noParams = Params+  { pDecl   = []+  , pUse    = []+  , pSubst  = Map.empty+  }++qualLabel :: Maybe ModName -> Ident -> Ident+qualLabel mb i =+  case mb of+    Nothing -> i+    Just mn ->+      let txt = Text.intercalate "'" (modNameChunksText mn ++ [identText i])+      in mkIdent txt+++type TypeParams = Params TParam Type+type ValParams  = Params Name   Expr++newTypeParams :: (Name -> TPFlavor) -> RewM (TypeParams,[Prop])+newTypeParams flav =+  do ro <- ask+     let newFlaf q = flav . mapNameIdent (qualLabel q)+     as <- lift (forM (tparams ro) \(q,a) -> TC.freshTParam (newFlaf q) a)+     let bad = [ x+               | x : _ : _ <- group (sort (map nameIdent (mapMaybe tpName as)))+               ]+     forM_ bad \i ->+       recordError (FunctorInstanceBadBacktick (BIMultipleParams i))++     let ts = map (TVar . TVBound) as+         su = Map.fromList (zip (map snd (tparams ro)) ts)+         ps = Params { pDecl = as, pUse = ts, pSubst = su }+     cs <- rewTypeM ps (constraints ro)+     pure (ps,cs)++-- Note: we pass all value parameters as a record+newValParams :: TypeParams -> RewM (ValParams, [(Name,Type)])+newValParams tps =+  do ro <- ask+     let vps = vparams ro+     if Map.null vps+       then pure (noParams, [])+       else do xts <- forM (Map.toList vps) \((q,x),t) ->+                        do t1 <- rewTypeM tps t+                           let l = qualLabel q (nameIdent x)+                           pure (x, l, t1)+               let (xs,ls,ts) = unzip3 xts+                   fs      = zip ls ts+                   sel l   = RecordSel l (Just ls)++               t <- case recordFromFieldsErr fs of+                      Right ok -> pure (TRec ok)+                      Left (x,_) ->+                        do recordError (FunctorInstanceBadBacktick+                                          (BIMultipleParams x))+                           pure (TRec (recordFromFields fs))++               r <- lift (TC.newLocalName NSValue (mkIdent "params"))+               let e = EVar r+               pure+                 ( Params+                     { pDecl  = [r]+                     , pUse   = [e]+                     , pSubst = Map.fromList [ (x,ESel e (sel l))+                                             | (x,l) <- zip xs ls ]+                     }+                 , [ (r,t) ]+                 )++liftRew ::+  ((?isOurs :: Name -> Bool, ?newNewtypes :: Map Name Newtype) => a) ->+  RewM a+liftRew x =+  do ro <- ask+     let ?isOurs      = isOurs ro+         ?newNewtypes = newNewtypes ro+     pure x++rewTypeM :: RewType t => TypeParams -> t -> RewM t+rewTypeM ps x =+  do let ?tparams = ps+     liftRew rewType <*> pure x++rewValM :: RewVal t => TypeParams -> Int -> ValParams -> t -> RewM t+rewValM ts cs vs x =+  do let ?tparams = ts+         ?cparams = cs+         ?vparams = vs+     liftRew rew <*> pure x++class RewType t where+  rewType ::+    ( ?isOurs      :: Name -> Bool+    , ?newNewtypes :: Map Name Newtype    -- Lazy+    , ?tparams     :: TypeParams+    ) => t -> t++instance RewType Type where+  rewType ty =+    case ty of++      TCon tc ts+        | TC (TCAbstract (UserTC x _)) <- tc+        , ?isOurs x  -> TCon tc (pUse ?tparams ++ rewType ts)+        | otherwise  -> TCon tc (rewType ts)++      TVar x ->+        case x of+          TVBound x' ->+            case Map.lookup x' (pSubst ?tparams) of+              Just t  -> t+              Nothing -> ty+          TVFree {} -> panic "rawType" ["Free unification variable"]++      TUser f ts t+        | ?isOurs f -> TUser f (pUse ?tparams ++ rewType ts) (rewType t)+        | otherwise -> TUser f (rewType ts) (rewType t)++      TRec fs -> TRec (rewType fs)++      TNewtype tdef ts+        | ?isOurs nm -> TNewtype tdef' (pUse ?tparams ++ rewType ts)+        | otherwise  -> TNewtype tdef (rewType ts)+        where+        nm    = ntName tdef+        tdef' = case Map.lookup nm ?newNewtypes of+                  Just yes -> yes+                  Nothing  -> panic "rewType" [ "Missing recursive newtype"+                                              , show (pp nm) ]++instance RewType a => RewType [a] where+  rewType = fmap rewType++instance RewType b => RewType (RecordMap a b) where+  rewType = fmap rewType++instance RewType Schema where+  rewType sch =+    Forall { sVars  = sVars sch+           , sProps = rewType (sProps sch)+           , sType  = rewType (sType sch)+           }+++class RewVal t where+  rew ::+    ( ?isOurs      :: Name -> Bool+    , ?newNewtypes :: Map Name Newtype    -- Lazy+    , ?tparams     :: TypeParams+    , ?cparams     :: Int                 -- Number of constraitns+    , ?vparams     :: ValParams+    ) => t -> t++instance RewVal a => RewVal [a] where+  rew = fmap rew++instance RewVal b => RewVal (RecordMap a b) where+  rew = fmap rew++{- x as cs vs  -->+   e (newAs ++ as) (newCS ++ cs) (newVS ++ vs)+-}+instance RewVal Expr where+  rew expr =+    case expr of+      EList es t        -> EList (rew es) (rewType t)+      ETuple es         -> ETuple (rew es)+      ERec fs           -> ERec (rew fs)+      ESel e l          -> ESel (rew e) l+      ESet t e1 s e2    -> ESet (rewType t) (rew e1) s (rew e2)+      EIf e1 e2 e3      -> EIf (rew e1) (rew e2) (rew e3)+      EComp t1 t2 e mss -> EComp (rewType t1) (rewType t2) (rew e) (rew mss)+      EVar x            -> tryVarApp+                           case Map.lookup x (pSubst ?vparams) of+                             Just p  -> p+                             Nothing -> expr++      ETApp e t         -> tryVarApp (ETApp (rew e) (rewType t))+      EProofApp e       -> tryVarApp (EProofApp (rew e))++      EApp e1 e2        -> EApp (rew e1) (rew e2)+      ETAbs a e         -> ETAbs a (rew e)+      EAbs x t e        -> EAbs x (rewType t) (rew e)+      ELocated r e      -> ELocated r (rew e)+      EProofAbs p e     -> EProofAbs (rewType p) (rew e)+      EWhere e ds       -> EWhere (rew e) (rew ds)+      EPropGuards gs t  -> EPropGuards gs' (rewType t)+        where gs' = [ (rewType <$> p, rew e) | (p,e) <- gs ]++    where+    tryVarApp orElse =+      case splitExprInst expr of+        (EVar x, ts, cs) | ?isOurs x ->+           let ets = foldl ETApp (EVar x) (pUse ?tparams ++ rewType ts)+               eps = iterate EProofApp ets !! (?cparams + cs)+               evs = foldl EApp eps (pUse ?vparams)+           in evs+        _ -> orElse+++instance RewVal DeclGroup where+  rew dg =+    case dg of+      Recursive ds    -> Recursive (rew ds)+      NonRecursive d  -> NonRecursive (rew d)++instance RewVal Decl where+  rew d = d { dDefinition = rew (dDefinition d)+            , dSignature  = rewType (dSignature d)+            }++instance RewVal DeclDef where+  rew def =+    case def of+      DPrim       -> def+      DForeign {} -> def+      DExpr e     -> DExpr (rew e)++instance RewVal Match where+  rew ma =+    case ma of+      From x t1 t2 e -> From x (rewType t1) (rewType t2) (rew e)+      Let d          -> Let (rew d)++
+ src/Cryptol/TypeCheck/ModuleInstance.hs view
@@ -0,0 +1,168 @@+{-# Language ImplicitParams, ConstraintKinds #-}+module Cryptol.TypeCheck.ModuleInstance where++import Data.Map(Map)+import qualified Data.Map as Map+import Data.Set(Set)+import qualified Data.Set as Set++import Cryptol.Parser.Position(Located)+import Cryptol.ModuleSystem.Interface(IfaceNames(..))+import Cryptol.IR.TraverseNames(TraverseNames,mapNames)+import Cryptol.TypeCheck.AST+import Cryptol.TypeCheck.Subst(Subst,TVars,apSubst)+++{- | `?tSu` should be applied to all types.+     `?vSu` shoudl be applied to all values. -}+type Su = (?tSu :: Subst, ?vSu :: Map Name Name)++-- | Has value names but no types.+doVInst :: (Su, TraverseNames a) => a -> a+doVInst = mapNames (\x -> Map.findWithDefault x x ?vSu)++-- | Has types but not values.+doTInst :: (Su, TVars a) => a -> a+doTInst = apSubst ?tSu++-- | Has both value names and types.+doTVInst :: (Su, TVars a, TraverseNames a) => a -> a+doTVInst = apSubst ?tSu . doVInst++doMap :: (Su, ModuleInstance a) => Map Name a -> Map Name a+doMap mp =+  Map.fromList [ (moduleInstance x, moduleInstance d) | (x,d) <- Map.toList mp ]++doSet :: Su => Set Name -> Set Name+doSet = Set.fromList . map moduleInstance . Set.toList+++++class ModuleInstance t where+  moduleInstance :: Su => t -> t++instance ModuleInstance a => ModuleInstance [a] where+  moduleInstance = map moduleInstance++instance ModuleInstance a => ModuleInstance (Located a) where+  moduleInstance l = moduleInstance <$> l++instance ModuleInstance Name where+  moduleInstance = doVInst++instance ModuleInstance name => ModuleInstance (ImpName name) where+  moduleInstance x =+    case x of+      ImpTop t -> ImpTop t+      ImpNested n -> ImpNested (moduleInstance n)++instance ModuleInstance (ModuleG name) where+  moduleInstance m =+    Module { mName             = mName m+           , mDoc              = Nothing+           , mExports          = doVInst (mExports m)+           , mParamTypes       = doMap (mParamTypes m)+           , mParamFuns        = doMap (mParamFuns m)+           , mParamConstraints = moduleInstance (mParamConstraints m)+           , mParams           = moduleInstance <$> mParams m+           , mFunctors         = doMap (mFunctors m)+           , mNested           = doSet (mNested m)+           , mTySyns           = doMap (mTySyns m)+           , mNewtypes         = doMap (mNewtypes m)+           , mPrimTypes        = doMap (mPrimTypes m)+           , mDecls            = moduleInstance (mDecls m)+           , mSubmodules       = doMap (mSubmodules m)+           , mSignatures       = doMap (mSignatures m)+           }++instance ModuleInstance Type where+  moduleInstance = doTInst++instance ModuleInstance Schema where+  moduleInstance = doTInst++instance ModuleInstance TySyn where+  moduleInstance ts =+    TySyn { tsName        = moduleInstance (tsName ts)+          , tsParams      = tsParams ts+          , tsConstraints = moduleInstance (tsConstraints ts)+          , tsDef         = moduleInstance (tsDef ts)+          , tsDoc         = tsDoc ts+          }++instance ModuleInstance Newtype where+  moduleInstance nt =+    Newtype { ntName        = moduleInstance (ntName nt)+            , ntParams      = ntParams nt+            , ntConstraints = moduleInstance (ntConstraints nt)+            , ntConName     = moduleInstance (ntConName nt)+            , ntFields      = moduleInstance <$> ntFields nt+            , ntDoc         = ntDoc nt+            }++instance ModuleInstance AbstractType where+  moduleInstance at =+    AbstractType { atName     = moduleInstance (atName at)+                 , atKind     = atKind at+                 , atCtrs     = let (ps,cs) = atCtrs at+                                in (ps, moduleInstance cs)+                 , atFixitiy  = atFixitiy at+                 , atDoc      = atDoc at+                 }++instance ModuleInstance DeclGroup where+  moduleInstance dg =+    case dg of+      Recursive ds    -> Recursive (moduleInstance ds)+      NonRecursive d -> NonRecursive (moduleInstance d)++instance ModuleInstance Decl where+  moduleInstance = doTVInst+++instance ModuleInstance name => ModuleInstance (IfaceNames name) where+  moduleInstance ns =+    IfaceNames { ifsName     = moduleInstance (ifsName ns)+               , ifsNested   = doSet (ifsNested ns)+               , ifsDefines  = doSet (ifsDefines ns)+               , ifsPublic   = doSet (ifsPublic ns)+               , ifsDoc      = ifsDoc ns+               }++instance ModuleInstance ModParamNames where+  moduleInstance si =+    ModParamNames { mpnTypes       = doMap (mpnTypes si)+                  , mpnConstraints = moduleInstance (mpnConstraints si)+                  , mpnFuns        = doMap (mpnFuns si)+                  , mpnTySyn       = doMap (mpnTySyn si)+                  , mpnDoc         = mpnDoc si+                  }++instance ModuleInstance ModTParam where+  moduleInstance mp =+    ModTParam { mtpName = moduleInstance (mtpName mp)+              , mtpKind = mtpKind mp+              , mtpDoc  = mtpDoc mp+              }++instance ModuleInstance ModVParam where+  moduleInstance mp =+    ModVParam { mvpName   = moduleInstance (mvpName mp)+              , mvpType   = moduleInstance (mvpType mp)+              , mvpDoc    = mvpDoc mp+              , mvpFixity = mvpFixity mp+              }++instance ModuleInstance ModParam where+  moduleInstance p =+    ModParam { mpName        = mpName p+             , mpIface       = moduleInstance (mpIface p)+             , mpParameters  = moduleInstance (mpParameters p)+             , mpQual        = mpQual p+             }+++++
src/Cryptol/TypeCheck/Monad.hs view
@@ -5,7 +5,6 @@ -- Maintainer  :  cryptol@galois.com -- Stability   :  provisional -- Portability :  portable-{-# LANGUAGE Safe #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-}@@ -22,6 +21,7 @@ import qualified Control.Applicative as A import qualified Control.Monad.Fail as Fail import           Control.Monad.Fix(MonadFix(..))+import           Data.Text(Text) import qualified Data.Map as Map import qualified Data.Set as Set import           Data.Map (Map)@@ -38,13 +38,14 @@ import           MonadLib hiding (mapM)  import           Cryptol.ModuleSystem.Name-                    (FreshM(..),Supply,mkParameter-                    , nameInfo, NameInfo(..),NameSource(..))+                    (FreshM(..),Supply,mkLocal,asLocal+                    , nameInfo, NameInfo(..),NameSource(..), nameTopModule)+import qualified Cryptol.ModuleSystem.Interface as If import           Cryptol.Parser.Position import qualified Cryptol.Parser.AST as P import           Cryptol.TypeCheck.AST import           Cryptol.TypeCheck.Subst-import           Cryptol.TypeCheck.Interface(genIface)+import           Cryptol.TypeCheck.Interface(genIfaceWithNames,genIfaceNames) import           Cryptol.TypeCheck.Unify(doMGU, runResult, UnificationError(..)                                         , Path, rootPath) import           Cryptol.TypeCheck.InferTypes@@ -54,8 +55,8 @@ import qualified Cryptol.TypeCheck.SimpleSolver as Simple import qualified Cryptol.TypeCheck.Solver.SMT as SMT import           Cryptol.TypeCheck.PP(NameMap)-import           Cryptol.Utils.PP(pp, (<+>), text,commaSep,brackets)-import           Cryptol.Utils.Ident(Ident,Namespace(..))+import           Cryptol.Utils.PP(pp, (<+>), text,commaSep,brackets,debugShowUniques)+import           Cryptol.Utils.Ident(Ident,Namespace(..),ModName) import           Cryptol.Utils.Panic(panic)  -- | Information needed for type inference.@@ -64,15 +65,16 @@   , inpVars      :: Map Name Schema   -- ^ Variables that are in scope   , inpTSyns     :: Map Name TySyn    -- ^ Type synonyms that are in scope   , inpNewtypes  :: Map Name Newtype  -- ^ Newtypes in scope-  , inpAbstractTypes :: Map Name AbstractType -- ^ Abstract types in scope+  , inpAbstractTypes :: Map Name AbstractType   -- ^ Abstract types in scope+  , inpSignatures :: !(Map Name ModParamNames)  -- ^ Signatures in scope +  , inpTopModules    :: ModName -> Maybe (ModuleG (), If.IfaceG ())+  , inpTopSignatures :: ModName -> Maybe ModParamNames+     -- When typechecking a module these start off empty.     -- We need them when type-checking an expression at the command     -- line, for example.-  , inpParamTypes       :: !(Map Name ModTParam)  -- ^ Type parameters-  , inpParamConstraints :: !([Located Prop])      -- ^ Constraints on parameters-  , inpParamFuns        :: !(Map Name ModVParam)  -- ^ Value parameters-+  , inpParams :: !ModParamNames    , inpNameSeeds :: NameSeeds         -- ^ Private state of type-checker   , inpMonoBinds :: Bool              -- ^ Should local bindings without@@ -120,24 +122,35 @@                  io $ modifyIORef' iSolveCounter (+1)  runInferM :: TVars a => InferInput -> InferM a -> IO (InferOutput a)-runInferM info (IM m) =-  do counter <- newIORef 0+runInferM info m0 =+  do let IM m = selectorScope m0+     counter <- newIORef 0+     let allPs = inpParams info+      let env = Map.map ExtVar (inpVars info)-            <> Map.map (ExtVar . newtypeConType) (inpNewtypes info)+            <> Map.fromList+              [ (ntConName nt, ExtVar (newtypeConType nt))+              | nt <- Map.elems (inpNewtypes info)+              ]+            <> Map.map (ExtVar . mvpType) (mpnFuns allPs) -     rec ro <- return RO { iRange     = inpRange info+     let ro =         RO { iRange     = inpRange info                          , iVars      = env+                         , iExtModules = inpTopModules info+                         , iExtSignatures = inpTopSignatures info                          , iExtScope = (emptyModule ExternalScope)-                             { mTySyns           = inpTSyns info+                             { mTySyns           = inpTSyns info <>+                                                   mpnTySyn allPs                              , mNewtypes         = inpNewtypes info                              , mPrimTypes        = inpAbstractTypes info-                             , mParamTypes       = inpParamTypes info-                             , mParamFuns        = inpParamFuns info-                             , mParamConstraints = inpParamConstraints info+                             , mParamTypes       = mpnTypes allPs+                             , mParamFuns        = mpnFuns  allPs+                             , mParamConstraints = mpnConstraints allPs+                             , mSignatures       = inpSignatures info                              }                           , iTVars         = []-                         , iSolvedHasLazy = iSolvedHas finalRW     -- RECURSION+                         , iSolvedHasLazy = Map.empty                          , iMonoBinds     = inpMonoBinds info                          , iCallStacks    = inpCallStacks info                          , iSolver        = inpSolver info@@ -145,29 +158,30 @@                          , iSolveCounter  = counter                          } -         (result, finalRW) <- runStateT rw-                            $ runReaderT ro m  -- RECURSION--     let theSu    = iSubst finalRW-         defSu    = defaultingSubst theSu-         warns    = fmap' (fmap' (apSubst theSu)) (iWarnings finalRW)+     mb <- runExceptionT (runStateT rw (runReaderT ro m))+     case mb of+       Left errs -> inferFailed [] errs+       Right (result, finalRW) ->+         do let theSu    = iSubst finalRW+                defSu    = defaultingSubst theSu+                warns    = fmap' (fmap' (apSubst theSu)) (iWarnings finalRW) -     case iErrors finalRW of-       [] ->-         case (iCts finalRW, iHasCts finalRW) of-           (cts,[])-             | nullGoals cts -> inferOk warns-                                  (iNameSeeds finalRW)-                                  (iSupply finalRW)-                                  (apSubst defSu result)-           (cts,has) ->-              inferFailed warns-                [ ( goalRange g-                  , UnsolvedGoals [apSubst theSu g]-                  ) | g <- fromGoals cts ++ map hasGoal has-                ]+            case iErrors finalRW of+              [] ->+                case iCts finalRW of+                  cts+                    | nullGoals cts -> inferOk warns+                                         (iNameSeeds finalRW)+                                         (iSupply finalRW)+                                         (apSubst defSu result)+                  cts ->+                     inferFailed warns+                       [ ( goalRange g+                         , UnsolvedGoals [apSubst theSu g]+                         ) | g <- fromGoals cts+                       ] -       errs -> inferFailed warns [(r,apSubst theSu e) | (r,e) <- errs]+              errs -> inferFailed warns [(r,apSubst theSu e) | (r,e) <- errs]    where   inferOk ws a b c  = pure (InferOK (computeFreeVarNames ws []) ws a b c)@@ -193,18 +207,70 @@           , iBindTypes  = mempty           } --+{- | 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.+-}+selectorScope :: InferM a -> InferM a+selectorScope (IM m1) = IM+  do ro <- ask+     rw <- get+     mb <- inBase+           do rec let ro1 = ro { iSolvedHasLazy = solved }+                      rw1 = rw { iHasCts = [] : iHasCts rw }+                  mb <- runExceptionT (runStateT rw1 (runReaderT ro1 m1))+                  let solved = case mb of+                                 Left {} -> Map.empty+                                 Right (_,rw2) -> iSolvedHas rw2+              pure mb+     case mb of+       Left err      -> raise err+       Right (a,rw1) ->+         case iHasCts rw1 of+           us : cs ->+             do let errs = [ (goalRange g, UnsolvedGoals [g])+                           | g <- map hasGoal us ]+                set rw1 { iErrors = errs ++ iErrors rw1, iHasCts = cs }+                unIM (abortIfErrors)+                pure a+           [] -> panic "selectorScope" ["No selector scope"]   -newtype InferM a = IM { unIM :: ReaderT RO (StateT RW IO) a }+newtype InferM a = IM { unIM :: ReaderT RO+                              ( StateT  RW+                              ( ExceptionT [(Range,Error)]+                                IO+                              )) a }   data ScopeName = ExternalScope                | LocalScope                | SubModule Name+               | SignatureScope Name (Maybe Text) -- ^ The Text is docs+               | TopSignatureScope P.ModName                | MTopModule P.ModName  -- | Read-only component of the monad.@@ -219,10 +285,20 @@    , iTVars    :: [TParam]    -- ^ Type variable that are in scope +  , iExtModules :: ModName -> Maybe (ModuleG (), If.IfaceG ())+    -- ^ An exteral top-level module.+    -- We need the actual module when we instantiate functors,+    -- because currently the type-checker desugars such modules.++  , iExtSignatures :: ModName -> Maybe ModParamNames+    -- ^ External top-level signatures.+   , iExtScope :: ModuleG ScopeName     -- ^ These are things we know about, but are not part of the     -- modules we are currently constructing.     -- XXX: this sould probably be an interface+    -- NOTE: External functors should be looked up in `iExtModules`+    -- and not here, as they may be top-level modules.    , iSolvedHasLazy :: Map Int HasGoalSln     -- ^ NOTE: This field is lazy in an important way!  It is the@@ -274,12 +350,18 @@    -- Constraints that need solving   , iCts      :: !Goals                -- ^ Ordinary constraints-  , iHasCts   :: ![HasGoal]-    {- ^ Tuple/record projection constraints.  The 'Int' is the "name"-         of the constraint, used so that we can name its solution properly. -}+  , iHasCts   :: ![[HasGoal]]+    {- ^ Tuple/record projection constraints.  These are separate from+       the other constraints because solving them results in actual elaboration+       of the term, indicating how to do the projection.  The modification+       of the term is done using lazyness, by looking up a thunk ahead of time+       (@iSolvedHasLazy@ in RO), which is filled in when the constrait is+       solved (@iSolvedHas@).  See also `selectorScope`.+    -}    , iScope :: ![ModuleG ScopeName]     -- ^ Nested scopes we are currently checking, most nested first.+    -- These are basically partially built modules.    , iBindTypes :: !(Map Name Schema)     -- ^ Types of variables that we know about.  We don't worry about scoping@@ -317,6 +399,7 @@ io :: IO a -> InferM a io m = IM $ inBase m + -- | The monadic computation is about the given range of source code. -- This is useful for error reporting. inRange :: Range -> InferM a -> InferM a@@ -345,7 +428,17 @@      IM $ sets_ $ \s -> s { iErrors = (r,e) : iErrors s }  -+-- | If there are any recoded errors than abort firther type-checking.+abortIfErrors :: InferM ()+abortIfErrors =+  do rw <- IM get+     case iErrors rw of+       [] -> pure ()+       es ->+         do es1 <- forM es \(l,e) ->+                      do e1 <- applySubst e+                         pure (l,e1)+            IM (raise es1)  recordWarning :: Warning -> InferM () recordWarning w =@@ -358,7 +451,7 @@   ignore     | DefaultingTo d _ <- w     , Just n <- tvSourceName (tvarDesc d)-    , Declared _ SystemName <- nameInfo n+    , GlobalName SystemName _ <- nameInfo n       = True     | otherwise = False @@ -443,22 +536,30 @@ newHasGoal l ty f =   do goalName <- newGoalName      g        <- newGoal CtSelector (pHas l ty f)-     IM $ sets_ $ \s -> s { iHasCts = HasGoal goalName g : iHasCts s }+     IM $ sets_ \s -> case iHasCts s of+                        cs : more ->+                          s { iHasCts = (HasGoal goalName g : cs) : more }+                        [] -> panic "newHasGoal" ["no selector scope"]      solns    <- IM $ fmap iSolvedHasLazy ask      return $ case Map.lookup goalName solns of                 Just e1 -> e1                 Nothing -> panic "newHasGoal" ["Unsolved has goal in result"]  --- | Add a previously generate has constrained+-- | Add a previously generated @Has@ constraint addHasGoal :: HasGoal -> InferM ()-addHasGoal g = IM $ sets_ $ \s -> s { iHasCts = g : iHasCts s }+addHasGoal g = IM $ sets_ \s -> case iHasCts s of+                                  cs : more -> s { iHasCts = (g : cs) : more }+                                  [] -> panic "addHasGoal" ["No selector scope"]  -- | Get the @Has@ constraints.  Each of this should either be solved, -- or added back using 'addHasGoal'. getHasGoals :: InferM [HasGoal]-getHasGoals = do gs <- IM $ sets $ \s -> (iHasCts s, s { iHasCts = [] })-                 applySubst gs+getHasGoals =+  do gs <- IM $ sets \s -> case iHasCts s of+                             cs : more -> (cs, s { iHasCts = [] : more })+                             [] -> panic "getHasGoals" ["No selector scope"]+     applySubst gs  -- | Specify the solution (@Expr -> Expr@) for the given constraint ('Int'). solveHasGoal :: Int -> HasGoalSln -> InferM ()@@ -469,10 +570,10 @@ --------------------------------------------------------------------------------  -- | Generate a fresh variable name to be used in a local binding.-newParamName :: Namespace -> Ident -> InferM Name-newParamName ns x =+newLocalName :: Namespace -> Ident -> InferM Name+newLocalName ns x =   do r <- curRange-     liftSupply (mkParameter ns x r)+     liftSupply (mkLocal ns x r)  newName :: (NameSeeds -> (a , NameSeeds)) -> InferM a newName upd = IM $ sets $ \s -> let (x,seeds) = upd (iNameSeeds s)@@ -506,7 +607,7 @@  checkParamKind tp flav k =     case flav of-      TPModParam _     -> return () -- All kinds allowed as module parameters+      TPModParam _     -> starOrHash       TPPropSynParam _ -> starOrHashOrProp       TPTySynParam _   -> starOrHash       TPSchemaParam _  -> starOrHash@@ -547,7 +648,20 @@      checkParamKind tp flav k      return tp +-- | Generate a new version of a type parameter.  We use this when+-- instantiating module parameters (the "backtick" imports)+freshTParam :: (Name -> TPFlavor) -> TParam -> InferM TParam+freshTParam mkF tp = newName \s ->+  let u = seedTVar s+  in ( tp { tpUnique = u+          , tpFlav   = case tpName tp of+                         Just n -> mkF (asLocal NSType n)+                         Nothing -> tpFlav tp -- shouldn't happen?+          }+     , s  { seedTVar = u + 1 }+     ) + -- | Generate an unknown type.  The doc is a note about what is this type about. newType :: TypeSource -> Kind -> InferM Type newType src k = TVar `fmap` newTVar src k@@ -635,7 +749,8 @@                   case v of                     ExtVar sch  -> getVars sch                     CurSCC _ t  -> getVars t-     sels <- IM $ fmap (map (goal . hasGoal) . iHasCts) get+     hasCts <- IM (iHasCts <$> get)+     let sels = map (goal . hasGoal) (concat hasCts)      fromSels <- mapM getVars sels      fromEx   <- (getVars . concatMap Map.elems) =<< IM (fmap iExistTVars get)      return (Set.unions fromEnv `Set.union` Set.unions fromSels@@ -656,8 +771,12 @@          do mb1 <- Map.lookup x . iBindTypes <$> IM get             case mb1 of               Just a -> pure (ExtVar a)-              Nothing -> panic "lookupVar" [ "Undefined vairable"-                                           , show x ]+              Nothing ->+                do mp <- IM $ asks iVars+                   panic "lookupVar" $ [ "Undefined vairable"+                                     , show x+                                     , "IVARS"+                                     ] ++ map (show . debugShowUniques . pp) (Map.keys mp)  -- | 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.@@ -680,10 +799,89 @@ lookupParamType :: Name -> InferM (Maybe ModTParam) lookupParamType x = Map.lookup x <$> getParamTypes --- | Lookup the schema for a parameter function.-lookupParamFun :: Name -> InferM (Maybe ModVParam)-lookupParamFun x = Map.lookup x <$> getParamFuns+lookupSignature :: P.ImpName Name -> InferM ModParamNames+lookupSignature nx =+  case nx of+    -- XXX: top+    P.ImpNested x ->+      do sigs <- getSignatures+         case Map.lookup x sigs of+           Just ips -> pure ips+           Nothing  -> panic "lookupSignature"+                        [ "Missing signature", show x ] +    P.ImpTop t ->+      do loaded <- iExtSignatures <$> IM ask+         case loaded t of+           Just ps -> pure ps+           Nothing -> panic "lookupSignature"+                        [ "Top level signature is not loaded", show (pp nx) ]++-- | Lookup an external (i.e., previously loaded) top module.+lookupTopModule :: ModName -> InferM (Maybe (ModuleG (), If.IfaceG ()))+lookupTopModule m =+  do ms <- iExtModules <$> IM ask+     pure (ms m)++lookupFunctor :: P.ImpName Name -> InferM (ModuleG ())+lookupFunctor iname =+  case iname of+    P.ImpTop m -> fst . fromMb <$> lookupTopModule m+    P.ImpNested m ->+      do localFuns <- getScope mFunctors+         case Map.lookup m localFuns of+           Just a -> pure a { mName = () }+           Nothing ->+             do mbTop <- lookupTopModule (nameTopModule m)+                pure (fromMb do a <- fst <$> mbTop+                                b <- Map.lookup m (mFunctors a)+                                pure b { mName = () })+  where+  fromMb mb = case mb of+                Just a -> a+                Nothing -> panic "lookupFunctor"+                                  [ "Missing functor", show iname ]+++{- | 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.+-}+lookupModule :: P.ImpName Name -> InferM (If.IfaceG ())+lookupModule iname =+  case iname of+    P.ImpTop m -> snd . fromMb <$> lookupTopModule m+    P.ImpNested m ->+      do localMods <- getScope mSubmodules+         case Map.lookup m localMods of+           Just names ->+              do n <- genIfaceWithNames names <$> getCurDecls+                 pure (If.ifaceForgetName n)++           Nothing ->+             do mb <- lookupTopModule (nameTopModule m)+                pure (fromMb+                         do iface <- snd <$> mb+                            names <- Map.lookup m+                                        (If.ifModules (If.ifDefines iface))+                            pure iface+                                   { If.ifNames = names { If.ifsName = () } })++  where+  fromMb mb = case mb of+                Just a -> a+                Nothing -> panic "lookupModule"+                                  [ "Missing module", show iname ]++++lookupModParam :: P.Ident -> InferM (Maybe ModParam)+lookupModParam p =+  do scope <- getScope mParams+     pure (Map.lookup p scope)++ -- | 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.@@ -717,10 +915,6 @@ getAbstractTypes :: InferM (Map Name AbstractType) getAbstractTypes = getScope mPrimTypes --- | Returns the parameter functions declarations-getParamFuns :: InferM (Map Name ModVParam)-getParamFuns = getScope mParamFuns- -- | Returns the abstract function declarations getParamTypes :: InferM (Map Name ModTParam) getParamTypes = getScope mParamTypes@@ -748,6 +942,11 @@ getCallStacks :: InferM Bool getCallStacks = IM (asks iCallStacks) +getSignatures :: InferM (Map Name ModParamNames)+getSignatures = getScope mSignatures+++ {- | 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@@ -795,15 +994,28 @@ newLocalScope :: InferM () newLocalScope = newScope LocalScope -newSubmoduleScope :: Name -> [Import] -> ExportSpec Name -> InferM ()-newSubmoduleScope x is e =-  do newScope (SubModule x)-     updScope \m -> m { mImports = is, mExports = e }+newSignatureScope :: Name -> Maybe Text -> InferM ()+newSignatureScope x doc =+  do updScope \o -> o { mNested = Set.insert x (mNested o) }+     newScope (SignatureScope x doc) -newModuleScope :: P.ModName -> [Import] -> ExportSpec Name -> InferM ()-newModuleScope x is e =+newTopSignatureScope :: ModName -> InferM ()+newTopSignatureScope x = newScope (TopSignatureScope x)++{- | 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. -}+newSubmoduleScope ::+  Name -> Maybe Text -> ExportSpec Name -> InferM ()+newSubmoduleScope x docs e =+  do updScope \o -> o { mNested = Set.insert x (mNested o) }+     newScope (SubModule x)+     updScope \m -> m { mDoc = docs, mExports = e }++newModuleScope :: P.ModName -> ExportSpec Name -> InferM ()+newModuleScope x e =   do newScope (MTopModule x)-     updScope \m -> m { mImports = is, mExports = e }+     updScope \m -> m { mDoc = Nothing, mExports = e }  -- | Update the current scope (first in the list). Assumes there is one. updScope :: (ModuleG ScopeName -> ModuleG ScopeName) -> InferM ()@@ -829,40 +1041,85 @@        case iScope rw of          x@Module { mName = SubModule m } : y : more -> rw { iScope = z : more }            where-           x1    = x { mName = m }-           iface = genIface x1-           me = if isParametrizedModule x1 then Map.singleton m x1 else mempty-           z = y { mImports     = mImports x ++ mImports y -- just for deps-                 , mSubModules  = Map.insert m iface (mSubModules y)+           x1    = x { mName = m, mDecls = reverse (mDecls x) } -                 , mTySyns      = mTySyns x <> mTySyns y-                 , mNewtypes    = mNewtypes x <> mNewtypes y-                 , mPrimTypes   = mPrimTypes x <> mPrimTypes y-                 , mDecls       = mDecls x <> mDecls y-                 , mFunctors    = me <> mFunctors x <> mFunctors y+           isFun = isParametrizedModule x1++           add :: Monoid a => (ModuleG ScopeName -> a) -> a+           add f = if isFun then f y else f x <> f y++           z = Module+                 { mName             = mName y+                 , mDoc              = mDoc y+                 , mExports          = mExports y+                 , mParamTypes       = mParamTypes y+                 , mParamFuns        = mParamFuns  y+                 , mParamConstraints = mParamConstraints y+                 , mParams           = mParams y+                 , mNested           = mNested y++                 , mTySyns      = add mTySyns+                 , mNewtypes    = add mNewtypes+                 , mPrimTypes   = add mPrimTypes+                 , mDecls       = add mDecls+                 , mSignatures  = add mSignatures+                 , mSubmodules  = if isFun+                                    then mSubmodules y+                                    else Map.insert m (genIfaceNames x1)+                                               (mSubmodules x <> mSubmodules y)+                 , mFunctors    = if isFun+                                    then Map.insert m x1 (mFunctors y)+                                    else mFunctors x <> mFunctors y                  }           _ -> panic "endSubmodule" [ "Not a submodule" ]  -endModule :: InferM Module+endModule :: InferM TCTopEntity endModule =   IM $ sets \rw ->     case iScope rw of       [ x ] | MTopModule m <- mName x ->-        ( x { mName = m, mDecls = reverse (mDecls x) }+        ( TCTopModule x { mName = m, mDecls = reverse (mDecls x) }         , rw { iScope = [] }         )       _ -> panic "endModule" [ "Not a single top module" ] -endModuleInstance :: InferM ()-endModuleInstance =+endSignature :: InferM ()+endSignature =   IM $ sets_ \rw ->     case iScope rw of-      [ x ] | MTopModule _ <- mName x -> rw { iScope = [] }-      _ -> panic "endModuleInstance" [ "Not single top module" ]+      x@Module { mName = SignatureScope m doc } : y : more ->+        rw { iScope = z : more }+        where+        z   = y { mSignatures = Map.insert m sig (mSignatures y) }+        sig = ModParamNames+                { mpnTypes       = mParamTypes x+                , mpnConstraints = mParamConstraints x+                , mpnFuns        = mParamFuns x+                , mpnTySyn       = mTySyns x+                , mpnDoc         = doc+                }+      _ -> panic "endSignature" [ "Not a signature scope" ] +endTopSignature :: InferM TCTopEntity+endTopSignature =+  IM $ sets \rw ->+    case iScope rw of+      [ x ] | TopSignatureScope m <- mName x ->+        ( TCTopSignature m ModParamNames+                             { mpnTypes       = mParamTypes x+                             , mpnConstraints = mParamConstraints x+                             , mpnFuns        = mParamFuns x+                             , mpnTySyn       = mTySyns x+                             , mpnDoc         = Nothing+                             }+        , rw { iScope = [] }+        )+      _ -> panic "endTopSignature" [ "Not a top-level signature" ] ++ -- | Get an environment combining all nested scopes. getScope :: Semigroup a => (ModuleG ScopeName -> a) -> InferM a getScope f =@@ -870,6 +1127,39 @@      rw <- IM get      pure (sconcat (f (iExtScope ro) :| map f (iScope rw))) +getCurDecls :: InferM (ModuleG ())+getCurDecls =+  do ro <- IM ask+     rw <- IM get+     pure (foldr (\m1 m2 -> mergeDecls (forget m1) m2)+                (forget (iExtScope ro)) (iScope rw))++  where+  forget m = m { mName = () }++  mergeDecls m1 m2 =+    Module+      { mName             = ()+      , mDoc              = Nothing+      , mExports          = mempty+      , mParams           = mempty+      , mParamTypes       = mempty+      , mParamConstraints = mempty+      , mParamFuns        = mempty+      , mNested           = mempty++      , mTySyns           = uni mTySyns+      , mNewtypes         = uni mNewtypes+      , mPrimTypes        = uni mPrimTypes+      , mDecls            = uni mDecls+      , mSubmodules       = uni mSubmodules+      , mFunctors         = uni mFunctors+      , mSignatures       = uni mSignatures+      }+    where+    uni f = f m1 <> f m2++ addDecls :: DeclGroup -> InferM () addDecls ds =   do updScope \r -> r { mDecls = ds : mDecls r }@@ -888,7 +1178,7 @@ addNewtype :: Newtype -> InferM () addNewtype t =   do updScope \r -> r { mNewtypes = Map.insert (ntName t) t (mNewtypes r) }-     IM $ sets_ \rw -> rw { iBindTypes = Map.insert (ntName t)+     IM $ sets_ \rw -> rw { iBindTypes = Map.insert (ntConName t)                                                     (newtypeConType t)                                                     (iBindTypes rw) } @@ -897,10 +1187,26 @@   updScope \r ->     r { mPrimTypes = Map.insert (atName t) t (mPrimTypes r) } + addParamType :: ModTParam -> InferM () addParamType a =   updScope \r -> r { mParamTypes = Map.insert (mtpName a) a (mParamTypes r) } +addSignatures :: Map Name ModParamNames -> InferM ()+addSignatures mp =+  updScope \r -> r { mSignatures = Map.union mp (mSignatures r) }++addSubmodules :: Map Name (If.IfaceNames Name) -> InferM ()+addSubmodules mp =+  updScope \r -> r { mSubmodules = Map.union mp (mSubmodules r) }++addFunctors :: Map Name (ModuleG Name) -> InferM ()+addFunctors mp =+  updScope \r -> r { mFunctors = Map.union mp (mFunctors r) }++++ -- | The sub-computation is performed with the given abstract function in scope. addParamFun :: ModVParam -> InferM () addParamFun x =@@ -912,6 +1218,10 @@ addParameterConstraints :: [Located Prop] -> InferM () addParameterConstraints ps =   updScope \r -> r { mParamConstraints = ps ++ mParamConstraints r }++addModParam :: ModParam -> InferM ()+addModParam p =+  updScope \r -> r { mParams = Map.insert (mpName p) p (mParams r) }   
src/Cryptol/TypeCheck/Parseable.hs view
@@ -63,6 +63,8 @@   --NOTE: erase all "proofs" for now (change the following two lines to change that)   showParseable (EProofAbs {-p-}_ e) = showParseable e --"(EProofAbs " ++ show p ++ showParseable e ++ ")"   showParseable (EProofApp e) = showParseable e --"(EProofApp " ++ showParseable e ++ ")"+  +  showParseable (EPropGuards guards _) = parens (text "EPropGuards" $$ showParseable guards)  instance (ShowParseable a, ShowParseable b) => ShowParseable (a,b) where   showParseable (x,y) = parens (showParseable x <> comma <> showParseable y)@@ -93,6 +95,7 @@  instance ShowParseable DeclDef where   showParseable DPrim = text (show DPrim)+  showParseable (DForeign t) = text (show $ DForeign t)   showParseable (DExpr e) = parens (text "DExpr" $$ showParseable e)  instance ShowParseable DeclGroup where
src/Cryptol/TypeCheck/Sanity.hs view
@@ -5,12 +5,15 @@ -- Maintainer  :  cryptol@galois.com -- Stability   :  provisional -- Portability :  portable+{-# Language OverloadedStrings #-} module Cryptol.TypeCheck.Sanity   ( tcExpr   , tcDecls   , tcModule   , ProofObligation+  , onlyNonTrivial   , Error(..)+  , AreSame(..)   , same   ) where @@ -19,8 +22,10 @@ import Cryptol.TypeCheck.AST import Cryptol.TypeCheck.Subst (apSubst, singleTParamSubst) import Cryptol.TypeCheck.Monad(InferInput(..))+import Cryptol.ModuleSystem.Name(nameLoc) import Cryptol.Utils.Ident import Cryptol.Utils.RecordMap+import Cryptol.Utils.PP  import Data.List (sort) import qualified Data.Set as Set@@ -48,7 +53,21 @@         k2    = withVars (Map.toList (fmap mvpType (mParamFuns m)))               $ checkDecls (mDecls m) +onlyNonTrivial :: [ProofObligation] -> [ProofObligation]+onlyNonTrivial = filter (not . trivialProofObligation) +-- | Identify proof obligations that are obviously true.+-- We can filter these to avoid clutter+trivialProofObligation :: ProofObligation -> Bool+trivialProofObligation oblig = pIsTrue goal || simpleEq || goal `elem` asmps+  where+  goal  = sType oblig+  asmps = sProps oblig+  simpleEq = case pIsEqual goal of+               Just (t1,t2) -> t1 == t2+               Nothing      -> False++ --------------------------------------------------------------------------------  checkDecls :: [DeclGroup] -> TcM ()@@ -107,23 +126,68 @@   where check = do mapM_ (checkTypeIs KProp) ps                    checkTypeIs KType t +data AreSame = SameIf [Prop]+             | NotSame +areSame :: AreSame+areSame = SameIf []++sameAnd :: AreSame -> AreSame -> AreSame+sameAnd x y =+  case (x,y) of+    (SameIf xs, SameIf ys) -> SameIf (xs ++ ys)+    _                      -> NotSame++sameBool :: Bool -> AreSame+sameBool b = if b then areSame else NotSame++sameTypes :: String -> Type -> Type -> TcM ()+sameTypes msg x y = sameSchemas msg (tMono x) (tMono y)++sameSchemas :: String -> Schema -> Schema -> TcM ()+sameSchemas msg x y =+  case same x y of+    NotSame   -> reportError (TypeMismatch msg x y)+    SameIf ps -> mapM_ proofObligation ps++++ class Same a where-  same :: a -> a -> Bool+  same :: a -> a -> AreSame  instance Same a => Same [a] where-  same [] [] = True-  same (x : xs) (y : ys) = same x y && same xs ys-  same _ _ = False+  same [] [] = areSame+  same (x : xs) (y : ys) = same x y `sameAnd` same xs ys+  same _ _ = NotSame +data Field a b = Field a b++instance (Eq a, Same b) => Same (Field a b) where+  same (Field x a) (Field y b) = sameBool (x == y) `sameAnd` same a b+ instance Same Type where-  same t1 t2 = tNoUser t1 == tNoUser t2+  same t1 t2+    | k1 /= k2    = NotSame+    | k1 == KNum  = if t1 == t2 then SameIf [] else SameIf [ t1 =#= t2 ]+    | otherwise   =+      case (tNoUser t1, tNoUser t2) of+        (TVar x, TVar y)               -> sameBool (x == y)+        (TRec x, TRec y)               -> same (mkRec x) (mkRec y)+        (TNewtype x xs, TNewtype y ys) -> same (Field x xs) (Field y ys)+        (TCon x xs, TCon y ys)         -> same (Field x xs) (Field y ys)+        _                              -> NotSame+      where+      k1 = kindOf t1+      k2 = kindOf t2+      mkRec r = [ Field x y | (x,y) <- canonicalFields r ]  instance Same Schema where-  same (Forall xs ps s) (Forall ys qs t) = same xs ys && same ps qs && same s t+  same (Forall xs ps s) (Forall ys qs t) =+    same xs ys `sameAnd` same ps qs `sameAnd` same s t  instance Same TParam where-  same x y = tpName x == tpName y && tpKind x == tpKind y+  same x y = sameBool (tpName x == tpName y && tpKind x == tpKind y)   @@ -153,8 +217,7 @@       do checkTypeIs KType t          forM_ es $ \e ->            do t1 <- exprType e-              unless (same t1 t) $-                reportError $ TypeMismatch "EList" (tMono t) (tMono t1)+              sameTypes "EList" t1 t           return $ tMono $ tSeq (tNum (length es)) t @@ -169,9 +232,7 @@        do ty  <- exprType e           expe <- checkHas ty x           has <- exprType v-          unless (same expe has) $-             reportError $-               TypeMismatch "ESet" (tMono expe) (tMono has)+          sameTypes "ESet" expe has           return (tMono ty)      ESel e sel -> do ty <- exprType e@@ -180,13 +241,11 @@      EIf e1 e2 e3 ->       do ty <- exprType e1-         unless (same tBit ty) $-           reportError $ TypeMismatch "EIf_condition" (tMono tBit) (tMono ty)+         sameTypes "EIf_condition" tBit ty           t1 <- exprType e2          t2 <- exprType e3-         unless (same t1 t2) $-           reportError $ TypeMismatch "EIf_arms" (tMono t1) (tMono t2)+         sameTypes "EIf_arms" t1 t2           return $ tMono t1 @@ -238,7 +297,9 @@           case tNoUser t1 of            TCon (TC TCFun) [ a, b ]-              | same a t2 -> return (tMono b)+              | SameIf ps <- same a t2 ->+                do mapM_ proofObligation ps+                   return (tMono b)            tf -> reportError (BadApplication tf t1)  @@ -270,6 +331,9 @@       in go dgs  +    EPropGuards _guards typ -> +      pure Forall {sVars = [], sProps = [], sType = typ}+ checkHas :: Type -> Selector -> TcM Type checkHas t sel =   case sel of@@ -398,12 +462,19 @@       do when checkSig $ checkSchema $ dSignature d          return (dName d, dSignature d) +    DForeign _ ->+      do when checkSig $ checkSchema $ dSignature d+         return (dName d, dSignature d)+     DExpr e ->       do let s = dSignature d          when checkSig $ checkSchema s          s1 <- exprSchema e-         unless (same s s1) $-           reportError $ TypeMismatch "DExpr" s s1+         let nm = dName d+             loc = "definition of " ++ show (pp nm) +++                            ", at " ++ show (pp (nameLoc nm))+         sameSchemas loc s s1+          return (dName d, s)  checkDeclGroup :: DeclGroup -> TcM [(Name, Schema)]@@ -427,7 +498,9 @@          t1 <- exprType e          case tNoUser t1 of            TCon (TC TCSeq) [ l, el ]-             | same elt el -> return ((x, tMono elt), l)+             | SameIf ps <- same elt el ->+               do mapM_ proofObligation ps+                  return ((x, tMono elt), l)              | otherwise -> reportError $ TypeMismatch "From" (tMono elt) (tMono el)  @@ -487,13 +560,15 @@     (Left err, _) -> Left err     (Right a, s)  -> Right (a, woProofObligations s)   where+  allPs = inpParams env+   ro = RO { roTVars = Map.fromList [ (tpUnique x, x)-                                      | tp <- Map.elems (inpParamTypes env)+                                      | tp <- Map.elems (mpnTypes allPs)                                       , let x = mtpParam tp ]-          , roAsmps = map thing (inpParamConstraints env)+          , roAsmps = map thing (mpnConstraints allPs)           , roRange = emptyRange           , roVars  = Map.union-                        (fmap mvpType (inpParamFuns env))+                        (fmap mvpType (mpnFuns allPs))                         (inpVars env)           }   rw = RW { woProofObligations = [] }@@ -579,3 +654,114 @@      case Map.lookup x (roVars ro) of        Just s -> return s        Nothing -> reportError $ UndefinedVariable x+++instance PP Error where+  ppPrec _ err =+    case err of++      TypeMismatch what expected actual ->+        ppErr ("Type mismatch in" <+> text what)+          [ "Expected:" <+> pp expected+          , "Actual  :" <+> pp actual+          ]++      ExpectedMono s ->+        ppErr "Not a monomorphic type"+          [ pp s ]++      TupleSelectorOutOfRange sel sz ->+        ppErr "Tuple selector out of range"+          [ "Selector:" <+> int sel+          , "Size    :" <+> int sz+          ]++      MissingField f fs ->+        ppErr "Invalid record selector"+          [ "Field: " <+> pp f+          , "Fields:" <+> commaSep (map pp fs)+          ]++      UnexpectedTupleShape expected actual ->+        ppErr "Unexpected tuple shape"+          [ "Expected:" <+> int expected+          , "Actual  :" <+> int actual+          ]++      UnexpectedRecordShape expected actual ->+        ppErr "Unexpected record shape"+          [ "Expected:" <+> commaSep (map pp expected)+          , "Actual  :" <+> commaSep (map pp actual)+          ]++      UnexpectedSequenceShape n t ->+        ppErr "Unexpected sequence shape"+          [ "Expected:" <+> int n+          , "Actual  :" <+> pp t+          ]++      BadSelector sel t ->+        ppErr "Bad selector"+          [ "Selector:" <+> pp sel+          , "Type    :" <+> pp t+          ]++      BadInstantiation ->+        ppErr "Bad instantiation" []++      Captured x ->+        ppErr "Captured type variable"+          [ "Variable:" <+> pp x ]++      BadProofNoAbs ->+        ppErr "Proof application without a proof abstraction" []++      BadProofTyVars xs ->+        ppErr "Proof application with type abstraction"+          [ "Type parameter:" <+> pp x | x <- xs ]++      KindMismatch expected actual ->+        ppErr "Kind mismatch"+          [ "Expected:" <+> pp expected+          , "Actual  :" <+> pp actual+          ]++      NotEnoughArgumentsInKind k ->+        ppErr "Not enough arguments in kind" [ pp k ]++      BadApplication t1 t2 ->+        ppErr "Bad application"+          [ "Function:" <+> pp t1+          , "Argument:" <+> pp t2+          ]++      FreeTypeVariable x ->+        ppErr "Free type variable"+          [ "Variable:" <+> pp x ]++      BadTypeApplication kf ka ->+        ppErr "Bad type application"+          [ "Function :" <+> pp kf+          , "Arguments:" <+> commaSep (map pp ka)+          ]++      RepeatedVariableInForall x ->+        ppErr "Repeated variable in forall"+          [ "Variable:" <+> pp x ]++      BadMatch t ->+        ppErr "Bad match"+          [ "Type:" <+> pp t ]++      EmptyArm -> ppErr "Empty comprehension arm" []++      UndefinedTypeVaraible x ->+        ppErr "Undefined type variable"+          [ "Variable:" <+> pp x ]++      UndefinedVariable x ->+        ppErr "Undefined variable"+          [ "Variable:" <+> pp x ]++    where+    ppErr x ys = hang x 2 (vcat [ "•" <+> y | y <- ys ])
src/Cryptol/TypeCheck/SimpType.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE PatternGuards #-}+{-# LANGUAGE Safe #-} -- See Note [-Wincomplete-uni-patterns and irrefutable patterns] in Cryptol.TypeCheck.TypePat {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module Cryptol.TypeCheck.SimpType where
src/Cryptol/TypeCheck/Solve.hs view
@@ -7,10 +7,10 @@ -- Portability :  portable  {-# LANGUAGE PatternGuards, BangPatterns, RecordWildCards #-}-{-# LANGUAGE Safe #-} module Cryptol.TypeCheck.Solve   ( simplifyAllConstraints   , proveImplication+  , tryProveImplication   , proveModuleTopLevel   , defaultAndSimplify   , defaultReplExpr@@ -37,6 +37,7 @@  import           Control.Applicative ((<|>)) import           Control.Monad(mzero)+import           Data.Containers.ListUtils (nubOrd) import           Data.Map (Map) import qualified Data.Map as Map import           Data.Set ( Set )@@ -265,28 +266,49 @@      cs <- getParamConstraints      case cs of        [] -> addGoals gs1-       _  -> do su2 <- proveImplication Nothing [] [] gs1+       _  -> do su2 <- proveImplication False Nothing [] [] gs1                 extendSubst su2  -- | Prove an implication, and return any improvements that we computed. -- Records errors, if any of the goals couldn't be solved.-proveImplication :: Maybe Name -> [TParam] -> [Prop] -> [Goal] -> InferM Subst-proveImplication lnam as ps gs =+proveImplication :: Bool -> Maybe Name ->+  [TParam] -> [Prop] -> [Goal] -> InferM Subst+proveImplication dedupErrs lnam as ps gs =   do evars <- varsWithAsmps      solver <- getSolver       extraAs <- (map mtpParam . Map.elems) <$> getParamTypes      extra   <- map thing <$> getParamConstraints -     (mbErr,su) <- io (proveImplicationIO solver lnam evars+     (mbErr,su) <- io (proveImplicationIO solver dedupErrs lnam evars                             (extraAs ++ as) (extra ++ ps) gs)      case mbErr of        Right ws  -> mapM_ recordWarning ws        Left errs -> mapM_ recordError errs      return su +-- | Tries to prove an implication. If proved, then returns `Right (m_su ::+-- InferM Subst)` where `m_su` is an `InferM` computation that results in the+-- solution substitution, and records any warning invoked during proving. If not+-- proved, then returns `Left (m_err :: InferM ())`, which records all errors+-- invoked during proving.+tryProveImplication :: +  Maybe Name -> [TParam] -> [Prop] -> [Goal] -> InferM Bool+tryProveImplication lnam as ps gs =+  do evars <- varsWithAsmps+     solver <- getSolver +     extraAs <- (map mtpParam . Map.elems) <$> getParamTypes+     extra   <- map thing <$> getParamConstraints++     (mbErr,_su) <- io (proveImplicationIO solver False lnam evars+                            (extraAs ++ as) (extra ++ ps) gs)+     case mbErr of+       Left {}  -> pure False+       Right {} -> pure True+ proveImplicationIO :: Solver+                   -> Bool     -- ^ Whether to remove duplicate goals in errors                    -> Maybe Name     -- ^ Checking this function                    -> Set TVar -- ^ These appear in the env., and we should                                -- not try to default them@@ -294,8 +316,8 @@                    -> [Prop]   -- ^ Assumed constraint                    -> [Goal]   -- ^ Collected constraints                    -> IO (Either [Error] [Warning], Subst)-proveImplicationIO _   _     _         _  [] [] = return (Right [], emptySubst)-proveImplicationIO s f varsInEnv ps asmps0 gs0 =+proveImplicationIO _ _         _ _         _  []     []  = return (Right [], emptySubst)+proveImplicationIO s dedupErrs f varsInEnv ps asmps0 gs0 =   do let ctxt = buildSolverCtxt asmps      res <- quickSolverIO ctxt gs      case res of@@ -315,7 +337,7 @@                                  return (Left (err gs3:errs), su) -- XXX: Old?                      (_,newGs,newSu,ws,errs) ->                        do let su1 = newSu @@ su-                          (res1,su2) <- proveImplicationIO s f varsInEnv ps+                          (res1,su2) <- proveImplicationIO s dedupErrs f varsInEnv ps                                                  (apSubst su1 asmps0) newGs                           let su3 = su2 @@ su1                           case res1 of@@ -329,7 +351,7 @@            $ DelayedCt { dctSource = f                        , dctForall = ps                        , dctAsmps  = asmps0-                       , dctGoals  = us+                       , dctGoals  = if dedupErrs then nubOrd us else us                        }  
src/Cryptol/TypeCheck/Solver/Class.hs view
@@ -7,6 +7,7 @@ -- Portability :  portable -- -- Solving class constraints.+-- If you make changes to this file, please update the documenation in RefMan.md  {-# LANGUAGE PatternGuards #-} module Cryptol.TypeCheck.Solver.Class
src/Cryptol/TypeCheck/Solver/Improve.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE Safe #-}+ -- | Look for opportunity to solve goals by instantiating variables. module Cryptol.TypeCheck.Solver.Improve where 
src/Cryptol/TypeCheck/Solver/Numeric/Interval.hs view
@@ -10,11 +10,13 @@  {-# LANGUAGE PatternGuards #-} {-# LANGUAGE BangPatterns #-}+{-# LANGUAGE Safe #-}  module Cryptol.TypeCheck.Solver.Numeric.Interval where  import Cryptol.TypeCheck.AST import Cryptol.TypeCheck.Solver.InfNat+import Cryptol.TypeCheck.PP(NameMap,ppWithNames) import Cryptol.Utils.PP hiding (int)  import           Data.Map ( Map )@@ -162,6 +164,14 @@ ppIntervals  = vcat . map ppr . Map.toList   where   ppr (var,i) = pp var <.> char ':' <+> ppInterval i++ppIntervalsWithNames :: NameMap -> Map TVar Interval -> Doc+ppIntervalsWithNames nms = vcat . map ppr . Map.toList+  where+  ppr :: (TVar,Interval) -> Doc+  ppr (var,i) = ppWithNames nms var <.> char ':' <+> ppInterval i++  ppInterval :: Interval -> Doc ppInterval x = brackets (hsep [ ppr (iLower x)
src/Cryptol/TypeCheck/Solver/SMT.hs view
@@ -10,7 +10,6 @@ {-# LANGUAGE FlexibleContexts #-} {-# Language FlexibleInstances #-} {-# LANGUAGE PatternGuards #-}-{-# LANGUAGE TypeSynonymInstances #-}  module Cryptol.TypeCheck.Solver.SMT   ( -- * Setup@@ -31,6 +30,9 @@   , checkUnsolvable   , tryGetModel   , shrinkModel++    -- * Lower level interactions+  , inNewFrame, TVars, declareVars, assume, unsolvable   ) where  import           SimpleSMT (SExpr)@@ -187,9 +189,6 @@ --------------------------------------------------------------------------------  --- -- | Returns goals that were not proved proveImp :: Solver -> [Prop] -> [Goal] -> IO [Goal] proveImp sol ps gs0 =@@ -288,13 +287,26 @@ pop :: Solver -> IO () pop sol = SMT.pop (solver sol) +inNewFrame :: Solver -> IO a -> IO a+inNewFrame sol m =+  do push sol+     a <- m+     pop sol+     pure a + declareVar :: Solver -> Int -> TVar -> IO (TVar, SExpr) declareVar s x v =   do let name = (if isFreeTV v then "fv" else "kv") ++ show x      e <- SMT.declare (solver s) name cryInfNat      SMT.assert (solver s) (SMT.fun "cryVar" [ e ])      return (v,e)+++declareVars :: Solver -> [TVar] -> IO TVars+declareVars sol vs =+  Map.fromList <$> zipWithM (declareVar sol) [ 0 .. ]+                                             [ v | v <- vs, kindOf v == KNum ]  assume :: Solver -> TVars -> Prop -> IO () assume s tvs p = SMT.assert (solver s) (SMT.fun "cryAssume" [ toSMT tvs p ])
src/Cryptol/TypeCheck/Solver/Selector.hs view
@@ -5,7 +5,7 @@ -- Maintainer  :  cryptol@galois.com -- Stability   :  provisional -- Portability :  portable-{-# LANGUAGE PatternGuards, Safe #-}+{-# LANGUAGE PatternGuards #-} module Cryptol.TypeCheck.Solver.Selector (tryHasGoal) where  import Cryptol.Parser.Position(Range)@@ -13,7 +13,7 @@ import Cryptol.TypeCheck.InferTypes import Cryptol.TypeCheck.Monad( InferM, unify, newGoals                               , newType, applySubst, solveHasGoal-                              , newParamName+                              , newLocalName                               ) import Cryptol.TypeCheck.Subst (listParamSubst, apSubst) import Cryptol.Utils.Ident (Ident, packIdent,Namespace(..))@@ -166,9 +166,9 @@   -- xs.s             ~~> [ x.s           | x <- xs ]   -- { xs | s = ys }  ~~> [ { x | s = y } | x <- xs | y <- ys ]   liftSeq len el =-    do x1 <- newParamName NSValue (packIdent "x")-       x2 <- newParamName NSValue (packIdent "x")-       y2 <- newParamName NSValue (packIdent "y")+    do x1 <- newLocalName NSValue (packIdent "x")+       x2 <- newLocalName NSValue (packIdent "x")+       y2 <- newLocalName NSValue (packIdent "y")        case tNoUser innerT of          TCon _ [_,eli] ->            do d <- mkSelSln s el eli@@ -190,8 +190,8 @@   -- f.s            ~~> \x -> (f x).s   -- { f | s = g }  ~~> \x -> { f x | s = g x }   liftFun t1 t2 =-    do x1 <- newParamName NSValue (packIdent "x")-       x2 <- newParamName NSValue (packIdent "x")+    do x1 <- newLocalName NSValue (packIdent "x")+       x2 <- newLocalName NSValue (packIdent "x")        case tNoUser innerT of          TCon _ [_,inT] ->            do d <- mkSelSln s t2 inT
src/Cryptol/TypeCheck/Solver/Types.hs view
@@ -1,4 +1,5 @@ {-# Language OverloadedStrings, DeriveGeneric, DeriveAnyClass #-}+{-# LANGUAGE Safe #-} module Cryptol.TypeCheck.Solver.Types where  import Data.Map(Map)
src/Cryptol/TypeCheck/Subst.hs view
@@ -7,10 +7,7 @@ -- Portability :  portable  {-# LANGUAGE BangPatterns #-}-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE DeriveFoldable #-} {-# LANGUAGE DeriveTraversable #-}-{-# LANGUAGE PatternGuards #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-}@@ -35,6 +32,7 @@   , applySubstToVar   , substToList   , fmap', (!$), (.$)+  , mergeDistinctSubst   ) where  import           Data.Maybe@@ -85,6 +83,29 @@     , suDefaulting = False     } +mergeDistinctSubst :: [Subst] -> Subst+mergeDistinctSubst sus =+  case sus of+    [] -> emptySubst+    _  -> foldr1 merge sus++  where+  merge s1 s2 = S { suFreeMap     = jn suFreeMap s1 s2+                  , suBoundMap    = jn suBoundMap s1 s2+                  , suDefaulting  = if suDefaulting s1 || suDefaulting s2+                                      then err+                                      else False+                  }++  err       = panic "mergeDistinctSubst" [ "Not distinct" ]+  bad _ _   = err+  jn f x y  = IntMap.unionWith bad (f x) (f y)++++++ -- | Reasons to reject a single-variable substitution. data SubstError   = SubstRecursive@@ -241,7 +262,15 @@          Just (TUser f ts1 t1)      TRec fs -> TRec `fmap` (anyJust (apSubstMaybe su) fs)-    TNewtype nt ts -> TNewtype nt `fmap` anyJust (apSubstMaybe su) ts++    {- We apply the substitution to the newtype as well, because it might+    contain module parameters, which need to be substituted when+    instantiating a functor. -}+    TNewtype nt ts ->+      uncurry TNewtype <$> anyJust2 (applySubstToNewtype su)+                                    (anyJust (apSubstMaybe su))+                                    (nt,ts)+     TVar x -> applySubstToVar su x  lookupSubst :: TVar -> Subst -> Maybe Type@@ -263,6 +292,16 @@       | suDefaulting su -> Just $! defaultFreeVar x       | otherwise       -> Nothing ++applySubstToNewtype :: Subst -> Newtype -> Maybe Newtype+applySubstToNewtype su nt =+  do (cs,fs) <- anyJust2+                  (anyJust (apSubstMaybe su))+                  (anyJust (apSubstMaybe su))+                  (ntConstraints nt, ntFields nt)+     pure nt { ntConstraints = cs, ntFields = fs }++ class TVars t where   apSubst :: Subst -> t -> t   -- ^ Replaces free variables. To prevent space leaks when used with@@ -351,7 +390,16 @@  instance TVars Schema where   apSubst su (Forall xs ps t) =-    Forall xs !$ (concatMap pSplitAnd (apSubst su ps)) !$ (apSubst su t)+    Forall xs !$ (map doProp ps) !$ (apSubst su t)+    where+    doProp = pAnd . pSplitAnd . apSubst su+    {- NOTE: when applying a substitution to the predicates of a schema+       we preserve the number of predicate, even if some of them became+       "True" or and "And".  This is to accomodate applying substitution+       to already type checked code (e.g., when instantiating a functor)+       where the predictes in the schema need to match the corresponding+       EProofAbs in the term.+    -}  instance TVars Expr where   apSubst su = go@@ -363,20 +411,16 @@         EAbs x t e1   -> EAbs x !$ (apSubst su t) !$ (go e1)         ETAbs a e     -> ETAbs a !$ (go e)         ETApp e t     -> ETApp !$ (go e) !$ (apSubst su t)-        EProofAbs p e -> EProofAbs !$ hmm !$ (go e)-          where hmm = case pSplitAnd (apSubst su p) of-                        [p1] -> p1-                        res -> panic "apSubst@EProofAbs"-                                [ "Predicate split or disappeared after"-                                , "we applied a substitution."-                                , "Predicate:"-                                , show (pp p)-                                , "Became:"-                                , show (map pp res)-                                , "subst:"-                                , show (pp su)-                                ]+        EProofAbs p e -> EProofAbs !$ p' !$ (go e)+          where p' = pAnd (pSplitAnd (apSubst su p))+          {- NOTE: we used to panic if `pSplitAnd` didn't return a single result.+          It is useful to avoid the panic if applying the substitution to+          already type checked code (e.g., when we are instantitaing a+          functor).  In that case, we don't have the option to modify the+          `EProofAbs` because we'd have to change all call sites, but things might+          simplify because of the extra info in the substitution. -} +         EProofApp e   -> EProofApp !$ (go e)          EVar {}       -> expr@@ -391,6 +435,8 @@          EWhere e ds   -> EWhere !$ (go e) !$ (apSubst su ds) +        EPropGuards guards ty -> EPropGuards !$ (\(props, e) -> (apSubst su `fmap'` props, apSubst su e)) `fmap'` guards .$ ty+ instance TVars Match where   apSubst su (From x len t e) = From x !$ (apSubst su len) !$ (apSubst su t) !$ (apSubst su e)   apSubst su (Let b)      = Let !$ (apSubst su b)@@ -401,15 +447,25 @@  instance TVars Decl where   apSubst su d =-    let !sig' = id $! apSubst su (dSignature d)+    let !sig' = apSubst su (dSignature d)         !def' = apSubst su (dDefinition d)     in d { dSignature = sig', dDefinition = def' }  instance TVars DeclDef where-  apSubst su (DExpr e) = DExpr !$ (apSubst su e)-  apSubst _  DPrim     = DPrim+  apSubst su (DExpr e)    = DExpr !$ (apSubst su e)+  apSubst _  DPrim        = DPrim+  apSubst _  (DForeign t) = DForeign t -instance TVars Module where+-- WARNING: This applies the substitution only to the declarations.+instance TVars (ModuleG names) where   apSubst su m =     let !decls' = apSubst su (mDecls m)-    in m { mDecls = decls' }+        !funs'  = apSubst su <$> mFunctors m+    in m { mDecls = decls', mFunctors = funs' }++-- WARNING: This applies the substitution only to the declarations in modules.+instance TVars TCTopEntity where+  apSubst su ent =+    case ent of+      TCTopModule m -> TCTopModule (apSubst su m)+      TCTopSignature {} -> ent
src/Cryptol/TypeCheck/TCon.hs view
@@ -40,7 +40,7 @@ builtInType :: M.Name -> Maybe TCon builtInType nm =   case M.nameInfo nm of-    M.Declared m _+    M.GlobalName _ OrigName { ogModule = m }       | m == M.TopModule preludeName -> Map.lookup (M.nameIdent nm) builtInTypes       | m == M.TopModule floatName   -> Map.lookup (M.nameIdent nm) builtInFloat       | m == M.TopModule arrayName   -> Map.lookup (M.nameIdent nm) builtInArray
src/Cryptol/TypeCheck/Type.hs view
@@ -16,6 +16,8 @@ import GHC.Generics (Generic) import Control.DeepSeq +import           Data.Map(Map)+import qualified Data.Map as Map import qualified Data.IntMap as IntMap import           Data.Maybe (fromMaybe) import           Data.Set (Set)@@ -23,9 +25,10 @@ import           Data.Text (Text)  import Cryptol.Parser.Selector-import Cryptol.Parser.Position(Range,emptyRange)+import Cryptol.Parser.Position(Located,thing,Range,emptyRange)+import Cryptol.Parser.AST(ImpName(..)) import Cryptol.ModuleSystem.Name-import Cryptol.Utils.Ident (Ident, isInfixIdent, exprModName)+import Cryptol.Utils.Ident (Ident, isInfixIdent, exprModName, ogModule, ModName) import Cryptol.TypeCheck.TCon import Cryptol.TypeCheck.PP import Cryptol.TypeCheck.Solver.InfNat@@ -37,18 +40,75 @@ infix  4 =#=, >== infixr 5 `tFun` ++--------------------------------------------------------------------------------+-- Module parameters++type FunctorParams = Map Ident ModParam++-- | Compute the names from all functor parameters+allParamNames :: FunctorParams -> ModParamNames+allParamNames mps =+  ModParamNames+    { mpnTypes       = Map.unions (map mpnTypes ps)+    , mpnConstraints = concatMap mpnConstraints ps+    , mpnFuns        = Map.unions (map mpnFuns ps)+    , mpnTySyn       = Map.unions (map mpnTySyn ps)+    , mpnDoc         = Nothing+    }+  where+  ps = map mpParameters (Map.elems mps)+++-- | A module parameter.  Corresponds to a "signature import".+-- A single module parameter can bring multiple things in scope.+data ModParam = ModParam+  { mpName        :: Ident+    -- ^ The name of a functor parameter.++  , mpQual        :: !(Maybe ModName)+    -- ^ This is the qualifier for the parameter.  We use it to+    -- derive parameter names when doing `_` imports.++  , mpIface       :: ImpName Name+    -- ^ The interface corresponding to this parameter.+    -- This is thing in `import interface`++  , mpParameters  :: ModParamNames+    {- ^ These are the actual parameters, not the ones in the interface+      For example if the same interface is used for multiple parameters+      the `ifmpParameters` would all be different. -}+  } deriving (Show, Generic, NFData)++-- | Information about the names brought in through an "interface import".+-- This is also used to keep information about.+data ModParamNames = ModParamNames+  { mpnTypes       :: Map Name ModTParam+    -- ^ Type parameters++  , mpnTySyn      :: !(Map Name TySyn)+    -- ^ Type synonyms++  , mpnConstraints :: [Located Prop]+    -- ^ Constraints on param. types+++  , mpnFuns        :: Map.Map Name ModVParam+    -- ^ Value parameters++  , mpnDoc         :: !(Maybe Text)+    -- ^ Documentation about the interface.+  } deriving (Show, Generic, NFData)+ -- | A type parameter of a module. data ModTParam = ModTParam   { mtpName   :: Name   , mtpKind   :: Kind-  , mtpNumber :: !Int -- ^ The number of the parameter in the module-                      -- This is used when we move parameters from the module-                      -- level to individual declarations-                      -- (type synonyms in particular)   , mtpDoc    :: Maybe Text   } deriving (Show,Generic,NFData)  +-- | This is how module parameters appear in actual types. mtpParam :: ModTParam -> TParam mtpParam mtp = TParam { tpUnique = nameUnique (mtpName mtp)                       , tpKind   = mtpKind mtp@@ -64,9 +124,9 @@   { mvpName   :: Name   , mvpType   :: Schema   , mvpDoc    :: Maybe Text-  , mvpFixity :: Maybe Fixity+  , mvpFixity :: Maybe Fixity       -- XXX: This should be in the name?   } deriving (Show,Generic,NFData)-+--------------------------------------------------------------------------------   @@ -259,6 +319,7 @@ data Newtype  = Newtype { ntName   :: Name                         , ntParams :: [TParam]                         , ntConstraints :: [Prop]+                        , ntConName :: !Name                         , ntFields :: RecordMap Ident Type                         , ntDoc :: Maybe Text                         } deriving (Show, Generic, NFData)@@ -285,6 +346,8 @@  -------------------------------------------------------------------------------- +instance HasKind AbstractType where+  kindOf at = foldr (:->) (atKind at) (map kindOf (fst (atCtrs at)))  instance HasKind TVar where   kindOf (TVFree  _ k _ _) = k@@ -696,7 +759,7 @@ tFun a b  = TCon (TC TCFun) [a,b]  -- | Eliminate outermost type synonyms.-tNoUser  :: Type -> Type+tNoUser :: Type -> Type tNoUser t = case t of               TUser _ _ a -> tNoUser a               _           -> t@@ -847,7 +910,50 @@   where   prop = TCon (PC PPrime) [ty] +-- Negation -------------------------------------------------------------------- +{-| `pNegNumeric` negates a simple (i.e., not And, not prime, etc) prop+over numeric type vars.  The result is a conjunction of properties.  -}+pNegNumeric :: Prop -> [Prop]+pNegNumeric prop =+  case tNoUser prop of+    TCon tcon tys ->+      case tcon of+        PC pc ->+          case pc of++            -- not (x == y)  <=>  x /= y+            PEqual -> [TCon (PC PNeq) tys]++            -- not (x /= y)  <=>  x == y+            PNeq -> [TCon (PC PEqual) tys]++            -- not (x >= y)  <=>  x /= y and y >= x+            PGeq -> [TCon (PC PNeq) tys, TCon (PC PGeq) (reverse tys)]++            -- not (fin x)  <=>  x == Inf+            PFin | [ty] <- tys -> [ty =#= tInf]+                 | otherwise -> bad++            -- not True  <=>  0 == 1+            PTrue -> [TCon (PC PEqual) [tZero, tOne]]++            _ -> bad++        TError _ki -> [prop] -- propogates `TError`++        TC _tc -> bad+        TF _tf -> bad++    _ -> bad++  where+  bad = panic "pNegNumeric"+          [ "Unexpeceted numeric constraint:"+          , pretty prop+          ]++ --------------------------------------------------------------------------------  noFreeVariables :: FVS t => t -> Bool@@ -873,6 +979,34 @@         TRec fs     -> fvs (recordElements fs)         TNewtype _nt ts -> fvs ts ++-- | Find the abstract types mentioned in a type.+class FreeAbstract t where+  freeAbstract :: t -> Set UserTC++instance FreeAbstract a => FreeAbstract [a] where+  freeAbstract = Set.unions . map freeAbstract++instance (FreeAbstract a, FreeAbstract b) => FreeAbstract (a,b) where+  freeAbstract (a,b) = Set.union (freeAbstract a) (freeAbstract b)++instance FreeAbstract TCon where+  freeAbstract tc =+    case tc of+      TC (TCAbstract ut) -> Set.singleton ut+      _                  -> Set.empty++instance FreeAbstract Type where+  freeAbstract ty =+    case ty of+      TCon tc ts      -> freeAbstract (tc,ts)+      TVar {}         -> Set.empty+      TUser _ _ t     -> freeAbstract t+      TRec fs         -> freeAbstract (recordElements fs)+      TNewtype _nt ts -> freeAbstract ts+++ instance FVS a => FVS (Maybe a) where   fvs Nothing  = Set.empty   fvs (Just x) = fvs x@@ -888,10 +1022,6 @@       Set.difference (Set.union (fvs ps) (fvs t)) bound     where bound = Set.fromList (map tpVar as) ---- -- Pretty Printing -------------------------------------------------------------  instance PP TParam where@@ -924,7 +1054,18 @@   ps  = ntParams nt   nm = addTNames ps emptyNameMap +ppNewtypeFull :: Newtype -> Doc+ppNewtypeFull nt =+  text "newtype" <+> pp (ntName nt) <+> hsep (map (ppWithNamesPrec nm 9) ps)+  $$ nest 2 (cs $$ ("=" <+> pp (ntConName nt) $$ nest 2 fs))+  where+  ps = ntParams nt+  nm = addTNames ps emptyNameMap+  fs = vcat [ pp f <.> ":" <+> pp t | (f,t) <- canonicalFields (ntFields nt) ]+  cs = vcat (map pp (ntConstraints nt)) ++ instance PP Schema where   ppPrec = ppWithNamesPrec IntMap.empty @@ -1115,7 +1256,8 @@     TypeParamInstPos f n   -> mk (sh f ++ "_" ++ show n)     DefinitionOf x ->       case nameInfo x of-        Declared m SystemName | m == TopModule exprModName -> mk "it"+        GlobalName SystemName og+          | ogModule og == TopModule exprModName -> mk "it"         _ -> using x     LenOfCompGen           -> mk "n"     GeneratorOfListComp    -> "seq"@@ -1176,3 +1318,24 @@       GeneratorOfListComp    -> "generator in a list comprehension"       FunApp                -> "function call"       TypeErrorPlaceHolder  -> "type error place-holder"++instance PP ModParamNames where+  ppPrec _ ps =+    let tps = Map.elems (mpnTypes ps)+    in+    vcat $ map pp tps +++          if null (mpnConstraints ps) then [] else+            [ "type constraint" <+>+                parens (commaSep (map (pp . thing) (mpnConstraints ps)))+            ] +++           [ pp t | t <- Map.elems (mpnTySyn ps) ] +++           map pp (Map.elems (mpnFuns ps))++instance PP ModTParam where+  ppPrec _ p =+    "type" <+> pp (mtpName p) <+> ":" <+> pp (mtpKind p)++instance PP ModVParam where+  ppPrec _ p = pp (mvpName p) <+> ":" <+> pp (mvpType p)++
src/Cryptol/TypeCheck/TypeOf.hs view
@@ -9,6 +9,7 @@ {-# LANGUAGE Safe                                #-} {-# LANGUAGE ViewPatterns                        #-} {-# LANGUAGE PatternGuards                       #-}+{-# LANGUAGE NamedFieldPuns                      #-} module Cryptol.TypeCheck.TypeOf   ( fastTypeOf   , fastSchemaOf@@ -43,6 +44,7 @@                         Just (_, t) -> t                         Nothing     -> panic "Cryptol.TypeCheck.TypeOf.fastTypeOf"                                          [ "EApp with non-function operator" ]+    EPropGuards _guards sType -> sType     -- Polymorphic fragment     EVar      {}  -> polymorphic     ETAbs     {}  -> polymorphic@@ -111,8 +113,11 @@     EComp  {}      -> monomorphic     EApp   {}      -> monomorphic     EAbs   {}      -> monomorphic++    -- PropGuards+    EPropGuards _ t -> Forall {sVars = [], sProps = [], sType = t}   where-    monomorphic = Forall [] [] (fastTypeOf tyenv expr)+    monomorphic = Forall {sVars = [], sProps = [], sType = fastTypeOf tyenv expr}  -- | Apply a substitution to a type *without* simplifying -- constraints like @Arith [n]a@ to @Arith a@. (This is in contrast to
src/Cryptol/TypeCheck/TypePat.hs view
@@ -1,5 +1,6 @@ -- See Note [-Wincomplete-uni-patterns and irrefutable patterns] {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}+{-# LANGUAGE Safe #-} module Cryptol.TypeCheck.TypePat   ( aInf, aNat, aNat' @@ -15,6 +16,7 @@    , aTVar   , aFreeTVar+  , anAbstractType   , aBit   , aSeq   , aWord@@ -123,6 +125,11 @@ aTVar = \a -> case tNoUser a of                 TVar x -> return x                 _      -> mzero++anAbstractType :: Pat Type UserTC+anAbstractType = \a -> case tNoUser a of+                         TCon (TC (TCAbstract ut)) [] -> pure ut+                         _                            -> mzero  aFreeTVar :: Pat Type TVar aFreeTVar t =
+ src/Cryptol/Utils/Benchmark.hs view
@@ -0,0 +1,36 @@+-- | Simple benchmarking of IO functions.+module Cryptol.Utils.Benchmark+  ( BenchmarkStats (..)+  , benchmark+  , secs+  ) where++import           Criterion.Measurement       (runBenchmark, secs, threshold)+import           Criterion.Measurement.Types+import           Data.Int+import qualified Data.Vector                 as V+import qualified Data.Vector.Unboxed         as U++-- | Statistics returned by 'benchmark'.+--+-- This is extremely crude compared to the full analysis that criterion can do,+-- but is enough for now.+data BenchmarkStats = BenchmarkStats+  { benchAvgTime    :: !Double+  , benchAvgCpuTime :: !Double+  , benchAvgCycles  :: !Int64+  } deriving Show++-- | Benchmark the application of the given function to the given input and the+-- execution of the resulting IO action to WHNF, spending at least the given+-- amount of time in seconds to collect measurements.+benchmark :: Double -> (a -> IO b) -> a -> IO BenchmarkStats+benchmark period f x = do+  (meas, _) <- runBenchmark (whnfAppIO f x) period+  let meas' = rescale <$> V.filter ((>= threshold) . measTime) meas+      len = length meas'+      sumMeasure sel = U.sum $ measure sel meas'+  pure BenchmarkStats+    { benchAvgTime = sumMeasure measTime / fromIntegral len+    , benchAvgCpuTime = sumMeasure measCpuTime / fromIntegral len+    , benchAvgCycles = sumMeasure measCycles `div` fromIntegral len }
src/Cryptol/Utils/Fixity.hs view
@@ -23,10 +23,10 @@  -- | Information about associativity. data Assoc = LeftAssoc | RightAssoc | NonAssoc-  deriving (Show, Eq, Generic, NFData)+  deriving (Show, Eq, Ord, Generic, NFData)  data Fixity = Fixity { fAssoc :: !Assoc, fLevel :: !Int }-  deriving (Eq, Generic, NFData, Show)+  deriving (Eq, Ord, Generic, NFData, Show)  data FixityCmp = FCError                | FCLeft
src/Cryptol/Utils/Ident.hs view
@@ -6,24 +6,29 @@ -- Stability   :  provisional -- Portability :  portable -{-# LANGUAGE DeriveGeneric, OverloadedStrings #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE OverloadedStrings #-}  module Cryptol.Utils.Ident   ( -- * Module names     ModPath(..)   , apPathRoot   , modPathCommon+  , modPathIsOrContains   , topModuleFor   , modPathSplit+  , modPathIsNormal    , ModName   , modNameToText   , textToModName   , modNameChunks+  , modNameChunksText   , packModName   , preludeName   , preludeReferenceName+  , undefinedModName   , floatName   , suiteBName   , arrayName@@ -31,10 +36,10 @@   , interactiveName   , noModuleName   , exprModName--  , isParamInstModName-  , paramInstModName-  , notParamInstModName+  , modNameArg+  , modNameIfaceMod+  , modNameToNormalModName+  , modNameIsNormal      -- * Identifiers   , Ident@@ -47,6 +52,9 @@   , nullIdent   , identText   , modParamIdent+  , identAnonArg+  , identAnonIfaceMod+  , identIsNormal      -- * Namespaces   , Namespace(..)@@ -54,6 +62,8 @@      -- * Original names   , OrigName(..)+  , OrigSource(..)+  , ogFromModParam      -- * Identifiers for primitives   , PrimIdent(..)@@ -67,11 +77,14 @@ import           Control.DeepSeq (NFData) import           Data.Char (isSpace) import           Data.List (unfoldr)+import           Data.Text (Text) import qualified Data.Text as T import           Data.String (IsString(..)) import           GHC.Generics (Generic) +import Cryptol.Utils.Panic(panic) + --------------------------------------------------------------------------------  -- | Namespaces for names@@ -115,6 +128,14 @@       (x:xs',y:ys') | x == y -> findCommon (Nested com x) xs' ys'       _                      -> (com, xs, ys) +-- | Does the first module path contain the second?+-- This returns true if the paths are the same.+modPathIsOrContains :: ModPath -> ModPath -> Bool+modPathIsOrContains p1 p2 =+  case modPathCommon p1 p2 of+    Just (_,[],_) -> True+    _ -> False+ modPathSplit :: ModPath -> (ModName, [Ident]) modPathSplit p0 = (top,reverse xs)   where@@ -125,47 +146,67 @@       Nested b i  -> (a, i:bs)         where (a,bs) = go b -+modPathIsNormal :: ModPath -> Bool+modPathIsNormal p = modNameIsNormal m && all identIsNormal is+  where (m,is) = modPathSplit p   -------------------------------------------------------------------------------- -- | Top-level Module names are just text.-data ModName = ModName T.Text+data ModName = ModName Text MaybeAnon   deriving (Eq,Ord,Show,Generic)  instance NFData ModName -modNameToText :: ModName -> T.Text-modNameToText (ModName x) = x+-- | Change a normal module name to a module name to be used for an+-- anonnymous argument.+modNameArg :: ModName -> ModName+modNameArg (ModName m fl) =+  case fl of+    NormalName        -> ModName m AnonModArgName+    AnonModArgName    -> panic "modNameArg" ["Name is not normal"]+    AnonIfaceModName  -> panic "modNameArg" ["Name is not normal"] -textToModName :: T.Text -> ModName-textToModName = ModName+-- | Change a normal module name to a module name to be used for an+-- anonnymous interface.+modNameIfaceMod :: ModName -> ModName+modNameIfaceMod (ModName m fl) =+  case fl of+    NormalName        -> ModName m AnonIfaceModName+    AnonModArgName    -> panic "modNameIfaceMod" ["Name is not normal"]+    AnonIfaceModName  -> panic "modNameIfaceMod" ["Name is not normal"] -modNameChunks :: ModName -> [String]-modNameChunks  = unfoldr step . modNameToText . notParamInstModName-  where-  step str-    | T.null str = Nothing-    | otherwise  = case T.breakOn modSep str of-                     (a,b) -> Just (T.unpack a,T.drop (T.length modSep) b)+-- | This is used when we check that the name of a module matches the+-- file where it is defined.+modNameToNormalModName :: ModName -> ModName+modNameToNormalModName (ModName t _) = ModName t NormalName -isParamInstModName :: ModName -> Bool-isParamInstModName (ModName x) = modInstPref `T.isPrefixOf` x+modNameToText :: ModName -> Text+modNameToText (ModName x fl) = maybeAnonText fl x --- | Convert a parameterized module's name to the name of the module--- containing the same definitions but with explicit parameters on each--- definition.-paramInstModName :: ModName -> ModName-paramInstModName (ModName x)-  | modInstPref `T.isPrefixOf` x = ModName x-  | otherwise = ModName (T.append modInstPref x)+-- | This is useful when we want to hide anonymous modules.+modNameIsNormal :: ModName -> Bool+modNameIsNormal (ModName _ fl) = isNormal fl +-- | Make a normal module name out of text.+textToModName :: T.Text -> ModName+textToModName txt = ModName txt NormalName -notParamInstModName :: ModName -> ModName-notParamInstModName (ModName x)-  | modInstPref `T.isPrefixOf` x = ModName (T.drop (T.length modInstPref) x)-  | otherwise = ModName x+-- | Break up a module name on the separators, `Text` version.+modNameChunksText :: ModName -> [T.Text]+modNameChunksText (ModName x fl) = unfoldr step x+  where+  step str+    | T.null str = Nothing+    | otherwise  =+      case T.breakOn modSep str of+        (a,b)+          | T.null b  -> Just (maybeAnonText fl str, b)+          | otherwise -> Just (a,T.drop (T.length modSep) b) +-- | Break up a module name on the separators, `String` version+modNameChunks :: ModName -> [String]+modNameChunks = map T.unpack . modNameChunksText  packModName :: [T.Text] -> ModName packModName strs = textToModName (T.intercalate modSep (map trim strs))@@ -176,13 +217,12 @@ modSep :: T.Text modSep  = "::" -modInstPref :: T.Text-modInstPref = "`"-- preludeName :: ModName preludeName  = packModName ["Cryptol"] +undefinedModName :: ModName+undefinedModName = packModName ["Undefined module"]+ preludeReferenceName :: ModName preludeReferenceName = packModName ["Cryptol","Reference"] @@ -213,16 +253,32 @@ data OrigName = OrigName   { ogNamespace :: Namespace   , ogModule    :: ModPath+  , ogSource    :: OrigSource   , ogName      :: Ident   } deriving (Eq,Ord,Show,Generic,NFData) +-- | Describes where a top-level name came from+data OrigSource =+    FromDefinition+  | FromFunctorInst+  | FromModParam Ident+    deriving (Eq,Ord,Show,Generic,NFData) +-- | Returns true iff the 'ogSource' of the given 'OrigName' is 'FromModParam'+ogFromModParam :: OrigName -> Bool+ogFromModParam og = case ogSource og of+                      FromModParam _ -> True+                      _ -> False++ -------------------------------------------------------------------------------- --- | Identifiers, along with a flag that indicates whether or not they're infix--- operators. The boolean is present just as cached information from the lexer,--- and never used during comparisons.-data Ident = Ident Bool T.Text+{- | The type of identifiers.+  * The boolean flag indicates whether or not they're infix operators.+    The boolean is present just as cached information from the lexer,+    and never used during comparisons.+  * The MaybeAnon indicates if this is an anonymous name  -}+data Ident = Ident Bool MaybeAnon T.Text              deriving (Show,Generic)  instance Eq Ident where@@ -230,39 +286,82 @@   a /= b = compare a b /= EQ  instance Ord Ident where-  compare (Ident _ i1) (Ident _ i2) = compare i1 i2+  compare (Ident _ mb1 i1) (Ident _ mb2 i2) = compare (mb1,i1) (mb2,i2)  instance IsString Ident where   fromString str = mkIdent (T.pack str)  instance NFData Ident +-- | Make a normal (i.e., not anonymous) identifier packIdent :: String -> Ident packIdent  = mkIdent . T.pack +-- | Make a normal (i.e., not anonymous) identifier packInfix :: String -> Ident packInfix  = mkInfix . T.pack  unpackIdent :: Ident -> String unpackIdent  = T.unpack . identText +-- | Make a normal (i.e., not anonymous) identifier mkIdent :: T.Text -> Ident-mkIdent  = Ident False+mkIdent  = Ident False NormalName  mkInfix :: T.Text -> Ident-mkInfix  = Ident True+mkInfix  = Ident True NormalName  isInfixIdent :: Ident -> Bool-isInfixIdent (Ident b _) = b+isInfixIdent (Ident b _ _) = b  nullIdent :: Ident -> Bool-nullIdent (Ident _ t) = T.null t+nullIdent = T.null . identText  identText :: Ident -> T.Text-identText (Ident _ t) = t+identText (Ident _ mb t) = maybeAnonText mb t  modParamIdent :: Ident -> Ident-modParamIdent (Ident x t) = Ident x (T.append (T.pack "module parameter ") t)+modParamIdent (Ident x a t) =+  Ident x a (T.append (T.pack "module parameter ") t)++-- | Make an anonymous identifier for the module corresponding to+-- a `where` block in a functor instantiation.+identAnonArg :: Ident -> Ident+identAnonArg (Ident b _ txt) = Ident b AnonModArgName txt++-- | Make an anonymous identifier for the interface corresponding to+-- a `parameter` declaration.+identAnonIfaceMod :: Ident -> Ident+identAnonIfaceMod (Ident b _ txt) = Ident b AnonIfaceModName txt++identIsNormal :: Ident -> Bool+identIsNormal (Ident _ mb _) = isNormal mb++--------------------------------------------------------------------------------++-- | Information about anonymous names.+data MaybeAnon = NormalName       -- ^ Not an anonymous name.+               | AnonModArgName   -- ^ Anonymous module (from `where`)+               | AnonIfaceModName -- ^ Anonymous interface (from `parameter`)+  deriving (Eq,Ord,Show,Generic)++instance NFData MaybeAnon++-- | Modify a name, if it is a nonymous+maybeAnonText :: MaybeAnon -> Text -> Text+maybeAnonText mb txt =+  case mb of+    NormalName       -> txt+    AnonModArgName   -> "`where` argument of " <> txt+    AnonIfaceModName -> "`parameter` interface of " <> txt++isNormal :: MaybeAnon -> Bool+isNormal mb =+  case mb of+    NormalName -> True+    _          -> False++   --------------------------------------------------------------------------------
src/Cryptol/Utils/PP.hs view
@@ -7,7 +7,7 @@ -- Portability :  portable  {-# LANGUAGE Safe #-}-+{-# LANGUAGE BlockArguments #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-}@@ -23,6 +23,7 @@ import           Data.Void (Void) import           GHC.Generics (Generic) import qualified Prettyprinter as PP+import qualified Prettyprinter.Util as PP import qualified Prettyprinter.Render.String as PP  -- | How to pretty print things when evaluating@@ -49,7 +50,8 @@                 | AutoExponent  -- ^ Only show exponent when needed  deriving Show -data FieldOrder = DisplayOrder | CanonicalOrder deriving (Bounded, Enum, Eq, Ord, Read, Show)+data FieldOrder = DisplayOrder | CanonicalOrder+  deriving (Bounded, Enum, Eq, Ord, Read, Show)   defaultPPOpts :: PPOpts@@ -91,7 +93,9 @@ -- | Never qualify names from this module. neverQualifyMod :: ModPath -> NameDisp neverQualifyMod mn = NameDisp $ \n ->-  if ogModule n == mn then Just UnQualified else Nothing+  case ogSource n of+    FromDefinition | ogModule n == mn -> Just UnQualified+    _ -> Nothing  neverQualify :: NameDisp neverQualify  = NameDisp $ \ _ -> Just UnQualified@@ -102,25 +106,52 @@ extend :: NameDisp -> NameDisp -> NameDisp extend  = mappend --- | Get the format for a name. When 'Nothing' is returned, the name is not--- currently in scope.+-- | Get the format for a name. getNameFormat :: OrigName -> NameDisp -> NameFormat getNameFormat m (NameDisp f)  = fromMaybe NotInScope (f m) getNameFormat _ EmptyNameDisp = NotInScope  -- | Produce a document in the context of the current 'NameDisp'. withNameDisp :: (NameDisp -> Doc) -> Doc-withNameDisp k = Doc (\disp -> runDoc disp (k disp))+withNameDisp k = withPPCfg (k . ppcfgNameDisp) +-- | Produce a document in the context of the current configuration.+withPPCfg :: (PPCfg -> Doc) -> Doc+withPPCfg k = Doc (\cfg -> runDocWith cfg (k cfg))+ -- | Fix the way that names are displayed inside of a doc. fixNameDisp :: NameDisp -> Doc -> Doc-fixNameDisp disp (Doc f) = Doc (\ _ -> f disp)+fixNameDisp disp d =+  withPPCfg (\cfg -> fixPPCfg cfg { ppcfgNameDisp = disp } d) +-- | Fix the way that names are displayed inside of a doc.+fixPPCfg :: PPCfg -> Doc -> Doc+fixPPCfg cfg (Doc f) = Doc (\_ -> f cfg) +updPPCfg :: (PPCfg -> PPCfg) -> Doc -> Doc+updPPCfg f d = withPPCfg (\cfg -> fixPPCfg (f cfg) d)++debugShowUniques :: Doc -> Doc+debugShowUniques = updPPCfg \cfg -> cfg { ppcfgShowNameUniques = True }++++ -- Documents ------------------------------------------------------------------- -newtype Doc = Doc (NameDisp -> PP.Doc Void) deriving (Generic, NFData)+data PPCfg = PPCfg+  { ppcfgNameDisp     :: NameDisp+  , ppcfgShowNameUniques :: Bool+  } +defaultPPCfg :: PPCfg+defaultPPCfg = PPCfg+  { ppcfgNameDisp = mempty+  , ppcfgShowNameUniques = False+  }++newtype Doc = Doc (PPCfg -> PP.Doc Void) deriving (Generic, NFData)+ instance Semigroup Doc where   (<>) = liftPP2 (<>) @@ -128,18 +159,22 @@   mempty = liftPP mempty   mappend = (<>) +runDocWith :: PPCfg -> Doc -> PP.Doc Void+runDocWith names (Doc f) = f names+ runDoc :: NameDisp -> Doc -> PP.Doc Void-runDoc names (Doc f) = f names+runDoc disp = runDocWith defaultPPCfg { ppcfgNameDisp = disp }  instance Show Doc where-  show d = PP.renderString (PP.layoutPretty opts (runDoc mempty d))-    where opts = PP.defaultLayoutOptions{ PP.layoutPageWidth = PP.AvailablePerLine 100 0.666 }+  show d = PP.renderString (PP.layoutPretty opts (runDocWith defaultPPCfg d))+    where opts = PP.defaultLayoutOptions+                    { PP.layoutPageWidth = PP.AvailablePerLine 100 0.666 }  instance IsString Doc where   fromString = text  renderOneLine :: Doc -> String-renderOneLine d = PP.renderString (PP.layoutCompact (runDoc mempty d))+renderOneLine d = PP.renderString (PP.layoutCompact (runDocWith defaultPPCfg d))  class PP a where   ppPrec :: Int -> a -> Doc@@ -231,6 +266,9 @@ liftSep :: ([PP.Doc Void] -> PP.Doc Void) -> ([Doc] -> Doc) liftSep f ds = Doc (\e -> f [ d e | Doc d <- ds ]) +reflow :: T.Text -> Doc+reflow x = liftPP (PP.reflow x)+ infixl 6 <.>, <+>, </>  (<.>) :: Doc -> Doc -> Doc@@ -337,6 +375,10 @@ colon :: Doc colon  = liftPP PP.colon +pipe :: Doc+pipe = liftPP PP.pipe++ instance PP T.Text where   ppPrec _ str = text (T.unpack str) @@ -346,7 +388,6 @@ instance PP ModName where   ppPrec _   = text . T.unpack . modNameToText - instance PP Assoc where   ppPrec _ LeftAssoc  = text "left-associative"   ppPrec _ RightAssoc = text "right-associative"@@ -368,7 +409,10 @@       case getNameFormat og disp of         UnQualified -> pp (ogName og)         Qualified m -> ppQual (TopModule m) (pp (ogName og))-        NotInScope  -> ppQual (ogModule og) (pp (ogName og))+        NotInScope  -> ppQual (ogModule og)+                       case ogSource og of+                         FromModParam x -> pp x <.> "::" <.> pp (ogName og)+                         _ -> pp (ogName og)     where    ppQual mo x =     case mo of@@ -380,6 +424,9 @@ instance PP Namespace where   ppPrec _ ns =     case ns of-      NSValue   -> "/*value*/"-      NSType    -> "/*type*/"-      NSModule  -> "/*module*/"+      NSValue     -> "/*value*/"+      NSType      -> "/*type*/"+      NSModule    -> "/*module*/"++instance PP PrimIdent where+  ppPrec _ (PrimIdent m t) = pp m <.> text (T.unpack t)
src/Cryptol/Utils/Panic.hs view
@@ -8,7 +8,7 @@  {-# LANGUAGE Trustworthy, TemplateHaskell #-} module Cryptol.Utils.Panic-  (HasCallStack, CryptolPanic, Cryptol, Panic, panic) where+  (HasCallStack, CryptolPanic, Cryptol, Panic, panic, xxxTODO) where  import Panic hiding (panic) import qualified Panic as Panic@@ -19,6 +19,9 @@  panic :: HasCallStack => String -> [String] -> a panic = Panic.panic Cryptol++xxxTODO :: HasCallStack => String -> a+xxxTODO x = panic "TODO" [x]  instance PanicComponent Cryptol where   panicComponentName _ = "Cryptol"
src/Cryptol/Utils/Patterns.hs view
@@ -2,6 +2,7 @@ {-# Language FunctionalDependencies #-} {-# Language FlexibleInstances #-} {-# Language TypeFamilies, UndecidableInstances #-}+{-# Language TypeOperators #-} module Cryptol.Utils.Patterns where  import Control.Monad(liftM,liftM2,ap,MonadPlus(..),guard)
src/Cryptol/Utils/RecordMap.hs view
@@ -14,6 +14,7 @@  {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE Safe #-}  module Cryptol.Utils.RecordMap   ( RecordMap@@ -21,6 +22,7 @@   , canonicalFields   , displayFields   , recordElements+  , displayElements   , fieldSet   , recordFromFields   , recordFromFieldsErr@@ -88,6 +90,11 @@ -- | Return a list of field/value pairs in canonical order. canonicalFields :: RecordMap a b -> [(a,b)] canonicalFields = Map.toList . recordMap++-- | Retrieve the elements of the record in display order+--   of the field names.+displayElements :: (Show a, Ord a) => RecordMap a b -> [b]+displayElements = map snd . displayFields  -- | Return a list of field/value pairs in display order. displayFields :: (Show a, Ord a) => RecordMap a b -> [(a,b)]
+ src/Cryptol/Utils/Types.hs view
@@ -0,0 +1,10 @@+-- | Useful information about various types.+module Cryptol.Utils.Types where++-- | Exponent and precision of 32-bit IEEE-754 floating point.+float32ExpPrec :: (Integer, Integer)+float32ExpPrec = (8, 24)++-- | Exponent and precision of 64-bit IEEE-754 floating point.+float64ExpPrec :: (Integer, Integer)+float64ExpPrec = (11, 53)
src/Cryptol/Version.hs view
@@ -6,7 +6,7 @@ -- Stability   :  provisional -- Portability :  portable -{-# LANGUAGE Safe #-}+{-# LANGUAGE CPP  #-}  module Cryptol.Version (     commitHash@@ -39,6 +39,9 @@     putLn ("Cryptol " ++ ver)     putLn ("Git commit " ++ commitHash)     putLn ("    branch " ++ commitBranch ++ dirtyLab)+#ifdef FFI_ENABLED+    putLn "FFI enabled"+#endif       where       dirtyLab | commitDirty = " (non-committed files present during build)"                | otherwise   = ""