diff --git a/src/Solcore/Frontend/TypeInference/TcStmt.hs b/src/Solcore/Frontend/TypeInference/TcStmt.hs index 8cebd3ff..b07ba819 100644 --- a/src/Solcore/Frontend/TypeInference/TcStmt.hs +++ b/src/Solcore/Frontend/TypeInference/TcStmt.hs @@ -338,7 +338,7 @@ createClosureType ids vs ty i <- incCounter s <- getSubst let - ts = map idType ids + ts = map idType ids dn = Name $ "t_closure" ++ show i ts' = everywhere (mkT gen) ts ns = map Var $ (apply s ids) @@ -460,7 +460,7 @@ tiFunDef d@(FunDef sig@(Signature _ _ n args _) bd) -- typing function body (bd1, ps1, t1) <- withLocalCtx lctx' (tcBody bd) `wrapError` d -- unifying context introduced type with infered function type - s <- unify nt (funtype ts' t1) `wrapError` d + s <- unify nt (funtype ts' t1) `wrapError` d -- building the function type scheme rs <- reduce [] ps1 `wrapError` d ty <- withCurrentSubst nt @@ -515,15 +515,15 @@ tcFunDef incl vs' qs d@(FunDef sig@(Signature vs ps n args rt) bd) let lctx' = if incl then (n, monotype nt) : lctx else lctx -- typing function body (bd1', ps1', t1') <- withLocalCtx lctx' (tcBody bd1) `wrapError` d - -- checking if the type checking have changed the type + -- checking if the type checking have changed the type -- due to unique type creation. let tynames = tyconNames t1' - changeTy <- or <$> mapM isUniqueTyName tynames + changeTy <- or <$> mapM isUniqueTyName tynames let rt2 = if changeTy then t1' else rt1' info ["Trying to unify: ", pretty rt2, " with ", pretty t1'] unify rt2 t1' `wrapError` d info ["Trying to unify: ", pretty nt, " with ", pretty (funtype ts' rt2)] - unify nt (funtype ts' rt2) `wrapError` d + unify nt (funtype ts' rt2) `wrapError` d -- building the function type scheme free <- getEnvMetaVars rs <- reduce (qs1 `union` ps1) ps1' `wrapError` d @@ -536,11 +536,11 @@ tcFunDef incl vs' qs d@(FunDef sig@(Signature vs ps n args rt) bd) when (ambiguous inf) $ ambiguousTypeError inf sig -- checking subsumption - unless changeTy $ do + unless changeTy $ do subsCheck sig inf ann `wrapError` d -- elaborating function body let ann' = if changeTy then inf else ann - fdt <- elabFunDef vs' sig1 bd1' inf ann' `wrapError` d + fdt <- elabFunDef vs' sig1 bd1' inf ann' `wrapError` d withCurrentSubst (fdt, ann') | otherwise = tiFunDef d @@ -691,7 +691,7 @@ verifySignatures instd@(Instance _ _ ps n ts t funs) = do -- get class info mcinfo <- Map.lookup n <$> gets classTable - when (isNothing mcinfo) (undefinedClass n) `wrapError` instd + when (isNothing mcinfo) (undefinedClass n) `wrapError` instd -- building instance constraint let -- this use of fromJust is safe, because is @@ -813,10 +813,10 @@ checkInstance idef@(Instance d vs ctx n ts t funs) -- checking the coverage condition insts' <- askInstEnv n `wrapError` ipred -- check overlapping only for non-default instances - let vs1 = bv ipred - ts1 <- mapM (const freshTyVar) vs1 + let vs1 = bv ipred + ts1 <- mapM (const freshTyVar) vs1 let env = zip vs1 ts1 - ipred' = insts env ipred + ipred' = insts env ipred unless d (checkOverlap ipred' insts' `wrapError` idef) -- check if default instance has a type variable as main argument. when d (checkDefaultInst (ctx :=> ipred) `wrapError` idef) @@ -1071,13 +1071,14 @@ tcYulExp (YIdent v) (_ :=> t) <- freshInst sch unify t word pure t -tcYulExp (YCall n es) +tcYulExp e@(YCall n es) = do - sch <- askEnv n `wrapError` (YCall n es) + sch <- askEnv n `wrapError` e (_ :=> t) <- freshInst sch ts <- mapM tcYulExp es t' <- freshTyVar - unify t (foldr (:->) t' ts) + s <- unify t (funtype ts t') `wrapError` e + extSubst s withCurrentSubst t' tcYLit :: YLiteral -> TcM Ty diff --git a/src/Solcore/Primitives/Primitives.hs b/src/Solcore/Primitives/Primitives.hs index d72d6759..f99588e0 100644 --- a/src/Solcore/Primitives/Primitives.hs +++ b/src/Solcore/Primitives/Primitives.hs @@ -186,7 +186,7 @@ yulPrimOps = [ (Name "stop", monotype unit) , (Name "slt", monotype (word :-> word :-> word)) , (Name "sgt", monotype (word :-> word :-> word)) , (Name "eq", monotype (word :-> word :-> word)) - , (Name "iszero", monotype (word :-> word :-> word)) + , (Name "iszero", monotype (word :-> word)) , (Name "and", monotype (word :-> word :-> word)) , (Name "or", monotype (word :-> word :-> word)) , (Name "xor", monotype (word :-> word :-> word)) diff --git a/test/Cases.hs b/test/Cases.hs index 775f0a2a..0a9d3ac8 100644 --- a/test/Cases.hs +++ b/test/Cases.hs @@ -187,6 +187,7 @@ cases = , runTestExpectingFailure "overlapping-heads.solc" caseFolder , runTestExpectingFailure "instance-wrong-sig.solc" caseFolder , runTestForFile "match-yul.solc" caseFolder + , runTestForFile "yul-function-typing.solc" caseFolder ] where caseFolder = "./test/examples/cases" diff --git a/test/examples/cases/yul-function-typing.solc b/test/examples/cases/yul-function-typing.solc new file mode 100644 index 00000000..32812c24 --- /dev/null +++ b/test/examples/cases/yul-function-typing.solc @@ -0,0 +1,8 @@ +function foo(length:word, pos:word) -> word { + let ret: word; + assembly { + // ret := add(pos, mul(0x20, iszero(iszero(length)))) + ret := iszero(iszero(length)) + } + return ret; +}