proposal: add 'unsafeCoerce'

John Meacham john at repetae.net
Mon Nov 27 23:04:54 EST 2006


On Mon, Nov 20, 2006 at 02:45:13PM +0000, Malcolm Wallace wrote:
> Simon Marlow <simonmarhaskell at gmail.com> wrote:
>
> > >>Now, can we say something portable about these uses?
> >
> > I'd like to have a precise (sound, if not complete) description of
> > when it's safe to use unsafeCoerce in GHC, but it needs some careful
> > thought.
>
> And not just GHC.  I think all the points you mention (below) would be
> entirely reasonable for all implementations.
>
> >   * cast that changes a phantom type, or changes a type that is not
> >     reflected by a part of the value,
> >     eg. 'unsafeCoerce (Left 3) :: Either Int a' should be fine for any
> >     'a',
> >
> >   * casting a polymorphic type to the actual type of the runtime value.
> >     That is, you can safely cast a value to its correct type.  (eg. in
> >     Typeable.cast).
> >
> >   * casting an unboxed type to another unboxed type of the same size.
>
> There is one more important use case you haven't mentioned:
>
>     * casting from a newtype to the contained value (or vice versa).
>
> This latter type of cast is the only one I can remember ever having used
> myself.

there are very few safe uses of unsafeCoerce in jhc. the only ones
guarenteed safe are

 * casting a recursive newtype to its representation and back (note,
   recursive newtypes are chosen via a loop-breaking algorithm in the
   compiler, so it is best to let it worry about this)
 * casting arbitrary values of kind * to a system provided type 'Box'
   and back again
 * casting arbitrary values of kind ! (the kind of strict boxed values)
   to a system provided type 'BoxBang' and back again
 * values may not ever be cast to anything other than Box and back _to
   their original type_ again. Even passing through any other type will
   poison them. in particular, even 'seq' is unsafe on casted values until
   they have been cast back to their original type.

casting of unboxed types is right out (and guarenteed impossible by the
type system)

there are specific primitives to cast from kind * values to the analog
type of kind ! values and back again these are not casts and are not
subject to the above rules. (though, converting something of kind * to
kind !  necessarily evaluates it).

any cross-platform use of unsafeCoerce is folly, unless of course you
have verified it is possible to use it in each compilers documentation
you wish to support.

since this is a perfectly reasonable thing to do, I support putting
unsafeCoerce in a standard spot, but with no standardized behavior.

        John

--
John Meacham - ⑆repetae.net⑆john⑈


More information about the Libraries mailing list