packages feed

cryptol 3.0.0 → 3.1.0

raw patch · 80 files changed

+2963/−1254 lines, 80 filesdep ~sbvdep ~what4PVP ok

version bump matches the API change (PVP)

Dependency ranges changed: sbv, what4

API changes (from Hackage documentation)

- Cryptol.Eval: evalNewtypeDecls :: EvalPrims sym => sym -> Map Name Newtype -> GenEvalEnv sym -> SEval sym (GenEvalEnv sym)
- Cryptol.Eval.Type: TVNewtype :: Newtype -> [Either Nat' TValue] -> RecordMap Ident TValue -> TValue
- Cryptol.Eval.Type: evalNewtypeBody :: TypeEnv -> Newtype -> [Either Nat' TValue] -> RecordMap Ident TValue
- Cryptol.IR.FreeVars: instance Cryptol.IR.FreeVars.FreeVars Cryptol.TypeCheck.Type.Newtype
- 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.Newtype
- Cryptol.ModuleSystem: [ifAbstractTypes] :: IfaceDecls -> Map Name AbstractType
- Cryptol.ModuleSystem: [ifNewtypes] :: IfaceDecls -> Map Name Newtype
- Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames Cryptol.ModuleSystem.NamingEnv.NamingEnv
- Cryptol.ModuleSystem.Env: loadedNewtypes :: ModuleEnv -> Map Name Newtype
- Cryptol.ModuleSystem.Interface: [ifAbstractTypes] :: IfaceDecls -> Map Name AbstractType
- Cryptol.ModuleSystem.Interface: [ifNewtypes] :: IfaceDecls -> Map Name Newtype
- Cryptol.ModuleSystem.Monad: getNewtypes :: ModuleM (Map Name Newtype)
- Cryptol.ModuleSystem.NamingEnv: NamingEnv :: Map Namespace (Map PName Names) -> NamingEnv
- Cryptol.ModuleSystem.NamingEnv: instance Control.DeepSeq.NFData Cryptol.ModuleSystem.NamingEnv.NamingEnv
- Cryptol.ModuleSystem.NamingEnv: instance Cryptol.Utils.PP.PP Cryptol.ModuleSystem.NamingEnv.NamingEnv
- Cryptol.ModuleSystem.NamingEnv: instance GHC.Base.Monoid Cryptol.ModuleSystem.NamingEnv.NamingEnv
- Cryptol.ModuleSystem.NamingEnv: instance GHC.Base.Semigroup Cryptol.ModuleSystem.NamingEnv.NamingEnv
- Cryptol.ModuleSystem.NamingEnv: instance GHC.Generics.Generic Cryptol.ModuleSystem.NamingEnv.NamingEnv
- Cryptol.ModuleSystem.NamingEnv: instance GHC.Show.Show Cryptol.ModuleSystem.NamingEnv.NamingEnv
- Cryptol.ModuleSystem.NamingEnv: modParamsNamingEnv :: ModParamNames -> NamingEnv
- Cryptol.ModuleSystem.NamingEnv: newtype NamingEnv
- Cryptol.ModuleSystem.Renamer: [rmInScope] :: RenamedModule -> NamingEnv
- Cryptol.Symbolic: FTNewtype :: Newtype -> [Either Nat' TValue] -> RecordMap Ident FinType -> FinType
- Cryptol.TypeCheck: [inpAbstractTypes] :: InferInput -> Map Name AbstractType
- Cryptol.TypeCheck: [inpNewtypes] :: InferInput -> Map Name Newtype
- Cryptol.TypeCheck.AST: [mNewtypes] :: ModuleG mname -> Map Name Newtype
- Cryptol.TypeCheck.AST: [mPrimTypes] :: ModuleG mname -> Map Name AbstractType
- Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.AddParams Cryptol.TypeCheck.Type.Newtype
- 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.Type.AbstractType
- Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.TypeCheck.Type.Newtype
- Cryptol.TypeCheck.Monad: [inpAbstractTypes] :: InferInput -> Map Name AbstractType
- Cryptol.TypeCheck.Monad: [inpNewtypes] :: InferInput -> Map Name Newtype
- Cryptol.TypeCheck.Monad: addNewtype :: Newtype -> InferM ()
- Cryptol.TypeCheck.Monad: addPrimType :: AbstractType -> InferM ()
- Cryptol.TypeCheck.Monad: getAbstractTypes :: InferM (Map Name AbstractType)
- Cryptol.TypeCheck.Monad: getNewtypes :: InferM (Map Name Newtype)
- Cryptol.TypeCheck.Monad: kLookupAbstractType :: Name -> KindM (Maybe AbstractType)
- Cryptol.TypeCheck.Monad: kLookupNewtype :: Name -> KindM (Maybe Newtype)
- Cryptol.TypeCheck.Monad: lookupAbstractType :: Name -> InferM (Maybe AbstractType)
- Cryptol.TypeCheck.Monad: lookupNewtype :: Name -> InferM (Maybe Newtype)
- Cryptol.TypeCheck.TCon: TCAbstract :: UserTC -> TC
- Cryptol.TypeCheck.TCon: UserTC :: Name -> Kind -> UserTC
- Cryptol.TypeCheck.TCon: data UserTC
- Cryptol.TypeCheck.TCon: instance Control.DeepSeq.NFData Cryptol.TypeCheck.TCon.UserTC
- Cryptol.TypeCheck.TCon: instance Cryptol.TypeCheck.TCon.HasKind Cryptol.TypeCheck.TCon.UserTC
- Cryptol.TypeCheck.TCon: instance Cryptol.Utils.PP.PP Cryptol.TypeCheck.TCon.UserTC
- Cryptol.TypeCheck.TCon: instance GHC.Classes.Eq Cryptol.TypeCheck.TCon.UserTC
- Cryptol.TypeCheck.TCon: instance GHC.Classes.Ord Cryptol.TypeCheck.TCon.UserTC
- Cryptol.TypeCheck.TCon: instance GHC.Generics.Generic Cryptol.TypeCheck.TCon.UserTC
- Cryptol.TypeCheck.TCon: instance GHC.Show.Show Cryptol.TypeCheck.TCon.UserTC
- Cryptol.TypeCheck.Type: AbstractType :: Name -> Kind -> ([TParam], [Prop]) -> Maybe Fixity -> Maybe Text -> AbstractType
- Cryptol.TypeCheck.Type: Newtype :: Name -> [TParam] -> [Prop] -> !Name -> RecordMap Ident Type -> Maybe Text -> Newtype
- Cryptol.TypeCheck.Type: TNewtype :: !Newtype -> ![Type] -> Type
- Cryptol.TypeCheck.Type: TPNewtypeParam :: Name -> TPFlavor
- Cryptol.TypeCheck.Type: [atCtrs] :: AbstractType -> ([TParam], [Prop])
- Cryptol.TypeCheck.Type: [atDoc] :: AbstractType -> Maybe Text
- Cryptol.TypeCheck.Type: [atFixitiy] :: AbstractType -> Maybe Fixity
- Cryptol.TypeCheck.Type: [atKind] :: AbstractType -> Kind
- Cryptol.TypeCheck.Type: [atName] :: AbstractType -> Name
- Cryptol.TypeCheck.Type: abstractTypeTC :: AbstractType -> TCon
- Cryptol.TypeCheck.Type: class FreeAbstract t
- Cryptol.TypeCheck.Type: data AbstractType
- Cryptol.TypeCheck.Type: data Newtype
- 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.AbstractType
- Cryptol.TypeCheck.Type: instance Control.DeepSeq.NFData Cryptol.TypeCheck.Type.Newtype
- Cryptol.TypeCheck.Type: instance Cryptol.TypeCheck.TCon.HasKind Cryptol.TypeCheck.Type.AbstractType
- Cryptol.TypeCheck.Type: instance Cryptol.TypeCheck.TCon.HasKind Cryptol.TypeCheck.Type.Newtype
- 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.PP.WithNames Cryptol.TypeCheck.Type.Newtype)
- Cryptol.TypeCheck.Type: instance Cryptol.Utils.PP.PP Cryptol.TypeCheck.Type.Newtype
- Cryptol.TypeCheck.Type: instance GHC.Classes.Eq Cryptol.TypeCheck.Type.Newtype
- Cryptol.TypeCheck.Type: instance GHC.Classes.Ord Cryptol.TypeCheck.Type.Newtype
- Cryptol.TypeCheck.Type: instance GHC.Generics.Generic Cryptol.TypeCheck.Type.AbstractType
- Cryptol.TypeCheck.Type: instance GHC.Generics.Generic Cryptol.TypeCheck.Type.Newtype
- Cryptol.TypeCheck.Type: instance GHC.Show.Show Cryptol.TypeCheck.Type.AbstractType
- Cryptol.TypeCheck.Type: instance GHC.Show.Show Cryptol.TypeCheck.Type.Newtype
- Cryptol.TypeCheck.Type: newtypeConType :: Newtype -> Schema
- Cryptol.TypeCheck.Type: newtypeParam :: Name -> TPFlavor
- Cryptol.TypeCheck.Type: ppNewtypeFull :: Newtype -> Doc
- Cryptol.TypeCheck.Type: ppNewtypeShort :: Newtype -> Doc
- Cryptol.TypeCheck.Type: tAbstract :: UserTC -> [Type] -> Type
- Cryptol.TypeCheck.Type: tNewtype :: Newtype -> [Type] -> Type
- Cryptol.TypeCheck.TypeMap: [tnewtype] :: TypeMap a -> Map Newtype (List TypeMap a)
- Cryptol.TypeCheck.TypePat: anAbstractType :: Pat Type UserTC
- Cryptol.TypeCheck.Unify: TNewtypeArg :: Newtype -> Int -> PathElement
- Cryptol.Utils.Ident: ogFromModParam :: OrigName -> Bool
+ Cryptol.Backend.Monad: NoMatchingConstructor :: Maybe String -> EvalError
+ Cryptol.Eval: NoMatchingConstructor :: Maybe String -> EvalError
+ Cryptol.Eval: evalEnumCon :: Backend sym => sym -> Ident -> Int -> SEval sym (Vector (SEval sym (GenValue sym)) -> GenValue sym)
+ Cryptol.Eval: evalNominalDecls :: EvalPrims sym => sym -> Map Name NominalType -> GenEvalEnv sym -> SEval sym (GenEvalEnv sym)
+ Cryptol.Eval.Reference: VEnum :: Ident -> [E Value] -> Value
+ Cryptol.Eval.Type: ConInfo :: Ident -> Vector a -> ConInfo a
+ Cryptol.Eval.Type: TVEnum :: Vector (ConInfo TValue) -> TNominalTypeValue
+ Cryptol.Eval.Type: TVNominal :: NominalType -> [Either Nat' TValue] -> TNominalTypeValue -> TValue
+ Cryptol.Eval.Type: TVStruct :: RecordMap Ident TValue -> TNominalTypeValue
+ Cryptol.Eval.Type: [conFields] :: ConInfo a -> Vector a
+ Cryptol.Eval.Type: [conIdent] :: ConInfo a -> Ident
+ Cryptol.Eval.Type: data ConInfo a
+ Cryptol.Eval.Type: data TNominalTypeValue
+ Cryptol.Eval.Type: evalNominalTypeBody :: TypeEnv -> NominalType -> [Either Nat' TValue] -> TNominalTypeValue
+ Cryptol.Eval.Type: instance Control.DeepSeq.NFData Cryptol.Eval.Type.TNominalTypeValue
+ Cryptol.Eval.Type: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Cryptol.Eval.Type.ConInfo a)
+ Cryptol.Eval.Type: instance Data.Foldable.Foldable Cryptol.Eval.Type.ConInfo
+ Cryptol.Eval.Type: instance Data.Traversable.Traversable Cryptol.Eval.Type.ConInfo
+ Cryptol.Eval.Type: instance GHC.Base.Functor Cryptol.Eval.Type.ConInfo
+ Cryptol.Eval.Type: instance GHC.Classes.Eq Cryptol.Eval.Type.TNominalTypeValue
+ Cryptol.Eval.Type: instance GHC.Classes.Eq a => GHC.Classes.Eq (Cryptol.Eval.Type.ConInfo a)
+ Cryptol.Eval.Type: instance GHC.Generics.Generic (Cryptol.Eval.Type.ConInfo a)
+ Cryptol.Eval.Type: instance GHC.Generics.Generic Cryptol.Eval.Type.TNominalTypeValue
+ Cryptol.Eval.Type: isNullaryCon :: ConInfo a -> Bool
+ Cryptol.Eval.Type: zipConInfo :: (a -> b -> c) -> ConInfo a -> ConInfo b -> ConInfo c
+ Cryptol.Eval.Value: CaseCont :: Map Ident ([SEval sym (GenValue sym)] -> SEval sym (GenValue sym)) -> Maybe (SEval sym (GenValue sym)) -> CaseCont sym
+ Cryptol.Eval.Value: VEnum :: !SInteger sym -> !IntMap (ConValue sym) -> GenValue sym
+ Cryptol.Eval.Value: [caseCon] :: CaseCont sym -> Map Ident ([SEval sym (GenValue sym)] -> SEval sym (GenValue sym))
+ Cryptol.Eval.Value: [caseDflt] :: CaseCont sym -> Maybe (SEval sym (GenValue sym))
+ Cryptol.Eval.Value: caseValue :: Backend sym => sym -> SInteger sym -> IntMap (ConValue sym) -> CaseCont sym -> SEval sym (GenValue sym)
+ Cryptol.Eval.Value: data CaseCont sym
+ Cryptol.Eval.Value: fromVEnum :: GenValue sym -> (SInteger sym, IntMap (ConValue sym))
+ Cryptol.Eval.Value: ppValuePrec :: forall sym. Backend sym => sym -> PPOpts -> Int -> GenValue sym -> SEval sym Doc
+ Cryptol.Eval.Value: type ConValue sym = ConInfo (SEval sym (GenValue sym))
+ Cryptol.IR.FreeVars: instance Cryptol.IR.FreeVars.FreeVars Cryptol.TypeCheck.AST.CaseAlt
+ Cryptol.IR.FreeVars: instance Cryptol.IR.FreeVars.FreeVars Cryptol.TypeCheck.Type.EnumCon
+ Cryptol.IR.FreeVars: instance Cryptol.IR.FreeVars.FreeVars Cryptol.TypeCheck.Type.NominalType
+ Cryptol.IR.FreeVars: instance Cryptol.IR.FreeVars.FreeVars Cryptol.TypeCheck.Type.NominalTypeDef
+ Cryptol.IR.FreeVars: instance Cryptol.IR.FreeVars.FreeVars Cryptol.TypeCheck.Type.StructCon
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.AST.CaseAlt
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.Type.EnumCon
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.Type.NominalType
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.Type.NominalTypeDef
+ Cryptol.IR.TraverseNames: instance Cryptol.IR.TraverseNames.TraverseNames Cryptol.TypeCheck.Type.StructCon
+ Cryptol.ModuleSystem: [ifNominalTypes] :: IfaceDecls -> Map Name NominalType
+ Cryptol.ModuleSystem: [meEvalForeignPolicy] :: ModuleEnv -> EvalForeignPolicy
+ Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames (Cryptol.ModuleSystem.Binds.InModule (Cryptol.Parser.AST.EnumDecl Cryptol.Parser.Name.PName))
+ Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames (Cryptol.Parser.AST.Pattern Cryptol.Parser.Name.PName)
+ Cryptol.ModuleSystem.Binds: instance Cryptol.ModuleSystem.Binds.BindsNames Cryptol.ModuleSystem.NamingEnv.Types.NamingEnv
+ Cryptol.ModuleSystem.Binds: newFunctorInst :: FreshM m => ModPath -> Name -> m Name
+ Cryptol.ModuleSystem.Env: AlwaysEvalForeign :: EvalForeignPolicy
+ Cryptol.ModuleSystem.Env: NeverEvalForeign :: EvalForeignPolicy
+ Cryptol.ModuleSystem.Env: PreferEvalForeign :: EvalForeignPolicy
+ Cryptol.ModuleSystem.Env: [meEvalForeignPolicy] :: ModuleEnv -> EvalForeignPolicy
+ Cryptol.ModuleSystem.Env: data EvalForeignPolicy
+ Cryptol.ModuleSystem.Env: defaultEvalForeignPolicy :: EvalForeignPolicy
+ Cryptol.ModuleSystem.Env: instance GHC.Classes.Eq Cryptol.ModuleSystem.Env.EvalForeignPolicy
+ Cryptol.ModuleSystem.Env: loadedNominalTypes :: ModuleEnv -> Map Name NominalType
+ Cryptol.ModuleSystem.Exports: exportCon :: Ord name => TopLevel name -> ExportSpec name
+ Cryptol.ModuleSystem.Interface: [ifNominalTypes] :: IfaceDecls -> Map Name NominalType
+ Cryptol.ModuleSystem.Monad: getEvalForeignPolicy :: ModuleM EvalForeignPolicy
+ Cryptol.ModuleSystem.Monad: getNominalTypes :: ModuleM (Map Name NominalType)
+ Cryptol.ModuleSystem.Name: NSConstructor :: Namespace
+ Cryptol.ModuleSystem.Name: nameToDefPName :: Name -> PName
+ Cryptol.ModuleSystem.NamingEnv: modParamNamesNamingEnv :: ModParamNames -> NamingEnv
+ Cryptol.ModuleSystem.NamingEnv: modParamNamingEnv :: ModParam -> NamingEnv
+ Cryptol.ModuleSystem.NamingEnv.Types: NamingEnv :: Map Namespace (Map PName Names) -> NamingEnv
+ Cryptol.ModuleSystem.NamingEnv.Types: consToValues :: NamingEnv -> NamingEnv
+ Cryptol.ModuleSystem.NamingEnv.Types: instance Control.DeepSeq.NFData Cryptol.ModuleSystem.NamingEnv.Types.NamingEnv
+ Cryptol.ModuleSystem.NamingEnv.Types: instance Cryptol.Utils.PP.PP Cryptol.ModuleSystem.NamingEnv.Types.NamingEnv
+ Cryptol.ModuleSystem.NamingEnv.Types: instance GHC.Base.Monoid Cryptol.ModuleSystem.NamingEnv.Types.NamingEnv
+ Cryptol.ModuleSystem.NamingEnv.Types: instance GHC.Base.Semigroup Cryptol.ModuleSystem.NamingEnv.Types.NamingEnv
+ Cryptol.ModuleSystem.NamingEnv.Types: instance GHC.Generics.Generic Cryptol.ModuleSystem.NamingEnv.Types.NamingEnv
+ Cryptol.ModuleSystem.NamingEnv.Types: instance GHC.Show.Show Cryptol.ModuleSystem.NamingEnv.Types.NamingEnv
+ Cryptol.ModuleSystem.NamingEnv.Types: newtype NamingEnv
+ Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Renamer.Rename Cryptol.Parser.AST.BindImpl
+ Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Renamer.Rename Cryptol.Parser.AST.CaseAlt
+ Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Renamer.Rename Cryptol.Parser.AST.EnumDecl
+ Cryptol.Parser.AST: CaseAlt :: Pattern n -> Expr n -> CaseAlt n
+ Cryptol.Parser.AST: DImpl :: BindImpl name -> BindDef name
+ Cryptol.Parser.AST: ECase :: Expr n -> [CaseAlt n] -> Expr n
+ Cryptol.Parser.AST: EnumCon :: Located name -> [Type name] -> EnumCon name
+ Cryptol.Parser.AST: EnumDecl :: Located name -> [TParam name] -> [TopLevel (EnumCon name)] -> EnumDecl name
+ Cryptol.Parser.AST: PCon :: Located n -> [Pattern n] -> Pattern n
+ Cryptol.Parser.AST: TDEnum :: TopLevel (EnumDecl name) -> TopDecl name
+ Cryptol.Parser.AST: [eCons] :: EnumDecl name -> [TopLevel (EnumCon name)]
+ Cryptol.Parser.AST: [eName] :: EnumDecl name -> Located name
+ Cryptol.Parser.AST: [eParams] :: EnumDecl name -> [TParam name]
+ Cryptol.Parser.AST: [ecFields] :: EnumCon name -> [Type name]
+ Cryptol.Parser.AST: [ecName] :: EnumCon name -> Located name
+ Cryptol.Parser.AST: [mInScope] :: ModuleG mname name -> NamingEnv
+ Cryptol.Parser.AST: bindImpl :: Bind name -> Maybe (BindImpl name)
+ Cryptol.Parser.AST: data BindImpl name
+ Cryptol.Parser.AST: data CaseAlt n
+ Cryptol.Parser.AST: data EnumCon name
+ Cryptol.Parser.AST: data EnumDecl name
+ Cryptol.Parser.AST: exprDef :: Expr name -> BindDef name
+ Cryptol.Parser.AST: impNameModPath :: ImpName Name -> ModPath
+ Cryptol.Parser.AST: instance (GHC.Show.Show name, Cryptol.Utils.PP.PPName name) => Cryptol.Utils.PP.PP (Cryptol.Parser.AST.BindImpl name)
+ Cryptol.Parser.AST: instance (GHC.Show.Show name, Cryptol.Utils.PP.PPName name) => Cryptol.Utils.PP.PP (Cryptol.Parser.AST.CaseAlt name)
+ Cryptol.Parser.AST: instance (GHC.Show.Show name, Cryptol.Utils.PP.PPName name) => Cryptol.Utils.PP.PP (Cryptol.Parser.AST.EnumCon name)
+ Cryptol.Parser.AST: instance (GHC.Show.Show name, Cryptol.Utils.PP.PPName name) => Cryptol.Utils.PP.PP (Cryptol.Parser.AST.EnumDecl name)
+ Cryptol.Parser.AST: instance Control.DeepSeq.NFData n => Control.DeepSeq.NFData (Cryptol.Parser.AST.CaseAlt n)
+ Cryptol.Parser.AST: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (Cryptol.Parser.AST.BindImpl name)
+ Cryptol.Parser.AST: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (Cryptol.Parser.AST.EnumCon name)
+ Cryptol.Parser.AST: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (Cryptol.Parser.AST.EnumDecl name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.AST.NoPos (Cryptol.Parser.AST.CaseAlt name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.AST.NoPos (Cryptol.Parser.AST.EnumCon name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.AST.NoPos (Cryptol.Parser.AST.EnumDecl name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.Position.HasLoc (Cryptol.Parser.AST.EnumCon name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.Position.HasLoc (Cryptol.Parser.AST.EnumDecl name)
+ Cryptol.Parser.AST: instance GHC.Base.Functor Cryptol.Parser.AST.BindImpl
+ Cryptol.Parser.AST: instance GHC.Base.Functor Cryptol.Parser.AST.CaseAlt
+ Cryptol.Parser.AST: instance GHC.Classes.Eq n => GHC.Classes.Eq (Cryptol.Parser.AST.CaseAlt n)
+ Cryptol.Parser.AST: instance GHC.Classes.Eq name => GHC.Classes.Eq (Cryptol.Parser.AST.BindImpl name)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.BindImpl name)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.CaseAlt n)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.EnumCon name)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.EnumDecl name)
+ Cryptol.Parser.AST: instance GHC.Show.Show n => GHC.Show.Show (Cryptol.Parser.AST.CaseAlt n)
+ Cryptol.Parser.AST: instance GHC.Show.Show name => GHC.Show.Show (Cryptol.Parser.AST.BindImpl name)
+ Cryptol.Parser.AST: instance GHC.Show.Show name => GHC.Show.Show (Cryptol.Parser.AST.EnumCon name)
+ Cryptol.Parser.AST: instance GHC.Show.Show name => GHC.Show.Show (Cryptol.Parser.AST.EnumDecl name)
+ Cryptol.Parser.Lexer: KW_case :: TokenKW
+ Cryptol.Parser.Lexer: KW_enum :: TokenKW
+ Cryptol.Parser.Lexer: KW_of :: TokenKW
+ Cryptol.Parser.Name: origNameToDefPName :: OrigName -> PName
+ Cryptol.Parser.Names: namesEnum :: EnumDecl name -> ([Located name], ())
+ Cryptol.Parser.Names: namesP' :: Ord name => Pattern name -> [Located name]
+ Cryptol.Parser.Names: tnamesEnum :: EnumDecl name -> ([Located name], ())
+ Cryptol.Parser.NoPat: InvalidConstructorPattern :: Range -> Error
+ Cryptol.Parser.NoPat: instance GHC.Base.Semigroup Cryptol.Parser.NoPat.AnnForeign
+ Cryptol.Parser.Token: KW_case :: TokenKW
+ Cryptol.Parser.Token: KW_enum :: TokenKW
+ Cryptol.Parser.Token: KW_of :: TokenKW
+ Cryptol.Symbolic: FEnum :: Vector (ConInfo FinType) -> FinNominalType
+ Cryptol.Symbolic: FStruct :: RecordMap Ident FinType -> FinNominalType
+ Cryptol.Symbolic: FTNominal :: NominalType -> [Either Nat' TValue] -> FinNominalType -> FinType
+ Cryptol.Symbolic: VarEnum :: SInteger sym -> Vector (ConInfo (VarShape sym)) -> VarShape sym
+ Cryptol.Symbolic: data FinNominalType
+ Cryptol.Transform.Specialize: specializeCaseAlt :: CaseAlt -> SpecM CaseAlt
+ Cryptol.TypeCheck: EnumTypeMismatch :: Type -> Error
+ Cryptol.TypeCheck: InvalidConPat :: Int -> Int -> Error
+ Cryptol.TypeCheck: OverlappingPat :: Maybe Ident -> [Range] -> Error
+ Cryptol.TypeCheck: UncoveredConPat :: [Name] -> Error
+ Cryptol.TypeCheck: [inpNominalTypes] :: InferInput -> Map Name NominalType
+ Cryptol.TypeCheck.AST: CaseAlt :: [(Name, Type)] -> Expr -> CaseAlt
+ Cryptol.TypeCheck.AST: ECase :: Expr -> Map Ident CaseAlt -> Maybe CaseAlt -> Expr
+ Cryptol.TypeCheck.AST: [mInScope] :: ModuleG mname -> NamingEnv
+ Cryptol.TypeCheck.AST: [mNominalTypes] :: ModuleG mname -> Map Name NominalType
+ Cryptol.TypeCheck.AST: data CaseAlt
+ Cryptol.TypeCheck.AST: instance Control.DeepSeq.NFData Cryptol.TypeCheck.AST.CaseAlt
+ Cryptol.TypeCheck.AST: instance Cryptol.Utils.PP.PP Cryptol.TypeCheck.AST.CaseAlt
+ Cryptol.TypeCheck.AST: instance GHC.Generics.Generic Cryptol.TypeCheck.AST.CaseAlt
+ Cryptol.TypeCheck.AST: instance GHC.Show.Show Cryptol.TypeCheck.AST.CaseAlt
+ Cryptol.TypeCheck.Error: EnumTypeMismatch :: Type -> Error
+ Cryptol.TypeCheck.Error: InvalidConPat :: Int -> Int -> Error
+ Cryptol.TypeCheck.Error: OverlappingPat :: Maybe Ident -> [Range] -> Error
+ Cryptol.TypeCheck.Error: UncoveredConPat :: [Name] -> Error
+ Cryptol.TypeCheck.Instantiate: instantiatePCon :: Name -> InferM ([Type], Int, [Type], Type)
+ Cryptol.TypeCheck.Kind: checkEnum :: EnumDecl Name -> Maybe Text -> InferM NominalType
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.AddParams Cryptol.TypeCheck.Type.NominalType
+ Cryptol.TypeCheck.ModuleBacktickInstance: instance Cryptol.TypeCheck.ModuleBacktickInstance.RewVal Cryptol.TypeCheck.AST.CaseAlt
+ Cryptol.TypeCheck.ModuleInstance: doInst :: (Su, TVars a, TraverseNames a) => a -> a
+ Cryptol.TypeCheck.ModuleInstance: doNameInst :: (Su, TraverseNames a) => a -> a
+ Cryptol.TypeCheck.ModuleInstance: doTVarInst :: (Su, TVars a) => a -> a
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.ModuleSystem.NamingEnv.Types.NamingEnv
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.TypeCheck.Type.EnumCon
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.TypeCheck.Type.NominalType
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.TypeCheck.Type.NominalTypeDef
+ Cryptol.TypeCheck.ModuleInstance: instance Cryptol.TypeCheck.ModuleInstance.ModuleInstance Cryptol.TypeCheck.Type.StructCon
+ Cryptol.TypeCheck.Monad: [inpNominalTypes] :: InferInput -> Map Name NominalType
+ Cryptol.TypeCheck.Monad: addNominal :: NominalType -> InferM ()
+ Cryptol.TypeCheck.Monad: getNominalTypes :: InferM (Map Name NominalType)
+ Cryptol.TypeCheck.Monad: kLookupNominal :: Name -> KindM (Maybe NominalType)
+ Cryptol.TypeCheck.Monad: lookupNominal :: Name -> InferM (Maybe NominalType)
+ Cryptol.TypeCheck.Parseable: instance Cryptol.TypeCheck.Parseable.ShowParseable Cryptol.TypeCheck.AST.CaseAlt
+ Cryptol.TypeCheck.Sanity: BadCase :: Maybe Type -> Error
+ Cryptol.TypeCheck.Sanity: BadCaseAlt :: Maybe Ident -> Error
+ Cryptol.TypeCheck.Subst: instance Cryptol.TypeCheck.Subst.TVars Cryptol.TypeCheck.AST.CaseAlt
+ Cryptol.TypeCheck.Type: Abstract :: NominalTypeDef
+ Cryptol.TypeCheck.Type: CasedExpression :: TypeSource
+ Cryptol.TypeCheck.Type: ConPat :: TypeSource
+ Cryptol.TypeCheck.Type: Enum :: [EnumCon] -> NominalTypeDef
+ Cryptol.TypeCheck.Type: EnumCon :: Name -> !Int -> [Type] -> Bool -> Maybe Text -> EnumCon
+ Cryptol.TypeCheck.Type: NominalType :: Name -> [TParam] -> !Kind -> [Prop] -> NominalTypeDef -> !Maybe Fixity -> Maybe Text -> NominalType
+ Cryptol.TypeCheck.Type: Struct :: StructCon -> NominalTypeDef
+ Cryptol.TypeCheck.Type: StructCon :: !Name -> RecordMap Ident Type -> StructCon
+ Cryptol.TypeCheck.Type: TNominal :: !NominalType -> ![Type] -> Type
+ Cryptol.TypeCheck.Type: TPNominalParam :: Name -> TPFlavor
+ Cryptol.TypeCheck.Type: [ecDoc] :: EnumCon -> Maybe Text
+ Cryptol.TypeCheck.Type: [ecFields] :: EnumCon -> [Type]
+ Cryptol.TypeCheck.Type: [ecName] :: EnumCon -> Name
+ Cryptol.TypeCheck.Type: [ecNumber] :: EnumCon -> !Int
+ Cryptol.TypeCheck.Type: [ecPublic] :: EnumCon -> Bool
+ Cryptol.TypeCheck.Type: [ntDef] :: NominalType -> NominalTypeDef
+ Cryptol.TypeCheck.Type: [ntFixity] :: NominalType -> !Maybe Fixity
+ Cryptol.TypeCheck.Type: [ntKind] :: NominalType -> !Kind
+ Cryptol.TypeCheck.Type: data EnumCon
+ Cryptol.TypeCheck.Type: data NominalType
+ Cryptol.TypeCheck.Type: data NominalTypeDef
+ Cryptol.TypeCheck.Type: data StructCon
+ Cryptol.TypeCheck.Type: instance Control.DeepSeq.NFData Cryptol.TypeCheck.Type.EnumCon
+ Cryptol.TypeCheck.Type: instance Control.DeepSeq.NFData Cryptol.TypeCheck.Type.NominalType
+ Cryptol.TypeCheck.Type: instance Control.DeepSeq.NFData Cryptol.TypeCheck.Type.NominalTypeDef
+ Cryptol.TypeCheck.Type: instance Control.DeepSeq.NFData Cryptol.TypeCheck.Type.StructCon
+ Cryptol.TypeCheck.Type: instance Cryptol.TypeCheck.TCon.HasKind Cryptol.TypeCheck.Type.NominalType
+ Cryptol.TypeCheck.Type: instance Cryptol.Utils.PP.PP (Cryptol.TypeCheck.PP.WithNames Cryptol.TypeCheck.Type.NominalType)
+ Cryptol.TypeCheck.Type: instance Cryptol.Utils.PP.PP Cryptol.TypeCheck.Type.NominalType
+ Cryptol.TypeCheck.Type: instance GHC.Classes.Eq Cryptol.TypeCheck.Type.NominalType
+ Cryptol.TypeCheck.Type: instance GHC.Classes.Ord Cryptol.TypeCheck.Type.NominalType
+ Cryptol.TypeCheck.Type: instance GHC.Generics.Generic Cryptol.TypeCheck.Type.EnumCon
+ Cryptol.TypeCheck.Type: instance GHC.Generics.Generic Cryptol.TypeCheck.Type.NominalType
+ Cryptol.TypeCheck.Type: instance GHC.Generics.Generic Cryptol.TypeCheck.Type.NominalTypeDef
+ Cryptol.TypeCheck.Type: instance GHC.Generics.Generic Cryptol.TypeCheck.Type.StructCon
+ Cryptol.TypeCheck.Type: instance GHC.Show.Show Cryptol.TypeCheck.Type.EnumCon
+ Cryptol.TypeCheck.Type: instance GHC.Show.Show Cryptol.TypeCheck.Type.NominalType
+ Cryptol.TypeCheck.Type: instance GHC.Show.Show Cryptol.TypeCheck.Type.NominalTypeDef
+ Cryptol.TypeCheck.Type: instance GHC.Show.Show Cryptol.TypeCheck.Type.StructCon
+ Cryptol.TypeCheck.Type: nominalParam :: Name -> TPFlavor
+ Cryptol.TypeCheck.Type: nominalTypeConTypes :: NominalType -> [(Name, Schema)]
+ Cryptol.TypeCheck.Type: nominalTypeIsAbstract :: NominalType -> Bool
+ Cryptol.TypeCheck.Type: ppNominalFull :: NominalType -> Doc
+ Cryptol.TypeCheck.Type: ppNominalShort :: NominalType -> Doc
+ Cryptol.TypeCheck.Type: primParam :: Name -> TPFlavor
+ Cryptol.TypeCheck.Type: tNominal :: NominalType -> [Type] -> Type
+ Cryptol.TypeCheck.TypeMap: [tnominal] :: TypeMap a -> Map NominalType (List TypeMap a)
+ Cryptol.TypeCheck.Unify: TNominalArg :: NominalType -> Int -> PathElement
+ Cryptol.Utils.Ident: NSConstructor :: Namespace
+ Cryptol.Utils.Ident: [ogFromParam] :: OrigName -> !Maybe Ident
+ Cryptol.Utils.Ident: identToModName :: Ident -> ModName
+ Cryptol.Utils.Ident: isUpperIdent :: Ident -> Bool
+ Cryptol.Utils.Ident: ogIsModParam :: OrigName -> Bool
+ Cryptol.Version: ffiEnabled :: Bool
- Cryptol.Backend.FFI: foreignLibPath :: FilePath -> IO (Maybe FilePath)
+ Cryptol.Backend.FFI: foreignLibPath :: FilePath -> IO (Maybe (FilePath, Bool))
- Cryptol.Eval.FFI: evalForeignDecls :: ForeignSrc -> [(Name, FFIFunType)] -> EvalEnv -> Eval (Either [FFILoadError] EvalEnv)
+ Cryptol.Eval.FFI: evalForeignDecls :: ForeignSrc -> [(Name, FFIFunType)] -> EvalEnv -> Eval ([FFILoadError], EvalEnv)
- Cryptol.Eval.Type: TVAbstract :: UserTC -> [Either Nat' TValue] -> TValue
+ Cryptol.Eval.Type: TVAbstract :: TNominalTypeValue
- 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: IfaceDecls :: Map Name TySyn -> Map Name NominalType -> Map Name IfaceDecl -> !Map Name (IfaceNames Name) -> !Map Name ModParamNames -> !Map Name (IfaceG Name) -> IfaceDecls
- Cryptol.ModuleSystem: ModuleEnv :: LoadedModules -> NameSeeds -> EvalEnv -> CoreLint -> !Bool -> Maybe ModName -> [FilePath] -> DynamicEnv -> !Supply -> ModuleEnv
+ Cryptol.ModuleSystem: ModuleEnv :: LoadedModules -> NameSeeds -> EvalEnv -> CoreLint -> !Bool -> Maybe ModName -> [FilePath] -> DynamicEnv -> !Supply -> EvalForeignPolicy -> ModuleEnv
- Cryptol.ModuleSystem.Env: FileInfo :: Fingerprint -> Set FilePath -> Set ModName -> Set FilePath -> FileInfo
+ Cryptol.ModuleSystem.Env: FileInfo :: Fingerprint -> Set FilePath -> Set ModName -> Map FilePath Bool -> FileInfo
- Cryptol.ModuleSystem.Env: ModuleEnv :: LoadedModules -> NameSeeds -> EvalEnv -> CoreLint -> !Bool -> Maybe ModName -> [FilePath] -> DynamicEnv -> !Supply -> ModuleEnv
+ Cryptol.ModuleSystem.Env: ModuleEnv :: LoadedModules -> NameSeeds -> EvalEnv -> CoreLint -> !Bool -> Maybe ModName -> [FilePath] -> DynamicEnv -> !Supply -> EvalForeignPolicy -> ModuleEnv
- Cryptol.ModuleSystem.Env: [fiForeignDeps] :: FileInfo -> Set FilePath
+ Cryptol.ModuleSystem.Env: [fiForeignDeps] :: FileInfo -> Map FilePath Bool
- 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: IfaceDecls :: Map Name TySyn -> Map Name NominalType -> Map Name IfaceDecl -> !Map Name (IfaceNames Name) -> !Map Name ModParamNames -> !Map Name (IfaceG Name) -> IfaceDecls
- Cryptol.ModuleSystem.Renamer: RenamedModule :: Module Name -> NamingEnv -> NamingEnv -> IfaceDecls -> RenamedModule
+ Cryptol.ModuleSystem.Renamer: RenamedModule :: Module Name -> NamingEnv -> IfaceDecls -> RenamedModule
- Cryptol.Parser.AST: DExpr :: Expr name -> BindDef name
+ Cryptol.Parser.AST: DExpr :: Expr name -> BindImpl name
- Cryptol.Parser.AST: DForeign :: BindDef name
+ Cryptol.Parser.AST: DForeign :: Maybe (BindImpl name) -> BindDef name
- Cryptol.Parser.AST: DPropGuards :: [PropGuardCase name] -> BindDef name
+ Cryptol.Parser.AST: DPropGuards :: [PropGuardCase name] -> BindImpl name
- Cryptol.Parser.AST: Module :: Located mname -> ModuleDefinition name -> ModuleG mname name
+ Cryptol.Parser.AST: Module :: Located mname -> ModuleDefinition name -> NamingEnv -> ModuleG mname name
- Cryptol.Parser.Names: namesP :: Pattern name -> [Located name]
+ Cryptol.Parser.Names: namesP :: Ord name => Pattern name -> ([Located name], Set name)
- 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: InferInput :: Range -> Map Name Schema -> Map Name TySyn -> Map Name NominalType -> !Map Name ModParamNames -> (ModName -> Maybe (ModuleG (), IfaceG ())) -> (ModName -> Maybe ModParamNames) -> !ModParamNames -> NameSeeds -> Bool -> Bool -> [FilePath] -> !PrimMap -> !Supply -> Solver -> InferInput
- Cryptol.TypeCheck.AST: DForeign :: FFIFunType -> DeclDef
+ Cryptol.TypeCheck.AST: DForeign :: FFIFunType -> Maybe Expr -> DeclDef
- 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.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 NominalType -> [DeclGroup] -> Map Name (IfaceNames Name) -> !Map Name ModParamNames -> NamingEnv -> ModuleG mname
- Cryptol.TypeCheck.Kind: checkNewtype :: Newtype Name -> Maybe Text -> InferM Newtype
+ Cryptol.TypeCheck.Kind: checkNewtype :: Newtype Name -> Maybe Text -> InferM NominalType
- Cryptol.TypeCheck.Kind: checkPrimType :: PrimType Name -> Maybe Text -> InferM AbstractType
+ Cryptol.TypeCheck.Kind: checkPrimType :: PrimType Name -> Maybe Text -> InferM NominalType
- Cryptol.TypeCheck.Module: doFunctorInst :: Located (ImpName Name) -> Located (ImpName Name) -> ModuleInstanceArgs Name -> Map Name Name -> Maybe Text -> InferM (Maybe TCTopEntity)
+ Cryptol.TypeCheck.Module: doFunctorInst :: Located (ImpName Name) -> Located (ImpName Name) -> ModuleInstanceArgs Name -> Map Name Name -> NamingEnv -> Maybe Text -> InferM (Maybe TCTopEntity)
- Cryptol.TypeCheck.ModuleInstance: type Su = (?tSu :: Subst, ?vSu :: Map Name Name)
+ Cryptol.TypeCheck.ModuleInstance: type Su = (?tVarSu :: Subst, ?nameSu :: Map Name Name)
- 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: InferInput :: Range -> Map Name Schema -> Map Name TySyn -> Map Name NominalType -> !Map Name ModParamNames -> (ModName -> Maybe (ModuleG (), IfaceG ())) -> (ModName -> Maybe ModParamNames) -> !ModParamNames -> NameSeeds -> Bool -> Bool -> [FilePath] -> !PrimMap -> !Supply -> Solver -> InferInput
- Cryptol.TypeCheck.Monad: newModuleScope :: ModName -> ExportSpec Name -> InferM ()
+ Cryptol.TypeCheck.Monad: newModuleScope :: ModName -> ExportSpec Name -> NamingEnv -> InferM ()
- Cryptol.TypeCheck.Monad: newSubmoduleScope :: Name -> Maybe Text -> ExportSpec Name -> InferM ()
+ Cryptol.TypeCheck.Monad: newSubmoduleScope :: Name -> Maybe Text -> ExportSpec Name -> NamingEnv -> InferM ()
- Cryptol.TypeCheck.Type: [ntConName] :: Newtype -> !Name
+ Cryptol.TypeCheck.Type: [ntConName] :: StructCon -> !Name
- Cryptol.TypeCheck.Type: [ntConstraints] :: Newtype -> [Prop]
+ Cryptol.TypeCheck.Type: [ntConstraints] :: NominalType -> [Prop]
- Cryptol.TypeCheck.Type: [ntDoc] :: Newtype -> Maybe Text
+ Cryptol.TypeCheck.Type: [ntDoc] :: NominalType -> Maybe Text
- Cryptol.TypeCheck.Type: [ntFields] :: Newtype -> RecordMap Ident Type
+ Cryptol.TypeCheck.Type: [ntFields] :: StructCon -> RecordMap Ident Type
- Cryptol.TypeCheck.Type: [ntName] :: Newtype -> Name
+ Cryptol.TypeCheck.Type: [ntName] :: NominalType -> Name
- Cryptol.TypeCheck.Type: [ntParams] :: Newtype -> [TParam]
+ Cryptol.TypeCheck.Type: [ntParams] :: NominalType -> [TParam]
- Cryptol.TypeCheck.TypeMap: TM :: Map TVar a -> Map TCon (List TypeMap a) -> Map [Ident] (List TypeMap a) -> Map Newtype (List TypeMap a) -> TypeMap a
+ Cryptol.TypeCheck.TypeMap: TM :: Map TVar a -> Map TCon (List TypeMap a) -> Map [Ident] (List TypeMap a) -> Map NominalType (List TypeMap a) -> TypeMap a
- Cryptol.Utils.Ident: FromModParam :: Ident -> OrigSource
+ Cryptol.Utils.Ident: FromModParam :: OrigSource
- Cryptol.Utils.Ident: OrigName :: Namespace -> ModPath -> OrigSource -> Ident -> OrigName
+ Cryptol.Utils.Ident: OrigName :: Namespace -> ModPath -> OrigSource -> Ident -> !Maybe Ident -> OrigName
- Cryptol.Utils.Panic: data Panic a
+ Cryptol.Utils.Panic: data () => Panic a

Files

CHANGES.md view
@@ -1,3 +1,49 @@+# 3.1.0 -- 2024-02-05++## Language changes++* Cryptol now supports *enum* declarations. An enum is a named typed which is+  defined by one or more constructors. Enums correspond to the notion of+  algebraic data types, which are commonly found in other programming+  languages.  See the [manual+  section](https://galoisinc.github.io/cryptol/master/TypeDeclarations.html#enums)+  for more information.++* Add two enum declarations to the Cryptol standard library:++  ```+  enum Option a = None | Some a++  enum Result t e = Ok t | Err e+  ```++  These types are useful for representing optional values (`Option`) or values+  that may fail in some way (`Result`).++* `foreign` functions can now have an optional Cryptol implementation, which by+  default is used when the foreign implementation cannot be found, or if the FFI+  is unavailable. The `:set evalForeign` REPL option controls this behavior.++## Bug fixes++* Fixed #1455, making anything in scope of the functor in scope at the REPL as+  well when an instantiation of the functor is loaded and focused, design+  choice (3) on the ticket.  In particular, the prelude will be in scope.++* Fix #1578, which caused `parmap` to crash when evaluated on certain types of+  sequences.++* Closed issues #813, #1237, #1397, #1446, #1486, #1492, #1495, #1537,+  #1538, #1542, #1544, #1548, #1551, #1552, #1554, #1556, #1561, #1562, #1566,+  #1567, #1569, #1571, #1584, #1588, #1590, #1598, #1599, #1604, #1605, #1606,+  #1607, #1609, #1610, #1611, #1612, #1613, #1615, #1616, #1617, #1618, and+  #1619.++* Merged pull requests #1429, #1512, #1534, #1535, #1536, #1540, #1541, #1543,+  #1547, #1549, #1550, #1555, #1557, #1558, #1559, #1564, #1565, #1568, #1570,+  #1572, #1573, #1577, #1579, #1580, #1583, #1585, #1586, #1592, #1600, #1601,+  and #1602.+ # 3.0.0 -- 2023-06-26  ## Language changes@@ -22,11 +68,11 @@  * 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))+  type parameters.  See this [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)+  call functions written in C. See this [manual section](https://galoisinc.github.io/cryptol/master/FFI.html)   for more information.  * The unary `-` operator now has the same precedence as binary `-`, meaning
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2013-2020 Galois Inc.+Copyright (c) 2013-2023 Galois Inc. All rights reserved.  Redistribution and use in source and binary forms, with or without
cryptol.cabal view
@@ -1,6 +1,6 @@ Cabal-version:       2.4 Name:                cryptol-Version:             3.0.0+Version:             3.1.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@@ -27,7 +27,7 @@   type:     git   location: https://github.com/GaloisInc/cryptol.git   -- add a tag on release branches-  tag:      3.0.0+  tag:      3.1.0   flag static@@ -74,7 +74,7 @@                        prettyprinter     >= 1.7.0,                        pretty-show,                        process           >= 1.2,-                       sbv               >= 9.1 && < 10.2,+                       sbv               >= 9.1 && < 10.3,                        simple-smt        >= 0.9.7,                        stm               >= 2.4,                        strict,@@ -85,7 +85,7 @@                        mtl               >= 2.2.1,                        time              >= 1.6.0.1,                        panic             >= 0.3,-                       what4             >= 1.4 && < 1.5+                       what4             >= 1.4 && < 1.6    if impl(ghc >= 9.0)     build-depends:     ghc-bignum        >= 1.0 && < 1.4@@ -141,6 +141,7 @@                        Cryptol.ModuleSystem.Name,                        Cryptol.ModuleSystem.Names,                        Cryptol.ModuleSystem.NamingEnv,+                       Cryptol.ModuleSystem.NamingEnv.Types,                        Cryptol.ModuleSystem.Binds                        Cryptol.ModuleSystem.Exports,                        Cryptol.ModuleSystem.Renamer,
cryptol/CheckExercises.hs view
@@ -5,7 +5,8 @@  module Main(main) where -import Control.Monad.State+import Control.Monad (forM_, when)+import Control.Monad.State (State, execState, gets, modify, modify') import Options.Applicative import Data.Char (isSpace, isAlpha) import Data.Foldable (traverse_)
lib/Cryptol.cry view
@@ -633,6 +633,25 @@ (>=$) : {a} (SignedCmp a) => a -> a -> Bit x >=$ y = ~(x <$ y) +// The Option and Result types ------------------------------------++/**+ * The 'Option a' type represents an optional value. Every 'Option a' value is+ * either 'Some' and contains a value of type 'a', or 'None' and does not. Among+ * other uses, optional values are useful for modeling return values for partial+ * functions, i.e., functions that are not defined over their entire input+ * range. In these situations, 'None' can be used as a placeholder return value.+ */+enum Option a = None | Some a++/**+ * Values of the 'Result t e' type can either be 'Ok', representing success and+ * containing a value of type 't', or 'Err', representing error and containing+ * an error value of type 'e'. Functions can return 'Result' whenever errors are+ * expected and recoverable. For instance, 'e' might be a 'String' with an error+ * message, or it might be an 'Integer' with an error code.+ */+enum Result t e = Ok t | Err e  // Bit specific operations ---------------------------------------- 
src/Cryptol/Backend/FFI.hs view
@@ -6,6 +6,7 @@ {-# LANGUAGE LambdaCase                #-} {-# LANGUAGE RecordWildCards           #-} {-# LANGUAGE ScopedTypeVariables       #-}+{-# LANGUAGE TupleSections             #-} {-# LANGUAGE TypeApplications          #-}  -- | The implementation of loading and calling external functions from shared@@ -37,15 +38,16 @@ import           Control.Exception import           Control.Monad import           Data.Bifunctor+import           Data.Maybe import           Data.Word import           Foreign                    hiding (newForeignPtr) import           Foreign.C.Types import           Foreign.Concurrent import           Foreign.LibFFI+import           System.Directory           (canonicalizePath, doesFileExist) import           System.FilePath            ((-<.>))-import           System.Directory(doesFileExist)+import           System.Info                (os) import           System.IO.Error-import           System.Info(os)  #if defined(mingw32_HOST_OS) import           System.Win32.DLL@@ -98,32 +100,35 @@   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+-- | Given the path to a Cryptol module, compute the location of the shared+-- library we'd like to load. If FFI is supported, returns the location and+-- whether or not it actually exists on disk. Otherwise, returns Nothing.+foreignLibPath :: FilePath -> IO (Maybe (FilePath, Bool))+foreignLibPath path = do+  path' <- canonicalizePath path+  let libPaths = map (path' -<.>) exts+      search ps =+        case ps of+          [] -> pure ((, False) <$> listToMaybe libPaths)+          p : more -> do+            yes <- doesFileExist p+            if yes then pure (Just (p, True)) else search more+  search libPaths+  where+  exts =     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)+       Just (libPath, True) ->+         tryLoad (CantLoadFFISrc path) (open libPath)+       _ ->+         pure (Left (CantLoadFFISrc path "File not found"))    where open libPath = do #if defined(mingw32_HOST_OS)@@ -272,5 +277,8 @@  unloadForeignSrc :: ForeignSrc -> IO () unloadForeignSrc _ = pure ()++foreignLibPath :: FilePath -> IO (Maybe (FilePath, Bool))+foreignLibPath _ = pure Nothing  #endif
src/Cryptol/Backend/FFI/Error.hs view
@@ -30,10 +30,12 @@         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)+      CantLoadFFIImpl name _msg ->+        "Could not load foreign implementation for binding" <+> text name+        -- We don't print the OS error message for more consistent test output+        -- 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))) <+>
src/Cryptol/Backend/Monad.hs view
@@ -422,6 +422,7 @@   | 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.+  | NoMatchingConstructor (Maybe String) -- ^ Missing `case` alternative   | FFINotSupported Name                 -- ^ Foreign function cannot be called   | FFITypeNumTooBig Name TParam Integer -- ^ Number passed to foreign function                                          --   as a type argument is too large@@ -447,15 +448,20 @@     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."+      , text "No foreign implementation is loaded,"+      , text "  or FFI calls are not supported in this context."       ]     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`" ]+    NoMatchingConstructor mbCon -> vcat+      [ "Missing `case` alternative" <+> con <.> "."+      ]+      where con = case mbCon of+                    Just c -> "for constructor" <+> backticks (text c)+                    Nothing -> mempty  instance Show EvalError where   show = show . pp
src/Cryptol/Backend/SeqMap.hs view
@@ -72,8 +72,9 @@                  !(SeqMap sym a)   | MemoSeqMap      !Nat'-     !(IORef (Map Integer a))-     !(IORef (Integer -> SEval sym a))+     !(IORef (Map Integer a, Integer -> SEval sym a))+     !(Integer -> SEval sym a)+      -- Use this to overwrite the evaluation function when the cache is full  indexSeqMap :: (Integer -> SEval sym a) -> SeqMap sym a indexSeqMap = IndexSeqMap@@ -84,21 +85,23 @@   case Map.lookup i m of     Just x  -> x     Nothing -> lookupSeqMap xs i-lookupSeqMap (MemoSeqMap sz cache eval) i =-  do mz <- liftIO (Map.lookup i <$> readIORef cache)-     case mz of-       Just z  -> return z++lookupSeqMap (MemoSeqMap sz cache_eval evalPanic) i =+  do (cache,eval) <- liftIO (readIORef cache_eval)+     case Map.lookup i cache of+       Just z -> pure z        Nothing ->-         do f <- liftIO (readIORef eval)-            v <- f i-            msz <- liftIO $ atomicModifyIORef' cache (\m ->-                        let m' = Map.insert i v m in (m', Map.size m'))-            -- If we memoize the entire map, overwrite the evaluation closure to let-            -- the garbage collector reap it-            when (case sz of Inf -> False; Nat sz' -> toInteger msz >= sz')-                 (liftIO (writeIORef eval-                    (\j -> panic "lookupSeqMap" ["Messed up size accounting", show sz, show j])))-            return v+        do v <- eval i+           liftIO $ atomicModifyIORef' cache_eval $ \(oldCache,oldFun) ->+             let !newCache = Map.insert i v oldCache+                 -- If we memoize the entire map,+                 -- overwrite the evaluation closure to let+                 -- the garbage collector reap it+                 !newEval =+                   case sz of+                     Nat sz' | toInteger (Map.size newCache) >= sz' -> evalPanic+                     _ -> oldFun+             in ((newCache, newEval), v)  instance Backend sym => Functor (SeqMap sym) where   fmap f xs = IndexSeqMap (\i -> f <$> lookupSeqMap xs i)@@ -173,12 +176,20 @@  memoMap sym sz x = do   stk <- sGetCallStack sym-  cache <- liftIO $ newIORef $ Map.empty-  evalRef <- liftIO $ newIORef $ eval stk-  return (MemoSeqMap sz cache evalRef)+  cache <- liftIO $ newIORef (Map.empty, eval stk)+  return (MemoSeqMap sz cache evalPanic)    where     eval stk i = sWithCallStack sym stk (lookupSeqMap x i)++    -- Not 100% sure that we actually need to do the bounds check here,+    -- or if we are assuming that the argument would be in bounds, but+    -- it doesn't really hurt to do it, as if we *did* already do the check+    -- this code should never run (unless we messed up something).+    evalPanic i = case sz of+                    Nat sz' | i < 0 || i >= sz' -> invalidIndex sym i+                    _ -> panic "lookupSeqMap"+                            ["Messed up size accounting", show sz, show i]   -- | Apply the given evaluation function pointwise to the two given
src/Cryptol/Eval.hs view
@@ -11,7 +11,6 @@ {-# LANGUAGE ImplicitParams #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE ParallelListComp #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE PatternGuards #-} {-# LANGUAGE ViewPatterns #-}@@ -28,9 +27,10 @@   , emptyEnv   , evalExpr   , evalDecls-  , evalNewtypeDecls+  , evalNominalDecls   , evalSel   , evalSetSel+  , evalEnumCon   , EvalError(..)   , EvalErrorEx(..)   , Unsupported(..)@@ -53,7 +53,7 @@ import Cryptol.Parser.Position import Cryptol.Parser.Selector(ppSelector) import Cryptol.TypeCheck.AST-import Cryptol.TypeCheck.Solver.InfNat(Nat'(..))+import Cryptol.TypeCheck.Solver.InfNat(Nat'(..),nMul) import Cryptol.Utils.Ident import Cryptol.Utils.Panic (panic) import Cryptol.Utils.PP@@ -62,6 +62,8 @@ import           Control.Monad import           Data.List import           Data.Maybe+import           Data.Vector(Vector)+import qualified Data.Vector as Vector import qualified Data.IntMap.Strict as IntMap import qualified Data.Map.Strict as Map import           Data.Semigroup@@ -96,7 +98,8 @@   Module         {- ^ Module containing declarations to evaluate -} ->   GenEvalEnv sym {- ^ Environment to extend -} ->   SEval sym (GenEvalEnv sym)-moduleEnv sym m env = evalDecls sym (mDecls m) =<< evalNewtypeDecls sym (mNewtypes m) env+moduleEnv sym m env = evalDecls sym (mDecls m) =<<+                          evalNominalDecls sym (mNominalTypes m) env  {-# SPECIALIZE evalExpr ::   (?range :: Range, ConcPrims) =>@@ -161,6 +164,17 @@      b <- fromVBit <$> eval c      iteValue sym b (eval t) (eval f) +  ECase e as d -> {-# SCC "evalExpr->ECase" #-} do+    val <- eval e+    let (con,fs) = fromVEnum val+    caseValue sym con fs+      CaseCont+        { caseCon = evalCase <$> as+        , caseDflt =+            do rhs <- d+               pure (evalCase rhs [pure val])+        }+   EComp n t h gs -> {-# SCC "evalExpr->EComp" #-} do       let len  = evalNumType (envTypes env) n       let elty = evalValType (envTypes env) t@@ -230,6 +244,10 @@   {-# INLINE eval #-}   eval = evalExpr sym env   ppV = ppValue sym defaultPPOpts+  evalCase (CaseAlt xs e) vs =+    do let addVar env' ((x,_),v) = bindVar sym x v env'+       newEnv <- foldM addVar env (zip xs vs)+       evalExpr sym newEnv e  -- | Checks whether an evaluated `Prop` holds checkProp :: Prop -> Bool@@ -296,42 +314,67 @@  -- Newtypes -------------------------------------------------------------------- -{-# SPECIALIZE evalNewtypeDecls ::+{-# SPECIALIZE evalNominalDecls ::   ConcPrims =>   Concrete ->-  Map.Map Name Newtype ->+  Map.Map Name NominalType ->   GenEvalEnv Concrete ->   SEval Concrete (GenEvalEnv Concrete)   #-} -evalNewtypeDecls ::+evalNominalDecls ::   EvalPrims sym =>   sym ->-  Map.Map Name Newtype ->+  Map.Map Name NominalType ->   GenEvalEnv sym ->   SEval sym (GenEvalEnv sym)-evalNewtypeDecls sym nts env = foldM (flip (evalNewtypeDecl sym)) env $ Map.elems nts+evalNominalDecls sym nts env = foldM (flip (evalNominalDecl sym)) env $ Map.elems nts  -- | Introduce the constructor function for a newtype.-evalNewtypeDecl ::+evalNominalDecl ::   EvalPrims sym =>   sym ->-  Newtype ->+  NominalType ->   GenEvalEnv sym ->   SEval sym (GenEvalEnv sym)-evalNewtypeDecl _sym nt = pure . bindVarDirect (ntConName nt) (foldr tabs con (ntParams nt))+evalNominalDecl sym nt env0 =+  case ntDef nt of+    Struct c -> pure (bindVarDirect (ntConName c) (mkCon structCon) env0)+    Enum cs  -> foldM enumCon env0 cs+    Abstract -> pure env0   where-  con           = PFun PPrim+  structCon = PFun PPrim+  mkCon c   = foldr tabs c (ntParams nt) +  enumCon env c =+    do con <- evalEnumCon sym (nameIdent (ecName c)) (ecNumber c)+       let done        = PVal . con . Vector.fromList . reverse+           fu _t f xs  = PFun (\v -> f (v:xs))+       pure (bindVarDirect (ecName c)+                           (mkCon (foldr fu done (ecFields c) [])) env)+   tabs tp body =     case tpKind tp of       KType -> PTyPoly  (\ _ -> body)       KNum  -> PNumPoly (\ _ -> body)-      k -> evalPanic "evalNewtypeDecl" ["illegal newtype parameter kind", show (pp k)]+      k ->+        evalPanic "evalNominalDecl" [ "illegal newtype parameter kind"+                                    , show (pp k)+                                    ] -{-# INLINE evalNewtypeDecl #-}+{-# INLINE evalNominalDecl #-} +-- | Make the function for a known constructor+evalEnumCon ::+  Backend sym =>+  sym -> Ident -> Int ->+  SEval sym (Vector (SEval sym (GenValue sym)) -> GenValue sym)+evalEnumCon sym i n =+  do tag <- integerLit sym (toInteger n)+     pure (VEnum tag . IntMap.singleton n . ConInfo i) ++ -- Declarations ----------------------------------------------------------------  {-# SPECIALIZE evalDecls ::@@ -368,7 +411,16 @@   SEval sym (GenEvalEnv sym) evalDeclGroup sym env dg = do   case dg of-    Recursive ds -> do+    Recursive ds0 -> do+      let ds = filter shouldEval ds0+          -- If there are foreign declarations, we should only evaluate them if+          -- they are not already bound in the environment by the previous+          -- Cryptol.Eval.FFI.evalForeignDecls pass.+          shouldEval d =+            case (dDefinition d, lookupVar (dName d) env) of+              (DForeign _ _, Just _) -> False+              _                      -> True+       -- declare a "hole" for each declaration       -- and extend the evaluation environment       holes <- mapM (declHole sym) ds@@ -432,14 +484,19 @@   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)]-    DForeign _ -> evalPanic "Unexpected foreign declaration in recursive group"-                            [show (ppLocName nm)]-    DExpr _    -> do-      (hole, fill) <- sDeclareHole sym msg-      return (nm, sch, hole, fill)+    DPrim -> evalPanic "Unexpected primitive declaration in recursive group"+                       [show (ppLocName nm)]+    DForeign _ me ->+      case me of+        Nothing -> evalPanic+          "Unexpected foreign declaration with no cryptol implementation in recursive group"+          [show (ppLocName nm)]+        Just _ -> doHole+    DExpr _ -> doHole   where+  doHole = do+    (hole, fill) <- sDeclareHole sym msg+    return (nm, sch, hole, fill)   nm = dName d   sch = dSignature d   msg = unwords ["while evaluating", show (pp nm)]@@ -470,17 +527,22 @@         Just (Left ex) -> bindVar sym (dName d) (evalExpr sym renv ex) env         Nothing        -> bindVar sym (dName d) (cryNoPrimError sym (dName d)) env -    DForeign _ -> do+    DForeign _ me -> 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.+      -- be in the environment. If not, then either the foreign source was+      -- missing, Cryptol was not compiled with FFI support enabled, or we are+      -- in a non-Concrete backend. In that case, we bind the name to the+      -- fallback cryptol implementation if present, or otherwise 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+        Nothing -> bindVar sym (dName d) val env+          where+          val =+            case me of+              Just e -> evalExpr sym renv e+              Nothing -> raiseError sym $ FFINotSupported $ dName d      DExpr e -> bindVar sym (dName d) (evalExpr sym renv e) env @@ -689,23 +751,23 @@   ListEnv sym ->   [Match] ->   SEval sym (ListEnv sym)-branchEnvs sym env matches = snd <$> foldM (evalMatch sym) (1, env) matches+branchEnvs sym env matches = snd <$> foldM (evalMatch sym) (Nat 1, env) matches  {-# SPECIALIZE evalMatch ::   (?range :: Range, ConcPrims) =>   Concrete ->-  (Integer, ListEnv Concrete) ->+  (Nat', ListEnv Concrete) ->   Match ->-  SEval Concrete (Integer, ListEnv Concrete)+  SEval Concrete (Nat', ListEnv Concrete)   #-}  -- | Turn a match into the list of environments it represents. evalMatch ::   (?range :: Range, EvalPrims sym) =>   sym ->-  (Integer, ListEnv sym) ->+  (Nat', ListEnv sym) ->   Match ->-  SEval sym (Integer, ListEnv sym)+  SEval sym (Nat', ListEnv sym) evalMatch sym (lsz, lenv) m = seq lsz $ case m of    -- many envs@@ -714,7 +776,7 @@       -- Select from a sequence of finite length.  This causes us to 'stutter'       -- through our previous choices `nLen` times.       Nat nLen -> do-        vss <- memoMap sym (Nat lsz) $ indexSeqMap $ \i -> evalExpr sym (evalListEnv lenv i) expr+        vss <- memoMap sym lsz $ indexSeqMap $ \i -> evalExpr sym (evalListEnv lenv i) expr         let stutter xs = \i -> xs (i `div` nLen)         let lenv' = lenv { leVars = fmap stutter (leVars lenv) }         let vs i = do let (q, r) = i `divMod` nLen@@ -723,27 +785,21 @@                         VSeq _ xs'  -> lookupSeqMap xs' r                         VStream xs' -> lookupSeqMap xs' r                         _           -> evalPanic "evalMatch" ["Not a list value"]-        return (lsz * nLen, bindVarList n vs lenv')+        return (nMul lsz len, bindVarList n vs lenv') -      -- Select from a sequence of infinite length.  Note that this means we-      -- will never need to backtrack into previous branches.  Thus, we can convert-      -- `leVars` elements of the comprehension environment into `leStatic` elements-      -- by selecting out the 0th element.+      {- Select from a sequence of infinite length.  Note that only the+         first generator in a sequence of generators may have infinite length,+         so we can just evaluate it once an for all (i.e., it does not change+         on each loop iteration, as it may happen in the finite case). -}       Inf -> do-        let allvars = IntMap.union (fmap (Right . ($ 0)) (leVars lenv)) (leStatic lenv)-        let lenv' = lenv { leVars   = IntMap.empty-                         , leStatic = allvars-                         }-        let env   = EvalEnv allvars (leTypes lenv)+        let env = EvalEnv (leStatic lenv) (leTypes lenv)         xs <- evalExpr sym env expr         let vs i = case xs of                      VWord _ w   -> VBit <$> indexWordValue sym w i                      VSeq _ xs'  -> lookupSeqMap xs' i                      VStream xs' -> lookupSeqMap xs' i                      _           -> evalPanic "evalMatch" ["Not a list value"]-        -- Selecting from an infinite list effectively resets the length of the-        -- list environment, so return 1 as the length-        return (1, bindVarList n vs lenv')+        return (Inf, bindVarList n vs lenv)      where       len  = evalNumType (leTypes lenv) l@@ -755,6 +811,6 @@     where       f env =           case dDefinition d of-            DPrim      -> evalPanic "evalMatch" ["Unexpected local primitive"]-            DForeign _ -> evalPanic "evalMatch" ["Unexpected local foreign"]-            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
@@ -20,6 +20,8 @@   ) where  import Control.Monad (guard, zipWithM, foldM, mzero)+import Data.Foldable (foldl')+import Data.List (find) import Data.Ratio(numerator,denominator) import Data.Word(Word32, Word64) import MonadLib( ChoiceT, findOne, lift )@@ -28,6 +30,8 @@  import qualified Data.Map.Strict as Map import Data.Map(Map)+import qualified Data.Vector as Vector+import qualified Data.IntMap.Strict as IMap  import Cryptol.TypeCheck.Solver.InfNat (Nat'(..)) @@ -75,14 +79,40 @@              Left _ -> mismatch -- different fields              Right efs -> pure (ERec efs) -      (TVNewtype nt ts tfs, VRecord vfs) ->+      (TVNominal nt ts (TVStruct tfs), VRecord vfs) ->         do -- NB, vfs first argument to keep their display order            res <- zipRecordsM (\_lbl v t -> go t =<< lift v) vfs tfs            case res of              Left _ -> mismatch -- different fields              Right efs ->-               let f = foldl (\x t -> ETApp x (tNumValTy t)) (EVar (ntConName nt)) ts+               let c = case ntDef nt of+                         Struct co -> ntConName co+                         Enum {} -> panic "toExpr" ["Enum vs Record"]+                         Abstract -> panic "toExp" ["Asbtract vs Record"]+                   f = foldl (\x t -> ETApp x (tNumValTy t)) (EVar c) ts                 in pure (EApp f (ERec efs))+      (TVNominal nt ts (TVEnum tfss), VEnum i' vf_map) ->+        let i = fromInteger i'+        in+        case tfss Vector.!? i of+          Nothing -> mismatch -- enum constructor not found+          Just conT ->+            do let tfs = conFields conT+               vfs <- case IMap.lookup i vf_map of+                        Just con -> pure (conFields con)+                        Nothing  -> panic "toExpr" ["Missing constructor"]+               guard (Vector.length tfs == Vector.length vfs)+               c <- case ntDef nt of+                      Struct {} -> panic "toExpr" ["Enum vs Record"]+                      Abstract {} -> panic "toExpr" ["Enum vs Abstract"]+                      Enum cons ->+                        case find (\con -> ecNumber con == i) cons of+                          Just con -> pure (ecName con)+                          Nothing -> mismatch+               let f = foldl' (\x t -> ETApp x (tNumValTy t)) (EVar c) ts+               foldl' EApp f <$>+                  (zipWithM go (Vector.toList tfs) =<<+                              lift (sequence (Vector.toList vfs)))        (TVTuple ts, VTuple tvs) ->         do guard (length ts == length tvs)
src/Cryptol/Eval/FFI.hs view
@@ -59,18 +59,19 @@ #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.+-- implementations from the given 'ForeignSrc'. If some implementations fail to+-- load then errors are reported for them but any successfully loaded+-- implementations are still added to the environment.+--+-- 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)+  Eval ([FFILoadError], EvalEnv) evalForeignDecls fsrc decls env = io do-  ePrims <- for decls \(name, ffiFunType) ->+  (errs, prims) <- partitionEithers <$> 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+  pure (errs, foldr (uncurry bindVarDirect) env prims)  -- | Generate a 'Prim' value representing the given foreign function, containing -- all the code necessary to marshal arguments and return values and do the@@ -422,9 +423,9 @@ #else  -- | Dummy implementation for when FFI is disabled. Does not add anything to--- the environment.+-- the environment or report any errors. evalForeignDecls :: ForeignSrc -> [(Name, FFIFunType)] -> EvalEnv ->-  Eval (Either [FFILoadError] EvalEnv)-evalForeignDecls _ _ env = pure $ Right env+  Eval ([FFILoadError], EvalEnv)+evalForeignDecls _ _ env = pure ([], env)  #endif
src/Cryptol/Eval/Generic.hs view
@@ -250,11 +250,8 @@               (\f fty -> sDelay sym (loop' fty (lookupRecord f l) (lookupRecord f r)))               fs -    TVAbstract {} ->-      evalPanic "ringBinary" ["Abstract type not in `Ring`"]--    TVNewtype {} ->-      evalPanic "ringBinary" ["Newtype not in `Ring`"]+    TVNominal {} ->+      evalPanic "ringBinary" ["Nominal type not in `Ring`"]  type UnaryWord sym = Integer -> SWord sym -> SEval sym (SWord sym) @@ -330,9 +327,7 @@           (\f fty -> sDelay sym (loop' fty (lookupRecord f v)))           fs -    TVAbstract {} -> evalPanic "ringUnary" ["Abstract type not in `Ring`"]--    TVNewtype {} -> evalPanic "ringUnary" ["Newtype not in `Ring`"]+    TVNominal {} -> evalPanic "ringUnary" ["Nominal type not in `Ring`"]   {-# SPECIALIZE ringNullary ::@@ -398,11 +393,8 @@              do xs <- traverse (sDelay sym . loop) fs                 pure $ VRecord xs -        TVAbstract {} ->-          evalPanic "ringNullary" ["Abstract type not in `Ring`"]--        TVNewtype {} ->-          evalPanic "ringNullary" ["Newtype not in `Ring`"]+        TVNominal {} ->+          evalPanic "ringNullary" ["Nominal type not in `Ring`"]  {-# SPECIALIZE integralBinary :: Concrete -> BinWord Concrete ->       (SInteger Concrete -> SInteger Concrete -> SEval Concrete (SInteger Concrete)) ->@@ -777,11 +769,9 @@                             (recordElements (fromVRecord v1))                             (recordElements (fromVRecord v2))                             k-        TVAbstract {} -> evalPanic "cmpValue"-                          [ "Abstract type not in `Cmp`" ] -        TVNewtype {} -> evalPanic "cmpValue"-                          [ "Newtype not in `Cmp`" ]+        TVNominal {} -> evalPanic "cmpValue"+                          [ "Nominal type not in `Cmp`" ]      cmpValues (t : ts) (x1 : xs1) (x2 : xs2) k =       do x1' <- x1@@ -951,9 +941,7 @@       do xs <- traverse (sDelay sym . zeroV sym) fields          pure $ VRecord xs -  TVAbstract {} -> evalPanic "zeroV" [ "Abstract type not in `Zero`" ]--  TVNewtype {} -> evalPanic "zeroV" [ "Newtype not in `Zero`" ]+  TVNominal {} -> evalPanic "zeroV" [ "Nominal type not in `Zero`" ]   {-# SPECIALIZE joinSeq ::@@ -1292,11 +1280,8 @@           (\f fty -> sDelay sym (loop' fty (lookupRecord f l) (lookupRecord f r)))           fields -    TVAbstract {} -> evalPanic "logicBinary"-                        [ "Abstract type not in `Logic`" ]--    TVNewtype {} -> evalPanic "logicBinary"-                        [ "Newtype not in `Logic`" ]+    TVNominal {} -> evalPanic "logicBinary"+                        [ "Nominal type not in `Logic`" ]  {-# SPECIALIZE logicUnary ::   Concrete ->@@ -1352,9 +1337,7 @@           (\f fty -> sDelay sym (loop' fty (lookupRecord f val)))           fields -    TVAbstract {} -> evalPanic "logicUnary" [ "Abstract type not in `Logic`" ]--    TVNewtype {} -> evalPanic "logicUnary" [ "Newtype not in `Logic`" ]+    TVNominal {} -> evalPanic "logicUnary" [ "Nominal type not in `Logic`" ]   {-# INLINE assertIndexInBounds #-}@@ -1877,22 +1860,23 @@ parmapV :: Backend sym => sym -> Prim sym parmapV sym =   PTyPoly \_a ->-  PTyPoly \_b ->-  PFinPoly \_n ->+  PTyPoly \b ->+  PFinPoly \n ->   PFun \f ->   PFun \xs ->   PPrim     do f' <- fromVFun sym <$> f        xs' <- xs-       case xs' of-          VWord n w ->-            do let m = asBitsMap sym w-               m' <- sparkParMap sym (\x -> f' (VBit <$> x)) n m-               VWord n <$> (bitmapWordVal sym n (fromVBit <$> m'))-          VSeq n m ->-            VSeq n <$> sparkParMap sym f' n m+       m <-+         case xs' of+           VWord _n w ->+             let m = asBitsMap sym w in+             sparkParMap sym (\x -> f' (VBit <$> x)) n m+           VSeq _n m ->+             sparkParMap sym f' n m -          _ -> panic "parmapV" ["expected sequence!"]+           _ -> panic "parmapV" ["expected finite sequence!"]+       mkSeq sym (Nat n) b m   sparkParMap ::
src/Cryptol/Eval/Reference.lhs view
@@ -36,16 +36,17 @@ > import qualified GHC.Num.Compat as Integer > import qualified Data.List as List >-> import Cryptol.ModuleSystem.Name (asPrim)+> import Cryptol.ModuleSystem.Name (asPrim,nameIdent) > import Cryptol.TypeCheck.Solver.InfNat (Nat'(..), nAdd, nMin, nMul) > import Cryptol.TypeCheck.AST > import Cryptol.Backend.FloatHelpers (BF(..)) > import qualified Cryptol.Backend.FloatHelpers as FP > import Cryptol.Backend.Monad (EvalError(..)) > import Cryptol.Eval.Type->   (TValue(..), isTBit, evalValType, evalNumType, TypeEnv, bindTypeVar)+>   (TValue(..), TNominalTypeValue(..),+>    isTBit, evalValType, evalNumType, TypeEnv, bindTypeVar) > import Cryptol.Eval.Concrete (mkBv, ppBV, lg2)-> import Cryptol.Utils.Ident (Ident,PrimIdent, prelPrim, floatPrim)+> import Cryptol.Utils.Ident (Ident,PrimIdent, prelPrim, floatPrim, unpackIdent) > import Cryptol.Utils.Panic (panic) > import Cryptol.Utils.PP > import Cryptol.Utils.RecordMap@@ -53,7 +54,7 @@ > import Cryptol.Eval.Type (evalType, lookupTypeVar, tNumTy, tValTy) > > import qualified Cryptol.ModuleSystem as M-> import qualified Cryptol.ModuleSystem.Env as M (loadedModules,loadedNewtypes)+> import qualified Cryptol.ModuleSystem.Env as M (loadedModules,loadedNominalTypes)  Overview ========@@ -176,6 +177,7 @@ >   | VList Nat' [E Value]       -- ^ @ [n]a   @ finite or infinite lists >   | VTuple [E Value]           -- ^ @ ( .. ) @ tuples >   | VRecord [(Ident, E Value)] -- ^ @ { .. } @ records+>   | VEnum Ident [E Value]      -- ^ @ Just x @, sum types >   | VFun (E Value -> E Value)  -- ^ functions >   | VPoly (TValue -> E Value)  -- ^ polymorphic values (kind *) >   | VNumPoly (Nat' -> E Value) -- ^ polymorphic values (kind #)@@ -222,6 +224,11 @@ > fromVRecord (VRecord fs) = fs > fromVRecord _            = evalPanic "fromVRecord" ["Expected a record"] >+> -- | Destructor for @VEnum@.+> fromVEnum :: Value -> (Ident,[E Value])+> fromVEnum (VEnum i fs) = (i,fs)+> fromVEnum _            = evalPanic "fromVEnum" ["Expected an enum value."]+> > -- | Destructor for @VFun@. > fromVFun :: Value -> (E Value -> E Value) > fromVFun (VFun f) = f@@ -310,6 +317,8 @@ >     EIf c t f -> >       condValue (fromVBit <$> evalExpr env c) (evalExpr env t) (evalExpr env f) >+>     ECase e alts dflt -> evalCase env (evalExpr env e) alts dflt+> >     EComp _n _ty e branches -> evalComp env e branches > >     EVar n ->@@ -338,7 +347,7 @@ >     EProofApp e    -> evalExpr env e >     EWhere e dgs   -> evalExpr (foldl evalDeclGroup env dgs) e >->     EPropGuards guards _ty -> +>     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"]@@ -346,7 +355,7 @@ > 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 +> -- | 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@@ -355,7 +364,7 @@ >   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 +>   where >     toType = either tNumTy tValTy  @@ -399,7 +408,7 @@ >   case (tyv, sel) of >     (TVTuple ts, TupleSel n _) -> updTupleAt ts n >     (TVRec fs, RecordSel n _)  -> updRecAt fs n->     (TVNewtype _ _ fs, RecordSel n _) -> updRecAt fs n+>     (TVNominal _ _ (TVStruct fs), RecordSel n _) -> updRecAt fs n >     (TVSeq len _, ListSel n _) -> updSeqAt len n >     (_, _) -> evalPanic "evalSet" ["type/selector mismatch", show tyv, show sel] >   where@@ -432,6 +441,20 @@ > condValue :: E Bool -> E Value -> E Value -> E Value > condValue c l r = c >>= \b -> if b then l else r +> evalCase :: Env -> E Value -> Map Ident CaseAlt -> Maybe CaseAlt -> E Value+> evalCase env e alts dflt =+>   do val <- e+>      let (tag,fields) = fromVEnum val+>      case Map.lookup tag alts of+>        Just alt -> evalCaseBranch alt fields+>        Nothing  ->+>          case dflt of+>            Just alt -> evalCaseBranch alt [pure val]+>            Nothing  -> Err (NoMatchingConstructor (Just (unpackIdent tag)))+>   where+>   evalCaseBranch (CaseAlt xs k) vs = evalExpr env' k+>     where env' = foldr bindVar env (zip (map fst xs) vs)+ List Comprehensions ------------------- @@ -531,29 +554,51 @@ > evalDecl :: Env -> Decl -> (Name, E Value) > evalDecl env d = >   case dDefinition d of->     DPrim      -> (dName d, pure (evalPrim (dName d)))->     DForeign _ -> (dName d, cryError $ FFINotSupported $ dName d)->     DExpr e    -> (dName d, evalExpr env e)+>     DPrim         -> (dName d, pure (evalPrim (dName d)))+>     DForeign _ me -> (dName d, val)+>       where+>         val =+>           case me of+>             Just e  -> evalExpr env e+>             Nothing -> cryError $ FFINotSupported $ dName d+>     DExpr e       -> (dName d, evalExpr env e) > -Newtypes---------+Nominal Types+------------- +We have three forms of nominal types: newtypes, enums, and abstract types.+ At runtime, newtypes values are represented in exactly the same way as records.  The constructor function for newtypes is thus basically just an identity function that consumes and ignores its type arguments. -> evalNewtypeDecl :: Env -> Newtype -> Env-> evalNewtypeDecl env nt = bindVar (ntConName nt, pure val) env+Enums are represented with a tag, which indicates what constructor+was used to create a value, as well as the types of the values stored in the+constructor.++> evalNominalDecl :: Env -> NominalType -> Env+> evalNominalDecl env nt =+>   case ntDef nt of+>     Struct c -> bindVar (ntConName c, mkCon newtypeCon) env+>     Enum cs  -> foldr enumCon env cs+>     Abstract -> env >   where->     val = foldr tabs con (ntParams nt)->     con = VFun (\x -> x)+>     mkCon con  = pure (foldr tabs con (ntParams nt))+>     newtypeCon = VFun id+>     enumCon c  =+>       bindVar (ecName c, mkCon (foldr addField tag (ecFields c) []))+>       where+>       tag                 = VEnum (nameIdent (ecName c)) . reverse+>       addField _t mk args = VFun (\v -> pure (mk (v:args)))+> >     tabs tp body = >       case tpKind tp of >         KType -> VPoly (\_ -> pure body) >         KNum  -> VNumPoly (\_ -> pure body)->         k -> evalPanic "evalNewtypeDecl" ["illegal newtype parameter kind", show k]+>         k -> evalPanic "evalNominalDecl"+>                                   ["illegal newtype parameter kind", show k]  Primitives ==========@@ -1016,8 +1061,7 @@ > zero (TVRec fields) = VRecord [ (f, pure (zero fty)) >                               | (f, fty) <- canonicalFields fields ] > zero (TVFun _ bty)  = VFun (\_ -> pure (zero bty))-> zero (TVAbstract{}) = evalPanic "zero" ["Abstract type not in `Zero`"]-> zero (TVNewtype{})  = evalPanic "zero" ["Newtype not in `Zero`"]+> zero (TVNominal {})  = evalPanic "zero" ["Nominal type not in `Zero`"]  Literals --------@@ -1085,8 +1129,7 @@ >         TVArray{}    -> evalPanic "logicUnary" ["Array not in class Logic"] >         TVRational   -> evalPanic "logicUnary" ["Rational not in class Logic"] >         TVFloat{}    -> evalPanic "logicUnary" ["Float not in class Logic"]->         TVAbstract{} -> evalPanic "logicUnary" ["Abstract type not in `Logic`"]->         TVNewtype{}  -> evalPanic "logicUnary" ["Newtype not in `Logic`"]+>         TVNominal {}  -> evalPanic "logicUnary" ["Nominal type not in `Logic`"]  > logicBinary :: (Bool -> Bool -> Bool) -> TValue -> E Value -> E Value -> E Value > logicBinary op = go@@ -1124,8 +1167,7 @@ >         TVArray{}    -> evalPanic "logicBinary" ["Array not in class Logic"] >         TVRational   -> evalPanic "logicBinary" ["Rational not in class Logic"] >         TVFloat{}    -> evalPanic "logicBinary" ["Float not in class Logic"]->         TVAbstract{} -> evalPanic "logicBinary" ["Abstract type not in `Logic`"]->         TVNewtype{}  -> evalPanic "logicBinary" ["Newtype not in `Logic`"]+>         TVNominal {} -> evalPanic "logicBinary" ["Nominal type not in `Logic`"]   Ring Arithmetic@@ -1171,9 +1213,7 @@ >           pure $ VTuple (map go tys) >         TVRec fs -> >           pure $ VRecord [ (f, go fty) | (f, fty) <- canonicalFields fs ]->         TVAbstract {} ->->           evalPanic "arithNullary" ["Abstract type not in `Ring`"]->         TVNewtype {} ->+>         TVNominal {} -> >           evalPanic "arithNullary" ["Newtype type not in `Ring`"]  > ringUnary ::@@ -1211,10 +1251,8 @@ >           do val' <- val >              pure $ VRecord [ (f, go fty (lookupRecord f val')) >                             | (f, fty) <- canonicalFields fs ]->         TVAbstract {} ->->           evalPanic "arithUnary" ["Abstract type not in `Ring`"]->         TVNewtype {} ->->           evalPanic "arithUnary" ["Newtype not in `Ring`"]+>         TVNominal {} ->+>           evalPanic "arithUnary" ["Nominal type not in `Ring`"]  > ringBinary :: >   (Integer -> Integer -> E Integer) ->@@ -1261,10 +1299,8 @@ >              pure $ VRecord >                [ (f, go fty (lookupRecord f l') (lookupRecord f r')) >                | (f, fty) <- canonicalFields fs ]->         TVAbstract {} ->->           evalPanic "arithBinary" ["Abstract type not in class `Ring`"]->         TVNewtype {} ->->           evalPanic "arithBinary" ["Newtype not in class `Ring`"]+>         TVNominal {} ->+>           evalPanic "arithBinary" ["Nominal type not in class `Ring`"]   Integral@@ -1441,10 +1477,8 @@ >          ls <- map snd . sortBy (comparing fst) . fromVRecord <$> l >          rs <- map snd . sortBy (comparing fst) . fromVRecord <$> r >          lexList (zipWith3 lexCompare tys ls rs)->     TVAbstract {} ->->       evalPanic "lexCompare" ["Abstract type not in `Cmp`"]->     TVNewtype {} ->->       evalPanic "lexCompare" ["Newtype not in `Cmp`"]+>     TVNominal {} ->+>       evalPanic "lexCompare" ["Nominal type not in `Cmp`"] > > lexList :: [E Ordering] -> E Ordering > lexList [] = pure EQ@@ -1497,10 +1531,8 @@ >          ls <- map snd . sortBy (comparing fst) . fromVRecord <$> l >          rs <- map snd . sortBy (comparing fst) . fromVRecord <$> r >          lexList (zipWith3 lexSignedCompare tys ls rs)->     TVAbstract {} ->->       evalPanic "lexSignedCompare" ["Abstract type not in `Cmp`"]->     TVNewtype {} ->->       evalPanic "lexSignedCompare" ["Newtype type not in `Cmp`"]+>     TVNominal {} ->+>       evalPanic "lexSignedCompare" ["Nominal type not in `Cmp`"]   Sequences@@ -1799,6 +1831,11 @@ >     VTuple vs  -> ppTuple (map (ppEValue opts) vs) >     VRecord fs -> ppRecord (map ppField fs) >       where ppField (f,r) = pp f <+> char '=' <+> ppEValue opts r+>     VEnum tag vs ->+>       case vs of+>         [] -> tagT+>         _  -> parens (tagT <+> hsep (map (ppEValue opts) vs))+>       where tagT = text (unpackIdent tag) >     VFun _     -> text "<function>" >     VPoly _    -> text "<polymorphic value>" >     VNumPoly _ -> text "<polymorphic value>"@@ -1815,6 +1852,6 @@ >   where >     modEnv = M.minpModuleEnv minp >     extDgs = concatMap mDecls (M.loadedModules modEnv) ++ M.deDecls (M.meDynEnv modEnv)->     nts    = Map.elems (M.loadedNewtypes modEnv)->     env    = foldl evalDeclGroup (foldl evalNewtypeDecl mempty nts) extDgs+>     nts    = Map.elems (M.loadedNominalTypes modEnv)+>     env    = foldl evalDeclGroup (foldl evalNominalDecl mempty nts) extDgs >     val    = evalExpr env expr
src/Cryptol/Eval/Type.hs view
@@ -6,12 +6,17 @@ -- Stability   :  provisional -- Portability :  portable -{-# LANGUAGE Safe, PatternGuards #-}+{-# LANGUAGE PatternGuards #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveTraversable #-} module Cryptol.Eval.Type where +import Data.Vector (Vector)+import qualified Data.Vector as Vector+import Data.List(sortOn) import Cryptol.Backend.Monad (evalPanic)+import Cryptol.ModuleSystem.Name(nameIdent) import Cryptol.TypeCheck.AST import Cryptol.TypeCheck.PP(pp) import Cryptol.TypeCheck.Solver.InfNat@@ -39,12 +44,35 @@   | TVTuple [TValue]          -- ^ @ (a, b, c )@   | TVRec (RecordMap Ident TValue) -- ^ @ { x : a, y : b, z : c } @   | TVFun TValue TValue       -- ^ @ a -> b @-  | TVNewtype Newtype+  | TVNominal NominalType               [Either Nat' TValue]-              (RecordMap Ident TValue)     -- ^ a named newtype-  | TVAbstract UserTC [Either Nat' TValue] -- ^ an abstract type+              TNominalTypeValue    -- ^ a named newtype     deriving (Generic, NFData, Eq) +data TNominalTypeValue =+    TVStruct (RecordMap Ident TValue)+  | TVEnum   (Vector (ConInfo TValue))  -- ^ Indexed by constructor number+  | TVAbstract+    deriving (Generic, NFData, Eq)++data ConInfo a = ConInfo+  { conIdent :: Ident+  , conFields :: Vector a+  } deriving (Generic,NFData,Eq,Functor,Foldable,Traversable)++isNullaryCon :: ConInfo a -> Bool+isNullaryCon = Vector.null . conFields++zipConInfo :: (a -> b -> c) -> ConInfo a -> ConInfo b -> ConInfo c+zipConInfo f x y+  | conIdent x == conIdent y =+    x { conFields = Vector.zipWith f (conFields x) (conFields y) }+  | otherwise = panic "zipConInfo" [ "Mismatched constructors"+                                   ,  show (pp (conIdent x))+                                   ,  show (pp (conIdent y))+                                   ]++ -- | Convert a type value back into a regular type tValTy :: TValue -> Type tValTy tv =@@ -60,8 +88,7 @@     TVTuple ts  -> tTuple (map tValTy ts)     TVRec fs    -> tRec (fmap tValTy fs)     TVFun t1 t2 -> tFun (tValTy t1) (tValTy t2)-    TVNewtype nt vs _ -> tNewtype nt (map tNumValTy vs)-    TVAbstract u vs -> tAbstract u (map tNumValTy vs)+    TVNominal nt vs _ -> tNominal nt (map tNumValTy vs)  tNumTy :: Nat' -> Type tNumTy Inf     = tInf@@ -132,7 +159,7 @@     TUser _ _ ty'  -> evalType env ty'     TRec fields    -> Right $ TVRec (fmap val fields) -    TNewtype nt ts -> Right $ TVNewtype nt tvs $ evalNewtypeBody env nt tvs+    TNominal nt ts -> Right $ TVNominal nt tvs $ evalNominalTypeBody env nt tvs         where tvs = map (evalType env) ts      TCon (TC c) ts ->@@ -150,15 +177,6 @@         (TCTuple _, _)  -> Right $ TVTuple (map val ts)         (TCNum n, [])   -> Left $ Nat n         (TCInf, [])     -> Left $ Inf-        (TCAbstract u,vs) ->-            case kindOf ty of-              KType -> Right $ TVAbstract u (map (evalType env) vs)-              k -> evalPanic "evalType"-                [ "Unsupported"-                , "*** Abstract type of kind: " ++ show (pp k)-                , "*** Name: " ++ show (pp u)-                ]-         _ -> evalPanic "evalType" ["not a value type", show ty]     TCon (TF f) ts      -> Left $ evalTF f (map num ts)     TCon (PC p) _       -> evalPanic "evalType" ["invalid predicate symbol", show p]@@ -173,10 +191,18 @@                                   ["Expecting a finite size, but got `inf`"]  -- | Evaluate the body of a newtype, given evaluated arguments-evalNewtypeBody :: TypeEnv -> Newtype -> [Either Nat' TValue] -> RecordMap Ident TValue-evalNewtypeBody env0 nt args = fmap (evalValType env') (ntFields nt)+evalNominalTypeBody ::+  TypeEnv -> NominalType -> [Either Nat' TValue] -> TNominalTypeValue+evalNominalTypeBody env0 nt args =+  case ntDef nt of+    Struct c -> TVStruct (fmap (evalValType env') (ntFields c))+    Enum cs  -> TVEnum (Vector.fromList (map doEnum (sortOn ecNumber cs)))+    Abstract -> TVAbstract   where   env' = loop env0 (ntParams nt) args++  doEnum c = ConInfo (nameIdent (ecName c))+                     (Vector.fromList (map (evalValType env') (ecFields c)))    loop env [] [] = env   loop env (p:ps) (a:as) = loop (bindTypeVar (TVBound p) a env) ps as
src/Cryptol/Eval/Value.hs view
@@ -25,7 +25,7 @@  module Cryptol.Eval.Value   ( -- * GenericValue-    GenValue(..)+    GenValue(..), ConValue   , forceValue   , Backend(..)   , asciiMode@@ -57,22 +57,30 @@   , fromVTuple   , fromVRecord   , lookupRecord+  , fromVEnum     -- ** Pretty printing   , defaultPPOpts   , ppValue+  , ppValuePrec     -- * Merge and if/then/else   , iteValue+  , caseValue, CaseCont(..)   , mergeValue   ) where  import Data.Ratio import Numeric (showIntAtBase)+import Data.Map(Map)+import qualified Data.Map as Map+import Data.IntMap.Strict (IntMap)+import qualified Data.IntMap.Strict as IMap+import qualified Data.Vector as Vector  import Cryptol.Backend import Cryptol.Backend.SeqMap import qualified Cryptol.Backend.Arch as Arch import Cryptol.Backend.Monad-  ( evalPanic, wordTooWide, CallStack, combineCallStacks )+  ( evalPanic, wordTooWide, CallStack, combineCallStacks,EvalError(..)) import Cryptol.Backend.FloatHelpers (fpPP) import Cryptol.Backend.WordValue @@ -80,7 +88,7 @@  import Cryptol.TypeCheck.Solver.InfNat(Nat'(..)) -import Cryptol.Utils.Ident (Ident)+import Cryptol.Utils.Ident (Ident,unpackIdent) import Cryptol.Utils.Logger(Logger) import Cryptol.Utils.Panic(panic) import Cryptol.Utils.PP@@ -105,6 +113,11 @@ data GenValue sym   = VRecord !(RecordMap Ident (SEval sym (GenValue sym))) -- ^ @ { .. } @   | VTuple ![SEval sym (GenValue sym)]              -- ^ @ ( .. ) @+  | VEnum !(SInteger sym) !(IntMap (ConValue sym))+    -- ^ As an example, consider the enum value @Just ()@. The 'SInteger' is the+    -- tag (e.g., 'Just' would have the tag @0@), and the 'IntMap' contains the+    -- fields (e.g., @{ 0 -> ("Just",()) }@. The 'IntMap' is only really needed+    -- to represent symbolic values.   | VBit !(SBit sym)                           -- ^ @ Bit    @   | VInteger !(SInteger sym)                   -- ^ @ Integer @ or @ Z n @   | VRational !(SRational sym)                 -- ^ @ Rational @@@ -118,12 +131,14 @@   | VNumPoly CallStack (Nat' -> SEval sym (GenValue sym))  -- ^ polymorphic values (kind #)  deriving Generic +type ConValue sym = ConInfo (SEval sym (GenValue sym))  -- | Force the evaluation of a value forceValue :: Backend sym => GenValue sym -> SEval sym () forceValue v = case v of   VRecord fs  -> mapM_ (forceValue =<<) fs   VTuple xs   -> mapM_ (forceValue =<<) xs+  VEnum i xs  -> seq i (mapM_ forceConValue xs)   VSeq n xs   -> mapM_ (forceValue =<<) (enumerateSeqMap n xs)   VBit b      -> seq b (return ())   VInteger i  -> seq i (return ())@@ -135,12 +150,14 @@   VPoly{}     -> return ()   VNumPoly{}  -> return () -+forceConValue :: Backend sym => ConValue sym -> SEval sym ()+forceConValue (ConInfo i vs) = i `seq` mapM_ (forceValue =<<) vs  instance Show (GenValue sym) where   show v = case v of     VRecord fs -> "record:" ++ show (displayOrder fs)     VTuple xs  -> "tuple:" ++ show (length xs)+    VEnum _ _  -> "enum"     VBit _     -> "bit"     VInteger _ -> "integer"     VRational _ -> "rational"@@ -160,23 +177,33 @@   PPOpts ->   GenValue sym ->   SEval sym Doc-ppValue x opts = loop+ppValue x opts = ppValuePrec x opts 0++ppValuePrec :: forall sym.+  Backend sym =>+  sym ->+  PPOpts ->+  Int ->+  GenValue sym ->+  SEval sym Doc+ppValuePrec x opts = loop   where-  loop :: GenValue sym -> SEval sym Doc-  loop val = case val of-    VRecord fs         -> do fs' <- traverse (>>= loop) fs+  loop :: Int -> GenValue sym -> SEval sym Doc+  loop prec val = case val of+    VRecord fs         -> do fs' <- traverse (>>= loop 0) fs                              return $ ppRecord (map ppField (fields fs'))       where       ppField (f,r) = pp f <+> char '=' <+> r-    VTuple vals        -> do vals' <- traverse (>>=loop) vals+    VTuple vals        -> do vals' <- traverse (>>=loop 0) vals                              return $ ppTuple vals'+    VEnum c vs         -> ppEnumVal prec c vs     VBit b             -> ppSBit x b     VInteger i         -> ppSInteger x i     VRational q        -> ppSRational x q     VFloat i           -> ppSFloat x opts i     VSeq sz vals       -> ppWordSeq sz vals     VWord _ wv         -> ppWordVal wv-    VStream vals       -> do vals' <- traverse (>>=loop) $ enumerateSeqMap (useInfLength opts) vals+    VStream vals       -> do vals' <- traverse (>>=loop 0) $ enumerateSeqMap (useInfLength opts) vals                              return $ ppList ( vals' ++ [text "..."] )     VFun{}             -> return $ text "<function>"     VPoly{}            -> return $ text "<polymorphic value>"@@ -187,6 +214,19 @@     DisplayOrder -> displayFields     CanonicalOrder -> canonicalFields +  ppEnumVal prec i mp =+    case integerAsLit x i of+      Just c ->+        case IMap.lookup (fromInteger c) mp of+          Just con+            | isNullaryCon con -> pure (pp (conIdent con))+            | otherwise ->+              do vds <- traverse (>>= loop 1) (conFields con)+                 let d = pp (conIdent con) <+> hsep (Vector.toList vds)+                 pure (if prec > 0 then parens d else d)+          Nothing -> panic "ppEnumVal" ["Malformed enum value", show c]+      Nothing -> pure (text "[?]")+   ppWordVal :: WordValue sym -> SEval sym Doc   ppWordVal w = ppSWord x opts =<< asWordVal x w @@ -202,7 +242,7 @@                 Just str -> return $ text (show str)                 _ -> do vs' <- mapM (ppSWord x opts) vs                         return $ ppList vs'-      _ -> do ws' <- traverse loop ws+      _ -> do ws' <- traverse (loop 0) ws               return $ ppList ws'  ppSBit :: Backend sym => sym -> SBit sym -> SEval sym Doc@@ -437,6 +477,12 @@   VRecord fs -> fs   _          -> evalPanic "fromVRecord" ["not a record", show val] +fromVEnum :: GenValue sym -> (SInteger sym, IntMap (ConValue sym))+fromVEnum val =+  case val of+    VEnum c xs -> (c,xs)+    _          -> evalPanic "fromVEnum" ["not an enum", show val]+ fromVFloat :: GenValue sym -> SFloat sym fromVFloat val =   case val of@@ -451,7 +497,7 @@     Nothing -> evalPanic "lookupRecord" ["malformed record", show val]  --- Merge and if/then/else+-- Merge and if/then/else and case  {-# INLINE iteValue #-} iteValue :: Backend sym =>@@ -465,6 +511,39 @@   | Just False <- bitAsLit sym b = y   | otherwise = mergeValue' sym b x y +data CaseCont sym = CaseCont+  { caseCon  :: Map Ident ([SEval sym (GenValue sym)] -> SEval sym (GenValue sym))+  , caseDflt :: Maybe (SEval sym (GenValue sym))+  }++caseValue :: Backend sym =>+  sym ->+  SInteger sym ->+  IntMap (ConValue sym) ->+  CaseCont sym ->+  SEval sym (GenValue sym)+caseValue sym tag alts k+  | Just c <- integerAsLit sym tag =+    case IMap.lookup (fromInteger c) alts of+      Just conV -> doCase conV+      Nothing -> panic "caseValue" ["Missing constructor for tag", show c]+  | otherwise = foldr doSymCase (doDefault Nothing) (IMap.toList alts)+  where+  doSymCase (n,con) otherOpts =+    do expect <- integerLit sym (toInteger n)+       yes    <- intEq sym tag expect+       iteValue sym yes (doCase con) otherOpts++  doDefault mb =+    case caseDflt k of+      Just yes -> yes+      Nothing  -> raiseError sym (NoMatchingConstructor mb)++  doCase (ConInfo con fs) =+    case Map.lookup con (caseCon k) of+      Just yes -> yes (Vector.toList fs)+      Nothing  -> doDefault (Just $! unpackIdent con)+ {-# INLINE mergeValue' #-} mergeValue' :: Backend sym =>   sym ->@@ -474,6 +553,10 @@   SEval sym (GenValue sym) mergeValue' sym = mergeEval sym (mergeValue sym) +mergeConValue ::+  Backend sym => sym -> SBit sym -> ConValue sym -> ConValue sym -> ConValue sym+mergeConValue sym c = zipConInfo (mergeValue' sym c)+ mergeValue :: Backend sym =>   sym ->   SBit sym ->@@ -487,6 +570,11 @@          case res of            Left f -> panic "Cryptol.Eval.Value" [ "mergeValue: incompatible record values", show f ]            Right r -> pure (VRecord r)++    (VEnum c1 fs1, VEnum c2 fs2) ->+      VEnum <$> iteInteger sym c c1 c2+            <*> pure (IMap.unionWith (mergeConValue sym c) fs1 fs2)+     (VTuple vs1  , VTuple vs2  ) | length vs1 == length vs2  ->                                   pure $ VTuple $ zipWith (mergeValue' sym c) vs1 vs2     (VBit b1     , VBit b2     ) -> VBit <$> iteBit sym c b1 b2
src/Cryptol/IR/FreeVars.hs view
@@ -93,7 +93,7 @@ instance FreeVars DeclDef where   freeVars d = case d of                  DPrim -> mempty-                 DForeign _ -> mempty+                 DForeign _ me -> foldMap freeVars me                  DExpr e -> freeVars e  @@ -107,6 +107,8 @@       ESel e _          -> freeVars e       ESet ty e _ v     -> freeVars ty <> freeVars [e,v]       EIf e1 e2 e3      -> freeVars [e1,e2,e3]+      ECase e as d      -> freeVars e <> freeVars (Map.elems as)+                                      <> maybe mempty freeVars d       EComp t1 t2 e mss -> freeVars [t1,t2] <> rmVals (defs mss) (freeVars e)                                             <> mconcat (map foldFree mss)       EVar x            -> mempty { valDeps = Set.singleton x }@@ -117,12 +119,16 @@       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 ]+      EPropGuards guards t -> mconcat [ freeVars e | (_, e) <- guards ]+                              <> freeVars t     where       foldFree :: (FreeVars a, Defs a) => [a] -> Deps       foldFree = foldr updateFree mempty       updateFree x rest = freeVars x <> rmVals (defs x) rest +instance FreeVars CaseAlt where+  freeVars (CaseAlt xs e) = foldr (rmVal . fst) (freeVars e) xs+ instance FreeVars Match where   freeVars m = case m of                  From _ t1 t2 e -> freeVars t1 <> freeVars t2 <> freeVars e@@ -142,7 +148,7 @@        TUser _ _ t -> freeVars t       TRec fs     -> freeVars (recordElements fs)-      TNewtype nt ts -> freeVars nt <> freeVars ts+      TNominal nt ts -> freeVars nt <> freeVars ts  instance FreeVars TVar where   freeVars tv = case tv of@@ -152,9 +158,22 @@ instance FreeVars TCon where   freeVars _tc = mempty -instance FreeVars Newtype where+instance FreeVars NominalType where   freeVars nt = foldr rmTParam base (ntParams nt)-    where base = freeVars (ntConstraints nt) <> freeVars (recordElements (ntFields nt))+    where base = freeVars (ntConstraints nt) <> freeVars (ntDef nt)++instance FreeVars NominalTypeDef where+  freeVars def =+    case def of+      Struct c -> freeVars c+      Enum cs -> freeVars cs+      Abstract -> mempty++instance FreeVars StructCon where+  freeVars c = freeVars (recordElements (ntFields c))++instance FreeVars EnumCon where+  freeVars c = freeVars (ecFields c)   --------------------------------------------------------------------------------
src/Cryptol/IR/TraverseNames.hs view
@@ -61,6 +61,9 @@       EIf e1 e2 e3      -> EIf <$> traverseNamesIP e1                                <*> traverseNamesIP e2                                <*> traverseNamesIP e3+      ECase e as d      -> ECase <$> traverseNamesIP e+                                 <*> traverse traverseNamesIP as+                                 <*> traverse traverseNamesIP d        EComp t1 t2 e mss -> EComp <$> traverseNamesIP t1                                  <*> traverseNamesIP t2@@ -82,6 +85,11 @@       EPropGuards gs t  -> EPropGuards <$> traverse doG gs <*> traverseNamesIP t         where doG (xs, e) = (,) <$> traverseNamesIP xs <*> traverseNamesIP e +instance TraverseNames CaseAlt where+  traverseNamesIP (CaseAlt xs e) =+    CaseAlt <$> traverse doPair xs <*> traverseNamesIP e+      where doPair (x,y) = (,) <$> traverseNamesIP x <*> traverseNamesIP y+ instance TraverseNames Match where   traverseNamesIP mat =     case mat of@@ -110,7 +118,7 @@   traverseNamesIP d =     case d of       DPrim   -> pure d-      DForeign t -> DForeign <$> traverseNamesIP t+      DForeign t me -> DForeign <$> traverseNamesIP t <*> traverseNamesIP me       DExpr e -> DExpr <$> traverseNamesIP e  instance TraverseNames Schema where@@ -138,7 +146,7 @@       TPSchemaParam x   -> TPSchemaParam  <$> traverseNamesIP x       TPTySynParam x    -> TPTySynParam   <$> traverseNamesIP x       TPPropSynParam x  -> TPPropSynParam <$> traverseNamesIP x-      TPNewtypeParam x  -> TPNewtypeParam <$> traverseNamesIP x+      TPNominalParam x  -> TPNominalParam <$> traverseNamesIP x       TPPrimParam x     -> TPPrimParam    <$> traverseNamesIP x  instance TraverseNames TVarInfo where@@ -167,6 +175,8 @@       TypeFromUserAnnotation      -> pure src       GeneratorOfListComp         -> pure src       TypeErrorPlaceHolder        -> pure src+      CasedExpression             -> pure src+      ConPat                      -> pure src  instance TraverseNames ArgDescr where   traverseNamesIP arg = mk <$> traverseNamesIP (argDescrFun arg)@@ -175,50 +185,53 @@ instance TraverseNames Type where   traverseNamesIP ty =     case ty of-      TCon tc ts    -> TCon <$> traverseNamesIP tc <*> traverseNamesIP ts+      TCon tc ts    -> TCon 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+      TRec rm       -> TRec <$> traverseRecordMap (const traverseNamesIP) rm+      TNominal nt ts -> TNominal <$> 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 NominalType where+  traverseNamesIP nt =+    NominalType+      <$> traverseNamesIP (ntName nt)+      <*> traverseNamesIP (ntParams nt)+      <*> pure (ntKind nt)+      <*> traverseNamesIP (ntConstraints nt)+      <*> traverseNamesIP (ntDef nt)+      <*> pure (ntFixity nt)+      <*> pure (ntDoc nt)++instance TraverseNames NominalTypeDef where+  traverseNamesIP def =+    case def of+      Struct c -> Struct <$> traverseNamesIP c+      Enum cs  -> Enum   <$> traverseNamesIP cs+      Abstract -> pure Abstract++instance TraverseNames StructCon where+  traverseNamesIP c =+    StructCon <$> traverseNamesIP (ntConName c)+              <*> traverseRecordMap (const traverseNamesIP) (ntFields c)++instance TraverseNames EnumCon where+  traverseNamesIP c =+    EnumCon <$> traverseNamesIP (ecName c)+            <*> pure (ecNumber c)+            <*> traverseNamesIP (ecFields c)+            <*> pure (ecPublic c)+            <*> pure (ecDoc c)++  instance TraverseNames ModTParam where   traverseNamesIP nt = mk <$> traverseNamesIP (mtpName nt)
src/Cryptol/ModuleSystem/Base.hs view
@@ -54,7 +54,8 @@                                 , LoadedModuleG(..), lmInterface                                 , meCoreLint, CoreLint(..)                                 , ModContext(..), ModContextParams(..)-                                , ModulePath(..), modulePathLabel)+                                , ModulePath(..), modulePathLabel+                                , EvalForeignPolicy (..)) import           Cryptol.Backend.FFI import qualified Cryptol.Eval                 as E import qualified Cryptol.Eval.Concrete as Concrete@@ -79,7 +80,7 @@ import Cryptol.Utils.Ident ( preludeName, floatName, arrayName, suiteBName, primeECName                            , preludeReferenceName, interactiveName, modNameChunks                            , modNameToNormalModName )-import Cryptol.Utils.PP (pretty)+import Cryptol.Utils.PP (pretty, pp, hang, vcat, ($$), (<+>), (<.>), colon) import Cryptol.Utils.Panic (panic) import Cryptol.Utils.Logger(logPutStrLn, logPrint) import Cryptol.Utils.Benchmark@@ -306,33 +307,46 @@       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]+      getEvalForeignPolicy >>= \case+        AlwaysEvalForeign -> doEvalForeign (ffiLoadErrors (T.mName tcm))+        PreferEvalForeign -> doEvalForeign \errs ->+          withLogger logPrint $+            hang+              ("[warning] Could not load all foreign implementations for module"+                <+> pp (T.mName tcm) <.> colon) 4 $+              vcat (map pp errs)+              $$ "Fallback cryptol implementations will be used if available"+        NeverEvalForeign -> pure Nothing      where foreigns  = findForeignDecls tcm           foreignFs = T.findForeignDeclsInFunctors tcm           dups      = [ d | d@(_ : _ : _) <- groupBy ((==) `on` nameIdent)                                            $ sortBy (compare `on` nameIdent)                                            $ map fst foreigns ]+          doEvalForeign handleErrs =+            case path of+              InFile p -> io (loadForeignSrc p) >>=+                \case +                  Right fsrc -> do+                    unless quiet $+                      case getForeignSrcPath fsrc of+                        Just fpath -> withLogger logPutStrLn $+                          "Loading dynamic library " ++ takeFileName fpath+                        Nothing -> pure ()+                    (errs, ()) <-+                      modifyEvalEnvM (evalForeignDecls fsrc foreigns)+                    unless (null errs) $+                      handleErrs errs+                    pure $ Just fsrc +                  Left err -> do+                    handleErrs [err]+                    pure Nothing++              InMem m _ -> panic "doLoadModule"+                ["Can't find foreign source of in-memory module", m]+ -- | Rewrite an import declaration to be of the form: -- -- > import foo as foo [ [hiding] (a,b,c) ]@@ -434,27 +448,25 @@      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+findDepsOf mpath =+  do (fp, incs, ms) <- parseModule mpath      let (anyF,imps) = mconcat (map (findDeps' . addPrelude) ms)-     fpath <- if getAny anyF+     fdeps <- if getAny anyF                 then do mb <- io case mpath of-                                   InFile can -> foreignLibPath can-                                   InMem {}   -> pure Nothing+                                   InFile path -> foreignLibPath path+                                   InMem {}    -> pure Nothing                         pure case mb of-                               Nothing -> Set.empty-                               Just f  -> Set.singleton f-                else pure Set.empty+                               Nothing -> Map.empty+                               Just (fpath, exists) ->+                                 Map.singleton fpath exists+                else pure Map.empty      pure        ( mpath        , FileInfo            { fiFingerprint = fp            , fiIncludeDeps = incs            , fiImportDeps  = Set.fromList (map importedModule (appEndo imps []))-           , fiForeignDeps = fpath+           , fiForeignDeps = fdeps            }        ) @@ -605,12 +617,11 @@   renMod <- renameModule epgm  -{--  -- dump renamed+  {- 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@@ -631,7 +642,11 @@   rewMod <- case tcm of               T.TCTopModule mo -> T.TCTopModule <$> liftSupply (`rewModule` mo)               T.TCTopSignature {} -> pure tcm-  pure (R.rmInScope renMod,rewMod)+  let nameEnv = case tcm of+                  T.TCTopModule mo -> T.mInScope mo+                  -- Name env for signatures does not change after typechecking+                  T.TCTopSignature {} -> mInScope (R.rmModule renMod)+  pure (nameEnv,rewMod)  data TCLinter o = TCLinter   { lintCheck ::@@ -742,8 +757,7 @@     { T.inpRange            = r     , T.inpVars             = Map.map ifDeclSig (ifDecls env)     , T.inpTSyns            = ifTySyns env-    , T.inpNewtypes         = ifNewtypes env-    , T.inpAbstractTypes    = ifAbstractTypes env+    , T.inpNominalTypes     = ifNominalTypes env     , T.inpSignatures       = ifSignatures env     , T.inpNameSeeds        = seeds     , T.inpMonoBinds        = monoBinds
src/Cryptol/ModuleSystem/Binds.hs view
@@ -1,7 +1,6 @@ {-# Language BlockArguments #-} {-# Language RecordWildCards #-} {-# Language FlexibleInstances #-}-{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveTraversable #-} module Cryptol.ModuleSystem.Binds   ( BindsNames@@ -13,6 +12,7 @@   , topModuleDefs   , topDeclsDefs   , newModParam+  , newFunctorInst   , InModule(..)   , ifaceToMod   , ifaceSigToMod@@ -25,7 +25,7 @@ import Data.Set(Set) import qualified Data.Set as Set import Data.Maybe(fromMaybe)-import Control.Monad(foldM)+import Control.Monad(foldM,forM) import qualified MonadLib as M  import Cryptol.Utils.Panic (panic)@@ -125,7 +125,7 @@   , modState     = ()   }   where-  env = modParamsNamingEnv ps+  env = modParamNamesNamingEnv ps   @@ -323,6 +323,7 @@       Decl d           -> namingEnv (InModule ns (tlValue d))       DPrimType d      -> namingEnv (InModule ns (tlValue d))       TDNewtype d      -> namingEnv (InModule ns (tlValue d))+      TDEnum d         -> namingEnv (InModule ns (tlValue d))       DParamDecl {}    -> mempty       Include _        -> mempty       DImport {}       -> mempty -- see 'openLoop' in the renamer@@ -363,10 +364,22 @@   namingEnv (InModule ~(Just ns) Newtype { .. }) = BuildNamingEnv $     do let Located { .. } = nName        ntName    <- newTop NSType  ns thing Nothing srcRange-       ntConName <- newTop NSValue ns thing Nothing srcRange+       ntConName <- newTop NSConstructor ns thing Nothing srcRange        return (singletonNS NSType thing ntName `mappend`-               singletonNS NSValue thing ntConName)+               singletonNS NSConstructor thing ntConName) +instance BindsNames (InModule (EnumDecl PName)) where+  namingEnv (InModule (Just ns) EnumDecl { .. }) = BuildNamingEnv $+    do enName   <- newTop NSType ns (thing eName) Nothing (srcRange eName)+       conNames <- forM eCons \topc ->+                      do let c     = ecName (tlValue topc)+                             pname = thing c+                         cName <- newTop NSConstructor ns pname Nothing+                                                                  (srcRange c)+                         pure (singletonNS NSConstructor pname cName)+       pure (mconcat (singletonNS NSType (thing eName) enName : conNames))+  namingEnv _ = panic "namingEnv" ["Unreachable"]+ -- | The naming environment for a single declaration. instance BindsNames (InModule (Decl PName)) where   namingEnv (InModule pfx d) = case d of@@ -400,6 +413,17 @@       SigTySyn ts _    -> namingEnv (InModule m (DType ts))       SigPropSyn ps _  -> namingEnv (InModule m (DProp ps)) +instance BindsNames (Pattern PName) where+  namingEnv pat =+    case pat of+      PVar x -> BuildNamingEnv (+        do y <- newLocal NSValue (thing x) (srcRange x)+           pure (singletonNS NSValue (thing x) y)+        )+      PCon _ xs     -> mconcat (map namingEnv xs)+      PLocated p _r -> namingEnv p+      PTyped p _t   -> namingEnv p+      _ -> panic "namingEnv" ["Unexpected pattern"]   @@ -419,6 +443,13 @@ -- to the signature. newModParam :: FreshM m => ModPath -> Ident -> Range -> Name -> m Name newModParam m i rng n = liftSupply (mkModParam m i rng n)++-- | Given a name in a functor, make a fresh name for the corresponding thing in+-- the instantiation.+--+-- The 'ModPath' should be the instantiation not the functor.+newFunctorInst :: FreshM m => ModPath -> Name -> m Name+newFunctorInst m n = liftSupply (freshNameFor m n)   {- | Do something in the context of a module.
src/Cryptol/ModuleSystem/Env.hs view
@@ -61,40 +61,43 @@  -- | This is the current state of the interpreter. data ModuleEnv = ModuleEnv-  { meLoadedModules :: LoadedModules+  { meLoadedModules     :: LoadedModules     -- ^ Information about all loaded modules.  See 'LoadedModule'.     -- Contains information such as the file where the module was loaded     -- from, as well as the module's interface, used for type checking. -  , meNameSeeds     :: T.NameSeeds+  , meNameSeeds         :: T.NameSeeds     -- ^ A source of new names for the type checker. -  , meEvalEnv       :: EvalEnv+  , meEvalEnv           :: EvalEnv     -- ^ The evaluation environment.  Contains the values for all loaded     -- modules, both public and private. -  , meCoreLint      :: CoreLint+  , meCoreLint          :: CoreLint     -- ^ Should we run the linter to ensure sanity. -  , meMonoBinds     :: !Bool+  , meMonoBinds         :: !Bool     -- ^ Are we assuming that local bindings are monomorphic.     -- XXX: We should probably remove this flag, and set it to 'True'.   -  , meFocusedModule :: Maybe ModName+  , meFocusedModule     :: Maybe ModName     -- ^ The "current" module.  Used to decide how to print names, for example. -  , meSearchPath    :: [FilePath]+  , meSearchPath        :: [FilePath]     -- ^ Where we look for things. -  , meDynEnv        :: DynamicEnv+  , meDynEnv            :: DynamicEnv     -- ^ This contains additional definitions that were made at the command     -- line, and so they don't reside in any module. -  , meSupply        :: !Supply+  , meSupply            :: !Supply     -- ^ Name source for the renamer +  , meEvalForeignPolicy :: EvalForeignPolicy+    -- ^ How to evaluate @foreign@ bindings.+   } deriving Generic  instance NFData ModuleEnv where@@ -105,6 +108,26 @@               | CoreLint          -- ^ Run core lint   deriving (Generic, NFData) +-- | How to evaluate @foreign@ bindings.+data EvalForeignPolicy+  -- | Use foreign implementation and report an error at module load time if it+  -- is unavailable.+  = AlwaysEvalForeign+  -- | Use foreign implementation by default, and when unavailable, fall back to cryptol implementation if present and report runtime error otherwise.+  | PreferEvalForeign+  -- | Always use cryptol implementation if present, and report runtime error+  -- otherwise.+  | NeverEvalForeign+  deriving Eq++defaultEvalForeignPolicy :: EvalForeignPolicy+defaultEvalForeignPolicy =+#ifdef FFI_ENABLED+  PreferEvalForeign+#else+  NeverEvalForeign+#endif+ resetModuleEnv :: ModuleEnv -> IO ModuleEnv resetModuleEnv env = do   for_ (getLoadedModules $ meLoadedModules env) $ \lm ->@@ -153,16 +176,17 @@                    ]    return ModuleEnv-    { meLoadedModules = mempty-    , meNameSeeds     = T.nameSeeds-    , meEvalEnv       = mempty-    , meFocusedModule = Nothing+    { meLoadedModules     = mempty+    , meNameSeeds         = T.nameSeeds+    , meEvalEnv           = mempty+    , meFocusedModule     = Nothing       -- we search these in order, taking the first match-    , meSearchPath    = searchPath-    , meDynEnv        = mempty-    , meMonoBinds     = True-    , meCoreLint      = NoCoreLint-    , meSupply        = emptySupply+    , meSearchPath        = searchPath+    , meDynEnv            = mempty+    , meMonoBinds         = True+    , meCoreLint          = NoCoreLint+    , meSupply            = emptySupply+    , meEvalForeignPolicy = defaultEvalForeignPolicy     }  -- | Try to focus a loaded module in the module environment.@@ -182,9 +206,9 @@ loadedNonParamModules :: ModuleEnv -> [T.Module] loadedNonParamModules = map lmModule . lmLoadedModules . meLoadedModules -loadedNewtypes :: ModuleEnv -> Map Name T.Newtype-loadedNewtypes menv = Map.unions-   [ ifNewtypes (ifDefines i) <> ifNewtypes (ifDefines i)+loadedNominalTypes :: ModuleEnv -> Map Name T.NominalType+loadedNominalTypes menv = Map.unions+   [ ifNominalTypes (ifDefines i) <> ifNominalTypes (ifDefines i)    | i <- map lmInterface (getLoadedModules (meLoadedModules menv))    ] @@ -540,7 +564,7 @@   { fiFingerprint :: Fingerprint   , fiIncludeDeps :: Set FilePath   , fiImportDeps  :: Set ModName-  , fiForeignDeps :: Set FilePath+  , fiForeignDeps :: Map FilePath Bool   } deriving (Show,Generic,NFData)  @@ -555,9 +579,10 @@     { fiFingerprint = fp     , fiIncludeDeps = incDeps     , fiImportDeps  = impDeps-    , fiForeignDeps = fromMaybe Set.empty+    , fiForeignDeps = fromMaybe Map.empty                       do src <- fsrc-                         Set.singleton <$> getForeignSrcPath src+                         fpath <- getForeignSrcPath src+                         pure $ Map.singleton fpath True     }  @@ -599,8 +624,7 @@ deIfaceDecls :: DynamicEnv -> IfaceDecls deIfaceDecls DEnv { deDecls = dgs, deTySyns = tySyns } =     IfaceDecls { ifTySyns = tySyns-               , ifNewtypes = Map.empty-               , ifAbstractTypes = Map.empty+               , ifNominalTypes = Map.empty                , ifDecls = decls                , ifModules = Map.empty                , ifFunctors = Map.empty
src/Cryptol/ModuleSystem/Exports.hs view
@@ -11,7 +11,8 @@ import GHC.Generics (Generic)  import Cryptol.Parser.AST-import Cryptol.Parser.Names(namesD,tnamesD,namesNT,tnamesNT)+import Cryptol.Parser.Names+         (namesD,tnamesD,namesNT,tnamesNT,tnamesEnum,namesEnum) import Cryptol.ModuleSystem.Name  exportedDecls :: Ord name => [TopDecl name] -> ExportSpec name@@ -24,7 +25,9 @@               ++ map exportType (names tnamesD td)       DPrimType t -> [ exportType (thing . primTName <$> t) ]       TDNewtype nt -> map exportType (names tnamesNT nt) ++-                      map exportBind (names namesNT nt)+                      map exportCon (names namesNT nt)+      TDEnum en -> map exportType (names tnamesEnum en)+                ++ map exportCon (names namesEnum en)       Include {}  -> []       DImport {} -> []       DParamDecl {} -> []@@ -67,6 +70,10 @@ exportBind :: Ord name => TopLevel name -> ExportSpec name exportBind = exportName NSValue +-- | Add a constructor name to the export list, if it should be exported.+exportCon :: Ord name => TopLevel name -> ExportSpec name+exportCon = exportName NSConstructor+ -- | Add a type synonym name to the export list, if it should be exported. exportType :: Ord name => TopLevel name -> ExportSpec name exportType = exportName NSType@@ -81,7 +88,7 @@  -- | Check to see if a binding is exported. isExportedBind :: Ord name => name -> ExportSpec name -> Bool-isExportedBind = isExported NSValue+isExportedBind x s = isExported NSValue x s || isExported NSConstructor x s  -- | Check to see if a type synonym is exported. isExportedType :: Ord name => name -> ExportSpec name -> Bool
src/Cryptol/ModuleSystem/Interface.hs view
@@ -97,8 +97,7 @@ -- modules, but not things from nested functors, which are in `ifFunctors`. data IfaceDecls = IfaceDecls   { ifTySyns        :: Map.Map Name TySyn-  , ifNewtypes      :: Map.Map Name Newtype-  , ifAbstractTypes :: Map.Map Name AbstractType+  , ifNominalTypes  :: Map.Map Name NominalType   , ifDecls         :: Map.Map Name IfaceDecl   , ifModules       :: !(Map.Map Name (IfaceNames Name))   , ifSignatures    :: !(Map.Map Name ModParamNames)@@ -117,8 +116,7 @@ filterIfaceDecls :: (Name -> Bool) -> IfaceDecls -> IfaceDecls filterIfaceDecls p ifs = IfaceDecls   { ifTySyns        = filterMap (ifTySyns ifs)-  , ifNewtypes      = filterMap (ifNewtypes ifs)-  , ifAbstractTypes = filterMap (ifAbstractTypes ifs)+  , ifNominalTypes  = filterMap (ifNominalTypes ifs)   , ifDecls         = filterMap (ifDecls ifs)   , ifModules       = filterMap (ifModules ifs)   , ifFunctors      = filterMap (ifFunctors ifs)@@ -130,8 +128,7 @@  ifaceDeclsNames :: IfaceDecls -> Set Name ifaceDeclsNames i = Set.unions [ Map.keysSet (ifTySyns i)-                               , Map.keysSet (ifNewtypes i)-                               , Map.keysSet (ifAbstractTypes i)+                               , Map.keysSet (ifNominalTypes i)                                , Map.keysSet (ifDecls i)                                , Map.keysSet (ifModules i)                                , Map.keysSet (ifFunctors i)@@ -142,8 +139,7 @@ instance Semigroup IfaceDecls where   l <> r = IfaceDecls     { ifTySyns   = Map.union (ifTySyns l)   (ifTySyns r)-    , ifNewtypes = Map.union (ifNewtypes l) (ifNewtypes r)-    , ifAbstractTypes = Map.union (ifAbstractTypes l) (ifAbstractTypes r)+    , ifNominalTypes = Map.union (ifNominalTypes l) (ifNominalTypes r)     , ifDecls    = Map.union (ifDecls l)    (ifDecls r)     , ifModules  = Map.union (ifModules l)  (ifModules r)     , ifFunctors = Map.union (ifFunctors l) (ifFunctors r)@@ -153,8 +149,7 @@ instance Monoid IfaceDecls where   mempty      = IfaceDecls                   { ifTySyns = mempty-                  , ifNewtypes = mempty-                  , ifAbstractTypes = mempty+                  , ifNominalTypes = mempty                   , ifDecls = mempty                   , ifModules = mempty                   , ifFunctors = mempty@@ -163,8 +158,7 @@   mappend = (<>)   mconcat ds  = IfaceDecls     { ifTySyns   = Map.unions (map ifTySyns   ds)-    , ifNewtypes = Map.unions (map ifNewtypes ds)-    , ifAbstractTypes = Map.unions (map ifAbstractTypes ds)+    , ifNominalTypes = Map.unions (map ifNominalTypes ds)     , ifDecls    = Map.unions (map ifDecls    ds)     , ifModules  = Map.unions (map ifModules ds)     , ifFunctors = Map.unions (map ifFunctors ds)@@ -194,8 +188,8 @@  ifaceDeclsPrimMap :: IfaceDecls -> PrimMap ifaceDeclsPrimMap IfaceDecls { .. } =-  PrimMap { primDecls = Map.fromList (newtypes ++ exprs)-          , primTypes = Map.fromList (newtypes ++ types)+  PrimMap { primDecls = Map.fromList (nominalVs ++ exprs)+          , primTypes = Map.fromList (nominalTs ++ types)           }   where   entry n = case asPrim n of@@ -205,9 +199,13 @@                           [ "Top level name not declared in a module?"                           , show n ] -  newtypes = map entry (Map.keys ifNewtypes)-  exprs    = map entry (Map.keys ifDecls)-  types    = map entry (Map.keys ifTySyns)+  nominalTs = map entry (Map.keys ifNominalTypes)+  nominalVs = [ entry n+              | nt <- Map.elems ifNominalTypes+              , (n,_) <- nominalTypeConTypes nt+              ]+  exprs     = map entry (Map.keys ifDecls)+  types     = map entry (Map.keys ifTySyns)   -- | Given an interface computing a map from original names to actual names,@@ -227,10 +225,12 @@    decls       = ifDefines ifa   from f      = Map.keysSet (f decls)-  tyNames     = Set.unions [ from ifTySyns, from ifNewtypes, from ifAbstractTypes ]+  tyNames     = Set.unions [ from ifTySyns, from ifNominalTypes ]   moNames     = Set.unions [ from ifModules, from ifSignatures, from ifFunctors ]   vaNames     = Set.unions [ newtypeCons, from ifDecls ]-  newtypeCons = Set.fromList (map ntConName (Map.elems (ifNewtypes decls)))+  newtypeCons = Set.fromList+                  (concatMap conNames (Map.elems (ifNominalTypes decls)))+    where conNames = map fst . nominalTypeConTypes   
src/Cryptol/ModuleSystem/Monad.hs view
@@ -508,6 +508,9 @@ getMonoBinds :: ModuleM Bool getMonoBinds  = ModuleT (meMonoBinds `fmap` get) +getEvalForeignPolicy :: ModuleM EvalForeignPolicy+getEvalForeignPolicy = ModuleT (meEvalForeignPolicy <$> get)+ setMonoBinds :: Bool -> ModuleM () setMonoBinds b = ModuleT $ do   env <- get@@ -571,8 +574,8 @@   do act <- getEvalOptsAction      liftIO act -getNewtypes :: ModuleM (Map T.Name T.Newtype)-getNewtypes = ModuleT (loadedNewtypes <$> get)+getNominalTypes :: ModuleM (Map T.Name T.NominalType)+getNominalTypes = ModuleT (loadedNominalTypes <$> get)  getFocusedModule :: ModuleM (Maybe P.ModName) getFocusedModule  = ModuleT (meFocusedModule `fmap` get)
src/Cryptol/ModuleSystem/Name.hs view
@@ -29,6 +29,7 @@   , nameLoc   , nameFixity   , nameNamespace+  , nameToDefPName   , asPrim   , asOrigName   , nameModPath@@ -70,7 +71,8 @@ import           Data.Char(isAlpha,toUpper)  -+import           Cryptol.Parser.Name (PName)+import qualified Cryptol.Parser.Name as PName import           Cryptol.Parser.Position (Range,Located(..)) import           Cryptol.Utils.Fixity import           Cryptol.Utils.Ident@@ -146,9 +148,9 @@                  NotInScope  ->                     let m = Text.pack (show (pp (ogModule og)))                     in-                    case ogSource og of-                      FromModParam q  -> m <> "::" <> Text.pack (show (pp q))-                      _ -> m+                    case ogFromParam og of+                      Just q  -> m <> "::" <> Text.pack (show (pp q))+                      Nothing -> m    -- Note that this assumes that `xs` is `l` and `ys` is `r`   cmpText xs ys =@@ -227,12 +229,21 @@ nameFixity :: Name -> Maybe Fixity nameFixity = nFixity +-- | Compute a `PName` for the definition site corresponding to the given+-- `Name`.   Usually this is an unqualified name, but names that come+-- from module parameters are qualified with the corresponding parameter name.+nameToDefPName :: Name -> PName+nameToDefPName n =+  case nInfo n of+    GlobalName _ og -> PName.origNameToDefPName og+    LocalName _ txt -> PName.mkUnqual txt+ -- | Primtiives must be in a top level module, at least for now. asPrim :: Name -> Maybe PrimIdent asPrim n =   case nInfo n of     GlobalName _ og-      | TopModule m <- ogModule og, not (ogFromModParam og) ->+      | TopModule m <- ogModule og, not (ogIsModParam og) ->         Just $ PrimIdent m $ identText $ ogName og      _ -> Nothing@@ -371,6 +382,7 @@                                 , ogModule    = m                                 , ogName      = ident                                 , ogSource    = FromDefinition+                                , ogFromParam = Nothing                                 }               } @@ -410,7 +422,8 @@                               { ogModule    = own                               , ogName      = nameIdent n                               , ogNamespace = nameNamespace n-                              , ogSource    = FromModParam pname+                              , ogSource    = FromModParam+                              , ogFromParam = Just pname                               }               , nFixity = nFixity n               , nLoc    = rng
src/Cryptol/ModuleSystem/NamingEnv.hs view
@@ -6,14 +6,14 @@ -- Stability   :  provisional -- Portability :  portable -{-# LANGUAGE DeriveAnyClass #-}-{-# LANGUAGE DeriveGeneric #-} {-# 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+module Cryptol.ModuleSystem.NamingEnv+  ( module Cryptol.ModuleSystem.NamingEnv.Types+  , module Cryptol.ModuleSystem.NamingEnv+  ) where  import Data.Maybe (mapMaybe,maybeToList) import           Data.Map.Strict (Map)@@ -22,9 +22,6 @@ import qualified Data.Set as Set import           Data.Foldable(foldl') -import GHC.Generics (Generic)-import Control.DeepSeq(NFData)- import Cryptol.Utils.PP import Cryptol.Utils.Panic (panic) import Cryptol.Utils.Ident(allNamespaces)@@ -34,24 +31,7 @@ import Cryptol.ModuleSystem.Names import Cryptol.ModuleSystem.Interface ---- | The 'NamingEnv' is used by the renamer to determine what--- identifiers refer to.-newtype NamingEnv = NamingEnv (Map Namespace (Map PName Names))-  deriving (Show,Generic,NFData)--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)--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))+import Cryptol.ModuleSystem.NamingEnv.Types   {- | This "joins" two naming environments by matching the text name.@@ -91,14 +71,16 @@     Just (One x) -> Set.singleton x     Just (Ambig as) -> as --- | Get a unqualified naming environment for the given names+-- | Get a naming environment for the given names.  The `PName`s correspond+-- to the definition sites of the corresponding `Name`s, so typically they+-- will be unqualified.  The exception is for names that comre from parameters,+-- which are qualified with the relevant parameter. namingEnvFromNames :: Set Name -> NamingEnv namingEnvFromNames xs = NamingEnv (foldl' add mempty xs)   where   add mp x = let ns = nameNamespace x-                 txt = nameIdent x              in Map.insertWith (Map.unionWith (<>))-                               ns (Map.singleton (mkUnqual txt) (One x))+                               ns (Map.singleton (nameToDefPName x) (One x))                                mp  @@ -191,11 +173,13 @@ -- | Find the ambiguous entries in an environmet. -- A name is ambiguous if it might refer to multiple entities. findAmbig :: NamingEnv -> [ [Name] ]-findAmbig (NamingEnv ns) =+findAmbig env =   [ Set.toList xs   | mp <- Map.elems ns   , Ambig xs <- Map.elems mp   ]+  where+  NamingEnv ns = consToValues env  -- | Get the subset of the first environment that shadows something -- in the second one.@@ -231,8 +215,8 @@  -- | Compute an unqualified naming environment, containing the various module -- parameters.-modParamsNamingEnv :: T.ModParamNames -> NamingEnv-modParamsNamingEnv T.ModParamNames { .. } =+modParamNamesNamingEnv :: T.ModParamNames -> NamingEnv+modParamNamesNamingEnv T.ModParamNames { .. } =   NamingEnv $ Map.fromList     [ (NSValue, Map.fromList $ map fromFu $ Map.keys mpnFuns)     , (NSType,  Map.fromList $ map fromTS (Map.elems mpnTySyn) ++@@ -248,12 +232,17 @@    fromTS ts = (toPName (T.tsName ts), One (T.tsName ts)) +-- | Compute a naming environment from a module parameter, qualifying it+-- according to 'mpQual'.+modParamNamingEnv :: T.ModParam -> NamingEnv+modParamNamingEnv mp = maybe id qualify (T.mpQual mp) $+  modParamNamesNamingEnv (T.mpParameters mp)  -- | 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 ]+  mconcat [ exprs, tySyns, ntTypes, ntExprs, mods, sigs ]   where   toPName n = mkUnqual (nameIdent n) @@ -264,19 +253,16 @@                     | n <- Map.keys ifTySyns ]    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+                    | nt <- Map.elems ifNominalTypes+                    , let tname  = T.ntName nt+                    , n  <- singletonNS NSType (toPName tname) tname+                          : [ singletonNS NSValue (toPName cname) cname+                            | cname <-map fst (T.nominalTypeConTypes nt)                             ]                     ] -  absTys  = mconcat [ singletonNS NSType (toPName n) n-                    | n <- Map.keys ifAbstractTypes ]-   ntExprs = mconcat [ singletonNS NSValue (toPName n) n-                    | n <- Map.keys ifNewtypes ]+                    | n <- Map.keys ifNominalTypes ]    mods    = mconcat [ singletonNS NSModule (toPName n) n                     | n <- Map.keys ifModules ]
+ src/Cryptol/ModuleSystem/NamingEnv/Types.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE DeriveAnyClass    #-}+{-# LANGUAGE DeriveGeneric     #-}+{-# LANGUAGE OverloadedStrings #-}++module Cryptol.ModuleSystem.NamingEnv.Types where++import           Data.Map.Strict            (Map)+import qualified Data.Map.Strict            as Map++import           Control.DeepSeq            (NFData)+import           GHC.Generics               (Generic)++import           Cryptol.ModuleSystem.Names+import           Cryptol.Parser.Name+import           Cryptol.Utils.Ident+import           Cryptol.Utils.PP++-- | The 'NamingEnv' is used by the renamer to determine what+-- identifiers refer to.+newtype NamingEnv = NamingEnv (Map Namespace (Map PName Names))+  deriving (Show,Generic,NFData)++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)++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))++-- | Move names in the constructor namespace to the value namespace.+-- This is handy when checking for ambiguities.+consToValues :: NamingEnv -> NamingEnv+consToValues (NamingEnv mps) =+  NamingEnv $+  case Map.updateLookupWithKey (\_ _ -> Nothing) NSConstructor mps of+    (Nothing, mp1) -> mp1+    (Just conMap, mp1) -> Map.insertWith (Map.unionWith (<>)) NSValue conMap mp1
src/Cryptol/ModuleSystem/Renamer.hs view
@@ -118,7 +118,6 @@ 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.  This provides the types for external     -- names (used by the type-checker).@@ -152,12 +151,11 @@       setResolvedLocals resolvedMods $        setNestedModule pathToName-       do (ifs,(inScope,m1)) <- collectIfaceDeps (renameModule' mname m)+       do (ifs,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?                  }@@ -220,12 +218,9 @@ renameModule' ::   ImpName Name {- ^ Resolved name for this module -} ->   ModuleG mname PName ->-  RenameM (NamingEnv, ModuleG mname Name)+  RenameM (ModuleG mname Name) renameModule' mname m =-  setCurMod-    case mname of-      ImpTop r    -> TopModule r-      ImpNested r -> Nested (nameModPath r) (nameIdent r)+  setCurMod (impNameModPath mname)    do resolved <- lookupResolved mname      shadowNames' CheckNone (rmodImports resolved)@@ -247,7 +242,7 @@                      let exports = exportedDecls ds1                      mapM_ recordUse (exported NSType exports)                      inScope <- getNamingEnv-                     pure (inScope, m { mDef = NormalModule ds1 })+                     pure m { mDef = NormalModule ds1, mInScope = inScope }           -- The things defined by this module are the *results*          -- of the instantiation, so we should *not* add them@@ -260,30 +255,20 @@               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+              -- This inScope is incomplete; it only contains names from the+              -- enclosing scope, but we also want the names in scope from the+              -- functor, for ease of testing at the command line. We will fix+              -- this up in doFunctorInst in the typechecker, because right now+              -- we don't have access yet to the inScope of the functor.+              inScope <- getNamingEnv -              pure (inScope, m { mDef = FunctorInstance f' as' imap })+              pure m { mDef = FunctorInstance f' as' imap, mInScope = inScope }           InterfaceModule s ->            shadowNames' CheckNone (rmodDefines resolved)              do d <- InterfaceModule <$> renameIfaceModule mname s                 inScope <- getNamingEnv-                pure (inScope, m { mDef = d })+                pure m { mDef = d, mInScope = inScope }   checkFunctorArgs :: ModuleInstanceArgs Name -> RenameM ()@@ -547,6 +532,7 @@       Decl tl                 -> isValDecl (tlValue tl)       DPrimType {}            -> False       TDNewtype {}            -> False+      TDEnum {}               -> False       DParamDecl {}           -> False       DInterfaceConstraint {} -> False @@ -599,6 +585,9 @@     DPrimType d             -> hasName (thing (primTName (tlValue d)))     TDNewtype d             -> hasName' (thing (nName (tlValue d)))                                         [ nConName (tlValue d) ]+    TDEnum d                -> hasName' (thing (eName (tlValue d)))+                                        (map (thing . ecName . tlValue)+                                             (eCons (tlValue d)))     DModule d               -> hasName (thing (mName m))       where NestedModule m = tlValue d @@ -696,9 +685,10 @@       forM_ repeated \ps ->        case ps of+         [] -> panic "doModParams" ["[]"]          [_]      -> pure ()-         ~(p : _) -> recordError (MultipleModParams (renModParamName p)-                                                    (map renModParamRange ps))+         (p : _) -> recordError (MultipleModParams (renModParamName p)+                                                   (map renModParamRange ps))       pure (mconcat paramEnvs,params) @@ -723,6 +713,7 @@       Decl d            -> Decl      <$> traverse rename d       DPrimType d       -> DPrimType <$> traverse rename d       TDNewtype n       -> TDNewtype <$> traverse rename n+      TDEnum n          -> TDEnum    <$> traverse rename n       Include n         -> return (Include n)       DModule m  -> DModule <$> traverse rename m       DImport li -> DImport <$> renI li@@ -820,10 +811,8 @@            nm             = thing lnm        n   <- resolveName NameBind NSModule nm        depsOf (NamedThing n)-         do -- XXX: we should store in scope somewhere if we want to browse-            -- nested modules properly-            let m' = m { mName = ImpNested <$> mName m }-            (_inScope,m1) <- renameModule' (ImpNested n) m'+         do let m' = m { mName = ImpNested <$> mName m }+            m1 <- renameModule' (ImpNested n) m'             pure (NestedModule m1 { mName = lnm { thing = n } })  @@ -881,7 +870,7 @@   rename n      =     shadowNames (nParams n) $     do nameT <- rnLocated (renameType NameBind) (nName n)-       nameC <- renameVar  NameBind (nConName n)+       nameC <- renameCon NameBind (nConName n)         depsOf (NamedThing nameC) (addDep (thing nameT)) @@ -893,9 +882,28 @@                            , nParams = ps'                            , nBody   = body' } -+instance Rename EnumDecl where+  rename n =+    shadowNames (eParams n) $+    do nameT  <- rnLocated (renameType NameBind) (eName n)+       nameCs <- forM (eCons n) \tlEc ->+                   do let con = tlValue tlEc+                      nameC <- rnLocated (renameCon NameBind) (ecName con)+                      depsOf (NamedThing (thing nameC)) (addDep (thing nameT))+                      pure (nameC,tlEc)+       depsOf (NamedThing (thing nameT)) $+         do ps' <- traverse rename (eParams n)+            cons <- forM nameCs \(c,tlEc) ->+                     do ts' <- traverse rename (ecFields (tlValue tlEc))+                        let con = EnumCon { ecName = c, ecFields = ts' }+                        pure tlEc { tlValue = con }+            pure EnumDecl { eName = nameT+                          , eParams = ps'+                          , eCons = cons+                          } --- | Try to resolve a name+-- | Try to resolve a name.+-- SPECIAL CASE: if we have a NameUse for NSValue, we also look in NSConstructor resolveNameMaybe :: NameType -> Namespace -> PName -> RenameM (Maybe Name) resolveNameMaybe nt expected qn =   do ro <- RenameM ask@@ -903,7 +911,14 @@          use = case expected of                  NSType -> recordUse                  _      -> const (pure ())-     case lkpIn expected of+         checkCon = case (nt,expected) of+                      (NameUse, NSValue) -> lkpIn NSConstructor+                      _ -> Nothing+         found = case (lkpIn expected, checkCon) of+                   (Just a, Just b) -> Just (a <> b)+                   (Nothing, y)     -> y+                   (x, Nothing)     -> x+     case found of        Just xs ->          case xs of           One n ->@@ -948,7 +963,7 @@         Nothing -> False  --- | Resolve a name, and report error on failure+-- | Resolve a name, and report error on failure. resolveName :: NameType -> Namespace -> PName -> RenameM Name resolveName nt expected qn =   do mb <- resolveNameMaybe nt expected qn@@ -960,6 +975,9 @@ renameVar :: NameType -> PName -> RenameM Name renameVar nt = resolveName nt NSValue +renameCon :: NameType -> PName -> RenameM Name+renameCon nt = resolveName nt NSConstructor+ renameType :: NameType -> PName -> RenameM Name renameType nt = resolveName nt NSType @@ -1063,8 +1081,11 @@                           }  instance Rename BindDef where-  rename DPrim     = return DPrim-  rename DForeign  = return DForeign+  rename DPrim        = return DPrim+  rename (DForeign i) = DForeign <$> traverse rename i+  rename (DImpl i)    = DImpl <$> rename i++instance Rename BindImpl where   rename (DExpr e) = DExpr <$> rename e   rename (DPropGuards cases) = DPropGuards <$> traverse rename cases @@ -1072,10 +1093,11 @@   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     PVar lv         -> PVar <$> rnLocated (renameVar NameBind) lv+    PCon c ps       -> PCon <$> rnLocated (renameCon NameUse)  c+                            <*> traverse rename ps     PWild           -> pure PWild     PTuple ps       -> PTuple   <$> traverse rename ps     PRecord nps     -> PRecord  <$> traverse (traverse rename) nps@@ -1153,6 +1175,7 @@     EApp f x        -> EApp    <$> rename f  <*> rename x     EAppT f ti      -> EAppT   <$> rename f  <*> traverse rename ti     EIf b t f       -> EIf     <$> rename b  <*> rename t  <*> rename f+    ECase e as      -> ECase   <$> rename e  <*> traverse rename as     EWhere e' ds    -> shadowNames (map (InModule Nothing) ds) $                           EWhere <$> rename e' <*> renameDecls ds     ETyped e' ty    -> ETyped  <$> rename e' <*> rename ty@@ -1326,7 +1349,7 @@     do n <- liftSupply (mkLocal NSValue (getIdent thing) srcRange)        -- XXX: for deps, we should record a use        return (singletonNS NSValue thing n)-+  go (PCon _ ps)      = bindVars ps   go PWild            = return mempty   go (PTuple ps)      = bindVars ps   go (PRecord fs)     = bindVars (fmap snd (recordElements fs))@@ -1389,6 +1412,8 @@          do res <- bindTypes ts             return (env' `mappend` res) +instance Rename CaseAlt where+  rename (CaseAlt p e) = shadowNames p (CaseAlt <$> rename p <*> rename e)  instance Rename Match where   rename m = case m of@@ -1416,8 +1441,6 @@     doc =       vcat [ "// --- Defines -----------------------------"            , pp (rmDefines rn)-           , "// --- In scope ----------------------------"-           , pp (rmInScope rn)            , "// -- Module -------------------------------"            , pp (rmModule rn)            , "// -----------------------------------------"
src/Cryptol/ModuleSystem/Renamer/Error.hs view
@@ -119,6 +119,7 @@                     NSValue   -> "Value"                     NSType    -> "Type"                     NSModule  -> "Module"+                    NSConstructor -> "Constructor"      OverlappingSyms qns ->       hang (text "[error]")@@ -134,6 +135,7 @@         where         sayNS ns = case ns of                      NSValue  -> "value"+                     NSConstructor -> "constructor"                      NSType   -> "type"                      NSModule -> "module"         suggestion =@@ -141,6 +143,8 @@              (NSValue,NSType) ->                 ["Did you mean `(" <.> pp (thing lqn) <.> text")?"]+            (NSConstructor,NSValue) ->+                ["Perhaps the constructor got shadowed?"]             _ -> []      FixityError o1 f1 o2 f2 ->@@ -159,13 +163,16 @@       ppLab as = ppNestedSels (thing as) <+> "at" <+> pp (srcRange as)      InvalidDependency ds ->-      hang "[error] Invalid recursive dependency:"+      hang ("[error] Invalid" <+> self <+>"dependency:")          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)+            self = case ds of+                     [_] -> "self"+                     _   -> "recursive"      MultipleModParams x rs ->       hang ("[error] Multiple parameters with name" <+> backticks (pp x))@@ -195,6 +202,7 @@           NSModule -> "submodule" <+> pp n           NSType   -> "type" <+> pp n           NSValue  -> pp n+          NSConstructor -> "constructor" <+> pp n       ModParamName _r i -> "module parameter" <+> pp i       ModPath mp ->         case modPathSplit mp of
src/Cryptol/ModuleSystem/Renamer/Imports.hs view
@@ -67,10 +67,11 @@  import Cryptol.Parser.AST   ( ImportG(..),PName, ModuleInstanceArgs(..), ImpName(..) )-import Cryptol.ModuleSystem.Binds (Mod(..), TopDef(..), modNested, ModKind(..))+import Cryptol.ModuleSystem.Binds+          ( Mod(..), TopDef(..), modNested, ModKind(..), newFunctorInst ) import Cryptol.ModuleSystem.Name-          ( Name, Supply, SupplyT, runSupplyT, liftSupply, freshNameFor-          , asOrigName, nameIdent, nameTopModule )+          ( Name, Supply, SupplyT, runSupplyT, asOrigName, nameIdent+          , nameTopModule ) import Cryptol.ModuleSystem.Names(Names(..)) import Cryptol.ModuleSystem.NamingEnv           ( NamingEnv(..), lookupNS, shadowing, travNamingEnv@@ -511,7 +512,7 @@    instName :: Name -> SupplyT (M.StateT (Set (Name,Name)) M.Id) Name   instName x =-    do y <- liftSupply (freshNameFor mpath x)+    do y <- newFunctorInst mpath x        when (x `Set.member` rmodNested def)             (M.lift (M.sets_ (Set.insert (x,y))))        pure y
src/Cryptol/Parser.y view
@@ -76,6 +76,7 @@    'type'      { Located $$ (Token (KW KW_type   ) _)}   'newtype'   { Located $$ (Token (KW KW_newtype) _)}+  'enum'      { Located $$ (Token (KW KW_enum) _)}   'module'    { Located $$ (Token (KW KW_module ) _)}   'submodule' { Located $$ (Token (KW KW_submodule ) _)}   'where'     { Located $$ (Token (KW KW_where  ) _)}@@ -83,6 +84,8 @@   'if'        { Located $$ (Token (KW KW_if     ) _)}   'then'      { Located $$ (Token (KW KW_then   ) _)}   'else'      { Located $$ (Token (KW KW_else   ) _)}+  'case'      { Located $$ (Token (KW KW_case) _)}+  'of'        { Located $$ (Token (KW KW_of) _)}   'interface' { Located $$ (Token (KW KW_interface) _)}   'x'         { Located $$ (Token (KW KW_x)       _)}   'down'      { Located $$ (Token (KW KW_down)    _)}@@ -280,11 +283,12 @@   : decl                   { [exportDecl Nothing   Public $1]                 }   | doc decl               { [exportDecl (Just $1) Public $2]                 }   | mbDoc 'include' STRLIT {% (return . Include) `fmap` fromStrLit $3         }-  | mbDoc 'property' name apats '=' expr+  | mbDoc 'property' name iapats '=' expr                            { [exportDecl $1 Public (mkProperty $3 $4 $6)]     }   | mbDoc 'property' name       '=' expr                            { [exportDecl $1 Public (mkProperty $3 [] $5)]     }   | mbDoc newtype          { [exportNewtype Public $1 $2]                     }+  | mbDoc enum             { [exportEnum Public $1 $2]                        }   | prim_bind              { $1                                               }   | foreign_bind           { $1                                               }   | private_decls          { $1                                               }@@ -367,18 +371,18 @@   : 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+  | var iapats_indices propguards_cases                            {% mkPropGuardsDecl $1 $2 $3 }   | var propguards_cases                            {% mkConstantPropGuardsDecl $1 $2 }-  | var apats_indices '=' expr+  | var iapats_indices '=' expr                            { at ($1,$4) $ mkIndexedDecl $1 $2 $4 } -  | apat pat_op apat '=' expr+  | iapat pat_op iapat '=' expr                            { at ($1,$5) $                              DBind $ Bind { bName      = $2                                           , bParams    = [$1,$3]-                                          , bDef       = at $5 (Located emptyRange (DExpr $5))+                                          , bDef       = at $5 (Located emptyRange (exprDef $5))                                           , bSignature = Nothing                                           , bPragmas   = []                                           , bMono      = False@@ -402,13 +406,13 @@  let_decl                :: { Decl PName }   : 'let' ipat '=' expr               { at ($2,$4) $ DPatBind $2 $4                    }-  | 'let' var apats_indices '=' expr  { at ($2,$5) $ mkIndexedDecl $2 $3 $5 }+  | 'let' var iapats_indices '=' expr  { at ($2,$5) $ mkIndexedDecl $2 $3 $5 }   | 'let' '(' op ')' '=' expr         { at ($2,$6) $ DPatBind (PVar $3) $6             }-  | 'let' apat pat_op apat '=' expr+  | 'let' iapat pat_op iapat '=' expr                            { at ($2,$6) $                              DBind $ Bind { bName      = $3                                           , bParams    = [$2,$4]-                                          , bDef       = at $6 (Located emptyRange (DExpr $6))+                                          , bDef       = at $6 (Located emptyRange (exprDef $6))                                           , bSignature = Nothing                                           , bPragmas   = []                                           , bMono      = False@@ -453,6 +457,19 @@   : '{' '}'                {% mkRecord (rComb $1 $2) (Located emptyRange) [] }   | '{' field_types '}'    {% mkRecord (rComb $1 $3) (Located emptyRange) $2 } ++enum                              :: { EnumDecl PName }+  : 'enum' type '=' enum_body        {% mkEnumDecl $2 $4 }++enum_body                         :: { [TopLevel (EnumCon PName)] }+  :     enum_con                     { [$1] }+  | '|' enum_con                     { [$2] }+  | enum_body '|' enum_con           { $3 : $1 }++enum_con                           :: { TopLevel (EnumCon PName) }+  : app_type                          {% mkConDecl Nothing   Public $1 }+  | doc  app_type                     {% mkConDecl (Just $1) Public $2 }+ vars_comma                 :: { [ LPName ]  }   : var                       { [ $1]      }   | vars_comma ',' var        { $3 : $1    }@@ -461,26 +478,6 @@   : name                      { $1 }   | '(' op ')'                { $2 } -apats                   :: { [Pattern PName] }-  : apat                   { [$1] }-  | apats apat             { $2 : $1 }--indices                 :: { [Pattern PName] }-  : '@' indices1           { $2 }-  | {- empty -}            { [] }--indices1                :: { [Pattern PName] }-  : apat                   { [$1] }-  | indices1 '@' apat      { $3 : $1 }--apats_indices           :: { ([Pattern PName], [Pattern PName]) }-  : apats indices          { ($1, $2) }-  | '@' indices1           { ([], $2) }--opt_apats_indices       :: { ([Pattern PName], [Pattern PName]) }-  : {- empty -}            { ([],[]) }-  | apats_indices          { $1 }- decls                   :: { [Decl PName] }   : decl ';'               { [$1] }   | decls decl ';'         { $2 : $1 }@@ -568,8 +565,11 @@ -- An expression without an obvious end marker longExpr                       :: { Expr PName }   : 'if' ifBranches 'else' exprNoWhere   { at ($1,$4) $ mkIf (reverse $2) $4 }-  | '\\' apats '->' exprNoWhere          { at ($1,$4) $ EFun emptyFunDesc (reverse $2) $4 }+  | '\\' iapats '->' exprNoWhere         { at ($1,$4) $ EFun emptyFunDesc (reverse $2) $4 }+  | 'case' expr 'of' 'v{' vcaseBranches 'v}' {at ($1,$6) (ECase $2 (reverse $5))}+  | 'case' expr 'of' '{' caseBranches '}' { at ($1,$6) (ECase $2 (reverse $5)) } + ifBranches                     :: { [(Expr PName, Expr PName)] }   : ifBranch                      { [$1] }   | ifBranches '|' ifBranch       { $3 : $1 }@@ -577,6 +577,17 @@ ifBranch                       :: { (Expr PName, Expr PName) }   : expr 'then' expr              { ($1, $3) } +vcaseBranches                  :: { [CaseAlt PName] }+  : caseBranch                    { [$1] }+  | vcaseBranches 'v;' caseBranch { $3 : $1 }++caseBranches                   :: { [CaseAlt PName] }+  : caseBranch                    { [$1] }+  | caseBranches ';' caseBranch   { $3 : $1 }++caseBranch                     :: { CaseAlt PName }+  : cpat '->' expr                { CaseAlt $1 $3 }+ simpleRHS                      :: { Expr PName }   : '-' simpleApp                 { at ($1,$2) (EPrefix PrefixNeg $2) }   | '~' simpleApp                 { at ($1,$2) (EPrefix PrefixComplement $2) }@@ -664,8 +675,8 @@   | field_exprs ',' field_expr    { $3 : $1 }  field_expr                     :: { UpdField PName }-  : field_path opt_apats_indices-                field_how expr    { UpdField $3 $1 (mkIndexedExpr $2 $4) }+  : field_path opt_iapats_indices field_how expr+                                  { UpdField $3 $1 (mkIndexedExpr $2 $4) }  field_path                     :: { [Located Selector] }   : aexpr                         {% exprToFieldPath $1 }@@ -713,20 +724,27 @@   | matches ',' match             { $3 : $1 }  match                          :: { Match PName }-  : pat '<-' expr                 { Match $1 $3 }+  : itpat '<-' expr               { Match $1 $3 }   --------------------------------------------------------------------------------+-- Generic patterns+ pat                            :: { Pattern PName }-  : ipat ':' type                 { at ($1,$3) $ PTyped $1 $3 }-  | ipat                          { $1                        }+  : cpat ':' type                 { at ($1,$3) $ PTyped $1 $3 }+  | cpat                          { $1                        } -ipat                           :: { Pattern PName }-  : ipat '#' ipat                 { at ($1,$3) $ PSplit $1 $3 }+cpat                           :: { Pattern PName }+  : cpat '#' cpat                 { at ($1,$3) $ PSplit $1 $3 }+  | qname apats                   { at ($1,$2) $ PCon $1 (reverse $2)   }   | apat                          { $1                        } +apats                          :: { [Pattern PName] }+  : apat                          { [$1] }+  | apats apat                    { $2 : $1 }+ apat                           :: { Pattern PName }-  : name                          { PVar $1                           }+  : qname                         { at $1 (mkPVar $1) }   | '_'                           { at $1       $ PWild               }   | '(' ')'                       { at ($1,$2) $ PTuple []            }   | '(' pat ')'                   { at ($1,$3)   $2                   }@@ -747,6 +765,41 @@ field_pats                     :: { [Named (Pattern PName)] }   : field_pat                     { [$1]    }   | field_pats ',' field_pat      { $3 : $1 }+++-- Irrefutable patterns+itpat                          :: { Pattern PName }+  : ipat ':' type                 { at ($1,$3) $ PTyped $1 $3 }+  | ipat                          { $1                        }++ipat                           :: { Pattern PName }+  : ipat '#' ipat                 { at ($1,$3) $ PSplit $1 $3 }+  | iapat                         { $1                        }++iapat                          :: { Pattern PName }+  : apat                          {% mkIPat $1 }++iapats                         :: { [Pattern PName] }+  : iapat                         { [$1] }+  | iapats iapat                  { $2 : $1 }++indices                 :: { [Pattern PName] }+  : '@' indices1           { $2 }+  | {- empty -}            { [] }++indices1                :: { [Pattern PName] }+  : iapat                  { [$1] }+  | indices1 '@' apat      { $3 : $1 }++iapats_indices          :: { ([Pattern PName], [Pattern PName]) }+  : iapats indices         { ($1, $2) }+  | '@' indices1           { ([], $2) }++opt_iapats_indices      :: { ([Pattern PName], [Pattern PName]) }+  : {- empty -}            { ([],[]) }+  | iapats_indices         { $1 }++  -------------------------------------------------------------------------------- 
src/Cryptol/Parser/AST.hs view
@@ -64,11 +64,13 @@   , PropSyn(..)   , Bind(..)   , BindDef(..), LBindDef+  , BindImpl(..), bindImpl, exprDef   , Pragma(..)   , ExportType(..)   , TopLevel(..)-  , Import, ImportG(..), ImportSpec(..), ImpName(..)+  , Import, ImportG(..), ImportSpec(..), ImpName(..), impNameModPath   , Newtype(..)+  , EnumDecl(..), EnumCon(..)   , PrimType(..)   , ParameterType(..)   , ParameterFun(..)@@ -88,6 +90,7 @@   , Match(..)   , Pattern(..)   , Selector(..)+  , CaseAlt(..)   , TypeInst(..)   , UpdField(..)   , UpdHow(..)@@ -106,6 +109,8 @@   , cppKind, ppSelector   ) where +import Cryptol.ModuleSystem.Name (Name, nameModPath, nameIdent)+import Cryptol.ModuleSystem.NamingEnv.Types import Cryptol.Parser.Name import Cryptol.Parser.Position import Cryptol.Parser.Selector@@ -158,6 +163,11 @@ data ModuleG mname name = Module   { mName     :: Located mname              -- ^ Name of the module   , mDef      :: ModuleDefinition name+  , mInScope  :: NamingEnv+    -- ^ Names in scope inside this module, filled in by the renamer.+    --   Also, for the 'FunctorInstance' case this is not the final result of+    --   the names in scope. The typechecker adds in the names in scope in the+    --   functor, so this will just contain the names in the enclosing scope.   } deriving (Show, Generic, NFData)  @@ -243,6 +253,7 @@     Decl (TopLevel (Decl name))   | DPrimType (TopLevel (PrimType name))   | TDNewtype (TopLevel (Newtype name)) -- ^ @newtype T as = t+  | TDEnum (TopLevel (EnumDecl name))   -- ^ @enum T as = cons@   | Include (Located FilePath)          -- ^ @include File@ (until NoInclude)    | DParamDecl Range (Signature name)   -- ^ @parameter ...@ (parser only)@@ -304,6 +315,10 @@   | ImpNested name              -- ^ The module in scope with the given name     deriving (Show, Generic, NFData, Eq, Ord) +impNameModPath :: ImpName Name -> ModPath+impNameModPath (ImpTop mn) = TopModule mn+impNameModPath (ImpNested n) = Nested (nameModPath n) (nameIdent n)+ -- | 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)@@ -475,11 +490,26 @@ type LBindDef = Located (BindDef PName)  data BindDef name = DPrim-                  | DForeign-                  | DExpr (Expr name)-                  | DPropGuards [PropGuardCase name]+                  -- | Foreign functions can have an optional cryptol+                  -- implementation+                  | DForeign (Maybe (BindImpl name))+                  | DImpl (BindImpl name)                     deriving (Eq, Show, Generic, NFData, Functor) +bindImpl :: Bind name -> Maybe (BindImpl name)+bindImpl bind =+  case thing (bDef bind) of+    DPrim       -> Nothing+    DForeign mi -> mi+    DImpl i     -> Just i++data BindImpl name = DExpr (Expr name)+                   | DPropGuards [PropGuardCase name]+                     deriving (Eq, Show, Generic, NFData, Functor)++exprDef :: Expr name -> BindDef name+exprDef = DImpl . DExpr+ data PropGuardCase name = PropGuardCase   { pgcProps :: [Located (Prop name)]   , pgcExpr  :: Expr name@@ -497,6 +527,17 @@   , nBody     :: Rec (Type name)     -- ^ Body   } deriving (Eq, Show, Generic, NFData) +data EnumDecl name = EnumDecl+  { eName     :: Located name               -- ^ Type name+  , eParams   :: [TParam name]              -- ^ Type params+  , eCons     :: [TopLevel (EnumCon name)]  -- ^ Value constructors+  } deriving (Show, Generic, NFData)++data EnumCon name = EnumCon+  { ecName    :: Located name+  , ecFields  :: [Type name]+  } deriving (Show, Generic, NFData)+ -- | A declaration for a type with no implementation. data PrimType name = PrimType { primTName :: Located name                               , primTKind :: Located Kind@@ -571,6 +612,7 @@               | EApp (Expr n) (Expr n)          -- ^ @ f x @               | EAppT (Expr n) [(TypeInst n)]   -- ^ @ f `{x = 8}, f`{8} @               | EIf (Expr n) (Expr n) (Expr n)  -- ^ @ if ok then e1 else e2 @+              | ECase (Expr n) [CaseAlt n]      -- ^ @ case e of { P -> e }@               | EWhere (Expr n) [Decl n]        -- ^ @ 1 + x where { x = 2 } @               | ETyped (Expr n) (Type n)        -- ^ @ 1 : [8] @               | ETypeVal (Type n)               -- ^ @ `(x + 1)@, @x@ is a type@@ -629,9 +671,13 @@                | PList [ Pattern n ]           -- ^ @ [ x, y, z ] @                | PTyped (Pattern n) (Type n)   -- ^ @ x : [8] @                | PSplit (Pattern n) (Pattern n)-- ^ @ (x # y) @+               | PCon (Located n) [Pattern n]  -- ^ @ Just x @                | PLocated (Pattern n) Range    -- ^ Location information                  deriving (Eq, Show, Generic, NFData, Functor) +data CaseAlt n = CaseAlt (Pattern n) (Expr n)+  deriving (Eq, Show, Generic, NFData, Functor)+ data Named a = Named { name :: Located Ident, value :: a }   deriving (Eq, Show, Foldable, Traversable, Generic, NFData, Functor) @@ -748,6 +794,7 @@       Decl tld    -> getLoc tld       DPrimType pt -> getLoc pt       TDNewtype n -> getLoc n+      TDEnum n -> getLoc n       Include lfp -> getLoc lfp       DModule d -> getLoc d       DImport d -> getLoc d@@ -801,6 +848,22 @@     where     locs = catMaybes ([ getLoc (nName n)] ++ map (Just . fst . snd) (displayFields (nBody n))) +instance HasLoc (EnumDecl name) where+  getLoc n+    | null locs = Nothing+    | otherwise = Just (rCombs locs)+    where+    locs = catMaybes (getLoc (eName n) : map getLoc (eCons n))++instance HasLoc (EnumCon name) where+  getLoc c+    | null locs = Nothing+    | otherwise = Just (rCombs locs)+    where+    locs = catMaybes (getLoc (ecName c) : map getLoc (ecFields c))+++ instance HasLoc (TySyn name) where   getLoc (TySyn x _ _ _) = getLoc x @@ -839,6 +902,7 @@ ppModule :: (Show name, PPName mname, PPName name) =>   Doc -> ModuleG mname name -> Doc ppModule kw m = kw' <+> ppL (mName m) <+> pp (mDef m)+  $$ indent 2 (vcat ["/* In scope:", indent 2 (pp (mInScope m)), " */"])   where   kw' = case mDef m of           InterfaceModule {} -> "interface" <+> kw@@ -890,6 +954,7 @@       Decl    d   -> pp d       DPrimType p -> pp p       TDNewtype n -> pp n+      TDEnum n -> pp n       Include l   -> text "include" <+> text (show (thing l))       DModule d -> pp d       DImport i -> pp (thing i)@@ -989,6 +1054,16 @@     , ppRecord (map (ppNamed' ":") (displayFields (nBody nt)))     ] +instance (Show name, PPName name) => PP (EnumDecl name) where+  ppPrec _ ed = nest 2 $ sep+    [ fsep $ [text "enum", ppL (eName ed)] ++ map pp (eParams ed) ++ [char '=']+    , vcat [ pre <+> pp con | (pre, con) <- pres `zip` eCons ed ]+    ]+    where pres = " " : repeat "|"++instance (Show name, PPName name) => PP (EnumCon name) where+  ppPrec _ c = pp (ecName c) <+> hsep (map (ppPrec 1) (ecFields c))+ instance (PP mname) => PP (ImportG mname) where   ppPrec _ d = vcat [ text "import" <+> sep ([pp (iModule d)] ++ mbInst ++                                                       mbAs ++ mbSpec)@@ -1051,8 +1126,13 @@   instance (Show name, PPName name) => PP (BindDef name) where-  ppPrec _ DPrim     = text "<primitive>"-  ppPrec _ DForeign  = text "<foreign>"+  ppPrec _ DPrim         = text "<primitive>"+  ppPrec p (DForeign mi) = case mi of+                             Just i  -> "(foreign)" <+> ppPrec p i+                             Nothing -> "<foreign>"+  ppPrec p (DImpl i)     = ppPrec p i++instance (Show name, PPName name) => PP (BindImpl name) where   ppPrec p (DExpr e) = ppPrec p e   ppPrec _p (DPropGuards _guards) = text "propguards" @@ -1195,6 +1275,10 @@                                       , text "then" <+> pp e2                                       , text "else" <+> pp e3 ] +      ECase e as    -> wrap n 0 $ vcat [ "case" <+> pp e <+> "of"+                                       , nest 2 (vcat (map pp as))+                                       ]+       ETyped e t    -> wrap n 0 (ppPrec 2 e <+> text ":" <+> pp t)        EWhere  e ds  -> wrap n 0 $ align $ vsep@@ -1230,6 +1314,9 @@    prefixText PrefixNeg        = "-"    prefixText PrefixComplement = "~" +instance (Show name, PPName name) => PP (CaseAlt name) where+  ppPrec _ (CaseAlt p e) = vcat [ pp p <+> "->", nest 2 (pp e) ]+ instance (Show name, PPName name) => PP (UpdField name) where   ppPrec _ (UpdField h xs e) = ppNestedSels (map thing xs) <+> pp h <+> pp e @@ -1242,6 +1329,10 @@   ppPrec n pat =     case pat of       PVar x        -> pp (thing x)+      PCon c ps ->+        case ps of+          [] -> pp c+          _  -> wrap n 1 (pp c <+> hsep (map (ppPrec 1) ps))       PWild         -> char '_'       PTuple ps     -> ppTuple (map pp ps)       PRecord fs    -> ppRecord (map (ppNamed' "=") (displayFields fs))@@ -1352,6 +1443,7 @@ instance NoPos (ModuleG mname name) where   noPos m = Module { mName      = mName m                    , mDef       = noPos (mDef m)+                   , mInScope   = mInScope m                    }  instance NoPos (ModuleDefinition name) where@@ -1381,6 +1473,7 @@       Decl    x   -> Decl     (noPos x)       DPrimType t -> DPrimType (noPos t)       TDNewtype n -> TDNewtype(noPos n)+      TDEnum n -> TDEnum (noPos n)       Include x   -> Include  (noPos x)       DModule d -> DModule (noPos d)       DImport d -> DImport (noPos d)@@ -1451,6 +1544,15 @@                     , nBody     = fmap noPos (nBody n)                     } +instance NoPos (EnumDecl name) where+  noPos n = EnumDecl { eName    = noPos (eName n)+                     , eParams  = eParams n+                     , eCons    = map noPos (eCons n)+                     }++instance NoPos (EnumCon name) where+  noPos c = EnumCon { ecName = noPos (ecName c), ecFields = noPos (ecFields c) }+ instance NoPos (Bind name) where   noPos x = Bind { bName      = noPos (bName      x)                  , bParams    = noPos (bParams    x)@@ -1508,6 +1610,7 @@       EParens e       -> EParens (noPos e)       EInfix x y f z  -> EInfix (noPos x) y f (noPos z)       EPrefix op x    -> EPrefix op (noPos x)+      ECase x y       -> ECase (noPos x) (noPos y)  instance NoPos (UpdField name) where   noPos (UpdField h xs e) = UpdField h xs (noPos e)@@ -1520,6 +1623,9 @@   noPos (Match x y)  = Match (noPos x) (noPos y)   noPos (MatchLet b) = MatchLet (noPos b) +instance NoPos (CaseAlt name) where+  noPos (CaseAlt p e) = CaseAlt (noPos p) (noPos e)+ instance NoPos (Pattern name) where   noPos pat =     case pat of@@ -1531,6 +1637,7 @@       PTyped x y   -> PTyped  (noPos x) (noPos y)       PSplit x y   -> PSplit  (noPos x) (noPos y)       PLocated x _ -> noPos x+      PCon n ps    -> PCon n (noPos ps)  instance NoPos (Schema name) where   noPos (Forall x y z _) = Forall (noPos x) (noPos y) (noPos z) Nothing
src/Cryptol/Parser/ExpandPropGuards.hs view
@@ -76,42 +76,46 @@ 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'+    DImpl (DPropGuards guards) -> expand (DImpl . DPropGuards) guards+    DForeign (Just (DPropGuards guards)) -> expand (DForeign . Just . DPropGuards) guards     _ -> pure [bind]++  where+  expand def 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 = exprDef e}+                }+            )+    (guards', binds') <- unzip <$> mapM goGuard guards+    pure $+      bind {bDef = def guards' <$ bDef bind} :+      binds'  patternToExpr :: Pattern PName -> Expr PName patternToExpr (PVar locName) = EVar (thing locName)
src/Cryptol/Parser/Layout.hs view
@@ -197,6 +197,7 @@ startsLayout ty =   case ty of     KW KW_where       -> True+    KW KW_of          -> True     KW KW_private     -> True     KW KW_parameter   -> True     _                 -> False
src/Cryptol/Parser/Lexer.x view
@@ -99,12 +99,15 @@ -- Please update the docs, if you add new entries. "else"                    { emit $ KW KW_else } "if"                      { emit $ KW KW_if }+"case"                    { emit $ KW KW_case }+"of"                      { emit $ KW KW_of } "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 }+"enum"                    { emit $ KW KW_enum } "pragma"                  { emit $ KW KW_pragma } "property"                { emit $ KW KW_property } "then"                    { emit $ KW KW_then }
src/Cryptol/Parser/Name.hs view
@@ -46,6 +46,17 @@ mkQual :: ModName -> Ident -> PName mkQual  = Qual +-- | Compute a `PName` for the definition site corresponding to the given+-- `OrigName`.   Usually this is an unqualified name, but names that come+-- from module parameters are qualified with the corresponding parameter name.+origNameToDefPName :: OrigName -> PName+origNameToDefPName og = toPName (ogName og)+  where+  toPName =+    case ogFromParam og of+      Nothing -> UnQual+      Just sig -> Qual (identToModName sig)+ getModName :: PName -> Maybe ModName getModName (Qual ns _) = Just ns getModName _           = Nothing
src/Cryptol/Parser/Names.hs view
@@ -13,6 +13,7 @@  module Cryptol.Parser.Names   ( tnamesNT+  , tnamesEnum   , tnamesT   , tnamesC @@ -20,7 +21,9 @@   , tnamesD   , namesB   , namesP+  , namesP'   , namesNT+  , namesEnum    , boundNames   , boundNamesSet@@ -39,6 +42,12 @@ namesNT :: Newtype name -> ([Located name], ()) namesNT x = ([ (nName x) { thing = nConName x } ], ()) +tnamesEnum :: EnumDecl name -> ([Located name],())+tnamesEnum n = ([ eName n], ())++namesEnum :: EnumDecl name -> ([Located name], ())+namesEnum n = (map (ecName . tlValue) (eCons n), ())+ -- | 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))@@ -53,7 +62,7 @@     DBind b       -> namesB b     DRec bs       -> let (xs,ys) = unzip (map namesB bs)                      in (concat xs, Set.unions ys)  -- remove binders?-    DPatBind p e  -> (namesP p, namesE e)+    DPatBind p e  -> (namesP' p, namesE e)     DSignature {} -> ([],Set.empty)     DFixity{}     -> ([],Set.empty)     DPragma {}    -> ([],Set.empty)@@ -64,16 +73,19 @@ -- | The names defined and used by a single binding. namesB :: Ord name => Bind name -> ([Located name], Set name) namesB b =-  ([bName b], boundLNames (namesPs (bParams b)) (namesDef (thing (bDef b))))+  ([bName b], boundLNames (namesPs' (bParams b)) (namesDef (thing (bDef b))))   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)+namesDef DPrim         = Set.empty+namesDef (DForeign mi) = foldMap namesImpl mi+namesDef (DImpl i)     = namesImpl i +namesImpl :: Ord name => BindImpl name -> Set name+namesImpl (DExpr e)            = namesE e+namesImpl (DPropGuards guards) = Set.unions (map (namesE . pgcExpr) guards) + -- | The names used by an expression. namesE :: Ord name => Expr name -> Set name namesE expr =@@ -98,11 +110,12 @@     EApp e1 e2    -> Set.union (namesE e1) (namesE e2)     EAppT e _     -> namesE e     EIf e1 e2 e3  -> Set.union (namesE e1) (Set.union (namesE e2) (namesE e3))+    ECase e as    -> Set.union (namesE e) (Set.unions (map namesCA as))     EWhere  e ds  -> let (bs,xs) = namesDs ds                      in Set.union (boundLNames bs (namesE e)) xs     ETyped e _    -> namesE e     ETypeVal _    -> Set.empty-    EFun _ ps e   -> boundLNames (namesPs ps) (namesE e)+    EFun _ ps e   -> boundLNames (fst (namesPs ps)) (namesE e) -- no free     ELocated e _  -> namesE e      ESplit e      -> namesE e@@ -113,16 +126,31 @@ namesUF :: Ord name => UpdField name -> Set name namesUF (UpdField _ _ e) = namesE e +namesCA :: Ord name => CaseAlt name -> Set name+namesCA (CaseAlt p e) = Set.union free (boundLNames defs (namesE e))+  where+  (defs,free) = namesP p++namesP' :: Ord name => Pattern name -> [Located name]+namesP' = fst . namesP++namesPs' :: Ord name => [Pattern name] -> [Located name]+namesPs' = fst . namesPs+ -- | The names defined by a group of patterns.-namesPs :: [Pattern name] -> [Located name]-namesPs = concatMap namesP+namesPs :: Ord name => [Pattern name] -> ([Located name], Set name)+namesPs ps = (concat defs, Set.unions uses)+  where+  (defs, uses) = unzip (map namesP ps)  -- | The names defined by a pattern.  These will always be unqualified names.-namesP :: Pattern name -> [Located name]+namesP :: Ord name => Pattern name -> ([Located name], Set name) namesP pat =   case pat of-    PVar x        -> [x]-    PWild         -> []+    PVar x        -> ([x], Set.empty)+    PCon c ps     -> (def, Set.insert (thing c) free)+      where (def,free) = namesPs ps+    PWild         -> ([],Set.empty)     PTuple ps     -> namesPs ps     PRecord fs    -> namesPs (map snd (recordElements fs))     PList ps      -> namesPs ps@@ -130,9 +158,11 @@     PSplit p1 p2  -> namesPs [p1,p2]     PLocated p _  -> namesP p ++ -- | The names defined and used by a match. namesM :: Ord name => Match name -> ([Located name], Set name)-namesM (Match p e)  = (namesP p, namesE e)+namesM (Match p e)  = (namesP' p, namesE e) namesM (MatchLet b) = namesB b  -- | The names defined and used by an arm of alist comprehension.@@ -190,11 +220,14 @@     setE = tnamesDef (thing (bDef b))  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)+tnamesDef DPrim         = Set.empty+tnamesDef (DForeign mi) = foldMap tnamesImpl mi+tnamesDef (DImpl i)     = tnamesImpl i +tnamesImpl :: Ord name => BindImpl name -> Set name+tnamesImpl (DExpr e)            = tnamesE e+tnamesImpl (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))@@ -225,6 +258,7 @@     EApp e1 e2      -> Set.union (tnamesE e1) (tnamesE e2)     EAppT e fs      -> Set.union (tnamesE e) (Set.unions (map tnamesTI fs))     EIf e1 e2 e3    -> Set.union (tnamesE e1) (Set.union (tnamesE e2) (tnamesE e3))+    ECase e as      -> Set.union (tnamesE e) (Set.unions (map tnamesCA as))     EWhere  e ds    -> let (bs,xs) = tnamesDs ds                        in Set.union (boundLNames bs (tnamesE e)) xs     ETyped e t      -> Set.union (tnamesE e) (tnamesT t)@@ -237,6 +271,9 @@     EInfix a _ _ b  -> Set.union (tnamesE a) (tnamesE b)     EPrefix _ e     -> tnamesE e +tnamesCA :: Ord name => CaseAlt name -> Set name+tnamesCA (CaseAlt p e) = Set.union (tnamesP p) (tnamesE e)+ tnamesUF :: Ord name => UpdField name -> Set name tnamesUF (UpdField _ _ e) = tnamesE e @@ -249,6 +286,7 @@ tnamesP pat =   case pat of     PVar _        -> Set.empty+    PCon _ ps     -> Set.unions (map tnamesP ps)     PWild         -> Set.empty     PTuple ps     -> Set.unions (map tnamesP ps)     PRecord fs    -> Set.unions (map (tnamesP . snd) (recordElements fs))
src/Cryptol/Parser/NoInclude.hs view
@@ -212,6 +212,7 @@   Decl _     -> pure [td]   DPrimType {} -> pure [td]   TDNewtype _-> pure [td]+  TDEnum _-> pure [td]   DParamDecl {} -> pure [td]   DInterfaceConstraint {} -> pure [td]   Include lf -> resolveInclude lf
src/Cryptol/Parser/NoPat.hs view
@@ -6,10 +6,12 @@ -- Stability   :  provisional -- Portability :  portable ----- The purpose of this module is to convert all patterns to variable+-- The purpose of this module is to convert all irrefutable patterns to variable -- patterns.  It also eliminates pattern bindings by de-sugaring them -- into `Bind`.  Furthermore, here we associate signatures, fixities,--- and pragmas with the names to which they belong.+-- and pragmas with the names to which they belong.  We also merge+-- empty 'DForeign' binds with their cryptol implementations, if they+-- exist.  {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-}@@ -22,7 +24,7 @@  import Cryptol.Parser.AST import Cryptol.Parser.Position(Range(..),emptyRange,start,at)-import Cryptol.Parser.Names (namesP)+import Cryptol.Parser.Names (namesP') import Cryptol.Utils.PP import Cryptol.Utils.Panic(panic) import Cryptol.Utils.RecordMap@@ -57,7 +59,7 @@  simpleBind :: Located PName -> Expr PName -> Bind PName simpleBind x e = Bind { bName = x, bParams = []-                      , bDef = at e (Located emptyRange (DExpr e))+                      , bDef = at e (Located emptyRange (exprDef e))                       , bSignature = Nothing, bPragmas = []                       , bMono = True, bInfix = False, bFixity = Nothing                       , bDoc = Nothing@@ -72,18 +74,29 @@ -- Simple patterns may only contain variables and type annotations.  -- XXX: We can replace the types in the selectors with annotations on the bindings.-noPat :: Pattern PName -> NoPatM (Pattern PName, [Bind PName])-noPat pat =+noPat :: Bool -> Pattern PName -> NoPatM (Pattern PName, [Bind PName])+noPat conOk pat =   case pat of     PVar x -> return (PVar x, []) +    PCon c ps+      | conOk ->+        do (as,dss) <- mapAndUnzipM (noPat False) ps+           pure (PCon c as, concat dss)++      | otherwise ->+        do let r = srcRange c+           recordError (InvalidConstructorPattern r)+           x <- newName+           pure (pVar r x, [])+     PWild ->       do x <- newName          r <- getRange          return (pVar r x, [])      PTuple ps ->-      do (as,dss) <- unzip `fmap` mapM noPat ps+      do (as,dss) <- unzip `fmap` mapM (noPat False) ps          x <- newName          r <- getRange          let len      = length ps@@ -97,7 +110,7 @@          return (pTy r x (TSeq (TNum 0) TWild), [])      PList ps ->-      do (as,dss) <- unzip `fmap` mapM noPat ps+      do (as,dss) <- unzip `fmap` mapM (noPat False) ps          x <- newName          r <- getRange          let len      = length ps@@ -107,7 +120,7 @@      PRecord fs ->       do let (shape, els) = unzip (canonicalFields fs)-         (as,dss) <- unzip `fmap` mapM (noPat . snd) els+         (as,dss) <- unzip `fmap` mapM (noPat False . snd) els          x <- newName          r <- getRange          let ty           = TRecord (fmap (\(rng,_) -> (rng,TWild)) fs)@@ -115,13 +128,13 @@          return (pTy r x ty, zipWith getN as shape ++ concat dss)      PTyped p t ->-      do (a,ds) <- noPat p+      do (a,ds) <- noPat conOk p          return (PTyped a t, ds)      -- XXX: We can do more with type annotations here     PSplit p1 p2 ->-      do (a1,ds1) <- noPat p1-         (a2,ds2) <- noPat p2+      do (a1,ds1) <- noPat False p1+         (a2,ds2) <- noPat False p2          x <- newName          tmp <- newName          r <- getRange@@ -130,11 +143,11 @@              b2   = sel a2 tmp (TupleSel 1 (Just 2))          return (pVar r x, bTmp : b1 : b2 : ds1 ++ ds2) -    PLocated p r1 -> inRange r1 (noPat p)+    PLocated p r1 -> inRange r1 (noPat conOk p)    where   pVar r x   = PVar (Located r x)-  pTy  r x t = PTyped (PVar (Located r x)) t+  pTy  r x   = PTyped (PVar (Located r x))   splitSimpleP :: Pattern PName -> (Located PName, [Type PName])@@ -166,6 +179,7 @@     EApp e1 e2    -> EApp   <$> noPatE e1 <*> noPatE e2     EAppT e ts    -> EAppT  <$> noPatE e <*> return ts     EIf e1 e2 e3  -> EIf    <$> noPatE e1 <*> noPatE e2 <*> noPatE e3+    ECase e as    -> ECase  <$> noPatE e  <*> traverse noPatAlt as     EWhere e ds   -> EWhere <$> noPatE e <*> noPatDs ds     ETyped e t    -> ETyped <$> noPatE e <*> return t     ETypeVal {}   -> return expr@@ -177,6 +191,14 @@     EInfix x y f z-> EInfix  <$> noPatE x <*> pure y <*> pure f <*> noPatE z     EPrefix op e  -> EPrefix op <$> noPatE e +noPatAlt :: CaseAlt PName -> NoPatM (CaseAlt PName)+noPatAlt (CaseAlt p e) =+  do (p1,ds) <- noPat True p+     e1 <- noPatE e+     let e2 = case ds of+                [] -> e1+                _  -> EWhere e1 (map DBind ds)+     pure (CaseAlt p1 e2)  noPatUF :: UpdField PName -> NoPatM (UpdField PName) noPatUF (UpdField h ls e) = UpdField h ls <$> noPatE e@@ -190,7 +212,7 @@ noPatFun :: Maybe PName -> Int -> [Pattern PName] -> Expr PName -> NoPatM (Expr PName) noPatFun _   _      []     e = noPatE e noPatFun mnm offset (p:ps) e =-  do (p',ds) <- noPat p+  do (p',ds) <- noPat False p      e' <- noPatFun mnm (offset+1) ps e      let body = case ds of                   [] -> e'@@ -207,7 +229,7 @@  noPatM :: Match PName -> NoPatM [Match PName] noPatM (Match p e) =-  do (x,bs) <- noPat p+  do (x,bs) <- noPat False p      e1     <- noPatE e      return (Match x e1 : map MatchLet bs) noPatM (MatchLet b) = (return . MatchLet) <$> noMatchB b@@ -220,21 +242,26 @@           | otherwise        -> panic "NoPat" [ "noMatchB: primitive with params"                                               , show b ] -    DForeign+    DForeign Nothing       | 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 }+    DForeign (Just i) -> noMatchI (DForeign . Just) i -    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 }+    DImpl i -> noMatchI DImpl i +  where+  noMatchI def i =+    do i' <- case i of+               DExpr e ->+                 DExpr <$> noPatFun (Just (thing (bName b))) 0 (bParams b) e+               DPropGuards guards ->+                 let nm = thing (bName b)+                     ps = bParams b+                 in  DPropGuards <$> mapM (noPatPropGuardCase nm ps) guards+       pure b { bParams = [], bDef = def i' <$ bDef b }+ noPatPropGuardCase ::   PName ->   [Pattern PName] ->@@ -254,13 +281,13 @@                           return [DBind b1]     DRec {}         -> panic "noMatchD" [ "DRec" ] -    DPatBind p e    -> do (p',bs) <- noPat p+    DPatBind p e    -> do (p',bs) <- noPat False p                           let (x,ts) = splitSimpleP p'                           e1 <- noPatE e                           let e2 = foldl ETyped e1 ts                           return $ DBind Bind { bName = x                                               , bParams = []-                                              , bDef = at e (Located emptyRange (DExpr e2))+                                              , bDef = at e (Located emptyRange (exprDef e2))                                               , bSignature = Nothing                                               , bPragmas = []                                               , bMono = False@@ -280,11 +307,13 @@   do ds1 <- concat <$> mapM noMatchD ds      let fixes = Map.fromListWith (++) $ concatMap toFixity ds1          amap = AnnotMap-           { annPragmas = Map.fromListWith (++) $ concatMap toPragma ds1-           , annSigs    = Map.fromListWith (++) $ concatMap toSig ds1-           , annValueFs = fixes-           , annTypeFs  = fixes-           , annDocs    = Map.empty+           { annPragmas  = Map.fromListWith (++) $ concatMap toPragma ds1+           , annSigs     = Map.fromListWith (++) $ concatMap toSig ds1+           , annValueFs  = fixes+           , annTypeFs   = fixes+           , annDocs     = Map.empty+             -- There shouldn't be any foreigns at non-top-level+           , annForeigns = Map.empty            }       (ds2, AnnotMap { .. }) <- runStateT amap (annotDs ds1)@@ -314,11 +343,12 @@          fixes     = Map.fromListWith (++) $ concatMap toFixity allDecls       let ann = AnnotMap-           { annPragmas = Map.fromListWith (++) $ concatMap toPragma allDecls-           , annSigs    = Map.fromListWith (++) $ concatMap toSig    allDecls-           , annValueFs = fixes-           , annTypeFs  = fixes-           , annDocs    = Map.fromListWith (++) $ concatMap toDocs $ decls tds+           { annPragmas  = Map.fromListWith (++) $ concatMap toPragma allDecls+           , annSigs     = Map.fromListWith (++) $ concatMap toSig    allDecls+           , annValueFs  = fixes+           , annTypeFs   = fixes+           , annDocs     = Map.fromListWith (++) $ concatMap toDocs $ decls tds+           , annForeigns = Map.fromListWith (<>) $ concatMap toForeigns allDecls           }       (tds', AnnotMap { .. }) <- runStateT ann (annotTopDs desugared)@@ -362,12 +392,25 @@  -------------------------------------------------------------------------------- +-- | For each binding name, does there exist an empty foreign bind, a normal+-- cryptol bind, or both.+data AnnForeign = OnlyForeign | OnlyImpl | BothForeignImpl++instance Semigroup AnnForeign where+  OnlyForeign     <> OnlyImpl        = BothForeignImpl+  OnlyImpl        <> OnlyForeign     = BothForeignImpl+  _               <> BothForeignImpl = BothForeignImpl+  BothForeignImpl <> _               = BothForeignImpl+  OnlyForeign     <> OnlyForeign     = OnlyForeign+  OnlyImpl        <> OnlyImpl        = OnlyImpl+ data AnnotMap = AnnotMap   { annPragmas  :: Map.Map PName [Located  Pragma       ]   , annSigs     :: Map.Map PName [Located (Schema PName)]   , annValueFs  :: Map.Map PName [Located  Fixity       ]   , annTypeFs   :: Map.Map PName [Located  Fixity       ]   , annDocs     :: Map.Map PName [Located  Text         ]+  , annForeigns :: Map.Map PName AnnForeign   }  type Annotates a = a -> StateT AnnotMap NoPatM a@@ -398,8 +441,9 @@         DParamDecl {} -> (d :) <$> annotTopDs ds         DInterfaceConstraint {} -> (d :) <$> annotTopDs ds -        -- XXX: we may want to add pragmas to newtypes?+        -- XXX: we may want to add pragmas to newtypes and enums?         TDNewtype {} -> (d :) <$> annotTopDs ds+        TDEnum {}    -> (d :) <$> annotTopDs ds         Include {}   -> (d :) <$> annotTopDs ds          DModule m ->@@ -428,7 +472,7 @@ annotD :: Decl PName -> ExceptionT () (StateT AnnotMap NoPatM) (Decl PName) annotD decl =   case decl of-    DBind b       -> DBind <$> lift (annotB b)+    DBind b       -> DBind <$> annotB b     DRec {}       -> panic "annotD" [ "DRec" ]     DSignature {} -> raise ()     DFixity{}     -> raise ()@@ -439,7 +483,10 @@     DLocated d r  -> (`DLocated` r) <$> annotD d  -- | Add pragma/signature annotations to a binding.-annotB :: Annotates (Bind PName)+-- Also perform de-duplication of empty 'DForeign' binds generated by the parser+-- if there exists a cryptol implementation.+-- The exception indicates which declarations are no longer needed.+annotB :: Bind PName -> ExceptionT () (StateT AnnotMap NoPatM) (Bind PName) annotB Bind { .. } =   do AnnotMap { .. } <- get      let name       = thing bName@@ -448,9 +495,17 @@          (thisSigs  , ss') = Map.updateLookupWithKey remove name annSigs          (thisFixes , fs') = Map.updateLookupWithKey remove name annValueFs          (thisDocs  , ds') = Map.updateLookupWithKey remove name annDocs-     s <- lift $ checkSigs name $ jn thisSigs-     f <- lift $ checkFixs name $ jn thisFixes-     d <- lift $ checkDocs name $ jn thisDocs+         thisForeign       = Map.lookup name annForeigns+     -- Compute the new def before updating the state, since we don't want to+     -- consume the annotations if we are throwing away an empty foreign def.+     def' <- case thisForeign of+               Just BothForeignImpl+                 | DForeign _ <- thing bDef -> raise ()+                 | DImpl i    <- thing bDef -> pure (DForeign (Just i) <$ bDef)+               _ -> pure bDef+     s <- lift $ lift $ checkSigs name $ jn thisSigs+     f <- lift $ lift $ checkFixs name $ jn thisFixes+     d <- lift $ lift $ checkDocs name $ jn thisDocs      set AnnotMap { annPragmas = ps'                   , annSigs    = ss'                   , annValueFs = fs'@@ -458,6 +513,7 @@                   , ..                   }      return Bind { bSignature = s+                 , bDef = def'                  , bPragmas = map thing (jn thisPs) ++ bPragmas                  , bFixity = f                  , bDoc = d@@ -544,13 +600,20 @@       DBind b         -> [ (thing (bName b), [txt]) ]       DRec {}         -> panic "toDocs" [ "DRec" ]       DLocated d _    -> go txt d-      DPatBind p _    -> [ (thing n, [txt]) | n <- namesP p ]+      DPatBind p _    -> [ (thing n, [txt]) | n <- namesP' p ]        -- XXX revisit these       DPragma _ _     -> []       DType _         -> []       DProp _         -> [] +-- | Is this declaration a foreign or regular bind?+toForeigns :: Decl PName -> [(PName, AnnForeign)]+toForeigns (DLocated d _) = toForeigns d+toForeigns (DBind Bind {..})+  | DForeign Nothing <- thing bDef = [ (thing bName, OnlyForeign) ]+  | DImpl _          <- thing bDef = [ (thing bName, OnlyImpl) ]+toForeigns _ = []  -------------------------------------------------------------------------------- newtype NoPatM a = M { unM :: ReaderT Range (StateT RW Id) a }@@ -563,6 +626,7 @@             | MultipleFixities PName [Range]             | FixityNoBind (Located PName)             | MultipleDocs PName [Range]+            | InvalidConstructorPattern Range               deriving (Show,Generic, NFData)  instance Functor NoPatM where fmap = liftM@@ -605,21 +669,21 @@     case err of       MultipleSignatures x ss ->         text "Multiple type signatures for" <+> quotes (pp x)-        $$ nest 2 (vcat (map pp ss))+        $$ indent 2 (vcat (map pp ss))        SignatureNoBind x s ->         text "At" <+> pp (srcRange x) <.> colon <+>         text "Type signature without a matching binding:"-         $$ nest 2 (pp (thing x) <+> colon <+> pp s)+         $$ indent 2 (pp (thing x) <+> colon <+> pp s)        PragmaNoBind x s ->         text "At" <+> pp (srcRange x) <.> colon <+>         text "Pragma without a matching binding:"-         $$ nest 2 (pp s)+         $$ indent 2 (pp s)        MultipleFixities n locs ->         text "Multiple fixity declarations for" <+> quotes (pp n)-        $$ nest 2 (vcat (map pp locs))+        $$ indent 2 (vcat (map pp locs))        FixityNoBind n ->         text "At" <+> pp (srcRange n) <.> colon <+>@@ -628,4 +692,10 @@        MultipleDocs n locs ->         text "Multiple documentation blocks given for:" <+> pp n-        $$ nest 2 (vcat (map pp locs))+        $$ indent 2 (vcat (map pp locs))++      InvalidConstructorPattern r ->+        "At" <+> pp r <.> colon <+> "Invalid constructor pattern"+         $$ indent 2 "Constructors may appear only at the top level of a case."++
src/Cryptol/Parser/ParserUtils.hs view
@@ -50,7 +50,7 @@                           , modNameArg, modNameIfaceMod                           , modNameToText, modNameIsNormal                           , modNameToNormalModName-                          , unpackIdent+                          , unpackIdent, isUpperIdent                           ) import Cryptol.Utils.PP import Cryptol.Utils.Panic@@ -512,6 +512,12 @@                                          , tlDoc    = d                                          , tlValue  = n } +exportEnum ::+  ExportType -> Maybe (Located Text) -> EnumDecl PName -> TopDecl PName+exportEnum e d n = TDEnum TopLevel { tlExport = e+                                   , tlDoc = d+                                   , tlValue = n }+ exportModule :: Maybe (Located Text) -> NestedModule PName -> TopDecl PName exportModule mbDoc m = DModule TopLevel { tlExport = Public                                         , tlDoc    = mbDoc@@ -550,6 +556,7 @@       Decl d                  -> Decl      d { tlExport = e }       DPrimType t             -> DPrimType t { tlExport = e }       TDNewtype n             -> TDNewtype n { tlExport = e }+      TDEnum n                -> TDEnum    n { tlExport = e }       DModule m               -> DModule   m { tlExport = e }       DModParam {}            -> decl       Include{}               -> decl@@ -587,6 +594,66 @@   do (nm,params) <- typeToDecl thead      pure (Newtype nm params (thing nm) (thing def)) +mkEnumDecl ::+  Type PName ->+  [ TopLevel (EnumCon PName) ] {- ^ Reversed -} ->+  ParseM (EnumDecl PName)+mkEnumDecl thead def =+  do (nm,params) <- typeToDecl thead+     mapM_ reportRepeated+        (Map.toList (Map.fromListWith (++) [ (thing k,[srcRange k])+                                           | k <- map (ecName . tlValue) def ]))+     pure EnumDecl+            { eName   = nm+            , eParams = params+            , eCons   = reverse def+            }+  where+  reportRepeated (i,xs) =+    case xs of+      l : ls@(_ : _) ->+        errorMessage l+          ( ("Multiple declarations for " ++ show (backticks (pp i)))+          : [ "Other declaration: " ++ show (pp x) | x <- ls ]+          )++      _ -> pure ()++mkConDecl ::+  Maybe (Located Text) -> ExportType ->+  Type PName -> ParseM (TopLevel (EnumCon PName))+mkConDecl mbDoc expT ty =+  do con <- go Nothing ty+     pure TopLevel { tlExport = expT, tlDoc = mbDoc, tlValue = con }+  where+  go mbLoc t =+    case t of+      TLocated t1 r -> go (Just r) t1+      TUser n ts ->+        case n of+          UnQual i+            | isUpperIdent i ->+              pure EnumCon { ecName = Located (getL mbLoc) (UnQual i)+                           , ecFields = ts+                           }+            | otherwise ->+              errorMessage (getL mbLoc)+                 [ "Malformed constructor declaration."+                 , "The constructor name should start with a capital letter."+                 ]++          _ -> errorMessage (getL mbLoc)+                 [ "Malformed constructor declaration."+                 , "The constructor name may not be qualified."+                 ]+      _ -> errorMessage (getL mbLoc) [ "Malformed constructor declaration." ]++  getL mb =+    case mb of+      Just r  -> r+      Nothing -> panic "mkConDecl" ["Missing type location"]++ typeToDecl :: Type PName -> ParseM (Located PName, [TParam PName]) typeToDecl ty0 =   case ty0 of@@ -692,7 +759,7 @@ mkProperty f ps e = at (f,e) $                     DBind Bind { bName       = f                                , bParams     = reverse ps-                               , bDef        = at e (Located emptyRange (DExpr e))+                               , bDef        = at e (Located emptyRange (exprDef e))                                , bSignature  = Nothing                                , bPragmas    = [PragmaProperty]                                , bMono       = False@@ -708,7 +775,7 @@ mkIndexedDecl f (ps, ixs) e =   DBind Bind { bName       = f              , bParams     = reverse ps-             , bDef        = at e (Located emptyRange (DExpr rhs))+             , bDef        = at e (Located emptyRange (exprDef rhs))              , bSignature  = Nothing              , bPragmas    = []              , bMono       = False@@ -735,7 +802,7 @@      pure $        DBind Bind { bName       = f                   , bParams     = reverse ps-                  , bDef        = Located (srcRange f) (DPropGuards gs)+                  , bDef        = Located (srcRange f) (DImpl (DPropGuards gs))                   , bSignature  = Nothing                   , bPragmas    = []                   , bMono       = False@@ -765,6 +832,34 @@     where     addIfThen (cond, doexpr) elseExpr = EIf cond doexpr elseExpr +mkPVar :: Located PName -> Pattern PName+mkPVar p =+  case thing p of+    UnQual i | isInfixIdent i || not (isUpperIdent i) -> PVar p+    _ -> PCon p []++mkIPat :: Pattern PName -> ParseM (Pattern PName)+mkIPat pat =+  case pat of+    PVar {}      -> pure pat+    PWild        -> pure pat+    PTuple ps    -> PTuple <$> traverse mkIPat ps+    PRecord rp   -> PRecord <$> traverseRecordMap upd rp+      where upd _ (x,y) = (,) x <$> mkIPat y+    PList ps     -> PList <$> traverse mkIPat ps+    PTyped p t   -> (`PTyped` t) <$> mkIPat p+    PSplit p1 p2 -> PSplit <$> mkIPat p1 <*> mkIPat p2+    PLocated p r -> (`PLocated` r) <$> mkIPat p+    PCon n ps    ->+      case ps of+        [] | UnQual {} <- thing n -> pure (PVar n)+        _ -> errorMessage (srcRange n)+               [ "Unexpected constructor pattern."+               , "Constructors patterns may be used only in `case` expressions."+               ]+++ mkPrimDecl :: Maybe (Located Text) -> LPName -> Schema PName -> [TopDecl PName] mkPrimDecl = mkNoImplDecl DPrim @@ -777,7 +872,11 @@             [ "`" ++ txt ++ "` is not a valid foreign name."             , "The name should contain only alpha-numeric characters or '_'."             ])-     pure (mkNoImplDecl DForeign mbDoc nm ty)+     -- We do allow optional cryptol implementations of foreign functions, these+     -- will be merged with this binding in the NoPat pass. In the parser they+     -- are just treated as a completely separate (non-foreign) binding with the+     -- same name.+     pure (mkNoImplDecl (DForeign Nothing) mbDoc nm ty)   where   isOk c = c == '_' || isAlphaNum c @@ -791,7 +890,7 @@ mkNoImplDecl :: BindDef PName   -> Maybe (Located Text) -> LPName -> Schema PName -> [TopDecl PName] mkNoImplDecl def mbDoc ln sig =-  [ exportDecl mbDoc Public+  [ exportDecl Nothing Public     $ DBind Bind { bName      = ln                  , bParams    = []                  , bDef       = at sig (Located emptyRange def)@@ -803,7 +902,7 @@                  , bDoc       = Nothing                  , bExport    = Public                  }-  , exportDecl Nothing Public+  , exportDecl mbDoc Public     $ DSignature [ln] sig   ] @@ -961,6 +1060,7 @@ mkModule :: Located ModName -> [TopDecl PName] -> Module PName mkModule nm ds = Module { mName = nm                         , mDef = NormalModule ds+                        , mInScope = mempty                         }  mkNested :: Module PName -> ParseM (NestedModule PName)@@ -979,8 +1079,9 @@   TopLevel { tlExport = Public            , tlDoc    = doc            , tlValue  = NestedModule-                        Module { mName = nm-                               , mDef  = InterfaceModule sig+                        Module { mName    = nm+                               , mDef     = InterfaceModule sig+                               , mInScope = mempty                                }            } @@ -1055,8 +1156,9 @@                       [TopDecl PName] ->                       Module PName mkModuleInstanceAnon nm fun ds =-  Module { mName  = nm-         , mDef   = FunctorInstance fun (DefaultInstAnonArg ds) mempty+  Module { mName    = nm+         , mDef     = FunctorInstance fun (DefaultInstAnonArg ds) mempty+         , mInScope = mempty          }  mkModuleInstance ::@@ -1065,8 +1167,9 @@   ModuleInstanceArgs PName ->   Module PName mkModuleInstance m f as =-  Module { mName = m-         , mDef  = FunctorInstance f as emptyModuleInstance+  Module { mName    = m+         , mDef     = FunctorInstance f as emptyModuleInstance+         , mInScope = mempty          }  @@ -1188,8 +1291,9 @@  mkTopSig :: Located ModName -> Signature PName -> [Module PName] mkTopSig nm sig =-  [ Module { mName = nm-           , mDef  = InterfaceModule sig+  [ Module { mName    = nm+           , mDef     = InterfaceModule sig+           , mInScope = mempty            }   ] @@ -1233,7 +1337,8 @@          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' }+         pure [ Module+                  { mName = nm, mDef  = NormalModule lds', mInScope = mempty }               , mo { mDef = FunctorInstance f as' mempty }               ] @@ -1283,6 +1388,7 @@           do let nm = mkAnon AnonIfaceMod <$> ownerName              pure ( [ Module { mName = nm                              , mDef = InterfaceModule sig+                             , mInScope = mempty                              }                      ]                   , [ DModParam@@ -1326,9 +1432,10 @@   ParseM [TopDecl PName] desugarInstImport i inst =   do ms <- desugarMod-           Module { mName = i { thing = iname }-                  , mDef  = FunctorInstance-                              (iModule <$> i) inst emptyModuleInstance+           Module { mName    = i { thing = iname }+                  , mDef     = FunctorInstance+                                 (iModule <$> i) inst emptyModuleInstance+                  , mInScope = mempty                   }      pure (DImport (newImp <$> i) : map modTop ms) 
src/Cryptol/Parser/Token.hs view
@@ -23,6 +23,8 @@ data TokenKW  = KW_else               | KW_fin               | KW_if+              | KW_case+              | KW_of               | KW_private               | KW_include               | KW_inf@@ -34,6 +36,7 @@               | KW_module               | KW_submodule               | KW_newtype+              | KW_enum               | KW_pragma               | KW_property               | KW_then
src/Cryptol/REPL/Browse.hs view
@@ -33,7 +33,7 @@     , browseFunctors disp decls     , browseTSyns disp decls     , browsePrimTys disp decls-    , browseNewtypes disp decls+    , browseNominalTypes disp decls     , browseVars disp decls     ] @@ -97,7 +97,7 @@   ppSection disp "Interface Submodules"     ppS (Map.mapWithKey (,) (ifSignatures decls))   where-  ppS (x,s) = pp x+  ppS (x,_s) = pp x   browseTSyns :: DispInfo -> IfaceDecls -> [Doc]@@ -110,13 +110,15 @@  browsePrimTys :: DispInfo -> IfaceDecls -> [Doc] browsePrimTys disp decls =-  ppSection disp "Primitive Types" ppA (ifAbstractTypes decls)+  ppSection disp "Primitive Types" ppA ats   where-  ppA a = nest 2 (sep [pp (T.atName a) <+> ":", pp (T.atKind a)])+  ats = Map.filter T.nominalTypeIsAbstract (ifNominalTypes decls)+  ppA a = nest 2 (sep [pp (T.ntName a) <+> ":", pp (T.kindOf a)]) -browseNewtypes :: DispInfo -> IfaceDecls -> [Doc]-browseNewtypes disp decls =-  ppSection disp "Newtypes" T.ppNewtypeShort (ifNewtypes decls)+browseNominalTypes :: DispInfo -> IfaceDecls -> [Doc]+browseNominalTypes disp decls =+  ppSection disp "Nominal Types" T.ppNominalShort+    (Map.filter (not . T.nominalTypeIsAbstract) (ifNominalTypes decls))  browseVars :: DispInfo -> IfaceDecls -> [Doc] browseVars disp decls =@@ -132,7 +134,7 @@  ppSection :: DispInfo -> String -> (a -> Doc) -> Map Name a -> [Doc] ppSection disp heading ppThing mp =-  ppSectionHeading heading +  ppSectionHeading heading   case dispHow disp of     BrowseExported | [(_,xs)] <- grouped -> ppThings xs     _ -> concatMap ppMod grouped@@ -151,7 +153,7 @@ ppSectionHeading :: String -> [Doc] -> [Doc] ppSectionHeading heading body   | null body = []-  | otherwise = +  | otherwise =      [ text heading      , text (map (const '=') heading)      , "    "
src/Cryptol/REPL/Command.hs view
@@ -121,6 +121,7 @@ import Data.Char (isSpace,isPunctuation,isSymbol,isAlphaNum,isAscii) import Data.Function (on) import Data.List (intercalate, nub, isPrefixOf)+import qualified Data.Map as Map import Data.Maybe (fromMaybe,mapMaybe,isNothing) import System.Environment (lookupEnv) import System.Exit (ExitCode(ExitSuccess))@@ -404,7 +405,10 @@ printCounterexample :: CounterExampleType -> Doc -> [Concrete.Value] -> REPL () printCounterexample cexTy exprDoc vs =   do ppOpts <- getPPValOpts-     docs <- mapM (rEval . E.ppValue Concrete ppOpts) vs+     -- NB: Use a precedence of 1 here, as `vs` will be pretty-printed as+     -- arguments to the function in `exprDoc`. This ensures that arguments+     -- are parenthesized as needed.+     docs <- mapM (rEval . E.ppValuePrec Concrete ppOpts 1) vs      let cexRes = case cexTy of            SafetyViolation    -> [text "~> ERROR"]            PredicateFalsified -> [text "= False"]@@ -1823,7 +1827,7 @@         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))+       depList show               "foreign"  (Map.toList (M.fiForeignDeps fi))         rPutStrLn "}" 
src/Cryptol/REPL/Help.hs view
@@ -34,18 +34,20 @@          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+         vNames = M.lookupListNS M.NSValue       qname rnEnv+         cNames = M.lookupListNS M.NSConstructor 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 (showConHelp env disp qname) cNames ++                  map (showModHelp env disp) mNames           separ = rPutStrLn "            ---------"      sequence_ (intersperse separ helps) -     when (null (vNames ++ tNames ++ mNames)) $+     when (null (vNames ++ cNames ++ tNames ++ mNames)) $        rPrint $ "Undefined name:" <+> pp qname  @@ -84,7 +86,7 @@     foldr addName emptySummary (Set.toList (M.ifsPublic info))   where   addName x ns = fromMaybe ns-               $ msum [ addT <$> msum [fromTS, fromNT, fromAT]+               $ msum [ addT <$> msum [fromTS, fromNT ]                       , addV <$> fromD                       , addM <$> msum [ fromM, fromS, fromF ]                       ]@@ -106,12 +108,9 @@     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)+    fromNT = do def <- Map.lookup x (M.ifNominalTypes 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) @@ -230,7 +229,7 @@   M.ModContextParams -> M.IfaceDecls -> NameDisp -> T.Name -> REPL () showTypeHelp ctxparams env nameEnv name =   fromMaybe (noInfo nameEnv name) $-  msum [ fromTySyn, fromPrimType, fromNewtype, fromTyParam ]+  msum [ fromTySyn, fromNominal, fromTyParam ]    where   fromTySyn =@@ -240,31 +239,40 @@                   ]        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)+  fromNominal =+    do nt <- Map.lookup name (M.ifNominalTypes env)+       let decl kw =+             vcat+               [ kw <+> pp (T.ntName nt) <.> ":" <+> pp (T.kindOf nt)+               , ""+               , "Constructors:" <+>+                                   commaSep+                                   (map (pp . fst) (T.nominalTypeConTypes nt))+               ]+       case T.ntDef nt of+         T.Struct {} -> pure $ doShowTyHelp nameEnv (decl "newtype") (T.ntDoc nt)+         T.Enum {}   -> pure $ doShowTyHelp nameEnv (decl "enum") (T.ntDoc nt)+         T.Abstract  -> pure (primTypeHelp 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)+  primTypeHelp nt =+    do rPutStrLn ""+       rPrint $ runDoc nameEnv $ nest 4+              $ "primitive type" <+> pp (T.ntName nt)+                         <+> ":" <+> pp (T.kindOf nt) -                 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)+       let vs = T.ntParams nt+       let cs = T.ntConstraints nt+       unless (null cs) $+         do let example = T.TNominal nt (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)+       doShowFix (T.ntFixity nt)+       doShowDocString (T.ntDoc nt)    allParamNames =     case ctxparams of@@ -293,14 +301,35 @@      rPrint (runDoc nameEnv (nest 4 decl))      doShowDocString doc +showConHelp :: M.IfaceDecls -> NameDisp -> P.PName -> T.Name -> REPL ()+showConHelp env nameEnv qname name =+  fromMaybe (noInfo nameEnv name) (Map.lookup name allCons)+  where+  allCons = foldr addCons mempty (M.ifNominalTypes env)+    where+    getDocs nt =+      case T.ntDef nt of+        T.Struct {} -> [ Nothing ]+        T.Enum cs   -> map (Just . T.ecDoc) cs+        T.Abstract  -> [] +    addCons nt mp = foldr (addCon nt) mp+                      (zip (T.nominalTypeConTypes nt) (getDocs nt))+    addCon nt ((c,t),d) = Map.insert c $+      do rPutStrLn ""+         rPrint (runDoc nameEnv $ vcat+            [ "Constructor of" <+> pp (T.ntName nt)+            , indent 4 $ hsep [ pp qname, ":", pp t ]+            ])+         maybe (pure ()) doShowDocString d + 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 ])+            (msum [ fromDecl, fromParameter ])   where   fromDecl =     do M.IfaceDecl { .. } <- Map.lookup name (M.ifDecls env)@@ -320,10 +349,6 @@                         (guard ifDeclInfix >> return P.defaultFixity)              doShowDocString ifDeclDoc--  fromNewtype =-    do _ <- Map.lookup name (M.ifNewtypes env)-       return $ return ()    allParamNames =     case ctxparams of
src/Cryptol/REPL/Monad.hs view
@@ -126,6 +126,7 @@ import Data.List (intercalate, isPrefixOf, unfoldr, sortBy) import Data.Maybe (catMaybes) import Data.Ord (comparing)+import Data.Tuple (swap) import Data.Typeable (Typeable) import System.Directory (findExecutable) import System.FilePath (splitSearchPath, searchPathSeparator)@@ -979,6 +980,26 @@                EnvBool False -> setIt M.NoCoreLint                _             -> return () +  , OptionDescr "evalForeign" ["eval-foreign"] defaultEvalForeignOpt+    checkEvalForeign+    (unlines+      [ "How to evaluate 'foreign' bindings:"+      , "  * always  Always call the foreign implementation with the FFI and"+      , "            report an error on module load if it is unavailable."+      , "  * prefer  Call the foreign implementation with the FFI by default,"+      , "            and when unavailable, fall back to the cryptol"+      , "            implementation if present and report runtime error"+      , "            otherwise."+      , "  * never   Never use the FFI. Always call the cryptol implementation"+      , "            if present, and report runtime error otherwise."+      , "Note: changes take effect on module reload."+      ]) $+    \case EnvString s+            | Just p <- lookup s evalForeignOptMap -> do+              me <- getModuleEnv+              setModuleEnv me { M.meEvalForeignPolicy = p }+          _ -> pure ()+   , simpleOpt "hashConsing" ["hash-consing"] (EnvBool True) noCheck     "Enable hash-consing in the What4 symbolic backends." @@ -1119,6 +1140,26 @@     _ | Just n <- readMaybe s -> return (SomeSat n)     _                         -> panic "REPL.Monad.getUserSatNum"                                    [ "invalid satNum option" ]++checkEvalForeign :: Checker+checkEvalForeign (EnvString s)+  | Just _ <- lookup s evalForeignOptMap = noWarns Nothing+checkEvalForeign _ = noWarns $ Just $ "evalForeign must be one of: "+  ++ intercalate ", " (map fst evalForeignOptMap)++evalForeignOptMap :: [(String, M.EvalForeignPolicy)]+evalForeignOptMap =+  [ ("always", M.AlwaysEvalForeign)+  , ("prefer", M.PreferEvalForeign)+  , ("never", M.NeverEvalForeign)+  ]++defaultEvalForeignOpt :: EnvVal+defaultEvalForeignOpt =+  case lookup M.defaultEvalForeignPolicy (map swap evalForeignOptMap) of+    Just s -> EnvString s+    Nothing -> panic "defaultEvalForeignOpt"+      ["cannot find option value matching default EvalForeignPolicy"]  checkTimeMeasurementPeriod :: Checker checkTimeMeasurementPeriod (EnvNum n)
src/Cryptol/Symbolic.hs view
@@ -26,6 +26,7 @@  , CounterExampleType(..)    -- * FinType  , FinType(..)+ , FinNominalType(..)  , finType  , unFinType  , predArgTypes@@ -44,9 +45,12 @@   import Control.Monad (foldM)+import qualified Data.IntMap.Strict as IntMap import Data.IORef(IORef) import Data.List (genericReplicate) import Data.Ratio+import Data.Vector(Vector)+import qualified Data.Vector as Vector import qualified LibBF as FP  @@ -59,7 +63,8 @@ import           Cryptol.Eval.Value import           Cryptol.TypeCheck.AST import           Cryptol.TypeCheck.Solver.InfNat-import           Cryptol.Eval.Type (TValue(..), evalType,tValTy,tNumValTy)+import           Cryptol.Eval.Type+  (TValue(..), TNominalTypeValue(..), evalType,tValTy,tNumValTy,ConInfo(..)) import           Cryptol.Utils.Ident (Ident,prelPrim,floatPrim) import           Cryptol.Utils.RecordMap import           Cryptol.Utils.Panic@@ -118,8 +123,6 @@                   | EmptyResult                   | ProverError  String -- predArgTypes :: QueryType -> Schema -> Either String [FinType] predArgTypes qtype schema@(Forall ts ps ty)   | null ts && null ps =@@ -149,8 +152,12 @@     | FTSeq Integer FinType     | FTTuple [FinType]     | FTRecord (RecordMap Ident FinType)-    | FTNewtype Newtype [Either Nat' TValue] (RecordMap Ident FinType)+    | FTNominal NominalType [Either Nat' TValue] FinNominalType +data FinNominalType =+    FStruct (RecordMap Ident FinType)+  | FEnum (Vector (ConInfo FinType))+ finType :: TValue -> Maybe FinType finType ty =   case ty of@@ -162,8 +169,12 @@     TVSeq n t           -> FTSeq n <$> finType t     TVTuple ts          -> FTTuple <$> traverse finType ts     TVRec fields        -> FTRecord <$> traverse finType fields-    TVNewtype u ts body -> FTNewtype u ts <$> traverse finType body-    TVAbstract {}       -> Nothing+    TVNominal u ts nv   -> FTNominal u ts <$>+      case nv of+        TVStruct body -> FStruct <$> traverse finType body+        TVEnum cs     -> FEnum   <$> traverse (traverse finType) cs+        TVAbstract    -> Nothing+     TVArray{}           -> Nothing     TVStream{}          -> Nothing     TVFun{}             -> Nothing@@ -179,7 +190,7 @@     FTSeq l ety       -> tSeq (tNum l) (finTypeToType ety)     FTTuple ftys      -> tTuple (finTypeToType <$> ftys)     FTRecord fs       -> tRec (finTypeToType <$> fs)-    FTNewtype u ts _  -> tNewtype u (map unArg ts)+    FTNominal u ts _  -> tNominal u (map unArg ts)  where   unArg (Left Inf)     = tInf   unArg (Left (Nat n)) = tNum n@@ -196,8 +207,12 @@     FTSeq n ety       -> TVSeq n (unFinType ety)     FTTuple ftys      -> TVTuple (unFinType <$> ftys)     FTRecord fs       -> TVRec   (unFinType <$> fs)-    FTNewtype u ts fs -> TVNewtype u ts (unFinType <$> fs) +    FTNominal u ts nv -> TVNominal u ts $+       case nv of+          FStruct fs  -> TVStruct (unFinType <$> fs)+          FEnum cs    -> TVEnum (fmap unFinType <$> cs)+ data VarShape sym   = VarBit (SBit sym)   | VarInteger (SInteger sym)@@ -207,6 +222,7 @@   | VarFinSeq Integer [VarShape sym]   | VarTuple [VarShape sym]   | VarRecord (RecordMap Ident (VarShape sym))+  | VarEnum (SInteger sym) (Vector (ConInfo (VarShape sym)))  ppVarShape :: Backend sym => sym -> VarShape sym -> Doc ppVarShape _sym (VarBit _b) = text "<bit>"@@ -222,6 +238,7 @@   ppRecord (map ppField (displayFields fs))  where   ppField (f,v) = pp f <+> char '=' <+> ppVarShape sym v+ppVarShape _sym (VarEnum {}) = text "<enum>"   -- | Flatten structured shapes (like tuples and sequences), leaving only@@ -241,6 +258,9 @@     VarFinSeq _ vs -> flattenShapes vs tl     VarTuple vs    -> flattenShapes vs tl     VarRecord fs   -> flattenShapes (recordElements fs) tl+    VarEnum _ cs   -> x : flattenShapes allCons tl+      where+      allCons = concatMap (Vector.toList . conFields) (Vector.toList cs)  varShapeToValue :: Backend sym => sym -> VarShape sym -> GenValue sym varShapeToValue sym var =@@ -253,6 +273,10 @@     VarFinSeq n vs -> VSeq n (finiteSeqMap sym (map (pure . varShapeToValue sym) vs))     VarTuple vs  -> VTuple (map (pure . varShapeToValue sym) vs)     VarRecord fs -> VRecord (fmap (pure . varShapeToValue sym) fs)+    VarEnum tag cons ->+      VEnum tag (IntMap.fromList+                   (zip [ 0 .. ] [ pure . varShapeToValue sym <$> c+                                 | c <- Vector.toList cons ]))  data FreshVarFns sym =   FreshVarFns@@ -277,8 +301,16 @@     FTSeq n t     -> VarFinSeq (toInteger n) <$> sequence (genericReplicate n (freshVar fns t))     FTTuple ts    -> VarTuple    <$> mapM (freshVar fns) ts     FTRecord fs   -> VarRecord   <$> traverse (freshVar fns) fs-    FTNewtype _ _ fs -> VarRecord <$> traverse (freshVar fns) fs+    FTNominal _ _ nv ->+      case nv of+        FStruct fs -> VarRecord <$> traverse (freshVar fns) fs+        FEnum conTs ->+          do let maxCon = toInteger (Vector.length conTs - 1)+             tag <- freshIntegerVar fns (Just 0) (Just maxCon)+             cons <- traverse (traverse (freshVar fns)) conTs+             pure (VarEnum tag cons) + computeModel ::   PrimMap ->   [FinType] ->@@ -332,6 +364,17 @@     (VarFinSeq _n vs, VarFinSeq _ xs) -> modelPred sym vs xs     (VarTuple vs, VarTuple xs) -> modelPred sym vs xs     (VarRecord vs, VarRecord xs) -> modelPred sym (recordElements vs) (recordElements xs)+    (VarEnum vi vcons,  VarEnum i cons) ->+      do tag     <- integerLit sym i+         sameTag <- intEq sym tag vi+         let i' = fromInteger i+             flds = Vector.toList . conFields+         sameFs  <- case (vcons Vector.!? i', cons Vector.!? i') of+                      (Just con1, Just con2) ->+                         modelPred sym (flds con1) (flds con2)+                      _ -> panic "varModelPred" ["malformed constructor"]+         bitAnd sym sameTag sameFs+     _ -> panic "varModelPred" ["variable shape mismatch!"]  @@ -344,13 +387,35 @@   go :: FinType -> VarShape Concrete.Concrete -> Expr   go ty val =     case (ty,val) of-      (FTNewtype nt ts tfs, VarRecord vfs) ->+      (FTNominal nt ts (FStruct tfs), VarRecord vfs) ->         let res = zipRecords (\_lbl v t -> go t v) vfs tfs          in case res of               Left _ -> mismatch -- different fields               Right efs ->-                let f = foldl (\x t -> ETApp x (tNumValTy t)) (EVar (ntConName nt)) ts+                let con = case ntDef nt of+                            Struct c -> ntConName c+                            Enum {} -> panic "varToExpr" ["Enum, expected Struct"]+                            Abstract {} -> panic "varToExpr"+                              ["Abstract, expected Struct"]+                    f = foldl (\x t -> ETApp x (tNumValTy t)) (EVar con) ts                  in EApp f (ERec efs)++      (FTNominal nt ts (FEnum cons), VarEnum tag conVs) ->+         foldl EApp conName args+         where+         tag' = fromInteger tag+         args = case (cons Vector.!? tag', conVs Vector.!? tag') of+                 (Just conT, Just conV) ->+                    Vector.toList+                       (Vector.zipWith go (conFields conT) (conFields conV))+                 _ -> panic "varToExpr" ["Malformed constructor"]++         conName =+           case ntDef nt of+             Enum cs | c : _ <- filter ((tag' ==) . ecNumber ) cs ->+                foldl (\x t -> ETApp x (tNumValTy t)) (EVar (ecName c)) ts++             _ -> panic "varToExpr" ["Missing constructor"]        (FTRecord tfs, VarRecord vfs) ->         let res = zipRecords (\_lbl v t -> go t v) vfs tfs
src/Cryptol/Symbolic/SBV.hs view
@@ -34,9 +34,11 @@ import Control.Monad.IO.Class import Control.Monad (when, foldM, forM_) import Data.Maybe (fromMaybe)+import Data.Traversable(mapAccumL) import qualified Data.Map as Map import qualified Control.Exception as X import System.Exit (ExitCode(ExitSuccess))+import qualified Data.Vector as Vector  import LibBF(bfNaN) @@ -57,6 +59,7 @@ import qualified Cryptol.Eval as Eval import qualified Cryptol.Eval.Concrete as Concrete import qualified Cryptol.Eval.Value as Eval+import           Cryptol.Eval.Type import           Cryptol.Eval.SBV import           Cryptol.Parser.Position (emptyRange) import           Cryptol.Symbolic@@ -316,7 +319,7 @@       getEOpts <- M.getEvalOptsAction -     ntEnv <- M.getNewtypes+     ntEnv <- M.getNominalTypes       -- The `addAsm` function is used to combine assumptions that      -- arise from the types of symbolic variables (e.g. Z n values@@ -351,7 +354,7 @@                  -- we apply it to the symbolic inputs.                  (safety,b) <- doSBVEval $                      do env <- Eval.evalDecls sym extDgs =<<-                                 Eval.evalNewtypeDecls sym ntEnv mempty+                                 Eval.evalNominalDecls sym ntEnv mempty                         v <- Eval.evalExpr sym env pcExpr                         appliedVal <- foldM (Eval.fromVFun sym) v args                         case pcQueryType of@@ -535,7 +538,17 @@         fs         = zip ns vs         r'         = recordFromFieldsWithDisplay (displayOrder r) fs -parseValue (FTNewtype _ _ r) cvs = parseValue (FTRecord r) cvs+parseValue (FTNominal _ _ nv) cvs =+  case nv of+    FStruct r -> parseValue (FTRecord r) cvs+    FEnum cons ->+      fromMaybe (panic "Cryptol.Symbolic.parseValue" ["no enum"]) $+      do (tag, cvs') <- SBV.genParse SBV.KUnbounded cvs+         let doCon input con =+               case parseValues (Vector.toList (conFields con)) input of+                 (vs,input') -> (input', con { conFields = Vector.fromList vs })+             (input3, conVs) = mapAccumL doCon cvs' cons+         pure (VarEnum tag conVs, input3)  parseValue (FTFloat e p) cvs =    (VarFloat FH.BF { FH.bfValue = bfNaN
src/Cryptol/Symbolic/What4.hs view
@@ -309,7 +309,7 @@                        ([FinType],[VarShape (What4 sym)],W4.Pred sym, W4.Pred sym)                ) prepareQuery sym ProverCommand { .. } = do-  ntEnv <- M.getNewtypes+  ntEnv <- M.getNominalTypes   case predArgTypes pcQueryType pcSchema of     Left msg -> pure (Left msg)     Right ts ->@@ -362,7 +362,7 @@         doW4Eval (w4 sym)          do env <- Eval.evalDecls sym extDgs =<<-                     Eval.evalNewtypeDecls sym ntEnv mempty+                     Eval.evalNominalDecls sym ntEnv mempty              v   <- Eval.evalExpr  sym env    pcExpr             appliedVal <-@@ -751,3 +751,6 @@       VarTuple <$> mapM (varShapeToConcrete evalFn) vs     VarRecord fs ->       VarRecord <$> traverse (varShapeToConcrete evalFn) fs+    VarEnum tag cons ->+      VarEnum <$> W4.groundEval evalFn tag+              <*> traverse (traverse (varShapeToConcrete evalFn)) cons
src/Cryptol/Testing/Random.hs view
@@ -33,8 +33,12 @@ import Control.Monad          (liftM2) import Control.Monad.IO.Class (MonadIO(..)) import Data.Bits-import Data.List              (unfoldr, genericTake, genericIndex, genericReplicate)+import Data.List              (unfoldr, genericTake, genericIndex,+                               genericReplicate, mapAccumL)+import qualified Data.IntMap.Strict as IntMap import qualified Data.Sequence as Seq+import Data.Vector(Vector)+import qualified Data.Vector as Vector  import System.Random.TF.Gen import System.Random.TF.Instances@@ -46,8 +50,10 @@ import Cryptol.Backend.SeqMap (indexSeqMap, finiteSeqMap) import Cryptol.Backend.WordValue (wordVal) -import Cryptol.Eval.Type      (TValue(..))-import Cryptol.Eval.Value     (GenValue(..), ppValue, defaultPPOpts, fromVFun)+import Cryptol.Eval(evalEnumCon)+import Cryptol.Eval.Type      ( TValue(..), TNominalTypeValue(..), ConInfo(..)+                              , isNullaryCon )+import Cryptol.Eval.Value     ( GenValue(..), ppValue, defaultPPOpts, fromVFun) import Cryptol.TypeCheck.Solver.InfNat (widthInteger) import Cryptol.Utils.Ident    (Ident) import Cryptol.Utils.Panic    (panic)@@ -164,12 +170,18 @@     TVRec fs ->          do gs <- traverse (randomValue sym) fs             return (randomRecord gs)-    TVNewtype _ _ fs ->-         do gs <- traverse (randomValue sym) fs-            return (randomRecord gs)++    TVNominal _ _ nval ->+      case nval of+        TVStruct fs ->+          do gs <- traverse (randomValue sym) fs+             return (randomRecord gs)+        TVEnum cons -> randomCon sym <$>+                          traverse (traverse (randomValue sym)) cons+        TVAbstract -> Nothing+     TVArray{} -> Nothing     TVFun{} -> Nothing-    TVAbstract{} -> Nothing  {-# INLINE randomBit #-} @@ -270,6 +282,69 @@       let (v, g') = gen sz g       in seq v (g', v) +-- | Generate a random constructor value belonging to an enum definition.+--+-- For the purposes of random testing, constructors with zero fields (i.e.,+-- nullary constructors) are less interesting than constructors with at least+-- one field (i.e., non-nullary constructors). For example, given+-- @enum Maybe a = Nothing | Just a@, we would like to generate more @Just@+-- values than @Nothing@ values. To ensure this, we employ the following+-- approach:+--+-- 1. If all constructors are nullary, then randomly pick one of these+--    constructors, where each constructor has an equal chance of being picked.+--+-- 2. If all constructors are non-nullary, then randomly pick one of these+--    constructors, where each constructor has an equal chance of being picked.+--    Then pick random values for each field in the constructor.+--+-- 3. Otherwise, pick a random number between 1 and 100. If the number is less+--    than or equal to 25, then randomly pick a nullary constructor. Otherwise,+--    randomly pick a non-nullary constructor. This biases the results so that+--    nullary constructors are only picked ~25% of the time.+randomCon ::+  forall sym g.+  (Backend sym, RandomGen g) =>+  sym ->+  Vector (ConInfo (Gen g sym)) ->+  Gen g sym+randomCon sym cons+    -- (1) from the Haddocks+  | null nonNullaryCons+  = randomCon' nullaryLen nullaryCons++    -- (2) from the Haddocks+  | null nullaryCons+  = randomCon' nonNullaryLen nonNullaryCons++    -- (3) from the Haddocks+  | otherwise+  = \sz g0 ->+      let (x :: Int, g1) = randomR (1, 100) g0 in+      if x <= 25+         then randomCon' nullaryLen nullaryCons sz g1+         else randomCon' nonNullaryLen nonNullaryCons sz g1+  where+    (nullaryLen,nullaryCons, nonNullaryLen, nonNullaryCons) =+       let check (!nullLen,nullary,!nonNullLen,nonNullary) i con+             | isNullaryCon con = ( 1+nullLen,(i,con) : nullary+                                  , nonNullLen, nonNullary)+             | otherwise        = (nullLen, nullary+                                  , 1+nonNullLen, (i,con) : nonNullary)+        in Vector.ifoldl' check (0,[],0,[]) cons++    randomCon' :: Int -> [(Int, ConInfo (Gen g sym))] -> Gen g sym+    randomCon' conLen cons' sz g0 =+      let (idx, g1) = randomR (0, conLen - 1) g0+          (num, con) = cons' !! idx+          (g2, !flds') =+            mapAccumL+              (\g gen ->+                let (v, g') = gen sz g in+                seq v (g', v))+              g1 (conFields con) in+      (($ flds') <$> evalEnumCon sym (conIdent con) num, g2)+ randomFloat ::   (Backend sym, RandomGen g) =>   sym ->@@ -398,8 +473,12 @@   TVTuple els -> product <$> mapM typeSize els   TVRec fs -> product <$> traverse typeSize fs   TVFun{} -> Nothing-  TVAbstract{} -> Nothing-  TVNewtype _ _ tbody -> typeSize (TVRec tbody)+  TVNominal _ _ nv ->+    case nv of+      TVStruct tbody -> typeSize (TVRec tbody)+      TVEnum cons -> sum <$> mapM (conSize . conFields) cons+        where conSize = foldr (\t sz -> liftM2 (*) (typeSize t) sz) (Just 1)+      TVAbstract -> Nothing  {- | Returns all the values in a type.  Returns an empty list of values, for types where 'typeSize' returned 'Nothing'. -}@@ -430,8 +509,16 @@       | xs <- traverse typeValues fs       ]     TVFun{} -> []-    TVAbstract{} -> []-    TVNewtype _ _ tbody -> typeValues (TVRec tbody)+    TVNominal _ _ nv ->+      case nv of+        TVStruct tbody -> typeValues (TVRec tbody)+        TVEnum cons ->+          [ VEnum (toInteger tag) (IntMap.singleton tag con')+          | (tag,con) <- zip [0..] (Vector.toList cons)+          , vs        <- mapM typeValues (conFields con)+          , let con' = con { conFields = pure <$> vs }+          ]+        TVAbstract -> []  -------------------------------------------------------------------------------- -- Driver function
src/Cryptol/Transform/MonoValues.hs view
@@ -187,6 +187,8 @@       ESel e s        -> ESel    <$> go e  <*> return s       ESet ty e s v   -> ESet ty <$> go e  <*> return s <*> go v       EIf e1 e2 e3    -> EIf     <$> go e1 <*> go e2 <*> go e3+      ECase e as d    -> ECase   <$> go e  <*> traverse (rewCase rews) as+                                           <*> traverse (rewCase rews) d        EComp len t e mss -> EComp len t <$> go e  <*> mapM (mapM (rewM rews)) mss       EVar _          -> return expr@@ -204,6 +206,9 @@       EPropGuards guards ty -> EPropGuards <$> (\(props, e) -> (,) <$> pure props <*> go e) `traverse` guards <*> pure ty  +rewCase :: RewMap -> CaseAlt -> M CaseAlt+rewCase rew (CaseAlt xs e) = CaseAlt xs <$> rewE rew e+ rewM :: RewMap -> Match -> M Match rewM rews ma =   case ma of@@ -218,9 +223,9 @@                  return d { dDefinition = e }  rewDef :: RewMap -> DeclDef -> M DeclDef-rewDef rews (DExpr e)    = DExpr <$> rewE rews e-rewDef _    DPrim        = return DPrim-rewDef _    (DForeign t) = return $ DForeign t+rewDef rews (DExpr e)       = DExpr <$> rewE rews e+rewDef _    DPrim           = return DPrim+rewDef rews (DForeign t me) = DForeign t <$> traverse (rewE rews) me  rewDeclGroup :: RewMap -> DeclGroup -> M DeclGroup rewDeclGroup rews dg =@@ -240,12 +245,17 @@    consider d   =     case dDefinition d of-      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+      DPrim         -> Left d+      DForeign _ me -> case me of+                         Nothing -> Left d+                         Just e  -> conExpr e+      DExpr e       -> conExpr e+    where+    conExpr 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
@@ -85,6 +85,9 @@     ESel e s      -> ESel <$> specializeExpr e <*> pure s     ESet ty e s v -> ESet ty <$> specializeExpr e <*> pure s <*> specializeExpr v     EIf e1 e2 e3  -> EIf <$> specializeExpr e1 <*> specializeExpr e2 <*> specializeExpr e3+    ECase e as d   -> ECase <$> specializeExpr e+                            <*> traverse specializeCaseAlt as+                            <*> traverse specializeCaseAlt d     EComp len t e mss -> EComp len t <$> specializeExpr e <*> traverse (traverse specializeMatch) mss     -- Bindings within list comprehensions always have monomorphic types.     EVar {}       -> specializeConst expr@@ -117,6 +120,8 @@           pm <- liftSpecT getPrimMap           pure $ eError pm ty "no constraint guard was satisfied" +specializeCaseAlt :: CaseAlt -> SpecM CaseAlt+specializeCaseAlt (CaseAlt xs e) = CaseAlt xs <$> specializeExpr e  specializeMatch :: Match -> SpecM Match specializeMatch (From qn l t e) = From qn l t <$> specializeExpr e@@ -201,11 +206,11 @@                  qname' <- freshName qname ts -- New type instance, record new name                  sig' <- instantiateSchema ts n (dSignature decl)                  modifySpecCache (Map.adjust (fmap (insertTM ts (qname', Nothing))) qname)+                 let spec e = specializeExpr =<< instantiateExpr ts n e                  rhs' <- case dDefinition decl of-                           DExpr e    -> do e' <- specializeExpr =<< instantiateExpr ts n e-                                            return (DExpr e')-                           DPrim      -> return DPrim-                           DForeign t -> return $ DForeign t+                           DExpr e       -> DExpr <$> spec e+                           DPrim         -> return DPrim+                           DForeign t me -> DForeign t <$> traverse spec me                  let decl' = decl { dName = qname', dSignature = sig', dDefinition = rhs' }                  modifySpecCache (Map.adjust (fmap (insertTM ts (qname', Just decl'))) qname)                  return (EVar qname')
src/Cryptol/TypeCheck.hs view
@@ -86,7 +86,7 @@                 [ P.Bind                     { P.bName      = P.Located { P.srcRange = loc, P.thing = fresh }                     , P.bParams    = []-                    , P.bDef       = P.Located (inpRange inp) (P.DExpr expr)+                    , P.bDef       = P.Located (inpRange inp) (P.exprDef expr)                     , P.bPragmas   = []                     , P.bSignature = Nothing                     , P.bMono      = False
src/Cryptol/TypeCheck/AST.hs view
@@ -36,6 +36,7 @@ import Cryptol.Utils.Ident (Ident,isInfixIdent,ModName,PrimIdent,prelPrim) import Cryptol.Parser.Position(Located,Range,HasLoc(..)) import Cryptol.ModuleSystem.Name+import Cryptol.ModuleSystem.NamingEnv.Types import Cryptol.ModuleSystem.Interface import Cryptol.ModuleSystem.Exports(ExportSpec(..)                                    , isExportedBind, isExportedType, isExported)@@ -106,11 +107,14 @@                        -- These have everything from this module and all submodules                      , mTySyns           :: Map Name TySyn-                     , mNewtypes         :: Map Name Newtype-                     , mPrimTypes        :: Map Name AbstractType+                     , mNominalTypes     :: Map Name NominalType                      , mDecls            :: [DeclGroup]                      , mSubmodules       :: Map Name (IfaceNames Name)                      , mSignatures       :: !(Map Name ModParamNames)++                     , mInScope          :: NamingEnv+                       -- ^ Things in scope at the top level.+                       --   Submodule in-scope information is in 'mSubmodules'.                      } deriving (Show, Generic, NFData)  emptyModule :: mname -> ModuleG mname@@ -128,28 +132,34 @@     , mNested           = mempty      , mTySyns           = mempty-    , mNewtypes         = mempty-    , mPrimTypes        = mempty+    , mNominalTypes     = mempty     , mDecls            = mempty     , mFunctors         = mempty     , mSubmodules       = mempty     , mSignatures       = mempty++    , mInScope          = 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+findForeignDecls = mapMaybe getForeign . concatMap groupDecls . mDecls+  where getForeign d =+          case dDefinition d of+            DForeign ffiType _ -> Just (dName d, ffiType)+            _                  -> Nothing --- | Find all the foreign declarations that are in functors.+-- | Find all the foreign declarations that are in functors, including in the+-- top-level module itself if it is a functor. -- This is used to report an error findForeignDeclsInFunctors :: ModuleG mname -> [Name]-findForeignDeclsInFunctors = concatMap fromM . Map.elems . mFunctors+findForeignDeclsInFunctors mo+  | isParametrizedModule mo = fromM mo+  | otherwise               = findInSubs mo   where-  fromM m = map fst (findForeignDecls m) ++ findForeignDeclsInFunctors m+  findInSubs :: ModuleG mname -> [Name]+  findInSubs = concatMap fromM . Map.elems . mFunctors+  fromM m = map fst (findForeignDecls m) ++ findInSubs m   @@ -172,6 +182,11 @@                                            --   The included type gives the type of the record being updated              | EIf Expr Expr Expr        -- ^ If-then-else+            | ECase Expr (Map Ident CaseAlt) (Maybe CaseAlt)+              -- ^ Case expression. The keys are the name of constructors+              -- `Nothing` for default case, the expresssions are what to+              -- do if the constructor matches.  If the constructor binds+              -- variables, then then the expr should be `EAbs`             | EComp Type Type Expr [[Match]]                                         -- ^ List comprehensions                                         --   The types cache the length of the@@ -211,6 +226,10 @@                deriving (Show, Generic, NFData) +-- | Used for case expressions.  Similar to a lambda, the variables+-- are bound by the value examined in the case.+data CaseAlt = CaseAlt [(Name,Type)] Expr+  deriving (Show, Generic, NFData)  data Match  = From Name Type Type Expr                                   -- ^ Type arguments are the length and element@@ -238,7 +257,9 @@                        } deriving (Generic, NFData, Show)  data DeclDef    = DPrim-                | DForeign FFIFunType+                -- | Foreign functions can have an optional cryptol+                -- implementation+                | DForeign FFIFunType (Maybe Expr)                 | DExpr Expr                   deriving (Show, Generic, NFData) @@ -294,9 +315,17 @@                     $ sep [ text "if"   <+> ppW e1                           , text "then" <+> ppW e2                           , text "else" <+> ppW e3 ]+      ECase e arms dflt ->+        optParens (prec > 0) $+        vcat [ "case" <+> pp e <+> "of"+             , indent 2 (vcat ppArms $$ ppDflt)+             ]+        where+        ppArms  = [ pp i <+> pp c | (i,c) <- reverse (Map.toList arms) ]+        ppDflt  = maybe mempty pp dflt        EComp _ _ e mss -> let arm ms = text "|" <+> commaSep (map ppW ms)-                          in brackets $ ppW e <+> (align (vcat (map arm mss)))+                          in brackets $ ppW e <+> align (vcat (map arm mss))        EVar x        -> ppPrefixName x @@ -344,6 +373,10 @@     ppW x   = ppWithNames nm x     ppWP x  = ppWithNamesPrec nm x +instance PP CaseAlt where+  ppPrec _ (CaseAlt xs e) = hsep (map ppV xs) <+> "->" <+> pp e+    where ppV (x,t) = parens (pp x <.> ":" <+> pp t)+ ppLam :: NameMap -> Int -> [TParam] -> [Prop] -> [(Name,Type)] -> Expr -> Doc ppLam nm prec [] [] [] e = nest 2 (ppWithNamesPrec nm prec e) ppLam nm prec ts ps xs e =@@ -456,9 +489,12 @@       ++ [ nest 2 (sep [pp dName <+> text "=", ppWithNames nm dDefinition]) ]  instance PP (WithNames DeclDef) where-  ppPrec _ (WithNames DPrim _)        = text "<primitive>"-  ppPrec _ (WithNames (DForeign _) _) = text "<foreign>"-  ppPrec _ (WithNames (DExpr e) nm)   = ppWithNames nm e+  ppPrec _ (WithNames DPrim _) = text "<primitive>"+  ppPrec _ (WithNames (DForeign _ me) nm) =+    case me of+      Just e -> text "(foreign)" <+> ppWithNames nm e+      Nothing -> text "<foreign>"+  ppPrec _ (WithNames (DExpr e) nm) = ppWithNames nm e  instance PP Decl where   ppPrec = ppWithNamesPrec IntMap.empty
src/Cryptol/TypeCheck/Error.hs view
@@ -94,6 +94,13 @@               | TypeMismatch TypeSource Path Type Type                 -- ^ Expected type, inferred type +              | EnumTypeMismatch Type+                -- ^ Expected an enum type, but inferred the supplied 'Type'+                --   instead, which is not an enum. This corresponds to the+                --   \"Matched Expression Must Have a Known Enum Type\"+                --   restriction for @case@ expressions, as described in the+                --   Cryptol Reference Manual.+               | SchemaMismatch Ident Schema Schema                 -- ^ Name of module parameter, expected scehema, actual schema.                 -- This may happen when instantiating modules.@@ -172,6 +179,18 @@               | InvalidConstraintGuard Prop                 -- ^ The given constraint may not be used as a constraint guard +              | InvalidConPat Int Int+                -- ^ Bad constructor pattern.+                -- 1) Number of parameters we have,+                -- 2) Number of parameters we need.++              | UncoveredConPat [Name]+                -- ^ A @case@ expression is non-exhaustive and does not cover+                --   the supplied constructor 'Name's.++              | OverlappingPat (Maybe Ident) [Range]+                -- ^ Overlapping patterns in a case+               | TemporaryError Doc                 -- ^ This is for errors that don't fit other cateogories.                 -- We should not use it much, and is generally to be used@@ -207,7 +226,11 @@     KindMismatch {}                                  -> 10     TyVarWithParams {}                               -> 9     TypeMismatch {}                                  -> 8+    EnumTypeMismatch {}                              -> 7     SchemaMismatch {}                                -> 7+    InvalidConPat {}                                 -> 7+    UncoveredConPat {}                               -> 7+    OverlappingPat {}                                -> 3     RecursiveType {}                                 -> 7     NotForAll {}                                     -> 6     TypeVariableEscaped {}                           -> 5@@ -281,6 +304,10 @@       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)+      EnumTypeMismatch t        -> EnumTypeMismatch !$ apSubst su t+      InvalidConPat {}          -> err+      UncoveredConPat {}        -> err+      OverlappingPat {}         -> err       RecursiveType src pa t1 t2   -> RecursiveType src pa !$ (apSubst su t1) !$ (apSubst su t2)       UnsolvedGoals gs          -> UnsolvedGoals !$ apSubst su gs       UnsolvableGoals gs        -> UnsolvableGoals !$ apSubst su gs@@ -331,6 +358,10 @@       RecursiveTypeDecls {}     -> Set.empty       SchemaMismatch _ t1 t2    -> fvs (t1,t2)       TypeMismatch _ _ t1 t2    -> fvs (t1,t2)+      EnumTypeMismatch t        -> fvs t+      InvalidConPat {}          -> Set.empty+      UncoveredConPat {}        -> Set.empty+      OverlappingPat {}         -> Set.empty       RecursiveType _ _ t1 t2   -> fvs (t1,t2)       UnsolvedGoals gs          -> fvs gs       UnsolvableGoals gs        -> fvs gs@@ -390,7 +421,7 @@                                               <+> ppWithNames names ty        NonExhaustivePropGuards n ->-        text "Could not prove that the constraint guards used in defining" <+> +        text "Could not prove that the constraint guards used in defining" <+>         pp n <+> text "were exhaustive."  instance PP (WithNames Error) where@@ -439,7 +470,7 @@         addTVarsDescsAfter names err $         nested "Malformed type."           ("Type synonym" <+> nm t <+> "was applied to" <+>-            pl extra "extra parameters" <.> text ".")+            pl extra "extra parameter" <.> text ".")        TooFewTyParams t few ->         addTVarsDescsAfter names err $@@ -461,6 +492,19 @@             ++ ppCtxt pa             ++ ["When checking" <+> pp src] +      EnumTypeMismatch t ->+        case tNoUser t of+          TVar {} ->+            nested "Failed to infer the type of cased expression."+              "Try giving the expression an explicit type annotation."+          _ ->+            addTVarsDescsAfter names err $+            nested "Type mismatch in cased expresson:" $+              vcat+                [ "Expected: an `enum` type"+                , "Inferred:" <+> ppWithNames names t+                ]+       SchemaMismatch i t1 t2 ->           addTVarsDescsAfter names err $           nested ("Type mismatch in module parameter" <+> quotes (pp i)) $@@ -469,6 +513,27 @@             , "Actual type:"   <+> ppWithNames names t2             ] +      InvalidConPat have need ->+        addTVarsDescsAfter names err $+        nested "Invalid constructor pattern" $+          vcat+            [ "Expected" <+> int need <+> "parameters,"+            , "but there are" <+> int have <.> "."+            ]++      UncoveredConPat conNames ->+        "Case expression does not cover the following patterns:"+        $$ commaSep (map pp conNames)++      OverlappingPat mbCon rs ->+        addTVarsDescsAfter names err $+        nested ("Overlapping choices for" <+> what <.> ":") $+          vcat [ "Pattern at" <+> pp r | r <- rs ]+        where+        what = case mbCon of+                 Just i  -> "constructor" <+> pp i+                 Nothing -> "default case"+       UnsolvableGoals gs -> explainUnsolvable names gs        UnsolvedGoals gs@@ -574,6 +639,7 @@               NSValue     -> "value"               NSType      -> "type"               NSModule    -> "module"+              NSConstructor -> "constructor"        FunctorInstanceBadBacktick bad ->         case bad of@@ -607,7 +673,7 @@                 [ "Parameter name:" <+> pp x                 , "Parameterized instantiation requires distinct parameter names"                 ]-                +        UnsupportedFFIKind src param k ->         nested "Kind of type variable unsupported for FFI: " $
src/Cryptol/TypeCheck/Infer.hs view
@@ -10,13 +10,11 @@  {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE PatternGuards #-}-{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE RecursiveDo #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE BlockArguments #-} -- 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 <&>" #-}@@ -43,7 +41,7 @@ import           Cryptol.TypeCheck.Solve import           Cryptol.TypeCheck.SimpType(tMul) import           Cryptol.TypeCheck.Kind(checkType,checkSchema,checkTySyn,-                                        checkPropSyn,checkNewtype,+                                        checkPropSyn,checkNewtype,checkEnum,                                         checkParameterType,                                         checkPrimType,                                         checkParameterConstraints,@@ -79,13 +77,14 @@ inferTopModule m =   case P.mDef m of     P.NormalModule ds ->-      do newModuleScope (thing (P.mName m)) (P.exportedDecls ds)+      do newModuleScope (thing (P.mName m)) (P.exportedDecls ds) (P.mInScope m)          checkTopDecls ds          proveModuleTopLevel          endModule      P.FunctorInstance f as inst ->-      do mb <- doFunctorInst (P.ImpTop <$> P.mName m) f as inst Nothing+      do mb <- doFunctorInst+           (P.ImpTop <$> P.mName m) f as inst (P.mInScope m) Nothing          case mb of            Just mo -> pure mo            Nothing -> panic "inferModule" ["Didnt' get a module"]@@ -202,6 +201,7 @@     P.EFun      {} -> mono     P.ESplit    {} -> mono     P.EPrefix   {} -> mono+    P.ECase {}     -> 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@@ -476,9 +476,134 @@            P.PrefixComplement -> "complement"          checkE (P.EApp prim e) tGoal +    P.ECase e as ->+     do et   <- newType CasedExpression KType+        alts <- forM as \a -> checkCaseAlt a et tGoal+        rng  <- curRange+        e1   <- checkE e (WithSource et CasedExpression (Just rng))++        -- Check for overlapping cases that follow default patterns, e.g.,+        --+        --   enum Foo = A | B+        --   f : Foo -> Bit+        --   f l =+        --     case l of+        --       _ -> True+        --       B -> False+        --+        -- In this example, the `B` case overlaps the catch-all `_` case.+        let defltAltAndOthers = dropWhile (\(_,x,_) -> isJust x) alts+        defltAlt <-+          case defltAltAndOthers of+            [] ->+              pure Nothing+            defltAlt@(_,defltPat,_):otherAlts -> do+              unless (null otherAlts) $+                recordError $+                OverlappingPat defltPat [ r | (r,_,_) <- defltAltAndOthers ]+              pure (Just defltAlt)++        -- Check that there are no overlapping patterns among the case+        -- alternatives, e.g.,+        --+        --   enum Foo = A | B+        --   g : Foo -> Bit+        --   g l =+        --     case l of+        --       A -> True+        --       B -> True+        --       B -> False+        --+        -- In this example, the two `B` cases overlap.+        let mp1 = Map.fromListWith (++) [ (x,[(r,y)]) | (r,x,y) <- alts ]+        forM_ (Map.toList mp1) \(mb,cs) ->+          case cs of+            [_] -> pure ()+            _   -> recordError (OverlappingPat mb [ r | (r,_) <- cs ])++        -- Check that the type of the scrutinee is unambiguously an enum.+        et' <- applySubst et+        cons <- case getLoc e of+                 Just r -> inRange r (expectEnum et')+                 Nothing -> expectEnum et'++        -- Check that the case expression covers all possible constructors.+        -- If there is a default case, there is no need to check anything,+        -- since the default case will catch any constructors that weren't+        -- explicitly matched on.+        case defltAlt of+          Just _ -> pure ()+          Nothing ->+            let uncoveredCons =+                  filter+                    (\con -> Map.notMember (Just (nameIdent (ecName con))) mp1)+                    cons in+            unless (null uncoveredCons) $+              recordError $ UncoveredConPat $ map ecName uncoveredCons++        let dflt = fmap (\(_,_,y) -> y) defltAlt+        let arms = Map.fromList [ (i,a) | (_,Just i, a) <- alts ]+        pure (ECase e1 arms dflt)+     P.EParens e -> checkE e tGoal  +checkCaseAlt ::+  P.CaseAlt Name -> Type -> TypeWithSource ->+  InferM (Range, Maybe Ident, CaseAlt)+checkCaseAlt (P.CaseAlt pat e) srcT resT =+  case pat of+    P.PCon c ps ->+      inRange (srcRange c) $+      do (_tArgs,_pArgs,fTs,cresT) <- instantiatePCon (thing c)+         -- XXX: should we store these somewhere?++         let have = length ps+             need = length fTs+         unless (have == need) (recordError (InvalidConPat have need))+         let expect = WithSource+                        { twsType = srcT+                        , twsRange = Just (srcRange c)+                        , twsSource = ConPat+                        }+         newGoals CtExactType =<< unify expect cresT+         xs <- zipWithM checkNested ps fTs+         e1 <- withMonoTypes (Map.fromList xs) (checkE e resT)+         pure (srcRange c, Just (nameIdent (thing c)), mkAlt xs e1)++    P.PVar x ->+      do let xty = (thing x, Located (srcRange x) srcT)+         e1 <- withMonoType xty (checkE e resT)+         pure (srcRange x, Nothing, mkAlt [xty] e1)++    P.PLocated p r -> inRange r (checkCaseAlt (P.CaseAlt p e) srcT resT)++    P.PTyped p t ->+      do t1 <- checkType t (Just KType)+         rng <- curRange+         newGoals CtExactType =<<+           unify (WithSource t1 TypeFromUserAnnotation (Just rng)) srcT+         checkCaseAlt (P.CaseAlt p e) t1 resT++    _ -> panic "checkCaseAlt" ["Unexpected pattern"]+  where+  checkNested p ty =+    case p of+      P.PVar x -> pure (thing x, Located (srcRange x) ty)+      P.PLocated p1 r -> inRange r (checkNested p1 ty)+      P.PTyped p1 t ->+        do t1 <- checkType t (Just KType)+           rng <- curRange+           newGoals CtExactType =<<+             unify (WithSource t1 TypeFromUserAnnotation (Just rng)) ty+           checkNested p1 t1+      _ -> panic "checkNested" ["Unexpected pattern"]++++  mkAlt xs = CaseAlt [ (x, thing t) | (x,t) <- xs ]++ checkRecUpd ::   Maybe (P.Expr Name) -> [ P.UpdField Name ] -> TypeWithSource -> InferM Expr checkRecUpd mb fs tGoal =@@ -610,6 +735,22 @@          return res  +-- | Retrieve the constructors from a type that is expected to be unambiguously+-- an enum, throwing an error if this is not the case.+expectEnum :: Type -> InferM [EnumCon]+expectEnum ty =+  case ty of+    TUser _ _ ty' ->+      expectEnum ty'++    TNominal nt _+      |  Enum ecs <- ntDef nt+      -> pure ecs++    _ -> do+      recordError (EnumTypeMismatch ty)+      pure []+ expectFin :: Int -> TypeWithSource -> InferM () expectFin n tGoal@(WithSource ty src rng) =   case ty of@@ -872,9 +1013,9 @@   -- so no need to look at noSig    hasConstraintGuards b =-    case thing (P.bDef b) of-      P.DPropGuards {} -> True-      _                -> False+    case P.bindImpl b of+      Just (P.DPropGuards {}) -> True+      _                       -> False   @@ -895,10 +1036,11 @@      Just s ->       do let wildOk = case thing bDef of-                        P.DForeign {}    -> NoWildCards-                        P.DPrim          -> NoWildCards-                        P.DExpr {}       -> AllowWildCards-                        P.DPropGuards {} -> NoWildCards+                        P.DForeign {}                   -> NoWildCards+                        P.DPrim                         -> NoWildCards+                        P.DImpl i -> case i of+                                       P.DExpr {}       -> AllowWildCards+                                       P.DPropGuards {} -> NoWildCards          s1 <- checkSchema wildOk s          return ((name, ExtVar (fst s1)), Left (checkSigB b s1)) @@ -993,9 +1135,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-                                      DForeign t -> DForeign t+                                      DExpr e       -> DExpr (genE e)+                                      DPrim         -> DPrim+                                      DForeign t me -> DForeign t (genE <$> me)                     , dSignature  = Forall asPs qs                                   $ apSubst su $ sType $ dSignature d                     }@@ -1017,31 +1159,33 @@      P.DPrim -> panic "checkMonoB" ["Primitive with no signature?"] -    P.DForeign -> panic "checkMonoB" ["Foreign 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)-         e1 <- checkFun (P.FunDesc (Just nm) 0) (P.bParams b) e tGoal-         let f = thing (P.bName b)-         return Decl { dName = f-                     , dSignature = Forall [] [] t-                     , dDefinition = DExpr e1-                     , dPragmas = P.bPragmas b-                     , dInfix = P.bInfix b-                     , dFixity = P.bFixity b-                     , dDoc = P.bDoc b-                     }+    P.DImpl i ->+      case i of -    P.DPropGuards _ ->-      tcPanic "checkMonoB"-        [ "Used constraint guards without a signature at "-        , show . pp $ P.bName b ]+        P.DExpr e ->+          do let nm = thing (P.bName b)+             let tGoal = WithSource t (DefinitionOf nm) (getLoc b)+             e1 <- checkFun (P.FunDesc (Just nm) 0) (P.bParams b) e tGoal+             let f = thing (P.bName b)+             return Decl { dName = f+                         , dSignature = Forall [] [] t+                         , dDefinition = DExpr e1+                         , dPragmas = P.bPragmas b+                         , dInfix = P.bInfix b+                         , dFixity = P.bFixity b+                         , 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) =-  let name = thing (P.bName b) in   case thing (P.bDef b) of      -- XXX what should we do with validSchema in this case?@@ -1056,10 +1200,13 @@         , dDoc        = P.bDoc b         } -    P.DForeign -> do+    P.DForeign mi -> do+      (asmps, t, me) <-+        case mi of+          Just i -> fmap Just <$> checkImpl i+          Nothing -> pure (asmps0, t0, Nothing)       let loc = getLoc b-          name' = thing $ P.bName b-          src = DefinitionOf name'+          src = DefinitionOf name       inRangeMb loc do         -- Ensure all type params are of kind #         forM_ as \a ->@@ -1067,10 +1214,10 @@             recordErrorLoc loc $ UnsupportedFFIKind src a $ tpKind a         withTParams as do           ffiFunType <--            case toFFIFunType (Forall as asmps0 t0) of+            case toFFIFunType (Forall as asmps t) of               Right (props, ffiFunType) -> ffiFunType <$ do-                ffiGoals <- traverse (newGoal (CtFFI name')) props-                proveImplication True (Just name') as asmps0 $+                ffiGoals <- traverse (newGoal (CtFFI name)) props+                proveImplication True (Just name) as asmps $                   validSchema ++ ffiGoals               Left err -> do                 recordErrorLoc loc $ UnsupportedFFIType src err@@ -1079,32 +1226,44 @@                   { ffiTParams = as, ffiArgTypes = []                   , ffiRetType = FFITuple [] }           pure Decl { dName       = thing (P.bName b)-                    , dSignature  = Forall as asmps0 t0-                    , dDefinition = DForeign ffiFunType+                    , dSignature  = Forall as asmps t+                    , dDefinition = DForeign ffiFunType me                     , 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-        (t, asmps, e2) <- checkBindDefExpr [] asmps0 e0+    P.DImpl i -> do+      (asmps, t, expr) <- checkImpl i+      return Decl+        { dName       = name+        , dSignature  = Forall as asmps t+        , dDefinition = DExpr expr+        , dPragmas    = P.bPragmas b+        , dInfix      = P.bInfix b+        , dFixity     = P.bFixity b+        , dDoc        = P.bDoc b+        } -        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-          }+  where -    P.DPropGuards cases0 ->+    name = thing (P.bName b)++    checkImpl :: P.BindImpl Name -> InferM ([Prop], Type, Expr)+    checkImpl i =       inRangeMb (getLoc b) $-        withTParams as $ do+      withTParams as $+      case i of++        P.DExpr e0 -> do+          (t, asmps, e2) <- checkBindDefExpr [] asmps0 e0+          pure ( asmps+               , t+               , foldr ETAbs (foldr EProofAbs e2 asmps) as+               )++        P.DPropGuards cases0 -> do           asmps1 <- applySubstPreds asmps0           t1     <- applySubst t0           cases1 <- mapM checkPropGuardCase cases0@@ -1115,25 +1274,14 @@               -- necessarily hold               recordWarning (NonExhaustivePropGuards name) -          let schema = Forall as asmps1 t1--          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-            }---  where+          pure ( asmps1+               , t1+               , foldr ETAbs+                   (foldr EProofAbs+                     (EPropGuards cases1 t1)+                   asmps1)+                 as+               )      checkBindDefExpr ::       [Prop] -> [Prop] -> P.Expr Name -> InferM (Type, [Prop], Expr)@@ -1183,8 +1331,8 @@  @ f : {...} A-f | (B1, B2) => ... -  | (C1, C2, C2) => ... +f | (B1, B2) => ...+  | (C1, C2, C2) => ... @  we check that it is exhaustive by trying to prove the following@@ -1302,11 +1450,15 @@        P.TDNewtype tl ->         do t <- checkNewtype (P.tlValue tl) (thing <$> P.tlDoc tl)-           addNewtype t+           addNominal t +      P.TDEnum tl ->+        do t <- checkEnum (P.tlValue tl) (thing <$> P.tlDoc tl)+           addNominal t+       P.DPrimType tl ->         do t <- checkPrimType (P.tlValue tl) (thing <$> P.tlDoc tl)-           addPrimType t+           addNominal t         P.DInterfaceConstraint _ cs ->@@ -1322,13 +1474,15 @@              do newSubmoduleScope (thing (P.mName m))                                   (thing <$> P.tlDoc tl)                                   (P.exportedDecls ds)+                                  (P.mInScope m)                 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+                _ <- doFunctorInst+                  (P.ImpNested <$> P.mName m) f as inst (P.mInScope m) doc                 pure ()             P.InterfaceModule sig ->
src/Cryptol/TypeCheck/Instantiate.hs view
@@ -11,6 +11,7 @@   , TypeArg(..)   , uncheckedTypeArg   , MaybeCheckedType(..)+  , instantiatePCon   ) where  import Cryptol.ModuleSystem.Name (nameIdent)@@ -60,7 +61,27 @@         where k' = kindOf t     Unchecked t -> checkType t (Just k) -+-- | Instantiate a pattern constructor.  Returns (A,B,C,D) where:+-- A) are the instantiations of the type parameters of the constructor+-- B) is how many proofs we would have if we had dictionaries+-- C) are the types of the fields of the constructor+-- D) is the type of the result of the constructor (i.e., what we are mathcing)+instantiatePCon :: Name -> InferM ([Type],Int,[Type],Type)+instantiatePCon nm =+  do vart <- lookupVar nm+     case vart of+       CurSCC {} -> panic "instantiatePCon" [ "CurSCC"]+       ExtVar s ->+         do (e,t) <- instantiateWith nm (EVar nm) s []+            let (_, tApps, proofApps) = splitExprInst e+                (fs,res) = splitFun t+            pure (tApps, proofApps,fs,res)+  where+  splitFun ty =+    case tIsFun ty of+      Nothing -> ([], ty)+      Just (a,b) -> (a:as,c)+        where (as,c) = splitFun b  instantiateWith :: Name -> Expr -> Schema -> [TypeArg] -> InferM (Expr,Type) instantiateWith nm e s ts
src/Cryptol/TypeCheck/Interface.hs view
@@ -40,9 +40,9 @@ genModDefines m =   Set.unions     [ Map.keysSet  (mTySyns m)-    , Map.keysSet  (mNewtypes m)-    , Set.fromList (map ntConName (Map.elems (mNewtypes m)))-    , Map.keysSet  (mPrimTypes m)+    , Map.keysSet  (mNominalTypes m)+    , Set.fromList (concatMap (map fst . nominalTypeConTypes)+                              (Map.elems (mNominalTypes m)))     , Set.fromList (map dName (concatMap groupDecls (mDecls m)))     , Map.keysSet  (mSubmodules m)     , Map.keysSet  (mFunctors m)@@ -65,8 +65,7 @@    , ifDefines = IfaceDecls     { ifTySyns          = mTySyns m-    , ifNewtypes        = mNewtypes m-    , ifAbstractTypes   = mPrimTypes m+    , ifNominalTypes    = mNominalTypes m     , ifDecls           = Map.fromList [ (qn,mkIfaceDecl d)                                        | dg <- mDecls m                                        , d  <- groupDecls dg
src/Cryptol/TypeCheck/Kind.hs view
@@ -14,6 +14,7 @@   ( checkType   , checkSchema   , checkNewtype+  , checkEnum   , checkPrimType   , checkTySyn   , checkPropSyn@@ -26,12 +27,13 @@ import           Cryptol.Parser.Position import           Cryptol.TypeCheck.AST import           Cryptol.TypeCheck.Error+import           Cryptol.TypeCheck.Subst(listSubst,apSubst) import           Cryptol.TypeCheck.Monad hiding (withTParams) import           Cryptol.TypeCheck.SimpType(tRebuild) import           Cryptol.TypeCheck.SimpleSolver(simplify) import           Cryptol.TypeCheck.Solve (simplifyAllConstraints)-import           Cryptol.TypeCheck.Subst(listSubst,apSubst) import           Cryptol.Utils.Panic (panic)+import           Cryptol.Utils.PP(pp,commaSep) import           Cryptol.Utils.RecordMap  import qualified Data.Map as Map@@ -39,7 +41,7 @@ import           Data.Maybe(fromMaybe) import           Data.Function(on) import           Data.Text (Text)-import           Control.Monad(unless,when,mplus)+import           Control.Monad(unless,mplus,forM,when)  -- | Check a type signature.  Returns validated schema, and any implicit -- constraints that we inferred.@@ -132,37 +134,86 @@                   }  -- | Check a newtype declaration.--- XXX: Do something with constraints.-checkNewtype :: P.Newtype Name -> Maybe Text -> InferM Newtype+checkNewtype :: P.Newtype Name -> Maybe Text -> InferM NominalType checkNewtype (P.Newtype x as con fs) mbD =   do ((as1,fs1),gs) <- collectGoals $        inRange (srcRange x) $-       do r <- withTParams NoWildCards newtypeParam as $+       do r <- withTParams NoWildCards nominalParam as $                flip traverseRecordMap fs $ \_n (rng,f) ->                  kInRange rng $ doCheckType f (Just KType)           simplifyAllConstraints           return r -     return Newtype { ntName   = thing x+     return NominalType+                    { ntName   = thing x+                    , ntKind   = KType                     , ntParams = as1                     , ntConstraints = map goal gs-                    , ntConName = con-                    , ntFields = fs1+                    , ntDef = Struct+                                StructCon { ntConName = con, ntFields = fs1 }+                    , ntFixity = Nothing                     , ntDoc = mbD                     } -checkPrimType :: P.PrimType Name -> Maybe Text -> InferM AbstractType+checkEnum :: P.EnumDecl Name -> Maybe Text -> InferM NominalType+checkEnum ed mbD =+  do let x = P.eName ed+     ((as1,cons1),gs) <- collectGoals $+       inRange (srcRange x) $+       do r <- withTParams NoWildCards nominalParam (P.eParams ed) $+               forM (P.eCons ed `zip` [0..]) \(tlC,nu) ->+                 do let con = P.tlValue tlC+                        cname = P.ecName con+                    ts <- kInRange (srcRange cname)+                            (mapM (`doCheckType` Just KType) (P.ecFields con))+                    pure EnumCon+                          { ecName   = thing cname+                          , ecNumber = nu+                          , ecFields = ts+                          , ecPublic = P.tlExport tlC == P.Public+                          , ecDoc    = thing <$> P.tlDoc tlC+                          }+          simplifyAllConstraints+          pure r+     pure NominalType+                  { ntName = thing x+                  , ntParams = as1+                  , ntKind = KType+                  , ntConstraints = map goal gs+                  , ntDef = Enum cons1+                  , ntFixity = Nothing+                  , ntDoc = mbD+                  }++checkPrimType :: P.PrimType Name -> Maybe Text -> InferM NominalType checkPrimType p mbD =   do let (as,cs) = P.primTCts p-     (as',cs') <- withTParams NoWildCards TPPrimParam as $-                    mapM checkProp cs-     pure AbstractType { atName = thing (P.primTName p)-                       , atKind = cvtK (thing (P.primTKind p))-                       , atFixitiy = P.primTFixity p-                       , atCtrs = (as',cs')-                       , atDoc = mbD-                       }+     (as',cs') <- withTParams NoWildCards TPPrimParam as (mapM checkProp cs)+     let (args,finK) = splitK (cvtK (thing (P.primTKind p)))+         (declared,others) = splitAt (length as') args+     unless (and (zipWith (==) (map kindOf as') args)) $+       panic "checkPrimType"+         [ "Primtive declaration, kind argument prefix mismach:"+         , "Expected: " ++ show (commaSep (map (pp . kindOf) as'))+         , "Actual: " ++ show (commaSep (map pp declared))+         ]+     pure NominalType+            { ntName = thing (P.primTName p)+            , ntParams = as'+            , ntKind = foldr (:->) finK others+            , ntFixity = P.primTFixity p+            , ntConstraints = cs'+            , ntDoc = mbD+            , ntDef = Abstract+            }+  where+  splitK k =+    case k of+      k1 :-> k2 -> (k1:ks,r)+        where (ks,r) = splitK k2+      _ -> ([], k) + checkType :: P.Type Name -> Maybe Kind -> InferM Type checkType t k =   do (_, t1) <- withTParams AllowWildCards schemaParam [] $ doCheckType t k@@ -270,9 +321,8 @@ checkTUser x ts k =   mcase kLookupTyVar      checkBoundVarUse $   mcase kLookupTSyn       checkTySynUse $-  mcase kLookupNewtype    checkNewTypeUse $+  mcase kLookupNominal    checkNominalTypeUse $   mcase kLookupParamType  checkModuleParamUse $-  mcase kLookupAbstractType checkAbstractTypeUse $   checkScopedVarUse -- none of the above, must be a scoped type variable,                     -- if the renamer did its job correctly.   where@@ -286,28 +336,36 @@        t1  <- kInstantiateT (tsDef tysyn) su        checkKind (TUser x ts1 t1) k k1 -  checkNewTypeUse nt =+  checkNominalTypeUse nt+    | Abstract <- ntDef nt =+      do (ts1,k1) <- appTy ts (kindOf nt)+         let as = ntParams nt+             ps = ntConstraints nt+         case as of+           [] -> pure ()+           _ -> do let need = length as+                       have = length ts1+                   when (need > have) $+                     kRecordError (TooFewTyParams (ntName nt) (need - have))+                   let su = listSubst (map tpVar as `zip` ts1)+                   kNewGoals (CtPartialTypeFun (ntName nt)) (apSubst su <$> ps)+         let ty =+               -- We must uphold the invariant that built-in abstract types+               -- are represented with TCon. User-defined abstract types use+               -- TNominal instead.+               case builtInType (ntName nt) of+                 Just tc -> TCon tc ts1+                 Nothing -> TNominal nt ts1+         checkKind ty k k1++    | otherwise =     do (ts1,k1) <- appTy ts (kindOf nt)        let as = ntParams nt        ts2 <- checkParams as ts1        let su = zip as ts2        ps1 <- mapM (`kInstantiateT` su) (ntConstraints nt)        kNewGoals (CtPartialTypeFun (ntName nt)) ps1-       checkKind (TNewtype nt ts2) k k1--  checkAbstractTypeUse absT =-    do let tc   = abstractTypeTC absT-       (ts1,k1) <- appTy ts (kindOf tc)-       let (as,ps) = atCtrs absT-       case ps of-          [] -> pure ()   -- common case-          _ -> do let need = length as-                      have = length ts1-                  when (need > have) $-                     kRecordError (TooFewTyParams (atName absT) (need - have))-                  let su = listSubst (map tpVar as `zip` ts1)-                  kNewGoals (CtPartialTypeFun (atName absT)) (apSubst su <$> ps)-       checkKind (TCon tc ts1) k k1+       checkKind (TNominal nt ts2) k k1    checkParams as ts1     | paramHave == paramNeed = return ts1
src/Cryptol/TypeCheck/Module.hs view
@@ -1,20 +1,24 @@ {-# Language BlockArguments, ImplicitParams #-} module Cryptol.TypeCheck.Module (doFunctorInst) where -import Data.List(partition)+import Data.List(partition,unzip4) import Data.Text(Text) import Data.Map(Map) import qualified Data.Map as Map+import qualified Data.Map.Merge.Strict as Map import Data.Set (Set) import qualified Data.Set as Set-import Control.Monad(unless,forM_)+import Control.Monad(unless,forM_,mapAndUnzipM)   import Cryptol.Utils.Panic(panic)-import Cryptol.Utils.Ident(Ident,Namespace(..),isInfixIdent)+import Cryptol.Utils.Ident(Ident,Namespace(..),ModPath,isInfixIdent) import Cryptol.Parser.Position (Range,Located(..), thing) import qualified Cryptol.Parser.AST as P+import Cryptol.ModuleSystem.Binds(newFunctorInst) import Cryptol.ModuleSystem.Name(nameIdent)+import Cryptol.ModuleSystem.NamingEnv+          (NamingEnv(..), modParamNamingEnv, shadowing, without) import Cryptol.ModuleSystem.Interface           ( IfaceG(..), IfaceDecls(..), IfaceNames(..), IfaceDecl(..)           , filterIfaceDecls@@ -36,16 +40,21 @@   {- ^ Instantitation.  These is the renaming for the functor that arises from        generativity (i.e., it is something that will make the names "fresh").   -} ->+  NamingEnv+  {- ^ Names in the enclosing scope of the instantiated module -} ->   Maybe Text                  {- ^ Documentation -} ->   InferM (Maybe TCTopEntity)-doFunctorInst m f as inst doc =+doFunctorInst m f as instMap0 enclosingInScope 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+     m2 <- do let mpath = P.impNameModPath (thing m)+              as2 <- mapM (checkArg mpath) argIs+              let (tySus,paramTySyns,decls,paramInstMaps) =+                    unzip4 [ (su,ts,ds,im) | DefinedInst su ts ds im <- as2 ]+              instMap <- addMissingTySyns mpath mf instMap0+              let ?tVarSu = mergeDistinctSubst tySus+                  ?nameSu = instMap <> mconcat paramInstMaps               let m1   = moduleInstance mf                   m2   = m1 { mName             = m                             , mDoc              = Nothing@@ -53,6 +62,7 @@                             , mParamFuns        = mempty                             , mParamConstraints = mempty                             , mParams           = mempty+                            , mTySyns = mconcat paramTySyns <> mTySyns m1                             , mDecls = map NonRecursive (concat decls) ++                                       mDecls m1                             }@@ -73,13 +83,27 @@                                  (Map.unions vps)                                  m2 +     -- An instantiation doesn't really have anything "in scope" per se, but+     -- here we compute what would be in scope as if you hand wrote the+     -- instantiation by copy-pasting the functor then substituting the+     -- parameters. That is, it would be whatever is in scope in the functor,+     -- together with any names in the enclosing scope if this is a nested+     -- module, with the functor's names taking precedence. This is used to+     -- determine what is in scope at the REPL when the instantiation is loaded+     -- and focused.+     --+     -- The exception is when instantiating with _, in which case we must delete+     -- the module parameters from the naming environment.+     let inScope0 = mInScope m2 `without`+           mconcat [ modParamNamingEnv mp | (_, mp, AddDeclParams) <- argIs ]+         inScope = inScope0 `shadowing` enclosingInScope+      case thing m of-       P.ImpTop mn    -> newModuleScope mn (mExports m2)-       P.ImpNested mn -> newSubmoduleScope mn doc (mExports m2)+       P.ImpTop mn    -> newModuleScope mn (mExports m2) inScope+       P.ImpNested mn -> newSubmoduleScope mn doc (mExports m2) inScope       mapM_ addTySyn     (Map.elems (mTySyns m2))-     mapM_ addNewtype   (Map.elems (mNewtypes m2))-     mapM_ addPrimType  (Map.elems (mPrimTypes m2))+     mapM_ addNominal   (Map.elems (mNominalTypes m2))      addSignatures      (mSignatures m2)      addSubmodules      (mSubmodules m2)      addFunctors        (mFunctors m2)@@ -100,10 +124,7 @@  {- | 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+be instantiated. -} checkArity ::   Range             {- ^ Location for reporting errors -} ->@@ -159,7 +180,16 @@                checkArgs done ps more  -data ArgInst = DefinedInst Subst [Decl] -- ^ Argument that defines the params+data ArgInst = -- | Argument that defines the params+               DefinedInst Subst+                 (Map Name TySyn)+                 -- ^ Type synonyms created from the functor's type parameters+                 [Decl]+                 -- ^ Bindings for value parameters+                 (Map Name Name)+                 -- ^ Map from the functor's parameter names to the new names+                 --   created for the instantiation+              | ParamInst (Set (MBQual TParam)) [Prop] (Map (MBQual Name) Type)                -- ^ Argument that add parameters                -- The type parameters are in their module type parameter@@ -179,8 +209,8 @@   * XXX: Extra parameters for instantiation by adding params -} checkArg ::-  (Range, ModParam, ActualArg) -> InferM ArgInst-checkArg (r,expect,actual') =+  ModPath -> (Range, ModParam, ActualArg) -> InferM ArgInst+checkArg mpath (r,expect,actual') =   case actual' of     AddDeclParams   -> paramInst     UseParameter {} -> definedInst@@ -197,7 +227,8 @@        pure (ParamInst as cs (Map.mapKeys qual fs))    definedInst =-    do tRens <- mapM (checkParamType r tyMap) (Map.toList (mpnTypes params))+    do (tRens, tSyns, tInstMaps) <- unzip3 <$>+         mapM (checkParamType mpath r tyMap) (Map.toList (mpnTypes params))        let renSu = listParamSubst (concat tRens)         {- Note: the constraints from the signature are already added to the@@ -205,12 +236,13 @@           doFunctorInst -}  -       vDecls <- concat <$>-                  mapM (checkParamValue r vMap)-                       [ s { mvpType = apSubst renSu (mvpType s) }-                       | s <- Map.elems (mpnFuns params) ]+       (vDecls, vInstMaps) <-+         mapAndUnzipM (checkParamValue mpath r vMap)+           [ s { mvpType = apSubst renSu (mvpType s) }+           | s <- Map.elems (mpnFuns params) ] -       pure (DefinedInst renSu vDecls)+       pure $ DefinedInst renSu (mconcat tSyns)+         (concat vDecls) (mconcat tInstMaps <> mconcat vInstMaps)     params = mpParameters expect@@ -231,8 +263,7 @@        UseModule actual ->         ( Map.unions [ nameMapToIdentMap fromTS      (ifTySyns decls)-                     , nameMapToIdentMap fromNewtype (ifNewtypes decls)-                     , nameMapToIdentMap fromPrimT   (ifAbstractTypes decls)+                     , nameMapToIdentMap fromNominal (ifNominalTypes decls)                      ]          , nameMapToIdentMap fromD (ifDecls decls)@@ -247,8 +278,7 @@          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) [])+        fromNominal nt  = (kindOf nt, TNominal nt [])        AddDeclParams -> panic "checkArg" ["AddDeclParams"] @@ -263,51 +293,72 @@  -- | 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) =+  ModPath                    {- ^ The new module we are creating -} ->+  Range                      {- ^ Location for error reporting -} ->+  Map Ident (Kind,Type)      {- ^ Actual types -} ->+  (Name,ModTParam)           {- ^ Type parameter -} ->+  InferM ([(TParam,Type)], Map Name TySyn, Map Name Name)+    {- ^ Mapping from parameter name to actual type (for type substitution),+         type synonym map from a fresh type name to the actual type+           (only so that the type can be referred to in the REPL;+            type synonyms are fully inlined into types at this point),+         and a map from the old type name to the fresh type name+           (for instantiation) -}+checkParamType mpath 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 []+         pure ([], Map.empty, Map.empty)     Just (actualK,actualT) ->       do unless (expectK == actualK)            (recordErrorLoc (Just r)                            (KindMismatch (Just (TVFromModParam name))                                                   expectK actualK))-         pure [(mtpParam mp, actualT)]+         name' <- newFunctorInst mpath name+         let tySyn = TySyn { tsName = name'+                           , tsParams = []+                           , tsConstraints = []+                           , tsDef = actualT+                           , tsDoc = mtpDoc mp }+         pure ( [(mtpParam mp, actualT)]+              , Map.singleton name' tySyn+              , Map.singleton name name'+              )  -- | Check a value parameter to a module. checkParamValue ::+  ModPath                 {- ^ The new module we are creating -} ->   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 =+  InferM ([Decl], Map Name Name)+  {- ^ Decl mapping a new name to the actual value,+       and a map from the value param name in the functor to the new name+         (for instantiation) -}+checkParamValue mpath 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 []+            pure ([], Map.empty)        Just actual ->          do e <- mkParamDef r (name,expectT) actual-            let d = Decl { dName        = name+            name' <- newFunctorInst mpath name+            let d = Decl { dName        = name'                          , dSignature   = expectT                          , dDefinition  = DExpr e                          , dPragmas     = []-                         , dInfix       = isInfixIdent (nameIdent name)+                         , dInfix       = isInfixIdent (nameIdent name')                          , dFixity      = mvpFixity mp                          , dDoc         = mvpDoc mp                          } -            pure [d]+            pure ([d], Map.singleton name name')   @@ -372,5 +423,21 @@      applySubst res  --+-- | The instMap we get from the renamer will not contain the fresh names for+-- certain things in the functor generated in the typechecking stage, if we are+-- instantiating a functor that is in the same file, since renaming and+-- typechecking happens together with the instantiation. In particular, if the+-- functor's interface has type synonyms, they will only get copied over into+-- the functor in the typechecker, so the renamer will not see them. Here we+-- make the fresh names for those missing type synonyms and add them to the+-- instMap.+addMissingTySyns ::+  ModPath                  {- ^ The new module we are creating -} ->+  ModuleG ()               {- ^ The functor -} ->+  Map Name Name            {- ^ instMap we get from renamer -} ->+  InferM (Map Name Name)   {- ^ the complete instMap -}+addMissingTySyns mpath f = Map.mergeA+  (Map.traverseMissing \name _ -> newFunctorInst mpath name)+  Map.preserveMissing+  (Map.zipWithMatched \_ _ name' -> name')+  (mTySyns f)
src/Cryptol/TypeCheck/ModuleBacktickInstance.hs view
@@ -18,15 +18,15 @@ import Data.Maybe(mapMaybe) import qualified Data.Text as Text -import Cryptol.Utils.Ident(ModPath(..), modPathIsOrContains,Namespace(..)+import Cryptol.Utils.Ident(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.AST(impNameModPath) import Cryptol.Parser.Position-import Cryptol.ModuleSystem.Name(-  nameModPath, nameModPathMaybe, nameIdent, mapNameIdent)+import Cryptol.ModuleSystem.Name(nameModPathMaybe, nameIdent, mapNameIdent) import Cryptol.TypeCheck.AST import Cryptol.TypeCheck.Error import qualified Cryptol.TypeCheck.Monad as TC@@ -56,7 +56,7 @@          , tparams = Set.toList as          , constraints = ps          , vparams = mp-         , newNewtypes = Map.empty+         , newNominalTypes = Map.empty          }      do unless (null bad)@@ -64,12 +64,12 @@         rec          ts <- doAddParams nt mTySyns-         nt <- doAddParams nt mNewtypes+         nt <- doAddParams nt mNominalTypes          ds <- doAddParams nt mDecls         pure m          { mTySyns   = ts-         , mNewtypes = nt+         , mNominalTypes = nt          , mDecls    = ds          } @@ -78,14 +78,14 @@        ++ mkBad mPrimTypes BIAbstractType        ++ mkBad mSignatures BIInterface +    mPrimTypes = Map.filter nominalTypeIsAbstract . mNominalTypes+     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)+    ourPath = impNameModPath (thing (mName m))      doAddParams nt sel =-      mapReader (\ro -> ro { newNewtypes = nt }) (addParams (sel m))+      mapReader (\ro -> ro { newNominalTypes = nt }) (addParams (sel m))   type RewM = ReaderT RO TC.InferM@@ -98,7 +98,7 @@   , tparams      :: [MBQual TParam]   , constraints  :: [Prop]   , vparams      :: Map (MBQual Name) Type-  , newNewtypes  :: Map Name Newtype+  , newNominalTypes :: Map Name NominalType   }  @@ -111,17 +111,28 @@ instance AddParams a => AddParams [a] where   addParams = mapM addParams -instance AddParams Newtype where+instance AddParams NominalType where   addParams nt =-    do (tps,cs) <- newTypeParams TPNewtypeParam+    do (tps,cs) <- newTypeParams TPNominalParam        rProps   <- rewTypeM tps (ntConstraints nt)-       rFields  <- rewTypeM tps (ntFields nt)+       def <- case ntDef nt of+                Struct con ->+                   Struct <$>+                   do rFields  <- rewTypeM tps (ntFields con)+                      pure con { ntFields = rFields }+                Enum cons ->+                  Enum <$>+                  forM cons \c ->+                    do rFileds <- rewTypeM tps (ecFields c)+                       pure c { ecFields = rFileds }+                Abstract -> pure Abstract        pure nt-         { ntParams       = pDecl tps ++ ntParams nt-         , ntConstraints  = cs ++ rProps-         , ntFields       = rFields+         { ntParams      = pDecl tps ++ ntParams nt+         , ntConstraints = cs ++ rProps+         , ntDef         = def          } + instance AddParams TySyn where   addParams ts =     do (tps,cs) <- newTypeParams TPTySynParam@@ -251,12 +262,12 @@                  )  liftRew ::-  ((?isOurs :: Name -> Bool, ?newNewtypes :: Map Name Newtype) => a) ->+  ((?isOurs :: Name -> Bool, ?newNominalTypes :: Map Name NominalType) => a) ->   RewM a liftRew x =   do ro <- ask      let ?isOurs      = isOurs ro-         ?newNewtypes = newNewtypes ro+         ?newNominalTypes = newNominalTypes ro      pure x  rewTypeM :: RewType t => TypeParams -> t -> RewM t@@ -274,7 +285,7 @@ class RewType t where   rewType ::     ( ?isOurs      :: Name -> Bool-    , ?newNewtypes :: Map Name Newtype    -- Lazy+    , ?newNominalTypes :: Map Name NominalType -- Lazy     , ?tparams     :: TypeParams     ) => t -> t @@ -282,10 +293,7 @@   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)+      TCon tc ts -> TCon tc (rewType ts)        TVar x ->         case x of@@ -301,12 +309,12 @@        TRec fs -> TRec (rewType fs) -      TNewtype tdef ts-        | ?isOurs nm -> TNewtype tdef' (pUse ?tparams ++ rewType ts)-        | otherwise  -> TNewtype tdef (rewType ts)+      TNominal tdef ts+        | ?isOurs nm -> TNominal tdef' (pUse ?tparams ++ rewType ts)+        | otherwise  -> TNominal tdef (rewType ts)         where         nm    = ntName tdef-        tdef' = case Map.lookup nm ?newNewtypes of+        tdef' = case Map.lookup nm ?newNominalTypes of                   Just yes -> yes                   Nothing  -> panic "rewType" [ "Missing recursive newtype"                                               , show (pp nm) ]@@ -328,7 +336,7 @@ class RewVal t where   rew ::     ( ?isOurs      :: Name -> Bool-    , ?newNewtypes :: Map Name Newtype    -- Lazy+    , ?newNominalTypes :: Map Name NominalType -- Lazy     , ?tparams     :: TypeParams     , ?cparams     :: Int                 -- Number of constraitns     , ?vparams     :: ValParams@@ -352,6 +360,7 @@       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)+      ECase e as d      -> ECase (rew e) (rew <$> as) (rew <$> d)       EComp t1 t2 e mss -> EComp (rewType t1) (rewType t2) (rew e) (rew mss)       EVar x            -> tryVarApp                            case Map.lookup x (pSubst ?vparams) of@@ -379,6 +388,9 @@                evs = foldl EApp eps (pUse ?vparams)            in evs         _ -> orElse++instance RewVal CaseAlt where+  rew (CaseAlt xs e) = CaseAlt xs (rew e)   instance RewVal DeclGroup where
src/Cryptol/TypeCheck/ModuleInstance.hs view
@@ -8,26 +8,29 @@  import Cryptol.Parser.Position(Located) import Cryptol.ModuleSystem.Interface(IfaceNames(..))+import Cryptol.ModuleSystem.NamingEnv(NamingEnv,mapNamingEnv) 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)+{- | `?tVarSu` substitutes 'Type's for 'TVar's which are module type parameters.+     `?nameSu` substitutes fresh 'Name's for the functor's 'Name's+       (in all namespaces). -}+type Su = (?tVarSu :: Subst, ?nameSu :: Map Name Name) --- | Has value names but no types.-doVInst :: (Su, TraverseNames a) => a -> a-doVInst = mapNames (\x -> Map.findWithDefault x x ?vSu)+-- | Instantiate something that has 'Name's.+doNameInst :: (Su, TraverseNames a) => a -> a+doNameInst = mapNames (\x -> Map.findWithDefault x x ?nameSu) --- | Has types but not values.-doTInst :: (Su, TVars a) => a -> a-doTInst = apSubst ?tSu+-- | Instantiate something that has 'TVar's.+doTVarInst :: (Su, TVars a) => a -> a+doTVarInst = apSubst ?tVarSu --- | Has both value names and types.-doTVInst :: (Su, TVars a, TraverseNames a) => a -> a-doTVInst = apSubst ?tSu . doVInst+-- | Instantiate something that has both 'TVar's and 'Name's.+-- Order is important here because '?tVarSu' might insert 'Name's.+doInst :: (Su, TVars a, TraverseNames a) => a -> a+doInst = doNameInst . doTVarInst  doMap :: (Su, ModuleInstance a) => Map Name a -> Map Name a doMap mp =@@ -49,8 +52,11 @@   moduleInstance l = moduleInstance <$> l  instance ModuleInstance Name where-  moduleInstance = doVInst+  moduleInstance = doNameInst +instance ModuleInstance NamingEnv where+  moduleInstance = mapNamingEnv doNameInst+ instance ModuleInstance name => ModuleInstance (ImpName name) where   moduleInstance x =     case x of@@ -61,7 +67,7 @@   moduleInstance m =     Module { mName             = mName m            , mDoc              = Nothing-           , mExports          = doVInst (mExports m)+           , mExports          = doNameInst (mExports m)            , mParamTypes       = doMap (mParamTypes m)            , mParamFuns        = doMap (mParamFuns m)            , mParamConstraints = moduleInstance (mParamConstraints m)@@ -69,18 +75,18 @@            , mFunctors         = doMap (mFunctors m)            , mNested           = doSet (mNested m)            , mTySyns           = doMap (mTySyns m)-           , mNewtypes         = doMap (mNewtypes m)-           , mPrimTypes        = doMap (mPrimTypes m)+           , mNominalTypes     = doMap (mNominalTypes m)            , mDecls            = moduleInstance (mDecls m)            , mSubmodules       = doMap (mSubmodules m)            , mSignatures       = doMap (mSignatures m)+           , mInScope          = moduleInstance (mInScope m)            }  instance ModuleInstance Type where-  moduleInstance = doTInst+  moduleInstance = doInst  instance ModuleInstance Schema where-  moduleInstance = doTInst+  moduleInstance = doInst  instance ModuleInstance TySyn where   moduleInstance ts =@@ -91,26 +97,42 @@           , tsDoc         = tsDoc ts           } -instance ModuleInstance Newtype where+instance ModuleInstance NominalType where   moduleInstance nt =-    Newtype { ntName        = moduleInstance (ntName nt)+    NominalType+            { ntName        = moduleInstance (ntName nt)             , ntParams      = ntParams nt+            , ntKind        = ntKind nt             , ntConstraints = moduleInstance (ntConstraints nt)-            , ntConName     = moduleInstance (ntConName nt)-            , ntFields      = moduleInstance <$> ntFields nt+            , ntDef         = moduleInstance (ntDef nt)+            , ntFixity      = ntFixity 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 NominalTypeDef where+  moduleInstance def =+    case def of+      Struct c -> Struct (moduleInstance c)+      Enum cs  -> Enum   (moduleInstance cs)+      Abstract -> Abstract +instance ModuleInstance StructCon where+  moduleInstance c =+    StructCon+      { ntConName     = moduleInstance (ntConName c)+      , ntFields      = moduleInstance <$> ntFields c+      }++instance ModuleInstance EnumCon where+  moduleInstance c =+    EnumCon+      { ecName        = moduleInstance (ecName c)+      , ecNumber      = ecNumber c+      , ecFields      = moduleInstance (ecFields c)+      , ecPublic      = ecPublic c+      , ecDoc         = ecDoc c+      }+ instance ModuleInstance DeclGroup where   moduleInstance dg =     case dg of@@ -118,7 +140,7 @@       NonRecursive d -> NonRecursive (moduleInstance d)  instance ModuleInstance Decl where-  moduleInstance = doTVInst+  moduleInstance = doInst   instance ModuleInstance name => ModuleInstance (IfaceNames name) where
src/Cryptol/TypeCheck/Monad.hs view
@@ -40,6 +40,7 @@ import           Cryptol.ModuleSystem.Name                     (FreshM(..),Supply,mkLocal,asLocal                     , nameInfo, NameInfo(..),NameSource(..), nameTopModule)+import           Cryptol.ModuleSystem.NamingEnv.Types import qualified Cryptol.ModuleSystem.Interface as If import           Cryptol.Parser.Position import qualified Cryptol.Parser.AST as P@@ -64,8 +65,7 @@   { inpRange     :: Range             -- ^ Location of program source   , 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+  , inpNominalTypes :: Map Name NominalType -- ^ Nominal types in scope   , inpSignatures :: !(Map Name ModParamNames)  -- ^ Signatures in scope    , inpTopModules    :: ModName -> Maybe (ModuleG (), If.IfaceG ())@@ -129,8 +129,9 @@       let env = Map.map ExtVar (inpVars info)             <> Map.fromList-              [ (ntConName nt, ExtVar (newtypeConType nt))-              | nt <- Map.elems (inpNewtypes info)+              [ (c, ExtVar t)+              | nt <- Map.elems (inpNominalTypes info)+              , (c,t) <- nominalTypeConTypes nt               ]             <> Map.map (ExtVar . mvpType) (mpnFuns allPs) @@ -141,8 +142,7 @@                          , iExtScope = (emptyModule ExternalScope)                              { mTySyns           = inpTSyns info <>                                                    mpnTySyn allPs-                             , mNewtypes         = inpNewtypes info-                             , mPrimTypes        = inpAbstractTypes info+                             , mNominalTypes     = inpNominalTypes info                              , mParamTypes       = mpnTypes allPs                              , mParamFuns        = mpnFuns  allPs                              , mParamConstraints = mpnConstraints allPs@@ -611,7 +611,7 @@       TPPropSynParam _ -> starOrHashOrProp       TPTySynParam _   -> starOrHash       TPSchemaParam _  -> starOrHash-      TPNewtypeParam _ -> starOrHash+      TPNominalParam _ -> starOrHash       TPPrimParam _    -> starOrHash       TPUnifyVar       -> starOrHash @@ -629,7 +629,6 @@         KType -> return ()         _ -> recordError (BadParameterKind tp k) - -- | Generate a new free type variable. newTParam :: P.TParam Name -> TPFlavor -> Kind -> InferM TParam newTParam nm flav k =@@ -788,12 +787,9 @@ lookupTSyn :: Name -> InferM (Maybe TySyn) lookupTSyn x = Map.lookup x <$> getTSyns --- | Lookup the definition of a newtype-lookupNewtype :: Name -> InferM (Maybe Newtype)-lookupNewtype x = Map.lookup x <$> getNewtypes--lookupAbstractType :: Name -> InferM (Maybe AbstractType)-lookupAbstractType x = Map.lookup x <$> getAbstractTypes+-- | Lookup the definition of a nominal type+lookupNominal :: Name -> InferM (Maybe NominalType)+lookupNominal x = Map.lookup x <$> getNominalTypes  -- | Lookup the kind of a parameter type lookupParamType :: Name -> InferM (Maybe ModTParam)@@ -907,13 +903,9 @@ getTSyns :: InferM (Map Name TySyn) getTSyns = getScope mTySyns --- | Returns the newtype declarations that are in scope.-getNewtypes :: InferM (Map Name Newtype)-getNewtypes = getScope mNewtypes---- | Returns the abstract type declarations that are in scope.-getAbstractTypes :: InferM (Map Name AbstractType)-getAbstractTypes = getScope mPrimTypes+-- | Returns the nominal type declarations that are in scope.+getNominalTypes :: InferM (Map Name NominalType)+getNominalTypes = getScope mNominalTypes  -- | Returns the abstract function declarations getParamTypes :: InferM (Map Name ModTParam)@@ -1006,16 +998,16 @@ 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 =+  Name -> Maybe Text -> ExportSpec Name -> NamingEnv -> InferM ()+newSubmoduleScope x docs e inScope =   do updScope \o -> o { mNested = Set.insert x (mNested o) }      newScope (SubModule x)-     updScope \m -> m { mDoc = docs, mExports = e }+     updScope \m -> m { mDoc = docs, mExports = e, mInScope = inScope } -newModuleScope :: P.ModName -> ExportSpec Name -> InferM ()-newModuleScope x e =+newModuleScope :: P.ModName -> ExportSpec Name -> NamingEnv -> InferM ()+newModuleScope x e inScope =   do newScope (MTopModule x)-     updScope \m -> m { mDoc = Nothing, mExports = e }+     updScope \m -> m { mDoc = Nothing, mExports = e, mInScope = inScope }  -- | Update the current scope (first in the list). Assumes there is one. updScope :: (ModuleG ScopeName -> ModuleG ScopeName) -> InferM ()@@ -1057,10 +1049,10 @@                  , mParamConstraints = mParamConstraints y                  , mParams           = mParams y                  , mNested           = mNested y+                 , mInScope          = mInScope y                   , mTySyns      = add mTySyns-                 , mNewtypes    = add mNewtypes-                 , mPrimTypes   = add mPrimTypes+                 , mNominalTypes = add mNominalTypes                  , mDecls       = add mDecls                  , mSignatures  = add mSignatures                  , mSubmodules  = if isFun@@ -1149,12 +1141,13 @@       , mNested           = mempty        , mTySyns           = uni mTySyns-      , mNewtypes         = uni mNewtypes-      , mPrimTypes        = uni mPrimTypes+      , mNominalTypes     = uni mNominalTypes       , mDecls            = uni mDecls       , mSubmodules       = uni mSubmodules       , mFunctors         = uni mFunctors       , mSignatures       = uni mSignatures++      , mInScope          = uni mInScope       }     where     uni f = f m1 <> f m2@@ -1175,18 +1168,12 @@      checkTShadowing "synonym" x      updScope \r -> r { mTySyns = Map.insert x t (mTySyns r) } -addNewtype :: Newtype -> InferM ()-addNewtype t =-  do updScope \r -> r { mNewtypes = Map.insert (ntName t) t (mNewtypes r) }-     IM $ sets_ \rw -> rw { iBindTypes = Map.insert (ntConName t)-                                                    (newtypeConType t)-                                                    (iBindTypes rw) }--addPrimType :: AbstractType -> InferM ()-addPrimType t =-  updScope \r ->-    r { mPrimTypes = Map.insert (atName t) t (mPrimTypes r) }-+addNominal :: NominalType -> InferM ()+addNominal t =+  do updScope \r -> r { mNominalTypes = Map.insert (ntName t) t (mNominalTypes r) }+     let cons = nominalTypeConTypes t+         ins  = uncurry Map.insert+     IM $ sets_ \rw -> rw { iBindTypes = foldr ins (iBindTypes rw) cons }  addParamType :: ModTParam -> InferM () addParamType a =@@ -1354,15 +1341,12 @@ kLookupTSyn :: Name -> KindM (Maybe TySyn) kLookupTSyn x = kInInferM $ lookupTSyn x --- | Lookup the definition of a newtype.-kLookupNewtype :: Name -> KindM (Maybe Newtype)-kLookupNewtype x = kInInferM $ lookupNewtype x+-- | Lookup the definition of a nominal type.+kLookupNominal :: Name -> KindM (Maybe NominalType)+kLookupNominal = kInInferM . lookupNominal  kLookupParamType :: Name -> KindM (Maybe ModTParam) kLookupParamType x = kInInferM (lookupParamType x)--kLookupAbstractType :: Name -> KindM (Maybe AbstractType)-kLookupAbstractType x = kInInferM $ lookupAbstractType x  kExistTVar :: Name -> Kind -> KindM Type kExistTVar x k = kInInferM $ existVar x k
src/Cryptol/TypeCheck/Parseable.hs view
@@ -18,6 +18,7 @@   ) where  import Data.Void+import qualified Data.Map as Map import Prettyprinter  import Cryptol.TypeCheck.AST@@ -52,6 +53,9 @@                                 showParseable e <+> showParseable s                                                 <+> showParseable v)   showParseable (EIf c t f) = parens (text "EIf" <+> showParseable c $$ showParseable t $$ showParseable f)+  showParseable (ECase e as d) =+    parens (text "ECase" <+> showParseable e $$ showParseable (Map.toList as)+                                             $$ showParseable d)   showParseable (EComp _ _ e mss) = parens (text "EComp" $$ showParseable e $$ showParseable mss)   showParseable (EVar n) = parens (text "EVar" <+> showParseable n)   showParseable (EApp fe ae) = parens (text "EApp" $$ showParseable fe $$ showParseable ae)@@ -89,13 +93,20 @@   showParseable (From n _ _ e) = parens (text "From" <+> showParseable n <+> showParseable e)   showParseable (Let d) = parens (text "MLet" <+> showParseable d) ++instance ShowParseable CaseAlt where+  showParseable (CaseAlt xs e) =+    parens (text "CaseAlt" <+> showParseable xs <+> showParseable e)++ instance ShowParseable Decl where   showParseable d = parens (text "Decl" <+> showParseable (dName d)                               $$ showParseable (dDefinition d))  instance ShowParseable DeclDef where   showParseable DPrim = text (show DPrim)-  showParseable (DForeign t) = text (show $ DForeign t)+  showParseable (DForeign t me) =+    parens (text "DForeign" $$ parens (text (show t)) $$ showParseable me)   showParseable (DExpr e) = parens (text "DExpr" $$ showParseable e)  instance ShowParseable DeclGroup where
src/Cryptol/TypeCheck/Sanity.hs view
@@ -18,24 +18,24 @@   ) where  -import Cryptol.Parser.Position(thing,Range,emptyRange)-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.Maybe(maybeToList) import Data.List (sort) import qualified Data.Set as Set import MonadLib import qualified Control.Applicative as A- import           Data.Map ( Map ) import qualified Data.Map as Map +import Cryptol.Parser.Position(thing,Range,emptyRange)+import Cryptol.TypeCheck.AST+import Cryptol.TypeCheck.Subst (apSubst, singleTParamSubst, mergeDistinctSubst)+import Cryptol.TypeCheck.Monad(InferInput(..))+import Cryptol.ModuleSystem.Name(nameLoc,nameIdent)+import Cryptol.Utils.Ident+import Cryptol.Utils.RecordMap+import Cryptol.Utils.PP + tcExpr :: InferInput -> Expr -> Either (Range, Error) (Schema, [ ProofObligation ]) tcExpr env e = runTcM env (exprSchema e) @@ -51,6 +51,8 @@   where check = foldr withTVar k1 (map mtpParam (Map.elems (mParamTypes m)))         k1    = foldr withAsmp k2 (map thing (mParamConstraints m))         k2    = withVars (Map.toList (fmap mvpType (mParamFuns m)))+              $ withVars (concatMap nominalTypeConTypes+                                                (Map.elems (mNominalTypes m)))               $ checkDecls (mDecls m)  onlyNonTrivial :: [ProofObligation] -> [ProofObligation]@@ -87,7 +89,7 @@       do ks <- mapM checkType ts          checkKind (kindOf tc) ks -    TNewtype nt ts ->+    TNominal nt ts ->       do ks <- mapM checkType ts          checkKind (kindOf nt) ks @@ -151,8 +153,6 @@     SameIf ps -> mapM_ proofObligation ps  -- class Same a where   same :: a -> a -> AreSame @@ -174,7 +174,7 @@       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)+        (TNominal x xs, TNominal y ys) -> same (Field x xs) (Field y ys)         (TCon x xs, TCon y ys)         -> same (Field x xs) (Field y ys)         _                              -> NotSame       where@@ -249,6 +249,39 @@           return $ tMono t1 +    ECase e as d ->+      do ty <- exprType e+         case tNoUser ty of+           TNominal nt targs+             | Enum cons <- ntDef nt ->+              do alts <- traverse checkCaseAlt as+                 dflt <- traverse checkCaseAlt d+                 let resTypes = map snd (maybeToList dflt ++ Map.elems alts)+                 resT <- case resTypes of+                           []     -> reportError (BadCase Nothing)+                           t : ts ->+                             do mapM_ (sameTypes "ECase_alt_result" t) ts+                                pure t++                 let su = mergeDistinctSubst+                            (zipWith singleTParamSubst (ntParams nt) targs)+                     conMap = Map.fromList [ (nameIdent (ecName c)+                                           , apSubst su <$> ecFields c)+                                           | c <- cons ]+                     checkCon (c,(ts,_)) =+                       case Map.lookup c conMap of+                         Just ts1 | length ts == length ts1 ->+                                zipWithM_ (sameTypes "ECase_alt_field") ts ts1+                         _ -> reportError (BadCaseAlt (Just c))+                 mapM_ checkCon (Map.toList alts)+                 case dflt of+                   Nothing -> pure ()+                   Just ([t],_) -> sameTypes "ECase_default_arg" t ty+                   _ -> reportError (BadCaseAlt Nothing)+                 pure (tMono resT)++           _ -> reportError (BadCase (Just ty))+     EComp len t e mss ->       do checkTypeIs KNum len          checkTypeIs KType t@@ -334,6 +367,14 @@     EPropGuards _guards typ ->        pure Forall {sVars = [], sProps = [], sType = typ} ++checkCaseAlt :: CaseAlt -> TcM ([Type], Type)+checkCaseAlt (CaseAlt xs e) =+  do ty <- foldr addVar (exprType e) xs+     pure (map snd xs, ty)+  where+  addVar (x,t) = withVar x t+ checkHas :: Type -> Selector -> TcM Type checkHas t sel =   case sel of@@ -437,9 +478,9 @@                                | tc1 == tc2 -> goMany ts1 ts2                             _ -> err -         TNewtype nt1 ts1 ->+         TNominal nt1 ts1 ->             case other of-              TNewtype nt2 ts2+              TNominal nt2 ts2                 | nt1 == nt2 -> goMany ts1 ts2               _ -> err @@ -462,21 +503,26 @@       do when checkSig $ checkSchema $ dSignature d          return (dName d, dSignature d) -    DForeign _ ->+    DForeign _ me ->       do when checkSig $ checkSchema $ dSignature d+         mapM_ checkExpr me          return (dName d, dSignature d)      DExpr e ->       do let s = dSignature d          when checkSig $ checkSchema s-         s1 <- exprSchema e-         let nm = dName d-             loc = "definition of " ++ show (pp nm) ++-                            ", at " ++ show (pp (nameLoc nm))-         sameSchemas loc s s1-+         checkExpr e          return (dName d, s) +  where+  checkExpr e =+    do let s = dSignature d+       s1 <- exprSchema e+       let nm = dName d+           loc = "definition of " ++ show (pp nm) +++                          ", at " ++ show (pp (nameLoc nm))+       sameSchemas loc s s1+ checkDeclGroup :: DeclGroup -> TcM [(Name, Schema)] checkDeclGroup dg =   case dg of@@ -567,9 +613,16 @@                                       , let x = mtpParam tp ]           , roAsmps = map thing (mpnConstraints allPs)           , roRange = emptyRange-          , roVars  = Map.union-                        (fmap mvpType (mpnFuns allPs))-                        (inpVars env)+          , roVars  = Map.unions+                        [ fmap mvpType (mpnFuns allPs)+                        , inpVars env+                        , Map.fromList+                            [ c+                            | nt <- Map.elems (inpNominalTypes env)+                            , c  <- nominalTypeConTypes nt+                            ]+                        ]+           }   rw = RW { woProofObligations = [] } @@ -597,6 +650,8 @@   | EmptyArm   | UndefinedTypeVaraible TVar   | UndefinedVariable Name+  | BadCase (Maybe Type)+  | BadCaseAlt (Maybe Ident)     deriving Show  reportError :: Error -> TcM a@@ -762,6 +817,19 @@       UndefinedVariable x ->         ppErr "Undefined variable"           [ "Variable:" <+> pp x ]++      BadCase mbt ->+        ppErr "Malformed cased expression" $+        case mbt of+          Just t  -> [ "Expected: `enum` type", "Actual:" <+> pp t ]+          Nothing -> [ "Empty alternatives" ]++      BadCaseAlt mbCon ->+        ppErr "Malformed case alternative" $+        [ case mbCon of+            Just c  -> "Alternative for constructor" <+> pp c+            Nothing -> "Default alternative"+        ]      where     ppErr x ys = hang x 2 (vcat [ "•" <+> y | y <- ys ])
src/Cryptol/TypeCheck/SimpType.hs view
@@ -18,12 +18,12 @@   go ty =     case ty of       TUser x xs t-        | withUser  -> TUser x xs (go t)-        | otherwise -> go t-      TVar _        -> ty-      TRec xs       -> TRec (fmap go xs)-      TNewtype nt xs -> TNewtype nt (map go xs)-      TCon tc ts    -> tCon tc (map go ts)+        | withUser    -> TUser x xs (go t)+        | otherwise   -> go t+      TVar _          -> ty+      TRec xs         -> TRec (fmap go xs)+      TNominal nt xs  -> TNominal nt (map go xs)+      TCon tc ts      -> tCon tc (map go ts)  tRebuild :: Type -> Type tRebuild = tRebuild' True
src/Cryptol/TypeCheck/Solver/Class.hs view
@@ -101,8 +101,8 @@   -- (Zero a, Zero b) => Zero { x1 : a, x2 : b }   TRec fs -> SolvedIf [ pZero ety | ety <- recordElements fs ] -  -- Zero <newtype> -> fails-  TNewtype{} -> Unsolvable+  -- Zero <nominal> -> fails+  TNominal {} -> Unsolvable    _ -> Unsolved @@ -140,8 +140,8 @@   -- (Logic a, Logic b) => Logic { x1 : a, x2 : b }   TRec fs -> SolvedIf [ pLogic ety | ety <- recordElements fs ] -  -- Logic <newtype> -> fails-  TNewtype{} -> Unsolvable+  -- Logic <nominal> -> fails+  TNominal {} -> Unsolvable    _ -> Unsolved @@ -180,8 +180,8 @@   -- (Ring a, Ring b) => Ring { x1 : a, x2 : b }   TRec fs -> SolvedIf [ pRing ety | ety <- recordElements fs ] -  -- Ring <newtype> -> fails-  TNewtype{} -> Unsolvable+  -- Ring <nominal> -> fails+  TNominal {} -> Unsolvable    _ -> Unsolved @@ -267,8 +267,8 @@   -- Field {x : a, y : b, ...} fails   TRec _ -> Unsolvable -  -- Field <newtype> -> fails-  TNewtype{} -> Unsolvable+  -- Field <nominal> -> fails+  TNominal {} -> Unsolvable    _ -> Unsolved @@ -309,8 +309,8 @@   -- Round {x : a, y : b, ...} fails   TRec _ -> Unsolvable -  -- Round <newtype> -> fails-  TNewtype{} -> Unsolvable+  -- Round <nominal> -> fails+  TNominal {} -> Unsolvable    _ -> Unsolved @@ -350,8 +350,8 @@   -- (Eq a, Eq b) => Eq { x:a, y:b }   TRec fs -> SolvedIf [ pEq e | e <- recordElements fs ] -  -- Eq <newtype> -> fails-  TNewtype{} -> Unsolvable+  -- Eq <nominal> -> fails+  TNominal {} -> Unsolvable    _ -> Unsolved @@ -390,8 +390,8 @@   -- (Cmp a, Cmp b) => Cmp { x:a, y:b }   TRec fs -> SolvedIf [ pCmp e | e <- recordElements fs ] -  -- Cmp <newtype> -> fails-  TNewtype{} -> Unsolvable+  -- Cmp <nominal> -> fails+  TNominal{} -> Unsolvable    _ -> Unsolved @@ -445,8 +445,8 @@   -- (SignedCmp a, SignedCmp b) => SignedCmp { x:a, y:b }   TRec fs -> SolvedIf [ pSignedCmp e | e <- recordElements fs ] -  -- SignedCmp <newtype> -> fails-  TNewtype{} -> Unsolvable+  -- SignedCmp <nominal> -> fails+  TNominal{} -> Unsolvable    _ -> Unsolved 
src/Cryptol/TypeCheck/Solver/SMT.hs view
@@ -5,7 +5,7 @@ -- Maintainer  :  cryptol@galois.com -- Stability   :  provisional -- Portability :  portable-{-# LANGUAGE Safe #-}+{-# LANGUAGE Trustworthy #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE FlexibleContexts #-} {-# Language FlexibleInstances #-}
src/Cryptol/TypeCheck/Solver/Selector.hs view
@@ -68,14 +68,18 @@     (RecordSel l _, ty) ->       case ty of         TRec fs -> return (lookupField l fs)-        TNewtype nt ts ->-          case lookupField l (ntFields nt) of-            Nothing -> return Nothing-            Just t ->-              do let su = listParamSubst (zip (ntParams nt) ts)-                 newGoals (CtPartialTypeFun (ntName nt))-                   $ apSubst su $ ntConstraints nt-                 return $ Just $ apSubst su t+        TNominal nt ts ->+          case ntDef nt of+            Struct c ->+              case lookupField l (ntFields c) of+                Nothing -> return Nothing+                Just t ->+                  do let su = listParamSubst (zip (ntParams nt) ts)+                     newGoals (CtPartialTypeFun (ntName nt))+                       $ apSubst su $ ntConstraints nt+                     return $ Just $ apSubst su t+            Enum {} -> pure Nothing+            Abstract -> pure Nothing          TCon (TC TCSeq) [len,el] -> liftSeq len el         TCon (TC TCFun) [t1,t2]  -> liftFun t1 t2
src/Cryptol/TypeCheck/Solver/Utils.hs view
@@ -22,7 +22,7 @@   go ty = case ty of             TVar x      -> return (x, tNum (0::Int))             TRec {}     -> []-            TNewtype{}  -> []+            TNominal {}  -> []             TUser _ _ t -> go t             TCon (TF TCAdd) [t1,t2] ->               do (a,yes) <- go t1@@ -46,7 +46,7 @@   case ty of     TVar {}     -> Nothing     TRec {}     -> Nothing-    TNewtype{}  -> Nothing+    TNominal {} -> Nothing     TUser _ _ t -> splitConstSummand t     TCon (TF TCAdd) [t1,t2] ->       do (k,t1') <- splitConstSummand t1@@ -65,7 +65,7 @@   case ty of     TVar {}     -> Nothing     TRec {}     -> Nothing-    TNewtype{}  -> Nothing+    TNominal {} -> Nothing     TUser _ _ t -> splitConstFactor t     TCon (TF TCMul) [t1,t2] ->       do (k,t1') <- splitConstFactor t1
src/Cryptol/TypeCheck/Subst.hs view
@@ -263,11 +263,11 @@      TRec fs -> TRec `fmap` (anyJust (apSubstMaybe su) fs) -    {- We apply the substitution to the newtype as well, because it might+    {- We apply the substitution to nominal types 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)+    TNominal nt ts ->+      uncurry TNominal <$> anyJust2 (applySubstToNominalType su)                                     (anyJust (apSubstMaybe su))                                     (nt,ts) @@ -293,15 +293,26 @@       | 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 }+applySubstToNominalType :: Subst -> NominalType -> Maybe NominalType+applySubstToNominalType su nt =+ do (cs,def)  <- anyJust2 (anyJust (apSubstMaybe su)) apSubstDef+                          (ntConstraints nt, ntDef nt)+    pure nt { ntConstraints = cs, ntDef = def }+  where+  apSubstDef d =+    case d of+      Struct c ->+        do fs <- anyJust (apSubstMaybe su) (ntFields c)+           pure (Struct c { ntFields = fs })+      Enum cs -> Enum <$> anyJust apSubstCon cs+      Abstract -> pure Abstract +  apSubstCon c =+    do fs <- anyJust (apSubstMaybe su) (ecFields c)+       pure c { ecFields = fs } ++ class TVars t where   apSubst :: Subst -> t -> t   -- ^ Replaces free variables. To prevent space leaks when used with@@ -355,7 +366,7 @@     tm' = TM { tvar = Map.fromList   vars              , tcon = fmap (lgo merge atNode) tcon              , trec = fmap (lgo merge atNode) trec-             , tnewtype = fmap (lgo merge atNode) tnewtype+             , tnominal = fmap (lgo merge atNode) tnominal              }      -- partition out variables that have been replaced with more specific types@@ -377,7 +388,7 @@  instance TVars a => TVars (Map.Map k a) where   -- NB, strict map-  apSubst su m = Map.map (apSubst su) m+  apSubst su = Map.map (apSubst su)  instance TVars TySyn where   apSubst su (TySyn nm params props t doc) =@@ -432,11 +443,20 @@         ESel e s      -> ESel !$ (go e) .$ s         EComp len t e mss -> EComp !$ (apSubst su len) !$ (apSubst su t) !$ (go e) !$ (apSubst su mss)         EIf e1 e2 e3  -> EIf !$ (go e1) !$ (go e2) !$ (go e3)+        ECase e as d  -> ECase !$ go e !$ (apSubst su <$> as)+                                       !$ (apSubst su <$> d)          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+        EPropGuards guards ty -> EPropGuards+          !$ (\(props, e) -> (apSubst su `fmap'` props, go e)) `fmap'` guards+          !$ apSubst su ty +instance TVars CaseAlt where+  apSubst su (CaseAlt xs e) = CaseAlt !$ [(x,apSubst su t) | (x,t) <- xs]+                                      !$ apSubst su e+    -- XXX: not as strict as the rest+ 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)@@ -452,9 +472,9 @@     in d { dSignature = sig', dDefinition = def' }  instance TVars DeclDef where-  apSubst su (DExpr e)    = DExpr !$ (apSubst su e)-  apSubst _  DPrim        = DPrim-  apSubst _  (DForeign t) = DForeign t+  apSubst su (DExpr e)       = DExpr !$ (apSubst su e)+  apSubst _  DPrim           = DPrim+  apSubst su (DForeign t me) = DForeign t !$ apSubst su me  -- WARNING: This applies the substitution only to the declarations. instance TVars (ModuleG names) where
src/Cryptol/TypeCheck/TCon.hs view
@@ -126,9 +126,6 @@   kindOf (TF tf)      = kindOf tf   kindOf (TError k)   = k -instance HasKind UserTC where-  kindOf (UserTC _ k) = k- instance HasKind TC where   kindOf tcon =     case tcon of@@ -143,7 +140,6 @@       TCSeq     -> KNum :-> KType :-> KType       TCFun     -> KType :-> KType :-> KType       TCTuple n -> foldr (:->) KType (replicate n KType)-      TCAbstract x -> kindOf x  instance HasKind PC where   kindOf pc =@@ -238,24 +234,11 @@             | TCSeq                    -- ^ @[_] _@             | TCFun                    -- ^ @_ -> _@             | TCTuple Int              -- ^ @(_, _, _)@-            | TCAbstract UserTC        -- ^ An abstract type               deriving (Show, Eq, Ord, Generic, NFData)  -data UserTC = UserTC M.Name Kind-              deriving (Show, Generic, NFData) -instance Eq UserTC where-  UserTC x _ == UserTC y _ = x == y -instance Ord UserTC where-  compare (UserTC x _) (UserTC y _) = compare x y------ -- | Built-in type functions. -- If you add additional user-visible constructors, -- please update 'primTys' in "Cryptol.Prims.Types".@@ -339,10 +322,6 @@       TCTuple 0 -> text "()"       TCTuple 1 -> text "(one tuple?)"       TCTuple n -> parens $ hcat $ replicate (n-1) comma-      TCAbstract u -> pp u--instance PP UserTC where-  ppPrec p (UserTC x _) = ppPrec p x  instance PP TFun where   ppPrec _ tcon =
src/Cryptol/TypeCheck/Type.hs view
@@ -150,7 +150,7 @@               | TPSchemaParam Name               | TPTySynParam Name               | TPPropSynParam Name-              | TPNewtypeParam Name+              | TPNominalParam Name               | TPPrimParam Name               deriving (Generic, NFData, Show) @@ -173,9 +173,12 @@ propSynParam :: Name -> TPFlavor propSynParam = TPPropSynParam -newtypeParam :: Name -> TPFlavor-newtypeParam = TPNewtypeParam+nominalParam :: Name -> TPFlavor+nominalParam = TPNominalParam +primParam :: Name -> TPFlavor+primParam = TPPrimParam+ modTyParam :: Name -> TPFlavor modTyParam = TPModParam @@ -188,7 +191,7 @@     TPSchemaParam x  -> Just x     TPTySynParam x   -> Just x     TPPropSynParam x -> Just x-    TPNewtypeParam x -> Just x+    TPNominalParam x -> Just x     TPPrimParam x    -> Just x  tpName :: TParam -> Maybe Name@@ -212,8 +215,8 @@             | TRec !(RecordMap Ident Type)               -- ^ Record type -            | TNewtype !Newtype ![Type]-              -- ^ A newtype+            | TNominal !NominalType ![Type]+              -- ^ A nominal types                deriving (Show, Generic, NFData) @@ -262,6 +265,8 @@                 | TypeOfIfCondExpr                 | TypeFromUserAnnotation                 | GeneratorOfListComp+                | CasedExpression+                | ConPat                 | TypeErrorPlaceHolder                   deriving (Show, Generic, NFData) @@ -315,40 +320,49 @@   --- | Named records-data Newtype  = Newtype { ntName   :: Name-                        , ntParams :: [TParam]-                        , ntConstraints :: [Prop]-                        , ntConName :: !Name-                        , ntFields :: RecordMap Ident Type-                        , ntDoc :: Maybe Text-                        } deriving (Show, Generic, NFData)+-- | Nominal types+data NominalType = NominalType+  { ntName        :: Name+  , ntParams      :: [TParam]+  , ntKind        :: !Kind             -- ^ Result kind+  , ntConstraints :: [Prop]+  , ntDef         :: NominalTypeDef+  , ntFixity      :: !(Maybe Fixity)+  , ntDoc         :: Maybe Text+  } deriving (Show, Generic, NFData) +-- | Definition of a nominal type+data NominalTypeDef =+    Struct StructCon+  | Enum [EnumCon]+  | Abstract+  deriving (Show, Generic, NFData) -instance Eq Newtype where-  x == y = ntName x == ntName y+-- | Constructor for a struct (aka newtype)+data StructCon = StructCon+  { ntConName     :: !Name+  , ntFields      :: RecordMap Ident Type+  } deriving (Show, Generic, NFData) -instance Ord Newtype where-  compare x y = compare (ntName x) (ntName y)+-- | Constructor for an enumeration+data EnumCon = EnumCon+  { ecName        :: Name+  , ecNumber      :: !Int -- ^ Number of constructor in the declaration+  , ecFields      :: [Type]+  , ecPublic      :: Bool+  , ecDoc         :: Maybe Text+  } deriving (Show,Generic,NFData)  --- | Information about an abstract type.-data AbstractType = AbstractType-  { atName    :: Name-  , atKind    :: Kind-  , atCtrs    :: ([TParam], [Prop])-  , atFixitiy :: Maybe Fixity-  , atDoc     :: Maybe Text-  } deriving (Show, Generic, NFData)-+instance Eq NominalType where+  x == y = ntName x == ntName y +instance Ord NominalType where+  compare x y = compare (ntName x) (ntName y)   -------------------------------------------------------------------------------- -instance HasKind AbstractType where-  kindOf at = foldr (:->) (atKind at) (map kindOf (fst (atCtrs at)))- instance HasKind TVar where   kindOf (TVFree  _ k _ _) = k   kindOf (TVBound tp) = kindOf tp@@ -360,16 +374,20 @@       TCon c ts   -> quickApply (kindOf c) ts       TUser _ _ t -> kindOf t       TRec {}     -> KType-      TNewtype{}  -> KType+      TNominal nt ts ->+        case ntDef nt of+          Struct {} -> KType+          Enum {}   -> KType+          Abstract  -> quickApply (kindOf nt) ts  instance HasKind TySyn where   kindOf ts = foldr (:->) (kindOf (tsDef ts)) (map kindOf (tsParams ts)) -instance HasKind Newtype where-  kindOf nt = foldr (:->) KType (map kindOf (ntParams nt))+instance HasKind NominalType where+  kindOf nt = foldr (:->) (ntKind nt) (map kindOf (ntParams nt))  instance HasKind TParam where-  kindOf p = tpKind p+  kindOf = tpKind  quickApply :: Kind -> [a] -> Kind quickApply k []               = k@@ -391,7 +409,7 @@   TCon x xs == TCon y ys  = x == y && xs == ys   TVar x    == TVar y     = x == y   TRec xs   == TRec ys    = xs == ys-  TNewtype ntx xs == TNewtype nty ys = ntx == nty && xs == ys+  TNominal ntx xs == TNominal nty ys = ntx == nty && xs == ys    _         == _          = False @@ -413,7 +431,7 @@       (TRec{}, _)             -> LT       (_, TRec{})             -> GT -      (TNewtype x xs, TNewtype y ys) -> compare (x,xs) (y,ys)+      (TNominal x xs, TNominal y ys) -> compare (x,xs) (y,ys)  instance Eq TParam where   x == y = tpUnique x == tpUnique y@@ -422,7 +440,7 @@   compare x y = compare (tpUnique x) (tpUnique y)  tpVar :: TParam -> TVar-tpVar p = TVBound p+tpVar = TVBound  -- | The type is "simple" (i.e., it contains no type functions). type SType  = Type@@ -454,27 +472,28 @@ superclassSet _ = mempty  -newtypeConType :: Newtype -> Schema-newtypeConType nt =-  Forall as (ntConstraints nt)-    $ TRec (ntFields nt) `tFun` TNewtype nt (map (TVar . tpVar) as)+nominalTypeConTypes :: NominalType -> [(Name,Schema)]+nominalTypeConTypes nt =+  case ntDef nt of+    Struct s -> [ ( ntConName s+                  , Forall as ctrs (TRec (ntFields s) `tFun` resT)+                  ) ]+    Enum cs  -> [ ( ecName c+                  , Forall as ctrs (foldr tFun resT (ecFields c))+                  )+                | c <- cs+                ]+    Abstract -> []   where-  as = ntParams nt-+  as    = ntParams nt+  ctrs  = ntConstraints nt+  resT  = TNominal nt (map (TVar . tpVar) as) -abstractTypeTC :: AbstractType -> TCon-abstractTypeTC at =-  case builtInType (atName at) of-    Just tcon-      | kindOf tcon == atKind at -> tcon-      | otherwise ->-        panic "abstractTypeTC"-          [ "Mismatch between built-in and declared type."-          , "Name: " ++ pretty (atName at)-          , "Declared: " ++ pretty (atKind at)-          , "Built-in: " ++ pretty (kindOf tcon)-          ]-    _         -> TC $ TCAbstract $ UserTC (atName at) (atKind at)+nominalTypeIsAbstract :: NominalType -> Bool+nominalTypeIsAbstract nt =+  case ntDef nt of+    Abstract -> True+    _        -> False  instance Eq TVar where   TVBound x       == TVBound y       = x == y@@ -712,11 +731,8 @@               Inf   -> tInf               Nat n -> tNum n -tAbstract :: UserTC -> [Type] -> Type-tAbstract u ts = TCon (TC (TCAbstract u)) ts--tNewtype :: Newtype -> [Type] -> Type-tNewtype nt ts = TNewtype nt ts+tNominal :: NominalType -> [Type] -> Type+tNominal = TNominal  tBit     :: Type tBit      = TCon (TC TCBit) []@@ -977,34 +993,7 @@         TVar x      -> Set.singleton x         TUser _ _ t -> go t         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-+        TNominal _nt ts -> fvs ts   instance FVS a => FVS (Maybe a) where@@ -1047,22 +1036,49 @@          used    = map snd named ++ IntMap.elems ns -ppNewtypeShort :: Newtype -> Doc-ppNewtypeShort nt =-  text "newtype" <+> pp (ntName nt) <+> hsep (map (ppWithNamesPrec nm 9) ps)+ppNominalShort :: NominalType -> Doc+ppNominalShort nt =+  kw <+> pp (ntName nt) <+> hsep (map (ppWithNamesPrec nm 9) ps)   where-  ps  = ntParams nt+  ps = ntParams nt   nm = addTNames ps emptyNameMap+  kw = case ntDef nt of+         Struct {} -> "newtype"+         Enum {}   -> "enum"+         Abstract {} -> "primitive type" -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))+ppNominalFull :: NominalType -> Doc+ppNominalFull nt =+  case ntDef nt of++    Struct con -> ppKWDef "newtype" ("=" <+> pp (ntConName con) $$ nest 2 fs)+      where fs = vcat [ pp f <.> ":" <+> pp t+                      | (f,t) <- canonicalFields (ntFields con) ]+    Enum cons ->+      ppKWDef "enum" $+      vcat [ pref <+> pp (ecName con) <+> hsep (map (ppPrec 1) (ecFields con))+           | (pref,con) <- zip ("=" : repeat "|") cons+           ]++    Abstract ->+      "primitive type" <+> paramBinds <+> ctrs <+> ppTyUse <+>+                                                        ":" <+> pp (ntKind nt)+      where+      paramBinds =+        case ps of+          [] -> mempty+          _  -> braces (commaSep (map ppBind ps))+      ppBind p = ppWithNamesPrec nm 0 p <+> ":" <+> pp (kindOf p)+      ppC     = ppWithNamesPrec nm 0+      ctrs = case ntConstraints nt of+               [] -> mempty+               _  -> parens (commaSep (map ppC (ntConstraints nt))) <+> "=>"   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))+  nm = addTNames ps emptyNameMap+  ppTyUse = pp (ntName nt) <+> hsep (map (ppWithNamesPrec nm 9) ps)+  ppKWDef kw def = (kw <+> ppTyUse) $$ nest 2 (cs $$ def)   @@ -1106,11 +1122,11 @@                   (_, ps) ->                     [pp n] ++ map (ppWithNames ns1) ps -instance PP Newtype where+instance PP NominalType where   ppPrec = ppWithNamesPrec IntMap.empty -instance PP (WithNames Newtype) where-  ppPrec _  (WithNames nt _) = ppNewtypeShort nt -- XXX: do the full thing?+instance PP (WithNames NominalType) where+  ppPrec _  (WithNames nt _) = ppNominalShort nt -- XXX: do the full thing?   @@ -1130,7 +1146,8 @@   ppPrec prec ty0@(WithNames ty nmMap) =     case ty of       TVar a  -> ppWithNames nmMap a-      TNewtype nt ts -> optParens (prec > 3) $ fsep (pp (ntName nt) : map (go 5) ts)+      TNominal nt ts -> optParens (prec > 3)+                                  (fsep (pp (ntName nt) : map (go 5) ts))       TRec fs -> ppRecord                     [ pp l <+> text ":" <+> go 0 t | (l,t) <- displayFields fs ] @@ -1233,7 +1250,7 @@                 TPSchemaParam n  -> declNm n                 TPTySynParam n   -> declNm n                 TPPropSynParam n -> declNm n-                TPNewtypeParam n -> declNm n+                TPNominalParam n -> declNm n                 TPPrimParam n    -> declNm n              TVFree x k _ d -> pickTVarName k (tvarDesc d) x@@ -1269,6 +1286,8 @@     FunApp                 -> "fun"     TypeFromUserAnnotation -> "user"     TypeErrorPlaceHolder   -> "err"+    CasedExpression        -> "case"+    ConPat                 -> "conp"   where   sh a      = show (pp a)   using a   = mk (sh a)@@ -1318,6 +1337,8 @@       GeneratorOfListComp    -> "generator in a list comprehension"       FunApp                -> "function call"       TypeErrorPlaceHolder  -> "type error place-holder"+      CasedExpression       -> "cased expression"+      ConPat                -> "constructor pattern"  instance PP ModParamNames where   ppPrec _ ps =
src/Cryptol/TypeCheck/TypeMap.hs view
@@ -118,16 +118,16 @@ data TypeMap a = TM { tvar :: Map TVar a                     , tcon :: Map TCon    (List TypeMap a)                     , trec :: Map [Ident] (List TypeMap a)-                    , tnewtype :: Map Newtype (List TypeMap a)+                    , tnominal :: Map NominalType (List TypeMap a)                     } deriving (Functor, Foldable, Traversable)  instance TrieMap TypeMap Type where-  emptyTM = TM { tvar = emptyTM, tcon = emptyTM, trec = emptyTM, tnewtype = emptyTM }+  emptyTM = TM { tvar = emptyTM, tcon = emptyTM, trec = emptyTM, tnominal = emptyTM }    nullTM ty = and [ nullTM (tvar ty)                   , nullTM (tcon ty)                   , nullTM (trec ty)-                  , nullTM (tnewtype ty)+                  , nullTM (tnominal ty)                   ]    lookupTM ty =@@ -137,7 +137,7 @@       TCon c ts   -> lookupTM ts <=< lookupTM c . tcon       TRec fs     -> let (xs,ts) = unzip $ canonicalFields fs                      in lookupTM ts <=< lookupTM xs . trec-      TNewtype nt ts -> lookupTM ts <=< lookupTM nt . tnewtype+      TNominal nt ts -> lookupTM ts <=< lookupTM nt . tnominal    alterTM ty f m =     case ty of@@ -146,7 +146,7 @@       TCon c ts   -> m { tcon = alterTM c (updSub ts f) (tcon m) }       TRec fs     -> let (xs,ts) = unzip $ canonicalFields fs                      in m { trec = alterTM xs (updSub ts f) (trec m) }-      TNewtype nt ts -> m { tnewtype = alterTM nt (updSub ts f) (tnewtype m) }+      TNominal nt ts -> m { tnominal = alterTM nt (updSub ts f) (tnominal m) }    toListTM m =     [ (TVar x,           v) | (x,v)   <- toListTM (tvar m) ] ++@@ -159,14 +159,14 @@           | (fs,m1) <- toListTM (trec m)           , (ts,v)  <- toListTM m1 ] ++ -    [ (TNewtype nt ts, v) | (nt,m1) <- toListTM (tnewtype m)+    [ (TNominal nt ts, v) | (nt,m1) <- toListTM (tnominal m)                           , (ts,v)  <- toListTM m1     ]    unionTM f m1 m2 = TM { tvar = unionTM f (tvar m1) (tvar m2)                        , tcon = unionTM (unionTM f) (tcon m1) (tcon m2)                        , trec = unionTM (unionTM f) (trec m1) (trec m2)-                       , tnewtype = unionTM (unionTM f) (tnewtype m1) (tnewtype m2)+                       , tnominal = unionTM (unionTM f) (tnominal m1) (tnominal m2)                        }    mapMaybeWithKeyTM f m =@@ -177,8 +177,8 @@                              (\ts a -> f (TRec (recordFromFields (zip fs ts))) a) l) (trec m)                                -- NB: this step loses 'displayOrder' information.                                --  It's not clear if we should try to fix this.-       , tnewtype = mapWithKeyTM (\nt l -> mapMaybeWithKeyTM-                                 (\ts a -> f (TNewtype nt ts) a) l) (tnewtype m)+       , tnominal = mapWithKeyTM (\nt l -> mapMaybeWithKeyTM+                                 (\ts a -> f (TNominal nt ts) a) l) (tnominal m)        }  
src/Cryptol/TypeCheck/TypeOf.hs view
@@ -38,6 +38,12 @@     ESel e sel    -> typeSelect (fastTypeOf tyenv e) sel     ESet ty _ _ _ -> ty     EIf _ e _     -> fastTypeOf tyenv e+    ECase _ as d  -> case d of+                       Just e -> fastTypeOfAlt tyenv e+                       Nothing ->+                         case Map.minView as of+                           Just (e,_) -> fastTypeOfAlt tyenv e+                           Nothing -> panic "fastTypeOf" ["Empty case"]     EComp len t _ _ -> tSeq len t     EAbs x t e    -> tFun t (fastTypeOf (Map.insert x (Forall [] [] t) tyenv) e)     EApp e _      -> case tIsFun (fastTypeOf tyenv e) of@@ -63,6 +69,11 @@                , pretty s                ] +fastTypeOfAlt :: Map Name Schema -> CaseAlt -> Type+fastTypeOfAlt tyenv (CaseAlt xs e) = fastTypeOf newEnv e+  where newEnv = foldr addVar tyenv xs+        addVar (x,t) = Map.insert x (tMono t)+ fastSchemaOf :: Map Name Schema -> Expr -> Schema fastSchemaOf tyenv expr =   case expr of@@ -110,6 +121,7 @@     ESet   {}      -> monomorphic     ESel   {}      -> monomorphic     EIf    {}      -> monomorphic+    ECase  {}      -> monomorphic     EComp  {}      -> monomorphic     EApp   {}      -> monomorphic     EAbs   {}      -> monomorphic@@ -128,7 +140,7 @@     TCon tc ts     -> TCon tc (map (plainSubst s) ts)     TUser f ts t   -> TUser f (map (plainSubst s) ts) (plainSubst s t)     TRec fs        -> TRec (fmap (plainSubst s) fs)-    TNewtype nt ts -> TNewtype nt (map (plainSubst s) ts)+    TNominal nt ts -> TNominal nt (map (plainSubst s) ts)     TVar x         -> apSubst s (TVar x)  -- | Yields the return type of the selector on the given argument type.@@ -146,8 +158,9 @@   | Just ty <- lookupField n fields = ty  -- Record selector applied to a newtype-typeSelect (TNewtype nt args) (RecordSel n _)-  | Just ty <- lookupField n (ntFields nt)+typeSelect (TNominal nt args) (RecordSel n _)+  | Struct con <- ntDef nt+  , Just ty <- lookupField n (ntFields con)   = plainSubst (listParamSubst (zip (ntParams nt) args)) ty  -- List selector applied to a sequence
src/Cryptol/TypeCheck/TypePat.hs view
@@ -16,7 +16,6 @@    , aTVar   , aFreeTVar-  , anAbstractType   , aBit   , aSeq   , aWord@@ -125,11 +124,6 @@ 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/TypeCheck/Unify.hs view
@@ -54,7 +54,7 @@  data PathElement =     TConArg     TC      Int-  | TNewtypeArg Newtype Int+  | TNominalArg NominalType Int   | TRecArg     Ident   deriving (Show,Generic,NFData) @@ -108,9 +108,9 @@     let paths = [ extPath p (TRecArg i) | (i,_) <- canonicalFields fs1 ]     in mguMany p paths (recordElements fs1) (recordElements fs2) -mgu p (TNewtype ntx xs) (TNewtype nty ys)+mgu p (TNominal ntx xs) (TNominal nty ys)   | ntx == nty =-    let paths = [ extPath p (TNewtypeArg ntx i) | i <- [ 0 .. ] ]+    let paths = [ extPath p (TNominalArg ntx i) | i <- [ 0 .. ] ]     in mguMany p paths xs ys  mgu p t1 t2@@ -192,7 +192,7 @@         _ -> justPrefix (kindArity (kindOf tc)) (pp tc) n -    TNewtypeArg nt n ->+    TNominalArg nt n ->       justPrefix (length (ntParams nt)) (pp (nameIdent (ntName nt))) n    where
src/Cryptol/Utils/Ident.hs view
@@ -26,6 +26,7 @@   , modNameChunks   , modNameChunksText   , packModName+  , identToModName   , preludeName   , preludeReferenceName   , undefinedModName@@ -49,6 +50,7 @@   , mkIdent   , mkInfix   , isInfixIdent+  , isUpperIdent   , nullIdent   , identText   , modParamIdent@@ -63,7 +65,7 @@     -- * Original names   , OrigName(..)   , OrigSource(..)-  , ogFromModParam+  , ogIsModParam      -- * Identifiers for primitives   , PrimIdent(..)@@ -75,7 +77,7 @@   ) where  import           Control.DeepSeq (NFData)-import           Data.Char (isSpace)+import           Data.Char (isSpace,isUpper) import           Data.List (unfoldr) import           Data.Text (Text) import qualified Data.Text as T@@ -88,7 +90,11 @@ --------------------------------------------------------------------------------  -- | Namespaces for names-data Namespace = NSValue | NSType | NSModule+data Namespace = NSValue+               | NSConstructor -- ^ This is for enum and newtype constructors++               | NSType+               | NSModule   deriving (Generic,Show,NFData,Eq,Ord,Enum,Bounded)  allNamespaces :: [Namespace]@@ -214,6 +220,9 @@   -- trim space off of the start and end of the string   trim str = T.dropWhile isSpace (T.dropWhileEnd isSpace str) +identToModName :: Ident -> ModName+identToModName (Ident _ anon txt) = ModName txt anon+ modSep :: T.Text modSep  = "::" @@ -255,19 +264,21 @@   , ogModule    :: ModPath   , ogSource    :: OrigSource   , ogName      :: Ident+  , ogFromParam :: !(Maybe Ident)+    -- ^ Does this name come from a module parameter   } deriving (Eq,Ord,Show,Generic,NFData)  -- | Describes where a top-level name came from data OrigSource =     FromDefinition   | FromFunctorInst-  | FromModParam Ident+  | FromModParam     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+ogIsModParam :: OrigName -> Bool+ogIsModParam og = case ogSource og of+                      FromModParam -> True                       _ -> False  @@ -313,6 +324,12 @@  isInfixIdent :: Ident -> Bool isInfixIdent (Ident b _ _) = b++isUpperIdent :: Ident -> Bool+isUpperIdent (Ident _ mb t) =+  case mb of+    NormalName | Just (c,_) <- T.uncons t -> isUpper c+    _ -> False  nullIdent :: Ident -> Bool nullIdent = T.null . identText
src/Cryptol/Utils/PP.hs view
@@ -410,21 +410,22 @@         UnQualified -> pp (ogName og)         Qualified m -> ppQual (TopModule m) (pp (ogName og))         NotInScope  -> ppQual (ogModule og)-                       case ogSource og of-                         FromModParam x -> pp x <.> "::" <.> pp (ogName og)-                         _ -> pp (ogName og)+                       case ogFromParam og of+                         Just x  -> pp x <.> "::" <.> pp (ogName og)+                         Nothing -> pp (ogName og)     where-   ppQual mo x =-    case mo of-      TopModule m-        | m == exprModName -> x-        | otherwise -> pp m <.> "::" <.> x-      Nested m y -> ppQual m (pp y <.> "::" <.> x)+    ppQual mo x =+      case mo of+        TopModule m+          | m == exprModName -> x+          | otherwise -> pp m <.> "::" <.> x+        Nested m y -> ppQual m (pp y <.> "::" <.> x)  instance PP Namespace where   ppPrec _ ns =     case ns of       NSValue     -> "/*value*/"+      NSConstructor -> "/*constructor*/"       NSType      -> "/*type*/"       NSModule    -> "/*module*/" 
src/Cryptol/Utils/RecordMap.hs view
@@ -37,7 +37,8 @@   ) where  import           Control.DeepSeq-import           Control.Monad.Except+import           Control.Monad.Except (ExceptT, MonadError(..), runExceptT)+import           Control.Monad.Trans (MonadTrans(..)) import           Data.Functor.Identity import           Data.Set (Set) import           Data.Map (Map)@@ -71,7 +72,7 @@   show = show . displayFields  instance (NFData a, NFData b) => NFData (RecordMap a b) where-  rnf = rnf . canonicalFields +  rnf = rnf . canonicalFields   -- | Return the fields in this record as a set.@@ -116,7 +117,7 @@ recordFromFields :: (Show a, Ord a) => [(a,b)] -> RecordMap a b recordFromFields xs =   case recordFromFieldsErr xs of-    Left (x,_) -> +    Left (x,_) ->           panic "recordFromFields"                 ["Repeated field value: " ++ show x]     Right r -> r
src/Cryptol/Version.hs view
@@ -13,6 +13,7 @@   , commitShortHash   , commitBranch   , commitDirty+  , ffiEnabled   , version   , displayVersion   ) where@@ -20,6 +21,7 @@ import Paths_cryptol import qualified GitRev import Data.Version (showVersion)+import Control.Monad (when)  commitHash :: String commitHash = GitRev.hash@@ -33,15 +35,20 @@ commitDirty :: Bool commitDirty = GitRev.dirty +ffiEnabled :: Bool+#ifdef FFI_ENABLED+ffiEnabled = True+#else+ffiEnabled = False+#endif+ displayVersion :: Monad m => (String -> m ()) -> m () displayVersion putLn = do     let ver = showVersion version     putLn ("Cryptol " ++ ver)     putLn ("Git commit " ++ commitHash)     putLn ("    branch " ++ commitBranch ++ dirtyLab)-#ifdef FFI_ENABLED-    putLn "FFI enabled"-#endif+    when ffiEnabled $ putLn "FFI enabled"       where       dirtyLab | commitDirty = " (non-committed files present during build)"                | otherwise   = ""