diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,11 @@
 # Changelog for polysemy-plugin
 
+## Unreleased
+
+## 0.4.0.0 (2021-07-12)
+
+* Support GHC 9.0.1
+
 ## 0.3.0.0 (2021-03-30)
 
 ### Breaking Changes
diff --git a/polysemy-plugin.cabal b/polysemy-plugin.cabal
--- a/polysemy-plugin.cabal
+++ b/polysemy-plugin.cabal
@@ -5,9 +5,9 @@
 -- see: https://github.com/sol/hpack
 
 name:           polysemy-plugin
-version:        0.3.0.0
+version:        0.4.0.0
 synopsis:       Disambiguate obvious uses of effects.
-description:    Please see the README on GitHub at <https://github.com/isovector/polysemy/tree/master/polysemy-plugin#readme>
+description:    Please see the README on GitHub at <https://github.com/polysemy-research/polysemy/tree/master/polysemy-plugin#readme>
 category:       Polysemy
 homepage:       https://github.com/polysemy-research/polysemy#readme
 bug-reports:    https://github.com/polysemy-research/polysemy/issues
@@ -66,7 +66,7 @@
   build-depends:
       base >=4.9 && <5
     , containers >=0.5 && <0.7
-    , ghc >=8.6.5 && <9
+    , ghc >=8.6.5 && <10
     , ghc-tcplugins-extra >=0.3 && <0.5
     , polysemy >=1.3
     , syb ==0.7.*
@@ -80,6 +80,7 @@
       BadSpec
       DoctestSpec
       ExampleSpec
+      InsertSpec
       LegitimateTypeErrorSpec
       MultipleVarsSpec
       PluginSpec
@@ -111,8 +112,8 @@
   build-depends:
       base >=4.9 && <5
     , containers >=0.5 && <0.7
-    , doctest >=0.16.0.1 && <0.17
-    , ghc >=8.6.5 && <9
+    , doctest >=0.16.0.1 && <0.19
+    , ghc >=8.6.5 && <10
     , ghc-tcplugins-extra >=0.3 && <0.5
     , hspec >=2.6.0 && <3
     , inspection-testing >=0.4.2 && <0.5
diff --git a/src/Polysemy/Plugin.hs b/src/Polysemy/Plugin.hs
--- a/src/Polysemy/Plugin.hs
+++ b/src/Polysemy/Plugin.hs
@@ -63,7 +63,11 @@
 
 import Polysemy.Plugin.Fundep
 
+#if __GLASGOW_HASKELL__ >= 900
+import GHC.Plugins
+#else
 import GhcPlugins
+#endif
 
 ------------------------------------------------------------------------------
 plugin :: Plugin
diff --git a/src/Polysemy/Plugin/Fundep.hs b/src/Polysemy/Plugin/Fundep.hs
--- a/src/Polysemy/Plugin/Fundep.hs
+++ b/src/Polysemy/Plugin/Fundep.hs
@@ -44,6 +44,14 @@
 import           Polysemy.Plugin.Fundep.Stuff
 import           Polysemy.Plugin.Fundep.Unification
 import           Polysemy.Plugin.Fundep.Utils
+#if __GLASGOW_HASKELL__ >= 900
+import           GHC.Tc.Types.Evidence
+import           GHC.Tc.Plugin (TcPluginM, tcPluginIO)
+import           GHC.Tc.Types
+import           GHC.Tc.Types.Constraint
+import           GHC.Tc.Solver.Monad hiding (tcLookupClass)
+import           GHC.Core.Type
+#else
 import           TcEvidence
 import           TcPluginM (TcPluginM, tcPluginIO)
 import           TcRnTypes
@@ -52,6 +60,7 @@
 #endif
 import           TcSMonad hiding (tcLookupClass)
 import           Type
+#endif
 
 
 
diff --git a/src/Polysemy/Plugin/Fundep/Stuff.hs b/src/Polysemy/Plugin/Fundep/Stuff.hs
--- a/src/Polysemy/Plugin/Fundep/Stuff.hs
+++ b/src/Polysemy/Plugin/Fundep/Stuff.hs
@@ -7,14 +7,23 @@
   ) where
 
 import Data.Kind (Type)
-import FastString (fsLit)
 import GHC (Name, Class, TyCon, mkModuleName)
 import GHC.TcPluginM.Extra (lookupModule, lookupName)
+#if __GLASGOW_HASKELL__ >= 900
+import GHC.Data.FastString (fsLit)
+import GHC.Types.Name.Occurrence (mkTcOcc)
+import GHC.Tc.Plugin (TcPluginM, tcLookupClass, tcLookupTyCon, unsafeTcPluginTcM)
+import GHC.Plugins (getDynFlags, unitState)
+import GHC.Unit.State (lookupModuleWithSuggestions, LookupResult (..))
+import GHC.Utils.Outputable (pprPanic, empty, text, (<+>), ($$))
+#else
+import FastString (fsLit)
 import OccName (mkTcOcc)
 import TcPluginM (TcPluginM, tcLookupClass, tcLookupTyCon, unsafeTcPluginTcM)
 import GhcPlugins (getDynFlags)
 import Packages (lookupModuleWithSuggestions, LookupResult (..))
 import Outputable (pprPanic, empty, text, (<+>), ($$))
+#endif
 
 
 
