diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs
index 7a6bca627744d5cab45826646d1c213f2fb06307..54fb684649b88395198e2c52a026053159555db7 100644
--- a/compiler/main/DynFlags.hs
+++ b/compiler/main/DynFlags.hs
@@ -912,6 +912,8 @@ data WarningFlag =
    | Opt_WarnMissingDerivingStrategies    -- Since 8.8
    | Opt_WarnPrepositiveQualifiedModule   -- Since TBD
    | Opt_WarnUnusedPackages               -- Since 8.10
+   | Opt_WarnInferredSafeImports          -- Since 8.10
+   | Opt_WarnMissingSafeHaskellMode       -- Since 8.10
    deriving (Eq, Show, Enum)
 
 data Language = Haskell98 | Haskell2010
@@ -922,11 +924,12 @@ instance Outputable Language where
 
 -- | The various Safe Haskell modes
 data SafeHaskellMode
-   = Sf_None
-   | Sf_Unsafe
-   | Sf_Trustworthy
-   | Sf_Safe
-   | Sf_Ignore
+   = Sf_None          -- ^ inferred unsafe
+   | Sf_Unsafe        -- ^ declared and checked
+   | Sf_Trustworthy   -- ^ declared and checked
+   | Sf_Safe          -- ^ declared and checked
+   | Sf_SafeInferred  -- ^ inferred as safe
+   | Sf_Ignore        -- ^ @-fno-safe-haskell@ state
    deriving (Eq)
 
 instance Show SafeHaskellMode where
@@ -934,6 +937,7 @@ instance Show SafeHaskellMode where
     show Sf_Unsafe       = "Unsafe"
     show Sf_Trustworthy  = "Trustworthy"
     show Sf_Safe         = "Safe"
+    show Sf_SafeInferred = "Safe-Inferred"
     show Sf_Ignore       = "Ignore"
 
 instance Outputable SafeHaskellMode where
