@@ -493,14 +493,17 @@ newtype instance Static User fnTy = UserStatic {userStaticPtr :: StaticPtr fnTy}
493
493
newtype instance Static System fnTy = SystemStatic { userStaticKey :: StaticKey }
494
494
deriving newtype (Eq , Ord , Show , Binary )
495
495
496
+ systemStatic :: Static User fnTy -> Static System fnTy
497
+ systemStatic (UserStatic ptr) = SystemStatic (staticKey ptr)
498
+
496
499
instance Show (Static User fnTy ) where
497
- showsPrec p ptr = showsPrec p (staticKey $ userStaticPtr ptr)
500
+ showsPrec p ptr = showsPrec p (systemStatic ptr)
498
501
instance Eq (Static User fnTy ) where
499
- (==) = (==) `on` (staticKey . userStaticPtr)
502
+ (==) = (==) `on` systemStatic
500
503
instance Ord (Static User fnTy ) where
501
- compare = compare `on` (staticKey . userStaticPtr)
504
+ compare = compare `on` systemStatic
502
505
instance Binary (Static User fnTy ) where
503
- put ( UserStatic ptr) = put (staticKey ptr)
506
+ put = put . systemStatic
504
507
get = do
505
508
ptrKey <- get @ StaticKey
506
509
case unsafePerformIO $ unsafeLookupStaticPtr ptrKey of
@@ -525,7 +528,7 @@ type Command = CommandData User
525
528
data CommandData (scope :: Scope ) (arg :: Hs. Type ) (res :: Hs. Type ) = Command
526
529
{ actionPtr :: ! (Static scope (arg -> res ))
527
530
-- ^ The (statically-known) action to execute.
528
- , actionArg :: ! (BinaryArg scope arg )
531
+ , actionArg :: ! (ScopedArgument scope arg )
529
532
-- ^ The (possibly dynamic) argument to pass to the action.
530
533
, cmdInstances :: ! (Static scope (Dict (Binary arg , Show arg )))
531
534
-- ^ Static evidence that the argument can be serialised and deserialised.
@@ -543,13 +546,13 @@ mkCommand
543
546
mkCommand dict actionPtr arg =
544
547
Command
545
548
{ actionPtr = UserStatic actionPtr
546
- , actionArg = BinaryArg arg
549
+ , actionArg = ScopedArgument arg
547
550
, cmdInstances = UserStatic dict
548
551
}
549
552
550
553
-- | Run a 'Command'.
551
554
runCommand :: Command args res -> res
552
- runCommand (Command {actionPtr = UserStatic ptr, actionArg = BinaryArg arg}) =
555
+ runCommand (Command {actionPtr = UserStatic ptr, actionArg = ScopedArgument arg}) =
553
556
deRefStaticPtr ptr arg
554
557
555
558
-- | Commands to execute a rule:
@@ -626,7 +629,7 @@ of their choosing.
626
629
627
630
This all makes sense within the Hooks API, but when communicating with an
628
631
external build system (such as cabal-install or HLS), these arguments are
629
- trated as opaque blobs of data (in particular if the Hooks are compiled into
632
+ treated as opaque blobs of data (in particular if the Hooks are compiled into
630
633
a separate executable, then the static pointers that contain the relevant
631
634
instances for these user-chosen types can only be dereferenced from within that
632
635
executable, and not on the side of the build system).
@@ -650,29 +653,29 @@ an 'Int64', we are nevertheless required to also serialise its size. This is bec
650
653
on the build-system side, we don't have access to any of the types, and thus don't know
651
654
how much to read in order to reconstruct the associated opaque 'ByteString'.
652
655
To ensure we always serialise/deserialise including the length of the data,
653
- the 'BinaryArg ' newtype is used, with a custom 'Binary' instance that always
656
+ the 'ScopedArgument ' newtype is used, with a custom 'Binary' instance that always
654
657
incldues the length. We use this newtype:
655
658
656
659
- in the definition of 'CommandData', for arguments to rules,
657
660
- in the definition of 'DepsRes', for the result of dynamic dependency computations.
658
661
-}
659
662
660
- newtype BinaryArg (scope :: Scope ) arg = BinaryArg { getArg :: arg }
663
+ newtype ScopedArgument (scope :: Scope ) arg = ScopedArgument { getArg :: arg }
661
664
deriving newtype (Eq , Ord , Show )
662
665
663
666
-- | Serialise/deserialise, always including the length of the payload.
664
- instance Binary arg => Binary (BinaryArg User arg ) where
665
- put (BinaryArg arg) = put @ LBS. ByteString (Binary. encode arg)
667
+ instance Binary arg => Binary (ScopedArgument User arg ) where
668
+ put (ScopedArgument arg) = put @ LBS. ByteString (Binary. encode arg)
666
669
get = do
667
670
dat <- get @ LBS. ByteString
668
671
case Binary. decodeOrFail dat of
669
672
Left (_, _, err) -> fail err
670
- Right (_, _, res) -> return $ BinaryArg res
673
+ Right (_, _, res) -> return $ ScopedArgument res
671
674
672
675
-- | Serialise and deserialise a raw ByteString, leaving it untouched.
673
- instance arg ~ LBS. ByteString => Binary (BinaryArg System arg ) where
674
- put (BinaryArg arg) = put arg
675
- get = BinaryArg <$> get
676
+ instance arg ~ LBS. ByteString => Binary (ScopedArgument System arg ) where
677
+ put (ScopedArgument arg) = put arg
678
+ get = ScopedArgument <$> get
676
679
677
680
-- | A placeholder for a command that has been omitted, e.g. when we don't
678
681
-- care about serialising/deserialising one particular command in a datatype.
@@ -681,7 +684,10 @@ data NoCmd (scope :: Scope) arg res = CmdOmitted
681
684
deriving anyclass (Binary )
682
685
683
686
-- | A dynamic dependency command.
684
- newtype DynDepsCmd scope depsArg depsRes = DynDepsCmd { dynDepsCmd :: CommandData scope depsArg (IO ([Dependency ], depsRes ))}
687
+ newtype DynDepsCmd scope depsArg depsRes = DynDepsCmd
688
+ { dynDepsCmd
689
+ :: CommandData scope depsArg (IO ([Dependency], depsRes))
690
+ }
685
691
686
692
deriving newtype instance Show (DynDepsCmd User depsArg depsRes )
687
693
deriving newtype instance Eq (DynDepsCmd User depsArg depsRes )
@@ -694,9 +700,16 @@ deriving newtype instance
694
700
=> Binary (DynDepsCmd System arg depsRes )
695
701
696
702
-- | The result of a dynamic dependency computation.
697
- newtype DepsRes (scope :: Scope ) depsArg depsRes = DepsRes { depsRes :: BinaryArg scope depsRes }
703
+ newtype DepsRes (scope :: Scope ) depsArg depsRes = DepsRes
704
+ { depsRes
705
+ :: ScopedArgument scope depsRes -- See Note [Hooks Binary instances]
706
+ }
698
707
deriving newtype (Show , Eq , Ord )
699
708
709
+ deriving newtype instance
710
+ Binary (ScopedArgument scope depsRes )
711
+ => Binary (DepsRes scope depsArg depsRes )
712
+
700
713
-- | Both the rule command and the (optional) dynamic dependency command.
701
714
type RuleCmds scope = RuleCommands scope DynDepsCmd CommandData
702
715
@@ -743,7 +756,8 @@ runRuleDynDepsCmd = \case
743
756
| Dict <- deRefStaticPtr instsPtr ->
744
757
Just $ do
745
758
(deps, depsRes) <- runCommand depsCmd
746
- return $ (deps, Binary. encode depsRes)
759
+ -- See Note [Hooks Binary instances]
760
+ return $ (deps, Binary. encode $ ScopedArgument @ User depsRes)
747
761
748
762
-- | Project out the command for running the rule, passing in the result of
749
763
-- the dependency computation if there was one.
@@ -783,7 +797,7 @@ ruleExecCmd
783
797
DynamicRuleCommands
784
798
{ dynamicRuleInstances = instsPtr
785
799
, dynamicRuleCommand = cmd
786
- , dynamicDeps = DepsRes $ BinaryArg depsResBinary
800
+ , dynamicDeps = DepsRes $ ScopedArgument depsResBinary
787
801
, dynamicRuleTypeRep = tr
788
802
}
789
803
@@ -792,7 +806,7 @@ runRuleExecCmd :: RuleExecCmd User -> IO ()
792
806
runRuleExecCmd = \ case
793
807
StaticRuleCommand {staticRuleCommand = cmd} -> runCommand cmd
794
808
DynamicRuleCommands
795
- { dynamicDeps = DepsRes (BinaryArg {getArg = res})
809
+ { dynamicDeps = DepsRes (ScopedArgument {getArg = res})
796
810
, dynamicRuleCommand = cmd
797
811
} ->
798
812
runCommand cmd res
@@ -930,12 +944,6 @@ instance
930
944
a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2
931
945
_ == _ = False
932
946
933
- instance Binary (BinaryArg scope depsRes ) => Binary (DepsRes scope depsArgs depsRes ) where
934
- put (DepsRes deps) = put $ Binary. encode deps -- See Note [put/get ByteString]
935
- get = do
936
- bs <- get
937
- return $ DepsRes $ Binary. decode bs -- See Note [put/get ByteString]
938
-
939
947
instance
940
948
( forall arg res . Binary (ruleCmd User arg res )
941
949
, forall depsArg depsRes . Binary depsRes => Binary (deps User depsArg depsRes )
@@ -1054,7 +1062,8 @@ instance
1054
1062
, dynamicRuleTypeRep = sTr
1055
1063
}
1056
1064
1057
- -- | Convenience function used for the pretty-printing @'Show' 'RuleBinary'@
1058
- -- instance.
1065
+ --------------------------------------------------------------------------------
1066
+ -- Showing rules
1067
+
1059
1068
ruleBinary :: Rule -> RuleBinary
1060
1069
ruleBinary = Binary. decode . Binary. encode
0 commit comments