[MLton] commit r4082: fixed bug in flexible record type inference

Stephen Weeks sweeks@mlton.org
Thu, 8 Sep 2005 22:50:17 -0700


The bug was tickled by the following program.

  val g = fn {...} => ()
  and h = fn () => ()
  val () = (h (); g {a = 13})

The bug showed as an IL type error indicating that "h" was applied to
the wrong number of type arguments.  The problem was that the
declaration of "h" expected one type argument but the application had
none.

The extra type variable arises because of the generalized flexrecord
in the type of g (note that the bug goes away without the "and").  The
bug was that type variable was not instantiated at the use of "h"
because the genflex did not occur in the type of h.  Prior to r3799,
this would have raised an internal bug message ("missing flexInst"),
and indeed this is what happens if you run MLton 20041109 on the
example.  However, in r3799, we removed the bug message and replaced
it with code that would silently continue, under the mistaken
impression that any genflexrecord must have had an instance, or the
user code must have already shown a type error.  This fix missed
exactly the case above.

The correct fix is to instantiate *all* genflexrecords that occur in
any type in the declaration, whether or not they actually occur in the
type of the function.  In the simple case above, that means that h
does get the extra type argument (unit) corresponding to the flexible
record field "a" in the argument to "g".

This fix also handles the problem that led to r3799, because the
missing flexinst will still be silently instantiated.

As a side note, only Poly/ML and MLton are able to infer the simple
example above.  Hamlet, Moscow ML, ML Kit, and SML/NJ all report
unresolved flexible record types.


----------------------------------------------------------------------

U   mlton/trunk/doc/changelog
U   mlton/trunk/mlton/elaborate/type-env.fun
U   mlton/trunk/regression/flexrecord.sml