mirror of
https://github.com/unisonweb/unison.git
synced 2024-09-11 02:25:39 +03:00
get transcripts passing
This commit is contained in:
parent
4b68359e6e
commit
7506ae26b6
@ -1,8 +1,11 @@
|
||||
module Unison.PrettyPrintEnvDecl.Names
|
||||
( makePPED,
|
||||
makeFilePPED,
|
||||
makeCodebasePPED,
|
||||
)
|
||||
where
|
||||
|
||||
import Unison.Names (Names)
|
||||
import Unison.PrettyPrintEnv.Names qualified as PPE
|
||||
import Unison.PrettyPrintEnvDecl (PrettyPrintEnvDecl (PrettyPrintEnvDecl))
|
||||
|
||||
@ -11,3 +14,23 @@ makePPED namer suffixifier =
|
||||
PrettyPrintEnvDecl
|
||||
(PPE.makePPE namer PPE.dontSuffixify)
|
||||
(PPE.makePPE namer suffixifier)
|
||||
|
||||
-- | Make a PPED suitable for names in a Unison file.
|
||||
--
|
||||
-- Such names have special suffixification rules: aliases may *not* be referred to by a common suffix. For example, if
|
||||
-- a file contains
|
||||
--
|
||||
-- one.foo = 6
|
||||
-- two.foo = 6
|
||||
--
|
||||
-- then the suffix `foo` will *not* be accepted (currently). So, this PPE uses the "suffixify by name" strategy.
|
||||
makeFilePPED :: Names -> PrettyPrintEnvDecl
|
||||
makeFilePPED names =
|
||||
makePPED (PPE.namer names) (PPE.suffixifyByName names)
|
||||
|
||||
-- | Make a PPED suitable for names in the codebase. These names are hash qualified and suffixified by hash.
|
||||
makeCodebasePPED :: Names -> PrettyPrintEnvDecl
|
||||
makeCodebasePPED names =
|
||||
makePPED
|
||||
(PPE.hqNamer 10 names)
|
||||
(PPE.suffixifyByHash names)
|
||||
|
@ -5,14 +5,12 @@
|
||||
module Unison.Cli.UpdateUtils
|
||||
( -- * Loading definitions
|
||||
loadNamespaceDefinitions,
|
||||
ConflictedName (..),
|
||||
|
||||
-- * Narrowing definitions
|
||||
narrowDefns,
|
||||
|
||||
-- * Hydrating definitions
|
||||
hydrateDefns,
|
||||
hydrateDefnsRel,
|
||||
|
||||
-- * Rendering definitions
|
||||
renderDefnsForUnisonFile,
|
||||
@ -27,11 +25,9 @@ import Data.Foldable qualified as Foldable
|
||||
import Data.List qualified as List
|
||||
import Data.List.NonEmpty qualified as List.NonEmpty
|
||||
import Data.Map.Strict qualified as Map
|
||||
import Data.Semialign (alignWith)
|
||||
import Data.Set qualified as Set
|
||||
import Data.Set.NonEmpty (NESet)
|
||||
import Data.Set.NonEmpty qualified as Set.NonEmpty
|
||||
import Data.These (These (..))
|
||||
import U.Codebase.Branch qualified as V2
|
||||
import U.Codebase.Causal qualified
|
||||
import U.Codebase.Reference (TermReferenceId, TypeReferenceId)
|
||||
@ -61,15 +57,14 @@ import Unison.Type (Type)
|
||||
import Unison.Typechecker qualified as Typechecker
|
||||
import Unison.Util.BiMultimap (BiMultimap)
|
||||
import Unison.Util.BiMultimap qualified as BiMultimap
|
||||
import Unison.Util.Conflicted (Conflicted (..))
|
||||
import Unison.Util.Defn (Defn (..))
|
||||
import Unison.Util.Defns (Defns (..), DefnsF, DefnsF2)
|
||||
import Unison.Util.Monoid qualified as Monoid
|
||||
import Unison.Util.Nametree (Nametree (..), traverseNametreeWithName, unflattenNametree, unflattenNametrees)
|
||||
import Unison.Util.Nametree (Nametree (..), traverseNametreeWithName, unflattenNametrees)
|
||||
import Unison.Util.Pretty (ColorText, Pretty)
|
||||
import Unison.Util.Pretty qualified as Pretty
|
||||
import Unison.Util.Relation (Relation)
|
||||
import Unison.Util.Relation qualified as Relation
|
||||
import Unison.Util.Set qualified as Set
|
||||
import Unison.Var (Var)
|
||||
import Prelude hiding (unzip, zip, zipWith)
|
||||
|
||||
@ -85,7 +80,11 @@ loadNamespaceDefinitions ::
|
||||
(Monad m) =>
|
||||
(V2.Referent -> m Referent) ->
|
||||
V2.Branch m ->
|
||||
m (Either ConflictedName (Nametree (DefnsF (Map NameSegment) Referent TypeReference)))
|
||||
m
|
||||
( Either
|
||||
(Defn (Conflicted Name Referent) (Conflicted Name TypeReference))
|
||||
(Nametree (DefnsF (Map NameSegment) Referent TypeReference))
|
||||
)
|
||||
loadNamespaceDefinitions referent2to1 =
|
||||
fmap assertNamespaceHasNoConflictedNames . go (Map.delete NameSegment.libSegment)
|
||||
where
|
||||
@ -102,25 +101,25 @@ loadNamespaceDefinitions referent2to1 =
|
||||
go id child
|
||||
pure Nametree {value = Defns {terms, types}, children}
|
||||
|
||||
data ConflictedName
|
||||
= ConflictedName'Term !Name !(NESet Referent)
|
||||
| ConflictedName'Type !Name !(NESet TypeReference)
|
||||
|
||||
-- | Assert that there are no unconflicted names in a namespace.
|
||||
assertNamespaceHasNoConflictedNames ::
|
||||
Nametree (DefnsF2 (Map NameSegment) NESet Referent TypeReference) ->
|
||||
Either ConflictedName (Nametree (DefnsF (Map NameSegment) Referent TypeReference))
|
||||
Either
|
||||
(Defn (Conflicted Name Referent) (Conflicted Name TypeReference))
|
||||
(Nametree (DefnsF (Map NameSegment) Referent TypeReference))
|
||||
assertNamespaceHasNoConflictedNames =
|
||||
traverseNametreeWithName \names defns -> do
|
||||
traverseNametreeWithName \segments defns -> do
|
||||
let toName segment =
|
||||
Name.fromReverseSegments (segment List.NonEmpty.:| segments)
|
||||
terms <-
|
||||
defns.terms & Map.traverseWithKey \name ->
|
||||
assertUnconflicted (ConflictedName'Term (Name.fromReverseSegments (name List.NonEmpty.:| names)))
|
||||
defns.terms & Map.traverseWithKey \segment ->
|
||||
assertUnconflicted (TermDefn . Conflicted (toName segment))
|
||||
types <-
|
||||
defns.types & Map.traverseWithKey \name ->
|
||||
assertUnconflicted (ConflictedName'Type (Name.fromReverseSegments (name List.NonEmpty.:| names)))
|
||||
defns.types & Map.traverseWithKey \segment ->
|
||||
assertUnconflicted (TypeDefn . Conflicted (toName segment))
|
||||
pure Defns {terms, types}
|
||||
where
|
||||
assertUnconflicted :: (NESet ref -> ConflictedName) -> NESet ref -> Either ConflictedName ref
|
||||
assertUnconflicted :: (NESet ref -> x) -> NESet ref -> Either x ref
|
||||
assertUnconflicted conflicted refs
|
||||
| Set.NonEmpty.size refs == 1 = Right (Set.NonEmpty.findMin refs)
|
||||
| otherwise = Left (conflicted refs)
|
||||
@ -134,19 +133,28 @@ narrowDefns ::
|
||||
forall term typ.
|
||||
(Ord term, Ord typ) =>
|
||||
DefnsF (Relation Name) term typ ->
|
||||
Either (Defn Name Name) (Nametree (DefnsF (Map NameSegment) term typ))
|
||||
Either
|
||||
( Defn
|
||||
(Conflicted Name term)
|
||||
(Conflicted Name typ)
|
||||
)
|
||||
(Nametree (DefnsF (Map NameSegment) term typ))
|
||||
narrowDefns =
|
||||
fmap unflattenNametrees . bitraverse (mapLeft TermDefn . go) (mapLeft TypeDefn . go)
|
||||
fmap unflattenNametrees
|
||||
. bitraverse
|
||||
(go (\name -> TermDefn . Conflicted name))
|
||||
(go (\name -> TypeDefn . Conflicted name))
|
||||
where
|
||||
go :: (Ord ref) => Relation Name ref -> Either Name (Map Name ref)
|
||||
go =
|
||||
go :: forall ref x. (Ord ref) => (Name -> NESet ref -> x) -> Relation Name ref -> Either x (Map Name ref)
|
||||
go conflicted =
|
||||
Map.traverseWithKey unconflicted . Relation.domain
|
||||
where
|
||||
unconflicted :: Name -> Set ref -> Either Name ref
|
||||
unconflicted name refs =
|
||||
case Set.asSingleton refs of
|
||||
Nothing -> Left name
|
||||
Just ref -> Right ref
|
||||
unconflicted :: Name -> Set ref -> Either x ref
|
||||
unconflicted name refs0
|
||||
| Set.NonEmpty.size refs == 1 = Right (Set.NonEmpty.findMin refs)
|
||||
| otherwise = Left (conflicted name refs)
|
||||
where
|
||||
refs = Set.NonEmpty.unsafeFromSet refs0
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
-- Hydrating definitions
|
||||
@ -196,58 +204,6 @@ hydrateDefns_ getComponent defns modify =
|
||||
defns2 =
|
||||
BiMultimap.fromRange defns
|
||||
|
||||
-- | Like 'hydrateDefns', but when you have a relation (i.e. names can be conflicted). Maybe this code should be deleted
|
||||
-- in favor of just asserting that names can't be conflicted before doing something (since it's easy to resolve: just
|
||||
-- rename one). But, for now, this exists.
|
||||
hydrateDefnsRel ::
|
||||
forall m name term typ.
|
||||
(Monad m, Ord name, Ord term, Ord typ) =>
|
||||
(Hash -> m [term]) ->
|
||||
(Hash -> m [typ]) ->
|
||||
DefnsF (Relation name) TermReferenceId TypeReferenceId ->
|
||||
m (DefnsF (Relation name) term (TypeReferenceId, typ))
|
||||
hydrateDefnsRel getTermComponent getTypeComponent = do
|
||||
bitraverse hydrateTerms hydrateTypes
|
||||
where
|
||||
hydrateTerms :: Relation name TermReferenceId -> m (Relation name term)
|
||||
hydrateTerms terms =
|
||||
hydrateDefnsRel_ getTermComponent terms \_ _ -> id
|
||||
|
||||
hydrateTypes :: Relation name TypeReferenceId -> m (Relation name (TypeReferenceId, typ))
|
||||
hydrateTypes types =
|
||||
hydrateDefnsRel_ getTypeComponent types \_ -> (,)
|
||||
|
||||
hydrateDefnsRel_ ::
|
||||
forall a b name m.
|
||||
(Ord b, Monad m, Ord name) =>
|
||||
(Hash -> m [a]) ->
|
||||
Relation name Reference.Id ->
|
||||
(name -> Reference.Id -> a -> b) ->
|
||||
m (Relation name b)
|
||||
hydrateDefnsRel_ getComponent defns modify =
|
||||
let hashes :: [Hash]
|
||||
hashes =
|
||||
defns
|
||||
& Relation.toList
|
||||
& List.foldl' (\acc (_, ref) -> Set.insert (Reference.idToHash ref) acc) Set.empty
|
||||
& Set.toList
|
||||
in hashes & Monoid.foldMapM \hash -> do
|
||||
component <- getComponent hash
|
||||
pure
|
||||
( List.foldl'
|
||||
f
|
||||
Relation.empty
|
||||
(Reference.componentFor hash component)
|
||||
)
|
||||
where
|
||||
f :: Relation name b -> (Reference.Id, a) -> Relation name b
|
||||
f acc (ref, x) =
|
||||
List.foldl' (g ref x) acc (Set.toList (Relation.lookupRan ref defns))
|
||||
|
||||
g :: Reference.Id -> a -> Relation name b -> name -> Relation name b
|
||||
g ref x acc2 name =
|
||||
Relation.insert name (modify name ref x) acc2
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
-- Rendering definitions
|
||||
|
||||
|
@ -44,7 +44,7 @@ import Unison.Cli.Monad (Cli)
|
||||
import Unison.Cli.Monad qualified as Cli
|
||||
import Unison.Cli.MonadUtils qualified as Cli
|
||||
import Unison.Cli.ProjectUtils qualified as ProjectUtils
|
||||
import Unison.Cli.UpdateUtils (hydrateDefns, renderDefnsForUnisonFile, ConflictedName (..), loadNamespaceDefinitions)
|
||||
import Unison.Cli.UpdateUtils (hydrateDefns, loadNamespaceDefinitions, renderDefnsForUnisonFile)
|
||||
import Unison.Codebase (Codebase)
|
||||
import Unison.Codebase qualified as Codebase
|
||||
import Unison.Codebase.Branch (Branch0)
|
||||
@ -70,7 +70,7 @@ import Unison.Debug qualified as Debug
|
||||
import Unison.Hash qualified as Hash
|
||||
import Unison.Merge.CombineDiffs (CombinedDiffOp (..), combineDiffs)
|
||||
import Unison.Merge.Database (MergeDatabase (..), makeMergeDatabase, referent2to1)
|
||||
import Unison.Merge.DeclCoherencyCheck (IncoherentDeclReason (..), checkDeclCoherency, lenientCheckDeclCoherency)
|
||||
import Unison.Merge.DeclCoherencyCheck (checkDeclCoherency, lenientCheckDeclCoherency)
|
||||
import Unison.Merge.DeclNameLookup (DeclNameLookup (..), expectConstructorNames)
|
||||
import Unison.Merge.Diff qualified as Merge
|
||||
import Unison.Merge.DiffOp (DiffOp (..))
|
||||
@ -228,10 +228,8 @@ doMerge info = do
|
||||
(defns3, declNameLookups, lcaDeclNameLookup) <- do
|
||||
let emptyNametree = Nametree {value = Defns Map.empty Map.empty, children = Map.empty}
|
||||
let loadDefns branch =
|
||||
Cli.runTransaction (loadNamespaceDefinitions (referent2to1 db) branch) & onLeftM \conflictedName ->
|
||||
done case conflictedName of
|
||||
ConflictedName'Term name refs -> Output.MergeConflictedTermName name refs
|
||||
ConflictedName'Type name refs -> Output.MergeConflictedTypeName name refs
|
||||
Cli.runTransaction (loadNamespaceDefinitions (referent2to1 db) branch)
|
||||
& onLeftM (done . Output.ConflictedDefn "merge")
|
||||
let load = \case
|
||||
Nothing -> pure (emptyNametree, DeclNameLookup Map.empty Map.empty)
|
||||
Just (who, branch) -> do
|
||||
@ -244,14 +242,7 @@ doMerge info = do
|
||||
Reference.toId
|
||||
defns
|
||||
)
|
||||
& onLeftM \err ->
|
||||
done case err of
|
||||
IncoherentDeclReason'ConstructorAlias typeName conName1 conName2 ->
|
||||
Output.MergeConstructorAlias who typeName conName1 conName2
|
||||
IncoherentDeclReason'MissingConstructorName name -> Output.MergeMissingConstructorName who name
|
||||
IncoherentDeclReason'NestedDeclAlias shorterName longerName ->
|
||||
Output.MergeNestedDeclAlias who shorterName longerName
|
||||
IncoherentDeclReason'StrayConstructor _typeRef name -> Output.MergeStrayConstructor who name
|
||||
& onLeftM (done . Output.IncoherentDeclDuringMerge who)
|
||||
pure (defns, declNameLookup)
|
||||
|
||||
(aliceDefns0, aliceDeclNameLookup) <- load (Just (mergeTarget, branches.alice))
|
||||
|
@ -4,7 +4,6 @@ module Unison.Codebase.Editor.HandleInput.Update2
|
||||
|
||||
-- * Misc helpers to be organized later
|
||||
addDefinitionsToUnisonFile,
|
||||
makeUnisonFile,
|
||||
findCtorNames,
|
||||
findCtorNamesMaybe,
|
||||
forwardCtorNames,
|
||||
@ -15,7 +14,6 @@ module Unison.Codebase.Editor.HandleInput.Update2
|
||||
typecheckedUnisonFileToBranchAdds,
|
||||
getNamespaceDependentsOf,
|
||||
getNamespaceDependentsOf2,
|
||||
makeComplicatedPPE,
|
||||
)
|
||||
where
|
||||
|
||||
@ -28,24 +26,22 @@ import Data.List.NonEmpty qualified as NonEmpty
|
||||
import Data.List.NonEmpty.Extra ((|>))
|
||||
import Data.Map qualified as Map
|
||||
import Data.Maybe (fromJust)
|
||||
import Data.Semialign (alignWith)
|
||||
import Data.Set qualified as Set
|
||||
import Data.Text qualified as Text
|
||||
import Data.Text.Lazy qualified as Lazy.Text
|
||||
import Data.These (These (..))
|
||||
import Text.Pretty.Simple (pShow)
|
||||
import U.Codebase.Reference (Reference, TermReferenceId)
|
||||
import U.Codebase.Reference qualified as Reference
|
||||
import U.Codebase.Sqlite.Operations qualified as Operations
|
||||
import U.Codebase.Sqlite.Operations qualified as Ops
|
||||
import Unison.Builtin.Decls qualified as Decls
|
||||
import Unison.Cli.Monad (Cli)
|
||||
import Unison.Cli.Monad (Cli, Env (..))
|
||||
import Unison.Cli.Monad qualified as Cli
|
||||
import Unison.Cli.MonadUtils qualified as Cli
|
||||
import Unison.Cli.Pretty qualified as Pretty
|
||||
import Unison.Cli.TypeCheck (computeTypecheckingEnvironment)
|
||||
import Unison.Cli.UniqueTypeGuidLookup qualified as Cli
|
||||
import Unison.Cli.UpdateUtils (hydrateDefns, hydrateDefnsRel, narrowDefns, renderDefnsForUnisonFile)
|
||||
import Unison.Cli.UpdateUtils (hydrateDefns, narrowDefns, renderDefnsForUnisonFile)
|
||||
import Unison.Codebase qualified as Codebase
|
||||
import Unison.Codebase.Branch (Branch0)
|
||||
import Unison.Codebase.Branch qualified as Branch
|
||||
@ -67,13 +63,13 @@ import Unison.Debug qualified as Debug
|
||||
import Unison.FileParsers qualified as FileParsers
|
||||
import Unison.Hash (Hash)
|
||||
import Unison.Merge.DeclCoherencyCheck (checkDeclCoherency)
|
||||
import Unison.Merge.DeclNameLookup (DeclNameLookup (..))
|
||||
import Unison.Name (Name)
|
||||
import Unison.Name qualified as Name
|
||||
import Unison.Name.Forward (ForwardName (..))
|
||||
import Unison.Name.Forward qualified as ForwardName
|
||||
import Unison.NameSegment qualified as NameSegment
|
||||
import Unison.NameSegment.Internal (NameSegment (NameSegment))
|
||||
import Unison.Names (Names (Names))
|
||||
import Unison.Names (Names)
|
||||
import Unison.Names qualified as Names
|
||||
import Unison.Parser.Ann (Ann)
|
||||
import Unison.Parser.Ann qualified as Ann
|
||||
@ -83,7 +79,7 @@ import Unison.PrettyPrintEnv.Names qualified as PPE
|
||||
import Unison.PrettyPrintEnvDecl (PrettyPrintEnvDecl)
|
||||
import Unison.PrettyPrintEnvDecl qualified as PPED
|
||||
import Unison.PrettyPrintEnvDecl.Names qualified as PPED
|
||||
import Unison.Reference (Reference' (..), TypeReference, TypeReferenceId)
|
||||
import Unison.Reference (TypeReference, TypeReferenceId)
|
||||
import Unison.Reference qualified as Reference (fromId)
|
||||
import Unison.Referent (Referent)
|
||||
import Unison.Referent qualified as Referent
|
||||
@ -103,7 +99,7 @@ import Unison.Util.BiMultimap (BiMultimap)
|
||||
import Unison.Util.BiMultimap qualified as BiMultimap
|
||||
import Unison.Util.Defns (Defns (..), DefnsF, defnsAreEmpty)
|
||||
import Unison.Util.Monoid qualified as Monoid
|
||||
import Unison.Util.Nametree (Nametree, unflattenNametree, flattenNametrees)
|
||||
import Unison.Util.Nametree (flattenNametrees)
|
||||
import Unison.Util.Pretty (ColorText, Pretty)
|
||||
import Unison.Util.Pretty qualified as Pretty
|
||||
import Unison.Util.Relation (Relation)
|
||||
@ -114,7 +110,7 @@ import Unison.WatchKind qualified as WK
|
||||
|
||||
handleUpdate2 :: Cli ()
|
||||
handleUpdate2 = do
|
||||
Cli.Env {codebase, writeSource} <- ask
|
||||
env <- ask
|
||||
tuf <- Cli.expectLatestTypecheckedFile
|
||||
let termAndDeclNames = getTermAndDeclNames tuf
|
||||
pp <- Cli.getCurrentProjectPath
|
||||
@ -122,13 +118,11 @@ handleUpdate2 = do
|
||||
let currentBranch0ExcludingLibdeps = Branch.deleteLibdeps currentBranch0
|
||||
let namesIncludingLibdeps = Branch.toNames currentBranch0
|
||||
let namesExcludingLibdeps = Branch.toNames currentBranch0ExcludingLibdeps
|
||||
let ctorNames = forwardCtorNames namesExcludingLibdeps
|
||||
|
||||
-- Assert that the namespace doesn't have any conflicted names
|
||||
defns <-
|
||||
narrowDefns
|
||||
(Branch.deepDefns currentBranch0ExcludingLibdeps)
|
||||
& onLeft \conflictedName -> wundefined
|
||||
narrowDefns (Branch.deepDefns currentBranch0ExcludingLibdeps)
|
||||
& onLeft (Cli.returnEarly . Output.ConflictedDefn "update")
|
||||
|
||||
-- Assert that the namespace doesn't have any incoherent decls
|
||||
declNameLookup <-
|
||||
@ -139,55 +133,54 @@ handleUpdate2 = do
|
||||
Reference.toId
|
||||
defns
|
||||
)
|
||||
& onLeftM \err -> wundefined
|
||||
|
||||
let defns1 = flattenNametrees defns
|
||||
& onLeftM (Cli.returnEarly . Output.IncoherentDeclDuringUpdate)
|
||||
|
||||
Cli.respond Output.UpdateLookingForDependents
|
||||
|
||||
dependents0 <-
|
||||
(dependents, hydratedDependents) <-
|
||||
Cli.runTransaction do
|
||||
getNamespaceDependentsOf2
|
||||
defns1
|
||||
(getExistingReferencesNamed termAndDeclNames namesExcludingLibdeps)
|
||||
-- Get all dependents of things being updated
|
||||
dependents0 <-
|
||||
getNamespaceDependentsOf2
|
||||
(flattenNametrees defns)
|
||||
(getExistingReferencesNamed termAndDeclNames namesExcludingLibdeps)
|
||||
|
||||
-- Throw away the dependents that are shadowed by the file itself
|
||||
let dependents1 :: DefnsF (Map Name) TermReferenceId TypeReferenceId
|
||||
dependents1 =
|
||||
bimap
|
||||
(`Map.withoutKeys` (Set.map Name.unsafeParseVar (UF.termNamespaceBindings tuf)))
|
||||
(`Map.withoutKeys` (Set.map Name.unsafeParseVar (UF.typeNamespaceBindings tuf)))
|
||||
dependents0
|
||||
-- Throw away the dependents that are shadowed by the file itself
|
||||
let dependents1 :: DefnsF (Map Name) TermReferenceId TypeReferenceId
|
||||
dependents1 =
|
||||
bimap
|
||||
(`Map.withoutKeys` (Set.map Name.unsafeParseVar (UF.termNamespaceBindings tuf)))
|
||||
(`Map.withoutKeys` (Set.map Name.unsafeParseVar (UF.typeNamespaceBindings tuf)))
|
||||
dependents0
|
||||
|
||||
-- Hydrate the dependents for rendering
|
||||
hydratedDependents <-
|
||||
hydrateDefns
|
||||
(Codebase.unsafeGetTermComponent env.codebase)
|
||||
Operations.expectDeclComponent
|
||||
dependents1
|
||||
|
||||
pure (dependents1, hydratedDependents)
|
||||
|
||||
secondTuf <- do
|
||||
case defnsAreEmpty dependents1 of
|
||||
case defnsAreEmpty dependents of
|
||||
-- If there are no dependents of the updates, then just use the already-typechecked file.
|
||||
True -> pure tuf
|
||||
False -> do
|
||||
hydratedDependents <-
|
||||
Cli.runTransaction do
|
||||
hydrateDefns
|
||||
(Codebase.unsafeGetTermComponent codebase)
|
||||
Operations.expectDeclComponent
|
||||
dependents1
|
||||
|
||||
let ppe = makeComplicatedPPE2 10 namesIncludingLibdeps (UF.typecheckedToNames tuf) dependents1
|
||||
|
||||
let renderedDependents :: DefnsF (Map Name) (Pretty ColorText) (Pretty ColorText)
|
||||
renderedDependents =
|
||||
renderDefnsForUnisonFile declNameLookup ppe hydratedDependents
|
||||
Cli.respond Output.UpdateStartTypechecking
|
||||
|
||||
let prettyUnisonFile =
|
||||
makePrettyUnisonFile (Pretty.prettyUnisonFile ppe (UF.discardTypes tuf)) renderedDependents
|
||||
|
||||
Cli.respond Output.UpdateStartTypechecking
|
||||
let ppe = makePPE 10 namesIncludingLibdeps (UF.typecheckedToNames tuf) dependents
|
||||
in makePrettyUnisonFile
|
||||
(Pretty.prettyUnisonFile ppe (UF.discardTypes tuf))
|
||||
(renderDefnsForUnisonFile declNameLookup ppe hydratedDependents)
|
||||
|
||||
parsingEnv <- makeParsingEnv pp namesIncludingLibdeps
|
||||
|
||||
secondTuf <-
|
||||
prettyParseTypecheck2 prettyUnisonFile parsingEnv & onLeftM \prettyUf -> do
|
||||
scratchFilePath <- fst <$> Cli.expectLatestFile
|
||||
liftIO $ writeSource (Text.pack scratchFilePath) (Text.pack $ Pretty.toPlain 80 prettyUf)
|
||||
liftIO $ env.writeSource (Text.pack scratchFilePath) (Text.pack $ Pretty.toPlain 80 prettyUf)
|
||||
Cli.returnEarly Output.UpdateTypecheckingFailure
|
||||
|
||||
Cli.respond Output.UpdateTypecheckingSuccess
|
||||
@ -201,7 +194,7 @@ handleUpdate2 = do
|
||||
Codebase.addDefsToCodebase env.codebase secondTuf
|
||||
typecheckedUnisonFileToBranchUpdates
|
||||
abort
|
||||
(findCtorNamesMaybe Output.UOUUpdate namesExcludingLibdeps ctorNames Nothing)
|
||||
(\typeName -> Right (Map.lookup typeName declNameLookup.declToConstructors))
|
||||
secondTuf
|
||||
Cli.stepAt "update" (path, Branch.batchUpdates branchUpdates)
|
||||
|
||||
@ -219,7 +212,7 @@ makePrettyUnisonFile originalFile dependents =
|
||||
<> Pretty.newline
|
||||
<> ( dependents
|
||||
& inAlphabeticalOrder
|
||||
& let f = foldMap (<> "\n") in bifoldMap f f
|
||||
& let f = foldMap (\defn -> defn <> Pretty.newline <> Pretty.newline) in bifoldMap f f
|
||||
)
|
||||
where
|
||||
inAlphabeticalOrder :: DefnsF (Map Name) a b -> DefnsF [] a b
|
||||
@ -308,7 +301,10 @@ typecheckedUnisonFileToBranchUpdates abort getConstructors tuf = do
|
||||
-- some decls will be deleted, we want to delete their
|
||||
-- constructors as well
|
||||
deleteConstructorActions <-
|
||||
(maybe [] (map (BranchUtil.makeAnnihilateTermName . Path.splitFromName)) <$> getConstructors (Name.unsafeParseVar symbol)) & onLeft abort
|
||||
( maybe [] (map (BranchUtil.makeAnnihilateTermName . Path.splitFromName))
|
||||
<$> getConstructors (Name.unsafeParseVar symbol)
|
||||
)
|
||||
& onLeft abort
|
||||
let deleteTypeAction = BranchUtil.makeAnnihilateTypeName split
|
||||
split = splitVar symbol
|
||||
insertTypeAction = BranchUtil.makeAddTypeName split (Reference.fromId typeRefId)
|
||||
@ -635,72 +631,16 @@ getNamespaceDependentsOf2 defns dependencies = do
|
||||
-- However, the following file will not fail to parse, if `one.foo` and `two.foo` are aliases in the codebase:
|
||||
--
|
||||
-- hey = foo + foo
|
||||
makeComplicatedPPE ::
|
||||
Int ->
|
||||
Names ->
|
||||
Names ->
|
||||
DefnsF (Relation Name) TermReferenceId TypeReferenceId ->
|
||||
PrettyPrintEnvDecl
|
||||
makeComplicatedPPE hashLen names initialFileNames dependents =
|
||||
primaryPPE `PPED.addFallback` secondaryPPE
|
||||
where
|
||||
primaryPPE =
|
||||
PPED.makePPED (PPE.namer namesInTheFile) (PPE.suffixifyByName namesInTheFile)
|
||||
|
||||
secondaryPPE =
|
||||
PPED.makePPED
|
||||
(PPE.hqNamer hashLen names)
|
||||
-- We don't want to over-suffixify for a reference in the namespace. For example, say we have "foo.bar" in the
|
||||
-- namespace and "oink.bar" in the file. "bar" may be a unique suffix among the namespace names, but would be
|
||||
-- ambiguous in the context of namespace + file names.
|
||||
--
|
||||
-- So, we use `unionLeftName`, which starts with the LHS names (the namespace), and adds to it names from the
|
||||
-- RHS (the initial file names, i.e. what was originally saved) that don't already exist in the LHS.
|
||||
(PPE.suffixifyByHash (Names.unionLeftName names initialFileNames))
|
||||
|
||||
namesInTheFile =
|
||||
initialFileNames <> dependentsNames
|
||||
|
||||
dependentsNames =
|
||||
Names
|
||||
{ terms = Relation.mapRan Referent.fromTermReferenceId dependents.terms,
|
||||
types = Relation.mapRan Reference.fromId dependents.types
|
||||
}
|
||||
|
||||
-- The big picture behind PPE building, though there are many details:
|
||||
--
|
||||
-- * We are updating old references to new references by rendering old references as names that are then parsed
|
||||
-- back to resolve to new references (the world's weirdest implementation of AST substitution).
|
||||
--
|
||||
-- * We have to render names that refer to definitions in the file with a different suffixification strategy
|
||||
-- (namely, "suffixify by name") than names that refer to things in the codebase.
|
||||
--
|
||||
-- This is because you *may* refer to aliases that share a suffix by that suffix for definitions in the
|
||||
-- codebase, but not in the file.
|
||||
--
|
||||
-- For example, the following file will fail to parse:
|
||||
--
|
||||
-- one.foo = 10
|
||||
-- two.foo = 10
|
||||
-- hey = foo + foo -- "Which foo do you mean? There are two."
|
||||
--
|
||||
-- However, the following file will not fail to parse, if `one.foo` and `two.foo` are aliases in the codebase:
|
||||
--
|
||||
-- hey = foo + foo
|
||||
makeComplicatedPPE2 ::
|
||||
makePPE ::
|
||||
Int ->
|
||||
Names ->
|
||||
Names ->
|
||||
DefnsF (Map Name) TermReferenceId TypeReferenceId ->
|
||||
PrettyPrintEnvDecl
|
||||
makeComplicatedPPE2 hashLen names initialFileNames dependents =
|
||||
primaryPPE `PPED.addFallback` secondaryPPE
|
||||
where
|
||||
primaryPPE =
|
||||
PPED.makePPED (PPE.namer namesInTheFile) (PPE.suffixifyByName namesInTheFile)
|
||||
|
||||
secondaryPPE =
|
||||
PPED.makePPED
|
||||
makePPE hashLen names initialFileNames dependents =
|
||||
PPED.addFallback
|
||||
(PPED.makeFilePPED (initialFileNames <> Names.fromUnconflictedReferenceIds dependents))
|
||||
( PPED.makePPED
|
||||
(PPE.hqNamer hashLen names)
|
||||
-- We don't want to over-suffixify for a reference in the namespace. For example, say we have "foo.bar" in the
|
||||
-- namespace and "oink.bar" in the file. "bar" may be a unique suffix among the namespace names, but would be
|
||||
@ -709,12 +649,4 @@ makeComplicatedPPE2 hashLen names initialFileNames dependents =
|
||||
-- So, we use `unionLeftName`, which starts with the LHS names (the namespace), and adds to it names from the
|
||||
-- RHS (the initial file names, i.e. what was originally saved) that don't already exist in the LHS.
|
||||
(PPE.suffixifyByHash (Names.unionLeftName names initialFileNames))
|
||||
|
||||
namesInTheFile =
|
||||
initialFileNames <> dependentsNames
|
||||
|
||||
dependentsNames =
|
||||
Names
|
||||
{ terms = Relation.fromMap (Map.map Referent.fromTermReferenceId dependents.terms),
|
||||
types = Relation.fromMap (Map.map Reference.fromId dependents.types)
|
||||
}
|
||||
)
|
||||
|
@ -27,7 +27,6 @@ import Unison.Codebase.Editor.HandleInput.Update2
|
||||
findCtorNamesMaybe,
|
||||
forwardCtorNames,
|
||||
getNamespaceDependentsOf,
|
||||
makeComplicatedPPE,
|
||||
makeParsingEnv,
|
||||
prettyParseTypecheck,
|
||||
typecheckedUnisonFileToBranchUpdates,
|
||||
@ -47,6 +46,7 @@ import Unison.PrettyPrintEnv qualified as PPE
|
||||
import Unison.PrettyPrintEnv.Names qualified as PPE
|
||||
import Unison.PrettyPrintEnvDecl (PrettyPrintEnvDecl (..))
|
||||
import Unison.PrettyPrintEnvDecl qualified as PPED (addFallback)
|
||||
import Unison.PrettyPrintEnvDecl.Names qualified as PPED (makeCodebasePPED, makeFilePPED)
|
||||
import Unison.Project (ProjectBranchName)
|
||||
import Unison.Reference (TermReference, TypeReference)
|
||||
import Unison.Referent (Referent)
|
||||
@ -138,7 +138,6 @@ handleUpgrade oldName newName = do
|
||||
(findCtorNames Output.UOUUpgrade currentLocalNames currentLocalConstructorNames)
|
||||
dependents
|
||||
UnisonFile.emptyUnisonFile
|
||||
hashLength <- Codebase.hashLength
|
||||
pure
|
||||
( unisonFile,
|
||||
makeOldDepPPE
|
||||
@ -148,7 +147,8 @@ handleUpgrade oldName newName = do
|
||||
(Branch.toNames oldNamespace)
|
||||
(Branch.toNames oldLocalNamespace)
|
||||
(Branch.toNames newLocalNamespace)
|
||||
`PPED.addFallback` makeComplicatedPPE hashLength currentDeepNamesSansOld mempty dependents
|
||||
`PPED.addFallback` PPED.makeFilePPED (Names.fromReferenceIds dependents)
|
||||
`PPED.addFallback` PPED.makeCodebasePPED currentDeepNamesSansOld
|
||||
)
|
||||
|
||||
pp@(PP.ProjectPath project projectBranch _path) <- Cli.getCurrentProjectPath
|
||||
|
@ -57,7 +57,7 @@ import Unison.Hash (Hash)
|
||||
import Unison.HashQualified qualified as HQ
|
||||
import Unison.HashQualifiedPrime qualified as HQ'
|
||||
import Unison.LabeledDependency (LabeledDependency)
|
||||
import Unison.Merge.DeclCoherencyCheck (IncoherentDeclReasons (..))
|
||||
import Unison.Merge.DeclCoherencyCheck (IncoherentDeclReason, IncoherentDeclReasons (..))
|
||||
import Unison.Name (Name)
|
||||
import Unison.NameSegment (NameSegment)
|
||||
import Unison.Names (Names)
|
||||
@ -84,6 +84,8 @@ import Unison.Term (Term)
|
||||
import Unison.Type (Type)
|
||||
import Unison.Typechecker.Context qualified as Context
|
||||
import Unison.UnisonFile qualified as UF
|
||||
import Unison.Util.Conflicted (Conflicted)
|
||||
import Unison.Util.Defn (Defn)
|
||||
import Unison.Util.Defns (DefnsF, defnsAreEmpty)
|
||||
import Unison.Util.Pretty qualified as P
|
||||
import Unison.Util.Relation (Relation)
|
||||
@ -199,15 +201,15 @@ data Output
|
||||
| -- | Function found, but has improper type
|
||||
-- Note: the constructor name is misleading here; we weren't necessarily looking for a "main".
|
||||
BadMainFunction
|
||||
-- | what we were trying to do (e.g. "run", "io.test")
|
||||
Text
|
||||
-- ^ what we were trying to do (e.g. "run", "io.test")
|
||||
-- | name of function
|
||||
(HQ.HashQualified Name)
|
||||
-- ^ name of function
|
||||
-- | bad type of function
|
||||
(Type Symbol Ann)
|
||||
-- ^ bad type of function
|
||||
PPE.PrettyPrintEnv
|
||||
-- | acceptable type(s) of function
|
||||
[Type Symbol Ann]
|
||||
-- ^ acceptable type(s) of function
|
||||
| BranchEmpty WhichBranchEmpty
|
||||
| LoadPullRequest (ReadRemoteNamespace Void) (ReadRemoteNamespace Void) Path' Path' Path' Path'
|
||||
| CreatedNewBranch Path.Absolute
|
||||
@ -244,12 +246,12 @@ data Output
|
||||
-- for terms. This additional info is used to provide an enhanced
|
||||
-- error message.
|
||||
SearchTermsNotFoundDetailed
|
||||
-- | @True@ if we are searching for a term, @False@ if we are searching for a type
|
||||
Bool
|
||||
-- ^ @True@ if we are searching for a term, @False@ if we are searching for a type
|
||||
-- | Misses (search terms that returned no hits for terms or types)
|
||||
[HQ.HashQualified Name]
|
||||
-- ^ Misses (search terms that returned no hits for terms or types)
|
||||
-- | Hits for types if we are searching for terms or terms if we are searching for types
|
||||
[HQ.HashQualified Name]
|
||||
-- ^ Hits for types if we are searching for terms or terms if we are searching for types
|
||||
| -- ask confirmation before deleting the last branch that contains some defns
|
||||
-- `Path` is one of the paths the user has requested to delete, and is paired
|
||||
-- with whatever named definitions would not have any remaining names if
|
||||
@ -392,8 +394,8 @@ data Output
|
||||
| CalculatingDiff
|
||||
| -- | The `local` in a `clone remote local` is ambiguous
|
||||
AmbiguousCloneLocal
|
||||
-- | Treating `local` as a project. We may know the branch name, if it was provided in `remote`.
|
||||
(ProjectAndBranch ProjectName ProjectBranchName)
|
||||
-- ^ Treating `local` as a project. We may know the branch name, if it was provided in `remote`.
|
||||
(ProjectAndBranch ProjectName ProjectBranchName)
|
||||
| -- | The `remote` in a `clone remote local` is ambiguous
|
||||
AmbiguousCloneRemote ProjectName (ProjectAndBranch ProjectName ProjectBranchName)
|
||||
@ -419,20 +421,17 @@ data Output
|
||||
| MergeSuccess !MergeSourceAndTarget
|
||||
| MergeSuccessFastForward !MergeSourceAndTarget
|
||||
| MergeConflictedAliases !MergeSourceOrTarget !Name !Name
|
||||
| MergeConflictedTermName !Name !(NESet Referent)
|
||||
| MergeConflictedTypeName !Name !(NESet TypeReference)
|
||||
| MergeConflictInvolvingBuiltin !Name
|
||||
| MergeConstructorAlias !MergeSourceOrTarget !Name !Name !Name
|
||||
| MergeDefnsInLib !MergeSourceOrTarget
|
||||
| MergeMissingConstructorName !MergeSourceOrTarget !Name
|
||||
| MergeNestedDeclAlias !MergeSourceOrTarget !Name !Name
|
||||
| MergeStrayConstructor !MergeSourceOrTarget !Name
|
||||
| InstalledLibdep !(ProjectAndBranch ProjectName ProjectBranchName) !NameSegment
|
||||
| NoUpgradeInProgress
|
||||
| UseLibInstallNotPull !(ProjectAndBranch ProjectName ProjectBranchName)
|
||||
| PullIntoMissingBranch !(ReadRemoteNamespace Share.RemoteProjectBranch) !(ProjectAndBranch (Maybe ProjectName) ProjectBranchName)
|
||||
| NoMergeInProgress
|
||||
| Output'DebugSynhashTerm !TermReference !Hash !Text
|
||||
| ConflictedDefn !Text {- what operation? -} !(Defn (Conflicted Name Referent) (Conflicted Name TypeReference))
|
||||
| IncoherentDeclDuringMerge !MergeSourceOrTarget !IncoherentDeclReason
|
||||
| IncoherentDeclDuringUpdate !IncoherentDeclReason
|
||||
|
||||
data MoreEntriesThanShown = MoreEntriesThanShown | AllEntriesShown
|
||||
deriving (Eq, Show)
|
||||
@ -658,20 +657,17 @@ isFailure o = case o of
|
||||
MergeSuccess {} -> False
|
||||
MergeSuccessFastForward {} -> False
|
||||
MergeConflictedAliases {} -> True
|
||||
MergeConflictedTermName {} -> True
|
||||
MergeConflictedTypeName {} -> True
|
||||
MergeConflictInvolvingBuiltin {} -> True
|
||||
MergeConstructorAlias {} -> True
|
||||
MergeDefnsInLib {} -> True
|
||||
MergeMissingConstructorName {} -> True
|
||||
MergeNestedDeclAlias {} -> True
|
||||
MergeStrayConstructor {} -> True
|
||||
InstalledLibdep {} -> False
|
||||
NoUpgradeInProgress {} -> True
|
||||
UseLibInstallNotPull {} -> False
|
||||
PullIntoMissingBranch {} -> True
|
||||
NoMergeInProgress {} -> True
|
||||
Output'DebugSynhashTerm {} -> False
|
||||
ConflictedDefn {} -> True
|
||||
IncoherentDeclDuringMerge {} -> True
|
||||
IncoherentDeclDuringUpdate {} -> True
|
||||
|
||||
isNumberedFailure :: NumberedOutput -> Bool
|
||||
isNumberedFailure = \case
|
||||
|
@ -85,7 +85,7 @@ import Unison.Hash32 (Hash32)
|
||||
import Unison.HashQualified qualified as HQ
|
||||
import Unison.HashQualifiedPrime qualified as HQ'
|
||||
import Unison.LabeledDependency as LD
|
||||
import Unison.Merge.DeclCoherencyCheck (IncoherentDeclReasons (..))
|
||||
import Unison.Merge.DeclCoherencyCheck (IncoherentDeclReason (..), IncoherentDeclReasons (..))
|
||||
import Unison.Name (Name)
|
||||
import Unison.Name qualified as Name
|
||||
import Unison.NameSegment qualified as NameSegment
|
||||
@ -141,6 +141,8 @@ import Unison.Term (Term)
|
||||
import Unison.Term qualified as Term
|
||||
import Unison.Type (Type)
|
||||
import Unison.UnisonFile qualified as UF
|
||||
import Unison.Util.Conflicted (Conflicted (..))
|
||||
import Unison.Util.Defn (Defn (..))
|
||||
import Unison.Util.Defns (Defns (..))
|
||||
import Unison.Util.List qualified as List
|
||||
import Unison.Util.Monoid (intercalateMap)
|
||||
@ -1384,12 +1386,6 @@ notifyUser dir = \case
|
||||
<> P.newline
|
||||
<> P.newline
|
||||
<> P.wrap "and then try merging again."
|
||||
MergeConflictedTermName name _refs ->
|
||||
pure . P.wrap $
|
||||
"The term name" <> prettyName name <> "is ambiguous. Please resolve the ambiguity before merging."
|
||||
MergeConflictedTypeName name _refs ->
|
||||
pure . P.wrap $
|
||||
"The type name" <> prettyName name <> "is ambiguous. Please resolve the ambiguity before merging."
|
||||
MergeConflictInvolvingBuiltin name ->
|
||||
pure . P.lines $
|
||||
[ P.wrap "Sorry, I wasn't able to perform the merge:",
|
||||
@ -1406,22 +1402,6 @@ notifyUser dir = \case
|
||||
<> "the same on both branches, or making neither of them a builtin, and then try the merge again."
|
||||
)
|
||||
]
|
||||
-- Note [ConstructorAliasMessage] If you change this, also change the other similar one
|
||||
MergeConstructorAlias aliceOrBob typeName conName1 conName2 ->
|
||||
pure . P.lines $
|
||||
[ P.wrap "Sorry, I wasn't able to perform the merge:",
|
||||
"",
|
||||
P.wrap $
|
||||
"On"
|
||||
<> P.group (prettyMergeSourceOrTarget aliceOrBob <> ",")
|
||||
<> "the type"
|
||||
<> prettyName typeName
|
||||
<> "has a constructor with multiple names, and I can't perform a merge in this situation:",
|
||||
"",
|
||||
P.indentN 2 (P.bulleted [prettyName conName1, prettyName conName2]),
|
||||
"",
|
||||
P.wrap "Please delete all but one name for each constructor, and then try merging again."
|
||||
]
|
||||
-- Note [DefnsInLibMessage] If you change this, also change the other similar one
|
||||
MergeDefnsInLib aliceOrBob ->
|
||||
pure . P.lines $
|
||||
@ -1435,54 +1415,6 @@ notifyUser dir = \case
|
||||
"",
|
||||
P.wrap "Please move or remove it and then try merging again."
|
||||
]
|
||||
-- Note [MissingConstructorNameMessage] If you change this, also change the other similar one
|
||||
MergeMissingConstructorName aliceOrBob name ->
|
||||
pure . P.lines $
|
||||
[ P.wrap "Sorry, I wasn't able to perform the merge:",
|
||||
"",
|
||||
P.wrap $
|
||||
"On"
|
||||
<> P.group (prettyMergeSourceOrTarget aliceOrBob <> ",")
|
||||
<> "the type"
|
||||
<> prettyName name
|
||||
<> "has some constructors with missing names, and I can't perform a merge in this situation.",
|
||||
"",
|
||||
P.wrap $
|
||||
"You can use"
|
||||
<> IP.makeExample IP.view [prettyName name]
|
||||
<> "and"
|
||||
<> IP.makeExample IP.aliasTerm ["<hash>", prettyName name <> ".<ConstructorName>"]
|
||||
<> "to give names to each unnamed constructor, and then try the merge again."
|
||||
]
|
||||
-- Note [NestedDeclAliasMessage] If you change this, also change the other similar one
|
||||
MergeNestedDeclAlias aliceOrBob shorterName longerName ->
|
||||
pure . P.wrap $
|
||||
"On"
|
||||
<> P.group (prettyMergeSourceOrTarget aliceOrBob <> ",")
|
||||
<> "the type"
|
||||
<> prettyName longerName
|
||||
<> "is an alias of"
|
||||
<> P.group (prettyName shorterName <> ".")
|
||||
<> "I'm not able to perform a merge when a type exists nested under an alias of itself. Please separate them or"
|
||||
<> "delete one copy, and then try merging again."
|
||||
-- Note [StrayConstructorMessage] If you change this, also change the other similar one
|
||||
MergeStrayConstructor aliceOrBob name ->
|
||||
pure . P.lines $
|
||||
[ P.wrap $
|
||||
"Sorry, I wasn't able to perform the merge, because I need all constructor names to be nested somewhere"
|
||||
<> "beneath the corresponding type name.",
|
||||
"",
|
||||
P.wrap $
|
||||
"On"
|
||||
<> P.group (prettyMergeSourceOrTarget aliceOrBob <> ",")
|
||||
<> "the constructor"
|
||||
<> prettyName name
|
||||
<> "is not nested beneath the corresponding type name. Please either use"
|
||||
<> IP.makeExample' IP.moveAll
|
||||
<> "to move it, or if it's an extra copy, you can simply"
|
||||
<> IP.makeExample' IP.delete
|
||||
<> "it. Then try the merge again."
|
||||
]
|
||||
PreviewMergeAlreadyUpToDate src dest ->
|
||||
pure . P.callout "😶" $
|
||||
P.wrap $
|
||||
@ -2161,6 +2093,139 @@ notifyUser dir = \case
|
||||
<> P.newline
|
||||
<> "Synhash tokens: "
|
||||
<> P.text filename
|
||||
ConflictedDefn operation defn ->
|
||||
pure . P.wrap $
|
||||
( case defn of
|
||||
TermDefn (Conflicted name _refs) -> "The term name" <> prettyName name <> "is ambiguous."
|
||||
TypeDefn (Conflicted name _refs) -> "The type name" <> prettyName name <> "is ambiguous."
|
||||
)
|
||||
<> "Please resolve the ambiguity, then try to"
|
||||
<> P.text operation
|
||||
<> "again."
|
||||
IncoherentDeclDuringMerge aliceOrBob reason ->
|
||||
case reason of
|
||||
-- Note [ConstructorAliasMessage] If you change this, also change the other similar ones
|
||||
IncoherentDeclReason'ConstructorAlias typeName conName1 conName2 ->
|
||||
pure . P.lines $
|
||||
[ P.wrap "Sorry, I wasn't able to perform the merge:",
|
||||
"",
|
||||
P.wrap $
|
||||
"On"
|
||||
<> P.group (prettyMergeSourceOrTarget aliceOrBob <> ",")
|
||||
<> "the type"
|
||||
<> prettyName typeName
|
||||
<> "has a constructor with multiple names, and I can't perform a merge in this situation:",
|
||||
"",
|
||||
P.indentN 2 (P.bulleted [prettyName conName1, prettyName conName2]),
|
||||
"",
|
||||
P.wrap "Please delete all but one name for each constructor, and then try merging again."
|
||||
]
|
||||
-- Note [MissingConstructorNameMessage] If you change this, also change the other similar ones
|
||||
IncoherentDeclReason'MissingConstructorName name ->
|
||||
pure . P.lines $
|
||||
[ P.wrap "Sorry, I wasn't able to perform the merge:",
|
||||
"",
|
||||
P.wrap $
|
||||
"On"
|
||||
<> P.group (prettyMergeSourceOrTarget aliceOrBob <> ",")
|
||||
<> "the type"
|
||||
<> prettyName name
|
||||
<> "has some constructors with missing names, and I can't perform a merge in this situation.",
|
||||
"",
|
||||
P.wrap $
|
||||
"You can use"
|
||||
<> IP.makeExample IP.view [prettyName name]
|
||||
<> "and"
|
||||
<> IP.makeExample IP.aliasTerm ["<hash>", prettyName name <> ".<ConstructorName>"]
|
||||
<> "to give names to each unnamed constructor, and then try the merge again."
|
||||
]
|
||||
-- Note [NestedDeclAliasMessage] If you change this, also change the other similar ones
|
||||
IncoherentDeclReason'NestedDeclAlias shorterName longerName ->
|
||||
pure . P.wrap $
|
||||
"On"
|
||||
<> P.group (prettyMergeSourceOrTarget aliceOrBob <> ",")
|
||||
<> "the type"
|
||||
<> prettyName longerName
|
||||
<> "is an alias of"
|
||||
<> P.group (prettyName shorterName <> ".")
|
||||
<> "I'm not able to perform a merge when a type exists nested under an alias of itself. Please separate them or"
|
||||
<> "delete one copy, and then try merging again."
|
||||
-- Note [StrayConstructorMessage] If you change this, also change the other similar ones
|
||||
IncoherentDeclReason'StrayConstructor _typeRef name ->
|
||||
pure . P.lines $
|
||||
[ P.wrap $
|
||||
"Sorry, I wasn't able to perform the merge, because I need all constructor names to be nested somewhere"
|
||||
<> "beneath the corresponding type name.",
|
||||
"",
|
||||
P.wrap $
|
||||
"On"
|
||||
<> P.group (prettyMergeSourceOrTarget aliceOrBob <> ",")
|
||||
<> "the constructor"
|
||||
<> prettyName name
|
||||
<> "is not nested beneath the corresponding type name. Please either use"
|
||||
<> IP.makeExample' IP.moveAll
|
||||
<> "to move it, or if it's an extra copy, you can simply"
|
||||
<> IP.makeExample' IP.delete
|
||||
<> "it. Then try the merge again."
|
||||
]
|
||||
IncoherentDeclDuringUpdate reason ->
|
||||
case reason of
|
||||
-- Note [ConstructorAliasMessage] If you change this, also change the other similar ones
|
||||
IncoherentDeclReason'ConstructorAlias typeName conName1 conName2 ->
|
||||
pure . P.lines $
|
||||
[ P.wrap "Sorry, I wasn't able to perform the update:",
|
||||
"",
|
||||
P.wrap $
|
||||
"The type"
|
||||
<> prettyName typeName
|
||||
<> "has a constructor with multiple names, and I can't perform an update in this situation:",
|
||||
"",
|
||||
P.indentN 2 (P.bulleted [prettyName conName1, prettyName conName2]),
|
||||
"",
|
||||
P.wrap "Please delete all but one name for each constructor, and then try updating again."
|
||||
]
|
||||
-- Note [MissingConstructorNameMessage] If you change this, also change the other similar ones
|
||||
IncoherentDeclReason'MissingConstructorName name ->
|
||||
pure . P.lines $
|
||||
[ P.wrap "Sorry, I wasn't able to perform the update:",
|
||||
"",
|
||||
P.wrap $
|
||||
"The type"
|
||||
<> prettyName name
|
||||
<> "has some constructors with missing names, and I can't perform an update in this situation.",
|
||||
"",
|
||||
P.wrap $
|
||||
"You can use"
|
||||
<> IP.makeExample IP.view [prettyName name]
|
||||
<> "and"
|
||||
<> IP.makeExample IP.aliasTerm ["<hash>", prettyName name <> ".<ConstructorName>"]
|
||||
<> "to give names to each unnamed constructor, and then try the update again."
|
||||
]
|
||||
-- Note [NestedDeclAliasMessage] If you change this, also change the other similar ones
|
||||
IncoherentDeclReason'NestedDeclAlias shorterName longerName ->
|
||||
pure . P.wrap $
|
||||
"The type"
|
||||
<> prettyName longerName
|
||||
<> "is an alias of"
|
||||
<> P.group (prettyName shorterName <> ".")
|
||||
<> "I'm not able to perform an update when a type exists nested under an alias of itself. Please separate"
|
||||
<> "them or delete one copy, and then try updating again."
|
||||
-- Note [StrayConstructorMessage] If you change this, also change the other similar ones
|
||||
IncoherentDeclReason'StrayConstructor _typeRef name ->
|
||||
pure . P.lines $
|
||||
[ P.wrap $
|
||||
"Sorry, I wasn't able to perform the update, because I need all constructor names to be nested somewhere"
|
||||
<> "beneath the corresponding type name.",
|
||||
"",
|
||||
P.wrap $
|
||||
"The constructor"
|
||||
<> prettyName name
|
||||
<> "is not nested beneath the corresponding type name. Please either use"
|
||||
<> IP.makeExample' IP.moveAll
|
||||
<> "to move it, or if it's an extra copy, you can simply"
|
||||
<> IP.makeExample' IP.delete
|
||||
<> "it. Then try the update again."
|
||||
]
|
||||
|
||||
prettyShareError :: ShareError -> Pretty
|
||||
prettyShareError =
|
||||
@ -2701,7 +2766,7 @@ handleTodoOutput todo
|
||||
things
|
||||
& map
|
||||
( \(typeName, prettyCon1, prettyCon2) ->
|
||||
-- Note [ConstructorAliasMessage] If you change this, also change the other similar one
|
||||
-- Note [ConstructorAliasMessage] If you change this, also change the other similar ones
|
||||
P.wrap ("The type" <> prettyName typeName <> "has a constructor with multiple names.")
|
||||
<> P.newline
|
||||
<> P.newline
|
||||
@ -2720,7 +2785,7 @@ handleTodoOutput todo
|
||||
for types0 \typ -> do
|
||||
n <- addNumberedArg (SA.Name typ)
|
||||
pure (n, typ)
|
||||
-- Note [MissingConstructorNameMessage] If you change this, also change the other similar one
|
||||
-- Note [MissingConstructorNameMessage] If you change this, also change the other similar ones
|
||||
pure $
|
||||
P.wrap
|
||||
"These types have some constructors with missing names."
|
||||
@ -2753,7 +2818,7 @@ handleTodoOutput todo
|
||||
n1 <- addNumberedArg (SA.Name short)
|
||||
n2 <- addNumberedArg (SA.Name long)
|
||||
pure (formatNum n1 <> prettyName short, formatNum n2 <> prettyName long)
|
||||
-- Note [NestedDeclAliasMessage] If you change this, also change the other similar one
|
||||
-- Note [NestedDeclAliasMessage] If you change this, also change the other similar ones
|
||||
pure $
|
||||
aliases1
|
||||
& map
|
||||
@ -2775,7 +2840,7 @@ handleTodoOutput todo
|
||||
nums <-
|
||||
for constructors \(_typeRef, constructor) -> do
|
||||
addNumberedArg (SA.Name constructor)
|
||||
-- Note [StrayConstructorMessage] If you change this, also change the other similar one
|
||||
-- Note [StrayConstructorMessage] If you change this, also change the other similar ones
|
||||
pure $
|
||||
P.wrap "These constructors are not nested beneath their corresponding type names:"
|
||||
<> P.newline
|
||||
|
@ -12,6 +12,8 @@ module Unison.Names
|
||||
filterByHQs,
|
||||
filterBySHs,
|
||||
filterTypes,
|
||||
fromReferenceIds,
|
||||
fromUnconflictedReferenceIds,
|
||||
map,
|
||||
makeAbsolute,
|
||||
makeRelative,
|
||||
@ -69,7 +71,7 @@ import Unison.Name (Name)
|
||||
import Unison.Name qualified as Name
|
||||
import Unison.NameSegment (NameSegment)
|
||||
import Unison.Prelude
|
||||
import Unison.Reference (Reference, TermReference, TypeReference)
|
||||
import Unison.Reference (Reference, TermReference, TermReferenceId, TypeReference, TypeReferenceId)
|
||||
import Unison.Reference qualified as Reference
|
||||
import Unison.Referent (Referent)
|
||||
import Unison.Referent qualified as Referent
|
||||
@ -105,6 +107,22 @@ instance Monoid (Names) where
|
||||
isEmpty :: Names -> Bool
|
||||
isEmpty n = R.null n.terms && R.null n.types
|
||||
|
||||
-- | Construct a 'Names' from unconflicted reference ids.
|
||||
fromReferenceIds :: DefnsF (Relation Name) TermReferenceId TypeReferenceId -> Names
|
||||
fromReferenceIds defns =
|
||||
Names
|
||||
{ terms = Relation.mapRan Referent.fromTermReferenceId defns.terms,
|
||||
types = Relation.mapRan Reference.fromId defns.types
|
||||
}
|
||||
|
||||
-- | Construct a 'Names' from unconflicted reference ids.
|
||||
fromUnconflictedReferenceIds :: DefnsF (Map Name) TermReferenceId TypeReferenceId -> Names
|
||||
fromUnconflictedReferenceIds defns =
|
||||
Names
|
||||
{ terms = Relation.fromMap (Map.map Referent.fromTermReferenceId defns.terms),
|
||||
types = Relation.fromMap (Map.map Reference.fromId defns.types)
|
||||
}
|
||||
|
||||
map :: (Name -> Name) -> Names -> Names
|
||||
map f (Names {terms, types}) = Names terms' types'
|
||||
where
|
||||
@ -542,7 +560,7 @@ lenientToNametree names =
|
||||
(lenientRelationToNametree names.terms)
|
||||
(lenientRelationToNametree names.types)
|
||||
where
|
||||
lenientRelationToNametree :: Ord a => Relation Name a -> Nametree (Map NameSegment a)
|
||||
lenientRelationToNametree :: (Ord a) => Relation Name a -> Nametree (Map NameSegment a)
|
||||
lenientRelationToNametree =
|
||||
-- The partial `Set.findMin` is fine here because Relation.domain only has non-empty Set values. A NESet would be
|
||||
-- better.
|
||||
|
10
unison-core/src/Unison/Util/Conflicted.hs
Normal file
10
unison-core/src/Unison/Util/Conflicted.hs
Normal file
@ -0,0 +1,10 @@
|
||||
module Unison.Util.Conflicted
|
||||
( Conflicted (..),
|
||||
)
|
||||
where
|
||||
|
||||
import Data.Set.NonEmpty (NESet)
|
||||
|
||||
-- | A conflicted thing.
|
||||
data Conflicted n a
|
||||
= Conflicted !n !(NESet a)
|
@ -55,6 +55,7 @@ library
|
||||
Unison.Type
|
||||
Unison.Type.Names
|
||||
Unison.Util.Components
|
||||
Unison.Util.Conflicted
|
||||
Unison.Util.Defn
|
||||
Unison.Util.Defns
|
||||
Unison.Util.Nametree
|
||||
|
@ -92,10 +92,14 @@ scratch/ns2> update
|
||||
scratch/main> diff.namespace /ns1: /ns2:
|
||||
scratch/ns2> alias.term d d'
|
||||
scratch/ns2> alias.type A A'
|
||||
scratch/ns2> alias.term A.A A'.A
|
||||
scratch/ns2> alias.type X X'
|
||||
scratch/ns2> alias.term X.x X'.x
|
||||
scratch/main> diff.namespace /ns1: /ns2:
|
||||
scratch/ns1> alias.type X X2
|
||||
scratch/ns1> alias.term X.x X2.x
|
||||
scratch/ns2> alias.type A' A''
|
||||
scratch/ns2> alias.term A'.A A''.A
|
||||
scratch/ns2> branch /ns3
|
||||
scratch/ns2> alias.term fromJust' yoohoo
|
||||
scratch/ns2> delete.term.verbose fromJust'
|
||||
|
@ -199,10 +199,18 @@ scratch/ns2> alias.type A A'
|
||||
|
||||
Done.
|
||||
|
||||
scratch/ns2> alias.term A.A A'.A
|
||||
|
||||
Done.
|
||||
|
||||
scratch/ns2> alias.type X X'
|
||||
|
||||
Done.
|
||||
|
||||
scratch/ns2> alias.term X.x X'.x
|
||||
|
||||
Done.
|
||||
|
||||
scratch/main> diff.namespace /ns1: /ns2:
|
||||
|
||||
Resolved name conflicts:
|
||||
@ -238,17 +246,29 @@ scratch/main> diff.namespace /ns1: /ns2:
|
||||
|
||||
16. X 17. X' (added)
|
||||
|
||||
18. fromJust' ┐ 19. fromJust#gjmq673r1v (removed)
|
||||
20. fromJust#gjmq673r1v ┘
|
||||
18. A.A 19. A'.A (added)
|
||||
|
||||
20. fromJust' ┐ 21. fromJust#gjmq673r1v (removed)
|
||||
22. fromJust#gjmq673r1v ┘
|
||||
|
||||
23. X.x 24. X'.x (added)
|
||||
|
||||
scratch/ns1> alias.type X X2
|
||||
|
||||
Done.
|
||||
|
||||
scratch/ns1> alias.term X.x X2.x
|
||||
|
||||
Done.
|
||||
|
||||
scratch/ns2> alias.type A' A''
|
||||
|
||||
Done.
|
||||
|
||||
scratch/ns2> alias.term A'.A A''.A
|
||||
|
||||
Done.
|
||||
|
||||
scratch/ns2> branch /ns3
|
||||
|
||||
Done. I've created the ns3 branch based off of ns2.
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Update on conflict
|
||||
|
||||
Updating conflicted definitions works fine.
|
||||
Conflicted definitions prevent `update` from succeeding.
|
||||
|
||||
```ucm:hide
|
||||
scratch/main> builtins.merge lib.builtins
|
||||
@ -21,7 +21,6 @@ scratch/main> delete.term temp
|
||||
x = 3
|
||||
```
|
||||
|
||||
```ucm
|
||||
```ucm:error
|
||||
scratch/main> update
|
||||
scratch/main> view x
|
||||
```
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Update on conflict
|
||||
|
||||
Updating conflicted definitions works fine.
|
||||
Conflicted definitions prevent `update` from succeeding.
|
||||
|
||||
``` unison
|
||||
x = 1
|
||||
@ -59,14 +59,7 @@ x = 3
|
||||
``` ucm
|
||||
scratch/main> update
|
||||
|
||||
Okay, I'm searching the branch for code that needs to be
|
||||
updated...
|
||||
|
||||
Done.
|
||||
|
||||
scratch/main> view x
|
||||
|
||||
x : Nat
|
||||
x = 3
|
||||
The term name x is ambiguous. Please resolve the ambiguity,
|
||||
then try to update again.
|
||||
|
||||
```
|
||||
|
@ -70,6 +70,11 @@ myproject/main> update
|
||||
|
||||
```
|
||||
``` unison:added-by-ucm scratch.u
|
||||
foo = +30
|
||||
|
||||
-- The definitions below are not compatible with the updated definitions above.
|
||||
-- Please fix the errors and run `update` again.
|
||||
|
||||
bar : Nat
|
||||
bar =
|
||||
use Nat +
|
||||
@ -85,6 +90,5 @@ d.y.y.y.y =
|
||||
use Nat +
|
||||
foo + 10
|
||||
|
||||
foo = +30
|
||||
```
|
||||
|
||||
|
@ -68,12 +68,16 @@ scratch/main> update
|
||||
|
||||
```
|
||||
``` unison:added-by-ucm scratch.u
|
||||
foo : Int
|
||||
foo = +5
|
||||
|
||||
-- The definitions below are not compatible with the updated definitions above.
|
||||
-- Please fix the errors and run `update` again.
|
||||
|
||||
bar : Nat
|
||||
bar =
|
||||
use Nat +
|
||||
foo + 10
|
||||
|
||||
foo : Int
|
||||
foo = +5
|
||||
```
|
||||
|
||||
|
@ -51,10 +51,14 @@ scratch/main> update
|
||||
|
||||
```
|
||||
``` unison:added-by-ucm scratch.u
|
||||
foo n = "hello, world!"
|
||||
|
||||
-- The definitions below are not compatible with the updated definitions above.
|
||||
-- Please fix the errors and run `update` again.
|
||||
|
||||
test> mynamespace.foo.test =
|
||||
n = 2
|
||||
if foo n == 2 then [Ok "passed"] else [Fail "wat"]
|
||||
|
||||
foo n = "hello, world!"
|
||||
```
|
||||
|
||||
|
@ -15,9 +15,6 @@ scratch/main> alias.term Foo.Bar Foo.BarAlias
|
||||
unique type Foo = Bar Nat Nat
|
||||
```
|
||||
|
||||
Bug: we leave `Foo.BarAlias` in the namespace with a nameless decl.
|
||||
|
||||
```ucm
|
||||
```ucm:error
|
||||
scratch/main> update
|
||||
scratch/main> find.verbose
|
||||
```
|
||||
|
@ -45,27 +45,18 @@ unique type Foo = Bar Nat Nat
|
||||
type Foo
|
||||
|
||||
```
|
||||
Bug: we leave `Foo.BarAlias` in the namespace with a nameless decl.
|
||||
|
||||
``` ucm
|
||||
scratch/main> update
|
||||
|
||||
Okay, I'm searching the branch for code that needs to be
|
||||
updated...
|
||||
|
||||
Done.
|
||||
|
||||
scratch/main> find.verbose
|
||||
|
||||
1. -- #8fk6k0j208th1ia4vnjtoc5fomd6le540prec255svg71bcfga9dofrvoq1d7v6010d6b6em4q51p8st5c5juhrev72cnnel8ko3o1g
|
||||
type Foo
|
||||
|
||||
2. -- #8fk6k0j208th1ia4vnjtoc5fomd6le540prec255svg71bcfga9dofrvoq1d7v6010d6b6em4q51p8st5c5juhrev72cnnel8ko3o1g#0
|
||||
Foo.Bar : Nat -> Nat -> Foo
|
||||
|
||||
3. -- #b509v3eg4kehsg29g6pvrogeb71ue32nm2fj9284n4i7lprsr7u9a7g6s695d09du0fsfti6rrsk1s62q5thpr1jjkqb3us3s0lrd60#0
|
||||
Foo.BarAlias : Nat -> #b509v3eg4k
|
||||
|
||||
Sorry, I wasn't able to perform the update:
|
||||
|
||||
The type Foo has a constructor with multiple names, and I
|
||||
can't perform an update in this situation:
|
||||
|
||||
* Foo.Bar
|
||||
* Foo.BarAlias
|
||||
|
||||
Please delete all but one name for each constructor, and then
|
||||
try updating again.
|
||||
|
||||
```
|
||||
|
@ -65,11 +65,15 @@ scratch/main> update
|
||||
|
||||
```
|
||||
``` unison:added-by-ucm scratch.u
|
||||
type Foo = Bar Nat
|
||||
|
||||
-- The definitions below are not compatible with the updated definitions above.
|
||||
-- Please fix the errors and run `update` again.
|
||||
|
||||
foo : Foo -> Nat
|
||||
foo = cases
|
||||
Bar n -> n
|
||||
Baz n m -> n Nat.+ m
|
||||
|
||||
type Foo = Bar Nat
|
||||
```
|
||||
|
||||
|
@ -104,6 +104,11 @@ scratch/main> find.verbose
|
||||
|
||||
```
|
||||
``` unison:added-by-ucm scratch.u
|
||||
type Foo = { bar : Nat }
|
||||
|
||||
-- The definitions below are not compatible with the updated definitions above.
|
||||
-- Please fix the errors and run `update` again.
|
||||
|
||||
Foo.baz : Foo -> Int
|
||||
Foo.baz = cases Foo _ baz -> baz
|
||||
|
||||
@ -113,6 +118,5 @@ Foo.baz.modify f = cases Foo bar baz -> Foo bar (f baz)
|
||||
Foo.baz.set : Int -> Foo -> Foo
|
||||
Foo.baz.set baz1 = cases Foo bar _ -> Foo bar baz1
|
||||
|
||||
type Foo = { bar : Nat }
|
||||
```
|
||||
|
||||
|
@ -54,15 +54,13 @@ scratch/main> view Foo
|
||||
|
||||
scratch/main> update
|
||||
|
||||
Okay, I'm searching the branch for code that needs to be
|
||||
updated...
|
||||
|
||||
I couldn't complete the update because the type Foo has
|
||||
unnamed constructors. (I currently need each constructor to
|
||||
have a name somewhere under the type name.)
|
||||
Sorry, I wasn't able to perform the update:
|
||||
|
||||
The type Foo has some constructors with missing names, and I
|
||||
can't perform an update in this situation.
|
||||
|
||||
You can use `view Foo` and
|
||||
`alias.term <hash> Foo.<ConstructorName>` to give names to
|
||||
each constructor, and then try the update again.
|
||||
each unnamed constructor, and then try the update again.
|
||||
|
||||
```
|
||||
|
@ -17,10 +17,6 @@ scratch/main> add
|
||||
unique type Foo = Bar Nat Nat
|
||||
```
|
||||
|
||||
Bug: we want this update to be rejected earlier, because it violates the "decl coherency" precondition that there's
|
||||
only one name for each constructor. We instead get too far in the update process, and are delivered a bogus scratch.u
|
||||
file to stare at.
|
||||
|
||||
```ucm:error
|
||||
scratch/main> update
|
||||
```
|
||||
|
@ -48,28 +48,12 @@ unique type Foo = Bar Nat Nat
|
||||
type Foo
|
||||
|
||||
```
|
||||
Bug: we want this update to be rejected earlier, because it violates the "decl coherency" precondition that there's
|
||||
only one name for each constructor. We instead get too far in the update process, and are delivered a bogus scratch.u
|
||||
file to stare at.
|
||||
|
||||
``` ucm
|
||||
scratch/main> update
|
||||
|
||||
Okay, I'm searching the branch for code that needs to be
|
||||
updated...
|
||||
|
||||
That's done. Now I'm making sure everything typechecks...
|
||||
|
||||
Typechecking failed. I've updated your scratch file with the
|
||||
definitions that need fixing. Once the file is compiling, try
|
||||
`update` again.
|
||||
The type A.B is an alias of A. I'm not able to perform an
|
||||
update when a type exists nested under an alias of itself.
|
||||
Please separate them or delete one copy, and then try updating
|
||||
again.
|
||||
|
||||
```
|
||||
``` unison:added-by-ucm scratch.u
|
||||
structural type A = B.OneAlias Foo
|
||||
|
||||
structural type A.B = OneAlias Foo
|
||||
|
||||
type Foo = Bar Nat Nat
|
||||
```
|
||||
|
||||
|
@ -15,9 +15,6 @@ scratch/main> alias.term Foo.Bar Stray.BarAlias
|
||||
unique type Foo = Bar Nat Nat
|
||||
```
|
||||
|
||||
Bug: we leave `Stray.BarAlias` in the namespace with a nameless decl.
|
||||
|
||||
```ucm
|
||||
```ucm:error
|
||||
scratch/main> update
|
||||
scratch/main> find.verbose
|
||||
```
|
||||
|
@ -45,27 +45,16 @@ unique type Foo = Bar Nat Nat
|
||||
type Foo
|
||||
|
||||
```
|
||||
Bug: we leave `Stray.BarAlias` in the namespace with a nameless decl.
|
||||
|
||||
``` ucm
|
||||
scratch/main> update
|
||||
|
||||
Okay, I'm searching the branch for code that needs to be
|
||||
updated...
|
||||
|
||||
Done.
|
||||
|
||||
scratch/main> find.verbose
|
||||
|
||||
1. -- #8fk6k0j208th1ia4vnjtoc5fomd6le540prec255svg71bcfga9dofrvoq1d7v6010d6b6em4q51p8st5c5juhrev72cnnel8ko3o1g
|
||||
type Foo
|
||||
|
||||
2. -- #8fk6k0j208th1ia4vnjtoc5fomd6le540prec255svg71bcfga9dofrvoq1d7v6010d6b6em4q51p8st5c5juhrev72cnnel8ko3o1g#0
|
||||
Foo.Bar : Nat -> Nat -> Foo
|
||||
|
||||
3. -- #b509v3eg4kehsg29g6pvrogeb71ue32nm2fj9284n4i7lprsr7u9a7g6s695d09du0fsfti6rrsk1s62q5thpr1jjkqb3us3s0lrd60#0
|
||||
Stray.BarAlias : Nat -> #b509v3eg4k
|
||||
|
||||
Sorry, I wasn't able to perform the update, because I need all
|
||||
constructor names to be nested somewhere beneath the
|
||||
corresponding type name.
|
||||
|
||||
The constructor Stray.BarAlias is not nested beneath the
|
||||
corresponding type name. Please either use `move` to move it,
|
||||
or if it's an extra copy, you can simply `delete` it. Then try
|
||||
the update again.
|
||||
|
||||
```
|
||||
|
@ -56,15 +56,13 @@ scratch/main> view Foo
|
||||
|
||||
scratch/main> update
|
||||
|
||||
Okay, I'm searching the branch for code that needs to be
|
||||
updated...
|
||||
|
||||
I couldn't complete the update because the type Foo has
|
||||
unnamed constructors. (I currently need each constructor to
|
||||
have a name somewhere under the type name.)
|
||||
Sorry, I wasn't able to perform the update:
|
||||
|
||||
The type Foo has some constructors with missing names, and I
|
||||
can't perform an update in this situation.
|
||||
|
||||
You can use `view Foo` and
|
||||
`alias.term <hash> Foo.<ConstructorName>` to give names to
|
||||
each constructor, and then try the update again.
|
||||
each unnamed constructor, and then try the update again.
|
||||
|
||||
```
|
||||
|
@ -60,9 +60,13 @@ scratch/main> update
|
||||
|
||||
```
|
||||
``` unison:added-by-ucm scratch.u
|
||||
type Foo = Bar Nat Nat
|
||||
|
||||
-- The definitions below are not compatible with the updated definitions above.
|
||||
-- Please fix the errors and run `update` again.
|
||||
|
||||
incrFoo : Foo -> Foo
|
||||
incrFoo = cases Bar n -> Bar (n Nat.+ 1)
|
||||
|
||||
type Foo = Bar Nat Nat
|
||||
```
|
||||
|
||||
|
@ -58,8 +58,12 @@ scratch/main> update
|
||||
|
||||
```
|
||||
``` unison:added-by-ucm scratch.u
|
||||
type Foo a = Bar Nat a
|
||||
|
||||
-- The definitions below are not compatible with the updated definitions above.
|
||||
-- Please fix the errors and run `update` again.
|
||||
|
||||
type Baz = Qux Foo
|
||||
|
||||
type Foo a = Bar Nat a
|
||||
```
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user