@@ -55,7 +64,14 @@
          $$ text "Probable fix: add `polysemy` to your cabal `build-depends`"
          $$ text "--------------------------------------------------------------------------------"
          $$ text ""
-  case lookupModuleWithSuggestions dflags (mkModuleName "Polysemy") Nothing of
+  case lookupModuleWithSuggestions
+#if __GLASGOW_HASKELL__ >= 900
+    (unitState dflags)
+#else
+    dflags
+#endif
+    (mkModuleName "Polysemy")
+    Nothing of
     LookupHidden _ _ -> error_msg
     LookupNotFound _ -> error_msg
 #if __GLASGOW_HASKELL__ >= 806
diff --git a/src/Polysemy/Plugin/Fundep/Unification.hs b/src/Polysemy/Plugin/Fundep/Unification.hs
--- a/src/Polysemy/Plugin/Fundep/Unification.hs
+++ b/src/Polysemy/Plugin/Fundep/Unification.hs
@@ -5,13 +5,20 @@
 import           Data.Bool
 import           Data.Function (on)
 import qualified Data.Set as S
-#if __GLASGOW_HASKELL__ >= 810
+#if __GLASGOW_HASKELL__ >= 900
+import           GHC.Tc.Types.Constraint
+#elif __GLASGOW_HASKELL__ >= 810
 import           Constraint
 #else
 import           TcRnTypes
 #endif
 
+#if __GLASGOW_HASKELL__ >= 900
+import           GHC.Core.Type
+#else
 import           Type
+#endif
+
 
 
 ------------------------------------------------------------------------------
diff --git a/test/InsertSpec.hs b/test/InsertSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/InsertSpec.hs
@@ -0,0 +1,22 @@
+module InsertSpec where
+
+import Polysemy.State (State)
+import Polysemy.Reader (Reader)
+import Polysemy.Internal (insertAt)
+import Polysemy
+import Test.Hspec
+
+insertAtWithIndex :: Sem (e1 : e2 : e3 : e4 : r) a -> Sem (e1 : e2 : Reader i : e3 : e4 : r) a
+insertAtWithIndex = insertAt @2
+
+insertAtAndRaiseUnder :: Sem (e1 : r) a -> Sem (e1 : e2 : State s : e3 : Reader i : e4 : r) a
+insertAtAndRaiseUnder = raise2Under . insertAt @2 . raiseUnder
+
+insertAtEmpty :: Sem (e1 : e2 : r) a -> Sem (e1 : e2 : r) a
+insertAtEmpty = insertAt @2
+
+spec :: Spec
+spec = parallel $ do
+  describe "insert" $ do
+    it "insert" $ do
+      1 `shouldBe` 1
diff --git a/test/TypeErrors.hs b/test/TypeErrors.hs
--- a/test/TypeErrors.hs
+++ b/test/TypeErrors.hs
@@ -9,6 +9,7 @@
 -- >>> :set -fplugin=Polysemy.Plugin
 -- >>> :m +Polysemy
 -- >>> :m +Polysemy.State
+-- >>> :m +Polysemy.Reader
 -- >>> :m +Data.Maybe
 
 
@@ -21,8 +22,55 @@
 -- ...
 -- ... Couldn't match expected type ...Sem r Bool... with actual type ...Bool...
 -- ...
--- ... Couldn't match expected type ...Maybe a0...
--- ... with actual type ...Sem r0 s0...
+-- ... Couldn't match expected type...Maybe a0...
+-- ... with actual type...Sem r0 s0...
 -- ...
 missingFmap = ()
 
+--------------------------------------------------------------------------------
+-- |
+-- >>> :{
+-- insertSome :: ∀ e1 e2 s r a . Sem (e1 ': e2 ': r) a -> Sem (e1 ': e2 ': State s ': r) a
+-- insertSome = insertAt
+-- :}
+-- ...
+-- ... insertAt: You must provide the index ...
+-- ...
+insertAtUnprovidedIndex = ()
+
+--------------------------------------------------------------------------------
+-- |
+-- >>> :{
+-- insertSome :: Sem (e1 : e2 : e3 : e4 : r) a -> Sem (e1 : e2 : Reader i : e3 : e4 : r) a
+-- insertSome = insertAt @1
+-- :}
+-- ...
+-- ...insertAt: Failed to insert effects at index 1
+-- ...
+-- ... before ...
+-- ...'[e1]
+-- ... after ...
+-- ...e2 : e3 : e4 : r
+-- ...Actual ...
+-- ...e1 : e2 : Reader i : e3 : e4 : r
+-- ...
+insertAtWrongIndex = ()
+
+--------------------------------------------------------------------------------
+-- |
+-- Note: The /Actual/ row doesn't match the return type because of the 'raiseUnder'.
+-- >>> :{
+-- insertSome :: Sem (e1 : r) a -> Sem (e1 : e2 : State s : e3 : Reader i : e4 : r) a
+-- insertSome = raiseUnder . insertAt @2 . raise2Under
+-- :}
+-- ...
+-- ...insertAt: Failed to insert effects at index 2
+-- ...
+-- ... before ...
+-- ...'[e1, State s]
+-- ... after ...
+-- ...e30 : r0
+-- ...Actual ...
+-- ...e1 : State s : e3 : Reader i : e4 : r
+-- ...
+insertAtAndRaiseWrongIndex = ()
