[MLton] A little bug

Matthew Fluet fluet@cs.cornell.edu
Thu, 10 Nov 2005 17:16:12 -0500 (EST)


> I attached a tgz file containing a little SML program bug.sml and a data
> file data.  This is what happens when I try out mlton.
>
> mlton bug.sml
> Type error: SSa2.TypeCheck2.coerce
> {from = ((word8) vector * IntInf.int), to = ((word8) vector * IntInf.int 
> ref)}
> Type error: analyze raised exception unhandled exception: TypeError
>
> unhandled exception: TypeError
>
> To me this looks like a bug.

>From fluet@lion.cs.cornell.edu Thu Nov 10 17:10:29 2005
Newsgroups: 
Date: Thu, 10 Nov 2005 17:10:29 -0500 (EST)
From: Matthew Fluet <fluet@lion.cs.cornell.edu>
To: varming@itu.dk
cc: MLton@mlton.org, mael@itu.dk, Stephen Weeks <sweeks@sweeks.com>
Subject: Re: [MLton] A little bug
Fcc: sent-mail
In-Reply-To: <Pine.LNX.4.64.0511101556580.9594@adm1-8.itu.dk>
Message-ID: <Pine.LNX.4.62.0511101658030.2281@lion.cs.cornell.edu>
References: <Pine.LNX.4.64.0511101556580.9594@adm1-8.itu.dk>
X-Reply-UID: (2 > )(1 1120659869 37147)/var/spool/mail/fluet
X-Reply-Mbox: inbox
X-Our-ReplyTo: Empty
X-Our-Headers: Reply-to
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed


> I attached a tgz file containing a little SML program bug.sml and a data
> file data.  This is what happens when I try out mlton.
>
> mlton bug.sml
> Type error: SSa2.TypeCheck2.coerce
> {from = ((word8) vector * IntInf.int), to = ((word8) vector * IntInf.int 
> ref)}
> Type error: analyze raised exception unhandled exception: TypeError
>
> unhandled exception: TypeError
>
> To me this looks like a bug.

Indeed, also a bug.  While the pass that manifests the bug is refFlatten, 
it turns out that the actual bug is in the SSA2 shrinker.  Here's the 
portion of the SSA2 IL for your program that manifests the bug:

Before refFlatten:

   L_719 (x_1436: list_8, x_1429: ((word8) vector * IntInf.int),
          x_1431: list_6)
     x_1967: IntInf.int = #1 x_1429
     x_1968: (word8) vector = #0 x_1429
     case x_1431 of
       nil_6 => L_721 | ::_10 => L_720
   L_721 ()
     x_1432: (IntInf.int ref) = (x_1967)
     x_1433: ((word8) vector * (IntInf.int ref)) = (x_1968, x_1432)
     x_1434: ::_10 of (list_6 * ((word8) vector * (IntInf.int ref)))
       = ::_10 (global_40,x_1433)
     x_1435: list_6 = x_1434: list_6
     case x_1431 of
       nil_6 => L_723 | ::_10 => L_722

After refFlatten, before shrinker:

   L_719 (x_1436: list_8, x_1429: ((word8) vector * IntInf.int),
          x_1431: list_6)
     x_1967: IntInf.int = #1 x_1429
     x_1968: (word8) vector = #0 x_1429
     case x_1431 of
       nil_6 => L_721 | ::_10 => L_720
   L_721 ()
     x_1433: ((word8) vector * IntInf.int ref) = (x_1968, x_1967)
     x_1434: ::_10 of (list_6 * ((word8) vector * IntInf.int ref))
       = ::_10 (global_40,x_1433)
     x_1435: list_6 = x_1434: list_6
     case x_1431 of
       nil_6 => L_723 | ::_10 => L_722

After shrinker:

   L_719 (x_1436: list_8, x_1429: ((word8) vector * IntInf.int),
          x_1431: list_6)
     x_1967: IntInf.int = #1 x_1429
     x_1968: (word8) vector = #0 x_1429
     case x_1431 of
       nil_6 => L_721 | ::_10 => L_720
   L_721 ()
     x_1434: ::_10 of (list_6 * ((word8) vector * IntInf.int ref))
       = ::_10 (global_40,x_1429)
     x_1435: list_6 = x_1434: list_6
     case x_1431 of
       nil_6 => L_723 | ::_10 => L_722

The problem is that the tuple (re)construction optimization in the SSA2 
shrinker should not occur when either the newly constructed tuple or the 
original tuple contains mutable fields.

Certainly, we should not attempt to use a tuple with different mutability 
in the fields, since that leads to a type error.  Even if the original 
tuple and the reconstructed tuple have the same type, we should not reuse 
the original tuple, since that would give rise to unwanted sharing.

It's probably all of a 2 or 3 line fix to the shrinker.  I'll try to get 
it in later this evening, but anyone else should feel free to take it in 
the meantime.