Client crash on materializing zero-arity operator (ArrayIndexOutOfBoundsException)
narwhalfire opened this issue ยท 7 comments
Issue type:
- ๐ Bug
Short description:
I have a chain of operators and one of them in the chain ends up with a signature of -> Operator
according to the materailizer. When I materialized a card based on this, the client crashed trying to render what I think was the tool tip.
Steps to reproduce the problem:
Construct variable cards based on the following Haskell code:
type NBT = String
type Item = String
-- implement integrated dynamics operators --
pipe :: (a -> b) -> (b -> c) -> (a -> c)
pipe = flip (.)
pipe2 :: (a -> b) -> (a -> c) -> (b -> c -> d) -> (a -> d)
pipe2 f g h = \x -> h (f x) (g x)
apply :: (a -> b) -> a -> b
apply f x = f x
apply2 :: (a -> b -> c) -> a -> b -> c
apply2 f x y = f x y
apply3 :: (a -> b -> c -> d) -> a -> b -> c -> d
apply3 f x y z = f x y z
-- materialized operators confirmed to work, implementation here not important --
getBloodAltarAmount :: NBT -> Int
getBloodAltarAmount _ = 0
areItemsEmpty :: NBT -> Bool
areItemsEmpty _ = True
eqNoNBT :: Item -> Item -> Bool
eqNoNBT _ _ = True
-- variable card chain --
t1 = pipe getBloodAltarAmount (>)
t2 = flip t1
t3 = pipe t2 pipe2
t4 = flip t3
t5 = pipe t4 flip
t6 = apply2 t5 areItemsEmpty (&&) -- materializes to -> Op
t7 = pipe t6 pipe -- crash when rendering the tool tip of the materialized card
t8 = flip t7
t9 = apply t8 (&&)
t10 = pipe eqNoNBT pipe
t11 = flip t10
t12 = pipe t9 flip
t13 = flip t12
t14 = apply t11 t13
t15 = pipe t14 flip
t16 = pipe t15 pipe
t17 = flip t16
t18 = apply t17 flip
t19 = flip t18
t20 = pipe t19 flip
t21 = flip t20
Expected behaviour:
I was using the above code to help me combine operators to get from a few operators to one with a desired type signature.
Given:
getBloodAltarAmount :: NBT -> Int
areItemsEmpty :: NBT -> Bool
eqNoNBT :: Item -> Item -> Bool
&& :: Bool -> Bool -> Bool
> :: Int -> Int -> Bool
Target:
NBT -> Int -> Item -> Item -> Bool
Running in ghci:
> :t t21
t21 :: NBT -> Int -> Item -> Item -> Bool
> :t t6
t6 :: Int -> NBT -> Bool
Other notes:
I also tried just materializing t21 with the full chain unmaterialized and got an error presumably related to #352
I'm trying to get an operator with a signature of NBT -> Int -> Item -> Item -> Bool
so I can have it materialized to just one variable card and apply the NBT of my altar, the blood amount I want, and the item I want to result in a predicate, Item -> Bool
. The goal of the predicate is that it returns true if the given item matches an item in an item frame, the altar has greater than a specified amount of blood, and there are no items in it. I'm not really sure how to avoid the problem of #352 since half of this was trial and error with getting the right type siganture out of haskell.
Versions:
This mod:
1.12.2-1.0.11 (Dynamics),
1.12.2-1.6.8 (Tunnels)
Minecraft: 1.12.2
Forge: 14.23.5.2838
Pack: FTB:Interactions 1.9.1
Launcher: MultiMC 0.6.5-1302
Log file:
You seem to be running a couple of versions behind. Could you check if the issue still persists on the latest ID version?
Just confirmed this to still persist in ID 1.12.2-1.0.16. Recreated the variable card chain up to t7 exactly.
https://pastebin.com/DvEjqEDQ
Pastebin
I just tried reproducing this after the fix of #754, and everything seems to be working properly.
@narwhalfire Could you try out the latest dev build if that fix indeed resolves the problem on your end as well?
The flip
operator probably needs to perform a check to see if an arity-1 operator that it received returns another operator when applied. The flip
operator should still be able to execute, in that case.
It might be a good idea to go through and find any other instances where an operator strictly depends on the actual/unexpanded arity of an operator that it receives as an argument. I can't think of any off the top of my head, though; there really aren't that many combinational operators.
Edit: Perhaps the third argument of pipe2
? It's a little hard to follow how that operator is implemented in the source. I know that argument must be an operator of at least arity-2.
Edie: Nevermind, I see. Pipe.pipeVariablesToOperators
is pulling double duty for both pipe
and pipe2
.
Cool, yeah looks like that fixed the crash as t7 :: Int -> (Bool -> c) -> NBT -> c
materializes to Number -> Operator -> Operator
.
Unfortunately t8 :: (Bool -> c) -> Int -> NBT -> c
materializes to Any -> Any
which may or may not be related to an error with t13 down the line.
t13 errors with The operator Flip received the operator Piped Operator with input length 1 while length 2 is required.
while t12 should be Int -> Bool -> NBT -> Bool
but materializes to Any -> Any
as well. But I think that's an entirely different issue.
Great! I'm closing this issue then.
@narwhalfire Could you open up a new issue for the flip
problem you are experiencing (if possible, with a more minimal example)?