Skip to content

Commit 9ac11a5

Browse files
authored
Make semantic integrity check insensitive to field order (#552)
... as standardized in dhall-lang/dhall-lang#223 Fixes #548 This changes β-normalization to sort fields so that semantic integrity checks don't change when reordering fields * Fix test failure The Nix build sets `HOME=/homeless-shelter`, which leads to a test failure since the test tries to create a "${HOME}/.cache" directory without first checking if "${HOME}" is accessible. This changes the `assertDirectory` function to recursively check parent directories to avoid this issue, which in turn fixes the test (since it gracefully creates no directories if none are accessible).
1 parent 8f48c67 commit 9ac11a5

File tree

7 files changed

+27
-5
lines changed

7 files changed

+27
-5
lines changed

dhall.cabal

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ Library
181181
directory >= 1.2.7.1 && < 1.4 ,
182182
exceptions >= 0.8.3 && < 0.11,
183183
filepath >= 1.4 && < 1.5 ,
184+
hashable < 1.3 ,
184185
haskeline >= 0.7.3.0 && < 0.8 ,
185186
insert-ordered-containers >= 0.2.1.0 && < 0.3 ,
186187
lens-family-core >= 1.0.0 && < 1.3 ,
@@ -266,7 +267,7 @@ Test-Suite tasty
266267
containers ,
267268
deepseq >= 1.2.0.1 && < 1.5 ,
268269
dhall ,
269-
hashable < 1.3 ,
270+
hashable ,
270271
insert-ordered-containers == 0.2.1.0 ,
271272
prettyprinter ,
272273
QuickCheck >= 2.10 && < 2.12,

src/Dhall/Core.hs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ import Crypto.Hash (SHA256)
6464
import Data.Bifunctor (Bifunctor(..))
6565
import Data.Data (Data)
6666
import Data.Foldable
67+
import Data.Hashable (Hashable)
6768
import Data.HashMap.Strict.InsOrd (InsOrdHashMap)
6869
import Data.HashSet (HashSet)
6970
import Data.String (IsString(..))
@@ -81,8 +82,10 @@ import Prelude hiding (succ)
8182

8283
import qualified Control.Monad
8384
import qualified Crypto.Hash
85+
import qualified Data.List
8486
import qualified Data.HashMap.Strict.InsOrd
8587
import qualified Data.HashSet
88+
import qualified Data.Ord
8689
import qualified Data.Sequence
8790
import qualified Data.Set
8891
import qualified Data.Text
@@ -1371,6 +1374,12 @@ denote (Project a b ) = Project (denote a) b
13711374
denote (ImportAlt a b ) = ImportAlt (denote a) (denote b)
13721375
denote (Embed a ) = Embed a
13731376

1377+
sortMap :: (Ord k, Hashable k) => InsOrdHashMap k v -> InsOrdHashMap k v
1378+
sortMap =
1379+
Data.HashMap.Strict.InsOrd.fromList
1380+
. Data.List.sortBy (Data.Ord.comparing fst)
1381+
. Data.HashMap.Strict.InsOrd.toList
1382+
13741383
{-| Reduce an expression to its normal form, performing beta reduction and applying
13751384
any custom definitions.
13761385
@@ -1646,16 +1655,16 @@ normalizeWith ctx e0 = loop (denote e0)
16461655
es' = fmap loop es
16471656
OptionalFold -> OptionalFold
16481657
OptionalBuild -> OptionalBuild
1649-
Record kts -> Record kts'
1658+
Record kts -> Record (sortMap kts')
16501659
where
16511660
kts' = fmap loop kts
1652-
RecordLit kvs -> RecordLit kvs'
1661+
RecordLit kvs -> RecordLit (sortMap kvs')
16531662
where
16541663
kvs' = fmap loop kvs
1655-
Union kts -> Union kts'
1664+
Union kts -> Union (sortMap kts')
16561665
where
16571666
kts' = fmap loop kts
1658-
UnionLit k v kvs -> UnionLit k v' kvs'
1667+
UnionLit k v kvs -> UnionLit k v' (sortMap kvs')
16591668
where
16601669
v' = loop v
16611670
kvs' = fmap loop kvs

src/Dhall/Import.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ import qualified Dhall.Pretty.Internal
186186
import qualified Dhall.TypeCheck
187187
import qualified System.Environment
188188
import qualified System.Directory as Directory
189+
import qualified System.FilePath as FilePath
189190
import qualified Text.Megaparsec
190191
import qualified Text.Parser.Combinators
191192
import qualified Text.Parser.Token
@@ -535,6 +536,8 @@ getCacheFile hash = do
535536
guard (accessible permissions)
536537

537538
else do
539+
assertDirectory (FilePath.takeDirectory directory)
540+
538541
liftIO (Directory.createDirectory directory)
539542

540543
liftIO (Directory.setPermissions directory private)

tests/Import.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ importTests =
4747
"works"
4848
"./tests/import/data/foo/bar"
4949
"./tests/import/relative.dhall"
50+
, shouldNotFailRelative
51+
"a semantic integrity check if fields are reordered"
52+
"./tests/import/"
53+
"./tests/import/fieldOrderC.dhall"
5054
]
5155
]
5256

tests/import/fieldOrderA.dhall

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ foo = 1, bar = True }

tests/import/fieldOrderB.dhall

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ bar = True, foo = 1 }

tests/import/fieldOrderC.dhall

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{ example0 = ./fieldOrderA.dhall sha256:c8e5944a964f1b35da4f2a7dc16b8de0221a518997fd84b0363a955d8f4459a4
2+
, example1 = ./fieldOrderB.dhall sha256:c8e5944a964f1b35da4f2a7dc16b8de0221a518997fd84b0363a955d8f4459a4
3+
}

0 commit comments

Comments
 (0)