Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TC: handle all const value types #1116

Merged
merged 1 commit into from
Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions src/Pact/Typechecker.hs
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,19 @@ notEmpty :: MonadThrow m => Info -> String -> [a] -> m [a]
notEmpty i msg [] = die i msg
notEmpty _ _ as = return as

-- | Safely return 'Term Name' to 'Term Ref' for value types and consts
hoistValueTerm :: MonadThrow m => Term Name -> m (Term Ref)
hoistValueTerm (TLiteral l i) = pure $ TLiteral l i
hoistValueTerm (TList vs ty i) =
TList <$> traverse hoistValueTerm vs <*> traverse hoistValueTerm ty <*> pure i
hoistValueTerm (TObject o i) = TObject <$> traverse bottom o <*> pure i
where
bottom n = die i $ "Unexpected reference in value context: " <> showPretty n
hoistValueTerm (TGuard g i) = TGuard <$> traverse hoistValueTerm g <*> pure i
hoistValueTerm (TModRef m i) = pure $ TModRef m i
hoistValueTerm (TConst a n v m i) =
TConst <$> traverse hoistValueTerm a <*> pure n <*> traverse hoistValueTerm v <*> pure m <*> pure i
hoistValueTerm t = die (getInfo t) $ "Unexpected term in value context: " <> showPretty t

-- | Build ASTs from terms.
toAST :: Term (Either Ref (AST Node)) -> TC (AST Node)
Expand All @@ -897,21 +910,9 @@ toAST TModRef{..} = do

n <- trackNode ty tcid
return $ ModRef n (_modRefName _tModRef) (_modRefSpec _tModRef)
toAST (TVar v i) = case v of -- value position only, TApp has its own resolver
toAST (TVar v _i) = case v of -- value position only, TApp has its own resolver
(Left (Ref r)) -> toAST (fmap Left r)
(Left (Direct t)) ->
case t of
TLiteral {..} ->
-- Handle references to pre-evaluated constants:
trackPrim _tInfo (litToPrim _tLiteral) (PrimLit _tLiteral)
TConst{..} -> case _tModule of
-- if modulename is nothing, it's a builtin
Nothing -> toAST $ return $ Left (Direct $ constTerm _tConstVal)
_ -> die i $ "Non-native constant value in native context: " <> showPretty t
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note, this enforcement is gone now. There's no real need for it -- even if it should be syntactically impossible for a user defconst to be Direct, it doesn't really mean anything is un-TC-able

TGuard{..} -> do
g <- traverse (toAST . return . Left . Direct) _tGuard
trackPrim _tInfo (TyGuard $ Just $ guardTypeOf _tGuard) (PrimGuard g)
_ -> die i $ "Native in value context: " <> showPretty t
(Left (Direct t)) -> hoistValueTerm t >>= toAST . fmap Left
(Right t) -> return t

toAST (TApp Term.App{..} _) = do
Expand Down
2 changes: 1 addition & 1 deletion tests/TypecheckSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ customFunChecks :: Text -> SpecWith TCResult
customFunChecks name = case name of
"tests/pact/tc.repl.tc-update-partial" -> do
-- TODO top levels don't get inferred return type, so we have to dig in here
it (show name ++ ":specializes partial type") $ \(tl, _) -> do
it (unpack name ++ ":specializes partial type") $ \(tl, _) -> do
shouldBe
(preview (tlFun . fBody . _head . aNode . aTy . tySchemaPartial) tl)
(Just $ PartialSchema $ Set.singleton "name")
Expand Down
12 changes: 12 additions & 0 deletions tests/pact/tc.repl
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@

(defconst FOUR (+ 2 2))

(defconst LIST (enumerate 0 10))

(defconst MODREF tc-test-impl)

(defconst OBJ (tc-test-inner))

(defconst GUARD (keyset-ref-guard 'keyset))

(deftable persons:{person})

(defun tc-add-person (person)
Expand Down Expand Up @@ -271,6 +279,10 @@
"test compliant modrefs with varying impl lists"
(tc-eq-modref tc-test-impl tc-test-impl-both)
)

(defun tc-native-const:bool ()
"test handling of native consts"
(= 0 CHARSET_ASCII))
)

(create-table persons)
Expand Down