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

Better errors for literal ranges in PlutusTx (PLT-8174) #5619

Merged
merged 37 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
cc2703e
WIP
kwxm Nov 2, 2023
f46e80b
Add PlutusTx.enumFromThenTo and tests
kwxm Nov 3, 2023
983f6cd
Remove range failure tests
kwxm Nov 3, 2023
9daed91
Generalise range syntax check to non-Integer types
kwxm Nov 3, 2023
62cc8fb
Extend enumFromThenTo tests
kwxm Nov 3, 2023
a4e3011
Extend enumFromThenTo tests
kwxm Nov 3, 2023
1af0087
Extend enumFromThenTo tests
kwxm Nov 3, 2023
acaa303
Restore missing test
kwxm Nov 3, 2023
094efa3
Restore missing comment
kwxm Nov 3, 2023
8b88ac9
Cover rewrite rules for enum ranges
kwxm Nov 3, 2023
b3f877d
Separate checks for finite and infinite ranges
kwxm Nov 4, 2023
ed1bb4d
Separate checks for finite and infinite ranges
kwxm Nov 4, 2023
50673bc
Improve tests involving possibly infinite lists
kwxm Nov 4, 2023
00f8844
Golden tests for literal range errors
kwxm Nov 5, 2023
8c17243
Amend comment
kwxm Nov 5, 2023
f6d1f1a
Really delete unwanted files
kwxm Nov 5, 2023
33421ed
Update comment
kwxm Nov 5, 2023
1188177
Delete plutus-tx-plugin/test/tmp/Main.hs
kwxm Nov 5, 2023
a04f3d8
Didn't want to commit those
kwxm Nov 5, 2023
1d87725
Merge branch 'kwxm/plugin/better-range-errors' of github.com:input-ou…
kwxm Nov 5, 2023
3122346
plutus-tx-tests -> plutus-tx-plugin-tests
kwxm Nov 5, 2023
7c2130b
Tidying up
kwxm Nov 5, 2023
699ebff
Efficiency improvements
kwxm Nov 6, 2023
beb3b52
Improve comment
kwxm Nov 9, 2023
2d41078
Add changelog entries
kwxm Nov 9, 2023
db2a12d
Merge branch 'master' into kwxm/plugin/better-range-errors
kwxm Nov 9, 2023
69d45d3
Remove redundant pragma
kwxm Nov 10, 2023
88c015d
Merge branch 'master' into kwxm/plugin/better-range-errors
kwxm Nov 14, 2023
a86d5c8
Update budget test results
kwxm Nov 14, 2023
fa4ef71
Restore -fplugin pragma in plutus-ledger-api test
kwxm Nov 14, 2023
e133bbe
Merge branch 'master' into kwxm/plugin/better-range-errors
kwxm Nov 14, 2023
fd46147
Merge branch 'master' into kwxm/plugin/better-range-errors
kwxm Nov 17, 2023
01fb753
Improve error messages
kwxm Nov 17, 2023
ef3e5b8
Improve error messages
kwxm Nov 17, 2023
465ddad
Update error messages in golden files
kwxm Nov 17, 2023
33d3787
Update error messages in golden files
kwxm Nov 17, 2023
2cc18fc
Merge branch 'master' into kwxm/plugin/better-range-errors
kwxm Nov 23, 2023
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
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
({cpu: 310936611
| mem: 1245566})
({cpu: 310959611
| mem: 1245666})
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
({cpu: 310775611
| mem: 1244866})
({cpu: 310798611
| mem: 1244966})
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Added

- A more informative error message when the plugin encounters a literal range.
2 changes: 1 addition & 1 deletion plutus-tx-plugin/plutus-tx-plugin.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ executable gen-plugin-opts-doc

default-language: Haskell2010

test-suite plutus-tx-tests
test-suite plutus-tx-plugin-tests
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I changed this because plutus-tx contains plutus-tx-test and I was getting very confused.

import: lang, ghc-version-support

