Skip to content

Commit 9af301d

Browse files
authored
Merge pull request #5332 from unisonweb/24-09-05-merge-branch-dependents
bugfix: reuse unique type guids on merge conflicts
2 parents 3fc8271 + c118fa3 commit 9af301d

File tree

5 files changed

+717
-472
lines changed

5 files changed

+717
-472
lines changed

unison-cli/src/Unison/Codebase/Editor/HandleInput/Merge2.hs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,6 @@ doMerge info = do
313313
Left _typecheckErr -> Nothing
314314
Right blob5 -> Just blob5
315315

316-
let stageOneBranch = defnsAndLibdepsToBranch0 env.codebase blob3.stageOne mergedLibdeps
317-
318316
let parents =
319317
causals <&> \causal -> (causal.causalHash, Codebase.expectBranchForHash env.codebase causal.causalHash)
320318

@@ -326,7 +324,11 @@ doMerge info = do
326324
info.description
327325
( HandleInput.Branch.CreateFrom'NamespaceWithParent
328326
info.alice.projectAndBranch.branch
329-
(Branch.mergeNode stageOneBranch parents.alice parents.bob)
327+
( Branch.mergeNode
328+
(defnsAndLibdepsToBranch0 env.codebase blob3.stageTwo mergedLibdeps)
329+
parents.alice
330+
parents.bob
331+
)
330332
)
331333
info.alice.projectAndBranch.project
332334
(findTemporaryBranchName info.alice.projectAndBranch.project.projectId mergeSourceAndTarget)
@@ -338,11 +340,18 @@ doMerge info = do
338340
done (Output.MergeFailure scratchFilePath mergeSourceAndTarget temporaryBranchName)
339341

340342
Cli.runTransaction (Codebase.addDefsToCodebase env.codebase blob5.file)
341-
let stageTwoBranch = Branch.batchUpdates (typecheckedUnisonFileToBranchAdds blob5.file) stageOneBranch
342343
Cli.updateProjectBranchRoot_
343344
info.alice.projectAndBranch.branch
344345
info.description
345-
(\_aliceBranch -> Branch.mergeNode stageTwoBranch parents.alice parents.bob)
346+
( \_aliceBranch ->
347+
Branch.mergeNode
348+
( Branch.batchUpdates
349+
(typecheckedUnisonFileToBranchAdds blob5.file)
350+
(defnsAndLibdepsToBranch0 env.codebase blob3.stageOne mergedLibdeps)
351+
)
352+
parents.alice
353+
parents.bob
354+
)
346355
pure (Output.MergeSuccess mergeSourceAndTarget)
347356

348357
Cli.respond finalOutput

unison-core/src/Unison/Util/Defns.hs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ module Unison.Util.Defns
1313
zipDefns,
1414
zipDefnsWith,
1515
zipDefnsWith3,
16+
zipDefnsWith4,
1617
)
1718
where
1819

@@ -99,3 +100,14 @@ zipDefnsWith3 ::
99100
Defns tm4 ty4
100101
zipDefnsWith3 f g (Defns terms1 types1) (Defns terms2 types2) (Defns terms3 types3) =
101102
Defns (f terms1 terms2 terms3) (g types1 types2 types3)
103+
104+
zipDefnsWith4 ::
105+
(tm1 -> tm2 -> tm3 -> tm4 -> tm5) ->
106+
(ty1 -> ty2 -> ty3 -> ty4 -> ty5) ->
107+
Defns tm1 ty1 ->
108+
Defns tm2 ty2 ->
109+
Defns tm3 ty3 ->
110+
Defns tm4 ty4 ->
111+
Defns tm5 ty5
112+
zipDefnsWith4 f g (Defns terms1 types1) (Defns terms2 types2) (Defns terms3 types3) (Defns terms4 types4) =
113+
Defns (f terms1 terms2 terms3 terms4) (g types1 types2 types3 types4)

