idris-lang / Idris2

A purely functional programming language with first class types
https://idris-lang.org/
Other
2.46k stars 368 forks source link

Type checker does not terminate when comparing codata types. #3209

Open yellowsquid opened 5 months ago

yellowsquid commented 5 months ago

Uncommenting oops or uhOh and then type checking causes Idris to loop indefinitely.

index : Nat -> Stream a -> a
index 0     (x :: xs) = x
index (S k) (x :: xs) = index k xs

iterate : (a -> a) -> a -> Stream a
iterate f x = x :: iterate f (f x)

Pred : Type
Pred = Type

fix : (Pred -> Pred) -> Pred
fix f = (n ** index n (iterate f Void))

oops : {n : Nat} -> index n (iterate f Void) -> fix f
-- oops {n} prf = (n ** prf)

uhOh : {n : Nat} -> index n (iterate f ()) -> index n (iterate f Void)
-- uhOh prf = prf

Environment

Idris commit: d34cf6261

Steps to Reproduce

  1. Type check the snippet.
  2. Uncomment the definition of oops.
  3. Type check the snippet again.
  4. Uncomment the definition of uhOh.
  5. Type check the snippet one last time.

Expected Behavior

Idris should accept the program as correct after uncommenting oops. It should provide a type error when uncommenting uhOh.

Observed Behavior

Idris will enter a seemingly infinite loop when uncommenting either definition.

Further Details

Idris works correctly for oops if you inline either Pred or fix.

The problem remains for oops if you:

No changes I have tried have caused uhOh to terminate.

buzden commented 5 months ago

Is this #964?

yellowsquid commented 5 months ago

Yes, but the bug when things don't unify seems to be a new observation. Feel free to close this as a duplicate and I'll update the original issue.