if flag(use-ghc-stub)
Expand Down
48 changes: 47 additions & 1 deletion plutus-tx-plugin/src/PlutusTx/Compiler/Expr.hs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ import Control.Monad
import Control.Monad.Reader (ask)
import Data.Array qualified as Array
import Data.ByteString qualified as BS
import Data.List (elemIndex)
import Data.List (elemIndex, isPrefixOf, isSuffixOf)
import Data.Map qualified as Map
import Data.Set qualified as Set
import Data.Text qualified as T
Expand Down Expand Up @@ -228,6 +228,40 @@ isProbablyIntegerEq (GHC.getName -> n)
True
isProbablyIntegerEq _ = False

-- | Check for literal ranges like [1..9] and [1, 5..101]. This will also
-- return `True` if there's an explicit use of `enumFromTo` or similar.
isProbablyBoundedRange :: GHC.Id -> Bool
isProbablyBoundedRange (GHC.getName -> n)
| Just m <- GHC.nameModule_maybe n
, GHC.moduleNameString (GHC.moduleName m) == "GHC.Enum" =
("$fEnum" `isPrefixOf` methodName &&
( "_$cenumFromTo" `isSuffixOf` methodName -- [1..100]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there any better way of getting names of particular instances of methods like enumFromTo? This was the best I could do and I'm not sure how robust it will be. I suppose that if the names that GHC produces change then the tests will start to fail.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, this is too bad. I hadn't realized that GHC might specialize enumFromTo.

The answer to your question is, unfortunately, no. There's no way to prevent GHC from specializing a method. It is only possible to disable user written rules, not builtin rules.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure if we should match on the specialized name. I don't know if we can guarantee that that isn't an arbitrarily messed up version 🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

We pass some information about GHC names through to the compiler in NameInfo in the CompileContext. Then you can use getThing to get the TypedThing and getName on that to get the Name. See how the stuff in Builitns works.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We pass some information about GHC names through to the compiler in NameInfo in the CompileContext. Then you can use getThing to get the TypedThing and getName on that to get the Name. See how the stuff in Builitns works.

Maybe we can come back to this in a later PR. I've run out of JIRA points on this.

Copy link
Contributor Author

@kwxm kwxm Nov 17, 2023

Choose a reason for hiding this comment

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

I'm not sure if we should match on the specialized name. I don't know if we can guarantee that that isn't an arbitrarily messed up version 🤔

That's what I was asking about in my original comment. Can we actually get at the original name, especially after the inlining/rewriting? Is that what NameInfo is about?

Copy link
Contributor

Choose a reason for hiding this comment

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

No, NameInfo is just for getting an actual GHC Name instead of string matching. I'm not sure it will match up if it has in fact been specialized. I'm not sure what we do in other cases, perhaps we just fail to spot stuff 🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess it's not too bad since we're failing instead of silently compiling differently.

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess since this is inherently heuristic rather than matching a precise name there's no point doing the NameInfo stuff and this is fine.

|| "_$cenumFromThenTo" `isSuffixOf` methodName -- [1,3..100]
)
)
|| "enumDeltaToInteger" `isPrefixOf` methodName
-- ^ These are introduced by inlining for Integer ranges in
-- GHC.Enum. This also happens for Char, Word, and Int, but those types
-- aren't supported in Plutus Core.
where methodName = GHC.occNameString (GHC.nameOccName n)
isProbablyBoundedRange _ = False

-- | Check for literal ranges like [1..] and [1, 5..]. This will also return
-- `True` if there's an explicit use of `enumFrom` or similar.
isProbablyUnboundedRange :: GHC.Id -> Bool
isProbablyUnboundedRange (GHC.getName -> n)
| Just m <- GHC.nameModule_maybe n
, GHC.moduleNameString (GHC.moduleName m) == "GHC.Enum" =
("$fEnum" `isPrefixOf` methodName &&
( "_$cenumFrom" `isSuffixOf` methodName -- [1..]
|| "_$cenumFromThen" `isSuffixOf` methodName -- [1,3..]
)
)
|| "enumDeltaInteger" `isPrefixOf` methodName -- Introduced by inlining
where methodName = GHC.occNameString (GHC.nameOccName n)
isProbablyUnboundedRange _ = False


