Skip to content

Commit 91cf548

Browse files
committed
Make PrimUnlifted ShorText instance safe
* 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 #22
1 parent f695250 commit 91cf548

File tree

4 files changed

+39
-3
lines changed

4 files changed

+39
-3
lines changed

primitive-unlifted.cabal

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ tested-with: GHC == 8.10.1
2424
library
2525
exposed-modules:
2626
Data.Primitive.Unlifted.Class
27+
Data.Primitive.Unlifted.Types
28+
Data.Primitive.Unlifted.Types.Unsafe
2729
Data.Primitive.Unlifted.Array
2830
Data.Primitive.Unlifted.SmallArray
2931
Data.Primitive.Unlifted.SmallArray.ST

src/Data/Primitive/Unlifted/Class.hs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
{-# language UnboxedTuples #-}
33
{-# language TypeFamilies #-}
44
{-# language ScopedTypeVariables #-}
5+
{-# language Trustworthy #-}
56

67
module Data.Primitive.Unlifted.Class
78
( PrimUnlifted(..)
@@ -27,6 +28,7 @@ import GHC.Exts (MutableByteArray#,ByteArray#
2728
import GHC.Exts (RuntimeRep(UnliftedRep))
2829
import GHC.Exts (MVar#,MutVar#,RealWorld)
2930
import GHC.Exts (TYPE)
31+
import Data.Primitive.Unlifted.Types.Unsafe (ShortText# (..))
3032

3133
import qualified Data.Primitive.MVar as PM
3234
import qualified GHC.Exts as Exts
@@ -72,9 +74,9 @@ instance PrimUnlifted ShortByteString where
7274
fromUnlifted# x = SBS x
7375

7476
instance PrimUnlifted ShortText where
75-
type Unlifted ShortText = ByteArray#
76-
toUnlifted# t = case toShortByteString t of { SBS x -> x }
77-
fromUnlifted# x = fromShortByteStringUnsafe (SBS x)
77+
type Unlifted ShortText = ShortText#
78+
toUnlifted# t = case toShortByteString t of { SBS x -> ShortText# x }
79+
fromUnlifted# (ShortText# x) = fromShortByteStringUnsafe (SBS x)
7880

7981
instance PrimUnlifted (MutableByteArray s) where
8082
type Unlifted (MutableByteArray s) = MutableByteArray# s
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{-# language MagicHash #-}
2+
3+
-- | Some types may impose invariants that are not natively
4+
-- enforced by their unlifted forms. This module exports
5+
-- newtypes around those unlifted forms that can be used to
6+
-- write safe @PrimUnlifted@ instances. At present, this is
7+
-- only done for the 'ShortText' type, but others may be added.
8+
--
9+
-- This module exports only abstract types. To access their
10+
-- constructors, import "Data.Primitive.Unlifted.Types.Unsafe".
11+
12+
module Data.Primitive.Unlifted.Types
13+
( ShortText#
14+
) where
15+
16+
import Data.Primitive.Unlifted.Types.Unsafe
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{-# language MagicHash #-}
2+
{-# language UnliftedNewtypes #-}
3+
4+
-- | Some types may impose invariants that are not natively
5+
-- enforced by their unlifted forms. This module defines
6+
-- newtypes around those unlifted forms that can be used to
7+
-- write safe @PrimUnlifted@ instances. At present, this is
8+
-- only done for the 'ShortText' type, but others may be added.
9+
10+
module Data.Primitive.Unlifted.Types.Unsafe
11+
( ShortText# (..)
12+
) where
13+
14+
import GHC.Exts (ByteArray#)
15+
16+
newtype ShortText# = ShortText# ByteArray#

0 commit comments

Comments
 (0)