Refactor `ModIface` serialisation to allow adding more deduplication tables
Split off from #24540, we propose to refactor the serialisation of `ModIface`.
The main goal is to change `UserData`, which has special support for deserialising `Name`s and `FastString`s.
See:
```haskell
data UserData =
UserData {
-- for *deserialising* only:
ud_get_name :: BinHandle -> IO Name,
ud_get_fs :: BinHandle -> IO FastString,
-- for *serialising* only:
ud_put_nonbinding_name :: BinHandle -> Name -> IO (),
-- ^ serialize a non-binding 'Name' (e.g. a reference to another
-- binding).
ud_put_binding_name :: BinHandle -> Name -> IO (),
-- ^ serialize a binding 'Name' (e.g. the name of an IfaceDecl)
ud_put_fs :: BinHandle -> FastString -> IO ()
}
```
This does not scale if we want to add more deduplication tables such as #24540.
Moreover, a lot of these fields are populated by `undef`.
This issue proposes to generalise `UserData` to allow arbitrary deduplication tables with minimal changes to the `Binary` class interface.
We split `UserData` (and `BinHandle`) into `Read`/`Write`, allowing us to always keep only exactly the information we need.
The second step is to generalise how `putWithTables` serialises deduplication tables, allowing us to conveniently add more deduplication tables later.
issue