@@ -3758,6 +3762,8 @@ dynamic_flags_deps = [
   , make_ord_flag defFlag "fno-safe-infer"   (noArg (\d ->
                                                     d { safeInfer = False }))
   , make_ord_flag defFlag "fno-safe-haskell" (NoArg (setSafeHaskell Sf_Ignore))
+
+        ------ position independent flags  ----------------------------------
   , make_ord_flag defGhcFlag "fPIC"          (NoArg (setGeneralFlag Opt_PIC))
   , make_ord_flag defGhcFlag "fno-PIC"       (NoArg (unSetGeneralFlag Opt_PIC))
   , make_ord_flag defGhcFlag "fPIE"          (NoArg (setGeneralFlag Opt_PIC))
@@ -4076,6 +4082,8 @@ wWarningFlagsDeps = [
   flagSpec "all-missed-specializations"  Opt_WarnAllMissedSpecs,
   flagSpec' "safe"                       Opt_WarnSafe setWarnSafe,
   flagSpec "trustworthy-safe"            Opt_WarnTrustworthySafe,
+  flagSpec "inferred-safe-imports"       Opt_WarnInferredSafeImports,
+  flagSpec "missing-safe-haskell-mode"   Opt_WarnMissingSafeHaskellMode,
   flagSpec "tabs"                        Opt_WarnTabs,
   flagSpec "type-defaults"               Opt_WarnTypeDefaults,
   flagSpec "typed-holes"                 Opt_WarnTypedHoles,
diff --git a/compiler/main/HscMain.hs b/compiler/main/HscMain.hs
index d7658ad2aa7a0558e5ec5ae2c37321934939ccaf..91a1f1d1e66fecb587567faf204a63a936f1cf44 100644
--- a/compiler/main/HscMain.hs
+++ b/compiler/main/HscMain.hs
@@ -1109,21 +1109,36 @@ hscCheckSafe' m l = do
                 let trust = getSafeMode $ mi_trust iface'
                     trust_own_pkg = mi_trust_pkg iface'
                     -- check module is trusted
-                    safeM = trust `elem` [Sf_Safe, Sf_Trustworthy]
+                    safeM = trust `elem` [Sf_Safe, Sf_SafeInferred, Sf_Trustworthy]
                     -- check package is trusted
                     safeP = packageTrusted dflags trust trust_own_pkg m
                     -- pkg trust reqs
                     pkgRs = S.fromList . map fst $ filter snd $ dep_pkgs $ mi_deps iface'
+                    -- warn if Safe module imports Safe-Inferred module.
+                    warns = if wopt Opt_WarnInferredSafeImports dflags
+                                && safeLanguageOn dflags
+                                && trust == Sf_SafeInferred
+                                then inferredImportWarn
+                                else emptyBag
                     -- General errors we throw but Safe errors we log
                     errs = case (safeM, safeP) of
                         (True, True ) -> emptyBag
                         (True, False) -> pkgTrustErr
                         (False, _   ) -> modTrustErr
                 in do
+                    logWarnings warns
                     logWarnings errs
                     return (trust == Sf_Trustworthy, pkgRs)
 
                 where
+                    inferredImportWarn = unitBag
+                        $ makeIntoWarning (Reason Opt_WarnInferredSafeImports)
+                        $ mkErrMsg dflags l (pkgQual dflags)
+                        $ sep
+                            [ text "Importing Safe-Inferred module "
+                                <> ppr (moduleName m)
+                                <> text " from explicitly Safe module"
+                            ]
                     pkgTrustErr = unitBag $ mkErrMsg dflags l (pkgQual dflags) $
                         sep [ ppr (moduleName m)
                                 <> text ": Can't be safely imported!"
@@ -1146,6 +1161,7 @@ hscCheckSafe' m l = do
     packageTrusted dflags _ _ _
         | not (packageTrustOn dflags) = True
     packageTrusted _ Sf_Safe  False _ = True
+    packageTrusted _ Sf_SafeInferred False _ = True
     packageTrusted dflags _ _ m
         | isHomePkg dflags m = True
         | otherwise = trusted $ getPackageDetails dflags (moduleUnitId m)
diff --git a/compiler/main/HscTypes.hs b/compiler/main/HscTypes.hs
index 0fa9ffa6649fad585e83d0fe63fb9009e5ca15e5..e2dbcb0ecfdc4c0426a46b078c2a6a4d57ef278a 100644
--- a/compiler/main/HscTypes.hs
+++ b/compiler/main/HscTypes.hs
@@ -2948,6 +2948,7 @@ trustInfoToNum it
             Sf_Unsafe       -> 1
             Sf_Trustworthy  -> 2
             Sf_Safe         -> 3
+            Sf_SafeInferred -> 4
             Sf_Ignore       -> 0
 
 numToTrustInfo :: Word8 -> IfaceTrustInfo
@@ -2955,9 +2956,7 @@ numToTrustInfo 0 = setSafeMode Sf_None
 numToTrustInfo 1 = setSafeMode Sf_Unsafe
 numToTrustInfo 2 = setSafeMode Sf_Trustworthy
 numToTrustInfo 3 = setSafeMode Sf_Safe
-numToTrustInfo 4 = setSafeMode Sf_Safe -- retained for backwards compat, used
-                                       -- to be Sf_SafeInfered but we no longer
-                                       -- differentiate.
+numToTrustInfo 4 = setSafeMode Sf_SafeInferred
 numToTrustInfo n = error $ "numToTrustInfo: bad input number! (" ++ show n ++ ")"
 
 instance Outputable IfaceTrustInfo where
@@ -2966,6 +2965,7 @@ instance Outputable IfaceTrustInfo where
     ppr (TrustInfo Sf_Unsafe)        = text "unsafe"
     ppr (TrustInfo Sf_Trustworthy)   = text "trustworthy"
     ppr (TrustInfo Sf_Safe)          = text "safe"
+    ppr (TrustInfo Sf_SafeInferred)  = text "safe-inferred"
 
 instance Binary IfaceTrustInfo where
     put_ bh iftrust = putByte bh $ trustInfoToNum iftrust
diff --git a/compiler/typecheck/TcRnMonad.hs b/compiler/typecheck/TcRnMonad.hs
index e297301b6b11a9bc23de69f4aafe5b5d2ca690c0..48d8cae8411f980d102a301472b05682f925829e 100644
--- a/compiler/typecheck/TcRnMonad.hs
+++ b/compiler/typecheck/TcRnMonad.hs
@@ -1835,13 +1835,13 @@ finalSafeMode :: DynFlags -> TcGblEnv -> IO SafeHaskellMode
 finalSafeMode dflags tcg_env = do
     safeInf <- fst <$> readIORef (tcg_safeInfer tcg_env)
     return $ case safeHaskell dflags of
-        Sf_None | safeInferOn dflags && safeInf -> Sf_Safe
+        Sf_None | safeInferOn dflags && safeInf -> Sf_SafeInferred
                 | otherwise                     -> Sf_None
         s -> s
 
 -- | Switch instances to safe instances if we're in Safe mode.
 fixSafeInstances :: SafeHaskellMode -> [ClsInst] -> [ClsInst]
-fixSafeInstances sfMode | sfMode /= Sf_Safe = id
+fixSafeInstances sfMode | sfMode /= Sf_Safe && sfMode /= Sf_SafeInferred = id
 fixSafeInstances _ = map fixSafe
   where fixSafe inst = let new_flag = (is_flag inst) { isSafeOverlap = True }
                        in inst { is_flag = new_flag }
diff --git a/docs/users_guide/safe_haskell.rst b/docs/users_guide/safe_haskell.rst
index bf7f1fb5d0286425fafc0844e93a5f6d3d567819..af016194bfcb815fe7775d1f75b36385653493e1 100644
--- a/docs/users_guide/safe_haskell.rst
+++ b/docs/users_guide/safe_haskell.rst
@@ -740,7 +740,7 @@ And one general flag:
     requiring the package that ``M`` resides in be considered trusted, for ``M``
     to be considered trusted.
 
-And three warning flags:
+And four warning flags:
 
 .. ghc-flag:: -Wunsafe
     :shortdesc: warn if the module being compiled is regarded to be unsafe.
@@ -777,6 +777,39 @@ And three warning flags:
     -XSafe , a more informative bound. Can be used to detect once a Safe Haskell
     bound can be improved as dependencies are updated.
 
+.. ghc-flag:: -Winferred-safe-imports
+    :shortdesc: warn when an explicitly Safe Haskell module imports a Safe-Inferred one
+    :type: dynamic
+    :reverse: -Wno-inferred-safe-imports
+    :category:
+
+    :since: 8.10.1
+
+    .. index::
+       single: safe haskell imports, warning
+
+    The module ``A`` below is annotated to be explictly ``Safe``, but it imports
+    ``Safe-Inferred`` module.
+
+        {-# LANGUAGE Safe #-}
+        module A where
+
+        import B (double)
+
+        quad :: Int -> Int
+        quad = double . double
+
+    
+        module B where
+
+        double :: Int -> Int
+        double n = n + n
+
+    The inferred status is volatile: if an unsafe import is added to the module
+    ``B``, it will cause compilation error of ``A``.  When
+    :ghc-flag:`-Winferred-safe-imports` is enabled, the compiler will emit a
+    warning about this.
+
 .. _safe-compilation:
 
 Safe Compilation
diff --git a/testsuite/tests/plugins/T16260.stdout b/testsuite/tests/plugins/T16260.stdout
index ae9d3fb4309a90b9aadfac913c1373389f67878c..dd1db9a46bf6febfbe93c0a3b61a8ba26f790374 100644
--- a/testsuite/tests/plugins/T16260.stdout
+++ b/testsuite/tests/plugins/T16260.stdout
@@ -1,4 +1,4 @@
 False
 None
 True
-Safe
+Safe-Inferred
diff --git a/testsuite/tests/safeHaskell/check/pkg01/safePkg01.stdout b/testsuite/tests/safeHaskell/check/pkg01/safePkg01.stdout
index 31b2278577bf17b096d643fba40a4c0cc2479187..53e219ddd552b916e321979e2c5bf4686c609768 100644
--- a/testsuite/tests/safeHaskell/check/pkg01/safePkg01.stdout
+++ b/testsuite/tests/safeHaskell/check/pkg01/safePkg01.stdout
@@ -4,42 +4,42 @@ pdb.safePkg01/local.db
 trusted: False
 
 M_SafePkg
-package dependencies: base-4.12.0.0* ghc-prim-0.6.1 integer-gmp-1.0.2.0
+package dependencies: base-4.13.0.0* ghc-prim-0.6.1 integer-gmp-1.0.2.0
 trusted: safe
 require own pkg trusted: False
 
 M_SafePkg2
-package dependencies: base-4.12.0.0 ghc-prim-0.6.1 integer-gmp-1.0.2.0
+package dependencies: base-4.13.0.0 ghc-prim-0.6.1 integer-gmp-1.0.2.0
 trusted: trustworthy
 require own pkg trusted: False
 
 M_SafePkg3
-package dependencies: base-4.12.0.0* ghc-prim-0.6.1 integer-gmp-1.0.2.0
+package dependencies: base-4.13.0.0* ghc-prim-0.6.1 integer-gmp-1.0.2.0
 trusted: safe
 require own pkg trusted: True
 
 M_SafePkg4
-package dependencies: base-4.12.0.0* ghc-prim-0.6.1 integer-gmp-1.0.2.0
+package dependencies: base-4.13.0.0* ghc-prim-0.6.1 integer-gmp-1.0.2.0
 trusted: safe
 require own pkg trusted: True
 
 M_SafePkg5
-package dependencies: base-4.12.0.0* ghc-prim-0.6.1 integer-gmp-1.0.2.0
-trusted: safe
+package dependencies: base-4.13.0.0* ghc-prim-0.6.1 integer-gmp-1.0.2.0
+trusted: safe-inferred
 require own pkg trusted: True
 
 M_SafePkg6
-package dependencies: array-0.5.2.0 base-4.12.0.0* bytestring-0.10.8.2* deepseq-1.4.4.0 ghc-prim-0.6.1 integer-gmp-1.0.2.0
+package dependencies: array-0.5.4.0 base-4.13.0.0* bytestring-0.10.9.0* deepseq-1.4.4.0 ghc-prim-0.6.1 integer-gmp-1.0.2.0
 trusted: trustworthy
 require own pkg trusted: False
 
 M_SafePkg7
-package dependencies: array-0.5.2.0 base-4.12.0.0* bytestring-0.10.8.2* deepseq-1.4.4.0 ghc-prim-0.6.1 integer-gmp-1.0.2.0
+package dependencies: array-0.5.4.0 base-4.13.0.0* bytestring-0.10.9.0* deepseq-1.4.4.0 ghc-prim-0.6.1 integer-gmp-1.0.2.0
 trusted: safe
 require own pkg trusted: False
 
 M_SafePkg8
-package dependencies: array-0.5.2.0 base-4.12.0.0 bytestring-0.10.8.2* deepseq-1.4.4.0 ghc-prim-0.6.1 integer-gmp-1.0.2.0
+package dependencies: array-0.5.4.0 base-4.13.0.0 bytestring-0.10.9.0* deepseq-1.4.4.0 ghc-prim-0.6.1 integer-gmp-1.0.2.0
 trusted: trustworthy
 require own pkg trusted: False
 
diff --git a/utils/haddock b/utils/haddock
index 83bb9870a117f9426e6f6cff6fec3bb6e93a7c18..5e333bad752b9c048ad5400b7159e32f4d3d65bd 160000
--- a/utils/haddock
+++ b/utils/haddock
@@ -1 +1 @@
-Subproject commit 83bb9870a117f9426e6f6cff6fec3bb6e93a7c18
+Subproject commit 5e333bad752b9c048ad5400b7159e32f4d3d65bd