futhark icon indicating copy to clipboard operation
futhark copied to clipboard

Improve type errors in the presence of type abbreviations

Open athas opened this issue 4 years ago • 3 comments

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.

athas avatar Jul 04 '20 10:07 athas

Could this be extended to uses of :t in futhark repl? Type signatures without abbreviations can get pretty ridiculous sometimes.

FluxusMagna avatar Aug 18 '20 23:08 FluxusMagna

Yeah, it would presumably be the same (yet-unknown) mechanism.

athas avatar Aug 19 '20 05:08 athas

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.

FluxusMagna avatar Oct 26 '22 14:10 FluxusMagna