module Unison.Merge.Mergeblob1
  ( Mergeblob1 (..),
    makeMergeblob1,
  )
where

import Data.List qualified as List
import Data.Map.Strict qualified as Map
import Unison.DataDeclaration (Decl)
import Unison.DataDeclaration qualified as DataDeclaration
import Unison.DeclNameLookup (DeclNameLookup)
import Unison.Merge.CombineDiffs (CombinedDiffOp, combineDiffs)
import Unison.Merge.DeclCoherencyCheck (IncoherentDeclReason, checkDeclCoherency, lenientCheckDeclCoherency)
import Unison.Merge.Diff (nameBasedNamespaceDiff)
import Unison.Merge.DiffOp (DiffOp)
import Unison.Merge.EitherWay (EitherWay (..))
import Unison.Merge.Libdeps (LibdepDiffOp, applyLibdepsDiff, diffLibdeps, getTwoFreshLibdepNames)
import Unison.Merge.Mergeblob0 (Mergeblob0 (..))
import Unison.Merge.PartialDeclNameLookup (PartialDeclNameLookup)
import Unison.Merge.PartitionCombinedDiffs (partitionCombinedDiffs)
import Unison.Merge.Synhashed (Synhashed)
import Unison.Merge.ThreeWay (ThreeWay)
import Unison.Merge.ThreeWay qualified as ThreeWay
import Unison.Merge.TwoWay (TwoWay (..))
import Unison.Merge.Unconflicts (Unconflicts)
import Unison.Name (Name)
import Unison.NameSegment (NameSegment)
import Unison.Parser.Ann (Ann)
import Unison.Prelude
import Unison.Reference (TermReference, TermReferenceId, TypeReference, TypeReferenceId)
import Unison.Referent (Referent)
import Unison.Symbol (Symbol)
import Unison.Term (Term)
import Unison.Type (Type)
import Unison.Util.BiMultimap (BiMultimap)
import Unison.Util.Defns (Defns (..), DefnsF, DefnsF2, DefnsF3)

