From 013d668159eb1adf2b6611c312c5820fb1861865 Mon Sep 17 00:00:00 2001 From: Moritz Kiefer Date: Wed, 11 Dec 2019 15:59:50 +0100 Subject: [PATCH] Add Eq instances for AnyTemplate, AnyChoice and AnyContractKey (#3816) * Add Eq instances for AnyTemplate, AnyChoice and AnyContractKey CHANGELOG_BEGIN - [DAML Standard Library] Add ``Eq`` instances for ``AnyTemplate``, ``AnyChoice`` and ``AnyContractKey``. CHANGELOG_END * Add DAML_ANY_TYPE to the CPP guard --- .../damlc/daml-stdlib-src/DA/Internal/LF.daml | 22 +++++++ .../damlc/tests/daml-test-files/AnyEq.daml | 58 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 compiler/damlc/tests/daml-test-files/AnyEq.daml diff --git a/compiler/damlc/daml-stdlib-src/DA/Internal/LF.daml b/compiler/damlc/daml-stdlib-src/DA/Internal/LF.daml index e0112ec2a5eb..1785a7635b0e 100644 --- a/compiler/damlc/daml-stdlib-src/DA/Internal/LF.daml +++ b/compiler/damlc/daml-stdlib-src/DA/Internal/LF.daml @@ -243,6 +243,28 @@ data AnyContractKey = AnyContractKey , getanyContractKeyTemplateRep : TemplateTypeRep } +#ifdef DAML_GENMAP && DAML_ANY_TYPE +-- We do not separate generic equality from generic maps so this guards on DAML_GENMAP. + +-- We do not have a general Eq instance for Any since Any is not exposed +-- to users directly and that instance will crash on some values but +-- we can have total Eq instances for AnyTemplate, AnyChoice and AnyContractKey +-- since those are guaranteed to be serializable. +eqAny : Any -> Any -> Bool +eqAny = primitive @"BEEqual" + +instance Eq AnyTemplate where + AnyTemplate a == AnyTemplate b = eqAny a b + +instance Eq AnyChoice where + AnyChoice aAny aRep == AnyChoice bAny bRep = + eqAny aAny bAny && aRep == bRep + +instance Eq AnyContractKey where + AnyContractKey aAny aRep == AnyContractKey bAny bRep = + eqAny aAny bAny && aRep == bRep +#endif + -- | Value-level representation of a type. -- We do not expose this directly and instead only expose TemplateTypeRep. data TypeRep = TypeRep Opaque diff --git a/compiler/damlc/tests/daml-test-files/AnyEq.daml b/compiler/damlc/tests/daml-test-files/AnyEq.daml new file mode 100644 index 000000000000..7921e862ce6b --- /dev/null +++ b/compiler/damlc/tests/daml-test-files/AnyEq.daml @@ -0,0 +1,58 @@ +-- Copyright (c) 2019, Digital Asset (Switzerland) GmbH and/or its affiliates. +-- All rights reserved. + +-- @SINCE-LF 1.8 +daml 1.2 +module AnyEq where + +import DA.Action + +template T1 + with + x : Int + p : Party + where + signatory p + key p : Party + maintainer key + choice C : () + controller p + do pure () + +template T1' + with + x : Int + p : Party + where + signatory p + key p : Party + maintainer key + +template T2 + with + y : Text + p : Party + where + signatory p + key (p, y) : (Party, Text) + maintainer key._1 + +-- We don’t have a Show instance for AnyTemplate so we cannot use === + +assertBool : CanAbort m => Text -> Bool -> m () +assertBool err success = unless success $ abort ("Failure: " <> show err) + +main = scenario do + p <- getParty "alice" + let t1A = T1 0 p + let t1B = T1 1 p + let t1'A = T1' 0 p + assertBool (show (t1A, t1A)) (toAnyTemplate t1A == toAnyTemplate t1A) + assertBool (show (t1A, t1B)) (toAnyTemplate t1A /= toAnyTemplate t1B) + assertBool (show (t1'A, t1'A)) (toAnyTemplate t1'A == toAnyTemplate t1'A) + assertBool (show (t1A, t1'A)) (toAnyTemplate t1A /= toAnyTemplate t1'A) + assertBool (show (C, C)) (toAnyChoice @T1 C == toAnyChoice @T1 C) + assertBool (show (C, Archive)) (toAnyChoice @T1 C /= toAnyChoice @T1 Archive) + assertBool ("T1, T2" <> show (Archive, Archive)) (toAnyChoice @T1 C /= toAnyChoice @T2 Archive) + assertBool ("T1, T1'" <> show (p, p)) (toAnyContractKey @T1 p /= toAnyContractKey @T1' p) + assertBool ("T1, T1" <> show (p, p)) (toAnyContractKey @T1 p == toAnyContractKey @T1 p)