-
Notifications
You must be signed in to change notification settings - Fork 483
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
[Builtins] Polish handling of integral types #6036
Changes from all commits
d39992e
a76d1ac
f202ac1
8d136bb
5a639ab
4f963a6
aca4446
8637022
b17f92e
ba20422
12aed03
9c442b3
b61cce8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
### Added | ||
|
||
- Missing `KnownTypeAst`, `ReadKnownIn` and `MakeKnownIn` for integral types (`Int8`, `Word16` etc) in #6036 | ||
|
||
### Changed | ||
|
||
- Made unlifting errors a bit more flexible by allowing operational unlifting errors in #6036 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -174,7 +174,7 @@ instance | |
type IsBuiltin _ (MetaForall name a) = 'False | ||
type ToHoles _ (MetaForall name a) = '[TypeHole a] | ||
type ToBinds uni acc (MetaForall name a) = ToBinds uni (Insert ('GADT.Some name) acc) a | ||
toTypeAst _ = toTypeAst $ Proxy @a | ||
typeAst = toTypeAst $ Proxy @a | ||
instance MakeKnownIn DefaultUni term a => MakeKnownIn DefaultUni term (MetaForall name a) where | ||
makeKnown (MetaForall x) = makeKnown x | ||
-- 'ReadKnownIn' doesn't make sense for 'MetaForall'. | ||
|
@@ -185,16 +185,19 @@ instance (tyname ~ TyName, KnownTypeAst tyname uni a) => | |
type IsBuiltin _ (PlcListRep a) = 'False | ||
type ToHoles _ (PlcListRep a) = '[RepHole a] | ||
type ToBinds uni acc (PlcListRep a) = ToBinds uni acc a | ||
toTypeAst _ = TyApp () Plc.listTy . toTypeAst $ Proxy @a | ||
typeAst = TyApp () Plc.listTy . toTypeAst $ Proxy @a | ||
|
||
instance tyname ~ TyName => KnownTypeAst tyname DefaultUni Void where | ||
toTypeAst _ = runQuote $ do | ||
type IsBuiltin _ _ = 'False | ||
type ToHoles _ _ = '[] | ||
type ToBinds _ acc _ = acc | ||
Comment on lines
190
to
+193
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
typeAst = runQuote $ do | ||
a <- freshTyName "a" | ||
pure $ TyForall () a (Type ()) $ TyVar () a | ||
instance UniOf term ~ DefaultUni => MakeKnownIn DefaultUni term Void where | ||
makeKnown = absurd | ||
instance UniOf term ~ DefaultUni => ReadKnownIn DefaultUni term Void where | ||
readKnown _ = throwing _UnliftingError "Can't unlift to 'Void'" | ||
readKnown _ = throwing _StructuralUnliftingError "Can't unlift to 'Void'" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We used to only support throwing structural unlifting errors with attached text and operational errors with no attached text (just raw failure), now we also support throwing operational unlifting errors with attached text (and use that feature, see below). Hence we now need to explicitly distinguish between the two kinds of errors. |
||
|
||
data BuiltinErrorCall = BuiltinErrorCall | ||
deriving stock (Show, Eq) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,7 +43,6 @@ import PlutusCore.Evaluation.ErrorWithCause | |
import PlutusCore.Evaluation.Result | ||
import PlutusCore.Pretty | ||
|
||
import Control.Monad.Except | ||
import Data.Either.Extras | ||
import Data.String | ||
import GHC.Exts (inline, oneShot) | ||
|
@@ -239,27 +238,17 @@ Lifting is allowed to the following classes of types: | |
one, and for another example define an instance for 'Void' in tests | ||
-} | ||
|
||
-- | Attach a @cause@ to a 'BuiltinError' and throw that. | ||
-- Note that an evaluator might require the cause to be computed lazily for best performance on the | ||
-- happy path, hence this function must not force its first argument. | ||
-- TODO: wrap @cause@ in 'Lazy' once we have it. | ||
throwBuiltinErrorWithCause | ||
:: (MonadError (ErrorWithCause err cause) m, AsUnliftingError err, AsEvaluationFailure err) | ||
=> cause -> BuiltinError -> m void | ||
throwBuiltinErrorWithCause cause = \case | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved it to |
||
BuiltinUnliftingError unlErr -> throwingWithCause _UnliftingError unlErr $ Just cause | ||
BuiltinEvaluationFailure -> throwingWithCause _EvaluationFailure () $ Just cause | ||
|
||
typeMismatchError | ||
:: PrettyParens (SomeTypeIn uni) | ||
=> uni (Esc a) | ||
-> uni (Esc b) | ||
-> UnliftingError | ||
typeMismatchError uniExp uniAct = fromString $ concat | ||
[ "Type mismatch: " | ||
, "expected: " ++ render (prettyBy botRenderContext $ SomeTypeIn uniExp) | ||
, "; actual: " ++ render (prettyBy botRenderContext $ SomeTypeIn uniAct) | ||
] | ||
-> UnliftingEvaluationError | ||
typeMismatchError uniExp uniAct = | ||
MkUnliftingEvaluationError . StructuralEvaluationError . fromString $ concat | ||
[ "Type mismatch: " | ||
, "expected: " ++ displayBy botRenderContext (SomeTypeIn uniExp) | ||
, "; actual: " ++ displayBy botRenderContext (SomeTypeIn uniAct) | ||
] | ||
-- Just for tidier Core to get generated, we don't care about performance here, since it's just a | ||
-- failure message and evaluation is about to be shut anyway. | ||
{-# NOINLINE typeMismatchError #-} | ||
|
@@ -291,7 +280,7 @@ readKnownConstant val = asConstant val >>= oneShot \case | |
-- optimize some of the matching away. | ||
case uniExp `geq` uniAct of | ||
Just Refl -> pure x | ||
Nothing -> throwing _UnliftingError $ typeMismatchError uniExp uniAct | ||
Nothing -> throwing _UnliftingEvaluationError $ typeMismatchError uniExp uniAct | ||
{-# INLINE readKnownConstant #-} | ||
|
||
-- See Note [Performance of ReadKnownIn and MakeKnownIn instances]. | ||
|
@@ -335,9 +324,7 @@ makeKnownOrFail x = case makeKnown x of | |
|
||
-- | Same as 'readKnown', but the cause of a potential failure is the provided term itself. | ||
readKnownSelf | ||
:: ( ReadKnown val a | ||
, AsUnliftingError err, AsEvaluationFailure err | ||
) | ||
:: (ReadKnown val a, AsUnliftingEvaluationError err, AsEvaluationFailure err) | ||
=> val -> Either (ErrorWithCause err val) a | ||
readKnownSelf val = fromRightM (throwBuiltinErrorWithCause val) $ readKnown val | ||
{-# INLINE readKnownSelf #-} | ||
|
@@ -361,7 +348,7 @@ instance | |
( TypeError ('Text "‘EvaluationResult’ cannot appear in the type of an argument") | ||
, uni ~ UniOf val | ||
) => ReadKnownIn uni val (EvaluationResult a) where | ||
readKnown _ = throwing _UnliftingError "Panic: 'TypeError' was bypassed" | ||
readKnown _ = throwing _StructuralUnliftingError "Panic: 'TypeError' was bypassed" | ||
-- Just for 'readKnown' not to appear in the generated Core. | ||
{-# INLINE readKnown #-} | ||
|
||
|
@@ -374,7 +361,7 @@ instance | |
( TypeError ('Text "‘Emitter’ cannot appear in the type of an argument") | ||
, uni ~ UniOf val | ||
) => ReadKnownIn uni val (Emitter a) where | ||
readKnown _ = throwing _UnliftingError "Panic: 'TypeError' was bypassed" | ||
readKnown _ = throwing _StructuralUnliftingError "Panic: 'TypeError' was bypassed" | ||
-- Just for 'readKnown' not to appear in the generated Core. | ||
{-# INLINE readKnown #-} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It now doesn't take a
proxy
argument, so that newtype- and via-deriving are available. The oldtoTypeAst
is now provided as a standalone function for backward compatibility.