diff --git a/persistent-vector.cabal b/persistent-vector.cabal
--- a/persistent-vector.cabal
+++ b/persistent-vector.cabal
@@ -1,5 +1,5 @@
 name: persistent-vector
-version: 0.1.0.0
+version: 0.1.0.1
 synopsis: A persistent sequence based on array mapped tries
 license: BSD3
 license-file: LICENSE
@@ -9,6 +9,8 @@
 build-type: Simple
 cabal-version: >=1.10
 extra-source-files: README.md
+homepage: https://github.com/travitch/persistent-vector
+bug-reports: https://github.com/travitch/persistent-vector/issues
 
 description:
   This package provides persistent vectors based on array mapped
@@ -38,7 +40,7 @@
   exposed-modules: Data.Vector.Persistent
   other-modules: Data.Vector.Persistent.Array
                  Data.Vector.Persistent.Unsafe
-  build-depends: base ==4.5.*, deepseq
+  build-depends: base ==4.*, deepseq
   hs-source-dirs: src
   ghc-options: -Wall
   ghc-prof-options: -auto-all
@@ -67,3 +69,7 @@
                  containers,
                  criterion,
                  deepseq
+
+source-repository head
+  type: git
+  location: git://github.com/travitch/persistent-vector.git
diff --git a/src/Data/Vector/Persistent.hs b/src/Data/Vector/Persistent.hs
--- a/src/Data/Vector/Persistent.hs
+++ b/src/Data/Vector/Persistent.hs
@@ -103,10 +103,14 @@
 -- where neither input is sliced.  For sliced inputs, we currently
 -- fall back to a list conversion.
 pvEq :: (Eq a) => Vector a -> Vector a -> Bool
-pvEq v1 v2
+pvEq EmptyVector EmptyVector = True
+pvEq v1@RootNode { } v2@RootNode { }
   | length v1 /= length v2 = False
   | isNotSliced v1 && isNotSliced v2 = pvSimpleEq v1 v2
   | otherwise = F.toList v1 == F.toList v2
+pvEq (DataNode a1) (DataNode a2) = a1 == a2
+pvEq (InternalNode a1) (InternalNode a2) = a1 == a2
+pvEq _ _ = False
 
 -- | A simple equality implementation for unsliced vectors.  This can
 -- proceed structurally.
@@ -121,11 +125,21 @@
 {-# INLINABLE pvCompare #-}
 -- | A dispatcher for comparison tests
 pvCompare :: (Ord a) => Vector a -> Vector a -> Ordering
-pvCompare v1 v2
-  | length v1 /= length v2 = compare (length v1) (length v2)
+pvCompare EmptyVector EmptyVector = EQ
+pvCompare (DataNode a1) (DataNode a2) = compare a1 a2
+pvCompare (InternalNode a1) (InternalNode a2) = compare a1 a2
+pvCompare v1@RootNode { vecSize = s1 } v2@RootNode { vecSize = s2 }
+  | s1 /= s2 = compare s1 s2
   | isNotSliced v1 && isNotSliced v2 = pvSimpleCompare v1 v2
   | otherwise = compare (F.toList v1) (F.toList v2)
+pvCompare EmptyVector _ = LT
+pvCompare _ EmptyVector = GT
+pvCompare (DataNode _) (InternalNode _) = LT
+pvCompare (InternalNode _) (DataNode _) = GT
+pvCompare _ _ = error "Data.Vector.Persistent: unexpected root node"
 
+
+
 pvSimpleCompare :: (Ord a) => Vector a -> Vector a -> Ordering
 pvSimpleCompare EmptyVector EmptyVector = EQ
 pvSimpleCompare (RootNode _ _ _ _ t1 v1) (RootNode _ _ _ _ t2 v2) =
@@ -272,6 +286,7 @@
 -- usually just return nonsense values.
 unsafeIndex :: Vector a -> Int -> a
 unsafeIndex vec userIndex
+--  | tailOffset vec < vecOffset vec = L.reverse (vecTail vec) !! (userIndex .&. 0x1f)
   | ix >= tailOffset vec && vecCapacity vec < vecSize vec =
     L.reverse (vecTail vec) !! (ix .&. 0x1f)
   | otherwise = go (vecShift vec) vec
@@ -310,14 +325,13 @@
 -- | O(1) Append an element to the end of the vector.
 snoc :: Vector a -> a -> Vector a
 snoc EmptyVector elt = singleton elt
-snoc v@RootNode { vecSize = sz, vecShift = sh, vecTail = t } elt
+snoc v@RootNode { vecSize = sz, vecShift = sh, vecOffset = off, vecTail = t } elt
   -- In this case, we are operating on a slice that has free space at
   -- the end inside of its tree.  Use 'update' to replace the formerly
   -- unreachable element and then make it reachable.
-  | vecCapacity v > sz =
-    let v' = update sz elt v
-    in v' { vecSize = vecSize v' + 1 }
-  -- Room in tail
+  | vecCapacity v >= sz =
+    let v' = v { vecSize = sz + 1 }
+    in update (sz - off) elt v'
   | sz .&. 0x1f /= 0 = v { vecTail = elt : t, vecSize = sz + 1 }
   -- Overflow current root
   | sz `shiftR` 5 > 1 `shiftL` sh =
