Remove ECast

The invariant that this used to ensure does not hold anymore, so
it was more confusing than not to have it.
This commit is contained in:
Iavor S. Diatchki 2017-02-23 15:18:05 -08:00
parent 1d8f2576c8
commit 174bb3c20a
11 changed files with 22 additions and 58 deletions

View File

@ -146,8 +146,6 @@ evalExpr env expr = case expr of
EProofAbs _ e -> evalExpr env e EProofAbs _ e -> evalExpr env e
EProofApp e -> evalExpr env e EProofApp e -> evalExpr env e
ECast e _ty -> evalExpr env e
EWhere e ds -> {-# SCC "evalExpr->EWhere" #-} do EWhere e ds -> {-# SCC "evalExpr->EWhere" #-} do
env' <- evalDecls ds env env' <- evalDecls ds env
evalExpr env' e evalExpr env' e

View File

@ -188,7 +188,6 @@ evalExpr env expr =
EAbs n _ty b -> VFun (\v -> evalExpr (bindVar (n, v) env) b) EAbs n _ty b -> VFun (\v -> evalExpr (bindVar (n, v) env) b)
EProofAbs _ e -> evalExpr env e EProofAbs _ e -> evalExpr env e
EProofApp e -> evalExpr env e EProofApp e -> evalExpr env e
ECast e _ty -> evalExpr env e
EWhere e dgs -> evalExpr (foldl evalDeclGroup env dgs) e EWhere e dgs -> evalExpr (foldl evalDeclGroup env dgs) e

View File

@ -195,7 +195,6 @@ rewE rews = go
EProofAbs x e -> EProofAbs x <$> go e EProofAbs x e -> EProofAbs x <$> go e
ECast e t -> ECast <$> go e <*> return t
EWhere e dgs -> EWhere <$> go e <*> inLocal EWhere e dgs -> EWhere <$> go e <*> inLocal
(mapM (rewDeclGroup rews) dgs) (mapM (rewDeclGroup rews) dgs)

View File

@ -99,8 +99,6 @@ specializeExpr expr =
EAbs qn t e -> EAbs qn t <$> specializeExpr e EAbs qn t e -> EAbs qn t <$> specializeExpr e
EProofAbs p e -> EProofAbs p <$> specializeExpr e EProofAbs p e -> EProofAbs p <$> specializeExpr e
EProofApp {} -> specializeConst expr EProofApp {} -> specializeConst expr
ECast e t -> ECast <$> specializeExpr e <*> pure t
-- TODO: if typeOf e == t, then drop the coercion.
EWhere e dgs -> specializeEWhere e dgs EWhere e dgs -> specializeEWhere e dgs
specializeMatch :: Match -> SpecM Match specializeMatch :: Match -> SpecM Match

View File

@ -92,23 +92,6 @@ data Expr = EList [Expr] Type -- ^ List value (with type of elements)
| EProofApp Expr {- proof -} | EProofApp Expr {- proof -}
{- | if e : t1, then cast e : t2
as long as we can prove that 't1 = t2'.
We could express this in terms of a built-in constant.
`cast :: {a,b} (a =*= b) => a -> b`
Using the constant is a bit verbose though, because we
end up with both the source and target type. So, instead
we use this language construct, which only stores the
target type, and the source type can be reconstructed
from the expression.
Another way to think of this is simply as an expression
with an explicit type annotation.
-}
| ECast Expr Type
| EWhere Expr [DeclGroup] | EWhere Expr [DeclGroup]
deriving (Show, Generic, NFData) deriving (Show, Generic, NFData)
@ -220,9 +203,6 @@ instance PP (WithNames Expr) where
ETApp e t -> optParens (prec > 3) ETApp e t -> optParens (prec > 3)
$ ppWP 3 e <+> ppWP 4 t $ ppWP 3 e <+> ppWP 4 t
ECast e t -> optParens (prec > 0)
( ppWP 2 e <+> text ":" <+> ppW t )
EWhere e ds -> optParens (prec > 0) EWhere e ds -> optParens (prec > 0)
( ppW e $$ text "where" ( ppW e $$ text "where"
$$ nest 2 (vcat (map ppW ds)) $$ nest 2 (vcat (map ppW ds))

View File

@ -108,7 +108,8 @@ appTys expr ts tGoal =
ExtVar s -> instantiateWith (EVar x) s ts ExtVar s -> instantiateWith (EVar x) s ts
CurSCC e t -> instantiateWith e (Forall [] [] t) ts CurSCC e t -> instantiateWith e (Forall [] [] t) ts
checkHasType e' t tGoal checkHasType t tGoal
return e'
P.ELit l -> do e <- desugarLiteral False l P.ELit l -> do e <- desugarLiteral False l
appTys e ts tGoal appTys e ts tGoal
@ -147,7 +148,8 @@ appTys expr ts tGoal =
(ie,t) <- instantiateWith e' (Forall [] [] tGoal) ts (ie,t) <- instantiateWith e' (Forall [] [] tGoal) ts
-- XXX seems weird to need to do this, as t should be the same -- XXX seems weird to need to do this, as t should be the same
-- as tGoal -- as tGoal
checkHasType ie t tGoal checkHasType t tGoal
return ie
inferTyParam :: P.TypeInst Name -> InferM (Located (Maybe Ident, Type)) inferTyParam :: P.TypeInst Name -> InferM (Located (Maybe Ident, Type))
@ -186,7 +188,8 @@ checkE expr tGoal =
ExtVar s -> instantiateWith (EVar x) s [] ExtVar s -> instantiateWith (EVar x) s []
CurSCC e t -> return (e, t) CurSCC e t -> return (e, t)
checkHasType e' t tGoal checkHasType t tGoal
return e'
P.ELit l -> (`checkE` tGoal) =<< desugarLiteral False l P.ELit l -> (`checkE` tGoal) =<< desugarLiteral False l
@ -308,7 +311,8 @@ checkE expr tGoal =
P.ETyped e t -> P.ETyped e t ->
do tSig <- checkTypeOfKind t KType do tSig <- checkTypeOfKind t KType
e' <- checkE e tSig e' <- checkE e tSig
checkHasType e' tSig tGoal checkHasType tSig tGoal
return e'
P.ETypeVal t -> P.ETypeVal t ->
do l <- curRange do l <- curRange
@ -455,12 +459,12 @@ expectFun = go []
newType (text "argument" <+> ordinal ix) KType newType (text "argument" <+> ordinal ix) KType
checkHasType :: Expr -> Type -> Type -> InferM Expr checkHasType :: Type -> Type -> InferM ()
checkHasType e inferredType givenType = checkHasType inferredType givenType =
do ps <- unify givenType inferredType do ps <- unify givenType inferredType
case ps of case ps of
[] -> return e [] -> return ()
_ -> newGoals CtExactType ps >> return (ECast e givenType) _ -> newGoals CtExactType ps
checkFun :: Doc -> [P.Pattern Name] -> P.Expr Name -> Type -> InferM Expr checkFun :: Doc -> [P.Pattern Name] -> P.Expr Name -> Type -> InferM Expr

View File

@ -75,15 +75,11 @@ instantiateWithPos e (Forall as ps t) ts =
The arguments that are provided will be instantiated as requested, The arguments that are provided will be instantiated as requested,
the rest will be instantiated with fresh type variables. the rest will be instantiated with fresh type variables.
Note that we assume that type parameters are not normalized. EProofApp (ETApp e t)
Generally, the resulting expression will look something like this:
ECast (EProofApp (ETApp e t)) t1
where where
- There will be one `ETApp t` for each insantiated type parameter; - There will be one `ETApp t` for each insantiated type parameter;
- there will be one `EProofApp` for each constraint on the schema; - there will be one `EProofApp` for each constraint on the schema;
- there will be `ECast` if we had equality constraints from normalization.
-} -}
instantiateWithNames :: Expr -> Schema -> [Located (Ident,Type)] instantiateWithNames :: Expr -> Schema -> [Located (Ident,Type)]
-> InferM (Expr,Type) -> InferM (Expr,Type)

View File

@ -318,12 +318,6 @@ exprSchema expr =
(_,_) -> reportError (BadProofTyVars as) (_,_) -> reportError (BadProofTyVars as)
ECast e t ->
do checkTypeIs KType t
t1 <- exprType e
convertible t t1
return (tMono t)
-- XXX: Check that defined things are disitnct? -- XXX: Check that defined things are disitnct?
EWhere e dgs -> EWhere e dgs ->
let go [] = exprSchema e let go [] = exprSchema e

View File

@ -40,20 +40,20 @@ listType n =
return (tSeq (tNum n) elems) return (tSeq (tNum n) elems)
improveSelector :: Selector -> Type -> InferM (Expr -> Expr) improveSelector :: Selector -> Type -> InferM ()
improveSelector sel outerT = improveSelector sel outerT =
case sel of case sel of
RecordSel _ mb -> cvt recordType mb RecordSel _ mb -> cvt recordType mb
TupleSel _ mb -> cvt tupleType mb TupleSel _ mb -> cvt tupleType mb
ListSel _ mb -> cvt listType mb ListSel _ mb -> cvt listType mb
where where
cvt _ Nothing = return id cvt _ Nothing = return ()
cvt f (Just a) = do ty <- f a cvt f (Just a) = do ty <- f a
cs <- unify ty outerT cs <- unify ty outerT
case cs of case cs of
[] -> return id [] -> return ()
_ -> do newGoals CtExactType cs _ -> do newGoals CtExactType cs
return (`ECast` ty) return ()
{- | Compute the type of a field based on the selector. {- | Compute the type of a field based on the selector.
@ -120,18 +120,17 @@ solveSelector sel outerT =
tryHasGoal :: HasGoal -> InferM () tryHasGoal :: HasGoal -> InferM ()
tryHasGoal has tryHasGoal has
| TCon (PC (PHas sel)) [ th, ft ] <- goal (hasGoal has) = | TCon (PC (PHas sel)) [ th, ft ] <- goal (hasGoal has) =
do outerCast <- improveSelector sel th do improveSelector sel th
outerT <- tNoUser `fmap` applySubst th outerT <- tNoUser `fmap` applySubst th
mbInnerT <- solveSelector sel outerT mbInnerT <- solveSelector sel outerT
case mbInnerT of case mbInnerT of
Nothing -> addHasGoal has Nothing -> addHasGoal has
Just innerT -> Just innerT ->
do cs <- unify innerT ft do cs <- unify innerT ft
innerCast <- case cs of case cs of
[] -> return id [] -> return ()
_ -> do newGoals CtExactType cs _ -> newGoals CtExactType cs
return (`ECast` ft) solveHasGoal (hasName has) (`ESel` sel)
solveHasGoal (hasName has) (innerCast . (`ESel` sel) . outerCast)
| otherwise = panic "hasGoalSolved" | otherwise = panic "hasGoalSolved"
[ "Unexpected selector proposition:" [ "Unexpected selector proposition:"

View File

@ -255,7 +255,6 @@ instance TVars Expr where
ETApp e t -> ETApp (go e) (apSubst su t) ETApp e t -> ETApp (go e) (apSubst su t)
EProofAbs p e -> EProofAbs (apSubst su p) (go e) EProofAbs p e -> EProofAbs (apSubst su p) (go e)
EProofApp e -> EProofApp (go e) EProofApp e -> EProofApp (go e)
ECast e t -> ECast (go e) (apSubst su t)
EVar {} -> expr EVar {} -> expr

View File

@ -40,7 +40,6 @@ fastTypeOf tyenv expr =
Just (_, t) -> t Just (_, t) -> t
Nothing -> panic "Cryptol.TypeCheck.TypeOf.fastTypeOf" Nothing -> panic "Cryptol.TypeCheck.TypeOf.fastTypeOf"
[ "EApp with non-function operator" ] [ "EApp with non-function operator" ]
ECast _ t -> t
-- Polymorphic fragment -- Polymorphic fragment
EVar {} -> polymorphic EVar {} -> polymorphic
ETAbs {} -> polymorphic ETAbs {} -> polymorphic
@ -93,7 +92,6 @@ fastSchemaOf tyenv expr =
EComp {} -> monomorphic EComp {} -> monomorphic
EApp {} -> monomorphic EApp {} -> monomorphic
EAbs {} -> monomorphic EAbs {} -> monomorphic
ECast {} -> monomorphic
where where
monomorphic = Forall [] [] (fastTypeOf tyenv expr) monomorphic = Forall [] [] (fastTypeOf tyenv expr)