{- Note [GHC runtime errors]
GHC has a number of runtime errors for things like pattern matching failures and so on.

Expand Down Expand Up @@ -730,6 +764,18 @@ compileExpr e = traceCompilation 2 ("Compiling expr:" GHC.<+> GHC.ppr e) $ do
GHC.Var n
| isProbablyBytestringEq n ->
throwPlain $ UnsupportedError "Use of Haskell ByteString equality, possibly via the Haskell Eq typeclass"
GHC.Var n
-- Try to produce a sensible error message if a range like [1..9] is encountered. This works
-- by looking for occurrences of GHC.Enum.enumFromTo and similar functions; the same error
-- occurs if these functions are used explicitly.
| isProbablyBoundedRange n ->
throwPlain $ UnsupportedError $ T.pack ("Use of enumFromTo or enumFromThenTo, possibly via range syntax. " ++
"Please use PlutusTx.Enum.enumFromTo or PlutusTx.Enum.enumFromThenTo instead.")
-- Throw an error if we find an infinite range like [1..]
GHC.Var n
| isProbablyUnboundedRange n ->
throwPlain $ UnsupportedError $ T.pack ("Use of enumFrom or enumFromThen, possibly via range syntax. " ++
"Unbounded ranges are not supported.")
-- locally bound vars
GHC.Var (lookupName scope . GHC.getName -> Just var) -> pure $ PIR.mkVar annMayInline var
-- Special kinds of id
Expand Down
6 changes: 3 additions & 3 deletions plutus-tx-plugin/test/Budget/9.2/show.pir.golden
Original file line number Diff line number Diff line change
Expand Up @@ -200,12 +200,12 @@ let
in
letrec
!`$fEnumBool_$cenumFromTo` : integer -> integer -> List integer
= \(x : integer) (y : integer) ->
= \(x : integer) (lim : integer) ->
Copy link
Contributor Author

Choose a reason for hiding this comment

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

See later for an explanation of why all of these have changed.

ifThenElse
{all dead. List integer}
(lessThanEqualsInteger x y)
(lessThanEqualsInteger x lim)
(/\dead ->
Cons {integer} x (`$fEnumBool_$cenumFromTo` (addInteger 1 x) y))
Cons {integer} x (`$fEnumBool_$cenumFromTo` (addInteger 1 x) lim))
(/\dead -> Nil {integer})
{all dead. dead}
in
Expand Down
6 changes: 3 additions & 3 deletions plutus-tx-plugin/test/Budget/9.2/show.uplc.golden
Original file line number Diff line number Diff line change
Expand Up @@ -256,16 +256,16 @@ program
, ws ]) ]))))) ])))
(delay (\x -> x))))
(fix1
(\`$fEnumBool_$cenumFromTo` x y ->
(\`$fEnumBool_$cenumFromTo` x lim ->
force
(force ifThenElse
(lessThanEqualsInteger x y)
(lessThanEqualsInteger x lim)
(delay
(constr 1
[ x
, (`$fEnumBool_$cenumFromTo`
(addInteger 1 x)
y) ]))
lim) ]))
(delay (constr 0 []))))))
-1234567890)
(fix1
Expand Down
6 changes: 3 additions & 3 deletions plutus-tx-plugin/test/Budget/9.2/sumL.pir.golden
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ letrec
in
letrec
!`$fEnumBool_$cenumFromTo` : integer -> integer -> List integer
= \(x : integer) (y : integer) ->
= \(x : integer) (lim : integer) ->
ifThenElse
{all dead. List integer}
(lessThanEqualsInteger x y)
(lessThanEqualsInteger x lim)
(/\dead ->
Cons {integer} x (`$fEnumBool_$cenumFromTo` (addInteger 1 x) y))
Cons {integer} x (`$fEnumBool_$cenumFromTo` (addInteger 1 x) lim))
(/\dead -> Nil {integer})
{all dead. dead}
in
Expand Down
8 changes: 5 additions & 3 deletions plutus-tx-plugin/test/Budget/9.2/sumL.uplc.golden
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ program
(\go ->
(\ls -> go 0 ls)
(fix1
(\`$fEnumBool_$cenumFromTo` x y ->
(\`$fEnumBool_$cenumFromTo` x lim ->
force
(force ifThenElse
(lessThanEqualsInteger x y)
(lessThanEqualsInteger x lim)
(delay
(constr 1
[ x
, (`$fEnumBool_$cenumFromTo` (addInteger 1 x) y) ]))
, (`$fEnumBool_$cenumFromTo`
(addInteger 1 x)
lim) ]))
(delay (constr 0 []))))
1
1000))
Expand Down
6 changes: 3 additions & 3 deletions plutus-tx-plugin/test/Budget/9.2/sumR.pir.golden
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ letrec
in
letrec
!`$fEnumBool_$cenumFromTo` : integer -> integer -> List integer
= \(x : integer) (y : integer) ->
= \(x : integer) (lim : integer) ->
ifThenElse
{all dead. List integer}
(lessThanEqualsInteger x y)
(lessThanEqualsInteger x lim)
(/\dead ->
Cons {integer} x (`$fEnumBool_$cenumFromTo` (addInteger 1 x) y))
Cons {integer} x (`$fEnumBool_$cenumFromTo` (addInteger 1 x) lim))
(/\dead -> Nil {integer})
{all dead. dead}
in
Expand Down
6 changes: 3 additions & 3 deletions plutus-tx-plugin/test/Budget/9.2/sumR.uplc.golden
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ program
(\go ds ->
force (case ds [(delay 0), (\x xs -> delay (addInteger x (go xs)))]))
(fix1
(\`$fEnumBool_$cenumFromTo` x y ->
(\`$fEnumBool_$cenumFromTo` x lim ->
force
(force ifThenElse
(lessThanEqualsInteger x y)
(lessThanEqualsInteger x lim)
(delay
(constr 1
[x, (`$fEnumBool_$cenumFromTo` (addInteger 1 x) y)]))
[x, (`$fEnumBool_$cenumFromTo` (addInteger 1 x) lim)]))
(delay (constr 0 []))))
1
1000))
Expand Down
6 changes: 3 additions & 3 deletions plutus-tx-plugin/test/Budget/9.6/show.pir.golden
Original file line number Diff line number Diff line change
Expand Up @@ -200,12 +200,12 @@ let
in
letrec
!`$fEnumBool_$cenumFromTo` : integer -> integer -> List integer
= \(x : integer) (y : integer) ->
= \(x : integer) (lim : integer) ->
ifThenElse
{all dead. List integer}
(lessThanEqualsInteger x y)
(lessThanEqualsInteger x lim)
(/\dead ->
Cons {integer} x (`$fEnumBool_$cenumFromTo` (addInteger 1 x) y))
Cons {integer} x (`$fEnumBool_$cenumFromTo` (addInteger 1 x) lim))
(/\dead -> Nil {integer})
{all dead. dead}
in
Expand Down
6 changes: 3 additions & 3 deletions plutus-tx-plugin/test/Budget/9.6/show.uplc.golden
Original file line number Diff line number Diff line change
Expand Up @@ -254,16 +254,16 @@ program
, ws ]) ]))))) ])))
(delay (\x -> x))))
(fix1
(\`$fEnumBool_$cenumFromTo` x y ->
(\`$fEnumBool_$cenumFromTo` x lim ->
force
(force ifThenElse
(lessThanEqualsInteger x y)
(lessThanEqualsInteger x lim)
(delay
(constr 1
[ x
, (`$fEnumBool_$cenumFromTo`
(addInteger 1 x)
y) ]))
lim) ]))
(delay (constr 0 []))))))
-1234567890)
(fix1
Expand Down
6 changes: 3 additions & 3 deletions plutus-tx-plugin/test/Budget/9.6/sumL.pir.golden
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ letrec
in
letrec
!`$fEnumBool_$cenumFromTo` : integer -> integer -> List integer
= \(x : integer) (y : integer) ->
= \(x : integer) (lim : integer) ->
ifThenElse
{all dead. List integer}
(lessThanEqualsInteger x y)
(lessThanEqualsInteger x lim)
(/\dead ->
Cons {integer} x (`$fEnumBool_$cenumFromTo` (addInteger 1 x) y))
Cons {integer} x (`$fEnumBool_$cenumFromTo` (addInteger 1 x) lim))
(/\dead -> Nil {integer})
{all dead. dead}
in
Expand Down
8 changes: 5 additions & 3 deletions plutus-tx-plugin/test/Budget/9.6/sumL.uplc.golden
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ program
(\go ->
(\ls -> go 0 ls)
(fix1
(\`$fEnumBool_$cenumFromTo` x y ->
(\`$fEnumBool_$cenumFromTo` x lim ->
force
(force ifThenElse
(lessThanEqualsInteger x y)
(lessThanEqualsInteger x lim)
(delay
(constr 1
[ x
, (`$fEnumBool_$cenumFromTo` (addInteger 1 x) y) ]))
, (`$fEnumBool_$cenumFromTo`
(addInteger 1 x)
lim) ]))
(delay (constr 0 []))))
1
1000))
Expand Down
6 changes: 3 additions & 3 deletions plutus-tx-plugin/test/Budget/9.6/sumR.pir.golden
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ letrec
in
letrec
!`$fEnumBool_$cenumFromTo` : integer -> integer -> List integer
= \(x : integer) (y : integer) ->
= \(x : integer) (lim : integer) ->
ifThenElse
{all dead. List integer}
(lessThanEqualsInteger x y)
(lessThanEqualsInteger x lim)
(/\dead ->
Cons {integer} x (`$fEnumBool_$cenumFromTo` (addInteger 1 x) y))
Cons {integer} x (`$fEnumBool_$cenumFromTo` (addInteger 1 x) lim))
(/\dead -> Nil {integer})
{all dead. dead}
in
Expand Down
6 changes: 3 additions & 3 deletions plutus-tx-plugin/test/Budget/9.6/sumR.uplc.golden
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ program
(\go ds ->
force (case ds [(delay 0), (\x xs -> delay (addInteger x (go xs)))]))
(fix1
(\`$fEnumBool_$cenumFromTo` x y ->
(\`$fEnumBool_$cenumFromTo` x lim ->
force
(force ifThenElse
(lessThanEqualsInteger x y)
(lessThanEqualsInteger x lim)
(delay
(constr 1
[x, (`$fEnumBool_$cenumFromTo` (addInteger 1 x) y)]))
[x, (`$fEnumBool_$cenumFromTo` (addInteger 1 x) lim)]))
(delay (constr 0 []))))
1
1000))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Error: Unsupported feature: Use of enumFrom or enumFromThen, possibly via range syntax. Unbounded ranges are not supported.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Error: Unsupported feature: Use of enumFrom or enumFromThen, possibly via range syntax. Unbounded ranges are not supported.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Error: Unsupported feature: Use of enumFromTo or enumFromThenTo, possibly via range syntax. Please use PlutusTx.Enum.enumFromTo or PlutusTx.Enum.enumFromThenTo instead.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Error: Unsupported feature: Use of enumFromTo or enumFromThenTo, possibly via range syntax. Please use PlutusTx.Enum.enumFromTo or PlutusTx.Enum.enumFromThenTo instead.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Error: Unsupported feature: Infinite ranges are not supported
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Error: Unsupported feature: Infinite ranges are not supported
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Error: Unsupported feature: Literal ranges are not supported: please use PlutusTx.Enum.enumFromTo or PlutusTx.Enum.enumFromThenTo
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Error: Unsupported feature: Literal ranges are not supported: please use PlutusTx.Enum.enumFromTo or PlutusTx.Enum.enumFromThenTo
50 changes: 34 additions & 16 deletions plutus-tx-plugin/test/Plugin/Errors/Spec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ module Plugin.Errors.Spec where

