Skip to content

Commit

Permalink
Make PrimUnlifted ShorText instance safe
Browse files Browse the repository at this point in the history
* Use a newtype to hide the unrestricted `ByteArray`
  underneath.

* Mark `Data.Primitive.Unlifted.Class` as `Trustworthy`. TODO:
  Discuss whether it's okay to do that without similarly changing
  the `PrimArray` instance.

Closes haskell-primitive#22
  • Loading branch information
treeowl committed Oct 20, 2020
1 parent f695250 commit 91cf548
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 3 deletions.
2 changes: 2 additions & 0 deletions primitive-unlifted.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ tested-with: GHC == 8.10.1
library
exposed-modules:
Data.Primitive.Unlifted.Class
Data.Primitive.Unlifted.Types
Data.Primitive.Unlifted.Types.Unsafe
Data.Primitive.Unlifted.Array
Data.Primitive.Unlifted.SmallArray
Data.Primitive.Unlifted.SmallArray.ST
Expand Down
8 changes: 5 additions & 3 deletions src/Data/Primitive/Unlifted/Class.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{-# language UnboxedTuples #-}
{-# language TypeFamilies #-}
{-# language ScopedTypeVariables #-}
{-# language Trustworthy #-}

module Data.Primitive.Unlifted.Class
( PrimUnlifted(..)
Expand All @@ -27,6 +28,7 @@ import GHC.Exts (MutableByteArray#,ByteArray#
import GHC.Exts (RuntimeRep(UnliftedRep))
import GHC.Exts (MVar#,MutVar#,RealWorld)
import GHC.Exts (TYPE)
import Data.Primitive.Unlifted.Types.Unsafe (ShortText# (..))

import qualified Data.Primitive.MVar as PM
import qualified GHC.Exts as Exts
Expand Down Expand Up @@ -72,9 +74,9 @@ instance PrimUnlifted ShortByteString where
fromUnlifted# x = SBS x

instance PrimUnlifted ShortText where
type Unlifted ShortText = ByteArray#
toUnlifted# t = case toShortByteString t of { SBS x -> x }
fromUnlifted# x = fromShortByteStringUnsafe (SBS x)
type Unlifted ShortText = ShortText#
toUnlifted# t = case toShortByteString t of { SBS x -> ShortText# x }
fromUnlifted# (ShortText# x) = fromShortByteStringUnsafe (SBS x)

instance PrimUnlifted (MutableByteArray s) where
type Unlifted (MutableByteArray s) = MutableByteArray# s
Expand Down
16 changes: 16 additions & 0 deletions src/Data/Primitive/Unlifted/Types.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{-# language MagicHash #-}

-- | Some types may impose invariants that are not natively
-- enforced by their unlifted forms. This module exports
-- newtypes around those unlifted forms that can be used to
-- write safe @PrimUnlifted@ instances. At present, this is
-- only done for the 'ShortText' type, but others may be added.
--
-- This module exports only abstract types. To access their
-- constructors, import "Data.Primitive.Unlifted.Types.Unsafe".

module Data.Primitive.Unlifted.Types
( ShortText#
) where

import Data.Primitive.Unlifted.Types.Unsafe
16 changes: 16 additions & 0 deletions src/Data/Primitive/Unlifted/Types/Unsafe.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{-# language MagicHash #-}
{-# language UnliftedNewtypes #-}

-- | Some types may impose invariants that are not natively
-- enforced by their unlifted forms. This module defines
-- newtypes around those unlifted forms that can be used to
-- write safe @PrimUnlifted@ instances. At present, this is
-- only done for the 'ShortText' type, but others may be added.

module Data.Primitive.Unlifted.Types.Unsafe
( ShortText# (..)
) where

import GHC.Exts (ByteArray#)

newtype ShortText# = ShortText# ByteArray#

0 comments on commit 91cf548

Please sign in to comment.