@@ -387,9 +401,15 @@
   | sz <= ix || ix < 0 = v
   -- Item is in tail,
   | ix >= toff && vecCapacity v < sz =
-    let tix = sz - 1 - ix
-        (keepHead, _:keepTail) = L.splitAt tix t
-    in v { vecTail = keepHead ++ (elt : keepTail) }
+    case t of
+      -- The tail can only be empty if this was a slice where the last
+      -- array in the tree is full and the slice left no tail.  This
+      -- is rare but we have to handle it.
+      [] -> v { vecTail = [elt] }
+      _ ->
+        let tix = sz - 1 - ix
+            (keepHead, _:keepTail) = L.splitAt tix t
+        in v { vecTail = keepHead ++ (elt : keepTail) }
   -- Otherwise the item to be replaced is in the tree
   | otherwise = v { intVecPtrs = go sh (intVecPtrs v) }
   where
@@ -429,6 +449,15 @@
 slice _ _ EmptyVector = EmptyVector
 slice start userLen v@RootNode { vecSize = sz, vecOffset = off, vecCapacity = cap, vecTail = t }
   | len <= 0 = EmptyVector
+  -- All the retained data is in the tail, so zero everything else out
+  | toff < start =
+    let t' = L.reverse $ L.take userLen $ L.drop (start - toff) $ L.reverse t
+    in v { vecOffset = 0
+         , vecCapacity = 0
+         , intVecPtrs = A.fromList 0 []
+         , vecSize = L.length t'
+         , vecTail = t'
+         }
   -- Start was negative, so we really start at zero and retain at most
   -- (len + start) elements.  In this case vecOffset remains the same.
   | start < 0 =
@@ -449,6 +478,7 @@
            , vecTail = L.take (L.length t' - ntake) t'
            }
   where
+    toff = tailOffset v
     len = max 0 (min userLen (sz - start))
 slice _ _ _ = error "Data.Vector.Persistent.slice: Internal node"
 
@@ -509,11 +539,12 @@
 -- Helpers
 
 tailOffset :: Vector a -> Int
+tailOffset EmptyVector = 0
 tailOffset v
   | len < 32 = 0
   | otherwise = (len - 1) `shiftR` 5 `shiftL` 5
   where
-    len = length v
+    len = vecSize v
 
 isNotSliced :: Vector a -> Bool
 isNotSliced v = vecOffset v == 0 && vecCapacity v < vecSize v
diff --git a/tests/pvTests.hs b/tests/pvTests.hs
--- a/tests/pvTests.hs
+++ b/tests/pvTests.hs
@@ -65,6 +65,7 @@
         , testProperty "mappendWorks" prop_mappendWorks
         , testProperty "shrink" prop_shrinkPreserves
         , testProperty "shrinkEq" prop_shrinkEquality
+        , testProperty "appendAfterSlice" prop_appendAfterSlice
         ]
 
 main :: IO ()
@@ -147,3 +148,10 @@
   v0 == V.shrink v0
   where
     v0 = V.slice s n (V.fromList il)
+
+prop_appendAfterSlice :: (SliceList, Int) -> Property
+prop_appendAfterSlice (SliceList il s n, elt) =
+  n - s < L.length il ==> Just elt == V.index v1 (V.length v1 - 1)
+  where
+    v0 = V.slice s n (V.fromList il)
+    v1 = V.snoc v0 elt
