diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,7 @@
+1.21.3 [2020.10.03]
+-------------------
+* Allow building with GHC 9.0.
+
 1.21.2 [2020.09.30]
 -------------------
 * Use `base-orphans-0.8.3` or later. This means that the `Linear.Instances`
diff --git a/linear.cabal b/linear.cabal
--- a/linear.cabal
+++ b/linear.cabal
@@ -1,6 +1,6 @@
 name:          linear
 category:      Math, Algebra
-version:       1.21.2
+version:       1.21.3
 license:       BSD3
 cabal-version: >= 1.10
 license-file:  LICENSE
@@ -122,6 +122,9 @@
   -- hack around the buggy unused matches check for class associated types in ghc 8 rc1
   if impl(ghc >= 8)
     ghc-options: -fno-warn-unused-matches
+
+  if impl(ghc >= 8.6)
+    ghc-options: -Wno-star-is-type
 
   default-language: Haskell2010
 
diff --git a/src/Linear/Plucker.hs b/src/Linear/Plucker.hs
--- a/src/Linear/Plucker.hs
+++ b/src/Linear/Plucker.hs
@@ -451,7 +451,7 @@
 type instance IxValue (Plucker a) = a
 
 instance Ixed (Plucker a) where
-  ix = el
+  ix i = el i
   {-# INLINE ix #-}
 
 instance Each (Plucker a) (Plucker b) a b where
@@ -527,19 +527,48 @@
 -- | Checks if two lines coincide in space. In other words, undirected equality.
 coincides :: (Epsilon a, Fractional a) => Plucker a -> Plucker a -> Bool
 coincides p1 p2 = Foldable.all nearZero $ (s *^ p2) - p1
-  where s = maybe 1 getFirst . getOption . fold $ saveDiv <$> p1 <*> p2
-        saveDiv x y | nearZero y = Option Nothing
-                    | otherwise  = Option . Just $ First (x / y)
+  where s = maybe 1 getFirst . getOptionCompat . fold $ saveDiv <$> p1 <*> p2
+        saveDiv x y | nearZero y = optionCompat Nothing
+                    | otherwise  = optionCompat . Just $ First (x / y)
 {-# INLINABLE coincides #-}
 
 -- | Checks if two lines coincide in space, and have the same
 -- orientation.
 coincides' :: (Epsilon a, Fractional a, Ord a) => Plucker a -> Plucker a -> Bool
 coincides' p1 p2 = Foldable.all nearZero ((s *^ p2) - p1) && s > 0
-  where s = maybe 1 getFirst . getOption . fold $ saveDiv <$> p1 <*> p2
-        saveDiv x y | nearZero y = Option Nothing
-                    | otherwise  = Option . Just $ First (x / y)
+  where s = maybe 1 getFirst . getOptionCompat . fold $ saveDiv <$> p1 <*> p2
+        saveDiv x y | nearZero y = optionCompat Nothing
+                    | otherwise  = optionCompat . Just $ First (x / y)
 {-# INLINABLE coincides' #-}
+
+-- The coincides and coincides' functions above require the use of a Maybe type
+-- with the following Monoid instance:
+--
+--   instance Semigroup a => Monoid (Maybe a) where ...
+--
+-- Unfortunately, Maybe has only had such an instance since base-4.11. Prior
+-- to that, its Monoid instance had an instance context of Monoid a, which is
+-- too strong. To compensate, we use CPP to define an OptionCompat type
+-- synonym, which is an alias for Maybe on recent versions of base and an alias
+-- for Data.Semigroup.Option on older versions of base. We don't want to use
+-- Option on recent versions of base, as it is deprecated.
+#if MIN_VERSION_base(4,11,0)
+type OptionCompat = Maybe
+
+optionCompat :: Maybe a -> OptionCompat a
+optionCompat = id
+
+getOptionCompat :: OptionCompat a -> Maybe a
+getOptionCompat = id
+#else
+type OptionCompat = Option
+
+optionCompat :: Maybe a -> OptionCompat a
+optionCompat = Option
+
+getOptionCompat :: OptionCompat a -> Maybe a
+getOptionCompat = getOption
+#endif
 
 -- | The minimum squared distance of a line from the origin.
 quadranceToOrigin :: Fractional a => Plucker a -> a
diff --git a/src/Linear/Quaternion.hs b/src/Linear/Quaternion.hs
--- a/src/Linear/Quaternion.hs
+++ b/src/Linear/Quaternion.hs
@@ -228,7 +228,7 @@
 type instance IxValue (Quaternion a) = a
 
 instance Ixed (Quaternion a) where
-  ix = el
+  ix i = el i
   {-# INLINE ix #-}
 
 instance Each (Quaternion a) (Quaternion b) a b where
diff --git a/src/Linear/V0.hs b/src/Linear/V0.hs
--- a/src/Linear/V0.hs
+++ b/src/Linear/V0.hs
@@ -324,7 +324,7 @@
 type instance IxValue (V0 a) = a
 
 instance Ixed (V0 a) where
-  ix = el
+  ix i = el i
   {-# INLINE ix #-}
 
 instance Each (V0 a) (V0 b) a b where
diff --git a/src/Linear/V1.hs b/src/Linear/V1.hs
--- a/src/Linear/V1.hs
+++ b/src/Linear/V1.hs
@@ -329,7 +329,7 @@
 type instance IxValue (V1 a) = a
 
 instance Ixed (V1 a) where
-  ix = el
+  ix i = el i
   {-# INLINE ix #-}
 
 instance Each (V1 a) (V1 b) a b where
diff --git a/src/Linear/V2.hs b/src/Linear/V2.hs
--- a/src/Linear/V2.hs
+++ b/src/Linear/V2.hs
@@ -387,7 +387,7 @@
 type instance IxValue (V2 a) = a
 
 instance Ixed (V2 a) where
-  ix = el
+  ix i = el i
   {-# INLINE ix #-}
 
 instance Each (V2 a) (V2 b) a b where
diff --git a/src/Linear/V3.hs b/src/Linear/V3.hs
--- a/src/Linear/V3.hs
+++ b/src/Linear/V3.hs
@@ -405,7 +405,7 @@
 type instance IxValue (V3 a) = a
 
 instance Ixed (V3 a) where
-  ix = el
+  ix i = el i
   {-# INLINE ix #-}
 
 instance Each (V3 a) (V3 b) a b where
diff --git a/src/Linear/V4.hs b/src/Linear/V4.hs
--- a/src/Linear/V4.hs
+++ b/src/Linear/V4.hs
@@ -554,7 +554,7 @@
 type instance IxValue (V4 a) = a
 
 instance Ixed (V4 a) where
-  ix = el
+  ix i = el i
 
 instance Each (V4 a) (V4 b) a b where
   each = traverse