data Mergeblob1 libdep = Mergeblob1
  { forall libdep.
Mergeblob1 libdep
-> TwoWay (DefnsF (Map Name) TermReference TermReference)
conflicts :: TwoWay (DefnsF (Map Name) TermReference TypeReference),
    forall libdep. Mergeblob1 libdep -> TwoWay DeclNameLookup
declNameLookups :: TwoWay DeclNameLookup,
    forall libdep.
Mergeblob1 libdep
-> ThreeWay
     (Defns (BiMultimap Referent Name) (BiMultimap TermReference Name))
defns :: ThreeWay (Defns (BiMultimap Referent Name) (BiMultimap TypeReference Name)),
    forall libdep.
Mergeblob1 libdep
-> DefnsF2 (Map Name) CombinedDiffOp Referent TermReference
diff :: DefnsF2 (Map Name) CombinedDiffOp Referent TypeReference,
    forall libdep.
Mergeblob1 libdep
-> TwoWay
     (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
diffs :: TwoWay (DefnsF3 (Map Name) DiffOp Synhashed Referent TypeReference),
    forall libdep.
Mergeblob1 libdep
-> ThreeWay
     (DefnsF
        (Map Name)
        (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
        (TermReferenceId, Decl Symbol Ann))
hydratedDefns ::
      ThreeWay
        ( DefnsF
            (Map Name)
            (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
            (TypeReferenceId, Decl Symbol Ann)
        ),
    forall libdep. Mergeblob1 libdep -> PartialDeclNameLookup
lcaDeclNameLookup :: PartialDeclNameLookup,
    forall libdep. Mergeblob1 libdep -> Map NameSegment libdep
libdeps :: Map NameSegment libdep,
    forall libdep.
Mergeblob1 libdep -> Map NameSegment (LibdepDiffOp libdep)
libdepsDiff :: Map NameSegment (LibdepDiffOp libdep),
    forall libdep.
Mergeblob1 libdep -> DefnsF Unconflicts Referent TermReference
unconflicts :: DefnsF Unconflicts Referent TypeReference
  }

makeMergeblob1 ::
  forall libdep.
  (Eq libdep) =>
  Mergeblob0 libdep ->
  ThreeWay
    ( DefnsF
        (Map Name)
        (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
        (TypeReferenceId, Decl Symbol Ann)
    ) ->
  Either (EitherWay IncoherentDeclReason) (Mergeblob1 libdep)
makeMergeblob1 :: forall libdep.
Eq libdep =>
Mergeblob0 libdep
-> ThreeWay
     (DefnsF
        (Map Name)
        (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
        (TermReferenceId, Decl Symbol Ann))
-> Either (EitherWay IncoherentDeclReason) (Mergeblob1 libdep)
makeMergeblob1 Mergeblob0 libdep
blob ThreeWay
  (DefnsF
     (Map Name)
     (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
     (TermReferenceId, Decl Symbol Ann))
hydratedDefns = do
  -- Make one big constructor count lookup for all type decls
  let numConstructors :: Map TermReferenceId Int
numConstructors =
        Map TermReferenceId Int
forall k a. Map k a
Map.empty
          Map TermReferenceId Int
-> (Map TermReferenceId Int -> Map TermReferenceId Int)
-> Map TermReferenceId Int
forall a b. a -> (a -> b) -> b
& [(TermReferenceId, Decl Symbol Ann)]
-> Map TermReferenceId Int -> Map TermReferenceId Int
f (Map Name (TermReferenceId, Decl Symbol Ann)
-> [(TermReferenceId, Decl Symbol Ann)]
forall k a. Map k a -> [a]
Map.elems ThreeWay
  (DefnsF
     (Map Name)
     (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
     (TermReferenceId, Decl Symbol Ann))
hydratedDefns.alice.types)
          Map TermReferenceId Int
-> (Map TermReferenceId Int -> Map TermReferenceId Int)
-> Map TermReferenceId Int
forall a b. a -> (a -> b) -> b
& [(TermReferenceId, Decl Symbol Ann)]
-> Map TermReferenceId Int -> Map TermReferenceId Int
f (Map Name (TermReferenceId, Decl Symbol Ann)
-> [(TermReferenceId, Decl Symbol Ann)]
forall k a. Map k a -> [a]
Map.elems ThreeWay
  (DefnsF
     (Map Name)
     (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
     (TermReferenceId, Decl Symbol Ann))
hydratedDefns.bob.types)
          Map TermReferenceId Int
-> (Map TermReferenceId Int -> Map TermReferenceId Int)
-> Map TermReferenceId Int
forall a b. a -> (a -> b) -> b
& [(TermReferenceId, Decl Symbol Ann)]
-> Map TermReferenceId Int -> Map TermReferenceId Int
f (Map Name (TermReferenceId, Decl Symbol Ann)
-> [(TermReferenceId, Decl Symbol Ann)]
forall k a. Map k a -> [a]
Map.elems ThreeWay
  (DefnsF
     (Map Name)
     (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
     (TermReferenceId, Decl Symbol Ann))
hydratedDefns.lca.types)
        where
          f :: [(TypeReferenceId, Decl Symbol Ann)] -> Map TypeReferenceId Int -> Map TypeReferenceId Int
          f :: [(TermReferenceId, Decl Symbol Ann)]
-> Map TermReferenceId Int -> Map TermReferenceId Int
f [(TermReferenceId, Decl Symbol Ann)]
types Map TermReferenceId Int
acc =
            (Map TermReferenceId Int
 -> (TermReferenceId, Decl Symbol Ann) -> Map TermReferenceId Int)
-> Map TermReferenceId Int
-> [(TermReferenceId, Decl Symbol Ann)]
-> Map TermReferenceId Int
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl'
              ( \Map TermReferenceId Int
acc (TermReferenceId
ref, Decl Symbol Ann
decl) ->
                  TermReferenceId
-> Int -> Map TermReferenceId Int -> Map TermReferenceId Int
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert TermReferenceId
ref (DataDeclaration Symbol Ann -> Int
forall v a. DataDeclaration v a -> Int
DataDeclaration.constructorCount (Decl Symbol Ann -> DataDeclaration Symbol Ann
forall v a. Decl v a -> DataDeclaration v a
DataDeclaration.asDataDecl Decl Symbol Ann
decl)) Map TermReferenceId Int
acc
              )
              Map TermReferenceId Int
acc
              [(TermReferenceId, Decl Symbol Ann)]
types

  -- Make Alice/Bob decl name lookups, which can fail if either have an incoherent decl
  TwoWay DeclNameLookup
declNameLookups <- do
    DeclNameLookup
alice <- HasCallStack =>
Nametree (DefnsF (Map NameSegment) Referent TermReference)
-> Map TermReferenceId Int
-> Either IncoherentDeclReason DeclNameLookup
Nametree (DefnsF (Map NameSegment) Referent TermReference)
-> Map TermReferenceId Int
-> Either IncoherentDeclReason DeclNameLookup
checkDeclCoherency Mergeblob0 libdep
blob.nametrees.alice Map TermReferenceId Int
numConstructors Either IncoherentDeclReason DeclNameLookup
-> (Either IncoherentDeclReason DeclNameLookup
    -> Either (EitherWay IncoherentDeclReason) DeclNameLookup)
-> Either (EitherWay IncoherentDeclReason) DeclNameLookup
forall a b. a -> (a -> b) -> b
& (IncoherentDeclReason -> EitherWay IncoherentDeclReason)
-> Either IncoherentDeclReason DeclNameLookup
-> Either (EitherWay IncoherentDeclReason) DeclNameLookup
forall a c b. (a -> c) -> Either a b -> Either c b
mapLeft IncoherentDeclReason -> EitherWay IncoherentDeclReason
forall a. a -> EitherWay a
Alice
    DeclNameLookup
bob <- HasCallStack =>
Nametree (DefnsF (Map NameSegment) Referent TermReference)
-> Map TermReferenceId Int
-> Either IncoherentDeclReason DeclNameLookup
Nametree (DefnsF (Map NameSegment) Referent TermReference)
-> Map TermReferenceId Int
-> Either IncoherentDeclReason DeclNameLookup
checkDeclCoherency Mergeblob0 libdep
blob.nametrees.bob Map TermReferenceId Int
numConstructors Either IncoherentDeclReason DeclNameLookup
-> (Either IncoherentDeclReason DeclNameLookup
    -> Either (EitherWay IncoherentDeclReason) DeclNameLookup)
-> Either (EitherWay IncoherentDeclReason) DeclNameLookup
forall a b. a -> (a -> b) -> b
& (IncoherentDeclReason -> EitherWay IncoherentDeclReason)
-> Either IncoherentDeclReason DeclNameLookup
-> Either (EitherWay IncoherentDeclReason) DeclNameLookup
forall a c b. (a -> c) -> Either a b -> Either c b
mapLeft IncoherentDeclReason -> EitherWay IncoherentDeclReason
forall a. a -> EitherWay a
Bob
    pure TwoWay {DeclNameLookup
alice :: DeclNameLookup
$sel:alice:TwoWay :: DeclNameLookup
alice, DeclNameLookup
bob :: DeclNameLookup
$sel:bob:TwoWay :: DeclNameLookup
bob}

  -- Make LCA decl name lookup
  let lcaDeclNameLookup :: PartialDeclNameLookup
lcaDeclNameLookup =
        Nametree (DefnsF (Map NameSegment) Referent TermReference)
-> Map TermReferenceId Int -> PartialDeclNameLookup
lenientCheckDeclCoherency Mergeblob0 libdep
blob.nametrees.lca Map TermReferenceId Int
numConstructors

  -- Diff LCA->Alice and LCA->Bob
  let diffs :: TwoWay (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
diffs =
        HasCallStack =>
TwoWay DeclNameLookup
-> PartialDeclNameLookup
-> ThreeWay
     (Defns (BiMultimap Referent Name) (BiMultimap TermReference Name))
-> Defns
     (Map TermReferenceId (Term Symbol Ann))
     (Map TermReferenceId (Decl Symbol Ann))
-> TwoWay
     (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
TwoWay DeclNameLookup
-> PartialDeclNameLookup
-> ThreeWay
     (Defns (BiMultimap Referent Name) (BiMultimap TermReference Name))
-> Defns
     (Map TermReferenceId (Term Symbol Ann))
     (Map TermReferenceId (Decl Symbol Ann))
-> TwoWay
     (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
nameBasedNamespaceDiff
          TwoWay DeclNameLookup
declNameLookups
          PartialDeclNameLookup
lcaDeclNameLookup
          Mergeblob0 libdep
blob.defns
          Defns
            { $sel:terms:Defns :: Map TermReferenceId (Term Symbol Ann)
terms =
                (DefnsF
   (Map Name)
   (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
   (TermReferenceId, Decl Symbol Ann)
 -> Map TermReferenceId (Term Symbol Ann))
-> ThreeWay
     (DefnsF
        (Map Name)
        (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
        (TermReferenceId, Decl Symbol Ann))
-> Map TermReferenceId (Term Symbol Ann)
forall m a. Monoid m => (a -> m) -> ThreeWay a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap
                  ((Map TermReferenceId (Term Symbol Ann)
 -> (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
 -> Map TermReferenceId (Term Symbol Ann))
-> Map TermReferenceId (Term Symbol Ann)
-> [(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))]
-> Map TermReferenceId (Term Symbol Ann)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' (\Map TermReferenceId (Term Symbol Ann)
acc (TermReferenceId
ref, (Term Symbol Ann
term, Type Symbol Ann
_)) -> TermReferenceId
-> Term Symbol Ann
-> Map TermReferenceId (Term Symbol Ann)
-> Map TermReferenceId (Term Symbol Ann)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert TermReferenceId
ref Term Symbol Ann
term Map TermReferenceId (Term Symbol Ann)
acc) Map TermReferenceId (Term Symbol Ann)
forall k a. Map k a
Map.empty ([(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))]
 -> Map TermReferenceId (Term Symbol Ann))
-> (DefnsF
      (Map Name)
      (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
      (TermReferenceId, Decl Symbol Ann)
    -> [(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))])
-> DefnsF
     (Map Name)
     (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
     (TermReferenceId, Decl Symbol Ann)
-> Map TermReferenceId (Term Symbol Ann)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map Name (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
-> [(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))]
forall k a. Map k a -> [a]
Map.elems (Map Name (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
 -> [(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))])
-> (DefnsF
      (Map Name)
      (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
      (TermReferenceId, Decl Symbol Ann)
    -> Map Name (TermReferenceId, (Term Symbol Ann, Type Symbol Ann)))
-> DefnsF
     (Map Name)
     (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
     (TermReferenceId, Decl Symbol Ann)
-> [(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.terms))
                  ThreeWay
  (DefnsF
     (Map Name)
     (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
     (TermReferenceId, Decl Symbol Ann))
hydratedDefns,
              $sel:types:Defns :: Map TermReferenceId (Decl Symbol Ann)
types =
                (DefnsF
   (Map Name)
   (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
   (TermReferenceId, Decl Symbol Ann)
 -> Map TermReferenceId (Decl Symbol Ann))
-> ThreeWay
     (DefnsF
        (Map Name)
        (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
        (TermReferenceId, Decl Symbol Ann))
-> Map TermReferenceId (Decl Symbol Ann)
forall m a. Monoid m => (a -> m) -> ThreeWay a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap
                  ((Map TermReferenceId (Decl Symbol Ann)
 -> (TermReferenceId, Decl Symbol Ann)
 -> Map TermReferenceId (Decl Symbol Ann))
-> Map TermReferenceId (Decl Symbol Ann)
-> [(TermReferenceId, Decl Symbol Ann)]
-> Map TermReferenceId (Decl Symbol Ann)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' (\Map TermReferenceId (Decl Symbol Ann)
acc (TermReferenceId
ref, Decl Symbol Ann
typ) -> TermReferenceId
-> Decl Symbol Ann
-> Map TermReferenceId (Decl Symbol Ann)
-> Map TermReferenceId (Decl Symbol Ann)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert TermReferenceId
ref Decl Symbol Ann
typ Map TermReferenceId (Decl Symbol Ann)
acc) Map TermReferenceId (Decl Symbol Ann)
forall k a. Map k a
Map.empty ([(TermReferenceId, Decl Symbol Ann)]
 -> Map TermReferenceId (Decl Symbol Ann))
-> (DefnsF
      (Map Name)
      (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
      (TermReferenceId, Decl Symbol Ann)
    -> [(TermReferenceId, Decl Symbol Ann)])
-> DefnsF
     (Map Name)
     (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
     (TermReferenceId, Decl Symbol Ann)
-> Map TermReferenceId (Decl Symbol Ann)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map Name (TermReferenceId, Decl Symbol Ann)
-> [(TermReferenceId, Decl Symbol Ann)]
forall k a. Map k a -> [a]
Map.elems (Map Name (TermReferenceId, Decl Symbol Ann)
 -> [(TermReferenceId, Decl Symbol Ann)])
-> (DefnsF
      (Map Name)
      (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
      (TermReferenceId, Decl Symbol Ann)
    -> Map Name (TermReferenceId, Decl Symbol Ann))
-> DefnsF
     (Map Name)
     (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
     (TermReferenceId, Decl Symbol Ann)
-> [(TermReferenceId, Decl Symbol Ann)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.types))
                  ThreeWay
  (DefnsF
     (Map Name)
     (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
     (TermReferenceId, Decl Symbol Ann))
hydratedDefns
            }

  -- Combine the LCA->Alice and LCA->Bob diffs together
  let diff :: DefnsF2 (Map Name) CombinedDiffOp Referent TermReference
diff =
        TwoWay (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
-> DefnsF2 (Map Name) CombinedDiffOp Referent TermReference
combineDiffs TwoWay (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
diffs

  -- Partition the combined diff into the conflicted things and the unconflicted things
  let (TwoWay (DefnsF (Map Name) TermReference TermReference)
conflicts, DefnsF Unconflicts Referent TermReference
unconflicts) =
        TwoWay
  (Defns (BiMultimap Referent Name) (BiMultimap TermReference Name))
-> TwoWay DeclNameLookup
-> DefnsF2 (Map Name) CombinedDiffOp Referent TermReference
-> (TwoWay (DefnsF (Map Name) TermReference TermReference),
    DefnsF Unconflicts Referent TermReference)
partitionCombinedDiffs (ThreeWay
  (Defns (BiMultimap Referent Name) (BiMultimap TermReference Name))
-> TwoWay
     (Defns (BiMultimap Referent Name) (BiMultimap TermReference Name))
forall a. ThreeWay a -> TwoWay a
ThreeWay.forgetLca Mergeblob0 libdep
blob.defns) TwoWay DeclNameLookup
declNameLookups DefnsF2 (Map Name) CombinedDiffOp Referent TermReference
diff

  -- Diff and merge libdeps
  let libdepsDiff :: Map NameSegment (LibdepDiffOp libdep)
      libdepsDiff :: Map NameSegment (LibdepDiffOp libdep)
libdepsDiff =
        ThreeWay (Map NameSegment libdep)
-> Map NameSegment (LibdepDiffOp libdep)
forall k v.
(Ord k, Eq v) =>
ThreeWay (Map k v) -> Map k (LibdepDiffOp v)
diffLibdeps Mergeblob0 libdep
blob.libdeps

  let libdeps :: Map NameSegment libdep
      libdeps :: Map NameSegment libdep
libdeps =
        (Set NameSegment -> NameSegment -> (NameSegment, NameSegment))
-> ThreeWay (Map NameSegment libdep)
-> Map NameSegment (LibdepDiffOp libdep)
-> Map NameSegment libdep
forall k v.
Ord k =>
(Set k -> k -> (k, k))
-> ThreeWay (Map k v) -> Map k (LibdepDiffOp v) -> Map k v
applyLibdepsDiff Set NameSegment -> NameSegment -> (NameSegment, NameSegment)
getTwoFreshLibdepNames Mergeblob0 libdep
blob.libdeps Map NameSegment (LibdepDiffOp libdep)
libdepsDiff

  pure
    Mergeblob1
      { TwoWay (DefnsF (Map Name) TermReference TermReference)
$sel:conflicts:Mergeblob1 :: TwoWay (DefnsF (Map Name) TermReference TermReference)
conflicts :: TwoWay (DefnsF (Map Name) TermReference TermReference)
conflicts,
        TwoWay DeclNameLookup
$sel:declNameLookups:Mergeblob1 :: TwoWay DeclNameLookup
declNameLookups :: TwoWay DeclNameLookup
declNameLookups,
        $sel:defns:Mergeblob1 :: ThreeWay
  (Defns (BiMultimap Referent Name) (BiMultimap TermReference Name))
defns = Mergeblob0 libdep
blob.defns,
        DefnsF2 (Map Name) CombinedDiffOp Referent TermReference
$sel:diff:Mergeblob1 :: DefnsF2 (Map Name) CombinedDiffOp Referent TermReference
diff :: DefnsF2 (Map Name) CombinedDiffOp Referent TermReference
diff,
        TwoWay (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
$sel:diffs:Mergeblob1 :: TwoWay (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
diffs :: TwoWay (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
diffs,
        ThreeWay
  (DefnsF
     (Map Name)
     (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
     (TermReferenceId, Decl Symbol Ann))
$sel:hydratedDefns:Mergeblob1 :: ThreeWay
  (DefnsF
     (Map Name)
     (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
     (TermReferenceId, Decl Symbol Ann))
hydratedDefns :: ThreeWay
  (DefnsF
     (Map Name)
     (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
     (TermReferenceId, Decl Symbol Ann))
hydratedDefns,
        PartialDeclNameLookup
$sel:lcaDeclNameLookup:Mergeblob1 :: PartialDeclNameLookup
lcaDeclNameLookup :: PartialDeclNameLookup
lcaDeclNameLookup,
        Map NameSegment libdep
$sel:libdeps:Mergeblob1 :: Map NameSegment libdep
libdeps :: Map NameSegment libdep
libdeps,
        Map NameSegment (LibdepDiffOp libdep)
$sel:libdepsDiff:Mergeblob1 :: Map NameSegment (LibdepDiffOp libdep)
libdepsDiff :: Map NameSegment (LibdepDiffOp libdep)
libdepsDiff,
        DefnsF Unconflicts Referent TermReference
$sel:unconflicts:Mergeblob1 :: DefnsF Unconflicts Referent TermReference
unconflicts :: DefnsF Unconflicts Referent TermReference
unconflicts
      }