!!! `project` causes memory inconsistencies
- Lingua principale
- Haskell
- Stelle
- 83
- Fork
- 16
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Descrizione
`project` (and potentially also `inject`, we haven’t verified`, will cause undefined behavior, which we noticed & verified in a production system.
*The bug only appears with optimizations enabled (only tested `-O2`), not in ghci*
I don’t have a minimal repro (yet), but I can describe what we did:
There was one function which loaded some data in `IO`, constructed a ist of `rec`, then before returning used `project` to reduce unnecessary fields in every list element:
```haskell
loadData :: IO (Record '[ "foo" := Text ])
loadData = do
listOfRes <-
pure
$ map
(project @'["foo" := Text, "bar" := Int] @'["foo" := Text])
listOfRes
```
And another function that pulled *a subset* of fields from the record, like this:
```haskell
requestBody = do
dat <- loadData
let mapDat d = (Json.object [
("foo", get #foo d)
])
pure $ Json.Array (map mapDat dat)
```
Let’s say the final data was
```haskell
[
{ foo = "xx" },
{ foo = "yy" },
{ foo = "zz" },
]
```
Then what would be actually returned was (!!):
```haskell
[
{ foo = "xx" },
{ foo = "xx" },
{ foo = "xx" },
]
```
now, if you rewrote the function to deeply evaluate the `project`ed record:
```haskell
loadData :: IO (Record '[ "foo" := Text ])
loadData = do
listOfRes <-
print listOfRes -- <- deeply evaluate the record by printing it
pure
$ map
(project @'["foo" := Text, "bar" := Int] @'["foo" := Text])
listOfRes
```
It would again return
```haskell
[
{ foo = "xx" },
{ foo = "yy" },
{ foo = "zz" },
]
```
When we rewrote the original function to construct a new record instead of `project`ing:
```haskell
loadData :: IO (Record '[ "foo" := Text ])
loadData = do
listOfRes <-
pure
$ map
(\res -> rcons #foo (get #foo res) rnil)
listOfRes
```
The problem went away.
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Valutazione
Questa issue non è ancora stata valutata.