import Test.Tasty.Extras

import PlutusCore.Test
import PlutusCore.Test (goldenUPlc)
import PlutusTx.Builtins qualified as Builtins
import PlutusTx.Code
import PlutusTx.Plugin
import PlutusTx.Code (CompiledCode)
import PlutusTx.Plugin.Utils (plc)
import PlutusTx.Test ()

import Data.Proxy
Expand All @@ -33,19 +33,23 @@ import GHC.Num.Integer
{- HLINT ignore -}

errors :: TestNested
errors = testNestedGhc "Errors" [
goldenUPlc "machInt" machInt
-- FIXME: This fails differently in nix, possibly due to slightly different optimization settings
-- , goldenPlc "negativeInt" negativeInt
, goldenUPlc "caseInt" caseInt
, goldenUPlc "stringLiteral" stringLiteral
, goldenUPlc "recursiveNewtype" recursiveNewtype
, goldenUPlc "mutualRecursionUnfoldingsLocal" mutualRecursionUnfoldingsLocal
, goldenUPlc "literalCaseInt" literalCaseInt
, goldenUPlc "literalCaseBs" literalCaseBs
, goldenUPlc "literalAppendBs" literalAppendBs
, goldenUPlc "literalCaseOther" literalCaseOther
]
errors = testNestedGhc "Errors"
[ goldenUPlc "machInt" machInt
-- FIXME: This fails differently in nix, possibly due to slightly different optimization settings
-- , goldenPlc "negativeInt" negativeInt
, goldenUPlc "caseInt" caseInt
, goldenUPlc "stringLiteral" stringLiteral
, goldenUPlc "recursiveNewtype" recursiveNewtype
, goldenUPlc "mutualRecursionUnfoldingsLocal" mutualRecursionUnfoldingsLocal
, goldenUPlc "literalCaseInt" literalCaseInt
, goldenUPlc "literalCaseBs" literalCaseBs
, goldenUPlc "literalAppendBs" literalAppendBs
, goldenUPlc "literalCaseOther" literalCaseOther
, goldenUPlc "rangeEnumFromTo" rangeEnumFromTo
, goldenUPlc "rangeEnumFromThenTo" rangeEnumFromThenTo
, goldenUPlc "rangeEnumFrom" rangeEnumFrom
, goldenUPlc "rangeEnumFromThen" rangeEnumFromThen
]

machInt :: CompiledCode Int
machInt = plc (Proxy @"machInt") (1::Int)
Expand Down Expand Up @@ -95,3 +99,17 @@ instance Eq AType where

literalCaseOther :: CompiledCode (AType -> AType)
literalCaseOther = plc (Proxy @"literalCaseOther") (\x -> case x of { "abc" -> ""; x -> x})

-- Tests for literal ranges (and the corresponding methods in GHC.Enum). These
-- should all fail with informative error messages.
rangeEnumFromTo :: CompiledCode [Integer]
Copy link
Member

Choose a reason for hiding this comment

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

Nice tests.

rangeEnumFromTo = plc (Proxy @"rangeEnumFromTo") [1..50]

rangeEnumFromThenTo :: CompiledCode [Integer]
rangeEnumFromThenTo = plc (Proxy @"rangeEnumFromThenTo") [1,7..50]

rangeEnumFrom :: CompiledCode [Integer]
rangeEnumFrom = plc (Proxy @"rangeEnumFrom") [1..]

rangeEnumFromThen :: CompiledCode [Integer]
rangeEnumFromThen = plc (Proxy @"rangeEnumFromThen") [1,5..]
Loading