diff --git a/Control/Concurrent/Async.hs b/Control/Concurrent/Async.hs
--- a/Control/Concurrent/Async.hs
+++ b/Control/Concurrent/Async.hs
@@ -117,7 +117,7 @@
     waitBothSTM,
 
     -- ** Linking
-    link, link2, ExceptionInLinkedThread(..),
+    link, linkOnly, link2, link2Only, ExceptionInLinkedThread(..),
 
     -- * Convenient utilities
     race, race_,
@@ -185,7 +185,7 @@
 instance Functor Async where
   fmap f (Async a w) = Async a (fmap (fmap f) w)
 
--- | Compare two 'Async's that may have different types
+-- | Compare two Asyncs that may have different types by their ThreadId.
 compareAsyncs :: Async a -> Async b -> Ordering
 compareAsyncs (Async t1 _) (Async t2 _) = compare t1 t2
 
@@ -230,7 +230,7 @@
 --
 -- > withAsync action inner = mask $ \restore -> do
 -- >   a <- async (restore action)
--- >   restore inner `finally` uninterruptibleCancel a
+-- >   restore (inner a) `finally` uninterruptibleCancel a
 --
 -- This is a useful variant of 'async' that ensures an @Async@ is
 -- never left running unintentionally.
@@ -289,7 +289,10 @@
 --
 {-# INLINE wait #-}
 wait :: Async a -> IO a
-wait = atomically . waitSTM
+wait = tryAgain . atomically . waitSTM
+  where
+    -- See: https://github.com/simonmar/async/issues/14
+    tryAgain f = f `catch` \BlockedIndefinitelyOnSTM -> f
 
 -- | Wait for an asynchronous action to complete, and return either
 -- @Left e@ if the action raised an exception @e@, or @Right a@ if it
@@ -537,8 +540,12 @@
 #endif
 
 instance Show ExceptionInLinkedThread where
-  show (ExceptionInLinkedThread (Async t _) e) =
-    "ExceptionInLinkedThread " ++ show t ++ " " ++ show e
+  showsPrec p (ExceptionInLinkedThread (Async t _) e) =
+    showParen (p >= 11) $
+      showString "ExceptionInLinkedThread " .
+      showsPrec 11 t .
+      showString " " .
+      showsPrec 11 e
 
 instance Exception ExceptionInLinkedThread where
 #if __GLASGOW_HASKELL__ >= 708
@@ -559,10 +566,11 @@
 
 -- | Link the given @Async@ to the current thread, such that if the
 -- @Async@ raises an exception, that exception will be re-thrown in
--- the current thread.  The supplied predicate determines which
--- exceptions in the target thread should be propagated to the source
--- thread.
+-- the current thread, wrapped in 'ExceptionInLinkedThread'.
 --
+-- The supplied predicate determines which exceptions in the target
+-- thread should be propagated to the source thread.
+--
 linkOnly
   :: (SomeException -> Bool)  -- ^ return 'True' if the exception
                               -- should be propagated, 'False'
@@ -588,6 +596,13 @@
 link2 :: Async a -> Async b -> IO ()
 link2 = link2Only (not . isCancel)
 
+-- | Link two @Async@s together, such that if either raises an
+-- exception, the same exception is re-thrown in the other @Async@,
+-- wrapped in 'ExceptionInLinkedThread'.
+--
+-- The supplied predicate determines which exceptions in the target
+-- thread should be propagated to the source thread.
+--
 link2Only :: (SomeException -> Bool) -> Async a -> Async b -> IO ()
 link2Only shouldThrow left@(Async tl _)  right@(Async tr _) =
   void $ forkRepeat $ do
@@ -755,12 +770,12 @@
 forConcurrently = flip mapConcurrently
 
 -- | `mapConcurrently_` is `mapConcurrently` with the return value discarded,
--- just like @mapM_
+-- just like @mapM_@.
 mapConcurrently_ :: F.Foldable f => (a -> IO b) -> f a -> IO ()
 mapConcurrently_ f = runConcurrently . F.foldMap (Concurrently . void . f)
 
 -- | `forConcurrently_` is `forConcurrently` with the return value discarded,
--- just like @forM_
+-- just like @forM_@.
 forConcurrently_ :: F.Foldable f => f a -> (a -> IO b) -> IO ()
 forConcurrently_ = flip mapConcurrently_
 
diff --git a/async.cabal b/async.cabal
--- a/async.cabal
+++ b/async.cabal
@@ -1,5 +1,5 @@
 name:                async
-version:             2.2.1
+version:             2.2.2
 -- don't forget to update ./changelog.md!
 synopsis:            Run IO operations asynchronously and wait for their results
 
@@ -34,7 +34,7 @@
 cabal-version:       >=1.10
 homepage:            https://github.com/simonmar/async
 bug-reports:         https://github.com/simonmar/async/issues
-tested-with:         GHC==8.2.2, GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2, GHC==7.2.2, GHC==7.0.4
+tested-with:         GHC==8.6.5, GHC==8.4.4, GHC==8.2.2, GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2, GHC==7.2.2, GHC==7.0.4
 
 extra-source-files:
     changelog.md
@@ -50,14 +50,14 @@
     if impl(ghc>=7.1)
         other-extensions: Trustworthy
     exposed-modules:     Control.Concurrent.Async
-    build-depends:       base >= 4.3 && < 4.12, hashable >= 1.1.1.0 && < 1.3, stm >= 2.2 && < 2.5
+    build-depends:       base >= 4.3 && < 4.14, hashable >= 1.1.2.0 && < 1.4, stm >= 2.2 && < 2.6
 
 test-suite test-async
     default-language: Haskell2010
     type:       exitcode-stdio-1.0
     hs-source-dirs: test
     main-is:    test-async.hs
-    build-depends: base >= 4.3 && < 4.12,
+    build-depends: base >= 4.3 && < 4.14,
                    async,
                    stm,
                    test-framework,
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,10 @@
+## Changes in 2.2.2:
+
+ - Builds with GHC 8.6.x
+ - linkOnly and link2Only are now exported
+ - wait now has the same behaviour with BlockedIndefinitelyOnSTM as waitCatch
+ - Documentation fixes
+
 ## Changes in 2.2.1:
 
  - Add a Hashable instance for Async
diff --git a/test/test-async.hs b/test/test-async.hs
--- a/test/test-async.hs
+++ b/test/test-async.hs
@@ -34,6 +34,7 @@
   , testCase "async_poll"        async_poll
   , testCase "async_poll2"       async_poll2
   , testCase "withasync_waitCatch_blocked" withasync_waitCatch_blocked
+  , testCase "withasync_wait_blocked" withasync_wait_blocked
   , testGroup "children surviving too long"
       [ testCase "concurrently+success" concurrently_success
       , testCase "concurrently+failure" concurrently_failure
@@ -140,6 +141,16 @@
 withasync_waitCatch_blocked :: Assertion
 withasync_waitCatch_blocked = do
   r <- withAsync (newEmptyMVar >>= takeMVar) waitCatch
+  case r of
+    Left e ->
+        case fromException e of
+            Just BlockedIndefinitelyOnMVar -> return ()
+            Nothing -> assertFailure $ show e
+    Right () -> assertFailure ""
+
+withasync_wait_blocked :: Assertion
+withasync_wait_blocked = do
+  r <- try $ withAsync (newEmptyMVar >>= takeMVar) wait
   case r of
     Left e ->
         case fromException e of
