pyret-lang
pyret-lang copied to clipboard
type-checker internal error?
data NeLoN:
| one(n :: Number)
| more(n :: Number, r :: NeLoN)
end
fun ra-to-nelon(r :: RawArray<Number>) -> NeLoN:
len = raw-array-length(r)
fun make-from-index(n :: Number):
v = raw-array-get(r, n)
if n == (len - 1):
one(v)
else:
more(v, make-from-index(n + 1))
end
end
make-from-index(0)
end
nelon = {
make0: {(): raise("can't make an empty NeLoN")},
make1: {(a1 :: Number): one(a1)},
make2: {(a1 :: Number, a2 :: Number): more(a1, one(a2))},
make3: {(a1 :: Number, a2 :: Number, a3 :: Number): more(a1, more(a2, one(a3)))},
make4: {(a1 :: Number, a2 :: Number, a3 :: Number, a4 :: Number): more(a1, more(a2, more(a3, one(a4))))},
make5: {(a1 :: Number, a2 :: Number, a3 :: Number, a4 :: Number, a5 :: Number): more(a1, more(a2, more(a3, more(a4, one(a5)))))},
make: {(args :: RawArray<Number>): ra-to-nelon(args)} }

Given that there's no cases anywhere in my code, I have to assume this is something internal… (or a desugaring that I can't identify).
Definitely a bug as you say. This is hitting a bad case in object inference somewhere. Dumb workaround so you can make progress if you want:
data NeLoN:
| one(n :: Number)
| more(n :: Number, r :: NeLoN)
end
fun ra-to-nelon(r :: RawArray<Number>) -> NeLoN:
len = raw-array-length(r)
fun make-from-index(n :: Number):
v = raw-array-get(r, n)
if n == (len - 1):
one(v)
else:
more(v, make-from-index(n + 1))
end
end
make-from-index(0)
end
type Maker<A, B> = {
make0 :: ( -> B),
make1 :: (A -> B),
make2 :: (A, A -> B),
make3 :: (A, A, A -> B),
make4 :: (A, A, A, A -> B),
make5 :: (A, A, A, A, A -> B),
make :: (RawArray<A> -> B)
}
nelon :: Maker<Number, NeLoN> = {
make0: {(): raise("can't make an empty NeLoN")},
make1: {(a1 :: Number): one(a1)},
make2: {(a1 :: Number, a2 :: Number): more(a1, one(a2))},
make3: {(a1 :: Number, a2 :: Number, a3 :: Number): more(a1, more(a2, one(a3)))},
make4: {(a1 :: Number, a2 :: Number, a3 :: Number, a4 :: Number): more(a1, more(a2, more(a3, one(a4))))},
make5: {(a1 :: Number, a2 :: Number, a3 :: Number, a4 :: Number, a5 :: Number): more(a1, more(a2, more(a3, more(a4, one(a5)))))},
make: {(args :: RawArray<Number>): ra-to-nelon(args)}
}
(Note that it's hard to make Maker as polymorphic as one might want if you had a polymorphic list, but this is an accurate type here)
I also reduced the test to:
o = { m: {(): raise("something") } }
(Which is context-independent)
So this is probably a bad use of bot in constraint solving for fields to track down.
Also, in case @blerner or someone else picks this up, I can't make this fail at the CLI, it builds fine across several different choices of context.
Actually, it wasn't that. We had never written a test with an inferred t-bot that got provided out of a module in typed mode. (Using CPO had an implicit provide * that triggered that path)
Interestingly, it's not necessarily great for make0 to have that inferred type.
Regression test added and fixed by 4844404d4 on horizon, will go out in next deploy with some other fixes, soon.
Also, someone should probably make it so we can type-check the compiler.