;; The widening thunk is memoised per signature, and the key is the types. ;; ;; It used to be a *name*, derived from mangle_ty, which flattens a whole ;; signature into one hyphen-joined string and loses arity and every type ;; boundary with it: (CFn [(Ptr i32)] i32) and (CFn [ptr i32] i32) — the ;; second over a struct someone called ptr — both flatten to the same thing. ;; Keyed on that, the second widening reuses the first's thunk and calls it ;; with the wrong arity, which both backends compile without a word and ;; neither runs. This program is that pair, and it prints 5 and 17. ;; ;; A struct named ptr is legal and ordinary; nothing about the collision ;; needed a program written to provoke it, only two signatures that happened ;; to flatten alike. (defstruct ptr [a i32 b i32]) (defn f1 [p (Ptr i32)] i32 (deref p)) (defn f2 [a ptr b i32] i32 (+ (.a a) b)) (defn use1 [f (Fn [(Ptr i32)] i32)] i32 (let [x 5] (f (addr x)))) (defn use2 [f (Fn [ptr i32] i32)] i32 (f (ptr {.a 10 .b 0}) 7)) (defn main [] i32 (println (use1 f1)) (println (use2 f2)) 0)