unison-merge/src/Unison/Merge/Mergeblob3.hs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ import Data.Zip (unzip)
1717
import Unison.DataDeclaration (Decl)
1818
import Unison.DataDeclaration qualified as DataDeclaration
1919
import Unison.DeclNameLookup (DeclNameLookup, expectConstructorNames)
20+
import Unison.DeclNameLookup qualified as DeclNameLookup
2021
import Unison.Merge.Mergeblob2 (Mergeblob2 (..))
2122
import Unison.Merge.PrettyPrintEnv (makePrettyPrintEnvs)
23+
import Unison.Merge.ThreeWay (ThreeWay)
2224
import Unison.Merge.ThreeWay qualified as ThreeWay
2325
import Unison.Merge.TwoWay (TwoWay)
2426
import Unison.Merge.TwoWay qualified as TwoWay
@@ -38,7 +40,7 @@ import Unison.Term (Term)
3840
import Unison.Type (Type)
3941
import Unison.Util.BiMultimap (BiMultimap)
4042
import Unison.Util.BiMultimap qualified as BiMultimap
41-
import Unison.Util.Defns (Defns (..), DefnsF, defnsAreEmpty, zipDefnsWith, zipDefnsWith3)
43+
import Unison.Util.Defns (Defns (..), DefnsF, defnsAreEmpty, zipDefnsWith, zipDefnsWith3, zipDefnsWith4)
4244
import Unison.Util.Pretty (ColorText, Pretty)
4345
import Unison.Util.Pretty qualified as Pretty
4446
import Unison.Util.Relation qualified as Relation
@@ -47,6 +49,7 @@ import Prelude hiding (unzip)
4749
data Mergeblob3 = Mergeblob3
4850
{ libdeps :: Names,
4951
stageOne :: DefnsF (Map Name) Referent TypeReference,
52+
stageTwo :: DefnsF (Map Name) Referent TypeReference,
5053
uniqueTypeGuids :: Map Name Text,
5154
unparsedFile :: Pretty ColorText
5255
}
@@ -64,6 +67,7 @@ makeMergeblob3 blob dependents0 libdeps authors =
6467

6568
-- Identify the unconflicted dependents we need to pull into the Unison file (either first for typechecking, if
6669
-- there aren't conflicts, or else for manual conflict resolution without a typechecking step, if there are)
70+
dependents :: TwoWay (DefnsF Set Name Name)
6771
dependents =
6872
filterDependents
6973
conflictsNames
@@ -105,6 +109,13 @@ makeMergeblob3 blob dependents0 libdeps authors =
105109
dependents
106110
(bimap BiMultimap.range BiMultimap.range blob.defns.lca),
107111
uniqueTypeGuids = makeUniqueTypeGuids blob.hydratedDefns,
112+
stageTwo =
113+
makeStageTwo
114+
blob.declNameLookups
115+
conflictsNames
116+
blob.unconflicts
117+
dependents
118+
(bimap BiMultimap.range BiMultimap.range <$> blob.defns),
108119
unparsedFile = makePrettyUnisonFile authors renderedConflicts renderedDependents
109120
}
110121

@@ -164,6 +175,41 @@ makeStageOneV :: Unconflicts v -> Set Name -> Map Name v -> Map Name v
164175
makeStageOneV unconflicts namesToDelete =
165176
(`Map.withoutKeys` namesToDelete) . Unconflicts.apply unconflicts
166177

178+
makeStageTwo ::
179+
forall term typ.
180+
TwoWay DeclNameLookup ->
181+
TwoWay (DefnsF Set Name Name) ->
182+
DefnsF Unconflicts term typ ->
183+
TwoWay (DefnsF Set Name Name) ->
184+
ThreeWay (DefnsF (Map Name) term typ) ->
185+
DefnsF (Map Name) term typ
186+
makeStageTwo declNameLookups conflicts unconflicts dependents defns =
187+
zipDefnsWith4 makeStageTwoV makeStageTwoV defns.lca aliceBiasedDependents unconflicts aliceConflicts
188+
where
189+
aliceConflicts :: DefnsF (Map Name) term typ
190+
aliceConflicts =
191+
zipDefnsWith
192+
(\defns conflicts -> Map.restrictKeys defns (conflicts <> aliceConstructorsOfTypeConflicts))
193+
Map.restrictKeys
194+
defns.alice
195+
conflicts.alice
196+
197+
aliceConstructorsOfTypeConflicts :: Set Name
198+
aliceConstructorsOfTypeConflicts =
199+
foldMap
200+
(Set.fromList . DeclNameLookup.expectConstructorNames declNameLookups.alice)
201+
conflicts.alice.types
202+
203+
aliceBiasedDependents :: DefnsF (Map Name) term typ
204+
aliceBiasedDependents =
205+
TwoWay.twoWay
206+
(zipDefnsWith (Map.unionWith const) (Map.unionWith const))
207+
(zipDefnsWith Map.restrictKeys Map.restrictKeys <$> ThreeWay.forgetLca defns <*> dependents)
208+
209+
makeStageTwoV :: Map Name v -> Map Name v -> Unconflicts v -> Map Name v -> Map Name v
210+
makeStageTwoV lca dependents unconflicts conflicts =
211+
Map.unionWith const conflicts (Unconflicts.apply unconflicts (Map.unionWith const dependents lca))
212+
167213
-- Given just named term/type reference ids, fill out all names that occupy the term and type namespaces. This is simply
168214
-- the given names plus all of the types' constructors.
169215
--

0 commit comments

Comments
 (0)