mirror of
https://github.com/unisonweb/unison.git
synced 2024-09-21 23:37:23 +03:00
⅄ trunk → 21-12-05-sqlite-query-exception
This commit is contained in:
commit
5e183f5971
@ -2,6 +2,7 @@
|
||||
module Unison.Util.Map
|
||||
( bimap,
|
||||
bitraverse,
|
||||
deleteLookup,
|
||||
foldMapM,
|
||||
unionWithM,
|
||||
)
|
||||
@ -20,6 +21,11 @@ bimap fa fb = Map.fromList . map (B.bimap fa fb) . Map.toList
|
||||
bitraverse :: (Applicative f, Ord a') => (a -> f a') -> (b -> f b') -> Map a b -> f (Map a' b')
|
||||
bitraverse fa fb = fmap Map.fromList . traverse (B.bitraverse fa fb) . Map.toList
|
||||
|
||||
-- | Like 'Map.delete', but returns the value as well.
|
||||
deleteLookup :: Ord k => k -> Map k v -> (Maybe v, Map k v)
|
||||
deleteLookup =
|
||||
Map.alterF (,Nothing)
|
||||
|
||||
-- | Construct a map from a foldable container by mapping each element to monadic action that returns a key and a value.
|
||||
--
|
||||
-- The map is constructed from the left: if two elements map to the same key, the second will overwrite the first.
|
||||
|
@ -45,6 +45,7 @@ default-extensions:
|
||||
- NamedFieldPuns
|
||||
- NumericUnderscores
|
||||
- OverloadedStrings
|
||||
- PatternSynonyms
|
||||
- ScopedTypeVariables
|
||||
- TupleSections
|
||||
- TypeApplications
|
||||
|
@ -9,6 +9,8 @@ module Unison.Sqlite.Exception
|
||||
|
||||
-- ** @SqliteQueryException@
|
||||
SqliteQueryException (..),
|
||||
pattern SqliteBusyException,
|
||||
isSqliteBusyException,
|
||||
SqliteQueryExceptionInfo (..),
|
||||
throwSqliteQueryException,
|
||||
SomeSqliteExceptionReason (..),
|
||||
@ -74,7 +76,7 @@ rethrowAsSqliteConnectException name file exception = do
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
-- SomeSqliteException
|
||||
-- └── SqliteConnectException
|
||||
-- └── SqliteQueryException
|
||||
|
||||
-- | A @SqliteQueryException@ represents an exception thrown during processing a query, paired with some context that
|
||||
-- resulted in the exception.
|
||||
@ -101,6 +103,15 @@ instance Exception SqliteQueryException where
|
||||
toException = toException . SomeSqliteException
|
||||
fromException = fromException >=> \(SomeSqliteException e) -> cast e
|
||||
|
||||
pattern SqliteBusyException :: SqliteQueryException
|
||||
pattern SqliteBusyException <- (isSqliteBusyException -> True)
|
||||
|
||||
isSqliteBusyException :: SqliteQueryException -> Bool
|
||||
isSqliteBusyException SqliteQueryException {exception = SomeSqliteExceptionReason reason} =
|
||||
case cast reason of
|
||||
Just (Sqlite.SQLError Sqlite.ErrorBusy _ _) -> True
|
||||
_ -> False
|
||||
|
||||
data SqliteQueryExceptionInfo params connection = SqliteQueryExceptionInfo
|
||||
{ connection :: connection,
|
||||
sql :: Sql,
|
||||
|
@ -24,12 +24,12 @@ data JournalMode
|
||||
|
||||
journalModeFromText :: Text -> Maybe JournalMode
|
||||
journalModeFromText = \case
|
||||
"DELETE" -> Just JournalMode'DELETE
|
||||
"TRUNCATE" -> Just JournalMode'TRUNCATE
|
||||
"PERSIST" -> Just JournalMode'PERSIST
|
||||
"MEMORY" -> Just JournalMode'MEMORY
|
||||
"WAL" -> Just JournalMode'WAL
|
||||
"OFF" -> Just JournalMode'OFF
|
||||
"delete" -> Just JournalMode'DELETE
|
||||
"truncate" -> Just JournalMode'TRUNCATE
|
||||
"persist" -> Just JournalMode'PERSIST
|
||||
"memory" -> Just JournalMode'MEMORY
|
||||
"wal" -> Just JournalMode'WAL
|
||||
"off" -> Just JournalMode'OFF
|
||||
_ -> Nothing
|
||||
|
||||
unsafeJournalModeFromText :: HasCallStack => Text -> JournalMode
|
||||
@ -38,12 +38,12 @@ unsafeJournalModeFromText s =
|
||||
|
||||
journalModeToText :: JournalMode -> Text
|
||||
journalModeToText = \case
|
||||
JournalMode'DELETE -> "DELETE"
|
||||
JournalMode'TRUNCATE -> "TRUNCATE"
|
||||
JournalMode'PERSIST -> "PERSIST"
|
||||
JournalMode'MEMORY -> "MEMORY"
|
||||
JournalMode'WAL -> "WAL"
|
||||
JournalMode'OFF -> "OFF"
|
||||
JournalMode'DELETE -> "delete"
|
||||
JournalMode'TRUNCATE -> "truncate"
|
||||
JournalMode'PERSIST -> "persist"
|
||||
JournalMode'MEMORY -> "memory"
|
||||
JournalMode'WAL -> "wal"
|
||||
JournalMode'OFF -> "off"
|
||||
|
||||
trySetJournalMode :: JournalMode -> Transaction ()
|
||||
trySetJournalMode mode0 = do
|
||||
|
@ -50,14 +50,17 @@ module Unison.Sqlite.Transaction
|
||||
)
|
||||
where
|
||||
|
||||
import Control.Concurrent (threadDelay)
|
||||
import Control.Exception (Exception (fromException), onException, throwIO)
|
||||
import Control.Monad.Trans.Reader (ReaderT (..))
|
||||
import qualified Database.SQLite.Simple as Sqlite
|
||||
import qualified Database.SQLite.Simple.FromField as Sqlite
|
||||
import Unison.Prelude
|
||||
import Unison.Prelude hiding (try)
|
||||
import Unison.Sqlite.Connection (Connection (..))
|
||||
import qualified Unison.Sqlite.Connection as Connection
|
||||
import Unison.Sqlite.Exception (SqliteExceptionReason)
|
||||
import Unison.Sqlite.Exception (SqliteExceptionReason, SqliteQueryException, pattern SqliteBusyException)
|
||||
import Unison.Sqlite.Sql
|
||||
import UnliftIO.Exception (catchAny, try, trySyncOrAsync, uninterruptibleMask)
|
||||
|
||||
newtype Transaction a
|
||||
= Transaction (Connection -> IO a)
|
||||
@ -67,13 +70,35 @@ newtype Transaction a
|
||||
|
||||
-- | Run a transaction on the given connection.
|
||||
runTransaction :: MonadIO m => Connection -> Transaction a -> m a
|
||||
runTransaction conn@(Connection _ _ conn0) (Transaction f) =
|
||||
-- TODO some sensible retry logic
|
||||
liftIO do
|
||||
Sqlite.execute_ conn0 "BEGIN"
|
||||
result <- f conn
|
||||
Sqlite.execute_ conn0 "COMMIT"
|
||||
runTransaction conn (Transaction f) = liftIO do
|
||||
uninterruptibleMask \restore -> do
|
||||
Connection.execute_ conn "BEGIN"
|
||||
result <-
|
||||
-- Catch all exceptions (sync or async), because we want to ROLLBACK the BEGIN no matter what.
|
||||
trySyncOrAsync @_ @SomeException (restore (f conn)) >>= \case
|
||||
Left exception -> do
|
||||
ignoringExceptions rollback
|
||||
case fromException exception of
|
||||
Just SqliteBusyException ->
|
||||
let loop microseconds = do
|
||||
restore (threadDelay microseconds)
|
||||
try @_ @SqliteQueryException (Connection.execute_ conn "BEGIN IMMEDIATE") >>= \case
|
||||
Left SqliteBusyException -> loop (microseconds * 2)
|
||||
Left exception -> throwIO exception
|
||||
Right () -> restore (f conn) `onException` ignoringExceptions rollback
|
||||
in loop 100_000
|
||||
_ -> throwIO exception
|
||||
Right result -> pure result
|
||||
Connection.execute_ conn "COMMIT"
|
||||
pure result
|
||||
where
|
||||
rollback :: IO ()
|
||||
rollback =
|
||||
Connection.execute_ conn "ROLLBACK"
|
||||
|
||||
ignoringExceptions :: IO () -> IO ()
|
||||
ignoringExceptions action =
|
||||
action `catchAny` \_ -> pure ()
|
||||
|
||||
-- Without results, with parameters
|
||||
|
||||
|
@ -47,6 +47,7 @@ library
|
||||
NamedFieldPuns
|
||||
NumericUnderscores
|
||||
OverloadedStrings
|
||||
PatternSynonyms
|
||||
ScopedTypeVariables
|
||||
TupleSections
|
||||
TypeApplications
|
||||
|
@ -18,6 +18,12 @@ main =
|
||||
bench "intersection" $ nf (uncurry R.intersection) rs,
|
||||
bench "union" $ nf (uncurry R.union) rs
|
||||
],
|
||||
env (pure (R.fromList ((,) <$> [(1 :: Int) .. 1000] <*> [(1 :: Int) .. 1000]))) \r ->
|
||||
bgroup
|
||||
"replaceDom"
|
||||
[ bench "old implementation" (nf (oldReplaceDom 1 2) r),
|
||||
bench "new implementation" (nf (R.replaceDom 2 2) r)
|
||||
],
|
||||
env (genRelation @Char @Char 10000 2) \r ->
|
||||
env (genSet @Char 100) \s ->
|
||||
bgroup
|
||||
@ -30,6 +36,10 @@ main =
|
||||
]
|
||||
]
|
||||
|
||||
oldReplaceDom :: (Ord a, Ord b) => a -> a -> Relation a b -> Relation a b
|
||||
oldReplaceDom a a' r =
|
||||
foldl' (\r b -> R.insert a' b $ R.delete a b r) r (R.lookupDom a r)
|
||||
|
||||
oldSubtractDom :: (Ord a, Ord b) => Set a -> Relation a b -> Relation a b
|
||||
oldSubtractDom s r =
|
||||
R.fromList [(a, b) | (a, b) <- R.toList r, not (a `Set.member` s)]
|
||||
|
@ -114,7 +114,9 @@ import qualified Data.Map as Map
|
||||
import qualified Data.Map.Internal as Map
|
||||
import Data.Ord (comparing)
|
||||
import qualified Data.Set as S
|
||||
import qualified Data.Set as Set
|
||||
import Unison.Prelude hiding (empty, toList)
|
||||
import qualified Unison.Util.Map as Map
|
||||
import qualified Unison.Util.Set as Set
|
||||
import Prelude hiding (filter, map, null)
|
||||
|
||||
@ -602,13 +604,31 @@ searchDom f r = go (domain r)
|
||||
searchRan :: (Ord a, Ord b) => (b -> Ordering) -> Relation a b -> Set a
|
||||
searchRan f r = searchDom f (swap r)
|
||||
|
||||
-- | @replaceDom x y r@ replaces all @(x, _)@ with @(y, _)@ in @r@.
|
||||
replaceDom :: (Ord a, Ord b) => a -> a -> Relation a b -> Relation a b
|
||||
replaceDom a a' r =
|
||||
foldl' (\r b -> insert a' b $ delete a b r) r (lookupDom a r)
|
||||
if a == a'
|
||||
then r
|
||||
else case Map.deleteLookup a (domain r) of
|
||||
(Nothing, _) -> r
|
||||
(Just bs, domain') ->
|
||||
Relation
|
||||
{ domain = Map.insertWith Set.union a' bs domain',
|
||||
range = foldl' (\acc b -> Map.adjust (Set.insert a' . Set.delete a) b acc) (range r) bs
|
||||
}
|
||||
|
||||
-- | @replaceRan x y r@ replaces all @(_, x)@ with @(_, y)@ in @r@.
|
||||
replaceRan :: (Ord a, Ord b) => b -> b -> Relation a b -> Relation a b
|
||||
replaceRan b b' r =
|
||||
foldl' (\r a -> insert a b' $ delete a b r) r (lookupRan b r)
|
||||
if b == b'
|
||||
then r
|
||||
else case Map.deleteLookup b (range r) of
|
||||
(Nothing, _) -> r
|
||||
(Just as, range') ->
|
||||
Relation
|
||||
{ domain = foldl' (\acc a -> Map.adjust (Set.insert b' . Set.delete b) a acc) (domain r) as,
|
||||
range = Map.insertWith Set.union b' as range'
|
||||
}
|
||||
|
||||
updateDom :: (Ord a, Ord b) => (a -> a) -> b -> Relation a b -> Relation a b
|
||||
updateDom f b r =
|
||||
|
@ -128,6 +128,9 @@ fromList xs = insertAll xs empty
|
||||
empty :: (Ord a, Ord b, Ord c) => Relation3 a b c
|
||||
empty = mempty
|
||||
|
||||
null :: Relation3 a b c -> Bool
|
||||
null r = Map.null $ d1 r
|
||||
|
||||
insert, delete
|
||||
:: (Ord a, Ord b, Ord c)
|
||||
=> a -> b -> c -> Relation3 a b c -> Relation3 a b c
|
||||
|
@ -47,6 +47,9 @@ toList = fmap (\(a,(b,(c,d))) -> (a,b,c,d)) . toNestedList
|
||||
empty :: (Ord a, Ord b, Ord c, Ord d) => Relation4 a b c d
|
||||
empty = mempty
|
||||
|
||||
null :: Relation4 a b c d -> Bool
|
||||
null r = Map.null $ d1 r
|
||||
|
||||
fromList :: (Ord a, Ord b, Ord c, Ord d) => [(a,b,c,d)] -> Relation4 a b c d
|
||||
fromList xs = insertAll xs empty
|
||||
|
||||
|
@ -476,6 +476,7 @@ builtinsSrc =
|
||||
, B "ThreadId.toText" $ threadId --> text
|
||||
|
||||
, B "Debug.watch" $ forall1 "a" (\a -> text --> a --> a)
|
||||
, B "Debug.trace" $ forall1 "a" (\a -> text --> a --> unit)
|
||||
, B "unsafe.coerceAbilities" $
|
||||
forall4 "a" "b" "e1" "e2" $ \a b e1 e2 ->
|
||||
(a --> Type.effect1 () e1 b) --> (a --> Type.effect1 () e2 b)
|
||||
|
@ -39,6 +39,7 @@ module Unison.Codebase.Branch
|
||||
, head
|
||||
, headHash
|
||||
, children
|
||||
, nonEmptyChildren
|
||||
, deepEdits'
|
||||
, toList0
|
||||
-- * step
|
||||
@ -118,6 +119,7 @@ import qualified Unison.Util.Star3 as Star3
|
||||
import qualified Unison.Util.List as List
|
||||
import qualified Data.Semialign as Align
|
||||
import Data.These (These(..))
|
||||
import qualified Unison.Util.Relation as Relation
|
||||
|
||||
-- | A node in the Unison namespace hierarchy
|
||||
-- along with its history.
|
||||
@ -228,6 +230,12 @@ types =
|
||||
children :: Lens' (Branch0 m) (Map NameSegment (Branch m))
|
||||
children = lens _children (\Branch0{..} x -> branch0 _terms _types x _edits)
|
||||
|
||||
nonEmptyChildren :: Branch0 m -> Map NameSegment (Branch m)
|
||||
nonEmptyChildren b =
|
||||
b
|
||||
& _children
|
||||
& Map.filter (not . isEmpty0 . head)
|
||||
|
||||
-- creates a Branch0 from the primary fields and derives the others.
|
||||
branch0 ::
|
||||
forall m.
|
||||
@ -260,7 +268,7 @@ branch0 terms types children edits =
|
||||
-- | Derive the 'deepTerms' field of a branch.
|
||||
deriveDeepTerms :: Branch0 m -> Branch0 m
|
||||
deriveDeepTerms branch =
|
||||
branch {deepTerms = makeDeepTerms (_terms branch) (_children branch)}
|
||||
branch {deepTerms = makeDeepTerms (_terms branch) (nonEmptyChildren branch)}
|
||||
where
|
||||
makeDeepTerms :: Metadata.Star Referent NameSegment -> Map NameSegment (Branch m) -> Relation Referent Name
|
||||
makeDeepTerms terms children =
|
||||
@ -273,7 +281,7 @@ deriveDeepTerms branch =
|
||||
-- | Derive the 'deepTypes' field of a branch.
|
||||
deriveDeepTypes :: Branch0 m -> Branch0 m
|
||||
deriveDeepTypes branch =
|
||||
branch {deepTypes = makeDeepTypes (_types branch) (_children branch)}
|
||||
branch {deepTypes = makeDeepTypes (_types branch) (nonEmptyChildren branch)}
|
||||
where
|
||||
makeDeepTypes :: Metadata.Star TypeReference NameSegment -> Map NameSegment (Branch m) -> Relation TypeReference Name
|
||||
makeDeepTypes types children =
|
||||
@ -286,7 +294,7 @@ deriveDeepTypes branch =
|
||||
-- | Derive the 'deepTermMetadata' field of a branch.
|
||||
deriveDeepTermMetadata :: Branch0 m -> Branch0 m
|
||||
deriveDeepTermMetadata branch =
|
||||
branch {deepTermMetadata = makeDeepTermMetadata (_terms branch) (_children branch)}
|
||||
branch {deepTermMetadata = makeDeepTermMetadata (_terms branch) (nonEmptyChildren branch)}
|
||||
where
|
||||
makeDeepTermMetadata :: Metadata.Star Referent NameSegment -> Map NameSegment (Branch m) -> Metadata.R4 Referent Name
|
||||
makeDeepTermMetadata terms children =
|
||||
@ -299,7 +307,7 @@ deriveDeepTermMetadata branch =
|
||||
-- | Derive the 'deepTypeMetadata' field of a branch.
|
||||
deriveDeepTypeMetadata :: Branch0 m -> Branch0 m
|
||||
deriveDeepTypeMetadata branch =
|
||||
branch {deepTypeMetadata = makeDeepTypeMetadata (_types branch) (_children branch)}
|
||||
branch {deepTypeMetadata = makeDeepTypeMetadata (_types branch) (nonEmptyChildren branch)}
|
||||
where
|
||||
makeDeepTypeMetadata :: Metadata.Star TypeReference NameSegment -> Map NameSegment (Branch m) -> Metadata.R4 TypeReference Name
|
||||
makeDeepTypeMetadata types children =
|
||||
@ -312,7 +320,7 @@ deriveDeepTypeMetadata branch =
|
||||
-- | Derive the 'deepPaths' field of a branch.
|
||||
deriveDeepPaths :: Branch0 m -> Branch0 m
|
||||
deriveDeepPaths branch =
|
||||
branch {deepPaths = makeDeepPaths (_children branch)}
|
||||
branch {deepPaths = makeDeepPaths (nonEmptyChildren branch)}
|
||||
where
|
||||
makeDeepPaths :: Map NameSegment (Branch m) -> Set Path
|
||||
makeDeepPaths children =
|
||||
@ -325,7 +333,7 @@ deriveDeepPaths branch =
|
||||
-- | Derive the 'deepEdits' field of a branch.
|
||||
deriveDeepEdits :: Branch0 m -> Branch0 m
|
||||
deriveDeepEdits branch =
|
||||
branch {deepEdits = makeDeepEdits (_edits branch) (_children branch)}
|
||||
branch {deepEdits = makeDeepEdits (_edits branch) (nonEmptyChildren branch)}
|
||||
where
|
||||
makeDeepEdits :: Map NameSegment (EditHash, m Patch) -> Map NameSegment (Branch m) -> Map Name EditHash
|
||||
makeDeepEdits edits children =
|
||||
@ -500,9 +508,15 @@ empty0 :: Branch0 m
|
||||
empty0 =
|
||||
Branch0 mempty mempty mempty mempty mempty mempty mempty mempty mempty mempty
|
||||
|
||||
-- | Checks whether a Branch0 is empty.
|
||||
-- | Checks whether a Branch0 is empty, which means that the branch contains no terms or
|
||||
-- types, and that the heads of all children are empty by the same definition.
|
||||
-- This is not as easy as checking whether the branch is equal to the `empty0` branch
|
||||
-- because child branches may be empty, but still have history.
|
||||
isEmpty0 :: Branch0 m -> Bool
|
||||
isEmpty0 = (== empty0)
|
||||
isEmpty0 (Branch0 _terms _types _children _edits deepTerms deepTypes _deepTermMetadata _deepTypeMetadata _deepPaths deepEdits) =
|
||||
Relation.null deepTerms
|
||||
&& Relation.null deepTypes
|
||||
&& Map.null deepEdits
|
||||
|
||||
-- | Checks whether a branch is empty AND has no history.
|
||||
isEmpty :: Branch m -> Bool
|
||||
@ -784,10 +798,13 @@ consBranch ::
|
||||
-- If the target branch is empty we just replace it.
|
||||
consBranch Empty headBranch = discardHistory headBranch
|
||||
consBranch baseBranch headBranch =
|
||||
Branch $
|
||||
Causal.consDistinct
|
||||
(head headBranch & children .~ combinedChildren)
|
||||
(_history baseBranch)
|
||||
if baseBranch == headBranch
|
||||
then baseBranch
|
||||
else
|
||||
Branch $
|
||||
Causal.consDistinct
|
||||
(head headBranch & children .~ combinedChildren)
|
||||
(_history baseBranch)
|
||||
where
|
||||
combineChildren :: These (Branch m) (Branch m) -> Branch m
|
||||
combineChildren = \case
|
||||
|
@ -14,7 +14,7 @@ where
|
||||
|
||||
import qualified Control.Concurrent
|
||||
import Control.Monad (filterM, unless, when, (>=>))
|
||||
import Control.Monad.Except (ExceptT, MonadError (throwError), runExceptT, withExceptT)
|
||||
import Control.Monad.Except (ExceptT (ExceptT), runExceptT, withExceptT)
|
||||
import qualified Control.Monad.Except as Except
|
||||
import Control.Monad.Extra (ifM, unlessM)
|
||||
import qualified Control.Monad.Extra as Monad
|
||||
@ -110,7 +110,6 @@ import qualified UnliftIO
|
||||
import UnliftIO.Directory (canonicalizePath, createDirectoryIfMissing, doesDirectoryExist, doesFileExist)
|
||||
import UnliftIO.STM
|
||||
import UnliftIO.Exception (catch, bracket)
|
||||
import Control.Monad.Trans.Except (mapExceptT)
|
||||
|
||||
debug, debugProcessBranches, debugCommitFailedTransaction :: Bool
|
||||
debug = False
|
||||
@ -174,16 +173,17 @@ createCodebaseOrError' debugName path action = do
|
||||
|
||||
fmap (Either.mapLeft CreateCodebaseUnknownSchemaVersion) (sqliteCodebase debugName path action)
|
||||
|
||||
openOrCreateCodebaseConnection ::
|
||||
MonadIO m =>
|
||||
withOpenOrCreateCodebaseConnection ::
|
||||
(MonadUnliftIO m) =>
|
||||
Codebase.DebugName ->
|
||||
FilePath ->
|
||||
m (IO (), Connection)
|
||||
openOrCreateCodebaseConnection debugName path = do
|
||||
(Connection -> m r) ->
|
||||
m r
|
||||
withOpenOrCreateCodebaseConnection debugName path action = do
|
||||
unlessM
|
||||
(doesFileExist $ path </> codebasePath)
|
||||
(initSchemaIfNotExist path)
|
||||
unsafeGetConnection debugName path
|
||||
withConnection debugName path action
|
||||
|
||||
-- get the codebase in dir
|
||||
getCodebaseOrError ::
|
||||
@ -1113,13 +1113,12 @@ pushGitBranch srcConn branch repo (PushGitBranchOpts setRoot _syncMode) = runExc
|
||||
|
||||
-- set up the cache dir
|
||||
remotePath <- time "Git fetch" $ withExceptT C.GitProtocolError $ pullBranch (writeToRead repo)
|
||||
(closeDestConn, destConn) <- openOrCreateCodebaseConnection "push.dest" remotePath
|
||||
mapExceptT (`finally` liftIO closeDestConn) $ do
|
||||
ExceptT . withOpenOrCreateCodebaseConnection "push.dest" remotePath $ \destConn -> do
|
||||
flip runReaderT destConn $ Q.savepoint "push"
|
||||
lift . flip State.execStateT emptySyncProgressState $
|
||||
flip State.execStateT emptySyncProgressState $
|
||||
syncInternal syncProgress srcConn destConn (Branch.transform lift branch)
|
||||
flip runReaderT destConn do
|
||||
if setRoot
|
||||
result <- if setRoot
|
||||
then do
|
||||
let newRootHash = Branch.headHash branch
|
||||
-- the call to runDB "handles" the possible DB error by bombing
|
||||
@ -1127,6 +1126,7 @@ pushGitBranch srcConn branch repo (PushGitBranchOpts setRoot _syncMode) = runExc
|
||||
Nothing -> do
|
||||
setRepoRoot newRootHash
|
||||
Q.release "push"
|
||||
pure $ Right ()
|
||||
Just oldRootHash -> do
|
||||
before oldRootHash newRootHash >>= \case
|
||||
Nothing ->
|
||||
@ -1139,13 +1139,17 @@ pushGitBranch srcConn branch repo (PushGitBranchOpts setRoot _syncMode) = runExc
|
||||
++ "."
|
||||
Just False -> do
|
||||
Q.rollbackRelease "push"
|
||||
throwError . C.GitProtocolError $ GitError.PushDestinationHasNewStuff repo
|
||||
pure . Left . C.GitProtocolError $ GitError.PushDestinationHasNewStuff repo
|
||||
Just True -> do
|
||||
setRepoRoot newRootHash
|
||||
Q.release "push"
|
||||
else Q.release "push"
|
||||
pure $ Right ()
|
||||
else do
|
||||
Q.release "push"
|
||||
pure $ Right ()
|
||||
|
||||
Q.setJournalMode JournalMode.DELETE
|
||||
pure result
|
||||
liftIO do
|
||||
void $ push remotePath repo
|
||||
where
|
||||
|
@ -762,7 +762,7 @@ data POp
|
||||
| CVLD -- validate
|
||||
| VALU | TLTT -- value, Term.Link.toText
|
||||
-- Debug
|
||||
| PRNT | INFO
|
||||
| PRNT | INFO | TRCE
|
||||
-- STM
|
||||
| ATOM
|
||||
deriving (Show,Eq,Ord)
|
||||
|
@ -736,6 +736,12 @@ raise
|
||||
where
|
||||
i = fromIntegral $ builtinTypeNumbering Map.! Ty.exceptionRef
|
||||
|
||||
gen'trace :: Var v => SuperNormal v
|
||||
gen'trace
|
||||
= binop0 0 $ \[t,v]
|
||||
-> TLets Direct [] [] (TPrm TRCE [t,v])
|
||||
$ TCon Ty.unitRef 0 []
|
||||
|
||||
code'missing :: Var v => SuperNormal v
|
||||
code'missing
|
||||
= unop0 1 $ \[link,b]
|
||||
@ -1457,6 +1463,7 @@ builtinLookup
|
||||
, ("bug", bug "builtin.bug")
|
||||
, ("todo", bug "builtin.todo")
|
||||
, ("Debug.watch", watch)
|
||||
, ("Debug.trace", gen'trace)
|
||||
, ("unsafe.coerceAbilities", poly'coerce)
|
||||
|
||||
, ("Char.toNat", cast Ty.charRef Ty.natRef)
|
||||
|
@ -53,6 +53,7 @@ import qualified Unison.LabeledDependency as RF
|
||||
import Unison.Reference (Reference)
|
||||
import qualified Unison.Referent as RF (pattern Ref)
|
||||
import qualified Unison.Reference as RF
|
||||
import qualified Unison.Util.Text as UT
|
||||
|
||||
import Unison.Util.EnumContainers as EC
|
||||
|
||||
@ -332,11 +333,22 @@ evalInContext ppe ctx w = do
|
||||
crs <- readTVarIO (combRefs $ ccache ctx)
|
||||
let hook = watchHook r
|
||||
decom = decompile (backReferenceTm crs (decompTm ctx))
|
||||
|
||||
prettyError (PE _ p) = p
|
||||
prettyError (BU nm c) = either id (bugMsg ppe nm) $ decom c
|
||||
|
||||
tr tx c = case decom c of
|
||||
Right dv -> do
|
||||
putStrLn $ "trace: " ++ UT.unpack tx
|
||||
putStrLn . toANSI 50 $ pretty ppe dv
|
||||
Left _ -> do
|
||||
putStrLn $ "trace: " ++ UT.unpack tx
|
||||
putStrLn "Couldn't decompile value."
|
||||
print c
|
||||
|
||||
result <- traverse (const $ readIORef r)
|
||||
. first prettyError
|
||||
<=< try $ apply0 (Just hook) (ccache ctx) w
|
||||
<=< try $ apply0 (Just hook) ((ccache ctx) { tracer = tr }) w
|
||||
pure $ decom =<< result
|
||||
|
||||
executeMainComb
|
||||
@ -483,7 +495,7 @@ getStoredCache = SCache
|
||||
|
||||
restoreCache :: StoredCache -> IO CCache
|
||||
restoreCache (SCache cs crs trs ftm fty int rtm rty)
|
||||
= CCache builtinForeigns
|
||||
= CCache builtinForeigns uglyTrace
|
||||
<$> newTVarIO (cs <> combs)
|
||||
<*> newTVarIO (crs <> builtinTermBackref)
|
||||
<*> newTVarIO (trs <> builtinTypeBackref)
|
||||
@ -493,6 +505,9 @@ restoreCache (SCache cs crs trs ftm fty int rtm rty)
|
||||
<*> newTVarIO (rtm <> builtinTermNumbering)
|
||||
<*> newTVarIO (rty <> builtinTypeNumbering)
|
||||
where
|
||||
uglyTrace tx c = do
|
||||
putStrLn $ "trace: " ++ UT.unpack tx
|
||||
print c
|
||||
rns = emptyRNs { dnum = refLookup "ty" builtinTypeNumbering }
|
||||
combs
|
||||
= mapWithKey
|
||||
|
@ -352,7 +352,7 @@ data BPrim2
|
||||
-- bytes
|
||||
| TAKB | DRPB | IDXB | CATB -- take,drop,index,append
|
||||
-- general
|
||||
| THRO -- throw
|
||||
| THRO | TRCE -- throw
|
||||
deriving (Show, Eq, Ord)
|
||||
|
||||
data MLit
|
||||
@ -1074,6 +1074,7 @@ emitPOp ANF.VALU = emitBP1 VALU
|
||||
|
||||
-- error call
|
||||
emitPOp ANF.EROR = emitBP2 THRO
|
||||
emitPOp ANF.TRCE = emitBP2 TRCE
|
||||
|
||||
-- non-prim translations
|
||||
emitPOp ANF.BLDS = Seq
|
||||
|
@ -59,7 +59,10 @@ import Unison.Runtime.Foreign.Function
|
||||
import Unison.Runtime.Stack
|
||||
import Unison.Runtime.MCode
|
||||
|
||||
import Unison.Util.Text (Text)
|
||||
|
||||
import qualified Unison.Type as Rf
|
||||
import qualified Unison.Builtin.Decls as Rf
|
||||
|
||||
import qualified Unison.Util.Bytes as By
|
||||
import Unison.Util.Pretty (toPlainUnbroken)
|
||||
@ -74,6 +77,7 @@ type DEnv = EnumMap Word64 Closure
|
||||
data CCache
|
||||
= CCache
|
||||
{ foreignFuncs :: EnumMap Word64 ForeignFunc
|
||||
, tracer :: Text -> Closure -> IO ()
|
||||
, combs :: TVar (EnumMap Word64 Combs)
|
||||
, combRefs :: TVar (EnumMap Word64 Reference)
|
||||
, tagRefs :: TVar (EnumMap Word64 Reference)
|
||||
@ -105,7 +109,7 @@ refNumTy' cc r = M.lookup r <$> refNumsTy cc
|
||||
|
||||
baseCCache :: IO CCache
|
||||
baseCCache
|
||||
= CCache builtinForeigns
|
||||
= CCache builtinForeigns noTrace
|
||||
<$> newTVarIO combs
|
||||
<*> newTVarIO builtinTermBackref
|
||||
<*> newTVarIO builtinTypeBackref
|
||||
@ -115,6 +119,7 @@ baseCCache
|
||||
<*> newTVarIO builtinTermNumbering
|
||||
<*> newTVarIO builtinTypeNumbering
|
||||
where
|
||||
noTrace _ _ = pure ()
|
||||
ftm = 1 + maximum builtinTermNumbering
|
||||
fty = 1 + maximum builtinTypeNumbering
|
||||
|
||||
@ -184,6 +189,23 @@ apply1 callback env clo = do
|
||||
where
|
||||
k0 = CB $ Hook callback
|
||||
|
||||
-- Entry point for evaluating a saved continuation.
|
||||
--
|
||||
-- The continuation must be from an evaluation context expecting a
|
||||
-- unit value.
|
||||
jump0
|
||||
:: (Stack 'UN -> Stack 'BX -> IO ())
|
||||
-> CCache -> Closure -> IO ()
|
||||
jump0 !callback !env !clo = do
|
||||
ustk <- alloc
|
||||
bstk <- alloc
|
||||
(denv, kf) <-
|
||||
topDEnv <$> readTVarIO (refTy env) <*> readTVarIO (refTm env)
|
||||
bstk <- bump bstk
|
||||
poke bstk (Enum Rf.unitRef unitTag)
|
||||
jump env denv ustk bstk (kf k0) (BArg1 0) clo
|
||||
where
|
||||
k0 = CB (Hook callback)
|
||||
|
||||
lookupDenv :: Word64 -> DEnv -> Closure
|
||||
lookupDenv p denv = fromMaybe BlackHole $ EC.lookup p denv
|
||||
@ -300,6 +322,11 @@ exec !_ !denv !ustk !bstk !k (BPrim2 CMPU i j) = do
|
||||
ustk <- bump ustk
|
||||
poke ustk . fromEnum $ universalCompare compare x y
|
||||
pure (denv, ustk, bstk, k)
|
||||
exec !env !denv !ustk !bstk !k (BPrim2 TRCE i j) = do
|
||||
tx <- peekOffBi bstk i
|
||||
clo <- peekOff bstk j
|
||||
tracer env tx clo
|
||||
pure (denv, ustk, bstk, k)
|
||||
exec !_ !denv !ustk !bstk !k (BPrim2 op i j) = do
|
||||
(ustk,bstk) <- bprim2 ustk bstk op i j
|
||||
pure (denv, ustk, bstk, k)
|
||||
@ -1373,6 +1400,7 @@ bprim2 !_ !bstk THRO i j = do
|
||||
name <- peekOffBi @Util.Text.Text bstk i
|
||||
x <- peekOff bstk j
|
||||
throwIO (BU (Util.Text.toText name) x)
|
||||
bprim2 !ustk !bstk TRCE _ _ = pure (ustk, bstk) -- impossible
|
||||
bprim2 !ustk !bstk CMPU _ _ = pure (ustk, bstk) -- impossible
|
||||
{-# inline bprim2 #-}
|
||||
|
||||
@ -1772,6 +1800,13 @@ charTag
|
||||
= packTags rt 0
|
||||
| otherwise = error "internal error: charTag"
|
||||
|
||||
unitTag :: Word64
|
||||
unitTag
|
||||
| Just n <- M.lookup Rf.unitRef builtinTypeNumbering
|
||||
, rt <- toEnum (fromIntegral n)
|
||||
= packTags rt 0
|
||||
| otherwise = error "internal error: unitTag"
|
||||
|
||||
universalCompare
|
||||
:: (Foreign -> Foreign -> Ordering)
|
||||
-> Closure
|
||||
|
@ -428,6 +428,7 @@ instance Tag BPrim2 where
|
||||
tag2word IDXB = 18
|
||||
tag2word CATB = 19
|
||||
tag2word THRO = 20
|
||||
tag2word TRCE = 21
|
||||
|
||||
word2tag 0 = pure EQLU
|
||||
word2tag 1 = pure CMPU
|
||||
@ -450,4 +451,5 @@ instance Tag BPrim2 where
|
||||
word2tag 18 = pure IDXB
|
||||
word2tag 19 = pure CATB
|
||||
word2tag 20 = pure THRO
|
||||
word2tag 21 = pure TRCE
|
||||
word2tag n = unknownTag "BPrim2" n
|
||||
|
@ -431,7 +431,7 @@ findShallowInBranch codebase b = do
|
||||
[ ShallowBranchEntry ns
|
||||
(SBH.fullFromHash $ Branch.headHash b)
|
||||
(defnCount b)
|
||||
| (ns, b) <- Map.toList $ Branch._children b0
|
||||
| (ns, b) <- Map.toList $ Branch.nonEmptyChildren b0
|
||||
]
|
||||
patchEntries =
|
||||
[ ShallowPatchEntry ns
|
||||
|
@ -660,7 +660,7 @@ loop = do
|
||||
let dest = resolveToAbsolute dest0
|
||||
-- if dest isn't empty: leave dest unchanged, and complain.
|
||||
destb <- getAt dest
|
||||
if Branch.isEmpty destb
|
||||
if Branch.isEmpty0 (Branch.head destb)
|
||||
then do
|
||||
ok <- updateAtM dest (const $ pure srcb)
|
||||
if ok then success else respond $ BranchEmpty src0
|
||||
@ -848,7 +848,7 @@ loop = do
|
||||
let path = resolveToAbsolute path'
|
||||
LoopState.currentPathStack %= Nel.cons path
|
||||
branch' <- getAt path
|
||||
when (Branch.isEmpty branch') (respond $ CreatedNewBranch path)
|
||||
when (Branch.isEmpty0 $ Branch.head branch') (respond $ CreatedNewBranch path)
|
||||
UpI ->
|
||||
use LoopState.currentPath >>= \p -> case Path.unsnoc (Path.unabsolute p) of
|
||||
Nothing -> pure ()
|
||||
@ -1903,8 +1903,8 @@ doPushRemoteBranch repo localPath syncMode remoteTarget = do
|
||||
shouldPushTo :: PushBehavior -> Branch m -> Bool
|
||||
shouldPushTo pushBehavior remoteBranch =
|
||||
case pushBehavior of
|
||||
PushBehavior.RequireEmpty -> Branch.isEmpty remoteBranch
|
||||
PushBehavior.RequireNonEmpty -> not (Branch.isEmpty remoteBranch)
|
||||
PushBehavior.RequireEmpty -> Branch.isEmpty0 (Branch.head remoteBranch)
|
||||
PushBehavior.RequireNonEmpty -> not (Branch.isEmpty0 (Branch.head remoteBranch))
|
||||
|
||||
-- | Handle a @ShowDefinitionI@ input command, i.e. `view` or `edit`.
|
||||
handleShowDefinition ::
|
||||
|
@ -2057,7 +2057,7 @@ bothCompletors c1 c2 q code b currentPath = do
|
||||
. nubOrdOn Completion.display
|
||||
$ suggestions1 ++ suggestions2
|
||||
|
||||
-- |
|
||||
-- | A completer for namespace paths.
|
||||
pathCompletor ::
|
||||
Applicative f =>
|
||||
-- | Turns a query and list of possible completions into a 'Completion'.
|
||||
@ -2092,7 +2092,7 @@ namespaceArg =
|
||||
-- | Recursively collects all names of namespaces which are children of the branch.
|
||||
allSubNamespaces :: Branch.Branch0 m -> [Text]
|
||||
allSubNamespaces b =
|
||||
flip Map.foldMapWithKey (Branch._children b) $
|
||||
flip Map.foldMapWithKey (Branch.nonEmptyChildren b) $
|
||||
\(NameSegment k) (Branch.head -> b') ->
|
||||
(k : fmap (\sn -> k <> "." <> sn) (allSubNamespaces b'))
|
||||
|
||||
|
@ -40,6 +40,53 @@ test = scope "gitsync22" . tests $
|
||||
destroyedRemote :
|
||||
flip map [(Ucm.CodebaseFormat2, "sc")]
|
||||
\(fmt, name) -> scope name $ tests [
|
||||
pushPullTest "pull-over-deleted-namespace" fmt
|
||||
(\repo -> [i|
|
||||
```unison:hide
|
||||
x = 1
|
||||
```
|
||||
```ucm:hide
|
||||
.> add
|
||||
.> push.create ${repo}
|
||||
```
|
||||
|])
|
||||
(\repo -> [i|
|
||||
```unison:hide
|
||||
child.y = 2
|
||||
```
|
||||
|
||||
Should be able to pull a branch from the repo over top of our deleted local branch.
|
||||
```ucm
|
||||
.> add
|
||||
.> delete.namespace child
|
||||
.> pull ${repo} child
|
||||
```
|
||||
|])
|
||||
,
|
||||
pushPullTest "push-over-deleted-namespace" fmt
|
||||
(\repo -> [i|
|
||||
```unison:hide
|
||||
child.x = 1
|
||||
y = 2
|
||||
```
|
||||
```ucm:hide
|
||||
.> add
|
||||
.> delete.namespace child
|
||||
.> push.create ${repo}
|
||||
```
|
||||
|])
|
||||
(\repo -> [i|
|
||||
```unison:hide
|
||||
child.z = 3
|
||||
```
|
||||
|
||||
Should be able to push a branch over top of a deleted remote branch.
|
||||
```ucm
|
||||
.> add
|
||||
.> push.create ${repo}:.child child
|
||||
```
|
||||
|])
|
||||
,
|
||||
pushPullTest "typeAlias" fmt
|
||||
(\repo -> [i|
|
||||
```ucm
|
||||
|
@ -86,389 +86,390 @@ Let's try it!
|
||||
-> Bytes
|
||||
-> Bytes
|
||||
-> Bytes
|
||||
66. Debug.watch : Text -> a -> a
|
||||
67. unique type Doc
|
||||
68. Doc.Blob : Text -> Doc
|
||||
69. Doc.Evaluate : Term -> Doc
|
||||
70. Doc.Join : [Doc] -> Doc
|
||||
71. Doc.Link : Link -> Doc
|
||||
72. Doc.Signature : Term -> Doc
|
||||
73. Doc.Source : Link -> Doc
|
||||
74. structural type Either a b
|
||||
75. Either.Left : a -> Either a b
|
||||
76. Either.Right : b -> Either a b
|
||||
77. structural ability Exception
|
||||
78. Exception.raise : Failure ->{Exception} x
|
||||
79. builtin type Float
|
||||
80. Float.* : Float -> Float -> Float
|
||||
81. Float.+ : Float -> Float -> Float
|
||||
82. Float.- : Float -> Float -> Float
|
||||
83. Float./ : Float -> Float -> Float
|
||||
84. Float.abs : Float -> Float
|
||||
85. Float.acos : Float -> Float
|
||||
86. Float.acosh : Float -> Float
|
||||
87. Float.asin : Float -> Float
|
||||
88. Float.asinh : Float -> Float
|
||||
89. Float.atan : Float -> Float
|
||||
90. Float.atan2 : Float -> Float -> Float
|
||||
91. Float.atanh : Float -> Float
|
||||
92. Float.ceiling : Float -> Int
|
||||
93. Float.cos : Float -> Float
|
||||
94. Float.cosh : Float -> Float
|
||||
95. Float.eq : Float -> Float -> Boolean
|
||||
96. Float.exp : Float -> Float
|
||||
97. Float.floor : Float -> Int
|
||||
98. Float.fromRepresentation : Nat -> Float
|
||||
99. Float.fromText : Text -> Optional Float
|
||||
100. Float.gt : Float -> Float -> Boolean
|
||||
101. Float.gteq : Float -> Float -> Boolean
|
||||
102. Float.log : Float -> Float
|
||||
103. Float.logBase : Float -> Float -> Float
|
||||
104. Float.lt : Float -> Float -> Boolean
|
||||
105. Float.lteq : Float -> Float -> Boolean
|
||||
106. Float.max : Float -> Float -> Float
|
||||
107. Float.min : Float -> Float -> Float
|
||||
108. Float.pow : Float -> Float -> Float
|
||||
109. Float.round : Float -> Int
|
||||
110. Float.sin : Float -> Float
|
||||
111. Float.sinh : Float -> Float
|
||||
112. Float.sqrt : Float -> Float
|
||||
113. Float.tan : Float -> Float
|
||||
114. Float.tanh : Float -> Float
|
||||
115. Float.toRepresentation : Float -> Nat
|
||||
116. Float.toText : Float -> Text
|
||||
117. Float.truncate : Float -> Int
|
||||
118. Handle.toText : Handle -> Text
|
||||
119. builtin type Int
|
||||
120. Int.* : Int -> Int -> Int
|
||||
121. Int.+ : Int -> Int -> Int
|
||||
122. Int.- : Int -> Int -> Int
|
||||
123. Int./ : Int -> Int -> Int
|
||||
124. Int.and : Int -> Int -> Int
|
||||
125. Int.complement : Int -> Int
|
||||
126. Int.eq : Int -> Int -> Boolean
|
||||
127. Int.fromRepresentation : Nat -> Int
|
||||
128. Int.fromText : Text -> Optional Int
|
||||
129. Int.gt : Int -> Int -> Boolean
|
||||
130. Int.gteq : Int -> Int -> Boolean
|
||||
131. Int.increment : Int -> Int
|
||||
132. Int.isEven : Int -> Boolean
|
||||
133. Int.isOdd : Int -> Boolean
|
||||
134. Int.leadingZeros : Int -> Nat
|
||||
135. Int.lt : Int -> Int -> Boolean
|
||||
136. Int.lteq : Int -> Int -> Boolean
|
||||
137. Int.mod : Int -> Int -> Int
|
||||
138. Int.negate : Int -> Int
|
||||
139. Int.or : Int -> Int -> Int
|
||||
140. Int.popCount : Int -> Nat
|
||||
141. Int.pow : Int -> Nat -> Int
|
||||
142. Int.shiftLeft : Int -> Nat -> Int
|
||||
143. Int.shiftRight : Int -> Nat -> Int
|
||||
144. Int.signum : Int -> Int
|
||||
145. Int.toFloat : Int -> Float
|
||||
146. Int.toRepresentation : Int -> Nat
|
||||
147. Int.toText : Int -> Text
|
||||
148. Int.trailingZeros : Int -> Nat
|
||||
149. Int.truncate0 : Int -> Nat
|
||||
150. Int.xor : Int -> Int -> Int
|
||||
151. unique type io2.BufferMode
|
||||
152. io2.BufferMode.BlockBuffering : BufferMode
|
||||
153. io2.BufferMode.LineBuffering : BufferMode
|
||||
154. io2.BufferMode.NoBuffering : BufferMode
|
||||
155. io2.BufferMode.SizedBlockBuffering : Nat -> BufferMode
|
||||
156. unique type io2.Failure
|
||||
157. io2.Failure.Failure : Type -> Text -> Any -> Failure
|
||||
158. unique type io2.FileMode
|
||||
159. io2.FileMode.Append : FileMode
|
||||
160. io2.FileMode.Read : FileMode
|
||||
161. io2.FileMode.ReadWrite : FileMode
|
||||
162. io2.FileMode.Write : FileMode
|
||||
163. builtin type io2.Handle
|
||||
164. builtin type io2.IO
|
||||
165. io2.IO.clientSocket.impl : Text
|
||||
66. Debug.trace : Text -> a -> ()
|
||||
67. Debug.watch : Text -> a -> a
|
||||
68. unique type Doc
|
||||
69. Doc.Blob : Text -> Doc
|
||||
70. Doc.Evaluate : Term -> Doc
|
||||
71. Doc.Join : [Doc] -> Doc
|
||||
72. Doc.Link : Link -> Doc
|
||||
73. Doc.Signature : Term -> Doc
|
||||
74. Doc.Source : Link -> Doc
|
||||
75. structural type Either a b
|
||||
76. Either.Left : a -> Either a b
|
||||
77. Either.Right : b -> Either a b
|
||||
78. structural ability Exception
|
||||
79. Exception.raise : Failure ->{Exception} x
|
||||
80. builtin type Float
|
||||
81. Float.* : Float -> Float -> Float
|
||||
82. Float.+ : Float -> Float -> Float
|
||||
83. Float.- : Float -> Float -> Float
|
||||
84. Float./ : Float -> Float -> Float
|
||||
85. Float.abs : Float -> Float
|
||||
86. Float.acos : Float -> Float
|
||||
87. Float.acosh : Float -> Float
|
||||
88. Float.asin : Float -> Float
|
||||
89. Float.asinh : Float -> Float
|
||||
90. Float.atan : Float -> Float
|
||||
91. Float.atan2 : Float -> Float -> Float
|
||||
92. Float.atanh : Float -> Float
|
||||
93. Float.ceiling : Float -> Int
|
||||
94. Float.cos : Float -> Float
|
||||
95. Float.cosh : Float -> Float
|
||||
96. Float.eq : Float -> Float -> Boolean
|
||||
97. Float.exp : Float -> Float
|
||||
98. Float.floor : Float -> Int
|
||||
99. Float.fromRepresentation : Nat -> Float
|
||||
100. Float.fromText : Text -> Optional Float
|
||||
101. Float.gt : Float -> Float -> Boolean
|
||||
102. Float.gteq : Float -> Float -> Boolean
|
||||
103. Float.log : Float -> Float
|
||||
104. Float.logBase : Float -> Float -> Float
|
||||
105. Float.lt : Float -> Float -> Boolean
|
||||
106. Float.lteq : Float -> Float -> Boolean
|
||||
107. Float.max : Float -> Float -> Float
|
||||
108. Float.min : Float -> Float -> Float
|
||||
109. Float.pow : Float -> Float -> Float
|
||||
110. Float.round : Float -> Int
|
||||
111. Float.sin : Float -> Float
|
||||
112. Float.sinh : Float -> Float
|
||||
113. Float.sqrt : Float -> Float
|
||||
114. Float.tan : Float -> Float
|
||||
115. Float.tanh : Float -> Float
|
||||
116. Float.toRepresentation : Float -> Nat
|
||||
117. Float.toText : Float -> Text
|
||||
118. Float.truncate : Float -> Int
|
||||
119. Handle.toText : Handle -> Text
|
||||
120. builtin type Int
|
||||
121. Int.* : Int -> Int -> Int
|
||||
122. Int.+ : Int -> Int -> Int
|
||||
123. Int.- : Int -> Int -> Int
|
||||
124. Int./ : Int -> Int -> Int
|
||||
125. Int.and : Int -> Int -> Int
|
||||
126. Int.complement : Int -> Int
|
||||
127. Int.eq : Int -> Int -> Boolean
|
||||
128. Int.fromRepresentation : Nat -> Int
|
||||
129. Int.fromText : Text -> Optional Int
|
||||
130. Int.gt : Int -> Int -> Boolean
|
||||
131. Int.gteq : Int -> Int -> Boolean
|
||||
132. Int.increment : Int -> Int
|
||||
133. Int.isEven : Int -> Boolean
|
||||
134. Int.isOdd : Int -> Boolean
|
||||
135. Int.leadingZeros : Int -> Nat
|
||||
136. Int.lt : Int -> Int -> Boolean
|
||||
137. Int.lteq : Int -> Int -> Boolean
|
||||
138. Int.mod : Int -> Int -> Int
|
||||
139. Int.negate : Int -> Int
|
||||
140. Int.or : Int -> Int -> Int
|
||||
141. Int.popCount : Int -> Nat
|
||||
142. Int.pow : Int -> Nat -> Int
|
||||
143. Int.shiftLeft : Int -> Nat -> Int
|
||||
144. Int.shiftRight : Int -> Nat -> Int
|
||||
145. Int.signum : Int -> Int
|
||||
146. Int.toFloat : Int -> Float
|
||||
147. Int.toRepresentation : Int -> Nat
|
||||
148. Int.toText : Int -> Text
|
||||
149. Int.trailingZeros : Int -> Nat
|
||||
150. Int.truncate0 : Int -> Nat
|
||||
151. Int.xor : Int -> Int -> Int
|
||||
152. unique type io2.BufferMode
|
||||
153. io2.BufferMode.BlockBuffering : BufferMode
|
||||
154. io2.BufferMode.LineBuffering : BufferMode
|
||||
155. io2.BufferMode.NoBuffering : BufferMode
|
||||
156. io2.BufferMode.SizedBlockBuffering : Nat -> BufferMode
|
||||
157. unique type io2.Failure
|
||||
158. io2.Failure.Failure : Type -> Text -> Any -> Failure
|
||||
159. unique type io2.FileMode
|
||||
160. io2.FileMode.Append : FileMode
|
||||
161. io2.FileMode.Read : FileMode
|
||||
162. io2.FileMode.ReadWrite : FileMode
|
||||
163. io2.FileMode.Write : FileMode
|
||||
164. builtin type io2.Handle
|
||||
165. builtin type io2.IO
|
||||
166. io2.IO.clientSocket.impl : Text
|
||||
-> Text
|
||||
->{IO} Either Failure Socket
|
||||
166. io2.IO.closeFile.impl : Handle ->{IO} Either Failure ()
|
||||
167. io2.IO.closeSocket.impl : Socket ->{IO} Either Failure ()
|
||||
168. io2.IO.createDirectory.impl : Text
|
||||
167. io2.IO.closeFile.impl : Handle ->{IO} Either Failure ()
|
||||
168. io2.IO.closeSocket.impl : Socket ->{IO} Either Failure ()
|
||||
169. io2.IO.createDirectory.impl : Text
|
||||
->{IO} Either Failure ()
|
||||
169. io2.IO.createTempDirectory.impl : Text
|
||||
170. io2.IO.createTempDirectory.impl : Text
|
||||
->{IO} Either
|
||||
Failure Text
|
||||
170. io2.IO.delay.impl : Nat ->{IO} Either Failure ()
|
||||
171. io2.IO.directoryContents.impl : Text
|
||||
171. io2.IO.delay.impl : Nat ->{IO} Either Failure ()
|
||||
172. io2.IO.directoryContents.impl : Text
|
||||
->{IO} Either
|
||||
Failure [Text]
|
||||
172. io2.IO.fileExists.impl : Text
|
||||
173. io2.IO.fileExists.impl : Text
|
||||
->{IO} Either Failure Boolean
|
||||
173. io2.IO.forkComp : '{IO} a ->{IO} ThreadId
|
||||
174. io2.IO.getArgs.impl : '{IO} Either Failure [Text]
|
||||
175. io2.IO.getBuffering.impl : Handle
|
||||
174. io2.IO.forkComp : '{IO} a ->{IO} ThreadId
|
||||
175. io2.IO.getArgs.impl : '{IO} Either Failure [Text]
|
||||
176. io2.IO.getBuffering.impl : Handle
|
||||
->{IO} Either
|
||||
Failure BufferMode
|
||||
176. io2.IO.getBytes.impl : Handle
|
||||
177. io2.IO.getBytes.impl : Handle
|
||||
-> Nat
|
||||
->{IO} Either Failure Bytes
|
||||
177. io2.IO.getCurrentDirectory.impl : '{IO} Either
|
||||
178. io2.IO.getCurrentDirectory.impl : '{IO} Either
|
||||
Failure Text
|
||||
178. io2.IO.getEnv.impl : Text ->{IO} Either Failure Text
|
||||
179. io2.IO.getFileSize.impl : Text ->{IO} Either Failure Nat
|
||||
180. io2.IO.getFileTimestamp.impl : Text
|
||||
179. io2.IO.getEnv.impl : Text ->{IO} Either Failure Text
|
||||
180. io2.IO.getFileSize.impl : Text ->{IO} Either Failure Nat
|
||||
181. io2.IO.getFileTimestamp.impl : Text
|
||||
->{IO} Either Failure Nat
|
||||
181. io2.IO.getLine.impl : Handle ->{IO} Either Failure Text
|
||||
182. io2.IO.getTempDirectory.impl : '{IO} Either Failure Text
|
||||
183. io2.IO.handlePosition.impl : Handle
|
||||
182. io2.IO.getLine.impl : Handle ->{IO} Either Failure Text
|
||||
183. io2.IO.getTempDirectory.impl : '{IO} Either Failure Text
|
||||
184. io2.IO.handlePosition.impl : Handle
|
||||
->{IO} Either Failure Nat
|
||||
184. io2.IO.isDirectory.impl : Text
|
||||
185. io2.IO.isDirectory.impl : Text
|
||||
->{IO} Either Failure Boolean
|
||||
185. io2.IO.isFileEOF.impl : Handle
|
||||
186. io2.IO.isFileEOF.impl : Handle
|
||||
->{IO} Either Failure Boolean
|
||||
186. io2.IO.isFileOpen.impl : Handle
|
||||
187. io2.IO.isFileOpen.impl : Handle
|
||||
->{IO} Either Failure Boolean
|
||||
187. io2.IO.isSeekable.impl : Handle
|
||||
188. io2.IO.isSeekable.impl : Handle
|
||||
->{IO} Either Failure Boolean
|
||||
188. io2.IO.kill.impl : ThreadId ->{IO} Either Failure ()
|
||||
189. io2.IO.listen.impl : Socket ->{IO} Either Failure ()
|
||||
190. io2.IO.openFile.impl : Text
|
||||
189. io2.IO.kill.impl : ThreadId ->{IO} Either Failure ()
|
||||
190. io2.IO.listen.impl : Socket ->{IO} Either Failure ()
|
||||
191. io2.IO.openFile.impl : Text
|
||||
-> FileMode
|
||||
->{IO} Either Failure Handle
|
||||
191. io2.IO.putBytes.impl : Handle
|
||||
192. io2.IO.putBytes.impl : Handle
|
||||
-> Bytes
|
||||
->{IO} Either Failure ()
|
||||
192. io2.IO.ref : a ->{IO} Ref {IO} a
|
||||
193. io2.IO.removeDirectory.impl : Text
|
||||
193. io2.IO.ref : a ->{IO} Ref {IO} a
|
||||
194. io2.IO.removeDirectory.impl : Text
|
||||
->{IO} Either Failure ()
|
||||
194. io2.IO.removeFile.impl : Text ->{IO} Either Failure ()
|
||||
195. io2.IO.renameDirectory.impl : Text
|
||||
195. io2.IO.removeFile.impl : Text ->{IO} Either Failure ()
|
||||
196. io2.IO.renameDirectory.impl : Text
|
||||
-> Text
|
||||
->{IO} Either Failure ()
|
||||
196. io2.IO.renameFile.impl : Text
|
||||
197. io2.IO.renameFile.impl : Text
|
||||
-> Text
|
||||
->{IO} Either Failure ()
|
||||
197. io2.IO.seekHandle.impl : Handle
|
||||
198. io2.IO.seekHandle.impl : Handle
|
||||
-> SeekMode
|
||||
-> Int
|
||||
->{IO} Either Failure ()
|
||||
198. io2.IO.serverSocket.impl : Optional Text
|
||||
199. io2.IO.serverSocket.impl : Optional Text
|
||||
-> Text
|
||||
->{IO} Either Failure Socket
|
||||
199. io2.IO.setBuffering.impl : Handle
|
||||
200. io2.IO.setBuffering.impl : Handle
|
||||
-> BufferMode
|
||||
->{IO} Either Failure ()
|
||||
200. io2.IO.setCurrentDirectory.impl : Text
|
||||
201. io2.IO.setCurrentDirectory.impl : Text
|
||||
->{IO} Either
|
||||
Failure ()
|
||||
201. io2.IO.socketAccept.impl : Socket
|
||||
202. io2.IO.socketAccept.impl : Socket
|
||||
->{IO} Either Failure Socket
|
||||
202. io2.IO.socketPort.impl : Socket ->{IO} Either Failure Nat
|
||||
203. io2.IO.socketReceive.impl : Socket
|
||||
203. io2.IO.socketPort.impl : Socket ->{IO} Either Failure Nat
|
||||
204. io2.IO.socketReceive.impl : Socket
|
||||
-> Nat
|
||||
->{IO} Either Failure Bytes
|
||||
204. io2.IO.socketSend.impl : Socket
|
||||
205. io2.IO.socketSend.impl : Socket
|
||||
-> Bytes
|
||||
->{IO} Either Failure ()
|
||||
205. io2.IO.stdHandle : StdHandle -> Handle
|
||||
206. io2.IO.systemTime.impl : '{IO} Either Failure Nat
|
||||
207. io2.IO.systemTimeMicroseconds : '{IO} Int
|
||||
208. unique type io2.IOError
|
||||
209. io2.IOError.AlreadyExists : IOError
|
||||
210. io2.IOError.EOF : IOError
|
||||
211. io2.IOError.IllegalOperation : IOError
|
||||
212. io2.IOError.NoSuchThing : IOError
|
||||
213. io2.IOError.PermissionDenied : IOError
|
||||
214. io2.IOError.ResourceBusy : IOError
|
||||
215. io2.IOError.ResourceExhausted : IOError
|
||||
216. io2.IOError.UserError : IOError
|
||||
217. unique type io2.IOFailure
|
||||
218. builtin type io2.MVar
|
||||
219. io2.MVar.isEmpty : MVar a ->{IO} Boolean
|
||||
220. io2.MVar.new : a ->{IO} MVar a
|
||||
221. io2.MVar.newEmpty : '{IO} MVar a
|
||||
222. io2.MVar.put.impl : MVar a -> a ->{IO} Either Failure ()
|
||||
223. io2.MVar.read.impl : MVar a ->{IO} Either Failure a
|
||||
224. io2.MVar.swap.impl : MVar a -> a ->{IO} Either Failure a
|
||||
225. io2.MVar.take.impl : MVar a ->{IO} Either Failure a
|
||||
226. io2.MVar.tryPut.impl : MVar a
|
||||
206. io2.IO.stdHandle : StdHandle -> Handle
|
||||
207. io2.IO.systemTime.impl : '{IO} Either Failure Nat
|
||||
208. io2.IO.systemTimeMicroseconds : '{IO} Int
|
||||
209. unique type io2.IOError
|
||||
210. io2.IOError.AlreadyExists : IOError
|
||||
211. io2.IOError.EOF : IOError
|
||||
212. io2.IOError.IllegalOperation : IOError
|
||||
213. io2.IOError.NoSuchThing : IOError
|
||||
214. io2.IOError.PermissionDenied : IOError
|
||||
215. io2.IOError.ResourceBusy : IOError
|
||||
216. io2.IOError.ResourceExhausted : IOError
|
||||
217. io2.IOError.UserError : IOError
|
||||
218. unique type io2.IOFailure
|
||||
219. builtin type io2.MVar
|
||||
220. io2.MVar.isEmpty : MVar a ->{IO} Boolean
|
||||
221. io2.MVar.new : a ->{IO} MVar a
|
||||
222. io2.MVar.newEmpty : '{IO} MVar a
|
||||
223. io2.MVar.put.impl : MVar a -> a ->{IO} Either Failure ()
|
||||
224. io2.MVar.read.impl : MVar a ->{IO} Either Failure a
|
||||
225. io2.MVar.swap.impl : MVar a -> a ->{IO} Either Failure a
|
||||
226. io2.MVar.take.impl : MVar a ->{IO} Either Failure a
|
||||
227. io2.MVar.tryPut.impl : MVar a
|
||||
-> a
|
||||
->{IO} Either Failure Boolean
|
||||
227. io2.MVar.tryRead.impl : MVar a
|
||||
228. io2.MVar.tryRead.impl : MVar a
|
||||
->{IO} Either
|
||||
Failure (Optional a)
|
||||
228. io2.MVar.tryTake : MVar a ->{IO} Optional a
|
||||
229. unique type io2.SeekMode
|
||||
230. io2.SeekMode.AbsoluteSeek : SeekMode
|
||||
231. io2.SeekMode.RelativeSeek : SeekMode
|
||||
232. io2.SeekMode.SeekFromEnd : SeekMode
|
||||
233. builtin type io2.Socket
|
||||
234. unique type io2.StdHandle
|
||||
235. io2.StdHandle.StdErr : StdHandle
|
||||
236. io2.StdHandle.StdIn : StdHandle
|
||||
237. io2.StdHandle.StdOut : StdHandle
|
||||
238. builtin type io2.STM
|
||||
239. io2.STM.atomically : '{STM} a ->{IO} a
|
||||
240. io2.STM.retry : '{STM} a
|
||||
241. builtin type io2.ThreadId
|
||||
242. builtin type io2.Tls
|
||||
243. builtin type io2.Tls.Cipher
|
||||
244. builtin type io2.Tls.ClientConfig
|
||||
245. io2.Tls.ClientConfig.certificates.set : [SignedCert]
|
||||
229. io2.MVar.tryTake : MVar a ->{IO} Optional a
|
||||
230. unique type io2.SeekMode
|
||||
231. io2.SeekMode.AbsoluteSeek : SeekMode
|
||||
232. io2.SeekMode.RelativeSeek : SeekMode
|
||||
233. io2.SeekMode.SeekFromEnd : SeekMode
|
||||
234. builtin type io2.Socket
|
||||
235. unique type io2.StdHandle
|
||||
236. io2.StdHandle.StdErr : StdHandle
|
||||
237. io2.StdHandle.StdIn : StdHandle
|
||||
238. io2.StdHandle.StdOut : StdHandle
|
||||
239. builtin type io2.STM
|
||||
240. io2.STM.atomically : '{STM} a ->{IO} a
|
||||
241. io2.STM.retry : '{STM} a
|
||||
242. builtin type io2.ThreadId
|
||||
243. builtin type io2.Tls
|
||||
244. builtin type io2.Tls.Cipher
|
||||
245. builtin type io2.Tls.ClientConfig
|
||||
246. io2.Tls.ClientConfig.certificates.set : [SignedCert]
|
||||
-> ClientConfig
|
||||
-> ClientConfig
|
||||
246. io2.TLS.ClientConfig.ciphers.set : [Cipher]
|
||||
247. io2.TLS.ClientConfig.ciphers.set : [Cipher]
|
||||
-> ClientConfig
|
||||
-> ClientConfig
|
||||
247. io2.Tls.ClientConfig.default : Text
|
||||
248. io2.Tls.ClientConfig.default : Text
|
||||
-> Bytes
|
||||
-> ClientConfig
|
||||
248. io2.Tls.ClientConfig.versions.set : [Version]
|
||||
249. io2.Tls.ClientConfig.versions.set : [Version]
|
||||
-> ClientConfig
|
||||
-> ClientConfig
|
||||
249. io2.Tls.decodeCert.impl : Bytes
|
||||
250. io2.Tls.decodeCert.impl : Bytes
|
||||
-> Either Failure SignedCert
|
||||
250. io2.Tls.decodePrivateKey : Bytes -> [PrivateKey]
|
||||
251. io2.Tls.encodeCert : SignedCert -> Bytes
|
||||
252. io2.Tls.encodePrivateKey : PrivateKey -> Bytes
|
||||
253. io2.Tls.handshake.impl : Tls ->{IO} Either Failure ()
|
||||
254. io2.Tls.newClient.impl : ClientConfig
|
||||
251. io2.Tls.decodePrivateKey : Bytes -> [PrivateKey]
|
||||
252. io2.Tls.encodeCert : SignedCert -> Bytes
|
||||
253. io2.Tls.encodePrivateKey : PrivateKey -> Bytes
|
||||
254. io2.Tls.handshake.impl : Tls ->{IO} Either Failure ()
|
||||
255. io2.Tls.newClient.impl : ClientConfig
|
||||
-> Socket
|
||||
->{IO} Either Failure Tls
|
||||
255. io2.Tls.newServer.impl : ServerConfig
|
||||
256. io2.Tls.newServer.impl : ServerConfig
|
||||
-> Socket
|
||||
->{IO} Either Failure Tls
|
||||
256. builtin type io2.Tls.PrivateKey
|
||||
257. io2.Tls.receive.impl : Tls ->{IO} Either Failure Bytes
|
||||
258. io2.Tls.send.impl : Tls -> Bytes ->{IO} Either Failure ()
|
||||
259. builtin type io2.Tls.ServerConfig
|
||||
260. io2.Tls.ServerConfig.certificates.set : [SignedCert]
|
||||
257. builtin type io2.Tls.PrivateKey
|
||||
258. io2.Tls.receive.impl : Tls ->{IO} Either Failure Bytes
|
||||
259. io2.Tls.send.impl : Tls -> Bytes ->{IO} Either Failure ()
|
||||
260. builtin type io2.Tls.ServerConfig
|
||||
261. io2.Tls.ServerConfig.certificates.set : [SignedCert]
|
||||
-> ServerConfig
|
||||
-> ServerConfig
|
||||
261. io2.Tls.ServerConfig.ciphers.set : [Cipher]
|
||||
262. io2.Tls.ServerConfig.ciphers.set : [Cipher]
|
||||
-> ServerConfig
|
||||
-> ServerConfig
|
||||
262. io2.Tls.ServerConfig.default : [SignedCert]
|
||||
263. io2.Tls.ServerConfig.default : [SignedCert]
|
||||
-> PrivateKey
|
||||
-> ServerConfig
|
||||
263. io2.Tls.ServerConfig.versions.set : [Version]
|
||||
264. io2.Tls.ServerConfig.versions.set : [Version]
|
||||
-> ServerConfig
|
||||
-> ServerConfig
|
||||
264. builtin type io2.Tls.SignedCert
|
||||
265. io2.Tls.terminate.impl : Tls ->{IO} Either Failure ()
|
||||
266. builtin type io2.Tls.Version
|
||||
267. unique type io2.TlsFailure
|
||||
268. builtin type io2.TVar
|
||||
269. io2.TVar.new : a ->{STM} TVar a
|
||||
270. io2.TVar.newIO : a ->{IO} TVar a
|
||||
271. io2.TVar.read : TVar a ->{STM} a
|
||||
272. io2.TVar.readIO : TVar a ->{IO} a
|
||||
273. io2.TVar.swap : TVar a -> a ->{STM} a
|
||||
274. io2.TVar.write : TVar a -> a ->{STM} ()
|
||||
275. unique type IsPropagated
|
||||
276. IsPropagated.IsPropagated : IsPropagated
|
||||
277. unique type IsTest
|
||||
278. IsTest.IsTest : IsTest
|
||||
279. unique type Link
|
||||
280. builtin type Link.Term
|
||||
281. Link.Term : Term -> Link
|
||||
282. Link.Term.toText : Term -> Text
|
||||
283. builtin type Link.Type
|
||||
284. Link.Type : Type -> Link
|
||||
285. builtin type List
|
||||
286. List.++ : [a] -> [a] -> [a]
|
||||
287. List.+: : a -> [a] -> [a]
|
||||
288. List.:+ : [a] -> a -> [a]
|
||||
289. List.at : Nat -> [a] -> Optional a
|
||||
290. List.cons : a -> [a] -> [a]
|
||||
291. List.drop : Nat -> [a] -> [a]
|
||||
292. List.empty : [a]
|
||||
293. List.size : [a] -> Nat
|
||||
294. List.snoc : [a] -> a -> [a]
|
||||
295. List.take : Nat -> [a] -> [a]
|
||||
296. metadata.isPropagated : IsPropagated
|
||||
297. metadata.isTest : IsTest
|
||||
298. builtin type Nat
|
||||
299. Nat.* : Nat -> Nat -> Nat
|
||||
300. Nat.+ : Nat -> Nat -> Nat
|
||||
301. Nat./ : Nat -> Nat -> Nat
|
||||
302. Nat.and : Nat -> Nat -> Nat
|
||||
303. Nat.complement : Nat -> Nat
|
||||
304. Nat.drop : Nat -> Nat -> Nat
|
||||
305. Nat.eq : Nat -> Nat -> Boolean
|
||||
306. Nat.fromText : Text -> Optional Nat
|
||||
307. Nat.gt : Nat -> Nat -> Boolean
|
||||
308. Nat.gteq : Nat -> Nat -> Boolean
|
||||
309. Nat.increment : Nat -> Nat
|
||||
310. Nat.isEven : Nat -> Boolean
|
||||
311. Nat.isOdd : Nat -> Boolean
|
||||
312. Nat.leadingZeros : Nat -> Nat
|
||||
313. Nat.lt : Nat -> Nat -> Boolean
|
||||
314. Nat.lteq : Nat -> Nat -> Boolean
|
||||
315. Nat.mod : Nat -> Nat -> Nat
|
||||
316. Nat.or : Nat -> Nat -> Nat
|
||||
317. Nat.popCount : Nat -> Nat
|
||||
318. Nat.pow : Nat -> Nat -> Nat
|
||||
319. Nat.shiftLeft : Nat -> Nat -> Nat
|
||||
320. Nat.shiftRight : Nat -> Nat -> Nat
|
||||
321. Nat.sub : Nat -> Nat -> Int
|
||||
322. Nat.toFloat : Nat -> Float
|
||||
323. Nat.toInt : Nat -> Int
|
||||
324. Nat.toText : Nat -> Text
|
||||
325. Nat.trailingZeros : Nat -> Nat
|
||||
326. Nat.xor : Nat -> Nat -> Nat
|
||||
327. structural type Optional a
|
||||
328. Optional.None : Optional a
|
||||
329. Optional.Some : a -> Optional a
|
||||
330. builtin type Ref
|
||||
331. Ref.read : Ref g a ->{g} a
|
||||
332. Ref.write : Ref g a -> a ->{g} ()
|
||||
333. builtin type Request
|
||||
334. builtin type Scope
|
||||
335. Scope.ref : a ->{Scope s} Ref {Scope s} a
|
||||
336. Scope.run : (∀ s. '{g, Scope s} r) ->{g} r
|
||||
337. structural type SeqView a b
|
||||
338. SeqView.VElem : a -> b -> SeqView a b
|
||||
339. SeqView.VEmpty : SeqView a b
|
||||
340. Socket.toText : Socket -> Text
|
||||
341. unique type Test.Result
|
||||
342. Test.Result.Fail : Text -> Result
|
||||
343. Test.Result.Ok : Text -> Result
|
||||
344. builtin type Text
|
||||
345. Text.!= : Text -> Text -> Boolean
|
||||
346. Text.++ : Text -> Text -> Text
|
||||
347. Text.drop : Nat -> Text -> Text
|
||||
348. Text.empty : Text
|
||||
349. Text.eq : Text -> Text -> Boolean
|
||||
350. Text.fromCharList : [Char] -> Text
|
||||
351. Text.fromUtf8.impl : Bytes -> Either Failure Text
|
||||
352. Text.gt : Text -> Text -> Boolean
|
||||
353. Text.gteq : Text -> Text -> Boolean
|
||||
354. Text.lt : Text -> Text -> Boolean
|
||||
355. Text.lteq : Text -> Text -> Boolean
|
||||
356. Text.repeat : Nat -> Text -> Text
|
||||
357. Text.size : Text -> Nat
|
||||
358. Text.take : Nat -> Text -> Text
|
||||
359. Text.toCharList : Text -> [Char]
|
||||
360. Text.toUtf8 : Text -> Bytes
|
||||
361. Text.uncons : Text -> Optional (Char, Text)
|
||||
362. Text.unsnoc : Text -> Optional (Text, Char)
|
||||
363. ThreadId.toText : ThreadId -> Text
|
||||
364. todo : a -> b
|
||||
365. structural type Tuple a b
|
||||
366. Tuple.Cons : a -> b -> Tuple a b
|
||||
367. structural type Unit
|
||||
368. Unit.Unit : ()
|
||||
369. Universal.< : a -> a -> Boolean
|
||||
370. Universal.<= : a -> a -> Boolean
|
||||
371. Universal.== : a -> a -> Boolean
|
||||
372. Universal.> : a -> a -> Boolean
|
||||
373. Universal.>= : a -> a -> Boolean
|
||||
374. Universal.compare : a -> a -> Int
|
||||
375. unsafe.coerceAbilities : (a ->{e1} b) -> a ->{e2} b
|
||||
376. builtin type Value
|
||||
377. Value.dependencies : Value -> [Term]
|
||||
378. Value.deserialize : Bytes -> Either Text Value
|
||||
379. Value.load : Value ->{IO} Either [Term] a
|
||||
380. Value.serialize : Value -> Bytes
|
||||
381. Value.value : a -> Value
|
||||
265. builtin type io2.Tls.SignedCert
|
||||
266. io2.Tls.terminate.impl : Tls ->{IO} Either Failure ()
|
||||
267. builtin type io2.Tls.Version
|
||||
268. unique type io2.TlsFailure
|
||||
269. builtin type io2.TVar
|
||||
270. io2.TVar.new : a ->{STM} TVar a
|
||||
271. io2.TVar.newIO : a ->{IO} TVar a
|
||||
272. io2.TVar.read : TVar a ->{STM} a
|
||||
273. io2.TVar.readIO : TVar a ->{IO} a
|
||||
274. io2.TVar.swap : TVar a -> a ->{STM} a
|
||||
275. io2.TVar.write : TVar a -> a ->{STM} ()
|
||||
276. unique type IsPropagated
|
||||
277. IsPropagated.IsPropagated : IsPropagated
|
||||
278. unique type IsTest
|
||||
279. IsTest.IsTest : IsTest
|
||||
280. unique type Link
|
||||
281. builtin type Link.Term
|
||||
282. Link.Term : Term -> Link
|
||||
283. Link.Term.toText : Term -> Text
|
||||
284. builtin type Link.Type
|
||||
285. Link.Type : Type -> Link
|
||||
286. builtin type List
|
||||
287. List.++ : [a] -> [a] -> [a]
|
||||
288. List.+: : a -> [a] -> [a]
|
||||
289. List.:+ : [a] -> a -> [a]
|
||||
290. List.at : Nat -> [a] -> Optional a
|
||||
291. List.cons : a -> [a] -> [a]
|
||||
292. List.drop : Nat -> [a] -> [a]
|
||||
293. List.empty : [a]
|
||||
294. List.size : [a] -> Nat
|
||||
295. List.snoc : [a] -> a -> [a]
|
||||
296. List.take : Nat -> [a] -> [a]
|
||||
297. metadata.isPropagated : IsPropagated
|
||||
298. metadata.isTest : IsTest
|
||||
299. builtin type Nat
|
||||
300. Nat.* : Nat -> Nat -> Nat
|
||||
301. Nat.+ : Nat -> Nat -> Nat
|
||||
302. Nat./ : Nat -> Nat -> Nat
|
||||
303. Nat.and : Nat -> Nat -> Nat
|
||||
304. Nat.complement : Nat -> Nat
|
||||
305. Nat.drop : Nat -> Nat -> Nat
|
||||
306. Nat.eq : Nat -> Nat -> Boolean
|
||||
307. Nat.fromText : Text -> Optional Nat
|
||||
308. Nat.gt : Nat -> Nat -> Boolean
|
||||
309. Nat.gteq : Nat -> Nat -> Boolean
|
||||
310. Nat.increment : Nat -> Nat
|
||||
311. Nat.isEven : Nat -> Boolean
|
||||
312. Nat.isOdd : Nat -> Boolean
|
||||
313. Nat.leadingZeros : Nat -> Nat
|
||||
314. Nat.lt : Nat -> Nat -> Boolean
|
||||
315. Nat.lteq : Nat -> Nat -> Boolean
|
||||
316. Nat.mod : Nat -> Nat -> Nat
|
||||
317. Nat.or : Nat -> Nat -> Nat
|
||||
318. Nat.popCount : Nat -> Nat
|
||||
319. Nat.pow : Nat -> Nat -> Nat
|
||||
320. Nat.shiftLeft : Nat -> Nat -> Nat
|
||||
321. Nat.shiftRight : Nat -> Nat -> Nat
|
||||
322. Nat.sub : Nat -> Nat -> Int
|
||||
323. Nat.toFloat : Nat -> Float
|
||||
324. Nat.toInt : Nat -> Int
|
||||
325. Nat.toText : Nat -> Text
|
||||
326. Nat.trailingZeros : Nat -> Nat
|
||||
327. Nat.xor : Nat -> Nat -> Nat
|
||||
328. structural type Optional a
|
||||
329. Optional.None : Optional a
|
||||
330. Optional.Some : a -> Optional a
|
||||
331. builtin type Ref
|
||||
332. Ref.read : Ref g a ->{g} a
|
||||
333. Ref.write : Ref g a -> a ->{g} ()
|
||||
334. builtin type Request
|
||||
335. builtin type Scope
|
||||
336. Scope.ref : a ->{Scope s} Ref {Scope s} a
|
||||
337. Scope.run : (∀ s. '{g, Scope s} r) ->{g} r
|
||||
338. structural type SeqView a b
|
||||
339. SeqView.VElem : a -> b -> SeqView a b
|
||||
340. SeqView.VEmpty : SeqView a b
|
||||
341. Socket.toText : Socket -> Text
|
||||
342. unique type Test.Result
|
||||
343. Test.Result.Fail : Text -> Result
|
||||
344. Test.Result.Ok : Text -> Result
|
||||
345. builtin type Text
|
||||
346. Text.!= : Text -> Text -> Boolean
|
||||
347. Text.++ : Text -> Text -> Text
|
||||
348. Text.drop : Nat -> Text -> Text
|
||||
349. Text.empty : Text
|
||||
350. Text.eq : Text -> Text -> Boolean
|
||||
351. Text.fromCharList : [Char] -> Text
|
||||
352. Text.fromUtf8.impl : Bytes -> Either Failure Text
|
||||
353. Text.gt : Text -> Text -> Boolean
|
||||
354. Text.gteq : Text -> Text -> Boolean
|
||||
355. Text.lt : Text -> Text -> Boolean
|
||||
356. Text.lteq : Text -> Text -> Boolean
|
||||
357. Text.repeat : Nat -> Text -> Text
|
||||
358. Text.size : Text -> Nat
|
||||
359. Text.take : Nat -> Text -> Text
|
||||
360. Text.toCharList : Text -> [Char]
|
||||
361. Text.toUtf8 : Text -> Bytes
|
||||
362. Text.uncons : Text -> Optional (Char, Text)
|
||||
363. Text.unsnoc : Text -> Optional (Text, Char)
|
||||
364. ThreadId.toText : ThreadId -> Text
|
||||
365. todo : a -> b
|
||||
366. structural type Tuple a b
|
||||
367. Tuple.Cons : a -> b -> Tuple a b
|
||||
368. structural type Unit
|
||||
369. Unit.Unit : ()
|
||||
370. Universal.< : a -> a -> Boolean
|
||||
371. Universal.<= : a -> a -> Boolean
|
||||
372. Universal.== : a -> a -> Boolean
|
||||
373. Universal.> : a -> a -> Boolean
|
||||
374. Universal.>= : a -> a -> Boolean
|
||||
375. Universal.compare : a -> a -> Int
|
||||
376. unsafe.coerceAbilities : (a ->{e1} b) -> a ->{e2} b
|
||||
377. builtin type Value
|
||||
378. Value.dependencies : Value -> [Term]
|
||||
379. Value.deserialize : Bytes -> Either Text Value
|
||||
380. Value.load : Value ->{IO} Either [Term] a
|
||||
381. Value.serialize : Value -> Bytes
|
||||
382. Value.value : a -> Value
|
||||
|
||||
|
||||
.builtin> alias.many 94-104 .mylib
|
||||
@ -477,17 +478,17 @@ Let's try it!
|
||||
|
||||
Added definitions:
|
||||
|
||||
1. Float.cosh : Float -> Float
|
||||
2. Float.eq : Float -> Float -> Boolean
|
||||
3. Float.exp : Float -> Float
|
||||
4. Float.floor : Float -> Int
|
||||
5. Float.fromRepresentation : Nat -> Float
|
||||
6. Float.fromText : Text -> Optional Float
|
||||
7. Float.gt : Float -> Float -> Boolean
|
||||
8. Float.gteq : Float -> Float -> Boolean
|
||||
9. Float.log : Float -> Float
|
||||
10. Float.logBase : Float -> Float -> Float
|
||||
11. Float.lt : Float -> Float -> Boolean
|
||||
1. Float.cos : Float -> Float
|
||||
2. Float.cosh : Float -> Float
|
||||
3. Float.eq : Float -> Float -> Boolean
|
||||
4. Float.exp : Float -> Float
|
||||
5. Float.floor : Float -> Int
|
||||
6. Float.fromRepresentation : Nat -> Float
|
||||
7. Float.fromText : Text -> Optional Float
|
||||
8. Float.gt : Float -> Float -> Boolean
|
||||
9. Float.gteq : Float -> Float -> Boolean
|
||||
10. Float.log : Float -> Float
|
||||
11. Float.logBase : Float -> Float -> Float
|
||||
|
||||
Tip: You can use `undo` or `reflog` to undo this change.
|
||||
|
||||
@ -547,17 +548,17 @@ I want to incorporate a few more from another namespace:
|
||||
|
||||
.mylib> find
|
||||
|
||||
1. Float.cosh : Float -> Float
|
||||
2. Float.eq : Float -> Float -> Boolean
|
||||
3. Float.exp : Float -> Float
|
||||
4. Float.floor : Float -> Int
|
||||
5. Float.fromRepresentation : Nat -> Float
|
||||
6. Float.fromText : Text -> Optional Float
|
||||
7. Float.gt : Float -> Float -> Boolean
|
||||
8. Float.gteq : Float -> Float -> Boolean
|
||||
9. Float.log : Float -> Float
|
||||
10. Float.logBase : Float -> Float -> Float
|
||||
11. Float.lt : Float -> Float -> Boolean
|
||||
1. Float.cos : Float -> Float
|
||||
2. Float.cosh : Float -> Float
|
||||
3. Float.eq : Float -> Float -> Boolean
|
||||
4. Float.exp : Float -> Float
|
||||
5. Float.floor : Float -> Int
|
||||
6. Float.fromRepresentation : Nat -> Float
|
||||
7. Float.fromText : Text -> Optional Float
|
||||
8. Float.gt : Float -> Float -> Boolean
|
||||
9. Float.gteq : Float -> Float -> Boolean
|
||||
10. Float.log : Float -> Float
|
||||
11. Float.logBase : Float -> Float -> Float
|
||||
12. List.adjacentPairs : [a] -> [(a, a)]
|
||||
13. List.all : (a ->{g} Boolean) -> [a] ->{g} Boolean
|
||||
14. List.any : (a ->{g} Boolean) -> [a] ->{g} Boolean
|
||||
|
@ -19,7 +19,7 @@ The `builtins.merge` command adds the known builtins to a `builtin` subnamespace
|
||||
8. Char/ (3 definitions)
|
||||
9. Code (builtin type)
|
||||
10. Code/ (8 definitions)
|
||||
11. Debug/ (1 definition)
|
||||
11. Debug/ (2 definitions)
|
||||
12. Doc (type)
|
||||
13. Doc/ (6 definitions)
|
||||
14. Either (type)
|
||||
|
62
unison-src/transcripts/empty-namespaces.md
Normal file
62
unison-src/transcripts/empty-namespaces.md
Normal file
@ -0,0 +1,62 @@
|
||||
# Empty namespace behaviours
|
||||
|
||||
```unison:hide
|
||||
mynamespace.x = 1
|
||||
```
|
||||
|
||||
```ucm:hide
|
||||
.> add
|
||||
.> delete.namespace mynamespace
|
||||
```
|
||||
|
||||
The deleted namespace shouldn't appear in `ls` output.
|
||||
```ucm:error
|
||||
.> ls
|
||||
```
|
||||
```ucm:error
|
||||
.> ls.verbose
|
||||
```
|
||||
```ucm:error
|
||||
.> find mynamespace
|
||||
```
|
||||
|
||||
## history
|
||||
|
||||
The history of the namespace should still exist if requested explicitly.
|
||||
|
||||
```ucm
|
||||
.> history mynamespace
|
||||
```
|
||||
|
||||
Merging an empty namespace should still copy its history if it has some.
|
||||
|
||||
```ucm
|
||||
.empty> history
|
||||
.empty> merge .mynamespace
|
||||
.empty> history
|
||||
```
|
||||
|
||||
Add and then delete a term to add some history to a deleted namespace.
|
||||
|
||||
```unison:hide
|
||||
deleted.x = 1
|
||||
stuff.thing = 2
|
||||
```
|
||||
|
||||
```ucm:hide
|
||||
.> add
|
||||
.> delete.namespace .deleted
|
||||
```
|
||||
|
||||
I should be allowed to fork over a deleted namespace
|
||||
|
||||
```ucm
|
||||
.> fork stuff deleted
|
||||
```
|
||||
|
||||
The history from the `deleted` namespace should have been overwritten by the history from `stuff`.
|
||||
|
||||
```ucm
|
||||
.> history stuff
|
||||
.> history deleted
|
||||
```
|
114
unison-src/transcripts/empty-namespaces.output.md
Normal file
114
unison-src/transcripts/empty-namespaces.output.md
Normal file
@ -0,0 +1,114 @@
|
||||
# Empty namespace behaviours
|
||||
|
||||
```unison
|
||||
mynamespace.x = 1
|
||||
```
|
||||
|
||||
The deleted namespace shouldn't appear in `ls` output.
|
||||
```ucm
|
||||
.> ls
|
||||
|
||||
nothing to show
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> ls.verbose
|
||||
|
||||
😶
|
||||
|
||||
No results. Check your spelling, or try using tab completion
|
||||
to supply command arguments.
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> find mynamespace
|
||||
|
||||
😶
|
||||
|
||||
No results. Check your spelling, or try using tab completion
|
||||
to supply command arguments.
|
||||
|
||||
```
|
||||
## history
|
||||
|
||||
The history of the namespace should still exist if requested explicitly.
|
||||
|
||||
```ucm
|
||||
.> history mynamespace
|
||||
|
||||
Note: The most recent namespace hash is immediately below this
|
||||
message.
|
||||
|
||||
⊙ #qjc20aua9h
|
||||
|
||||
- Deletes:
|
||||
|
||||
x
|
||||
|
||||
□ #hkrqt3tm05 (start of history)
|
||||
|
||||
```
|
||||
Merging an empty namespace should still copy its history if it has some.
|
||||
|
||||
```ucm
|
||||
☝️ The namespace .empty is empty.
|
||||
|
||||
.empty> history
|
||||
|
||||
☝️ The namespace .empty is empty.
|
||||
|
||||
.empty> merge .mynamespace
|
||||
|
||||
Nothing changed as a result of the merge.
|
||||
|
||||
.empty> history
|
||||
|
||||
Note: The most recent namespace hash is immediately below this
|
||||
message.
|
||||
|
||||
⊙ #qjc20aua9h
|
||||
|
||||
- Deletes:
|
||||
|
||||
x
|
||||
|
||||
□ #hkrqt3tm05 (start of history)
|
||||
|
||||
```
|
||||
Add and then delete a term to add some history to a deleted namespace.
|
||||
|
||||
```unison
|
||||
deleted.x = 1
|
||||
stuff.thing = 2
|
||||
```
|
||||
|
||||
I should be allowed to fork over a deleted namespace
|
||||
|
||||
```ucm
|
||||
.> fork stuff deleted
|
||||
|
||||
Done.
|
||||
|
||||
```
|
||||
The history from the `deleted` namespace should have been overwritten by the history from `stuff`.
|
||||
|
||||
```ucm
|
||||
.> history stuff
|
||||
|
||||
Note: The most recent namespace hash is immediately below this
|
||||
message.
|
||||
|
||||
|
||||
|
||||
□ #3bm1524lb7 (start of history)
|
||||
|
||||
.> history deleted
|
||||
|
||||
Note: The most recent namespace hash is immediately below this
|
||||
message.
|
||||
|
||||
|
||||
|
||||
□ #3bm1524lb7 (start of history)
|
||||
|
||||
```
|
@ -23,7 +23,7 @@ Technically, the definitions all exist, but they have no names. `builtins.merge`
|
||||
|
||||
.foo> ls
|
||||
|
||||
1. builtin/ (381 definitions)
|
||||
1. builtin/ (382 definitions)
|
||||
|
||||
```
|
||||
And for a limited time, you can get even more builtin goodies:
|
||||
@ -35,7 +35,7 @@ And for a limited time, you can get even more builtin goodies:
|
||||
|
||||
.foo> ls
|
||||
|
||||
1. builtin/ (549 definitions)
|
||||
1. builtin/ (550 definitions)
|
||||
|
||||
```
|
||||
More typically, you'd start out by pulling `base.
|
||||
|
@ -125,13 +125,13 @@ We can also delete the fork if we're done with it. (Don't worry, it's still in t
|
||||
Note: The most recent namespace hash is immediately below this
|
||||
message.
|
||||
|
||||
⊙ #7gjmqmlj0v
|
||||
⊙ #5aa4qmhvur
|
||||
|
||||
- Deletes:
|
||||
|
||||
feature1.y
|
||||
|
||||
⊙ #7qqt9t3qr5
|
||||
⊙ #g1jho38v97
|
||||
|
||||
+ Adds / updates:
|
||||
|
||||
@ -142,26 +142,26 @@ We can also delete the fork if we're done with it. (Don't worry, it's still in t
|
||||
Original name New name(s)
|
||||
feature1.y master.y
|
||||
|
||||
⊙ #u86vero990
|
||||
⊙ #dkcip47417
|
||||
|
||||
+ Adds / updates:
|
||||
|
||||
feature1.y
|
||||
|
||||
⊙ #el4liebh4m
|
||||
⊙ #at9qnsl83m
|
||||
|
||||
> Moves:
|
||||
|
||||
Original name New name
|
||||
x master.x
|
||||
|
||||
⊙ #pne2sthbc8
|
||||
⊙ #g271dghaje
|
||||
|
||||
+ Adds / updates:
|
||||
|
||||
x
|
||||
|
||||
□ #qnkdl1f20n (start of history)
|
||||
□ #aooso6apun (start of history)
|
||||
|
||||
```
|
||||
To resurrect an old version of a namespace, you can learn its hash via the `history` command, then use `fork #namespacehash .newname`.
|
||||
|
@ -59,16 +59,16 @@ y = 2
|
||||
most recent, along with the command that got us there. Try:
|
||||
|
||||
`fork 2 .old`
|
||||
`fork #7m7gaa64si .old` to make an old namespace
|
||||
`fork #ttu893rclh .old` to make an old namespace
|
||||
accessible again,
|
||||
|
||||
`reset-root #7m7gaa64si` to reset the root namespace and
|
||||
`reset-root #ttu893rclh` to reset the root namespace and
|
||||
its history to that of the
|
||||
specified namespace.
|
||||
|
||||
1. #k8o73d0cc0 : add
|
||||
2. #7m7gaa64si : add
|
||||
3. #qnkdl1f20n : builtins.merge
|
||||
1. #opcc5n8q9a : add
|
||||
2. #ttu893rclh : add
|
||||
3. #aooso6apun : builtins.merge
|
||||
4. #sjg2v58vn2 : (initial reflogged namespace)
|
||||
|
||||
```
|
||||
|
@ -13,7 +13,7 @@ Let's look at some examples. We'll start with a namespace with just the builtins
|
||||
|
||||
|
||||
|
||||
□ #tfjjgvaq9l (start of history)
|
||||
□ #afd37h0nli (start of history)
|
||||
|
||||
.> fork builtin builtin2
|
||||
|
||||
@ -42,21 +42,21 @@ Now suppose we `fork` a copy of builtin, then rename `Nat.+` to `frobnicate`, th
|
||||
Note: The most recent namespace hash is immediately below this
|
||||
message.
|
||||
|
||||
⊙ #uiahjr3nvu
|
||||
⊙ #k528t27n2n
|
||||
|
||||
> Moves:
|
||||
|
||||
Original name New name
|
||||
Nat.frobnicate Nat.+
|
||||
|
||||
⊙ #ov2s5dsaba
|
||||
⊙ #3a5rbkh4bd
|
||||
|
||||
> Moves:
|
||||
|
||||
Original name New name
|
||||
Nat.+ Nat.frobnicate
|
||||
|
||||
□ #tfjjgvaq9l (start of history)
|
||||
□ #afd37h0nli (start of history)
|
||||
|
||||
```
|
||||
If we merge that back into `builtin`, we get that same chain of history:
|
||||
@ -71,21 +71,21 @@ If we merge that back into `builtin`, we get that same chain of history:
|
||||
Note: The most recent namespace hash is immediately below this
|
||||
message.
|
||||
|
||||
⊙ #uiahjr3nvu
|
||||
⊙ #k528t27n2n
|
||||
|
||||
> Moves:
|
||||
|
||||
Original name New name
|
||||
Nat.frobnicate Nat.+
|
||||
|
||||
⊙ #ov2s5dsaba
|
||||
⊙ #3a5rbkh4bd
|
||||
|
||||
> Moves:
|
||||
|
||||
Original name New name
|
||||
Nat.+ Nat.frobnicate
|
||||
|
||||
□ #tfjjgvaq9l (start of history)
|
||||
□ #afd37h0nli (start of history)
|
||||
|
||||
```
|
||||
Let's try again, but using a `merge.squash` (or just `squash`) instead. The history will be unchanged:
|
||||
@ -106,7 +106,7 @@ Let's try again, but using a `merge.squash` (or just `squash`) instead. The hist
|
||||
|
||||
|
||||
|
||||
□ #tfjjgvaq9l (start of history)
|
||||
□ #afd37h0nli (start of history)
|
||||
|
||||
```
|
||||
The churn that happened in `mybuiltin` namespace ended up back in the same spot, so the squash merge of that namespace with our original namespace had no effect.
|
||||
@ -485,13 +485,13 @@ This checks to see that squashing correctly preserves deletions:
|
||||
Note: The most recent namespace hash is immediately below this
|
||||
message.
|
||||
|
||||
⊙ #dp0rpp67if
|
||||
⊙ #jma01uqhdr
|
||||
|
||||
- Deletes:
|
||||
|
||||
Nat.* Nat.+
|
||||
|
||||
□ #tfjjgvaq9l (start of history)
|
||||
□ #afd37h0nli (start of history)
|
||||
|
||||
```
|
||||
Notice that `Nat.+` and `Nat.*` are deleted by the squash, and we see them deleted in one atomic step in the history.
|
||||
|
Loading…
Reference in New Issue
Block a user