futhark
futhark copied to clipboard
Improve type errors in the presence of type abbreviations
type foo = {x: i32, y: i32, z: i32}
type bar = {x: f32, y: f32, z: f32}
let f (x: foo) : bar = x
This produces the following error:
Function body does not have expected type.
Expected: {x: f32, y: f32, z: f32}
Actual: {x: i32, y: i32, z: i32}
Types
f32
and
i32
do not match.
When matching types of record field "x".
Not so bad in this case, but generally it can become quite confusing that the type checker will never use any type abbreviations when reporting type errors, but instead always use the fully expanded type. This should be fixed somehow.
Could this be extended to uses of :t
in futhark repl
? Type signatures without abbreviations can get pretty ridiculous sometimes.
Yeah, it would presumably be the same (yet-unknown) mechanism.
I will bump this with an example of how bad it can be:
Error at potential.fut:268:23-269:47:
Cannot apply "stackWith" to "(pointPairs pairs <> combinationNet)" (invalid type).
Expected: {add: p2₇₀ -> p2₇₀ -> p2₇₀,
parameter: p2₇₀,
propagation: p2₇₀ -> ((f32, f32, f32), {r: f32, v: (f32, f32, f32)})
-> (o2₇₃,
o2₇₃ -> (((f32, f32, f32),
{r: f32, v: (f32, f32, f32)}),
p2₇₀)),
scale: f32 -> p2₇₀ -> p2₇₀,
sum: (k: i64) -> [k]p2₇₀ -> p2₇₀,
zero: p2₇₀}
Actual: {add: ([m]((f32, f32, f32), (f32, f32, f32)),
(((((([m](), [n][m]f32), [n]()), [n][n]f32), [n]()), [n]f32),
())) -> ([m]((f32, f32, f32), (f32, f32, f32)),
(((((([m](), [n][m]f32), [n]()), [n][n]f32), [n]()),
[n]f32),
())) -> ([m]((f32, f32, f32), (f32, f32, f32)),
(((((([m](), [n][m]f32), [n]()),
[n][n]f32),
[n]()),
[n]f32),
())),
parameter: ([m]((f32, f32, f32), (f32, f32, f32)),
(((((([m](), [n][m]f32), [n]()), [n][n]f32), [n]()),
[n]f32),
())),
propagation: ([m]((f32, f32, f32), (f32, f32, f32)),
(((((([m](), [n][m]f32), [n]()), [n][n]f32), [n]()),
[n]f32),
())) -> ((f32, f32, f32),
((f32, f32, f32),
(f32, f32, f32),
(f32, f32, f32))) -> (f32,
f32 -> (((f32,
f32,
f32),
((f32,
f32,
f32),
(f32,
f32,
f32),
(f32,
f32,
f32))),
([m]((f32,
f32,
f32),
(f32,
f32,
f32)),
(((((([m](),
[n][m]f32),
[n]()),
[n][n]f32),
[n]()),
[n]f32),
())))),
scale: f32 -> ([m]((f32, f32, f32), (f32, f32, f32)),
(((((([m](), [n][m]f32), [n]()), [n][n]f32), [n]()),
[n]f32),
())) -> ([m]((f32, f32, f32), (f32, f32, f32)),
(((((([m](), [n][m]f32), [n]()), [n][n]f32),
[n]()),
[n]f32),
())),
sum: (k: i64) -> [k]([m]((f32, f32, f32), (f32, f32, f32)),
(((((([m](), [n][m]f32), [n]()), [n][n]f32),
[n]()),
[n]f32),
())) -> ([m]((f32, f32, f32), (f32, f32, f32)),
(((((([m](), [n][m]f32), [n]()),
[n][n]f32),
[n]()),
[n]f32),
())),
zero: ([m]((f32, f32, f32), (f32, f32, f32)),
(((((([m](), [n][m]f32), [n]()), [n][n]f32), [n]()), [n]f32),
()))}
Unshared fields: r, v, 0, 1, 2.
When matching types of record field "1".
When matching parameter types.
When matching return types.
When matching types of record field "propagation".
This is one of my neural networks. Something is wrong, but due to expansion of everything, it beomes rather difficult to see what. While this is no doubt worse than average, I've seen significantly longer signatures too.