{-# LANGUAGE MultiWayIf          #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE UnboxedTuples #-}
module GHC.Core.Lint (
    LintPassResultConfig (..),
    LintFlags (..),
    StaticPtrCheck (..),
    LintConfig (..),
    WarnsAndErrs,
    lintCoreBindings', lintUnfolding,
    lintPassResult, lintExpr,
    lintAnnots, lintAxioms,
    
    EndPassConfig (..),
    endPassIO,
    displayLintResults, dumpPassResult
 ) where
import GHC.Prelude
import GHC.Driver.DynFlags
import GHC.Tc.Utils.TcType ( isFloatingPrimTy, isTyFamFree )
import GHC.Unit.Module.ModGuts
import GHC.Platform
import GHC.Core
import GHC.Core.FVs
import GHC.Core.Utils
import GHC.Core.Stats ( coreBindsStats )
import GHC.Core.DataCon
import GHC.Core.Ppr
import GHC.Core.Coercion
import GHC.Core.Type as Type
import GHC.Core.Multiplicity
import GHC.Core.UsageEnv
import GHC.Core.TyCo.Rep   
import GHC.Core.TyCo.Compare( eqType )
import GHC.Core.TyCo.Subst
import GHC.Core.TyCo.FVs
import GHC.Core.TyCo.Ppr
import GHC.Core.TyCon as TyCon
import GHC.Core.Coercion.Axiom
import GHC.Core.FamInstEnv( compatibleBranches )
import GHC.Core.Unify
import GHC.Core.Opt.Arity    ( typeArity, exprIsDeadEnd )
import GHC.Core.Opt.Monad
import GHC.Types.Literal
import GHC.Types.Var as Var
import GHC.Types.Var.Env
import GHC.Types.Var.Set
import GHC.Types.Name
import GHC.Types.Name.Env
import GHC.Types.Id
import GHC.Types.Id.Info
import GHC.Types.SrcLoc
import GHC.Types.Tickish
import GHC.Types.RepType
import GHC.Types.Basic
import GHC.Types.Demand      ( splitDmdSig, isDeadEndDiv )
import GHC.Builtin.Names
import GHC.Builtin.Types.Prim
import GHC.Builtin.Types ( multiplicityTy )
import GHC.Data.Bag
import GHC.Data.List.SetOps
import GHC.Utils.Monad
import GHC.Utils.Outputable as Outputable
import GHC.Utils.Panic
import GHC.Utils.Constants (debugIsOn)
import GHC.Utils.Misc
import GHC.Utils.Error
import qualified GHC.Utils.Error as Err
import GHC.Utils.Logger
import Control.Monad
import Data.Foldable      ( for_, toList )
import Data.List.NonEmpty ( NonEmpty(..), groupWith )
import Data.List          ( partition )
import Data.Maybe
import GHC.Data.Pair
import GHC.Base (oneShot)
import GHC.Data.Unboxed
data EndPassConfig = EndPassConfig
  { EndPassConfig -> Bool
ep_dumpCoreSizes :: !Bool
  
  
  , EndPassConfig -> Maybe LintPassResultConfig
ep_lintPassResult :: !(Maybe LintPassResultConfig)
  
  , EndPassConfig -> NamePprCtx
ep_namePprCtx :: !NamePprCtx
  , EndPassConfig -> Maybe DumpFlag
ep_dumpFlag :: !(Maybe DumpFlag)
  , EndPassConfig -> SDoc
ep_prettyPass :: !SDoc
  , EndPassConfig -> SDoc
ep_passDetails :: !SDoc
  }
endPassIO :: Logger
          -> EndPassConfig
          -> CoreProgram -> [CoreRule]
          -> IO ()
endPassIO :: Logger -> EndPassConfig -> CoreProgram -> [CoreRule] -> IO ()
endPassIO Logger
logger EndPassConfig
cfg CoreProgram
binds [CoreRule]
rules
  = do { Logger
-> Bool
-> NamePprCtx
-> Maybe DumpFlag
-> String
-> SDoc
-> CoreProgram
-> [CoreRule]
-> IO ()
dumpPassResult Logger
logger (EndPassConfig -> Bool
ep_dumpCoreSizes EndPassConfig
cfg) (EndPassConfig -> NamePprCtx
ep_namePprCtx EndPassConfig
cfg) Maybe DumpFlag
mb_flag
                        (SDocContext -> SDoc -> String
renderWithContext SDocContext
defaultSDocContext (EndPassConfig -> SDoc
ep_prettyPass EndPassConfig
cfg))
                        (EndPassConfig -> SDoc
ep_passDetails EndPassConfig
cfg) CoreProgram
binds [CoreRule]
rules
       ; Maybe LintPassResultConfig
-> (LintPassResultConfig -> IO ()) -> IO ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (EndPassConfig -> Maybe LintPassResultConfig
ep_lintPassResult EndPassConfig
cfg) ((LintPassResultConfig -> IO ()) -> IO ())
-> (LintPassResultConfig -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \LintPassResultConfig
lp_cfg ->
           Logger -> LintPassResultConfig -> CoreProgram -> IO ()
lintPassResult Logger
logger LintPassResultConfig
lp_cfg CoreProgram
binds
       }
  where
    mb_flag :: Maybe DumpFlag
mb_flag = case EndPassConfig -> Maybe DumpFlag
ep_dumpFlag EndPassConfig
cfg of
                Just DumpFlag
flag | Logger -> DumpFlag -> Bool
logHasDumpFlag Logger
logger DumpFlag
flag                    -> DumpFlag -> Maybe DumpFlag
forall a. a -> Maybe a
Just DumpFlag
flag
                          | Logger -> DumpFlag -> Bool
logHasDumpFlag Logger
logger DumpFlag
Opt_D_verbose_core2core -> DumpFlag -> Maybe DumpFlag
forall a. a -> Maybe a
Just DumpFlag
flag
                Maybe DumpFlag
_ -> Maybe DumpFlag
forall a. Maybe a
Nothing
dumpPassResult :: Logger
               -> Bool                  
               -> NamePprCtx
               -> Maybe DumpFlag        
                                        
               -> String                
               -> SDoc                  
               -> CoreProgram -> [CoreRule]
               -> IO ()
dumpPassResult :: Logger
-> Bool
-> NamePprCtx
-> Maybe DumpFlag
-> String
-> SDoc
-> CoreProgram
-> [CoreRule]
-> IO ()
dumpPassResult Logger
logger Bool
dump_core_sizes NamePprCtx
name_ppr_ctx Maybe DumpFlag
mb_flag String
hdr SDoc
extra_info CoreProgram
binds [CoreRule]
rules
  = do { Maybe DumpFlag -> (DumpFlag -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ Maybe DumpFlag
mb_flag ((DumpFlag -> IO ()) -> IO ()) -> (DumpFlag -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \DumpFlag
flag -> do
           Logger
-> PprStyle -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
logDumpFile Logger
logger (NamePprCtx -> PprStyle
mkDumpStyle NamePprCtx
name_ppr_ctx) DumpFlag
flag String
hdr DumpFormat
FormatCore SDoc
dump_doc
         
         
         
       ; Logger -> JoinArity -> SDoc -> IO ()
Err.debugTraceMsg Logger
logger JoinArity
2 SDoc
size_doc
       }
  where
    size_doc :: SDoc
size_doc = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep [String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Result size of" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
hdr, JoinArity -> SDoc -> SDoc
nest JoinArity
2 (SDoc
forall doc. IsLine doc => doc
equals SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> CoreStats -> SDoc
forall a. Outputable a => a -> SDoc
ppr (CoreProgram -> CoreStats
coreBindsStats CoreProgram
binds))]
    dump_doc :: SDoc
dump_doc  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ JoinArity -> SDoc -> SDoc
nest JoinArity
2 SDoc
extra_info
                     , SDoc
size_doc
                     , SDoc
blankLine
                     , if Bool
dump_core_sizes
                        then CoreProgram -> SDoc
pprCoreBindingsWithSize CoreProgram
binds
                        else CoreProgram -> SDoc
forall b. OutputableBndr b => [Bind b] -> SDoc
pprCoreBindings         CoreProgram
binds
                     , Bool -> SDoc -> SDoc
forall doc. IsOutput doc => Bool -> doc -> doc
ppUnless ([CoreRule] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CoreRule]
rules) SDoc
pp_rules ]
    pp_rules :: SDoc
pp_rules = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ SDoc
blankLine
                    , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"------ Local rules for imported ids --------"
                    , [CoreRule] -> SDoc
pprRules [CoreRule]
rules ]
data LintPassResultConfig = LintPassResultConfig
  { LintPassResultConfig -> DiagOpts
lpr_diagOpts         :: !DiagOpts
  , LintPassResultConfig -> Platform
lpr_platform         :: !Platform
  , LintPassResultConfig -> LintFlags
lpr_makeLintFlags    :: !LintFlags
  , LintPassResultConfig -> Bool
lpr_showLintWarnings :: !Bool
  , LintPassResultConfig -> SDoc
lpr_passPpr          :: !SDoc
  , LintPassResultConfig -> [Var]
lpr_localsInScope    :: ![Var]
  }
lintPassResult :: Logger -> LintPassResultConfig
               -> CoreProgram -> IO ()
lintPassResult :: Logger -> LintPassResultConfig -> CoreProgram -> IO ()
lintPassResult Logger
logger LintPassResultConfig
cfg CoreProgram
binds
  = do { let warns_and_errs :: WarnsAndErrs
warns_and_errs = LintConfig -> CoreProgram -> WarnsAndErrs
lintCoreBindings'
               (LintConfig
                { l_diagOpts :: DiagOpts
l_diagOpts = LintPassResultConfig -> DiagOpts
lpr_diagOpts LintPassResultConfig
cfg
                , l_platform :: Platform
l_platform = LintPassResultConfig -> Platform
lpr_platform LintPassResultConfig
cfg
                , l_flags :: LintFlags
l_flags    = LintPassResultConfig -> LintFlags
lpr_makeLintFlags LintPassResultConfig
cfg
                , l_vars :: [Var]
l_vars     = LintPassResultConfig -> [Var]
lpr_localsInScope LintPassResultConfig
cfg
                })
               CoreProgram
binds
       ; Logger -> String -> IO ()
Err.showPass Logger
logger (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
           String
"Core Linted result of " String -> String -> String
forall a. [a] -> [a] -> [a]
++
           SDocContext -> SDoc -> String
renderWithContext SDocContext
defaultSDocContext (LintPassResultConfig -> SDoc
lpr_passPpr LintPassResultConfig
cfg)
       ; Logger -> Bool -> SDoc -> SDoc -> WarnsAndErrs -> IO ()
displayLintResults Logger
logger
                            (LintPassResultConfig -> Bool
lpr_showLintWarnings LintPassResultConfig
cfg) (LintPassResultConfig -> SDoc
lpr_passPpr LintPassResultConfig
cfg)
                            (CoreProgram -> SDoc
forall b. OutputableBndr b => [Bind b] -> SDoc
pprCoreBindings CoreProgram
binds) WarnsAndErrs
warns_and_errs
       }
displayLintResults :: Logger
                   -> Bool 
                           
                   -> SDoc 
                   -> SDoc 
                   -> WarnsAndErrs
                   -> IO ()
displayLintResults :: Logger -> Bool -> SDoc -> SDoc -> WarnsAndErrs -> IO ()
displayLintResults Logger
logger Bool
display_warnings SDoc
pp_what SDoc
pp_pgm (Bag SDoc
warns, Bag SDoc
errs)
  | Bool -> Bool
not (Bag SDoc -> Bool
forall a. Bag a -> Bool
isEmptyBag Bag SDoc
errs)
  = do { Logger -> MessageClass -> SrcSpan -> SDoc -> IO ()
logMsg Logger
logger MessageClass
Err.MCInfo SrcSpan
noSrcSpan  
           (SDoc -> IO ()) -> SDoc -> IO ()
forall a b. (a -> b) -> a -> b
$ PprStyle -> SDoc -> SDoc
withPprStyle PprStyle
defaultDumpStyle
           ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc -> SDoc
lint_banner String
"errors" SDoc
pp_what, Bag SDoc -> SDoc
Err.pprMessageBag Bag SDoc
errs
                 , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"*** Offending Program ***"
                 , SDoc
pp_pgm
                 , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"*** End of Offense ***" ])
       ; Logger -> JoinArity -> IO ()
Err.ghcExit Logger
logger JoinArity
1 }
  | Bool -> Bool
not (Bag SDoc -> Bool
forall a. Bag a -> Bool
isEmptyBag Bag SDoc
warns)
  , LogFlags -> Bool
log_enable_debug (Logger -> LogFlags
logFlags Logger
logger)
  , Bool
display_warnings
  = Logger -> MessageClass -> SrcSpan -> SDoc -> IO ()
logMsg Logger
logger MessageClass
Err.MCInfo SrcSpan
noSrcSpan  
      (SDoc -> IO ()) -> SDoc -> IO ()
forall a b. (a -> b) -> a -> b
$ PprStyle -> SDoc -> SDoc
withPprStyle PprStyle
defaultDumpStyle
        (String -> SDoc -> SDoc
lint_banner String
"warnings" SDoc
pp_what SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ Bag SDoc -> SDoc
Err.pprMessageBag ((SDoc -> SDoc) -> Bag SDoc -> Bag SDoc
forall a b. (a -> b) -> Bag a -> Bag b
mapBag (SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ SDoc
blankLine) Bag SDoc
warns))
  | Bool
otherwise = () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
lint_banner :: String -> SDoc -> SDoc
lint_banner :: String -> SDoc -> SDoc
lint_banner String
string SDoc
pass = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"*** Core Lint"      SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
string
                          SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
": in result of" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
pass
                          SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"***"
lintCoreBindings' :: LintConfig -> CoreProgram -> WarnsAndErrs
lintCoreBindings' :: LintConfig -> CoreProgram -> WarnsAndErrs
lintCoreBindings' LintConfig
cfg CoreProgram
binds
  = LintConfig -> LintM ((), [UsageEnv]) -> WarnsAndErrs
forall a. LintConfig -> LintM a -> WarnsAndErrs
initL LintConfig
cfg (LintM ((), [UsageEnv]) -> WarnsAndErrs)
-> LintM ((), [UsageEnv]) -> WarnsAndErrs
forall a b. (a -> b) -> a -> b
$
    LintLocInfo -> LintM ((), [UsageEnv]) -> LintM ((), [UsageEnv])
forall a. LintLocInfo -> LintM a -> LintM a
addLoc LintLocInfo
TopLevelBindings           (LintM ((), [UsageEnv]) -> LintM ((), [UsageEnv]))
-> LintM ((), [UsageEnv]) -> LintM ((), [UsageEnv])
forall a b. (a -> b) -> a -> b
$
    do { Bool -> SDoc -> LintM ()
checkL ([NonEmpty Var] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [NonEmpty Var]
dups) ([NonEmpty Var] -> SDoc
dupVars [NonEmpty Var]
dups)
       ; Bool -> SDoc -> LintM ()
checkL ([NonEmpty Name] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [NonEmpty Name]
ext_dups) ([NonEmpty Name] -> SDoc
dupExtVars [NonEmpty Name]
ext_dups)
       ; TopLevelFlag
-> [(Var, CoreExpr)]
-> ([Var] -> LintM ())
-> LintM ((), [UsageEnv])
forall a.
TopLevelFlag
-> [(Var, CoreExpr)] -> ([Var] -> LintM a) -> LintM (a, [UsageEnv])
lintRecBindings TopLevelFlag
TopLevel [(Var, CoreExpr)]
all_pairs (([Var] -> LintM ()) -> LintM ((), [UsageEnv]))
-> ([Var] -> LintM ()) -> LintM ((), [UsageEnv])
forall a b. (a -> b) -> a -> b
$ \[Var]
_ ->
         () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return () }
  where
    all_pairs :: [(Var, CoreExpr)]
all_pairs = CoreProgram -> [(Var, CoreExpr)]
forall b. [Bind b] -> [(b, Expr b)]
flattenBinds CoreProgram
binds
     
     
     
    binders :: [Var]
binders = ((Var, CoreExpr) -> Var) -> [(Var, CoreExpr)] -> [Var]
forall a b. (a -> b) -> [a] -> [b]
map (Var, CoreExpr) -> Var
forall a b. (a, b) -> a
fst [(Var, CoreExpr)]
all_pairs
    ([Var]
_, [NonEmpty Var]
dups) = (Var -> Var -> Ordering) -> [Var] -> ([Var], [NonEmpty Var])
forall a. (a -> a -> Ordering) -> [a] -> ([a], [NonEmpty a])
removeDups Var -> Var -> Ordering
forall a. Ord a => a -> a -> Ordering
compare [Var]
binders
    
    
    
    
    
    
    ext_dups :: [NonEmpty Name]
ext_dups = ([Name], [NonEmpty Name]) -> [NonEmpty Name]
forall a b. (a, b) -> b
snd (([Name], [NonEmpty Name]) -> [NonEmpty Name])
-> ([Name], [NonEmpty Name]) -> [NonEmpty Name]
forall a b. (a -> b) -> a -> b
$ (Name -> (Module, OccName)) -> [Name] -> ([Name], [NonEmpty Name])
forall b a. Ord b => (a -> b) -> [a] -> ([a], [NonEmpty a])
removeDupsOn Name -> (Module, OccName)
ord_ext ([Name] -> ([Name], [NonEmpty Name]))
-> [Name] -> ([Name], [NonEmpty Name])
forall a b. (a -> b) -> a -> b
$
               (Name -> Bool) -> [Name] -> [Name]
forall a. (a -> Bool) -> [a] -> [a]
filter Name -> Bool
isExternalName ([Name] -> [Name]) -> [Name] -> [Name]
forall a b. (a -> b) -> a -> b
$ (Var -> Name) -> [Var] -> [Name]
forall a b. (a -> b) -> [a] -> [b]
map Var -> Name
Var.varName [Var]
binders
    ord_ext :: Name -> (Module, OccName)
ord_ext Name
n = (HasDebugCallStack => Name -> Module
Name -> Module
nameModule Name
n, Name -> OccName
nameOccName Name
n)
lintUnfolding :: Bool             
              -> LintConfig
              -> SrcLoc
              -> CoreExpr
              -> Maybe (Bag SDoc) 
lintUnfolding :: Bool -> LintConfig -> SrcLoc -> CoreExpr -> Maybe (Bag SDoc)
lintUnfolding Bool
is_compulsory LintConfig
cfg SrcLoc
locn CoreExpr
expr
  | Bag SDoc -> Bool
forall a. Bag a -> Bool
isEmptyBag Bag SDoc
errs = Maybe (Bag SDoc)
forall a. Maybe a
Nothing
  | Bool
otherwise       = Bag SDoc -> Maybe (Bag SDoc)
forall a. a -> Maybe a
Just Bag SDoc
errs
  where
    (Bag SDoc
_warns, Bag SDoc
errs) = LintConfig -> LintM (LintedType, UsageEnv) -> WarnsAndErrs
forall a. LintConfig -> LintM a -> WarnsAndErrs
initL LintConfig
cfg (LintM (LintedType, UsageEnv) -> WarnsAndErrs)
-> LintM (LintedType, UsageEnv) -> WarnsAndErrs
forall a b. (a -> b) -> a -> b
$
                     if Bool
is_compulsory
                       
                     then LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. LintM a -> LintM a
noFixedRuntimeRepChecks LintM (LintedType, UsageEnv)
linter
                     else LintM (LintedType, UsageEnv)
linter
    linter :: LintM (LintedType, UsageEnv)
linter = LintLocInfo
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. LintLocInfo -> LintM a -> LintM a
addLoc (SrcLoc -> LintLocInfo
ImportedUnfolding SrcLoc
locn) (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$
             CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
expr
lintExpr :: LintConfig
         -> CoreExpr
         -> Maybe (Bag SDoc)  
lintExpr :: LintConfig -> CoreExpr -> Maybe (Bag SDoc)
lintExpr LintConfig
cfg CoreExpr
expr
  | Bag SDoc -> Bool
forall a. Bag a -> Bool
isEmptyBag Bag SDoc
errs = Maybe (Bag SDoc)
forall a. Maybe a
Nothing
  | Bool
otherwise       = Bag SDoc -> Maybe (Bag SDoc)
forall a. a -> Maybe a
Just Bag SDoc
errs
  where
    (Bag SDoc
_warns, Bag SDoc
errs) = LintConfig -> LintM (LintedType, UsageEnv) -> WarnsAndErrs
forall a. LintConfig -> LintM a -> WarnsAndErrs
initL LintConfig
cfg LintM (LintedType, UsageEnv)
linter
    linter :: LintM (LintedType, UsageEnv)
linter = LintLocInfo
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. LintLocInfo -> LintM a -> LintM a
addLoc LintLocInfo
TopLevelBindings (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$
             CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
expr
lintRecBindings :: TopLevelFlag -> [(Id, CoreExpr)]
                -> ([LintedId] -> LintM a) -> LintM (a, [UsageEnv])
lintRecBindings :: forall a.
TopLevelFlag
-> [(Var, CoreExpr)] -> ([Var] -> LintM a) -> LintM (a, [UsageEnv])
lintRecBindings TopLevelFlag
top_lvl [(Var, CoreExpr)]
pairs [Var] -> LintM a
thing_inside
  = TopLevelFlag
-> [Var]
-> ([Var] -> LintM (a, [UsageEnv]))
-> LintM (a, [UsageEnv])
forall a. TopLevelFlag -> [Var] -> ([Var] -> LintM a) -> LintM a
lintIdBndrs TopLevelFlag
top_lvl [Var]
bndrs (([Var] -> LintM (a, [UsageEnv])) -> LintM (a, [UsageEnv]))
-> ([Var] -> LintM (a, [UsageEnv])) -> LintM (a, [UsageEnv])
forall a b. (a -> b) -> a -> b
$ \ [Var]
bndrs' ->
    do { [UsageEnv]
ues <- (Var -> CoreExpr -> LintM UsageEnv)
-> [Var] -> [CoreExpr] -> LintM [UsageEnv]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM Var -> CoreExpr -> LintM UsageEnv
lint_pair [Var]
bndrs' [CoreExpr]
rhss
       ; a
a <- [Var] -> LintM a
thing_inside [Var]
bndrs'
       ; (a, [UsageEnv]) -> LintM (a, [UsageEnv])
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a, [UsageEnv]
ues) }
  where
    ([Var]
bndrs, [CoreExpr]
rhss) = [(Var, CoreExpr)] -> ([Var], [CoreExpr])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Var, CoreExpr)]
pairs
    lint_pair :: Var -> CoreExpr -> LintM UsageEnv
lint_pair Var
bndr' CoreExpr
rhs
      = LintLocInfo -> LintM UsageEnv -> LintM UsageEnv
forall a. LintLocInfo -> LintM a -> LintM a
addLoc (Var -> LintLocInfo
RhsOf Var
bndr') (LintM UsageEnv -> LintM UsageEnv)
-> LintM UsageEnv -> LintM UsageEnv
forall a b. (a -> b) -> a -> b
$
        do { (LintedType
rhs_ty, UsageEnv
ue) <- Var -> CoreExpr -> LintM (LintedType, UsageEnv)
lintRhs Var
bndr' CoreExpr
rhs         
           ; TopLevelFlag
-> RecFlag -> Var -> CoreExpr -> LintedType -> LintM ()
lintLetBind TopLevelFlag
top_lvl RecFlag
Recursive Var
bndr' CoreExpr
rhs LintedType
rhs_ty
           ; UsageEnv -> LintM UsageEnv
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return UsageEnv
ue }
lintLetBody :: [LintedId] -> CoreExpr -> LintM (LintedType, UsageEnv)
lintLetBody :: [Var] -> CoreExpr -> LintM (LintedType, UsageEnv)
lintLetBody [Var]
bndrs CoreExpr
body
  = do { (LintedType
body_ty, UsageEnv
body_ue) <- LintLocInfo
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. LintLocInfo -> LintM a -> LintM a
addLoc ([Var] -> LintLocInfo
BodyOfLetRec [Var]
bndrs) (CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
body)
       ; (Var -> LintM ()) -> [Var] -> LintM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (LintedType -> Var -> LintM ()
lintJoinBndrType LintedType
body_ty) [Var]
bndrs
       ; (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (LintedType
body_ty, UsageEnv
body_ue) }
lintLetBind :: TopLevelFlag -> RecFlag -> LintedId
              -> CoreExpr -> LintedType -> LintM ()
lintLetBind :: TopLevelFlag
-> RecFlag -> Var -> CoreExpr -> LintedType -> LintM ()
lintLetBind TopLevelFlag
top_lvl RecFlag
rec_flag Var
binder CoreExpr
rhs LintedType
rhs_ty
  = do { let binder_ty :: LintedType
binder_ty = Var -> LintedType
idType Var
binder
       ; LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys LintedType
binder_ty LintedType
rhs_ty (Var -> SDoc -> LintedType -> SDoc
mkRhsMsg Var
binder (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"RHS") LintedType
rhs_ty)
       
       
       ; Bool -> SDoc -> LintM ()
checkL (Bool -> Bool
not (Var -> Bool
isCoVar Var
binder) Bool -> Bool -> Bool
|| CoreExpr -> Bool
forall b. Expr b -> Bool
isCoArg CoreExpr
rhs)
                (Var -> CoreExpr -> SDoc
mkLetErr Var
binder CoreExpr
rhs)
        
        
       ; Bool -> SDoc -> LintM ()
checkL ( Var -> Bool
isJoinId Var
binder
               Bool -> Bool -> Bool
|| LintedType -> Bool
mightBeLiftedType LintedType
binder_ty
               Bool -> Bool -> Bool
|| (RecFlag -> Bool
isNonRec RecFlag
rec_flag Bool -> Bool -> Bool
&& CoreExpr -> Bool
exprOkForSpeculation CoreExpr
rhs)
               Bool -> Bool -> Bool
|| Var -> Bool
isDataConWorkId Var
binder Bool -> Bool -> Bool
|| Var -> Bool
isDataConWrapId Var
binder 
               Bool -> Bool -> Bool
|| CoreExpr -> Bool
exprIsTickedString CoreExpr
rhs)
           (Var -> SDoc -> SDoc
badBndrTyMsg Var
binder (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"unlifted"))
        
        
        
       ; Bool -> SDoc -> LintM ()
checkL (Bool -> Bool
not (TopLevelFlag -> Bool
isTopLevel TopLevelFlag
top_lvl Bool -> Bool -> Bool
&& LintedType
binder_ty LintedType -> LintedType -> Bool
`eqType` LintedType
addrPrimTy)
                 Bool -> Bool -> Bool
|| CoreExpr -> Bool
exprIsTickedString CoreExpr
rhs)
           (Var -> SDoc
mkTopNonLitStrMsg Var
binder)
       ; LintFlags
flags <- LintM LintFlags
getLintFlags
         
         
       ; case Var -> Maybe JoinArity
isJoinId_maybe Var
binder of
            Maybe JoinArity
Nothing    -> () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
            Just JoinArity
arity ->  Bool -> SDoc -> LintM ()
checkL (JoinArity -> LintedType -> Bool
isValidJoinPointType JoinArity
arity LintedType
binder_ty)
                                  (Var -> LintedType -> SDoc
mkInvalidJoinPointMsg Var
binder LintedType
binder_ty)
       ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (LintFlags -> Bool
lf_check_inline_loop_breakers LintFlags
flags
               Bool -> Bool -> Bool
&& Unfolding -> Bool
isStableUnfolding (Var -> Unfolding
realIdUnfolding Var
binder)
               Bool -> Bool -> Bool
&& OccInfo -> Bool
isStrongLoopBreaker (Var -> OccInfo
idOccInfo Var
binder)
               Bool -> Bool -> Bool
&& InlinePragma -> Bool
isInlinePragma (Var -> InlinePragma
idInlinePragma Var
binder))
              (SDoc -> LintM ()
addWarnL (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"INLINE binder is (non-rule) loop breaker:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
binder))
              
       
       
       
       
       
       
       ; Bool -> SDoc -> LintM ()
checkL (LintedType -> JoinArity
typeArity (Var -> LintedType
idType Var
binder) JoinArity -> JoinArity -> Bool
forall a. Ord a => a -> a -> Bool
>= Var -> JoinArity
idArity Var
binder)
           (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"idArity" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> JoinArity -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> JoinArity
idArity Var
binder) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+>
           String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"exceeds typeArity" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+>
           JoinArity -> SDoc
forall a. Outputable a => a -> SDoc
ppr (LintedType -> JoinArity
typeArity (Var -> LintedType
idType Var
binder)) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
colon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+>
           Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
binder)
       
       
       ; case DmdSig -> ([Demand], Divergence)
splitDmdSig (Var -> DmdSig
idDmdSig Var
binder) of
           ([Demand]
demands, Divergence
result_info) | Divergence -> Bool
isDeadEndDiv Divergence
result_info ->
             Bool -> SDoc -> LintM ()
checkL ([Demand]
demands [Demand] -> JoinArity -> Bool
forall a. [a] -> JoinArity -> Bool
`lengthAtLeast` Var -> JoinArity
idArity Var
binder)
               (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"idArity" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> JoinArity -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> JoinArity
idArity Var
binder) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+>
               String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"exceeds arity imposed by the strictness signature" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+>
               DmdSig -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> DmdSig
idDmdSig Var
binder) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
colon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+>
               Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
binder)
           ([Demand], Divergence)
_ -> () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
       ; LintLocInfo -> LintM () -> LintM ()
forall a. LintLocInfo -> LintM a -> LintM a
addLoc (Var -> LintLocInfo
RuleOf Var
binder) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$ (CoreRule -> LintM ()) -> [CoreRule] -> LintM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Var -> LintedType -> CoreRule -> LintM ()
lintCoreRule Var
binder LintedType
binder_ty) (Var -> [CoreRule]
idCoreRules Var
binder)
       ; LintLocInfo -> LintM () -> LintM ()
forall a. LintLocInfo -> LintM a -> LintM a
addLoc (Var -> LintLocInfo
UnfoldingOf Var
binder) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$
         Var -> LintedType -> Unfolding -> LintM ()
lintIdUnfolding Var
binder LintedType
binder_ty (Var -> Unfolding
idUnfolding Var
binder)
       ; () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return () }
        
        
lintRhs :: Id -> CoreExpr -> LintM (LintedType, UsageEnv)
lintRhs :: Var -> CoreExpr -> LintM (LintedType, UsageEnv)
lintRhs Var
bndr CoreExpr
rhs
    | Just JoinArity
arity <- Var -> Maybe JoinArity
isJoinId_maybe Var
bndr
    = JoinArity -> Maybe Var -> CoreExpr -> LintM (LintedType, UsageEnv)
lintJoinLams JoinArity
arity (Var -> Maybe Var
forall a. a -> Maybe a
Just Var
bndr) CoreExpr
rhs
    | AlwaysTailCalled JoinArity
arity <- OccInfo -> TailCallInfo
tailCallInfo (Var -> OccInfo
idOccInfo Var
bndr)
    = JoinArity -> Maybe Var -> CoreExpr -> LintM (LintedType, UsageEnv)
lintJoinLams JoinArity
arity Maybe Var
forall a. Maybe a
Nothing CoreExpr
rhs
lintRhs Var
_bndr CoreExpr
rhs = (LintFlags -> StaticPtrCheck)
-> LintM LintFlags -> LintM StaticPtrCheck
forall a b. (a -> b) -> LintM a -> LintM b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap LintFlags -> StaticPtrCheck
lf_check_static_ptrs LintM LintFlags
getLintFlags LintM StaticPtrCheck
-> (StaticPtrCheck -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv)
forall a b. LintM a -> (a -> LintM b) -> LintM b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= StaticPtrCheck -> LintM (LintedType, UsageEnv)
go
  where
    
    
    go :: StaticPtrCheck -> LintM (OutType, UsageEnv)
    go :: StaticPtrCheck -> LintM (LintedType, UsageEnv)
go StaticPtrCheck
AllowAtTopLevel
      | ([Var]
binders0, CoreExpr
rhs') <- CoreExpr -> ([Var], CoreExpr)
collectTyBinders CoreExpr
rhs
      , Just (CoreExpr
fun, LintedType
t, CoreExpr
info, CoreExpr
e) <- CoreExpr -> Maybe (CoreExpr, LintedType, CoreExpr, CoreExpr)
collectMakeStaticArgs CoreExpr
rhs'
      = LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. LintM a -> LintM a
markAllJoinsBad (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$
        (Var
 -> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv)
-> [Var]
-> LintM (LintedType, UsageEnv)
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr
        
        Var -> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
lintLambda
        
        (do (LintedType, UsageEnv)
fun_ty_ue <- CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
fun
            (LintedType, UsageEnv)
-> [CoreExpr] -> LintM (LintedType, UsageEnv)
lintCoreArgs (LintedType, UsageEnv)
fun_ty_ue [LintedType -> CoreExpr
forall b. LintedType -> Expr b
Type LintedType
t, CoreExpr
info, CoreExpr
e]
        )
        [Var]
binders0
    go StaticPtrCheck
_ = LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. LintM a -> LintM a
markAllJoinsBad (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$ CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
rhs
lintJoinLams :: JoinArity -> Maybe Id -> CoreExpr -> LintM (LintedType, UsageEnv)
lintJoinLams :: JoinArity -> Maybe Var -> CoreExpr -> LintM (LintedType, UsageEnv)
lintJoinLams JoinArity
join_arity Maybe Var
enforce CoreExpr
rhs
  = JoinArity -> CoreExpr -> LintM (LintedType, UsageEnv)
go JoinArity
join_arity CoreExpr
rhs
  where
    go :: JoinArity -> CoreExpr -> LintM (LintedType, UsageEnv)
go JoinArity
0 CoreExpr
expr            = CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
expr
    go JoinArity
n (Lam Var
var CoreExpr
body)  = Var -> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
lintLambda Var
var (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$ JoinArity -> CoreExpr -> LintM (LintedType, UsageEnv)
go (JoinArity
nJoinArity -> JoinArity -> JoinArity
forall a. Num a => a -> a -> a
-JoinArity
1) CoreExpr
body
    go JoinArity
n CoreExpr
expr | Just Var
bndr <- Maybe Var
enforce 
              = SDoc -> LintM (LintedType, UsageEnv)
forall a. SDoc -> LintM a
failWithL (SDoc -> LintM (LintedType, UsageEnv))
-> SDoc -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$ Var -> JoinArity -> JoinArity -> CoreExpr -> SDoc
mkBadJoinArityMsg Var
bndr JoinArity
join_arity JoinArity
n CoreExpr
rhs
              | Bool
otherwise 
              = LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. LintM a -> LintM a
markAllJoinsBad (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$ CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
expr
                
lintIdUnfolding :: Id -> Type -> Unfolding -> LintM ()
lintIdUnfolding :: Var -> LintedType -> Unfolding -> LintM ()
lintIdUnfolding Var
bndr LintedType
bndr_ty Unfolding
uf
  | Unfolding -> Bool
isStableUnfolding Unfolding
uf
  , Just CoreExpr
rhs <- Unfolding -> Maybe CoreExpr
maybeUnfoldingTemplate Unfolding
uf
  = do { LintedType
ty <- (LintedType, UsageEnv) -> LintedType
forall a b. (a, b) -> a
fst ((LintedType, UsageEnv) -> LintedType)
-> LintM (LintedType, UsageEnv) -> LintM LintedType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (if Unfolding -> Bool
isCompulsoryUnfolding Unfolding
uf
                        then LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. LintM a -> LintM a
noFixedRuntimeRepChecks (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$ Var -> CoreExpr -> LintM (LintedType, UsageEnv)
lintRhs Var
bndr CoreExpr
rhs
            
            
                        else Var -> CoreExpr -> LintM (LintedType, UsageEnv)
lintRhs Var
bndr CoreExpr
rhs)
       ; LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys LintedType
bndr_ty LintedType
ty (Var -> SDoc -> LintedType -> SDoc
mkRhsMsg Var
bndr (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"unfolding") LintedType
ty) }
lintIdUnfolding  Var
_ LintedType
_ Unfolding
_
  = () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()       
                    
type LintedType     = Type
type LintedKind     = Kind
type LintedCoercion = Coercion
type LintedTyCoVar  = TyCoVar
type LintedId       = Id
lintCastExpr :: CoreExpr -> LintedType -> Coercion -> LintM LintedType
lintCastExpr :: CoreExpr -> LintedType -> Coercion -> LintM LintedType
lintCastExpr CoreExpr
expr LintedType
expr_ty Coercion
co
  = do { Coercion
co' <- Coercion -> LintM Coercion
lintCoercion Coercion
co
       ; let (Pair LintedType
from_ty LintedType
to_ty, Role
role) = Coercion -> (Pair LintedType, Role)
coercionKindRole Coercion
co'
       ; LintedType -> SDoc -> LintM ()
checkValueType LintedType
to_ty (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
         String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"target of cast" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
quotes (Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co')
       ; Coercion -> Role -> Role -> LintM ()
forall thing. Outputable thing => thing -> Role -> Role -> LintM ()
lintRole Coercion
co' Role
Representational Role
role
       ; LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys LintedType
from_ty LintedType
expr_ty (CoreExpr -> Coercion -> LintedType -> LintedType -> SDoc
mkCastErr CoreExpr
expr Coercion
co' LintedType
from_ty LintedType
expr_ty)
       ; LintedType -> LintM LintedType
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return LintedType
to_ty }
lintCoreExpr :: CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr :: CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr (Var Var
var)
  = do
      var_pair :: (LintedType, UsageEnv)
var_pair@(LintedType
var_ty, UsageEnv
_) <- Var -> JoinArity -> LintM (LintedType, UsageEnv)
lintIdOcc Var
var JoinArity
0
      CoreExpr -> [CoreExpr] -> LintedType -> LintM ()
checkCanEtaExpand (Var -> CoreExpr
forall b. Var -> Expr b
Var Var
var) [] LintedType
var_ty
      (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (LintedType, UsageEnv)
var_pair
lintCoreExpr (Lit Literal
lit)
  = (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Literal -> LintedType
literalType Literal
lit, UsageEnv
zeroUE)
lintCoreExpr (Cast CoreExpr
expr Coercion
co)
  = do (LintedType
expr_ty, UsageEnv
ue) <- LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. LintM a -> LintM a
markAllJoinsBad (CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
expr)
            
       LintedType
to_ty <- CoreExpr -> LintedType -> Coercion -> LintM LintedType
lintCastExpr CoreExpr
expr LintedType
expr_ty Coercion
co
       (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (LintedType
to_ty, UsageEnv
ue)
lintCoreExpr (Tick CoreTickish
tickish CoreExpr
expr)
  = do case CoreTickish
tickish of
         Breakpoint XBreakpoint 'TickishPassCore
_ JoinArity
_ [XTickishId 'TickishPassCore]
ids -> [Var] -> (Var -> LintM (Var, LintedType)) -> LintM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Var]
[XTickishId 'TickishPassCore]
ids ((Var -> LintM (Var, LintedType)) -> LintM ())
-> (Var -> LintM (Var, LintedType)) -> LintM ()
forall a b. (a -> b) -> a -> b
$ \Var
id -> do
                                 Var -> LintM ()
checkDeadIdOcc Var
id
                                 Var -> LintM (Var, LintedType)
lookupIdInScope Var
id
         CoreTickish
_                  -> () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
       Bool
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. Bool -> LintM a -> LintM a
markAllJoinsBadIf Bool
block_joins (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$ CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
expr
  where
    block_joins :: Bool
block_joins = Bool -> Bool
not (CoreTickish
tickish CoreTickish -> TickishScoping -> Bool
forall (pass :: TickishPass).
GenTickish pass -> TickishScoping -> Bool
`tickishScopesLike` TickishScoping
SoftScope)
      
      
      
      
      
lintCoreExpr (Let (NonRec Var
tv (Type LintedType
ty)) CoreExpr
body)
  | Var -> Bool
isTyVar Var
tv
  =     
    do  { LintedType
ty' <- LintedType -> LintM LintedType
lintType LintedType
ty
        ; Var
-> (Var -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv)
forall a. Var -> (Var -> LintM a) -> LintM a
lintTyBndr Var
tv              ((Var -> LintM (LintedType, UsageEnv))
 -> LintM (LintedType, UsageEnv))
-> (Var -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$ \ Var
tv' ->
    do  { LintLocInfo -> LintM () -> LintM ()
forall a. LintLocInfo -> LintM a -> LintM a
addLoc (Var -> LintLocInfo
RhsOf Var
tv) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$ Var -> LintedType -> LintM ()
lintTyKind Var
tv' LintedType
ty'
                
                
        ; Var
-> LintedType
-> LintM (LintedType, UsageEnv)
-> LintM (LintedType, UsageEnv)
forall a. Var -> LintedType -> LintM a -> LintM a
extendTvSubstL Var
tv LintedType
ty'        (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$
          LintLocInfo
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. LintLocInfo -> LintM a -> LintM a
addLoc ([Var] -> LintLocInfo
BodyOfLetRec [Var
tv]) (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$
          CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
body } }
lintCoreExpr (Let (NonRec Var
bndr CoreExpr
rhs) CoreExpr
body)
  | Var -> Bool
isId Var
bndr
  = do { 
         (LintedType
rhs_ty, UsageEnv
let_ue) <- Var -> CoreExpr -> LintM (LintedType, UsageEnv)
lintRhs Var
bndr CoreExpr
rhs
          
         
       ; BindingSite
-> Var
-> (Var -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv)
forall a. BindingSite -> Var -> (Var -> LintM a) -> LintM a
lintBinder BindingSite
LetBind Var
bndr ((Var -> LintM (LintedType, UsageEnv))
 -> LintM (LintedType, UsageEnv))
-> (Var -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$ \Var
bndr' ->
    do { TopLevelFlag
-> RecFlag -> Var -> CoreExpr -> LintedType -> LintM ()
lintLetBind TopLevelFlag
NotTopLevel RecFlag
NonRecursive Var
bndr' CoreExpr
rhs LintedType
rhs_ty
       ; Var
-> UsageEnv
-> LintM (LintedType, UsageEnv)
-> LintM (LintedType, UsageEnv)
forall a. Var -> UsageEnv -> LintM a -> LintM a
addAliasUE Var
bndr UsageEnv
let_ue ([Var] -> CoreExpr -> LintM (LintedType, UsageEnv)
lintLetBody [Var
bndr'] CoreExpr
body) } }
  | Bool
otherwise
  = SDoc -> LintM (LintedType, UsageEnv)
forall a. SDoc -> LintM a
failWithL (Var -> CoreExpr -> SDoc
mkLetErr Var
bndr CoreExpr
rhs)       
lintCoreExpr e :: CoreExpr
e@(Let (Rec [(Var, CoreExpr)]
pairs) CoreExpr
body)
  = do  { 
          Bool -> SDoc -> LintM ()
checkL (Bool -> Bool
not ([(Var, CoreExpr)] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Var, CoreExpr)]
pairs)) (CoreExpr -> SDoc
emptyRec CoreExpr
e)
          
        ; let ([Var]
_, [NonEmpty Var]
dups) = (Var -> Var -> Ordering) -> [Var] -> ([Var], [NonEmpty Var])
forall a. (a -> a -> Ordering) -> [a] -> ([a], [NonEmpty a])
removeDups Var -> Var -> Ordering
forall a. Ord a => a -> a -> Ordering
compare [Var]
bndrs
        ; Bool -> SDoc -> LintM ()
checkL ([NonEmpty Var] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [NonEmpty Var]
dups) ([NonEmpty Var] -> SDoc
dupVars [NonEmpty Var]
dups)
          
        ; Bool -> SDoc -> LintM ()
checkL ((Var -> Bool) -> [Var] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Var -> Bool
isJoinId [Var]
bndrs Bool -> Bool -> Bool
|| (Var -> Bool) -> [Var] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Bool -> Bool
not (Bool -> Bool) -> (Var -> Bool) -> Var -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Var -> Bool
isJoinId) [Var]
bndrs) (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
          [Var] -> SDoc
mkInconsistentRecMsg [Var]
bndrs
          
        ; ((LintedType
body_type, UsageEnv
body_ue), [UsageEnv]
ues) <-
            TopLevelFlag
-> [(Var, CoreExpr)]
-> ([Var] -> LintM (LintedType, UsageEnv))
-> LintM ((LintedType, UsageEnv), [UsageEnv])
forall a.
TopLevelFlag
-> [(Var, CoreExpr)] -> ([Var] -> LintM a) -> LintM (a, [UsageEnv])
lintRecBindings TopLevelFlag
NotTopLevel [(Var, CoreExpr)]
pairs (([Var] -> LintM (LintedType, UsageEnv))
 -> LintM ((LintedType, UsageEnv), [UsageEnv]))
-> ([Var] -> LintM (LintedType, UsageEnv))
-> LintM ((LintedType, UsageEnv), [UsageEnv])
forall a b. (a -> b) -> a -> b
$ \ [Var]
bndrs' ->
            [Var] -> CoreExpr -> LintM (LintedType, UsageEnv)
lintLetBody [Var]
bndrs' CoreExpr
body
        ; (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (LintedType
body_type, UsageEnv
body_ue  UsageEnv -> UsageEnv -> UsageEnv
`addUE` LintedType -> UsageEnv -> UsageEnv
scaleUE LintedType
ManyTy ((UsageEnv -> UsageEnv -> UsageEnv) -> [UsageEnv] -> UsageEnv
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 UsageEnv -> UsageEnv -> UsageEnv
addUE [UsageEnv]
ues)) }
  where
    bndrs :: [Var]
bndrs = ((Var, CoreExpr) -> Var) -> [(Var, CoreExpr)] -> [Var]
forall a b. (a -> b) -> [a] -> [b]
map (Var, CoreExpr) -> Var
forall a b. (a, b) -> a
fst [(Var, CoreExpr)]
pairs
lintCoreExpr e :: CoreExpr
e@(App CoreExpr
_ CoreExpr
_)
  | Var Var
fun <- CoreExpr
fun
  , Var
fun Var -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
runRWKey
    
    
  , CoreExpr
ty_arg1 : CoreExpr
ty_arg2 : CoreExpr
arg3 : [CoreExpr]
rest <- [CoreExpr]
args
  = do { (LintedType, UsageEnv)
fun_pair1      <- (LintedType, UsageEnv) -> CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreArg (Var -> LintedType
idType Var
fun, UsageEnv
zeroUE) CoreExpr
ty_arg1
       ; (LintedType
fun_ty2, UsageEnv
ue2) <- (LintedType, UsageEnv) -> CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreArg (LintedType, UsageEnv)
fun_pair1            CoreExpr
ty_arg2
         
       ; let lintRunRWCont :: CoreArg -> LintM (LintedType, UsageEnv)
             lintRunRWCont :: CoreExpr -> LintM (LintedType, UsageEnv)
lintRunRWCont expr :: CoreExpr
expr@(Lam Var
_ CoreExpr
_) =
                JoinArity -> Maybe Var -> CoreExpr -> LintM (LintedType, UsageEnv)
lintJoinLams JoinArity
1 (Var -> Maybe Var
forall a. a -> Maybe a
Just Var
fun) CoreExpr
expr
             lintRunRWCont CoreExpr
other = LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. LintM a -> LintM a
markAllJoinsBad (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$ CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
other
             
       ; (LintedType
arg3_ty, UsageEnv
ue3) <- CoreExpr -> LintM (LintedType, UsageEnv)
lintRunRWCont CoreExpr
arg3
       ; (LintedType, UsageEnv)
app_ty <- CoreExpr
-> LintedType
-> LintedType
-> UsageEnv
-> UsageEnv
-> LintM (LintedType, UsageEnv)
lintValApp CoreExpr
arg3 LintedType
fun_ty2 LintedType
arg3_ty UsageEnv
ue2 UsageEnv
ue3
       ; (LintedType, UsageEnv)
-> [CoreExpr] -> LintM (LintedType, UsageEnv)
lintCoreArgs (LintedType, UsageEnv)
app_ty [CoreExpr]
rest }
  | Bool
otherwise
  = do { (LintedType, UsageEnv)
fun_pair <- CoreExpr -> JoinArity -> LintM (LintedType, UsageEnv)
lintCoreFun CoreExpr
fun ([CoreExpr] -> JoinArity
forall a. [a] -> JoinArity
forall (t :: * -> *) a. Foldable t => t a -> JoinArity
length [CoreExpr]
args)
       ; app_pair :: (LintedType, UsageEnv)
app_pair@(LintedType
app_ty, UsageEnv
_) <- (LintedType, UsageEnv)
-> [CoreExpr] -> LintM (LintedType, UsageEnv)
lintCoreArgs (LintedType, UsageEnv)
fun_pair [CoreExpr]
args
       ; CoreExpr -> [CoreExpr] -> LintedType -> LintM ()
checkCanEtaExpand CoreExpr
fun [CoreExpr]
args LintedType
app_ty
       ; (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (LintedType, UsageEnv)
app_pair}
  where
    skipTick :: CoreTickish -> Bool
skipTick CoreTickish
t = case CoreExpr -> CoreExpr
forall b. Expr b -> Expr b
collectFunSimple CoreExpr
e of
      (Var Var
v) -> Var -> CoreTickish -> Bool
forall (pass :: TickishPass). Var -> GenTickish pass -> Bool
etaExpansionTick Var
v CoreTickish
t
      CoreExpr
_ -> CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishFloatable CoreTickish
t
    (CoreExpr
fun, [CoreExpr]
args, [CoreTickish]
_source_ticks) = (CoreTickish -> Bool)
-> CoreExpr -> (CoreExpr, [CoreExpr], [CoreTickish])
forall b.
(CoreTickish -> Bool)
-> Expr b -> (Expr b, [Expr b], [CoreTickish])
collectArgsTicks CoreTickish -> Bool
skipTick CoreExpr
e
      
      
      
      
      
      
      
      
      
      
      
      
lintCoreExpr (Lam Var
var CoreExpr
expr)
  = LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. LintM a -> LintM a
markAllJoinsBad (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$
    Var -> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
lintLambda Var
var (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$ CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
expr
lintCoreExpr (Case CoreExpr
scrut Var
var LintedType
alt_ty [Alt Var]
alts)
  = CoreExpr
-> Var -> LintedType -> [Alt Var] -> LintM (LintedType, UsageEnv)
lintCaseExpr CoreExpr
scrut Var
var LintedType
alt_ty [Alt Var]
alts
lintCoreExpr (Type LintedType
ty)
  = SDoc -> LintM (LintedType, UsageEnv)
forall a. SDoc -> LintM a
failWithL (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Type found as expression" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty)
lintCoreExpr (Coercion Coercion
co)
  = do { Coercion
co' <- LintLocInfo -> LintM Coercion -> LintM Coercion
forall a. LintLocInfo -> LintM a -> LintM a
addLoc (Coercion -> LintLocInfo
InCo Coercion
co) (LintM Coercion -> LintM Coercion)
-> LintM Coercion -> LintM Coercion
forall a b. (a -> b) -> a -> b
$
                Coercion -> LintM Coercion
lintCoercion Coercion
co
       ; (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Coercion -> LintedType
coercionType Coercion
co', UsageEnv
zeroUE) }
lintIdOcc :: Var -> Int 
           -> LintM (LintedType, UsageEnv) 
lintIdOcc :: Var -> JoinArity -> LintM (LintedType, UsageEnv)
lintIdOcc Var
var JoinArity
nargs
  = LintLocInfo
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. LintLocInfo -> LintM a -> LintM a
addLoc (Var -> LintLocInfo
OccOf Var
var) (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$
    do  { Bool -> SDoc -> LintM ()
checkL (Var -> Bool
isNonCoVarId Var
var)
                 (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Non term variable" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
var)
                 
        
        
        
        
        
        
        
        
        
        
        
        ; (Var
bndr, LintedType
linted_bndr_ty) <- Var -> LintM (Var, LintedType)
lookupIdInScope Var
var
        ; let occ_ty :: LintedType
occ_ty  = Var -> LintedType
idType Var
var
              bndr_ty :: LintedType
bndr_ty = Var -> LintedType
idType Var
bndr
        ; LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys LintedType
occ_ty LintedType
bndr_ty (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
          Var -> Var -> LintedType -> LintedType -> SDoc
mkBndrOccTypeMismatchMsg Var
bndr Var
var LintedType
bndr_ty LintedType
occ_ty
          
          
        ; LintFlags
lf <- LintM LintFlags
getLintFlags
        ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (JoinArity
nargs JoinArity -> JoinArity -> Bool
forall a. Eq a => a -> a -> Bool
/= JoinArity
0 Bool -> Bool -> Bool
&& LintFlags -> StaticPtrCheck
lf_check_static_ptrs LintFlags
lf StaticPtrCheck -> StaticPtrCheck -> Bool
forall a. Eq a => a -> a -> Bool
/= StaticPtrCheck
AllowAnywhere) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$
            Bool -> SDoc -> LintM ()
checkL (Var -> Name
idName Var
var Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
/= Name
makeStaticName) (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
              String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Found makeStatic nested in an expression"
        ; Var -> LintM ()
checkDeadIdOcc Var
var
        ; Var -> JoinArity -> LintM ()
checkJoinOcc Var
var JoinArity
nargs
        ; case Var -> Maybe DataCon
isDataConId_maybe Var
var of
             Maybe DataCon
Nothing -> () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
             Just DataCon
dc -> String -> DataCon -> LintM ()
checkTypeDataConOcc String
"expression" DataCon
dc
        ; UsageEnv
usage <- Var -> LintM UsageEnv
varCallSiteUsage Var
var
        ; (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (LintedType
linted_bndr_ty, UsageEnv
usage) }
lintCoreFun :: CoreExpr
            -> Int                          
            -> LintM (LintedType, UsageEnv) 
lintCoreFun :: CoreExpr -> JoinArity -> LintM (LintedType, UsageEnv)
lintCoreFun (Var Var
var) JoinArity
nargs
  = Var -> JoinArity -> LintM (LintedType, UsageEnv)
lintIdOcc Var
var JoinArity
nargs
lintCoreFun (Lam Var
var CoreExpr
body) JoinArity
nargs
  
  
  | JoinArity
nargs JoinArity -> JoinArity -> Bool
forall a. Eq a => a -> a -> Bool
/= JoinArity
0
  = Var -> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
lintLambda Var
var (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$ CoreExpr -> JoinArity -> LintM (LintedType, UsageEnv)
lintCoreFun CoreExpr
body (JoinArity
nargs JoinArity -> JoinArity -> JoinArity
forall a. Num a => a -> a -> a
- JoinArity
1)
lintCoreFun CoreExpr
expr JoinArity
nargs
  = Bool
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. Bool -> LintM a -> LintM a
markAllJoinsBadIf (JoinArity
nargs JoinArity -> JoinArity -> Bool
forall a. Eq a => a -> a -> Bool
/= JoinArity
0) (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$
      
    CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
expr
lintLambda :: Var -> LintM (Type, UsageEnv) -> LintM (Type, UsageEnv)
lintLambda :: Var -> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
lintLambda Var
var LintM (LintedType, UsageEnv)
lintBody =
    LintLocInfo
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. LintLocInfo -> LintM a -> LintM a
addLoc (Var -> LintLocInfo
LambdaBodyOf Var
var) (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$
    BindingSite
-> Var
-> (Var -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv)
forall a. BindingSite -> Var -> (Var -> LintM a) -> LintM a
lintBinder BindingSite
LambdaBind Var
var ((Var -> LintM (LintedType, UsageEnv))
 -> LintM (LintedType, UsageEnv))
-> (Var -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$ \ Var
var' ->
    do { (LintedType
body_ty, UsageEnv
ue) <- LintM (LintedType, UsageEnv)
lintBody
       ; UsageEnv
ue' <- UsageEnv -> Var -> LintM UsageEnv
checkLinearity UsageEnv
ue Var
var'
       ; (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (HasDebugCallStack => Var -> LintedType -> LintedType
Var -> LintedType -> LintedType
mkLamType Var
var' LintedType
body_ty, UsageEnv
ue') }
checkDeadIdOcc :: Id -> LintM ()
checkDeadIdOcc :: Var -> LintM ()
checkDeadIdOcc Var
id
  | OccInfo -> Bool
isDeadOcc (Var -> OccInfo
idOccInfo Var
id)
  = do { Bool
in_case <- LintM Bool
inCasePat
       ; Bool -> SDoc -> LintM ()
checkL Bool
in_case
                (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Occurrence of a dead Id" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
id) }
  | Bool
otherwise
  = () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
lintJoinBndrType :: LintedType 
                 -> LintedId   
                -> LintM ()
lintJoinBndrType :: LintedType -> Var -> LintM ()
lintJoinBndrType LintedType
body_ty Var
bndr
  | Just JoinArity
arity <- Var -> Maybe JoinArity
isJoinId_maybe Var
bndr
  , let bndr_ty :: LintedType
bndr_ty = Var -> LintedType
idType Var
bndr
  , ([PiTyBinder]
bndrs, LintedType
res) <- LintedType -> ([PiTyBinder], LintedType)
splitPiTys LintedType
bndr_ty
  = Bool -> SDoc -> LintM ()
checkL ([PiTyBinder] -> JoinArity
forall a. [a] -> JoinArity
forall (t :: * -> *) a. Foldable t => t a -> JoinArity
length [PiTyBinder]
bndrs JoinArity -> JoinArity -> Bool
forall a. Ord a => a -> a -> Bool
>= JoinArity
arity
            Bool -> Bool -> Bool
&& LintedType
body_ty LintedType -> LintedType -> Bool
`eqType` [PiTyBinder] -> LintedType -> LintedType
mkPiTys (JoinArity -> [PiTyBinder] -> [PiTyBinder]
forall a. JoinArity -> [a] -> [a]
drop JoinArity
arity [PiTyBinder]
bndrs) LintedType
res) (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
    SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Join point returns different type than body")
       JoinArity
2 ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Join bndr:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
bndr SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> LintedType
idType Var
bndr)
               , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Join arity:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> JoinArity -> SDoc
forall a. Outputable a => a -> SDoc
ppr JoinArity
arity
               , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Body type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
body_ty ])
  | Bool
otherwise
  = () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
checkJoinOcc :: Id -> JoinArity -> LintM ()
checkJoinOcc :: Var -> JoinArity -> LintM ()
checkJoinOcc Var
var JoinArity
n_args
  | Just JoinArity
join_arity_occ <- Var -> Maybe JoinArity
isJoinId_maybe Var
var
  = do { Maybe JoinArity
mb_join_arity_bndr <- Var -> LintM (Maybe JoinArity)
lookupJoinId Var
var
       ; case Maybe JoinArity
mb_join_arity_bndr of {
           Maybe JoinArity
Nothing -> 
                      do { IdSet
join_set <- LintM IdSet
getValidJoins
                         ; SDoc -> LintM ()
addErrL (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"join set " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> IdSet -> SDoc
forall a. Outputable a => a -> SDoc
ppr IdSet
join_set SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$
                                    Var -> SDoc
invalidJoinOcc Var
var) } ;
           Just JoinArity
join_arity_bndr ->
    do { Bool -> SDoc -> LintM ()
checkL (JoinArity
join_arity_bndr JoinArity -> JoinArity -> Bool
forall a. Eq a => a -> a -> Bool
== JoinArity
join_arity_occ) (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
           
         Var -> JoinArity -> JoinArity -> SDoc
mkJoinBndrOccMismatchMsg Var
var JoinArity
join_arity_bndr JoinArity
join_arity_occ
       ; Bool -> SDoc -> LintM ()
checkL (JoinArity
n_args JoinArity -> JoinArity -> Bool
forall a. Eq a => a -> a -> Bool
== JoinArity
join_arity_occ) (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
           
         Var -> JoinArity -> JoinArity -> SDoc
mkBadJumpMsg Var
var JoinArity
join_arity_occ JoinArity
n_args } } }
  | Bool
otherwise
  = () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
checkTypeDataConOcc :: String -> DataCon -> LintM ()
checkTypeDataConOcc :: String -> DataCon -> LintM ()
checkTypeDataConOcc String
what DataCon
dc
  = Bool -> SDoc -> LintM ()
checkL (Bool -> Bool
not (TyCon -> Bool
isTypeDataTyCon (DataCon -> TyCon
dataConTyCon DataCon
dc))) (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
    (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"type data constructor found in a" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
what SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
colon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> DataCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr DataCon
dc)
checkCanEtaExpand :: CoreExpr   
                  -> [CoreArg]  
                  -> LintedType 
                  -> LintM ()
checkCanEtaExpand :: CoreExpr -> [CoreExpr] -> LintedType -> LintM ()
checkCanEtaExpand (Var Var
fun_id) [CoreExpr]
args LintedType
app_ty
  = do { Bool
do_rep_poly_checks <- LintFlags -> Bool
lf_check_fixed_rep (LintFlags -> Bool) -> LintM LintFlags -> LintM Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LintM LintFlags
getLintFlags
       ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
do_rep_poly_checks Bool -> Bool -> Bool
&& Var -> Bool
hasNoBinding Var
fun_id) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$
           Bool -> SDoc -> LintM ()
checkL ([LintedType] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [LintedType]
bad_arg_tys) SDoc
err_msg }
    where
      arity :: Arity
      arity :: JoinArity
arity = Var -> JoinArity
idArity Var
fun_id
      nb_val_args :: Int
      nb_val_args :: JoinArity
nb_val_args = (CoreExpr -> Bool) -> [CoreExpr] -> JoinArity
forall a. (a -> Bool) -> [a] -> JoinArity
count CoreExpr -> Bool
forall b. Expr b -> Bool
isValArg [CoreExpr]
args
      
      
      
      
      check_args :: [Type] -> [Type]
      check_args :: [LintedType] -> [LintedType]
check_args = JoinArity -> [LintedType] -> [LintedType]
go (JoinArity
nb_val_args JoinArity -> JoinArity -> JoinArity
forall a. Num a => a -> a -> a
+ JoinArity
1)
        where
          go :: Int    
             -> [Type] 
             -> [Type] 
                       
          go :: JoinArity -> [LintedType] -> [LintedType]
go JoinArity
i [LintedType]
_
            | JoinArity
i JoinArity -> JoinArity -> Bool
forall a. Ord a => a -> a -> Bool
> JoinArity
arity
            = []
          go JoinArity
_ []
            
            
            
            = String -> SDoc -> [LintedType]
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"checkCanEtaExpand: arity larger than number of value arguments apparent in type"
                (SDoc -> [LintedType]) -> SDoc -> [LintedType]
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat
                  [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"fun_id =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
fun_id
                  , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"arity =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> JoinArity -> SDoc
forall a. Outputable a => a -> SDoc
ppr JoinArity
arity
                  , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"app_ty =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
app_ty
                  , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"args = " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [CoreExpr] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [CoreExpr]
args
                  , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"nb_val_args =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> JoinArity -> SDoc
forall a. Outputable a => a -> SDoc
ppr JoinArity
nb_val_args ]
          go JoinArity
i (LintedType
ty : [LintedType]
bndrs)
            | HasDebugCallStack => LintedType -> Bool
LintedType -> Bool
typeHasFixedRuntimeRep LintedType
ty
            = JoinArity -> [LintedType] -> [LintedType]
go (JoinArity
iJoinArity -> JoinArity -> JoinArity
forall a. Num a => a -> a -> a
+JoinArity
1) [LintedType]
bndrs
            | Bool
otherwise
            = LintedType
ty LintedType -> [LintedType] -> [LintedType]
forall a. a -> [a] -> [a]
: JoinArity -> [LintedType] -> [LintedType]
go (JoinArity
iJoinArity -> JoinArity -> JoinArity
forall a. Num a => a -> a -> a
+JoinArity
1) [LintedType]
bndrs
      bad_arg_tys :: [Type]
      bad_arg_tys :: [LintedType]
bad_arg_tys = [LintedType] -> [LintedType]
check_args ([LintedType] -> [LintedType])
-> ([(Scaled LintedType, FunTyFlag)] -> [LintedType])
-> [(Scaled LintedType, FunTyFlag)]
-> [LintedType]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Scaled LintedType, FunTyFlag) -> LintedType)
-> [(Scaled LintedType, FunTyFlag)] -> [LintedType]
forall a b. (a -> b) -> [a] -> [b]
map (Scaled LintedType -> LintedType
forall a. Scaled a -> a
scaledThing (Scaled LintedType -> LintedType)
-> ((Scaled LintedType, FunTyFlag) -> Scaled LintedType)
-> (Scaled LintedType, FunTyFlag)
-> LintedType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Scaled LintedType, FunTyFlag) -> Scaled LintedType
forall a b. (a, b) -> a
fst) ([(Scaled LintedType, FunTyFlag)] -> [LintedType])
-> [(Scaled LintedType, FunTyFlag)] -> [LintedType]
forall a b. (a -> b) -> a -> b
$ LintedType -> [(Scaled LintedType, FunTyFlag)]
getRuntimeArgTys LintedType
app_ty
        
        
        
        
        
        
        
        
        
      err_msg :: SDoc
      err_msg :: SDoc
err_msg
        = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Cannot eta expand" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
quotes (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
fun_id)
               , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"The following type" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> [LintedType] -> SDoc
forall a. [a] -> SDoc
plural [LintedType]
bad_arg_tys
                 SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [LintedType] -> SDoc
forall a. [a] -> SDoc
doOrDoes [LintedType]
bad_arg_tys SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"not have a fixed runtime representation:"
               , JoinArity -> SDoc -> SDoc
nest JoinArity
2 (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (LintedType -> SDoc) -> [LintedType] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map LintedType -> SDoc
ppr_ty_ki [LintedType]
bad_arg_tys ]
      ppr_ty_ki :: Type -> SDoc
      ppr_ty_ki :: LintedType -> SDoc
ppr_ty_ki LintedType
ty = SDoc
bullet SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
ty)
checkCanEtaExpand CoreExpr
_ [CoreExpr]
_ LintedType
_
  = () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
checkLinearity :: UsageEnv -> Var -> LintM UsageEnv
checkLinearity :: UsageEnv -> Var -> LintM UsageEnv
checkLinearity UsageEnv
body_ue Var
lam_var =
  case Var -> Maybe LintedType
varMultMaybe Var
lam_var of
    Just LintedType
mult -> do
      let (Usage
lhs, UsageEnv
body_ue') = UsageEnv -> Var -> (Usage, UsageEnv)
forall n. NamedThing n => UsageEnv -> n -> (Usage, UsageEnv)
popUE UsageEnv
body_ue Var
lam_var
          err_msg :: SDoc
err_msg = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Linearity failure in lambda:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
lam_var
                    SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ Usage -> SDoc
forall a. Outputable a => a -> SDoc
ppr Usage
lhs SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"⊈" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
mult
      Usage -> LintedType -> SDoc -> LintM ()
ensureSubUsage Usage
lhs LintedType
mult SDoc
err_msg
      UsageEnv -> LintM UsageEnv
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return UsageEnv
body_ue'
    Maybe LintedType
Nothing    -> UsageEnv -> LintM UsageEnv
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return UsageEnv
body_ue 
lintCoreArgs  :: (LintedType, UsageEnv) -> [CoreArg] -> LintM (LintedType, UsageEnv)
lintCoreArgs :: (LintedType, UsageEnv)
-> [CoreExpr] -> LintM (LintedType, UsageEnv)
lintCoreArgs (LintedType
fun_ty, UsageEnv
fun_ue) [CoreExpr]
args = ((LintedType, UsageEnv)
 -> CoreExpr -> LintM (LintedType, UsageEnv))
-> (LintedType, UsageEnv)
-> [CoreExpr]
-> LintM (LintedType, UsageEnv)
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM (LintedType, UsageEnv) -> CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreArg (LintedType
fun_ty, UsageEnv
fun_ue) [CoreExpr]
args
lintCoreArg  :: (LintedType, UsageEnv) -> CoreArg -> LintM (LintedType, UsageEnv)
lintCoreArg :: (LintedType, UsageEnv) -> CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreArg (LintedType
fun_ty, UsageEnv
ue) (Type LintedType
arg_ty)
  = do { Bool -> SDoc -> LintM ()
checkL (Bool -> Bool
not (LintedType -> Bool
isCoercionTy LintedType
arg_ty))
                (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Unnecessary coercion-to-type injection:"
                  SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
arg_ty)
       ; LintedType
arg_ty' <- LintedType -> LintM LintedType
lintType LintedType
arg_ty
       ; LintedType
res <- LintedType -> LintedType -> LintM LintedType
lintTyApp LintedType
fun_ty LintedType
arg_ty'
       ; (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (LintedType
res, UsageEnv
ue) }
lintCoreArg (LintedType
fun_ty, UsageEnv
fun_ue) CoreExpr
arg
  = do { (LintedType
arg_ty, UsageEnv
arg_ue) <- LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. LintM a -> LintM a
markAllJoinsBad (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$ CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
arg
           
       ; LintFlags
flags <- LintM LintFlags
getLintFlags
       ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (LintFlags -> Bool
lf_check_fixed_rep LintFlags
flags) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$
         
         
         do { Bool -> SDoc -> LintM ()
checkL (HasDebugCallStack => LintedType -> Bool
LintedType -> Bool
typeHasFixedRuntimeRep LintedType
arg_ty)
                     (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Argument does not have a fixed runtime representation"
                      SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
arg SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon
                      SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
arg_ty SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
arg_ty))) }
       ; CoreExpr
-> LintedType
-> LintedType
-> UsageEnv
-> UsageEnv
-> LintM (LintedType, UsageEnv)
lintValApp CoreExpr
arg LintedType
fun_ty LintedType
arg_ty UsageEnv
fun_ue UsageEnv
arg_ue }
lintAltBinders :: UsageEnv
               -> Var         
               -> LintedType     
               -> LintedType     
               -> [(Mult, OutVar)]    
               -> LintM UsageEnv
lintAltBinders :: UsageEnv
-> Var
-> LintedType
-> LintedType
-> [(LintedType, Var)]
-> LintM UsageEnv
lintAltBinders UsageEnv
rhs_ue Var
_case_bndr LintedType
scrut_ty LintedType
con_ty []
  = do { LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys LintedType
con_ty LintedType
scrut_ty (LintedType -> LintedType -> SDoc
mkBadPatMsg LintedType
con_ty LintedType
scrut_ty)
       ; UsageEnv -> LintM UsageEnv
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return UsageEnv
rhs_ue }
lintAltBinders UsageEnv
rhs_ue Var
case_bndr LintedType
scrut_ty LintedType
con_ty ((LintedType
var_w, Var
bndr):[(LintedType, Var)]
bndrs)
  | Var -> Bool
isTyVar Var
bndr
  = do { LintedType
con_ty' <- LintedType -> LintedType -> LintM LintedType
lintTyApp LintedType
con_ty (Var -> LintedType
mkTyVarTy Var
bndr)
       ; UsageEnv
-> Var
-> LintedType
-> LintedType
-> [(LintedType, Var)]
-> LintM UsageEnv
lintAltBinders UsageEnv
rhs_ue Var
case_bndr LintedType
scrut_ty LintedType
con_ty'  [(LintedType, Var)]
bndrs }
  | Bool
otherwise
  = do { (LintedType
con_ty', UsageEnv
_) <- CoreExpr
-> LintedType
-> LintedType
-> UsageEnv
-> UsageEnv
-> LintM (LintedType, UsageEnv)
lintValApp (Var -> CoreExpr
forall b. Var -> Expr b
Var Var
bndr) LintedType
con_ty (Var -> LintedType
idType Var
bndr) UsageEnv
zeroUE UsageEnv
zeroUE
         
         
       ; UsageEnv
rhs_ue' <- UsageEnv -> Var -> LintedType -> Var -> LintM UsageEnv
checkCaseLinearity UsageEnv
rhs_ue Var
case_bndr LintedType
var_w Var
bndr
       ; UsageEnv
-> Var
-> LintedType
-> LintedType
-> [(LintedType, Var)]
-> LintM UsageEnv
lintAltBinders UsageEnv
rhs_ue' Var
case_bndr LintedType
scrut_ty LintedType
con_ty' [(LintedType, Var)]
bndrs }
checkCaseLinearity :: UsageEnv -> Var -> Mult -> Var -> LintM UsageEnv
checkCaseLinearity :: UsageEnv -> Var -> LintedType -> Var -> LintM UsageEnv
checkCaseLinearity UsageEnv
ue Var
case_bndr LintedType
var_w Var
bndr = do
  Usage -> LintedType -> SDoc -> LintM ()
ensureSubUsage Usage
lhs LintedType
rhs SDoc
err_msg
  SDoc -> LintedType -> LintedType -> LintM ()
lintLinearBinder (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
bndr) (LintedType
case_bndr_w LintedType -> LintedType -> LintedType
`mkMultMul` LintedType
var_w) (Var -> LintedType
varMult Var
bndr)
  UsageEnv -> LintM UsageEnv
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (UsageEnv -> LintM UsageEnv) -> UsageEnv -> LintM UsageEnv
forall a b. (a -> b) -> a -> b
$ UsageEnv -> Var -> UsageEnv
forall n. NamedThing n => UsageEnv -> n -> UsageEnv
deleteUE UsageEnv
ue Var
bndr
  where
    lhs :: Usage
lhs = Usage
bndr_usage Usage -> Usage -> Usage
`addUsage` (LintedType
var_w LintedType -> Usage -> Usage
`scaleUsage` Usage
case_bndr_usage)
    rhs :: LintedType
rhs = LintedType
case_bndr_w LintedType -> LintedType -> LintedType
`mkMultMul` LintedType
var_w
    err_msg :: SDoc
err_msg  = (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Linearity failure in variable:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
bndr
                SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ Usage -> SDoc
forall a. Outputable a => a -> SDoc
ppr Usage
lhs SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"⊈" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
rhs
                SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Computed by:"
                SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"LHS:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
lhs_formula
                SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"RHS:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
rhs_formula)
    lhs_formula :: SDoc
lhs_formula = Usage -> SDoc
forall a. Outputable a => a -> SDoc
ppr Usage
bndr_usage SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"+"
                                 SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (Usage -> SDoc
forall a. Outputable a => a -> SDoc
ppr Usage
case_bndr_usage SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"*" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
var_w)
    rhs_formula :: SDoc
rhs_formula = LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
case_bndr_w SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"*" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
var_w
    case_bndr_w :: LintedType
case_bndr_w = Var -> LintedType
varMult Var
case_bndr
    case_bndr_usage :: Usage
case_bndr_usage = UsageEnv -> Var -> Usage
forall n. NamedThing n => UsageEnv -> n -> Usage
lookupUE UsageEnv
ue Var
case_bndr
    bndr_usage :: Usage
bndr_usage = UsageEnv -> Var -> Usage
forall n. NamedThing n => UsageEnv -> n -> Usage
lookupUE UsageEnv
ue Var
bndr
lintTyApp :: LintedType -> LintedType -> LintM LintedType
lintTyApp :: LintedType -> LintedType -> LintM LintedType
lintTyApp LintedType
fun_ty LintedType
arg_ty
  | Just (Var
tv,LintedType
body_ty) <- LintedType -> Maybe (Var, LintedType)
splitForAllTyCoVar_maybe LintedType
fun_ty
  = do  { Var -> LintedType -> LintM ()
lintTyKind Var
tv LintedType
arg_ty
        ; InScopeSet
in_scope <- LintM InScopeSet
getInScope
        
        
        
        ; LintedType -> LintM LintedType
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (InScopeSet -> [Var] -> [LintedType] -> LintedType -> LintedType
substTyWithInScope InScopeSet
in_scope [Var
tv] [LintedType
arg_ty] LintedType
body_ty) }
  | Bool
otherwise
  = SDoc -> LintM LintedType
forall a. SDoc -> LintM a
failWithL (LintedType -> LintedType -> SDoc
mkTyAppMsg LintedType
fun_ty LintedType
arg_ty)
lintValApp :: CoreExpr -> LintedType -> LintedType -> UsageEnv -> UsageEnv -> LintM (LintedType, UsageEnv)
lintValApp :: CoreExpr
-> LintedType
-> LintedType
-> UsageEnv
-> UsageEnv
-> LintM (LintedType, UsageEnv)
lintValApp CoreExpr
arg LintedType
fun_ty LintedType
arg_ty UsageEnv
fun_ue UsageEnv
arg_ue
  | Just (FunTyFlag
_, LintedType
w, LintedType
arg_ty', LintedType
res_ty') <- LintedType -> Maybe (FunTyFlag, LintedType, LintedType, LintedType)
splitFunTy_maybe LintedType
fun_ty
  = do { LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys LintedType
arg_ty' LintedType
arg_ty (LintedType -> LintedType -> CoreExpr -> SDoc
mkAppMsg LintedType
arg_ty' LintedType
arg_ty CoreExpr
arg)
       ; let app_ue :: UsageEnv
app_ue =  UsageEnv -> UsageEnv -> UsageEnv
addUE UsageEnv
fun_ue (LintedType -> UsageEnv -> UsageEnv
scaleUE LintedType
w UsageEnv
arg_ue)
       ; (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (LintedType
res_ty', UsageEnv
app_ue) }
  | Bool
otherwise
  = SDoc -> LintM (LintedType, UsageEnv)
forall a. SDoc -> LintM a
failWithL SDoc
err2
  where
    err2 :: SDoc
err2 = LintedType -> LintedType -> CoreExpr -> SDoc
mkNonFunAppMsg LintedType
fun_ty LintedType
arg_ty CoreExpr
arg
lintTyKind :: OutTyVar -> LintedType -> LintM ()
lintTyKind :: Var -> LintedType -> LintM ()
lintTyKind Var
tyvar LintedType
arg_ty
  = Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (LintedType
arg_kind LintedType -> LintedType -> Bool
`eqType` LintedType
tyvar_kind) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$
    SDoc -> LintM ()
addErrL (Var -> LintedType -> SDoc
mkKindErrMsg Var
tyvar LintedType
arg_ty SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Linted Arg kind:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
arg_kind))
  where
    tyvar_kind :: LintedType
tyvar_kind = Var -> LintedType
tyVarKind Var
tyvar
    arg_kind :: LintedType
arg_kind = HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
arg_ty
lintCaseExpr :: CoreExpr -> Id -> Type -> [CoreAlt] -> LintM (LintedType, UsageEnv)
lintCaseExpr :: CoreExpr
-> Var -> LintedType -> [Alt Var] -> LintM (LintedType, UsageEnv)
lintCaseExpr CoreExpr
scrut Var
var LintedType
alt_ty [Alt Var]
alts =
  do { let e :: CoreExpr
e = CoreExpr -> Var -> LintedType -> [Alt Var] -> CoreExpr
forall b. Expr b -> b -> LintedType -> [Alt b] -> Expr b
Case CoreExpr
scrut Var
var LintedType
alt_ty [Alt Var]
alts   
     
     ; (LintedType
scrut_ty, UsageEnv
scrut_ue) <- LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. LintM a -> LintM a
markAllJoinsBad (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$ CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
scrut
          
          
     ; let scrut_mult :: LintedType
scrut_mult = Var -> LintedType
varMult Var
var
     ; LintedType
alt_ty <- LintLocInfo -> LintM LintedType -> LintM LintedType
forall a. LintLocInfo -> LintM a -> LintM a
addLoc (CoreExpr -> LintLocInfo
CaseTy CoreExpr
scrut) (LintM LintedType -> LintM LintedType)
-> LintM LintedType -> LintM LintedType
forall a b. (a -> b) -> a -> b
$
                 LintedType -> LintM LintedType
lintValueType LintedType
alt_ty
     ; LintedType
var_ty <- LintLocInfo -> LintM LintedType -> LintM LintedType
forall a. LintLocInfo -> LintM a -> LintM a
addLoc (Var -> LintLocInfo
IdTy Var
var) (LintM LintedType -> LintM LintedType)
-> LintM LintedType -> LintM LintedType
forall a b. (a -> b) -> a -> b
$
                 LintedType -> LintM LintedType
lintValueType (Var -> LintedType
idType Var
var)
     
     
     
     
     
     
     
     ; let isLitPat :: Alt b -> Bool
isLitPat (Alt (LitAlt Literal
_) [b]
_  Expr b
_) = Bool
True
           isLitPat Alt b
_                     = Bool
False
     ; Bool -> SDoc -> LintM ()
checkL (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ LintedType -> Bool
isFloatingPrimTy LintedType
scrut_ty Bool -> Bool -> Bool
&& (Alt Var -> Bool) -> [Alt Var] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Alt Var -> Bool
forall {b}. Alt b -> Bool
isLitPat [Alt Var]
alts)
         (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Lint warning: Scrutinising floating-point expression with literal pattern in case analysis (see #9238)."
          SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"scrut" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
scrut)
     ; case LintedType -> Maybe TyCon
tyConAppTyCon_maybe (Var -> LintedType
idType Var
var) of
         Just TyCon
tycon
              | Bool
debugIsOn
              , TyCon -> Bool
isAlgTyCon TyCon
tycon
              , Bool -> Bool
not (TyCon -> Bool
isAbstractTyCon TyCon
tycon)
              , [DataCon] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (TyCon -> [DataCon]
tyConDataCons TyCon
tycon)
              , Bool -> Bool
not (CoreExpr -> Bool
exprIsDeadEnd CoreExpr
scrut)
              -> String -> SDoc -> LintM () -> LintM ()
forall a. String -> SDoc -> a -> a
pprTrace String
"Lint warning: case binder's type has no constructors" (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
var SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> LintedType
idType Var
var))
                        
                      (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$ () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
         Maybe TyCon
_otherwise -> () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
        
     ; Subst
subst <- LintM Subst
getSubst
     ; LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys LintedType
var_ty LintedType
scrut_ty (Var -> LintedType -> LintedType -> Subst -> SDoc
mkScrutMsg Var
var LintedType
var_ty LintedType
scrut_ty Subst
subst)
       
     ; BindingSite
-> Var
-> (Var -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv)
forall a. BindingSite -> Var -> (Var -> LintM a) -> LintM a
lintBinder BindingSite
CaseBind Var
var ((Var -> LintM (LintedType, UsageEnv))
 -> LintM (LintedType, UsageEnv))
-> (Var -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$ \Var
_ ->
       do { 
          ; [UsageEnv]
alt_ues <- (Alt Var -> LintM UsageEnv) -> [Alt Var] -> LintM [UsageEnv]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Var
-> LintedType
-> LintedType
-> LintedType
-> Alt Var
-> LintM UsageEnv
lintCoreAlt Var
var LintedType
scrut_ty LintedType
scrut_mult LintedType
alt_ty) [Alt Var]
alts
          ; let case_ue :: UsageEnv
case_ue = (LintedType -> UsageEnv -> UsageEnv
scaleUE LintedType
scrut_mult UsageEnv
scrut_ue) UsageEnv -> UsageEnv -> UsageEnv
`addUE` [UsageEnv] -> UsageEnv
supUEs [UsageEnv]
alt_ues
          ; CoreExpr -> LintedType -> [Alt Var] -> LintM ()
checkCaseAlts CoreExpr
e LintedType
scrut_ty [Alt Var]
alts
          ; (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (LintedType
alt_ty, UsageEnv
case_ue) } }
checkCaseAlts :: CoreExpr -> LintedType -> [CoreAlt] -> LintM ()
checkCaseAlts :: CoreExpr -> LintedType -> [Alt Var] -> LintM ()
checkCaseAlts CoreExpr
e LintedType
ty [Alt Var]
alts =
  do { Bool -> SDoc -> LintM ()
checkL ((Alt Var -> Bool) -> [Alt Var] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Alt Var -> Bool
forall {b}. Alt b -> Bool
non_deflt [Alt Var]
con_alts) (CoreExpr -> SDoc
mkNonDefltMsg CoreExpr
e)
         
     ; Bool -> SDoc -> LintM ()
checkL ([Alt Var] -> Bool
forall {a}. [Alt a] -> Bool
increasing_tag [Alt Var]
con_alts) (CoreExpr -> SDoc
mkNonIncreasingAltsMsg CoreExpr
e)
         
          
          
          
          
          
          
          
          
     ; Bool -> SDoc -> LintM ()
checkL (Maybe CoreExpr -> Bool
forall a. Maybe a -> Bool
isJust Maybe CoreExpr
maybe_deflt Bool -> Bool -> Bool
|| Bool -> Bool
not Bool
is_infinite_ty Bool -> Bool -> Bool
|| [Alt Var] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Alt Var]
alts)
              (CoreExpr -> SDoc
nonExhaustiveAltsMsg CoreExpr
e) }
  where
    ([Alt Var]
con_alts, Maybe CoreExpr
maybe_deflt) = [Alt Var] -> ([Alt Var], Maybe CoreExpr)
forall b. [Alt b] -> ([Alt b], Maybe (Expr b))
findDefault [Alt Var]
alts
        
    increasing_tag :: [Alt a] -> Bool
increasing_tag (Alt a
alt1 : rest :: [Alt a]
rest@( Alt a
alt2 : [Alt a]
_)) = Alt a
alt1 Alt a -> Alt a -> Bool
forall a. Alt a -> Alt a -> Bool
`ltAlt` Alt a
alt2 Bool -> Bool -> Bool
&& [Alt a] -> Bool
increasing_tag [Alt a]
rest
    increasing_tag [Alt a]
_                         = Bool
True
    non_deflt :: Alt b -> Bool
non_deflt (Alt AltCon
DEFAULT [b]
_ Expr b
_) = Bool
False
    non_deflt Alt b
_                 = Bool
True
    is_infinite_ty :: Bool
is_infinite_ty = case LintedType -> Maybe TyCon
tyConAppTyCon_maybe LintedType
ty of
                        Maybe TyCon
Nothing    -> Bool
False
                        Just TyCon
tycon -> TyCon -> Bool
isPrimTyCon TyCon
tycon
lintAltExpr :: CoreExpr -> LintedType -> LintM UsageEnv
lintAltExpr :: CoreExpr -> LintedType -> LintM UsageEnv
lintAltExpr CoreExpr
expr LintedType
ann_ty
  = do { (LintedType
actual_ty, UsageEnv
ue) <- CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
expr
       ; LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys LintedType
actual_ty LintedType
ann_ty (CoreExpr -> LintedType -> LintedType -> SDoc
mkCaseAltMsg CoreExpr
expr LintedType
actual_ty LintedType
ann_ty)
       ; UsageEnv -> LintM UsageEnv
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return UsageEnv
ue }
         
lintCoreAlt :: Var              
            -> LintedType       
            -> Mult             
            -> LintedType       
            -> CoreAlt
            -> LintM UsageEnv
lintCoreAlt :: Var
-> LintedType
-> LintedType
-> LintedType
-> Alt Var
-> LintM UsageEnv
lintCoreAlt Var
case_bndr LintedType
_ LintedType
scrut_mult LintedType
alt_ty (Alt AltCon
DEFAULT [Var]
args CoreExpr
rhs) =
  do { Bool -> SDoc -> LintM ()
lintL ([Var] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Var]
args) ([Var] -> SDoc
mkDefaultArgsMsg [Var]
args)
     ; UsageEnv
rhs_ue <- CoreExpr -> LintedType -> LintM UsageEnv
lintAltExpr CoreExpr
rhs LintedType
alt_ty
     ; let (Usage
case_bndr_usage, UsageEnv
rhs_ue') = UsageEnv -> Var -> (Usage, UsageEnv)
forall n. NamedThing n => UsageEnv -> n -> (Usage, UsageEnv)
popUE UsageEnv
rhs_ue Var
case_bndr
           err_msg :: SDoc
err_msg = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Linearity failure in the DEFAULT clause:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
case_bndr
                     SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ Usage -> SDoc
forall a. Outputable a => a -> SDoc
ppr Usage
case_bndr_usage SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"⊈" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
scrut_mult
     ; Usage -> LintedType -> SDoc -> LintM ()
ensureSubUsage Usage
case_bndr_usage LintedType
scrut_mult SDoc
err_msg
     ; UsageEnv -> LintM UsageEnv
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return UsageEnv
rhs_ue' }
lintCoreAlt Var
case_bndr LintedType
scrut_ty LintedType
_ LintedType
alt_ty (Alt (LitAlt Literal
lit) [Var]
args CoreExpr
rhs)
  | Literal -> Bool
litIsLifted Literal
lit
  = SDoc -> LintM UsageEnv
forall a. SDoc -> LintM a
failWithL SDoc
integerScrutinisedMsg
  | Bool
otherwise
  = do { Bool -> SDoc -> LintM ()
lintL ([Var] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Var]
args) ([Var] -> SDoc
mkDefaultArgsMsg [Var]
args)
       ; LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys LintedType
lit_ty LintedType
scrut_ty (LintedType -> LintedType -> SDoc
mkBadPatMsg LintedType
lit_ty LintedType
scrut_ty)
       ; UsageEnv
rhs_ue <- CoreExpr -> LintedType -> LintM UsageEnv
lintAltExpr CoreExpr
rhs LintedType
alt_ty
       ; UsageEnv -> LintM UsageEnv
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (UsageEnv -> Var -> UsageEnv
forall n. NamedThing n => UsageEnv -> n -> UsageEnv
deleteUE UsageEnv
rhs_ue Var
case_bndr) 
       }
  where
    lit_ty :: LintedType
lit_ty = Literal -> LintedType
literalType Literal
lit
lintCoreAlt Var
case_bndr LintedType
scrut_ty LintedType
_scrut_mult LintedType
alt_ty alt :: Alt Var
alt@(Alt (DataAlt DataCon
con) [Var]
args CoreExpr
rhs)
  | TyCon -> Bool
isNewTyCon (DataCon -> TyCon
dataConTyCon DataCon
con)
  = UsageEnv
zeroUE UsageEnv -> LintM () -> LintM UsageEnv
forall a b. a -> LintM b -> LintM a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ SDoc -> LintM ()
addErrL (LintedType -> Alt Var -> SDoc
mkNewTyDataConAltMsg LintedType
scrut_ty Alt Var
alt)
  | Just (TyCon
tycon, [LintedType]
tycon_arg_tys) <- HasDebugCallStack => LintedType -> Maybe (TyCon, [LintedType])
LintedType -> Maybe (TyCon, [LintedType])
splitTyConApp_maybe LintedType
scrut_ty
  = LintLocInfo -> LintM UsageEnv -> LintM UsageEnv
forall a. LintLocInfo -> LintM a -> LintM a
addLoc (Alt Var -> LintLocInfo
CaseAlt Alt Var
alt) (LintM UsageEnv -> LintM UsageEnv)
-> LintM UsageEnv -> LintM UsageEnv
forall a b. (a -> b) -> a -> b
$  do
    { String -> DataCon -> LintM ()
checkTypeDataConOcc String
"pattern" DataCon
con
    ; Bool -> SDoc -> LintM ()
lintL (TyCon
tycon TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== DataCon -> TyCon
dataConTyCon DataCon
con) (TyCon -> DataCon -> SDoc
mkBadConMsg TyCon
tycon DataCon
con)
      
      
    ; let { con_payload_ty :: LintedType
con_payload_ty = HasDebugCallStack => LintedType -> [LintedType] -> LintedType
LintedType -> [LintedType] -> LintedType
piResultTys (DataCon -> LintedType
dataConRepType DataCon
con) [LintedType]
tycon_arg_tys
          ; binderMult :: PiTyBinder -> LintedType
binderMult (Named ForAllTyBinder
_)   = LintedType
ManyTy
          ; binderMult (Anon Scaled LintedType
st FunTyFlag
_) = Scaled LintedType -> LintedType
forall a. Scaled a -> LintedType
scaledMult Scaled LintedType
st
          
          ; multiplicities :: [LintedType]
multiplicities = (PiTyBinder -> LintedType) -> [PiTyBinder] -> [LintedType]
forall a b. (a -> b) -> [a] -> [b]
map PiTyBinder -> LintedType
binderMult ([PiTyBinder] -> [LintedType]) -> [PiTyBinder] -> [LintedType]
forall a b. (a -> b) -> a -> b
$ ([PiTyBinder], LintedType) -> [PiTyBinder]
forall a b. (a, b) -> a
fst (([PiTyBinder], LintedType) -> [PiTyBinder])
-> ([PiTyBinder], LintedType) -> [PiTyBinder]
forall a b. (a -> b) -> a -> b
$ LintedType -> ([PiTyBinder], LintedType)
splitPiTys LintedType
con_payload_ty }
        
    ; BindingSite -> [Var] -> ([Var] -> LintM UsageEnv) -> LintM UsageEnv
forall a. BindingSite -> [Var] -> ([Var] -> LintM a) -> LintM a
lintBinders BindingSite
CasePatBind [Var]
args (([Var] -> LintM UsageEnv) -> LintM UsageEnv)
-> ([Var] -> LintM UsageEnv) -> LintM UsageEnv
forall a b. (a -> b) -> a -> b
$ \ [Var]
args' -> do
      {
        UsageEnv
rhs_ue <- CoreExpr -> LintedType -> LintM UsageEnv
lintAltExpr CoreExpr
rhs LintedType
alt_ty
      ; UsageEnv
rhs_ue' <- LintLocInfo -> LintM UsageEnv -> LintM UsageEnv
forall a. LintLocInfo -> LintM a -> LintM a
addLoc (Alt Var -> LintLocInfo
CasePat Alt Var
alt) (UsageEnv
-> Var
-> LintedType
-> LintedType
-> [(LintedType, Var)]
-> LintM UsageEnv
lintAltBinders UsageEnv
rhs_ue Var
case_bndr LintedType
scrut_ty LintedType
con_payload_ty (String -> [LintedType] -> [Var] -> [(LintedType, Var)]
forall a b. HasDebugCallStack => String -> [a] -> [b] -> [(a, b)]
zipEqual String
"lintCoreAlt" [LintedType]
multiplicities  [Var]
args'))
      ; UsageEnv -> LintM UsageEnv
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (UsageEnv -> LintM UsageEnv) -> UsageEnv -> LintM UsageEnv
forall a b. (a -> b) -> a -> b
$ UsageEnv -> Var -> UsageEnv
forall n. NamedThing n => UsageEnv -> n -> UsageEnv
deleteUE UsageEnv
rhs_ue' Var
case_bndr
      }
   }
  | Bool
otherwise   
  = UsageEnv
zeroUE UsageEnv -> LintM () -> LintM UsageEnv
forall a b. a -> LintM b -> LintM a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ SDoc -> LintM ()
addErrL (LintedType -> Alt Var -> SDoc
mkBadAltMsg LintedType
scrut_ty Alt Var
alt)
lintLinearBinder :: SDoc -> Mult -> Mult -> LintM ()
lintLinearBinder :: SDoc -> LintedType -> LintedType -> LintM ()
lintLinearBinder SDoc
doc LintedType
actual_usage LintedType
described_usage
  = LintedType -> LintedType -> SDoc -> LintM ()
ensureSubMult LintedType
actual_usage LintedType
described_usage SDoc
err_msg
    where
      err_msg :: SDoc
err_msg = (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Multiplicity of variable does not agree with its context"
                SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ SDoc
doc
                SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
actual_usage
                SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Annotation:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
described_usage)
lintBinders :: BindingSite -> [Var] -> ([Var] -> LintM a) -> LintM a
lintBinders :: forall a. BindingSite -> [Var] -> ([Var] -> LintM a) -> LintM a
lintBinders BindingSite
_    []         [Var] -> LintM a
linterF = [Var] -> LintM a
linterF []
lintBinders BindingSite
site (Var
var:[Var]
vars) [Var] -> LintM a
linterF = BindingSite -> Var -> (Var -> LintM a) -> LintM a
forall a. BindingSite -> Var -> (Var -> LintM a) -> LintM a
lintBinder BindingSite
site Var
var ((Var -> LintM a) -> LintM a) -> (Var -> LintM a) -> LintM a
forall a b. (a -> b) -> a -> b
$ \Var
var' ->
                                      BindingSite -> [Var] -> ([Var] -> LintM a) -> LintM a
forall a. BindingSite -> [Var] -> ([Var] -> LintM a) -> LintM a
lintBinders BindingSite
site [Var]
vars (([Var] -> LintM a) -> LintM a) -> ([Var] -> LintM a) -> LintM a
forall a b. (a -> b) -> a -> b
$ \ [Var]
vars' ->
                                      [Var] -> LintM a
linterF (Var
var'Var -> [Var] -> [Var]
forall a. a -> [a] -> [a]
:[Var]
vars')
lintBinder :: BindingSite -> Var -> (Var -> LintM a) -> LintM a
lintBinder :: forall a. BindingSite -> Var -> (Var -> LintM a) -> LintM a
lintBinder BindingSite
site Var
var Var -> LintM a
linterF
  | Var -> Bool
isTyCoVar Var
var = Var -> (Var -> LintM a) -> LintM a
forall a. Var -> (Var -> LintM a) -> LintM a
lintTyCoBndr Var
var Var -> LintM a
linterF
  | Bool
otherwise     = TopLevelFlag -> BindingSite -> Var -> (Var -> LintM a) -> LintM a
forall a.
TopLevelFlag -> BindingSite -> Var -> (Var -> LintM a) -> LintM a
lintIdBndr TopLevelFlag
NotTopLevel BindingSite
site Var
var Var -> LintM a
linterF
lintTyBndr :: TyVar -> (LintedTyCoVar -> LintM a) -> LintM a
lintTyBndr :: forall a. Var -> (Var -> LintM a) -> LintM a
lintTyBndr = Var -> (Var -> LintM a) -> LintM a
forall a. Var -> (Var -> LintM a) -> LintM a
lintTyCoBndr  
lintTyCoBndr :: TyCoVar -> (LintedTyCoVar -> LintM a) -> LintM a
lintTyCoBndr :: forall a. Var -> (Var -> LintM a) -> LintM a
lintTyCoBndr Var
tcv Var -> LintM a
thing_inside
  = do { Subst
subst <- LintM Subst
getSubst
       ; LintedType
tcv_type' <- LintedType -> LintM LintedType
lintType (Var -> LintedType
varType Var
tcv)
       ; let tcv' :: Var
tcv' = InScopeSet -> Var -> Var
uniqAway (Subst -> InScopeSet
getSubstInScope Subst
subst) (Var -> Var) -> Var -> Var
forall a b. (a -> b) -> a -> b
$
                    Var -> LintedType -> Var
setVarType Var
tcv LintedType
tcv_type'
             subst' :: Subst
subst' = Subst -> Var -> Var -> Subst
extendTCvSubstWithClone Subst
subst Var
tcv Var
tcv'
       
       ; if (Var -> Bool
isTyVar Var
tcv)
         then 
              Bool -> SDoc -> LintM ()
lintL (LintedType -> Bool
isLiftedTypeKind (HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
tcv_type')) (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
              SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"TyVar whose kind does not have kind Type:")
                 JoinArity
2 (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
tcv' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
tcv_type' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
tcv_type'))
         else 
              
              Bool -> SDoc -> LintM ()
lintL (LintedType -> Bool
isCoVarType LintedType
tcv_type') (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
              String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"CoVar with non-coercion type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
pprTyVar Var
tcv
       ; Subst -> LintM a -> LintM a
forall a. Subst -> LintM a -> LintM a
updateSubst Subst
subst' (Var -> LintM a
thing_inside Var
tcv') }
lintIdBndrs :: forall a. TopLevelFlag -> [Id] -> ([LintedId] -> LintM a) -> LintM a
lintIdBndrs :: forall a. TopLevelFlag -> [Var] -> ([Var] -> LintM a) -> LintM a
lintIdBndrs TopLevelFlag
top_lvl [Var]
ids [Var] -> LintM a
thing_inside
  = [Var] -> ([Var] -> LintM a) -> LintM a
go [Var]
ids [Var] -> LintM a
thing_inside
  where
    go :: [Id] -> ([Id] -> LintM a) -> LintM a
    go :: [Var] -> ([Var] -> LintM a) -> LintM a
go []       [Var] -> LintM a
thing_inside = [Var] -> LintM a
thing_inside []
    go (Var
id:[Var]
ids) [Var] -> LintM a
thing_inside = TopLevelFlag -> BindingSite -> Var -> (Var -> LintM a) -> LintM a
forall a.
TopLevelFlag -> BindingSite -> Var -> (Var -> LintM a) -> LintM a
lintIdBndr TopLevelFlag
top_lvl BindingSite
LetBind Var
id  ((Var -> LintM a) -> LintM a) -> (Var -> LintM a) -> LintM a
forall a b. (a -> b) -> a -> b
$ \Var
id' ->
                               [Var] -> ([Var] -> LintM a) -> LintM a
go [Var]
ids                         (([Var] -> LintM a) -> LintM a) -> ([Var] -> LintM a) -> LintM a
forall a b. (a -> b) -> a -> b
$ \[Var]
ids' ->
                               [Var] -> LintM a
thing_inside (Var
id' Var -> [Var] -> [Var]
forall a. a -> [a] -> [a]
: [Var]
ids')
lintIdBndr :: TopLevelFlag -> BindingSite
           -> InVar -> (OutVar -> LintM a) -> LintM a
lintIdBndr :: forall a.
TopLevelFlag -> BindingSite -> Var -> (Var -> LintM a) -> LintM a
lintIdBndr TopLevelFlag
top_lvl BindingSite
bind_site Var
id Var -> LintM a
thing_inside
  = Bool -> SDoc -> LintM a -> LintM a
forall a. HasCallStack => Bool -> SDoc -> a -> a
assertPpr (Var -> Bool
isId Var
id) (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
id) (LintM a -> LintM a) -> LintM a -> LintM a
forall a b. (a -> b) -> a -> b
$
    do { LintFlags
flags <- LintM LintFlags
getLintFlags
       ; Bool -> SDoc -> LintM ()
checkL (Bool -> Bool
not (LintFlags -> Bool
lf_check_global_ids LintFlags
flags) Bool -> Bool -> Bool
|| Var -> Bool
isLocalId Var
id)
                (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Non-local Id binder" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
id)
                
       
       ; Bool -> SDoc -> LintM ()
checkL (Bool -> Bool
not (Var -> Bool
isExportedId Var
id) Bool -> Bool -> Bool
|| Bool
is_top_lvl)
           (Var -> SDoc
mkNonTopExportedMsg Var
id)
       
       ; Bool -> SDoc -> LintM ()
checkL (Bool -> Bool
not (Name -> Bool
isExternalName (Var -> Name
Var.varName Var
id)) Bool -> Bool -> Bool
|| Bool
is_top_lvl)
           (Var -> SDoc
mkNonTopExternalNameMsg Var
id)
          
       ; Bool -> SDoc -> LintM ()
lintL (Var -> Bool
isJoinId Var
id Bool -> Bool -> Bool
|| Bool -> Bool
not (LintFlags -> Bool
lf_check_fixed_rep LintFlags
flags)
                Bool -> Bool -> Bool
|| HasDebugCallStack => LintedType -> Bool
LintedType -> Bool
typeHasFixedRuntimeRep LintedType
id_ty) (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
         String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Binder does not have a fixed runtime representation:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
id SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+>
            SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
id_ty SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
id_ty))
       
       ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Var -> Bool
isJoinId Var
id) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$
         Bool -> SDoc -> LintM ()
checkL (Bool -> Bool
not Bool
is_top_lvl Bool -> Bool -> Bool
&& Bool
is_let_bind) (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
         Var -> SDoc
mkBadJoinBindMsg Var
id
       
       
       ; Bool -> SDoc -> LintM ()
lintL (Bool -> Bool
not (LintedType -> Bool
isCoVarType LintedType
id_ty))
               (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Non-CoVar has coercion type" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
id SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
id_ty)
       
       
       ; Bool -> SDoc -> LintM ()
lintL (Bool -> Bool
not (BindingSite
bind_site BindingSite -> BindingSite -> Bool
forall a. Eq a => a -> a -> Bool
== BindingSite
LambdaBind Bool -> Bool -> Bool
&& Unfolding -> Bool
isEvaldUnfolding (Var -> Unfolding
idUnfolding Var
id)))
                (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Lambda binder with value or OtherCon unfolding.")
       ; LintedType
linted_ty <- LintLocInfo -> LintM LintedType -> LintM LintedType
forall a. LintLocInfo -> LintM a -> LintM a
addLoc (Var -> LintLocInfo
IdTy Var
id) (LintedType -> LintM LintedType
lintValueType LintedType
id_ty)
       ; Var -> LintedType -> LintM a -> LintM a
forall a. Var -> LintedType -> LintM a -> LintM a
addInScopeId Var
id LintedType
linted_ty (LintM a -> LintM a) -> LintM a -> LintM a
forall a b. (a -> b) -> a -> b
$
         Var -> LintM a
thing_inside (Var -> LintedType -> Var
setIdType Var
id LintedType
linted_ty) }
  where
    id_ty :: LintedType
id_ty = Var -> LintedType
idType Var
id
    is_top_lvl :: Bool
is_top_lvl = TopLevelFlag -> Bool
isTopLevel TopLevelFlag
top_lvl
    is_let_bind :: Bool
is_let_bind = case BindingSite
bind_site of
                    BindingSite
LetBind -> Bool
True
                    BindingSite
_       -> Bool
False
lintValueType :: Type -> LintM LintedType
lintValueType :: LintedType -> LintM LintedType
lintValueType LintedType
ty
  = LintLocInfo -> LintM LintedType -> LintM LintedType
forall a. LintLocInfo -> LintM a -> LintM a
addLoc (LintedType -> LintLocInfo
InType LintedType
ty) (LintM LintedType -> LintM LintedType)
-> LintM LintedType -> LintM LintedType
forall a b. (a -> b) -> a -> b
$
    do  { LintedType
ty' <- LintedType -> LintM LintedType
lintType LintedType
ty
        ; let sk :: LintedType
sk = HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
ty'
        ; Bool -> SDoc -> LintM ()
lintL (LintedType -> Bool
isTYPEorCONSTRAINT LintedType
sk) (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
          SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Ill-kinded type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty)
             JoinArity
2 (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"has kind:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
sk)
        ; LintedType -> LintM LintedType
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return LintedType
ty' }
checkTyCon :: TyCon -> LintM ()
checkTyCon :: TyCon -> LintM ()
checkTyCon TyCon
tc
  = Bool -> SDoc -> LintM ()
checkL (Bool -> Bool
not (TyCon -> Bool
isTcTyCon TyCon
tc)) (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Found TcTyCon:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc)
lintType :: Type -> LintM LintedType
lintType :: LintedType -> LintM LintedType
lintType (TyVarTy Var
tv)
  | Bool -> Bool
not (Var -> Bool
isTyVar Var
tv)
  = SDoc -> LintM LintedType
forall a. SDoc -> LintM a
failWithL (Var -> SDoc
mkBadTyVarMsg Var
tv)
  | Bool
otherwise
  = do { Subst
subst <- LintM Subst
getSubst
       ; case Subst -> Var -> Maybe LintedType
lookupTyVar Subst
subst Var
tv of
           Just LintedType
linted_ty -> LintedType -> LintM LintedType
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return LintedType
linted_ty
           
           
           
           Maybe LintedType
Nothing | Var
tv Var -> Subst -> Bool
`isInScope` Subst
subst
                   -> LintedType -> LintM LintedType
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Var -> LintedType
TyVarTy Var
tv)
                   | Bool
otherwise
                   -> SDoc -> LintM LintedType
forall a. SDoc -> LintM a
failWithL (SDoc -> LintM LintedType) -> SDoc -> LintM LintedType
forall a b. (a -> b) -> a -> b
$
                      SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"The type variable" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> BindingSite -> Var -> SDoc
forall a. OutputableBndr a => BindingSite -> a -> SDoc
pprBndr BindingSite
LetBind Var
tv)
                         JoinArity
2 (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"is out of scope")
     }
lintType ty :: LintedType
ty@(AppTy LintedType
t1 LintedType
t2)
  | TyConApp {} <- LintedType
t1
  = SDoc -> LintM LintedType
forall a. SDoc -> LintM a
failWithL (SDoc -> LintM LintedType) -> SDoc -> LintM LintedType
forall a b. (a -> b) -> a -> b
$ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"TyConApp to the left of AppTy:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty
  | Bool
otherwise
  = do { LintedType
t1' <- LintedType -> LintM LintedType
lintType LintedType
t1
       ; LintedType
t2' <- LintedType -> LintM LintedType
lintType LintedType
t2
       ; LintedType -> LintedType -> [LintedType] -> LintM ()
lint_ty_app LintedType
ty (HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
t1') [LintedType
t2']
       ; LintedType -> LintM LintedType
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (LintedType -> LintedType -> LintedType
AppTy LintedType
t1' LintedType
t2') }
lintType ty :: LintedType
ty@(TyConApp TyCon
tc [LintedType]
tys)
  | TyCon -> Bool
isTypeSynonymTyCon TyCon
tc Bool -> Bool -> Bool
|| TyCon -> Bool
isTypeFamilyTyCon TyCon
tc
  = do { Bool
report_unsat <- LintFlags -> Bool
lf_report_unsat_syns (LintFlags -> Bool) -> LintM LintFlags -> LintM Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LintM LintFlags
getLintFlags
       ; Bool -> LintedType -> TyCon -> [LintedType] -> LintM LintedType
lintTySynFamApp Bool
report_unsat LintedType
ty TyCon
tc [LintedType]
tys }
  | Just {} <- HasDebugCallStack => TyCon -> [LintedType] -> Maybe LintedType
TyCon -> [LintedType] -> Maybe LintedType
tyConAppFunTy_maybe TyCon
tc [LintedType]
tys
    
    
    
  = SDoc -> LintM LintedType
forall a. SDoc -> LintM a
failWithL (SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Saturated application of" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
quotes (TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc)) JoinArity
2 (LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty))
  | Bool
otherwise  
  = do { TyCon -> LintM ()
checkTyCon TyCon
tc
       ; [LintedType]
tys' <- (LintedType -> LintM LintedType)
-> [LintedType] -> LintM [LintedType]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM LintedType -> LintM LintedType
lintType [LintedType]
tys
       ; LintedType -> LintedType -> [LintedType] -> LintM ()
lint_ty_app LintedType
ty (TyCon -> LintedType
tyConKind TyCon
tc) [LintedType]
tys'
       ; LintedType -> LintM LintedType
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (TyCon -> [LintedType] -> LintedType
TyConApp TyCon
tc [LintedType]
tys') }
lintType ty :: LintedType
ty@(FunTy FunTyFlag
af LintedType
tw LintedType
t1 LintedType
t2)
  = do { LintedType
t1' <- LintedType -> LintM LintedType
lintType LintedType
t1
       ; LintedType
t2' <- LintedType -> LintM LintedType
lintType LintedType
t2
       ; LintedType
tw' <- LintedType -> LintM LintedType
lintType LintedType
tw
       ; SDoc -> LintedType -> LintedType -> LintedType -> LintM ()
lintArrow (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"type or kind" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
quotes (LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty)) LintedType
t1' LintedType
t2' LintedType
tw'
       ; let real_af :: FunTyFlag
real_af = HasDebugCallStack => LintedType -> LintedType -> FunTyFlag
LintedType -> LintedType -> FunTyFlag
chooseFunTyFlag LintedType
t1 LintedType
t2
       ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (FunTyFlag
real_af FunTyFlag -> FunTyFlag -> Bool
forall a. Eq a => a -> a -> Bool
== FunTyFlag
af) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$ SDoc -> LintM ()
addErrL (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
         SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Bad FunTyFlag in FunTy")
            JoinArity
2 ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty
                    , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"FunTyFlag =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> FunTyFlag -> SDoc
forall a. Outputable a => a -> SDoc
ppr FunTyFlag
af
                    , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Computed FunTyFlag =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> FunTyFlag -> SDoc
forall a. Outputable a => a -> SDoc
ppr FunTyFlag
real_af ])
       ; LintedType -> LintM LintedType
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (FunTyFlag -> LintedType -> LintedType -> LintedType -> LintedType
FunTy FunTyFlag
af LintedType
tw' LintedType
t1' LintedType
t2') }
lintType ty :: LintedType
ty@(ForAllTy (Bndr Var
tcv ForAllTyFlag
vis) LintedType
body_ty)
  | Bool -> Bool
not (Var -> Bool
isTyCoVar Var
tcv)
  = SDoc -> LintM LintedType
forall a. SDoc -> LintM a
failWithL (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Non-Tyvar or Non-Covar bound in type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty)
  | Bool
otherwise
  = Var -> (Var -> LintM LintedType) -> LintM LintedType
forall a. Var -> (Var -> LintM a) -> LintM a
lintTyCoBndr Var
tcv ((Var -> LintM LintedType) -> LintM LintedType)
-> (Var -> LintM LintedType) -> LintM LintedType
forall a b. (a -> b) -> a -> b
$ \Var
tcv' ->
    do { LintedType
body_ty' <- LintedType -> LintM LintedType
lintType LintedType
body_ty
       ; Var -> LintedType -> LintM ()
lintForAllBody Var
tcv' LintedType
body_ty'
       ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Var -> Bool
isCoVar Var
tcv) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$
         Bool -> SDoc -> LintM ()
lintL (Var
tcv Var -> IdSet -> Bool
`elemVarSet` LintedType -> IdSet
tyCoVarsOfType LintedType
body_ty) (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
         String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Covar does not occur in the body:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
tcv SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
body_ty)
         
         
       ; LintedType -> LintM LintedType
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (ForAllTyBinder -> LintedType -> LintedType
ForAllTy (Var -> ForAllTyFlag -> ForAllTyBinder
forall var argf. var -> argf -> VarBndr var argf
Bndr Var
tcv' ForAllTyFlag
vis) LintedType
body_ty') }
lintType ty :: LintedType
ty@(LitTy TyLit
l)
  = do { TyLit -> LintM ()
lintTyLit TyLit
l; LintedType -> LintM LintedType
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return LintedType
ty }
lintType (CastTy LintedType
ty Coercion
co)
  = do { LintedType
ty' <- LintedType -> LintM LintedType
lintType LintedType
ty
       ; Coercion
co' <- Coercion -> LintM Coercion
lintStarCoercion Coercion
co
       ; let tyk :: LintedType
tyk = HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
ty'
             cok :: LintedType
cok = Coercion -> LintedType
coercionLKind Coercion
co'
       ; LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys LintedType
tyk LintedType
cok (LintedType -> Coercion -> LintedType -> LintedType -> SDoc
mkCastTyErr LintedType
ty Coercion
co LintedType
tyk LintedType
cok)
       ; LintedType -> LintM LintedType
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (LintedType -> Coercion -> LintedType
CastTy LintedType
ty' Coercion
co') }
lintType (CoercionTy Coercion
co)
  = do { Coercion
co' <- Coercion -> LintM Coercion
lintCoercion Coercion
co
       ; LintedType -> LintM LintedType
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Coercion -> LintedType
CoercionTy Coercion
co') }
lintForAllBody :: LintedTyCoVar -> LintedType -> LintM ()
lintForAllBody :: Var -> LintedType -> LintM ()
lintForAllBody Var
tcv LintedType
body_ty
  = do { LintedType -> SDoc -> LintM ()
checkValueType LintedType
body_ty (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"the body of forall:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
body_ty)
         
         
         
         
       ; let body_kind :: LintedType
body_kind = HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
body_ty
       ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Var -> Bool
isTyVar Var
tcv) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$
         case [Var] -> LintedType -> Maybe LintedType
occCheckExpand [Var
tcv] LintedType
body_kind of
           Just {} -> () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
           Maybe LintedType
Nothing -> SDoc -> LintM ()
forall a. SDoc -> LintM a
failWithL (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
                      SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Variable escape in forall:")
                         JoinArity
2 ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"tyvar:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
tcv
                                 , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
body_ty
                                 , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"kind:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
body_kind ])
    }
lintTySynFamApp :: Bool -> InType -> TyCon -> [InType] -> LintM LintedType
lintTySynFamApp :: Bool -> LintedType -> TyCon -> [LintedType] -> LintM LintedType
lintTySynFamApp Bool
report_unsat LintedType
ty TyCon
tc [LintedType]
tys
  | Bool
report_unsat   
  , [LintedType]
tys [LintedType] -> JoinArity -> Bool
forall a. [a] -> JoinArity -> Bool
`lengthLessThan` TyCon -> JoinArity
tyConArity TyCon
tc
  = SDoc -> LintM LintedType
forall a. SDoc -> LintM a
failWithL (SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Un-saturated type application") JoinArity
2 (LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty))
  
  | ExpandsSyn [(Var, LintedType)]
tenv LintedType
rhs [LintedType]
tys' <- TyCon -> [LintedType] -> ExpandSynResult LintedType
forall tyco. TyCon -> [tyco] -> ExpandSynResult tyco
expandSynTyCon_maybe TyCon
tc [LintedType]
tys
  , let expanded_ty :: LintedType
expanded_ty = LintedType -> [LintedType] -> LintedType
mkAppTys (HasDebugCallStack => Subst -> LintedType -> LintedType
Subst -> LintedType -> LintedType
substTy ([(Var, LintedType)] -> Subst
mkTvSubstPrs [(Var, LintedType)]
tenv) LintedType
rhs) [LintedType]
tys'
  = do { 
         
         [LintedType]
tys' <- Bool -> LintM [LintedType] -> LintM [LintedType]
forall a. Bool -> LintM a -> LintM a
setReportUnsat Bool
False ((LintedType -> LintM LintedType)
-> [LintedType] -> LintM [LintedType]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM LintedType -> LintM LintedType
lintType [LintedType]
tys)
       ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
report_unsat (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$
         do { LintedType
_ <- LintedType -> LintM LintedType
lintType LintedType
expanded_ty
            ; () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return () }
       ; LintedType -> LintedType -> [LintedType] -> LintM ()
lint_ty_app LintedType
ty (TyCon -> LintedType
tyConKind TyCon
tc) [LintedType]
tys'
       ; LintedType -> LintM LintedType
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (TyCon -> [LintedType] -> LintedType
TyConApp TyCon
tc [LintedType]
tys') }
  
  | Bool
otherwise
  = do { [LintedType]
tys' <- (LintedType -> LintM LintedType)
-> [LintedType] -> LintM [LintedType]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM LintedType -> LintM LintedType
lintType [LintedType]
tys
       ; LintedType -> LintedType -> [LintedType] -> LintM ()
lint_ty_app LintedType
ty (TyCon -> LintedType
tyConKind TyCon
tc) [LintedType]
tys'
       ; LintedType -> LintM LintedType
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (TyCon -> [LintedType] -> LintedType
TyConApp TyCon
tc [LintedType]
tys') }
checkValueType :: LintedType -> SDoc -> LintM ()
checkValueType :: LintedType -> SDoc -> LintM ()
checkValueType LintedType
ty SDoc
doc
  = Bool -> SDoc -> LintM ()
lintL (LintedType -> Bool
isTYPEorCONSTRAINT LintedType
kind)
          (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Non-Type-like kind when Type-like expected:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
kind SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$
           String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"when checking" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
doc)
  where
    kind :: LintedType
kind = HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
ty
lintArrow :: SDoc -> LintedType -> LintedType -> LintedType -> LintM ()
lintArrow :: SDoc -> LintedType -> LintedType -> LintedType -> LintM ()
lintArrow SDoc
what LintedType
t1 LintedType
t2 LintedType
tw  
                         
  = do { Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (LintedType -> Bool
isTYPEorCONSTRAINT LintedType
k1) (SDoc -> LintedType -> LintM ()
report (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"argument") LintedType
k1)
       ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (LintedType -> Bool
isTYPEorCONSTRAINT LintedType
k2) (SDoc -> LintedType -> LintM ()
report (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"result")   LintedType
k2)
       ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (LintedType -> Bool
isMultiplicityTy LintedType
kw)         (SDoc -> LintedType -> LintM ()
report (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"multiplicity") LintedType
kw) }
  where
    k1 :: LintedType
k1 = HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
t1
    k2 :: LintedType
k2 = HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
t2
    kw :: LintedType
kw = HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
tw
    report :: SDoc -> LintedType -> LintM ()
report SDoc
ar LintedType
k = SDoc -> LintM ()
addErrL ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Ill-kinded" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
ar)
                                     JoinArity
2 (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"in" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
what)
                                , SDoc
what SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"kind:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
k ])
lint_ty_app :: Type -> LintedKind -> [LintedType] -> LintM ()
lint_ty_app :: LintedType -> LintedType -> [LintedType] -> LintM ()
lint_ty_app LintedType
msg_ty LintedType
k [LintedType]
tys
    
  = (LintedType -> SDoc)
-> LintedType -> LintedType -> [LintedType] -> LintM ()
forall msg_thing.
Outputable msg_thing =>
(msg_thing -> SDoc)
-> msg_thing -> LintedType -> [LintedType] -> LintM ()
lint_app (\LintedType
msg_ty -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"type" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
quotes (LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
msg_ty)) LintedType
msg_ty LintedType
k [LintedType]
tys
lint_co_app :: Coercion -> LintedKind -> [LintedType] -> LintM ()
lint_co_app :: Coercion -> LintedType -> [LintedType] -> LintM ()
lint_co_app Coercion
msg_ty LintedType
k [LintedType]
tys
    
  = (Coercion -> SDoc)
-> Coercion -> LintedType -> [LintedType] -> LintM ()
forall msg_thing.
Outputable msg_thing =>
(msg_thing -> SDoc)
-> msg_thing -> LintedType -> [LintedType] -> LintM ()
lint_app (\Coercion
msg_ty -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"coercion" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
quotes (Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
msg_ty)) Coercion
msg_ty LintedType
k [LintedType]
tys
lintTyLit :: TyLit -> LintM ()
lintTyLit :: TyLit -> LintM ()
lintTyLit (NumTyLit Integer
n)
  | Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
0    = () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  | Bool
otherwise = SDoc -> LintM ()
forall a. SDoc -> LintM a
failWithL SDoc
msg
    where msg :: SDoc
msg = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Negative type literal:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer Integer
n
lintTyLit (StrTyLit FastString
_) = () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
lintTyLit (CharTyLit Char
_) = () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
lint_app :: Outputable msg_thing => (msg_thing -> SDoc) -> msg_thing -> LintedKind -> [LintedType] -> LintM ()
lint_app :: forall msg_thing.
Outputable msg_thing =>
(msg_thing -> SDoc)
-> msg_thing -> LintedType -> [LintedType] -> LintM ()
lint_app msg_thing -> SDoc
mk_msg msg_thing
msg_type !LintedType
kfn [LintedType]
arg_tys
    = do { !InScopeSet
in_scope <- LintM InScopeSet
getInScope
         
         
         
         ; InScopeSet -> LintedType -> [LintedType] -> LintM ()
go_app InScopeSet
in_scope LintedType
kfn [LintedType]
arg_tys
         }
  where
    
    
    
    go_app :: InScopeSet -> LintedKind -> [Type] -> LintM ()
    go_app :: InScopeSet -> LintedType -> [LintedType] -> LintM ()
go_app !InScopeSet
in_scope !LintedType
kfn [LintedType]
ta
      | Just LintedType
kfn' <- LintedType -> Maybe LintedType
coreView LintedType
kfn
      = InScopeSet -> LintedType -> [LintedType] -> LintM ()
go_app InScopeSet
in_scope LintedType
kfn' [LintedType]
ta
    go_app InScopeSet
_in_scope LintedType
_kind [] = () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    go_app InScopeSet
in_scope fun_kind :: LintedType
fun_kind@(FunTy FunTyFlag
_ LintedType
_ LintedType
kfa LintedType
kfb) (LintedType
ta:[LintedType]
tas)
      = do { let ka :: LintedType
ka = HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
ta
           ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (LintedType
ka LintedType -> LintedType -> Bool
`eqType` LintedType
kfa) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$
             SDoc -> LintM ()
addErrL (LintedType
-> [LintedType] -> (msg_thing -> SDoc) -> msg_thing -> SDoc -> SDoc
forall a1 a2 t.
(Outputable a1, Outputable a2) =>
a1 -> a2 -> (t -> SDoc) -> t -> SDoc -> SDoc
lint_app_fail_msg LintedType
kfn [LintedType]
arg_tys msg_thing -> SDoc
mk_msg msg_thing
msg_type (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Fun:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> (LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
fun_kind SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ta SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ka)))
           ; InScopeSet -> LintedType -> [LintedType] -> LintM ()
go_app InScopeSet
in_scope LintedType
kfb [LintedType]
tas }
    go_app InScopeSet
in_scope (ForAllTy (Bndr Var
kv ForAllTyFlag
_vis) LintedType
kfn) (LintedType
ta:[LintedType]
tas)
      = do { let kv_kind :: LintedType
kv_kind = Var -> LintedType
varType Var
kv
                 ka :: LintedType
ka      = HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
ta
           ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (LintedType
ka LintedType -> LintedType -> Bool
`eqType` LintedType
kv_kind) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$
             SDoc -> LintM ()
addErrL (LintedType
-> [LintedType] -> (msg_thing -> SDoc) -> msg_thing -> SDoc -> SDoc
forall a1 a2 t.
(Outputable a1, Outputable a2) =>
a1 -> a2 -> (t -> SDoc) -> t -> SDoc -> SDoc
lint_app_fail_msg LintedType
kfn [LintedType]
arg_tys msg_thing -> SDoc
mk_msg msg_thing
msg_type (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Forall:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
kv SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
kv_kind SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$
                                                    LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ta SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ka)))
           ; let kind' :: LintedType
kind' = HasDebugCallStack => Subst -> LintedType -> LintedType
Subst -> LintedType -> LintedType
substTy (Subst -> Var -> LintedType -> Subst
extendTCvSubst (InScopeSet -> Subst
mkEmptySubst InScopeSet
in_scope) Var
kv LintedType
ta) LintedType
kfn
           ; InScopeSet -> LintedType -> [LintedType] -> LintM ()
go_app InScopeSet
in_scope LintedType
kind' [LintedType]
tas }
    go_app InScopeSet
_ LintedType
kfn [LintedType]
ta
       = SDoc -> LintM ()
forall a. SDoc -> LintM a
failWithL (LintedType
-> [LintedType] -> (msg_thing -> SDoc) -> msg_thing -> SDoc -> SDoc
forall a1 a2 t.
(Outputable a1, Outputable a2) =>
a1 -> a2 -> (t -> SDoc) -> t -> SDoc -> SDoc
lint_app_fail_msg LintedType
kfn [LintedType]
arg_tys msg_thing -> SDoc
mk_msg msg_thing
msg_type (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Not a fun:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> (LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
kfn SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ [LintedType] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [LintedType]
ta)))
lint_app_fail_msg :: (Outputable a1, Outputable a2) => a1 -> a2 -> (t -> SDoc) -> t -> SDoc -> SDoc
lint_app_fail_msg :: forall a1 a2 t.
(Outputable a1, Outputable a2) =>
a1 -> a2 -> (t -> SDoc) -> t -> SDoc -> SDoc
lint_app_fail_msg a1
kfn a2
arg_tys t -> SDoc
mk_msg t
msg_type SDoc
extra = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Kind application error in") JoinArity
2 (t -> SDoc
mk_msg t
msg_type)
                      , JoinArity -> SDoc -> SDoc
nest JoinArity
2 (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Function kind =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> a1 -> SDoc
forall a. Outputable a => a -> SDoc
ppr a1
kfn)
                      , JoinArity -> SDoc -> SDoc
nest JoinArity
2 (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Arg types =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> a2 -> SDoc
forall a. Outputable a => a -> SDoc
ppr a2
arg_tys)
                      , SDoc
extra ]
lintCoreRule :: OutVar -> LintedType -> CoreRule -> LintM ()
lintCoreRule :: Var -> LintedType -> CoreRule -> LintM ()
lintCoreRule Var
_ LintedType
_ (BuiltinRule {})
  = () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()  
lintCoreRule Var
fun LintedType
fun_ty rule :: CoreRule
rule@(Rule { ru_name :: CoreRule -> FastString
ru_name = FastString
name, ru_bndrs :: CoreRule -> [Var]
ru_bndrs = [Var]
bndrs
                                   , ru_args :: CoreRule -> [CoreExpr]
ru_args = [CoreExpr]
args, ru_rhs :: CoreRule -> CoreExpr
ru_rhs = CoreExpr
rhs })
  = BindingSite -> [Var] -> ([Var] -> LintM ()) -> LintM ()
forall a. BindingSite -> [Var] -> ([Var] -> LintM a) -> LintM a
lintBinders BindingSite
LambdaBind [Var]
bndrs (([Var] -> LintM ()) -> LintM ())
-> ([Var] -> LintM ()) -> LintM ()
forall a b. (a -> b) -> a -> b
$ \ [Var]
_ ->
    do { (LintedType
lhs_ty, UsageEnv
_) <- (LintedType, UsageEnv)
-> [CoreExpr] -> LintM (LintedType, UsageEnv)
lintCoreArgs (LintedType
fun_ty, UsageEnv
zeroUE) [CoreExpr]
args
       ; (LintedType
rhs_ty, UsageEnv
_) <- case Var -> Maybe JoinArity
isJoinId_maybe Var
fun of
                     Just JoinArity
join_arity
                       -> do { Bool -> SDoc -> LintM ()
checkL ([CoreExpr]
args [CoreExpr] -> JoinArity -> Bool
forall a. [a] -> JoinArity -> Bool
`lengthIs` JoinArity
join_arity) (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
                                Var -> JoinArity -> CoreRule -> SDoc
mkBadJoinPointRuleMsg Var
fun JoinArity
join_arity CoreRule
rule
                               
                             ; CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
rhs }
                     Maybe JoinArity
_ -> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a. LintM a -> LintM a
markAllJoinsBad (LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv))
-> LintM (LintedType, UsageEnv) -> LintM (LintedType, UsageEnv)
forall a b. (a -> b) -> a -> b
$ CoreExpr -> LintM (LintedType, UsageEnv)
lintCoreExpr CoreExpr
rhs
       ; LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys LintedType
lhs_ty LintedType
rhs_ty (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
         (SDoc
rule_doc SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"lhs type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
lhs_ty
                            , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"rhs type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
rhs_ty
                            , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"fun_ty:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
fun_ty ])
       ; let bad_bndrs :: [Var]
bad_bndrs = (Var -> Bool) -> [Var] -> [Var]
forall a. (a -> Bool) -> [a] -> [a]
filter Var -> Bool
is_bad_bndr [Var]
bndrs
       ; Bool -> SDoc -> LintM ()
checkL ([Var] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Var]
bad_bndrs)
                (SDoc
rule_doc SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"unbound" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [Var] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Var]
bad_bndrs)
            
    }
  where
    rule_doc :: SDoc
rule_doc = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Rule" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
doubleQuotes (FastString -> SDoc
forall doc. IsLine doc => FastString -> doc
ftext FastString
name) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
colon
    lhs_fvs :: IdSet
lhs_fvs = [CoreExpr] -> IdSet
exprsFreeVars [CoreExpr]
args
    rhs_fvs :: IdSet
rhs_fvs = CoreExpr -> IdSet
exprFreeVars CoreExpr
rhs
    is_bad_bndr :: Var -> Bool
    
    is_bad_bndr :: Var -> Bool
is_bad_bndr Var
bndr = Bool -> Bool
not (Var
bndr Var -> IdSet -> Bool
`elemVarSet` IdSet
lhs_fvs)
                    Bool -> Bool -> Bool
&& Var
bndr Var -> IdSet -> Bool
`elemVarSet` IdSet
rhs_fvs
                    Bool -> Bool -> Bool
&& Maybe Coercion -> Bool
forall a. Maybe a -> Bool
isNothing (Var -> Maybe Coercion
isReflCoVar_maybe Var
bndr)
lintStarCoercion :: InCoercion -> LintM LintedCoercion
lintStarCoercion :: Coercion -> LintM Coercion
lintStarCoercion Coercion
g
  = do { Coercion
g' <- Coercion -> LintM Coercion
lintCoercion Coercion
g
       ; let Pair LintedType
t1 LintedType
t2 = Coercion -> Pair LintedType
coercionKind Coercion
g'
       ; LintedType -> SDoc -> LintM ()
checkValueType LintedType
t1 (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"the kind of the left type in" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
g)
       ; LintedType -> SDoc -> LintM ()
checkValueType LintedType
t2 (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"the kind of the right type in" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
g)
       ; Coercion -> Role -> Role -> LintM ()
forall thing. Outputable thing => thing -> Role -> Role -> LintM ()
lintRole Coercion
g Role
Nominal (Coercion -> Role
coercionRole Coercion
g)
       ; Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return Coercion
g' }
lintCoercion :: InCoercion -> LintM LintedCoercion
lintCoercion :: Coercion -> LintM Coercion
lintCoercion (CoVarCo Var
cv)
  | Bool -> Bool
not (Var -> Bool
isCoVar Var
cv)
  = SDoc -> LintM Coercion
forall a. SDoc -> LintM a
failWithL (SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Bad CoVarCo:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
cv)
                  JoinArity
2 (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"With offending type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> LintedType
varType Var
cv)))
  | Bool
otherwise
  = do { Subst
subst <- LintM Subst
getSubst
       ; case Subst -> Var -> Maybe Coercion
lookupCoVar Subst
subst Var
cv of
           Just Coercion
linted_co -> Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return Coercion
linted_co ;
           Maybe Coercion
Nothing
              | Var
cv Var -> Subst -> Bool
`isInScope` Subst
subst
                   -> Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Var -> Coercion
CoVarCo Var
cv)
              | Bool
otherwise
                   ->
                      
                      SDoc -> LintM Coercion
forall a. SDoc -> LintM a
failWithL (SDoc -> LintM Coercion) -> SDoc -> LintM Coercion
forall a b. (a -> b) -> a -> b
$
                      SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"The coercion variable" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> BindingSite -> Var -> SDoc
forall a. OutputableBndr a => BindingSite -> a -> SDoc
pprBndr BindingSite
LetBind Var
cv)
                         JoinArity
2 (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"is out of scope")
     }
lintCoercion (Refl LintedType
ty)
  = do { LintedType
ty' <- LintedType -> LintM LintedType
lintType LintedType
ty
       ; Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (LintedType -> Coercion
Refl LintedType
ty') }
lintCoercion (GRefl Role
r LintedType
ty MCoercion
MRefl)
  = do { LintedType
ty' <- LintedType -> LintM LintedType
lintType LintedType
ty
       ; Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Role -> LintedType -> MCoercion -> Coercion
GRefl Role
r LintedType
ty' MCoercion
MRefl) }
lintCoercion (GRefl Role
r LintedType
ty (MCo Coercion
co))
  = do { LintedType
ty' <- LintedType -> LintM LintedType
lintType LintedType
ty
       ; Coercion
co' <- Coercion -> LintM Coercion
lintCoercion Coercion
co
       ; let tk :: LintedType
tk = HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
ty'
             tl :: LintedType
tl = Coercion -> LintedType
coercionLKind Coercion
co'
       ; LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys LintedType
tk LintedType
tl (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
         SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"GRefl coercion kind mis-match:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co)
            JoinArity
2 ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty', LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
tk, LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
tl])
       ; Coercion -> Role -> Role -> LintM ()
forall thing. Outputable thing => thing -> Role -> Role -> LintM ()
lintRole Coercion
co' Role
Nominal (Coercion -> Role
coercionRole Coercion
co')
       ; Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Role -> LintedType -> MCoercion -> Coercion
GRefl Role
r LintedType
ty' (Coercion -> MCoercion
MCo Coercion
co')) }
lintCoercion co :: Coercion
co@(TyConAppCo Role
r TyCon
tc [Coercion]
cos)
  | Just {} <- HasDebugCallStack => Role -> TyCon -> [Coercion] -> Maybe Coercion
Role -> TyCon -> [Coercion] -> Maybe Coercion
tyConAppFunCo_maybe Role
r TyCon
tc [Coercion]
cos
  = SDoc -> LintM Coercion
forall a. SDoc -> LintM a
failWithL (SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Saturated application of" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
quotes (TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc))
                  JoinArity
2 (Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co))
    
  | Just {} <- TyCon -> Maybe ([Var], LintedType)
synTyConDefn_maybe TyCon
tc
  = SDoc -> LintM Coercion
forall a. SDoc -> LintM a
failWithL (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Synonym in TyConAppCo:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co)
  | Bool
otherwise
  = do { TyCon -> LintM ()
checkTyCon TyCon
tc
       ; [Coercion]
cos' <- (Coercion -> LintM Coercion) -> [Coercion] -> LintM [Coercion]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Coercion -> LintM Coercion
lintCoercion [Coercion]
cos
       ; let ([Pair LintedType]
co_kinds, [Role]
co_roles) = [(Pair LintedType, Role)] -> ([Pair LintedType], [Role])
forall a b. [(a, b)] -> ([a], [b])
unzip ((Coercion -> (Pair LintedType, Role))
-> [Coercion] -> [(Pair LintedType, Role)]
forall a b. (a -> b) -> [a] -> [b]
map Coercion -> (Pair LintedType, Role)
coercionKindRole [Coercion]
cos')
       ; Coercion -> LintedType -> [LintedType] -> LintM ()
lint_co_app Coercion
co (TyCon -> LintedType
tyConKind TyCon
tc) ((Pair LintedType -> LintedType)
-> [Pair LintedType] -> [LintedType]
forall a b. (a -> b) -> [a] -> [b]
map Pair LintedType -> LintedType
forall a. Pair a -> a
pFst [Pair LintedType]
co_kinds)
       ; Coercion -> LintedType -> [LintedType] -> LintM ()
lint_co_app Coercion
co (TyCon -> LintedType
tyConKind TyCon
tc) ((Pair LintedType -> LintedType)
-> [Pair LintedType] -> [LintedType]
forall a b. (a -> b) -> [a] -> [b]
map Pair LintedType -> LintedType
forall a. Pair a -> a
pSnd [Pair LintedType]
co_kinds)
       ; (Role -> Role -> LintM ()) -> [Role] -> [Role] -> LintM ()
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m ()
zipWithM_ (Coercion -> Role -> Role -> LintM ()
forall thing. Outputable thing => thing -> Role -> Role -> LintM ()
lintRole Coercion
co) (Role -> TyCon -> [Role]
tyConRoleListX Role
r TyCon
tc) [Role]
co_roles
       ; Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Role -> TyCon -> [Coercion] -> Coercion
TyConAppCo Role
r TyCon
tc [Coercion]
cos') }
lintCoercion co :: Coercion
co@(AppCo Coercion
co1 Coercion
co2)
  | TyConAppCo {} <- Coercion
co1
  = SDoc -> LintM Coercion
forall a. SDoc -> LintM a
failWithL (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"TyConAppCo to the left of AppCo:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co)
  | Just (TyConApp {}, Role
_) <- Coercion -> Maybe (LintedType, Role)
isReflCo_maybe Coercion
co1
  = SDoc -> LintM Coercion
forall a. SDoc -> LintM a
failWithL (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Refl (TyConApp ...) to the left of AppCo:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co)
  | Bool
otherwise
  = do { Coercion
co1' <- Coercion -> LintM Coercion
lintCoercion Coercion
co1
       ; Coercion
co2' <- Coercion -> LintM Coercion
lintCoercion Coercion
co2
       ; let (Pair LintedType
lk1 LintedType
rk1, Role
r1) = Coercion -> (Pair LintedType, Role)
coercionKindRole Coercion
co1'
             (Pair LintedType
lk2 LintedType
rk2, Role
r2) = Coercion -> (Pair LintedType, Role)
coercionKindRole Coercion
co2'
       ; Coercion -> LintedType -> [LintedType] -> LintM ()
lint_co_app Coercion
co (HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
lk1) [LintedType
lk2]
       ; Coercion -> LintedType -> [LintedType] -> LintM ()
lint_co_app Coercion
co (HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
rk1) [LintedType
rk2]
       ; if Role
r1 Role -> Role -> Bool
forall a. Eq a => a -> a -> Bool
== Role
Phantom
         then Bool -> SDoc -> LintM ()
lintL (Role
r2 Role -> Role -> Bool
forall a. Eq a => a -> a -> Bool
== Role
Phantom Bool -> Bool -> Bool
|| Role
r2 Role -> Role -> Bool
forall a. Eq a => a -> a -> Bool
== Role
Nominal)
                     (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Second argument in AppCo cannot be R:" SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$
                      Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co)
         else Coercion -> Role -> Role -> LintM ()
forall thing. Outputable thing => thing -> Role -> Role -> LintM ()
lintRole Coercion
co Role
Nominal Role
r2
       ; Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Coercion -> Coercion -> Coercion
AppCo Coercion
co1' Coercion
co2') }
lintCoercion co :: Coercion
co@(ForAllCo Var
tcv Coercion
kind_co Coercion
body_co)
  | Bool -> Bool
not (Var -> Bool
isTyCoVar Var
tcv)
  = SDoc -> LintM Coercion
forall a. SDoc -> LintM a
failWithL (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Non tyco binder in ForAllCo:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co)
  | Bool
otherwise
  = do { Coercion
kind_co' <- Coercion -> LintM Coercion
lintStarCoercion Coercion
kind_co
       ; Var -> (Var -> LintM Coercion) -> LintM Coercion
forall a. Var -> (Var -> LintM a) -> LintM a
lintTyCoBndr Var
tcv ((Var -> LintM Coercion) -> LintM Coercion)
-> (Var -> LintM Coercion) -> LintM Coercion
forall a b. (a -> b) -> a -> b
$ \Var
tcv' ->
    do { Coercion
body_co' <- Coercion -> LintM Coercion
lintCoercion Coercion
body_co
       ; LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys (Var -> LintedType
varType Var
tcv') (Coercion -> LintedType
coercionLKind Coercion
kind_co') (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
         String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Kind mis-match in ForallCo" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co
       
       
       
       
       
       
       ; let Pair LintedType
lty LintedType
rty = Coercion -> Pair LintedType
coercionKind Coercion
body_co'
       ; Var -> LintedType -> LintM ()
lintForAllBody Var
tcv' LintedType
lty
       ; Var -> LintedType -> LintM ()
lintForAllBody Var
tcv' LintedType
rty
       ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Var -> Bool
isCoVar Var
tcv) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$
         Bool -> SDoc -> LintM ()
lintL (Var -> Coercion -> Bool
almostDevoidCoVarOfCo Var
tcv Coercion
body_co) (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
         String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Covar can only appear in Refl and GRefl: " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co
         
         
         
       ; Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Var -> Coercion -> Coercion -> Coercion
ForAllCo Var
tcv' Coercion
kind_co' Coercion
body_co') } }
lintCoercion co :: Coercion
co@(FunCo { fco_role :: Coercion -> Role
fco_role = Role
r, fco_afl :: Coercion -> FunTyFlag
fco_afl = FunTyFlag
afl, fco_afr :: Coercion -> FunTyFlag
fco_afr = FunTyFlag
afr
                       , fco_mult :: Coercion -> Coercion
fco_mult = Coercion
cow, fco_arg :: Coercion -> Coercion
fco_arg = Coercion
co1, fco_res :: Coercion -> Coercion
fco_res = Coercion
co2 })
  = do { Coercion
co1' <- Coercion -> LintM Coercion
lintCoercion Coercion
co1
       ; Coercion
co2' <- Coercion -> LintM Coercion
lintCoercion Coercion
co2
       ; Coercion
cow' <- Coercion -> LintM Coercion
lintCoercion Coercion
cow
       ; let Pair LintedType
lt1 LintedType
rt1 = Coercion -> Pair LintedType
coercionKind Coercion
co1
             Pair LintedType
lt2 LintedType
rt2 = Coercion -> Pair LintedType
coercionKind Coercion
co2
             Pair LintedType
ltw LintedType
rtw = Coercion -> Pair LintedType
coercionKind Coercion
cow
       ; Bool -> SDoc -> LintM ()
lintL (FunTyFlag
afl FunTyFlag -> FunTyFlag -> Bool
forall a. Eq a => a -> a -> Bool
== HasDebugCallStack => LintedType -> LintedType -> FunTyFlag
LintedType -> LintedType -> FunTyFlag
chooseFunTyFlag LintedType
lt1 LintedType
lt2) (String -> SDoc
bad_co_msg String
"afl")
       ; Bool -> SDoc -> LintM ()
lintL (FunTyFlag
afr FunTyFlag -> FunTyFlag -> Bool
forall a. Eq a => a -> a -> Bool
== HasDebugCallStack => LintedType -> LintedType -> FunTyFlag
LintedType -> LintedType -> FunTyFlag
chooseFunTyFlag LintedType
rt1 LintedType
rt2) (String -> SDoc
bad_co_msg String
"afr")
       ; SDoc -> LintedType -> LintedType -> LintedType -> LintM ()
lintArrow (String -> SDoc
bad_co_msg String
"arrowl") LintedType
lt1 LintedType
lt2 LintedType
ltw
       ; SDoc -> LintedType -> LintedType -> LintedType -> LintM ()
lintArrow (String -> SDoc
bad_co_msg String
"arrowr") LintedType
rt1 LintedType
rt2 LintedType
rtw
       ; Coercion -> Role -> Role -> LintM ()
forall thing. Outputable thing => thing -> Role -> Role -> LintM ()
lintRole Coercion
co1 Role
r (Coercion -> Role
coercionRole Coercion
co1)
       ; Coercion -> Role -> Role -> LintM ()
forall thing. Outputable thing => thing -> Role -> Role -> LintM ()
lintRole Coercion
co2 Role
r (Coercion -> Role
coercionRole Coercion
co2)
       ; LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys (HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
ltw) LintedType
multiplicityTy (String -> SDoc
bad_co_msg String
"mult-l")
       ; LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys (HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
rtw) LintedType
multiplicityTy (String -> SDoc
bad_co_msg String
"mult-r")
       ; let expected_mult_role :: Role
expected_mult_role = case Role
r of
                                    Role
Phantom -> Role
Phantom
                                    Role
_ -> Role
Nominal
       ; Coercion -> Role -> Role -> LintM ()
forall thing. Outputable thing => thing -> Role -> Role -> LintM ()
lintRole Coercion
cow Role
expected_mult_role (Coercion -> Role
coercionRole Coercion
cow)
       ; Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Coercion
co { fco_mult = cow', fco_arg = co1', fco_res = co2' }) }
  where
    bad_co_msg :: String -> SDoc
bad_co_msg String
s = SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Bad coercion" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
s))
                      JoinArity
2 ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"afl:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> FunTyFlag -> SDoc
forall a. Outputable a => a -> SDoc
ppr FunTyFlag
afl
                              , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"afr:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> FunTyFlag -> SDoc
forall a. Outputable a => a -> SDoc
ppr FunTyFlag
afr
                              , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"arg_co:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co1
                              , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"res_co:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co2 ])
lintCoercion co :: Coercion
co@(UnivCo UnivCoProvenance
prov Role
r LintedType
ty1 LintedType
ty2)
  = do { LintedType
ty1' <- LintedType -> LintM LintedType
lintType LintedType
ty1
       ; LintedType
ty2' <- LintedType -> LintM LintedType
lintType LintedType
ty2
       ; let k1 :: LintedType
k1 = HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
ty1'
             k2 :: LintedType
k2 = HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
ty2'
       ; UnivCoProvenance
prov' <- LintedType
-> LintedType -> UnivCoProvenance -> LintM UnivCoProvenance
lint_prov LintedType
k1 LintedType
k2 UnivCoProvenance
prov
       ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Role
r Role -> Role -> Bool
forall a. Eq a => a -> a -> Bool
/= Role
Phantom Bool -> Bool -> Bool
&& LintedType -> Bool
isTYPEorCONSTRAINT LintedType
k1
                            Bool -> Bool -> Bool
&& LintedType -> Bool
isTYPEorCONSTRAINT LintedType
k2)
              (LintedType -> LintedType -> LintM ()
checkTypes LintedType
ty1 LintedType
ty2)
       ; Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (UnivCoProvenance -> Role -> LintedType -> LintedType -> Coercion
UnivCo UnivCoProvenance
prov' Role
r LintedType
ty1' LintedType
ty2') }
   where
     report :: String -> SDoc
report String
s = SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text (String -> SDoc) -> String -> SDoc
forall a b. (a -> b) -> a -> b
$ String
"Unsafe coercion: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s)
                     JoinArity
2 ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"From:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty1
                             , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"  To:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty2])
     isUnBoxed :: PrimRep -> Bool
     isUnBoxed :: PrimRep -> Bool
isUnBoxed = Bool -> Bool
not (Bool -> Bool) -> (PrimRep -> Bool) -> PrimRep -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PrimRep -> Bool
isGcPtrRep
       
     checkTypes :: LintedType -> LintedType -> LintM ()
checkTypes LintedType
t1 LintedType
t2
       | UnivCoProvenance -> Bool
allow_ill_kinded_univ_co UnivCoProvenance
prov
       = () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()  
       | Bool
otherwise
       = do { Bool -> SDoc -> LintM ()
checkWarnL Bool
fixed_rep_1
                         (String -> SDoc
report String
"left-hand type does not have a fixed runtime representation")
            ; Bool -> SDoc -> LintM ()
checkWarnL Bool
fixed_rep_2
                         (String -> SDoc
report String
"right-hand type does not have a fixed runtime representation")
            ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
fixed_rep_1 Bool -> Bool -> Bool
&& Bool
fixed_rep_2) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$
              do { Bool -> SDoc -> LintM ()
checkWarnL ([PrimRep]
reps1 [PrimRep] -> [PrimRep] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [PrimRep]
reps2)
                              (String -> SDoc
report String
"between values with different # of reps")
                 ; (PrimRep -> PrimRep -> LintM ())
-> [PrimRep] -> [PrimRep] -> LintM ()
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m ()
zipWithM_ PrimRep -> PrimRep -> LintM ()
validateCoercion [PrimRep]
reps1 [PrimRep]
reps2 }}
       where
         fixed_rep_1 :: Bool
fixed_rep_1 = HasDebugCallStack => LintedType -> Bool
LintedType -> Bool
typeHasFixedRuntimeRep LintedType
t1
         fixed_rep_2 :: Bool
fixed_rep_2 = HasDebugCallStack => LintedType -> Bool
LintedType -> Bool
typeHasFixedRuntimeRep LintedType
t2
         
         
         reps1 :: [PrimRep]
reps1 = HasDebugCallStack => LintedType -> [PrimRep]
LintedType -> [PrimRep]
typePrimRep LintedType
t1
         reps2 :: [PrimRep]
reps2 = HasDebugCallStack => LintedType -> [PrimRep]
LintedType -> [PrimRep]
typePrimRep LintedType
t2
     
     
     
     
     allow_ill_kinded_univ_co :: UnivCoProvenance -> Bool
allow_ill_kinded_univ_co (CorePrepProv Bool
homo_kind) = Bool -> Bool
not Bool
homo_kind
     allow_ill_kinded_univ_co UnivCoProvenance
_                        = Bool
False
     validateCoercion :: PrimRep -> PrimRep -> LintM ()
     validateCoercion :: PrimRep -> PrimRep -> LintM ()
validateCoercion PrimRep
rep1 PrimRep
rep2
       = do { Platform
platform <- LintM Platform
getPlatform
            ; Bool -> SDoc -> LintM ()
checkWarnL (PrimRep -> Bool
isUnBoxed PrimRep
rep1 Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== PrimRep -> Bool
isUnBoxed PrimRep
rep2)
                         (String -> SDoc
report String
"between unboxed and boxed value")
            ; Bool -> SDoc -> LintM ()
checkWarnL (Platform -> PrimRep -> JoinArity
TyCon.primRepSizeB Platform
platform PrimRep
rep1
                           JoinArity -> JoinArity -> Bool
forall a. Eq a => a -> a -> Bool
== Platform -> PrimRep -> JoinArity
TyCon.primRepSizeB Platform
platform PrimRep
rep2)
                         (String -> SDoc
report String
"between unboxed values of different size")
            ; let fl :: Maybe Bool
fl = (Bool -> Bool -> Bool) -> Maybe Bool -> Maybe Bool -> Maybe Bool
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
(==) (PrimRep -> Maybe Bool
TyCon.primRepIsFloat PrimRep
rep1)
                                   (PrimRep -> Maybe Bool
TyCon.primRepIsFloat PrimRep
rep2)
            ; case Maybe Bool
fl of
                Maybe Bool
Nothing    -> SDoc -> LintM ()
addWarnL (String -> SDoc
report String
"between vector types")
                Just Bool
False -> SDoc -> LintM ()
addWarnL (String -> SDoc
report String
"between float and integral values")
                Maybe Bool
_          -> () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
            }
     lint_prov :: LintedType
-> LintedType -> UnivCoProvenance -> LintM UnivCoProvenance
lint_prov LintedType
k1 LintedType
k2 (PhantomProv Coercion
kco)
       = do { Coercion
kco' <- Coercion -> LintM Coercion
lintStarCoercion Coercion
kco
            ; Coercion -> Role -> Role -> LintM ()
forall thing. Outputable thing => thing -> Role -> Role -> LintM ()
lintRole Coercion
co Role
Phantom Role
r
            ; Coercion -> LintedType -> LintedType -> LintM ()
check_kinds Coercion
kco' LintedType
k1 LintedType
k2
            ; UnivCoProvenance -> LintM UnivCoProvenance
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Coercion -> UnivCoProvenance
PhantomProv Coercion
kco') }
     lint_prov LintedType
k1 LintedType
k2 (ProofIrrelProv Coercion
kco)
       = do { Bool -> SDoc -> LintM ()
lintL (LintedType -> Bool
isCoercionTy LintedType
ty1) (LintedType -> Coercion -> SDoc
mkBadProofIrrelMsg LintedType
ty1 Coercion
co)
            ; Bool -> SDoc -> LintM ()
lintL (LintedType -> Bool
isCoercionTy LintedType
ty2) (LintedType -> Coercion -> SDoc
mkBadProofIrrelMsg LintedType
ty2 Coercion
co)
            ; Coercion
kco' <- Coercion -> LintM Coercion
lintStarCoercion Coercion
kco
            ; Coercion -> LintedType -> LintedType -> LintM ()
check_kinds Coercion
kco LintedType
k1 LintedType
k2
            ; UnivCoProvenance -> LintM UnivCoProvenance
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Coercion -> UnivCoProvenance
ProofIrrelProv Coercion
kco') }
     lint_prov LintedType
_ LintedType
_ prov :: UnivCoProvenance
prov@(PluginProv String
_)   = UnivCoProvenance -> LintM UnivCoProvenance
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return UnivCoProvenance
prov
     lint_prov LintedType
_ LintedType
_ prov :: UnivCoProvenance
prov@(CorePrepProv Bool
_) = UnivCoProvenance -> LintM UnivCoProvenance
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return UnivCoProvenance
prov
     check_kinds :: Coercion -> LintedType -> LintedType -> LintM ()
check_kinds Coercion
kco LintedType
k1 LintedType
k2
       = do { let Pair LintedType
k1' LintedType
k2' = Coercion -> Pair LintedType
coercionKind Coercion
kco
            ; LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys LintedType
k1 LintedType
k1' (LeftOrRight -> Coercion -> SDoc
mkBadUnivCoMsg LeftOrRight
CLeft  Coercion
co)
            ; LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys LintedType
k2 LintedType
k2' (LeftOrRight -> Coercion -> SDoc
mkBadUnivCoMsg LeftOrRight
CRight Coercion
co) }
lintCoercion (SymCo Coercion
co)
  = do { Coercion
co' <- Coercion -> LintM Coercion
lintCoercion Coercion
co
       ; Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Coercion -> Coercion
SymCo Coercion
co') }
lintCoercion co :: Coercion
co@(TransCo Coercion
co1 Coercion
co2)
  = do { Coercion
co1' <- Coercion -> LintM Coercion
lintCoercion Coercion
co1
       ; Coercion
co2' <- Coercion -> LintM Coercion
lintCoercion Coercion
co2
       ; let ty1b :: LintedType
ty1b = Coercion -> LintedType
coercionRKind Coercion
co1'
             ty2a :: LintedType
ty2a = Coercion -> LintedType
coercionLKind Coercion
co2'
       ; LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys LintedType
ty1b LintedType
ty2a
               (SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Trans coercion mis-match:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co)
                   JoinArity
2 ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [Pair LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Coercion -> Pair LintedType
coercionKind Coercion
co1'), Pair LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Coercion -> Pair LintedType
coercionKind Coercion
co2')]))
       ; Coercion -> Role -> Role -> LintM ()
forall thing. Outputable thing => thing -> Role -> Role -> LintM ()
lintRole Coercion
co (Coercion -> Role
coercionRole Coercion
co1) (Coercion -> Role
coercionRole Coercion
co2)
       ; Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Coercion -> Coercion -> Coercion
TransCo Coercion
co1' Coercion
co2') }
lintCoercion the_co :: Coercion
the_co@(SelCo CoSel
cs Coercion
co)
  = do { Coercion
co' <- Coercion -> LintM Coercion
lintCoercion Coercion
co
       ; let (Pair LintedType
s LintedType
t, Role
co_role) = Coercion -> (Pair LintedType, Role)
coercionKindRole Coercion
co'
       ; if 
            | Just (Var, LintedType)
_ <- LintedType -> Maybe (Var, LintedType)
splitForAllTyCoVar_maybe LintedType
s
            , Just (Var, LintedType)
_ <- LintedType -> Maybe (Var, LintedType)
splitForAllTyCoVar_maybe LintedType
t
            , CoSel
SelForAll <- CoSel
cs
            ,   (LintedType -> Bool
isForAllTy_ty LintedType
s Bool -> Bool -> Bool
&& LintedType -> Bool
isForAllTy_ty LintedType
t)
             Bool -> Bool -> Bool
|| (LintedType -> Bool
isForAllTy_co LintedType
s Bool -> Bool -> Bool
&& LintedType -> Bool
isForAllTy_co LintedType
t)
            -> Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (CoSel -> Coercion -> Coercion
SelCo CoSel
cs Coercion
co')
            
            | LintedType -> Bool
isFunTy LintedType
s
            , LintedType -> Bool
isFunTy LintedType
t
            , SelFun {} <- CoSel
cs
            -> Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (CoSel -> Coercion -> Coercion
SelCo CoSel
cs Coercion
co')
            
            | Just (TyCon
tc_s, [LintedType]
tys_s) <- HasDebugCallStack => LintedType -> Maybe (TyCon, [LintedType])
LintedType -> Maybe (TyCon, [LintedType])
splitTyConApp_maybe LintedType
s
            , Just (TyCon
tc_t, [LintedType]
tys_t) <- HasDebugCallStack => LintedType -> Maybe (TyCon, [LintedType])
LintedType -> Maybe (TyCon, [LintedType])
splitTyConApp_maybe LintedType
t
            , TyCon
tc_s TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tc_t
            , SelTyCon JoinArity
n Role
r0 <- CoSel
cs
            , TyCon -> Role -> Bool
isInjectiveTyCon TyCon
tc_s Role
co_role
                
            , [LintedType]
tys_s [LintedType] -> [LintedType] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [LintedType]
tys_t
            , [LintedType]
tys_s [LintedType] -> JoinArity -> Bool
forall a. [a] -> JoinArity -> Bool
`lengthExceeds` JoinArity
n
            -> do { Coercion -> Role -> Role -> LintM ()
forall thing. Outputable thing => thing -> Role -> Role -> LintM ()
lintRole Coercion
the_co (Role -> TyCon -> JoinArity -> Role
tyConRole Role
co_role TyCon
tc_s JoinArity
n) Role
r0
                  ; Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (CoSel -> Coercion -> Coercion
SelCo CoSel
cs Coercion
co') }
            | Bool
otherwise
            -> SDoc -> LintM Coercion
forall a. SDoc -> LintM a
failWithL (SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Bad SelCo:")
                             JoinArity
2 (Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
the_co SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
s SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
t)) }
lintCoercion the_co :: Coercion
the_co@(LRCo LeftOrRight
lr Coercion
co)
  = do { Coercion
co' <- Coercion -> LintM Coercion
lintCoercion Coercion
co
       ; let Pair LintedType
s LintedType
t = Coercion -> Pair LintedType
coercionKind Coercion
co'
             r :: Role
r        = Coercion -> Role
coercionRole Coercion
co'
       ; Coercion -> Role -> Role -> LintM ()
forall thing. Outputable thing => thing -> Role -> Role -> LintM ()
lintRole Coercion
co Role
Nominal Role
r
       ; case (LintedType -> Maybe (LintedType, LintedType)
splitAppTy_maybe LintedType
s, LintedType -> Maybe (LintedType, LintedType)
splitAppTy_maybe LintedType
t) of
           (Just (LintedType, LintedType)
_, Just (LintedType, LintedType)
_) -> Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (LeftOrRight -> Coercion -> Coercion
LRCo LeftOrRight
lr Coercion
co')
           (Maybe (LintedType, LintedType), Maybe (LintedType, LintedType))
_ -> SDoc -> LintM Coercion
forall a. SDoc -> LintM a
failWithL (SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Bad LRCo:")
                              JoinArity
2 (Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
the_co SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
s SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
t)) }
lintCoercion (InstCo Coercion
co Coercion
arg)
  = do { Coercion
co'  <- Coercion -> LintM Coercion
lintCoercion Coercion
co
       ; Coercion
arg' <- Coercion -> LintM Coercion
lintCoercion Coercion
arg
       ; let Pair LintedType
t1 LintedType
t2 = Coercion -> Pair LintedType
coercionKind Coercion
co'
             Pair LintedType
s1 LintedType
s2 = Coercion -> Pair LintedType
coercionKind Coercion
arg'
       ; Coercion -> Role -> Role -> LintM ()
forall thing. Outputable thing => thing -> Role -> Role -> LintM ()
lintRole Coercion
arg Role
Nominal (Coercion -> Role
coercionRole Coercion
arg')
      ; case (LintedType -> Maybe (Var, LintedType)
splitForAllTyVar_maybe LintedType
t1, LintedType -> Maybe (Var, LintedType)
splitForAllTyVar_maybe LintedType
t2) of
         
         { (Just (Var
tv1,LintedType
_), Just (Var
tv2,LintedType
_))
             | HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
s1 LintedType -> LintedType -> Bool
`eqType` Var -> LintedType
tyVarKind Var
tv1
             , HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
s2 LintedType -> LintedType -> Bool
`eqType` Var -> LintedType
tyVarKind Var
tv2
             -> Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Coercion -> Coercion -> Coercion
InstCo Coercion
co' Coercion
arg')
             | Bool
otherwise
             -> SDoc -> LintM Coercion
forall a. SDoc -> LintM a
failWithL (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Kind mis-match in inst coercion1" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co)
         ; (Maybe (Var, LintedType), Maybe (Var, LintedType))
_ -> case (LintedType -> Maybe (Var, LintedType)
splitForAllCoVar_maybe LintedType
t1, LintedType -> Maybe (Var, LintedType)
splitForAllCoVar_maybe LintedType
t2) of
         
         { (Just (Var
cv1, LintedType
_), Just (Var
cv2, LintedType
_))
             | HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
s1 LintedType -> LintedType -> Bool
`eqType` Var -> LintedType
varType Var
cv1
             , HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
s2 LintedType -> LintedType -> Bool
`eqType` Var -> LintedType
varType Var
cv2
             , CoercionTy Coercion
_ <- LintedType
s1
             , CoercionTy Coercion
_ <- LintedType
s2
             -> Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Coercion -> Coercion -> Coercion
InstCo Coercion
co' Coercion
arg')
             | Bool
otherwise
             -> SDoc -> LintM Coercion
forall a. SDoc -> LintM a
failWithL (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Kind mis-match in inst coercion2" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co)
         ; (Maybe (Var, LintedType), Maybe (Var, LintedType))
_ -> SDoc -> LintM Coercion
forall a. SDoc -> LintM a
failWithL (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Bad argument of inst") }}}
lintCoercion co :: Coercion
co@(AxiomInstCo CoAxiom Branched
con JoinArity
ind [Coercion]
cos)
  = do { Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (JoinArity
0 JoinArity -> JoinArity -> Bool
forall a. Ord a => a -> a -> Bool
<= JoinArity
ind Bool -> Bool -> Bool
&& JoinArity
ind JoinArity -> JoinArity -> Bool
forall a. Ord a => a -> a -> Bool
< Branches Branched -> JoinArity
forall (br :: BranchFlag). Branches br -> JoinArity
numBranches (CoAxiom Branched -> Branches Branched
forall (br :: BranchFlag). CoAxiom br -> Branches br
coAxiomBranches CoAxiom Branched
con))
                (SDoc -> LintM ()
bad_ax (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"index out of range"))
       ; let CoAxBranch { cab_tvs :: CoAxBranch -> [Var]
cab_tvs   = [Var]
ktvs
                        , cab_cvs :: CoAxBranch -> [Var]
cab_cvs   = [Var]
cvs
                        , cab_roles :: CoAxBranch -> [Role]
cab_roles = [Role]
roles } = CoAxiom Branched -> JoinArity -> CoAxBranch
forall (br :: BranchFlag). CoAxiom br -> JoinArity -> CoAxBranch
coAxiomNthBranch CoAxiom Branched
con JoinArity
ind
       ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([Coercion]
cos [Coercion] -> [Var] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` ([Var]
ktvs [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ [Var]
cvs)) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$
           SDoc -> LintM ()
bad_ax (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"lengths")
       ; [Coercion]
cos' <- (Coercion -> LintM Coercion) -> [Coercion] -> LintM [Coercion]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Coercion -> LintM Coercion
lintCoercion [Coercion]
cos
       ; Subst
subst <- LintM Subst
getSubst
       ; let empty_subst :: Subst
empty_subst = Subst -> Subst
zapSubst Subst
subst
       ; (Subst, Subst)
_ <- ((Subst, Subst) -> (Var, Role, Coercion) -> LintM (Subst, Subst))
-> (Subst, Subst)
-> [(Var, Role, Coercion)]
-> LintM (Subst, Subst)
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldlM (Subst, Subst) -> (Var, Role, Coercion) -> LintM (Subst, Subst)
check_ki (Subst
empty_subst, Subst
empty_subst)
                              ([Var] -> [Role] -> [Coercion] -> [(Var, Role, Coercion)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 ([Var]
ktvs [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ [Var]
cvs) [Role]
roles [Coercion]
cos')
       ; let fam_tc :: TyCon
fam_tc = CoAxiom Branched -> TyCon
forall (br :: BranchFlag). CoAxiom br -> TyCon
coAxiomTyCon CoAxiom Branched
con
       ; case Coercion -> Maybe CoAxBranch
checkAxInstCo Coercion
co of
           Just CoAxBranch
bad_branch -> SDoc -> LintM ()
bad_ax (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"inconsistent with" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+>
                                       TyCon -> CoAxBranch -> SDoc
pprCoAxBranch TyCon
fam_tc CoAxBranch
bad_branch
           Maybe CoAxBranch
Nothing -> () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
       ; Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (CoAxiom Branched -> JoinArity -> [Coercion] -> Coercion
AxiomInstCo CoAxiom Branched
con JoinArity
ind [Coercion]
cos') }
  where
    bad_ax :: SDoc -> LintM ()
bad_ax SDoc
what = SDoc -> LintM ()
addErrL (SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text  String
"Bad axiom application" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens SDoc
what)
                        JoinArity
2 (Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co))
    check_ki :: (Subst, Subst) -> (Var, Role, Coercion) -> LintM (Subst, Subst)
check_ki (Subst
subst_l, Subst
subst_r) (Var
ktv, Role
role, Coercion
arg')
      = do { let Pair LintedType
s' LintedType
t' = Coercion -> Pair LintedType
coercionKind Coercion
arg'
                 sk' :: LintedType
sk' = HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
s'
                 tk' :: LintedType
tk' = HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
t'
           ; Coercion -> Role -> Role -> LintM ()
forall thing. Outputable thing => thing -> Role -> Role -> LintM ()
lintRole Coercion
arg' Role
role (Coercion -> Role
coercionRole Coercion
arg')
           ; let ktv_kind_l :: LintedType
ktv_kind_l = HasDebugCallStack => Subst -> LintedType -> LintedType
Subst -> LintedType -> LintedType
substTy Subst
subst_l (Var -> LintedType
tyVarKind Var
ktv)
                 ktv_kind_r :: LintedType
ktv_kind_r = HasDebugCallStack => Subst -> LintedType -> LintedType
Subst -> LintedType -> LintedType
substTy Subst
subst_r (Var -> LintedType
tyVarKind Var
ktv)
           ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (LintedType
sk' LintedType -> LintedType -> Bool
`eqType` LintedType
ktv_kind_l)
                    (SDoc -> LintM ()
bad_ax (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"check_ki1" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co, LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
sk', Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
ktv, LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ktv_kind_l ] ))
           ; Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (LintedType
tk' LintedType -> LintedType -> Bool
`eqType` LintedType
ktv_kind_r)
                    (SDoc -> LintM ()
bad_ax (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"check_ki2" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co, LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
tk', Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
ktv, LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ktv_kind_r ] ))
           ; (Subst, Subst) -> LintM (Subst, Subst)
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Subst -> Var -> LintedType -> Subst
extendTCvSubst Subst
subst_l Var
ktv LintedType
s',
                     Subst -> Var -> LintedType -> Subst
extendTCvSubst Subst
subst_r Var
ktv LintedType
t') }
lintCoercion (KindCo Coercion
co)
  = do { Coercion
co' <- Coercion -> LintM Coercion
lintCoercion Coercion
co
       ; Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Coercion -> Coercion
KindCo Coercion
co') }
lintCoercion (SubCo Coercion
co')
  = do { Coercion
co' <- Coercion -> LintM Coercion
lintCoercion Coercion
co'
       ; Coercion -> Role -> Role -> LintM ()
forall thing. Outputable thing => thing -> Role -> Role -> LintM ()
lintRole Coercion
co' Role
Nominal (Coercion -> Role
coercionRole Coercion
co')
       ; Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Coercion -> Coercion
SubCo Coercion
co') }
lintCoercion this :: Coercion
this@(AxiomRuleCo CoAxiomRule
ax [Coercion]
cos)
  = do { [Coercion]
cos' <- (Coercion -> LintM Coercion) -> [Coercion] -> LintM [Coercion]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Coercion -> LintM Coercion
lintCoercion [Coercion]
cos
       ; JoinArity -> [Role] -> [Coercion] -> LintM ()
lint_roles JoinArity
0 (CoAxiomRule -> [Role]
coaxrAsmpRoles CoAxiomRule
ax) [Coercion]
cos'
       ; case CoAxiomRule -> [Pair LintedType] -> Maybe (Pair LintedType)
coaxrProves CoAxiomRule
ax ((Coercion -> Pair LintedType) -> [Coercion] -> [Pair LintedType]
forall a b. (a -> b) -> [a] -> [b]
map Coercion -> Pair LintedType
coercionKind [Coercion]
cos') of
           Maybe (Pair LintedType)
Nothing -> String -> [SDoc] -> LintM Coercion
forall a. String -> [SDoc] -> LintM a
err String
"Malformed use of AxiomRuleCo" [ Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
this ]
           Just Pair LintedType
_  -> Coercion -> LintM Coercion
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (CoAxiomRule -> [Coercion] -> Coercion
AxiomRuleCo CoAxiomRule
ax [Coercion]
cos') }
  where
  err :: forall a. String -> [SDoc] -> LintM a
  err :: forall a. String -> [SDoc] -> LintM a
err String
m [SDoc]
xs  = SDoc -> LintM a
forall a. SDoc -> LintM a
failWithL (SDoc -> LintM a) -> SDoc -> LintM a
forall a b. (a -> b) -> a -> b
$
              SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
m) JoinArity
2 (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Rule:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> FastString -> SDoc
forall a. Outputable a => a -> SDoc
ppr (CoAxiomRule -> FastString
coaxrName CoAxiomRule
ax) SDoc -> [SDoc] -> [SDoc]
forall a. a -> [a] -> [a]
: [SDoc]
xs)
  lint_roles :: JoinArity -> [Role] -> [Coercion] -> LintM ()
lint_roles JoinArity
n (Role
e : [Role]
es) (Coercion
co : [Coercion]
cos)
    | Role
e Role -> Role -> Bool
forall a. Eq a => a -> a -> Bool
== Coercion -> Role
coercionRole Coercion
co = JoinArity -> [Role] -> [Coercion] -> LintM ()
lint_roles (JoinArity
nJoinArity -> JoinArity -> JoinArity
forall a. Num a => a -> a -> a
+JoinArity
1) [Role]
es [Coercion]
cos
    | Bool
otherwise = String -> [SDoc] -> LintM ()
forall a. String -> [SDoc] -> LintM a
err String
"Argument roles mismatch"
                      [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In argument:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> JoinArity -> SDoc
forall doc. IsLine doc => JoinArity -> doc
int (JoinArity
nJoinArity -> JoinArity -> JoinArity
forall a. Num a => a -> a -> a
+JoinArity
1)
                      , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Expected:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Role -> SDoc
forall a. Outputable a => a -> SDoc
ppr Role
e
                      , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Found:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Role -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Coercion -> Role
coercionRole Coercion
co) ]
  lint_roles JoinArity
_ [] []  = () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  lint_roles JoinArity
n [] [Coercion]
rs  = String -> [SDoc] -> LintM ()
forall a. String -> [SDoc] -> LintM a
err String
"Too many coercion arguments"
                          [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Expected:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> JoinArity -> SDoc
forall doc. IsLine doc => JoinArity -> doc
int JoinArity
n
                          , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Provided:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> JoinArity -> SDoc
forall doc. IsLine doc => JoinArity -> doc
int (JoinArity
n JoinArity -> JoinArity -> JoinArity
forall a. Num a => a -> a -> a
+ [Coercion] -> JoinArity
forall a. [a] -> JoinArity
forall (t :: * -> *) a. Foldable t => t a -> JoinArity
length [Coercion]
rs) ]
  lint_roles JoinArity
n [Role]
es []  = String -> [SDoc] -> LintM ()
forall a. String -> [SDoc] -> LintM a
err String
"Not enough coercion arguments"
                          [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Expected:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> JoinArity -> SDoc
forall doc. IsLine doc => JoinArity -> doc
int (JoinArity
n JoinArity -> JoinArity -> JoinArity
forall a. Num a => a -> a -> a
+ [Role] -> JoinArity
forall a. [a] -> JoinArity
forall (t :: * -> *) a. Foldable t => t a -> JoinArity
length [Role]
es)
                          , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Provided:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> JoinArity -> SDoc
forall doc. IsLine doc => JoinArity -> doc
int JoinArity
n ]
lintCoercion (HoleCo CoercionHole
h)
  = do { SDoc -> LintM ()
addErrL (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Unfilled coercion hole:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> CoercionHole -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoercionHole
h
       ; Coercion -> LintM Coercion
lintCoercion (Var -> Coercion
CoVarCo (CoercionHole -> Var
coHoleCoVar CoercionHole
h)) }
checkAxInstCo :: Coercion -> Maybe CoAxBranch
checkAxInstCo :: Coercion -> Maybe CoAxBranch
checkAxInstCo (AxiomInstCo CoAxiom Branched
ax JoinArity
ind [Coercion]
cos)
  = let branch :: CoAxBranch
branch       = CoAxiom Branched -> JoinArity -> CoAxBranch
forall (br :: BranchFlag). CoAxiom br -> JoinArity -> CoAxBranch
coAxiomNthBranch CoAxiom Branched
ax JoinArity
ind
        tvs :: [Var]
tvs          = CoAxBranch -> [Var]
coAxBranchTyVars CoAxBranch
branch
        cvs :: [Var]
cvs          = CoAxBranch -> [Var]
coAxBranchCoVars CoAxBranch
branch
        incomps :: [CoAxBranch]
incomps      = CoAxBranch -> [CoAxBranch]
coAxBranchIncomps CoAxBranch
branch
        ([LintedType]
tys, [LintedType]
cotys) = [Var] -> [LintedType] -> ([LintedType], [LintedType])
forall b a. [b] -> [a] -> ([a], [a])
splitAtList [Var]
tvs ((Coercion -> LintedType) -> [Coercion] -> [LintedType]
forall a b. (a -> b) -> [a] -> [b]
map Coercion -> LintedType
coercionLKind [Coercion]
cos)
        co_args :: [Coercion]
co_args      = (LintedType -> Coercion) -> [LintedType] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map LintedType -> Coercion
stripCoercionTy [LintedType]
cotys
        subst :: Subst
subst        = [Var] -> [LintedType] -> Subst
HasDebugCallStack => [Var] -> [LintedType] -> Subst
zipTvSubst [Var]
tvs [LintedType]
tys Subst -> Subst -> Subst
`composeTCvSubst`
                       [Var] -> [Coercion] -> Subst
HasDebugCallStack => [Var] -> [Coercion] -> Subst
zipCvSubst [Var]
cvs [Coercion]
co_args
        target :: [LintedType]
target   = HasDebugCallStack => Subst -> [LintedType] -> [LintedType]
Subst -> [LintedType] -> [LintedType]
Type.substTys Subst
subst (CoAxBranch -> [LintedType]
coAxBranchLHS CoAxBranch
branch)
        in_scope :: InScopeSet
in_scope = IdSet -> InScopeSet
mkInScopeSet (IdSet -> InScopeSet) -> IdSet -> InScopeSet
forall a b. (a -> b) -> a -> b
$
                   [IdSet] -> IdSet
unionVarSets ((CoAxBranch -> IdSet) -> [CoAxBranch] -> [IdSet]
forall a b. (a -> b) -> [a] -> [b]
map ([LintedType] -> IdSet
tyCoVarsOfTypes ([LintedType] -> IdSet)
-> (CoAxBranch -> [LintedType]) -> CoAxBranch -> IdSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CoAxBranch -> [LintedType]
coAxBranchLHS) [CoAxBranch]
incomps)
        flattened_target :: [LintedType]
flattened_target = InScopeSet -> [LintedType] -> [LintedType]
flattenTys InScopeSet
in_scope [LintedType]
target in
    [LintedType] -> [CoAxBranch] -> Maybe CoAxBranch
check_no_conflict [LintedType]
flattened_target [CoAxBranch]
incomps
  where
    check_no_conflict :: [Type] -> [CoAxBranch] -> Maybe CoAxBranch
    check_no_conflict :: [LintedType] -> [CoAxBranch] -> Maybe CoAxBranch
check_no_conflict [LintedType]
_    [] = Maybe CoAxBranch
forall a. Maybe a
Nothing
    check_no_conflict [LintedType]
flat (b :: CoAxBranch
b@CoAxBranch { cab_lhs :: CoAxBranch -> [LintedType]
cab_lhs = [LintedType]
lhs_incomp } : [CoAxBranch]
rest)
         
      | UnifyResultM Subst
SurelyApart <- BindFun -> [LintedType] -> [LintedType] -> UnifyResultM Subst
tcUnifyTysFG BindFun
alwaysBindFun [LintedType]
flat [LintedType]
lhs_incomp
      = [LintedType] -> [CoAxBranch] -> Maybe CoAxBranch
check_no_conflict [LintedType]
flat [CoAxBranch]
rest
      | Bool
otherwise
      = CoAxBranch -> Maybe CoAxBranch
forall a. a -> Maybe a
Just CoAxBranch
b
checkAxInstCo Coercion
_ = Maybe CoAxBranch
forall a. Maybe a
Nothing
lintAxioms :: Logger
           -> LintConfig
           -> SDoc 
           -> [CoAxiom Branched]
           -> IO ()
lintAxioms :: Logger -> LintConfig -> SDoc -> [CoAxiom Branched] -> IO ()
lintAxioms Logger
logger LintConfig
cfg SDoc
what [CoAxiom Branched]
axioms =
  Logger -> Bool -> SDoc -> SDoc -> WarnsAndErrs -> IO ()
displayLintResults Logger
logger Bool
True SDoc
what ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (CoAxiom Branched -> SDoc) -> [CoAxiom Branched] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map CoAxiom Branched -> SDoc
forall (br :: BranchFlag). CoAxiom br -> SDoc
pprCoAxiom [CoAxiom Branched]
axioms) (WarnsAndErrs -> IO ()) -> WarnsAndErrs -> IO ()
forall a b. (a -> b) -> a -> b
$
  LintConfig -> LintM () -> WarnsAndErrs
forall a. LintConfig -> LintM a -> WarnsAndErrs
initL LintConfig
cfg (LintM () -> WarnsAndErrs) -> LintM () -> WarnsAndErrs
forall a b. (a -> b) -> a -> b
$
  do { (CoAxiom Branched -> LintM ()) -> [CoAxiom Branched] -> LintM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ CoAxiom Branched -> LintM ()
lint_axiom [CoAxiom Branched]
axioms
     ; let axiom_groups :: [NonEmpty (CoAxiom Branched)]
axiom_groups = (CoAxiom Branched -> TyCon)
-> [CoAxiom Branched] -> [NonEmpty (CoAxiom Branched)]
forall (f :: * -> *) b a.
(Foldable f, Eq b) =>
(a -> b) -> f a -> [NonEmpty a]
groupWith CoAxiom Branched -> TyCon
forall (br :: BranchFlag). CoAxiom br -> TyCon
coAxiomTyCon [CoAxiom Branched]
axioms
     ; (NonEmpty (CoAxiom Branched) -> LintM ())
-> [NonEmpty (CoAxiom Branched)] -> LintM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ NonEmpty (CoAxiom Branched) -> LintM ()
lint_axiom_group [NonEmpty (CoAxiom Branched)]
axiom_groups }
lint_axiom :: CoAxiom Branched -> LintM ()
lint_axiom :: CoAxiom Branched -> LintM ()
lint_axiom ax :: CoAxiom Branched
ax@(CoAxiom { co_ax_tc :: forall (br :: BranchFlag). CoAxiom br -> TyCon
co_ax_tc = TyCon
tc, co_ax_branches :: forall (br :: BranchFlag). CoAxiom br -> Branches br
co_ax_branches = Branches Branched
branches
                       , co_ax_role :: forall (br :: BranchFlag). CoAxiom br -> Role
co_ax_role = Role
ax_role })
  = LintLocInfo -> LintM () -> LintM ()
forall a. LintLocInfo -> LintM a -> LintM a
addLoc (CoAxiom Branched -> LintLocInfo
InAxiom CoAxiom Branched
ax) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$
    do { (CoAxBranch -> LintM ()) -> [CoAxBranch] -> LintM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (TyCon -> CoAxBranch -> LintM ()
lint_branch TyCon
tc) [CoAxBranch]
branch_list
       ; LintM ()
extra_checks }
  where
    branch_list :: [CoAxBranch]
branch_list = Branches Branched -> [CoAxBranch]
forall (br :: BranchFlag). Branches br -> [CoAxBranch]
fromBranches Branches Branched
branches
    extra_checks :: LintM ()
extra_checks
      | TyCon -> Bool
isNewTyCon TyCon
tc
      = do { CoAxBranch { cab_tvs :: CoAxBranch -> [Var]
cab_tvs     = [Var]
tvs
                        , cab_eta_tvs :: CoAxBranch -> [Var]
cab_eta_tvs = [Var]
eta_tvs
                        , cab_cvs :: CoAxBranch -> [Var]
cab_cvs     = [Var]
cvs
                        , cab_roles :: CoAxBranch -> [Role]
cab_roles   = [Role]
roles
                        , cab_lhs :: CoAxBranch -> [LintedType]
cab_lhs     = [LintedType]
lhs_tys }
              <- case [CoAxBranch]
branch_list of
               [CoAxBranch
branch] -> CoAxBranch -> LintM CoAxBranch
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return CoAxBranch
branch
               [CoAxBranch]
_        -> SDoc -> LintM CoAxBranch
forall a. SDoc -> LintM a
failWithL (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"multi-branch axiom with newtype")
           ; let ax_lhs :: LintedType
ax_lhs = [Var] -> LintedType -> LintedType
mkInfForAllTys [Var]
tvs (LintedType -> LintedType) -> LintedType -> LintedType
forall a b. (a -> b) -> a -> b
$
                          TyCon -> [LintedType] -> LintedType
mkTyConApp TyCon
tc [LintedType]
lhs_tys
                 nt_tvs :: [Var]
nt_tvs = [Var] -> [Var] -> [Var]
forall b a. [b] -> [a] -> [a]
takeList [Var]
tvs (TyCon -> [Var]
tyConTyVars TyCon
tc)
                    
                 nt_lhs :: LintedType
nt_lhs = [Var] -> LintedType -> LintedType
mkInfForAllTys [Var]
nt_tvs (LintedType -> LintedType) -> LintedType -> LintedType
forall a b. (a -> b) -> a -> b
$
                          TyCon -> [LintedType] -> LintedType
mkTyConApp TyCon
tc ([Var] -> [LintedType]
mkTyVarTys [Var]
nt_tvs)
                 
           ; Bool -> SDoc -> LintM ()
lintL (LintedType
ax_lhs LintedType -> LintedType -> Bool
`eqType` LintedType
nt_lhs)
                   (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Newtype axiom LHS does not match newtype definition")
           ; Bool -> SDoc -> LintM ()
lintL ([Var] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Var]
cvs)
                   (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Newtype axiom binds coercion variables")
           ; Bool -> SDoc -> LintM ()
lintL ([Var] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Var]
eta_tvs)  
                                   
                   (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Newtype axiom has eta-tvs")
           ; Bool -> SDoc -> LintM ()
lintL (Role
ax_role Role -> Role -> Bool
forall a. Eq a => a -> a -> Bool
== Role
Representational)
                   (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Newtype axiom role not representational")
           ; Bool -> SDoc -> LintM ()
lintL ([Role]
roles [Role] -> [Var] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [Var]
tvs)
                   (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Newtype axiom roles list is the wrong length." SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$
                    String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"roles:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep ((Role -> SDoc) -> [Role] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Role -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Role]
roles))
           ; Bool -> SDoc -> LintM ()
lintL ([Role]
roles [Role] -> [Role] -> Bool
forall a. Eq a => a -> a -> Bool
== [Role] -> [Role] -> [Role]
forall b a. [b] -> [a] -> [a]
takeList [Role]
roles (TyCon -> [Role]
tyConRoles TyCon
tc))
                   ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Newtype axiom roles do not match newtype tycon's."
                         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"axiom roles:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep ((Role -> SDoc) -> [Role] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Role -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Role]
roles)
                         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"tycon roles:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep ((Role -> SDoc) -> [Role] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Role -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TyCon -> [Role]
tyConRoles TyCon
tc)) ])
           }
      | TyCon -> Bool
isFamilyTyCon TyCon
tc
      = do { if | TyCon -> Bool
isTypeFamilyTyCon TyCon
tc
                  -> Bool -> SDoc -> LintM ()
lintL (Role
ax_role Role -> Role -> Bool
forall a. Eq a => a -> a -> Bool
== Role
Nominal)
                           (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"type family axiom is not nominal")
                | TyCon -> Bool
isDataFamilyTyCon TyCon
tc
                  -> Bool -> SDoc -> LintM ()
lintL (Role
ax_role Role -> Role -> Bool
forall a. Eq a => a -> a -> Bool
== Role
Representational)
                           (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"data family axiom is not representational")
                | Bool
otherwise
                  -> SDoc -> LintM ()
addErrL (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"A family TyCon is neither a type family nor a data family:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc)
           ; (CoAxBranch -> LintM ()) -> [CoAxBranch] -> LintM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (TyCon -> CoAxBranch -> LintM ()
lint_family_branch TyCon
tc) [CoAxBranch]
branch_list }
      | Bool
otherwise
      = SDoc -> LintM ()
addErrL (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Axiom tycon is neither a newtype nor a family.")
lint_branch :: TyCon -> CoAxBranch -> LintM ()
lint_branch :: TyCon -> CoAxBranch -> LintM ()
lint_branch TyCon
ax_tc (CoAxBranch { cab_tvs :: CoAxBranch -> [Var]
cab_tvs = [Var]
tvs, cab_cvs :: CoAxBranch -> [Var]
cab_cvs = [Var]
cvs
                              , cab_lhs :: CoAxBranch -> [LintedType]
cab_lhs = [LintedType]
lhs_args, cab_rhs :: CoAxBranch -> LintedType
cab_rhs = LintedType
rhs })
  = BindingSite -> [Var] -> ([Var] -> LintM ()) -> LintM ()
forall a. BindingSite -> [Var] -> ([Var] -> LintM a) -> LintM a
lintBinders BindingSite
LambdaBind ([Var]
tvs [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ [Var]
cvs) (([Var] -> LintM ()) -> LintM ())
-> ([Var] -> LintM ()) -> LintM ()
forall a b. (a -> b) -> a -> b
$ \[Var]
_ ->
    do { let lhs :: LintedType
lhs = TyCon -> [LintedType] -> LintedType
mkTyConApp TyCon
ax_tc [LintedType]
lhs_args
       ; LintedType
lhs' <- LintedType -> LintM LintedType
lintType LintedType
lhs
       ; LintedType
rhs' <- LintedType -> LintM LintedType
lintType LintedType
rhs
       ; let lhs_kind :: LintedType
lhs_kind = HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
lhs'
             rhs_kind :: LintedType
rhs_kind = HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
rhs'
       ; Bool -> SDoc -> LintM ()
lintL (Bool -> Bool
not (LintedType
lhs_kind LintedType -> LintedType -> Bool
`typesAreApart` LintedType
rhs_kind)) (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
         SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Inhomogeneous axiom")
            JoinArity
2 (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"lhs:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
lhs SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
lhs_kind SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$
               String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"rhs:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
rhs SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
rhs_kind) }
         
         
         
         
lint_family_branch :: TyCon -> CoAxBranch -> LintM ()
lint_family_branch :: TyCon -> CoAxBranch -> LintM ()
lint_family_branch TyCon
fam_tc br :: CoAxBranch
br@(CoAxBranch { cab_tvs :: CoAxBranch -> [Var]
cab_tvs     = [Var]
tvs
                                         , cab_eta_tvs :: CoAxBranch -> [Var]
cab_eta_tvs = [Var]
eta_tvs
                                         , cab_cvs :: CoAxBranch -> [Var]
cab_cvs     = [Var]
cvs
                                         , cab_roles :: CoAxBranch -> [Role]
cab_roles   = [Role]
roles
                                         , cab_lhs :: CoAxBranch -> [LintedType]
cab_lhs     = [LintedType]
lhs
                                         , cab_incomps :: CoAxBranch -> [CoAxBranch]
cab_incomps = [CoAxBranch]
incomps })
  = do { Bool -> SDoc -> LintM ()
lintL (TyCon -> Bool
isDataFamilyTyCon TyCon
fam_tc Bool -> Bool -> Bool
|| [Var] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Var]
eta_tvs)
               (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Type family axiom has eta-tvs")
       ; Bool -> SDoc -> LintM ()
lintL ((Var -> Bool) -> [Var] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Var -> IdSet -> Bool
`elemVarSet` [LintedType] -> IdSet
tyCoVarsOfTypes [LintedType]
lhs) [Var]
tvs)
               (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Quantified variable in family axiom unused in LHS")
       ; Bool -> SDoc -> LintM ()
lintL ((LintedType -> Bool) -> [LintedType] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all LintedType -> Bool
isTyFamFree [LintedType]
lhs)
               (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Type family application on LHS of family axiom")
       ; Bool -> SDoc -> LintM ()
lintL ((Role -> Bool) -> [Role] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Role -> Role -> Bool
forall a. Eq a => a -> a -> Bool
== Role
Nominal) [Role]
roles)
               (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Non-nominal role in family axiom" SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$
                String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"roles:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep ((Role -> SDoc) -> [Role] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Role -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Role]
roles))
       ; Bool -> SDoc -> LintM ()
lintL ([Var] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Var]
cvs)
               (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Coercion variables bound in family axiom")
       ; [CoAxBranch] -> (CoAxBranch -> LintM ()) -> LintM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [CoAxBranch]
incomps ((CoAxBranch -> LintM ()) -> LintM ())
-> (CoAxBranch -> LintM ()) -> LintM ()
forall a b. (a -> b) -> a -> b
$ \ CoAxBranch
br' ->
           Bool -> SDoc -> LintM ()
lintL (Bool -> Bool
not (CoAxBranch -> CoAxBranch -> Bool
compatibleBranches CoAxBranch
br CoAxBranch
br')) (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
           SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Incorrect incompatible branches:")
              JoinArity
2 ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Branch:"       SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> CoAxBranch -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoAxBranch
br,
                       String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Bogus incomp:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> CoAxBranch -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoAxBranch
br']) }
lint_axiom_group :: NonEmpty (CoAxiom Branched) -> LintM ()
lint_axiom_group :: NonEmpty (CoAxiom Branched) -> LintM ()
lint_axiom_group (CoAxiom Branched
_  :| []) = () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
lint_axiom_group (CoAxiom Branched
ax :| [CoAxiom Branched]
axs)
  = do { Bool -> SDoc -> LintM ()
lintL (TyCon -> Bool
isOpenFamilyTyCon TyCon
tc)
               (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Non-open-family with multiple axioms")
       ; let all_pairs :: [(CoAxiom Branched, CoAxiom Branched)]
all_pairs = [ (CoAxiom Branched
ax1, CoAxiom Branched
ax2) | CoAxiom Branched
ax1 <- [CoAxiom Branched]
all_axs
                                      , CoAxiom Branched
ax2 <- [CoAxiom Branched]
all_axs ]
       ; ((CoAxiom Branched, CoAxiom Branched) -> LintM ())
-> [(CoAxiom Branched, CoAxiom Branched)] -> LintM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (TyCon -> (CoAxiom Branched, CoAxiom Branched) -> LintM ()
lint_axiom_pair TyCon
tc) [(CoAxiom Branched, CoAxiom Branched)]
all_pairs }
  where
    all_axs :: [CoAxiom Branched]
all_axs = CoAxiom Branched
ax CoAxiom Branched -> [CoAxiom Branched] -> [CoAxiom Branched]
forall a. a -> [a] -> [a]
: [CoAxiom Branched]
axs
    tc :: TyCon
tc      = CoAxiom Branched -> TyCon
forall (br :: BranchFlag). CoAxiom br -> TyCon
coAxiomTyCon CoAxiom Branched
ax
lint_axiom_pair :: TyCon -> (CoAxiom Branched, CoAxiom Branched) -> LintM ()
lint_axiom_pair :: TyCon -> (CoAxiom Branched, CoAxiom Branched) -> LintM ()
lint_axiom_pair TyCon
tc (CoAxiom Branched
ax1, CoAxiom Branched
ax2)
  | Just br1 :: CoAxBranch
br1@(CoAxBranch { cab_tvs :: CoAxBranch -> [Var]
cab_tvs = [Var]
tvs1
                         , cab_lhs :: CoAxBranch -> [LintedType]
cab_lhs = [LintedType]
lhs1
                         , cab_rhs :: CoAxBranch -> LintedType
cab_rhs = LintedType
rhs1 }) <- CoAxiom Branched -> Maybe CoAxBranch
forall (br :: BranchFlag). CoAxiom br -> Maybe CoAxBranch
coAxiomSingleBranch_maybe CoAxiom Branched
ax1
  , Just br2 :: CoAxBranch
br2@(CoAxBranch { cab_tvs :: CoAxBranch -> [Var]
cab_tvs = [Var]
tvs2
                         , cab_lhs :: CoAxBranch -> [LintedType]
cab_lhs = [LintedType]
lhs2
                         , cab_rhs :: CoAxBranch -> LintedType
cab_rhs = LintedType
rhs2 }) <- CoAxiom Branched -> Maybe CoAxBranch
forall (br :: BranchFlag). CoAxiom br -> Maybe CoAxBranch
coAxiomSingleBranch_maybe CoAxiom Branched
ax2
  = Bool -> SDoc -> LintM ()
lintL (CoAxBranch -> CoAxBranch -> Bool
compatibleBranches CoAxBranch
br1 CoAxBranch
br2) (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$
    [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Axioms", CoAxiom Branched -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoAxiom Branched
ax1, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"and", CoAxiom Branched -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoAxiom Branched
ax2
                , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"are incompatible" ]
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"tvs1 =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [Var] -> SDoc
pprTyVars [Var]
tvs1
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"lhs1 =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TyCon -> [LintedType] -> LintedType
mkTyConApp TyCon
tc [LintedType]
lhs1)
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"rhs1 =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
rhs1
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"tvs2 =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [Var] -> SDoc
pprTyVars [Var]
tvs2
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"lhs2 =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TyCon -> [LintedType] -> LintedType
mkTyConApp TyCon
tc [LintedType]
lhs2)
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"rhs2 =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
rhs2 ]
  | Bool
otherwise
  = SDoc -> LintM ()
addErrL (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Open type family axiom has more than one branch: either" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+>
             CoAxiom Branched -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoAxiom Branched
ax1 SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"or" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> CoAxiom Branched -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoAxiom Branched
ax2)
data LintEnv
  = LE { LintEnv -> LintFlags
le_flags :: LintFlags       
       , LintEnv -> [LintLocInfo]
le_loc   :: [LintLocInfo]   
       , LintEnv -> Subst
le_subst :: Subst  
                               
            
            
            
            
            
       , LintEnv -> VarEnv (Var, LintedType)
le_ids   :: VarEnv (Id, LintedType)    
            
            
            
            
            
       , LintEnv -> IdSet
le_joins :: IdSet     
                               
                               
       , LintEnv -> NameEnv UsageEnv
le_ue_aliases :: NameEnv UsageEnv 
                                           
                                           
       , LintEnv -> Platform
le_platform   :: Platform         
       , LintEnv -> DiagOpts
le_diagOpts   :: DiagOpts         
       }
data LintFlags
  = LF { LintFlags -> Bool
lf_check_global_ids           :: Bool 
       , LintFlags -> Bool
lf_check_inline_loop_breakers :: Bool 
       , LintFlags -> StaticPtrCheck
lf_check_static_ptrs :: StaticPtrCheck 
       , LintFlags -> Bool
lf_report_unsat_syns :: Bool 
       , LintFlags -> Bool
lf_check_linearity :: Bool 
       , LintFlags -> Bool
lf_check_fixed_rep :: Bool 
    }
data StaticPtrCheck
    = AllowAnywhere
        
    | AllowAtTopLevel
        
    | RejectEverywhere
        
  deriving StaticPtrCheck -> StaticPtrCheck -> Bool
(StaticPtrCheck -> StaticPtrCheck -> Bool)
-> (StaticPtrCheck -> StaticPtrCheck -> Bool) -> Eq StaticPtrCheck
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StaticPtrCheck -> StaticPtrCheck -> Bool
== :: StaticPtrCheck -> StaticPtrCheck -> Bool
$c/= :: StaticPtrCheck -> StaticPtrCheck -> Bool
/= :: StaticPtrCheck -> StaticPtrCheck -> Bool
Eq
newtype LintM a =
   LintM' { forall a. LintM a -> LintEnv -> WarnsAndErrs -> LResult a
unLintM ::
            LintEnv ->
            WarnsAndErrs ->           
            LResult a } 
pattern LintM :: (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
pattern $mLintM :: forall {r} {a}.
LintM a
-> ((LintEnv -> WarnsAndErrs -> LResult a) -> r)
-> ((# #) -> r)
-> r
$bLintM :: forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM m <- LintM' m
  where
    LintM LintEnv -> WarnsAndErrs -> LResult a
m = (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM' ((LintEnv -> WarnsAndErrs -> LResult a)
-> LintEnv -> WarnsAndErrs -> LResult a
forall a b. (a -> b) -> a -> b
oneShot ((LintEnv -> WarnsAndErrs -> LResult a)
 -> LintEnv -> WarnsAndErrs -> LResult a)
-> (LintEnv -> WarnsAndErrs -> LResult a)
-> LintEnv
-> WarnsAndErrs
-> LResult a
forall a b. (a -> b) -> a -> b
$ \LintEnv
env -> (WarnsAndErrs -> LResult a) -> WarnsAndErrs -> LResult a
forall a b. (a -> b) -> a -> b
oneShot ((WarnsAndErrs -> LResult a) -> WarnsAndErrs -> LResult a)
-> (WarnsAndErrs -> LResult a) -> WarnsAndErrs -> LResult a
forall a b. (a -> b) -> a -> b
$ \WarnsAndErrs
we -> LintEnv -> WarnsAndErrs -> LResult a
m LintEnv
env WarnsAndErrs
we)
    
{-# COMPLETE LintM #-}
instance Functor (LintM) where
  fmap :: forall a b. (a -> b) -> LintM a -> LintM b
fmap a -> b
f (LintM LintEnv -> WarnsAndErrs -> LResult a
m) = (LintEnv -> WarnsAndErrs -> LResult b) -> LintM b
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM ((LintEnv -> WarnsAndErrs -> LResult b) -> LintM b)
-> (LintEnv -> WarnsAndErrs -> LResult b) -> LintM b
forall a b. (a -> b) -> a -> b
$ \LintEnv
e WarnsAndErrs
w -> (a -> b) -> LResult a -> LResult b
forall a1 a2. (a1 -> a2) -> LResult a1 -> LResult a2
mapLResult a -> b
f (LintEnv -> WarnsAndErrs -> LResult a
m LintEnv
e WarnsAndErrs
w)
type WarnsAndErrs = (Bag SDoc, Bag SDoc)
type LResult a = (# MaybeUB a, WarnsAndErrs #)
pattern LResult :: MaybeUB a -> WarnsAndErrs -> LResult a
pattern $mLResult :: forall {r} {a}.
LResult a -> (MaybeUB a -> WarnsAndErrs -> r) -> ((# #) -> r) -> r
$bLResult :: forall a. MaybeUB a -> WarnsAndErrs -> LResult a
LResult m w = (# m, w #)
{-# COMPLETE LResult #-}
mapLResult :: (a1 -> a2) -> LResult a1 -> LResult a2
mapLResult :: forall a1 a2. (a1 -> a2) -> LResult a1 -> LResult a2
mapLResult a1 -> a2
f (LResult MaybeUB a1
r WarnsAndErrs
w) = MaybeUB a2 -> WarnsAndErrs -> LResult a2
forall a. MaybeUB a -> WarnsAndErrs -> LResult a
LResult ((a1 -> a2) -> MaybeUB a1 -> MaybeUB a2
forall a b. (a -> b) -> MaybeUB a -> MaybeUB b
fmapMaybeUB a1 -> a2
f MaybeUB a1
r) WarnsAndErrs
w
fromBoxedLResult :: (Maybe a, WarnsAndErrs) -> LResult a
fromBoxedLResult :: forall a. (Maybe a, WarnsAndErrs) -> LResult a
fromBoxedLResult (Just a
x, WarnsAndErrs
errs) = MaybeUB a -> WarnsAndErrs -> LResult a
forall a. MaybeUB a -> WarnsAndErrs -> LResult a
LResult (a -> MaybeUB a
forall a. a -> MaybeUB a
JustUB a
x) WarnsAndErrs
errs
fromBoxedLResult (Maybe a
Nothing,WarnsAndErrs
errs) = MaybeUB a -> WarnsAndErrs -> LResult a
forall a. MaybeUB a -> WarnsAndErrs -> LResult a
LResult (# #) -> forall a. MaybeUB a
forall a. MaybeUB a
NothingUB WarnsAndErrs
errs
instance Applicative LintM where
      pure :: forall a. a -> LintM a
pure a
x = (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM ((LintEnv -> WarnsAndErrs -> LResult a) -> LintM a)
-> (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a b. (a -> b) -> a -> b
$ \ LintEnv
_ WarnsAndErrs
errs -> MaybeUB a -> WarnsAndErrs -> LResult a
forall a. MaybeUB a -> WarnsAndErrs -> LResult a
LResult (a -> MaybeUB a
forall a. a -> MaybeUB a
JustUB a
x) WarnsAndErrs
errs
                                   
      <*> :: forall a b. LintM (a -> b) -> LintM a -> LintM b
(<*>) = LintM (a -> b) -> LintM a -> LintM b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
instance Monad LintM where
  LintM a
m >>= :: forall a b. LintM a -> (a -> LintM b) -> LintM b
>>= a -> LintM b
k  = (LintEnv -> WarnsAndErrs -> LResult b) -> LintM b
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM (\ LintEnv
env WarnsAndErrs
errs ->
                       let res :: LResult a
res = LintM a -> LintEnv -> WarnsAndErrs -> LResult a
forall a. LintM a -> LintEnv -> WarnsAndErrs -> LResult a
unLintM LintM a
m LintEnv
env WarnsAndErrs
errs in
                         case LResult a
res of
                           LResult (JustUB a
r) WarnsAndErrs
errs' -> LintM b -> LintEnv -> WarnsAndErrs -> LResult b
forall a. LintM a -> LintEnv -> WarnsAndErrs -> LResult a
unLintM (a -> LintM b
k a
r) LintEnv
env WarnsAndErrs
errs'
                           LResult MaybeUB a
NothingUB WarnsAndErrs
errs' -> MaybeUB b -> WarnsAndErrs -> LResult b
forall a. MaybeUB a -> WarnsAndErrs -> LResult a
LResult (# #) -> forall a. MaybeUB a
forall a. MaybeUB a
NothingUB WarnsAndErrs
errs'
                    )
                          
                      
                          
                          
instance MonadFail LintM where
    fail :: forall a. String -> LintM a
fail String
err = SDoc -> LintM a
forall a. SDoc -> LintM a
failWithL (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
err)
getPlatform :: LintM Platform
getPlatform :: LintM Platform
getPlatform = (LintEnv -> WarnsAndErrs -> LResult Platform) -> LintM Platform
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM (\ LintEnv
e WarnsAndErrs
errs -> (MaybeUB Platform -> WarnsAndErrs -> LResult Platform
forall a. MaybeUB a -> WarnsAndErrs -> LResult a
LResult (Platform -> MaybeUB Platform
forall a. a -> MaybeUB a
JustUB (Platform -> MaybeUB Platform) -> Platform -> MaybeUB Platform
forall a b. (a -> b) -> a -> b
$ LintEnv -> Platform
le_platform LintEnv
e) WarnsAndErrs
errs))
data LintLocInfo
  = RhsOf Id            
  | OccOf Id            
  | LambdaBodyOf Id     
  | RuleOf Id           
  | UnfoldingOf Id      
  | BodyOfLetRec [Id]   
  | CaseAlt CoreAlt     
  | CasePat CoreAlt     
  | CaseTy CoreExpr     
                        
  | IdTy Id             
  | AnExpr CoreExpr     
  | ImportedUnfolding SrcLoc 
  | TopLevelBindings
  | InType Type         
  | InCo   Coercion     
  | InAxiom (CoAxiom Branched)   
data LintConfig = LintConfig
  { LintConfig -> DiagOpts
l_diagOpts   :: !DiagOpts         
  , LintConfig -> Platform
l_platform   :: !Platform         
  , LintConfig -> LintFlags
l_flags      :: !LintFlags        
  , LintConfig -> [Var]
l_vars       :: ![Var]            
  }
initL :: LintConfig
      -> LintM a            
      -> WarnsAndErrs
initL :: forall a. LintConfig -> LintM a -> WarnsAndErrs
initL LintConfig
cfg LintM a
m
  = case LintM a -> LintEnv -> WarnsAndErrs -> LResult a
forall a. LintM a -> LintEnv -> WarnsAndErrs -> LResult a
unLintM LintM a
m LintEnv
env (Bag SDoc
forall a. Bag a
emptyBag, Bag SDoc
forall a. Bag a
emptyBag) of
      LResult (JustUB a
_) WarnsAndErrs
errs -> WarnsAndErrs
errs
      LResult MaybeUB a
NothingUB errs :: WarnsAndErrs
errs@(Bag SDoc
_, Bag SDoc
e) | Bool -> Bool
not (Bag SDoc -> Bool
forall a. Bag a -> Bool
isEmptyBag Bag SDoc
e) -> WarnsAndErrs
errs
                                    | Bool
otherwise -> String -> SDoc -> WarnsAndErrs
forall a. HasCallStack => String -> SDoc -> a
pprPanic (String
"Bug in Lint: a failure occurred " String -> String -> String
forall a. [a] -> [a] -> [a]
++
                                                      String
"without reporting an error message") SDoc
forall doc. IsOutput doc => doc
empty
  where
    ([Var]
tcvs, [Var]
ids) = (Var -> Bool) -> [Var] -> ([Var], [Var])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Var -> Bool
isTyCoVar ([Var] -> ([Var], [Var])) -> [Var] -> ([Var], [Var])
forall a b. (a -> b) -> a -> b
$ LintConfig -> [Var]
l_vars LintConfig
cfg
    env :: LintEnv
env = LE { le_flags :: LintFlags
le_flags = LintConfig -> LintFlags
l_flags LintConfig
cfg
             , le_subst :: Subst
le_subst = InScopeSet -> Subst
mkEmptySubst ([Var] -> InScopeSet
mkInScopeSetList [Var]
tcvs)
             , le_ids :: VarEnv (Var, LintedType)
le_ids   = [(Var, (Var, LintedType))] -> VarEnv (Var, LintedType)
forall a. [(Var, a)] -> VarEnv a
mkVarEnv [(Var
id, (Var
id,Var -> LintedType
idType Var
id)) | Var
id <- [Var]
ids]
             , le_joins :: IdSet
le_joins = IdSet
emptyVarSet
             , le_loc :: [LintLocInfo]
le_loc = []
             , le_ue_aliases :: NameEnv UsageEnv
le_ue_aliases = NameEnv UsageEnv
forall a. NameEnv a
emptyNameEnv
             , le_platform :: Platform
le_platform = LintConfig -> Platform
l_platform LintConfig
cfg
             , le_diagOpts :: DiagOpts
le_diagOpts = LintConfig -> DiagOpts
l_diagOpts LintConfig
cfg
             }
setReportUnsat :: Bool -> LintM a -> LintM a
setReportUnsat :: forall a. Bool -> LintM a -> LintM a
setReportUnsat Bool
ru LintM a
thing_inside
  = (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM ((LintEnv -> WarnsAndErrs -> LResult a) -> LintM a)
-> (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a b. (a -> b) -> a -> b
$ \ LintEnv
env WarnsAndErrs
errs ->
    let env' :: LintEnv
env' = LintEnv
env { le_flags = (le_flags env) { lf_report_unsat_syns = ru } }
    in LintM a -> LintEnv -> WarnsAndErrs -> LResult a
forall a. LintM a -> LintEnv -> WarnsAndErrs -> LResult a
unLintM LintM a
thing_inside LintEnv
env' WarnsAndErrs
errs
noFixedRuntimeRepChecks :: LintM a -> LintM a
noFixedRuntimeRepChecks :: forall a. LintM a -> LintM a
noFixedRuntimeRepChecks LintM a
thing_inside
  = (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM ((LintEnv -> WarnsAndErrs -> LResult a) -> LintM a)
-> (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a b. (a -> b) -> a -> b
$ \LintEnv
env WarnsAndErrs
errs ->
    let env' :: LintEnv
env' = LintEnv
env { le_flags = (le_flags env) { lf_check_fixed_rep = False } }
    in LintM a -> LintEnv -> WarnsAndErrs -> LResult a
forall a. LintM a -> LintEnv -> WarnsAndErrs -> LResult a
unLintM LintM a
thing_inside LintEnv
env' WarnsAndErrs
errs
getLintFlags :: LintM LintFlags
getLintFlags :: LintM LintFlags
getLintFlags = (LintEnv -> WarnsAndErrs -> LResult LintFlags) -> LintM LintFlags
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM ((LintEnv -> WarnsAndErrs -> LResult LintFlags) -> LintM LintFlags)
-> (LintEnv -> WarnsAndErrs -> LResult LintFlags)
-> LintM LintFlags
forall a b. (a -> b) -> a -> b
$ \ LintEnv
env WarnsAndErrs
errs -> (Maybe LintFlags, WarnsAndErrs) -> LResult LintFlags
forall a. (Maybe a, WarnsAndErrs) -> LResult a
fromBoxedLResult (LintFlags -> Maybe LintFlags
forall a. a -> Maybe a
Just (LintEnv -> LintFlags
le_flags LintEnv
env), WarnsAndErrs
errs)
checkL :: Bool -> SDoc -> LintM ()
checkL :: Bool -> SDoc -> LintM ()
checkL Bool
True  SDoc
_   = () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
checkL Bool
False SDoc
msg = SDoc -> LintM ()
forall a. SDoc -> LintM a
failWithL SDoc
msg
lintL :: Bool -> SDoc -> LintM ()
lintL :: Bool -> SDoc -> LintM ()
lintL = Bool -> SDoc -> LintM ()
checkL
checkWarnL :: Bool -> SDoc -> LintM ()
checkWarnL :: Bool -> SDoc -> LintM ()
checkWarnL Bool
True   SDoc
_  = () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
checkWarnL Bool
False SDoc
msg = SDoc -> LintM ()
addWarnL SDoc
msg
failWithL :: SDoc -> LintM a
failWithL :: forall a. SDoc -> LintM a
failWithL SDoc
msg = (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM ((LintEnv -> WarnsAndErrs -> LResult a) -> LintM a)
-> (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a b. (a -> b) -> a -> b
$ \ LintEnv
env (Bag SDoc
warns,Bag SDoc
errs) ->
                (Maybe a, WarnsAndErrs) -> LResult a
forall a. (Maybe a, WarnsAndErrs) -> LResult a
fromBoxedLResult (Maybe a
forall a. Maybe a
Nothing, (Bag SDoc
warns, Bool -> LintEnv -> Bag SDoc -> SDoc -> Bag SDoc
addMsg Bool
True LintEnv
env Bag SDoc
errs SDoc
msg))
addErrL :: SDoc -> LintM ()
addErrL :: SDoc -> LintM ()
addErrL SDoc
msg = (LintEnv -> WarnsAndErrs -> LResult ()) -> LintM ()
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM ((LintEnv -> WarnsAndErrs -> LResult ()) -> LintM ())
-> (LintEnv -> WarnsAndErrs -> LResult ()) -> LintM ()
forall a b. (a -> b) -> a -> b
$ \ LintEnv
env (Bag SDoc
warns,Bag SDoc
errs) ->
              (Maybe (), WarnsAndErrs) -> LResult ()
forall a. (Maybe a, WarnsAndErrs) -> LResult a
fromBoxedLResult (() -> Maybe ()
forall a. a -> Maybe a
Just (), (Bag SDoc
warns, Bool -> LintEnv -> Bag SDoc -> SDoc -> Bag SDoc
addMsg Bool
True LintEnv
env Bag SDoc
errs SDoc
msg))
addWarnL :: SDoc -> LintM ()
addWarnL :: SDoc -> LintM ()
addWarnL SDoc
msg = (LintEnv -> WarnsAndErrs -> LResult ()) -> LintM ()
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM ((LintEnv -> WarnsAndErrs -> LResult ()) -> LintM ())
-> (LintEnv -> WarnsAndErrs -> LResult ()) -> LintM ()
forall a b. (a -> b) -> a -> b
$ \ LintEnv
env (Bag SDoc
warns,Bag SDoc
errs) ->
              (Maybe (), WarnsAndErrs) -> LResult ()
forall a. (Maybe a, WarnsAndErrs) -> LResult a
fromBoxedLResult (() -> Maybe ()
forall a. a -> Maybe a
Just (), (Bool -> LintEnv -> Bag SDoc -> SDoc -> Bag SDoc
addMsg Bool
False LintEnv
env Bag SDoc
warns SDoc
msg, Bag SDoc
errs))
addMsg :: Bool -> LintEnv ->  Bag SDoc -> SDoc -> Bag SDoc
addMsg :: Bool -> LintEnv -> Bag SDoc -> SDoc -> Bag SDoc
addMsg Bool
is_error LintEnv
env Bag SDoc
msgs SDoc
msg
  = Bool -> SDoc -> Bag SDoc -> Bag SDoc
forall a. HasCallStack => Bool -> SDoc -> a -> a
assertPpr ([(SrcLoc, SDoc)] -> Bool
forall (f :: * -> *) a. Foldable f => f a -> Bool
notNull [(SrcLoc, SDoc)]
loc_msgs) SDoc
msg (Bag SDoc -> Bag SDoc) -> Bag SDoc -> Bag SDoc
forall a b. (a -> b) -> a -> b
$
    Bag SDoc
msgs Bag SDoc -> SDoc -> Bag SDoc
forall a. Bag a -> a -> Bag a
`snocBag` SDoc -> SDoc
mk_msg SDoc
msg
  where
   loc_msgs :: [(SrcLoc, SDoc)]  
   loc_msgs :: [(SrcLoc, SDoc)]
loc_msgs = (LintLocInfo -> (SrcLoc, SDoc))
-> [LintLocInfo] -> [(SrcLoc, SDoc)]
forall a b. (a -> b) -> [a] -> [b]
map LintLocInfo -> (SrcLoc, SDoc)
dumpLoc (LintEnv -> [LintLocInfo]
le_loc LintEnv
env)
   cxt_doc :: SDoc
cxt_doc = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ [SDoc] -> [SDoc]
forall a. [a] -> [a]
reverse ([SDoc] -> [SDoc]) -> [SDoc] -> [SDoc]
forall a b. (a -> b) -> a -> b
$ ((SrcLoc, SDoc) -> SDoc) -> [(SrcLoc, SDoc)] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (SrcLoc, SDoc) -> SDoc
forall a b. (a, b) -> b
snd [(SrcLoc, SDoc)]
loc_msgs
                  , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Substitution:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Subst -> SDoc
forall a. Outputable a => a -> SDoc
ppr (LintEnv -> Subst
le_subst LintEnv
env) ]
   context :: SDoc
context | Bool
is_error  = SDoc
cxt_doc
           | Bool
otherwise = SDoc -> SDoc
forall doc. IsOutput doc => doc -> doc
whenPprDebug SDoc
cxt_doc
     
     
   msg_span :: SrcSpan
msg_span = case [ SrcSpan
span | (SrcLoc
loc,SDoc
_) <- [(SrcLoc, SDoc)]
loc_msgs
                          , let span :: SrcSpan
span = SrcLoc -> SrcSpan
srcLocSpan SrcLoc
loc
                          , SrcSpan -> Bool
isGoodSrcSpan SrcSpan
span ] of
               []    -> SrcSpan
noSrcSpan
               (SrcSpan
s:[SrcSpan]
_) -> SrcSpan
s
   !diag_opts :: DiagOpts
diag_opts = LintEnv -> DiagOpts
le_diagOpts LintEnv
env
   mk_msg :: SDoc -> SDoc
mk_msg SDoc
msg = MessageClass -> SrcSpan -> SDoc -> SDoc
mkLocMessage (DiagOpts
-> DiagnosticReason -> Maybe DiagnosticCode -> MessageClass
mkMCDiagnostic DiagOpts
diag_opts DiagnosticReason
WarningWithoutFlag Maybe DiagnosticCode
forall a. Maybe a
Nothing) SrcSpan
msg_span
                             (SDoc
msg SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ SDoc
context)
addLoc :: LintLocInfo -> LintM a -> LintM a
addLoc :: forall a. LintLocInfo -> LintM a -> LintM a
addLoc LintLocInfo
extra_loc LintM a
m
  = (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM ((LintEnv -> WarnsAndErrs -> LResult a) -> LintM a)
-> (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a b. (a -> b) -> a -> b
$ \ LintEnv
env WarnsAndErrs
errs ->
    LintM a -> LintEnv -> WarnsAndErrs -> LResult a
forall a. LintM a -> LintEnv -> WarnsAndErrs -> LResult a
unLintM LintM a
m (LintEnv
env { le_loc = extra_loc : le_loc env }) WarnsAndErrs
errs
inCasePat :: LintM Bool         
inCasePat :: LintM Bool
inCasePat = (LintEnv -> WarnsAndErrs -> LResult Bool) -> LintM Bool
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM ((LintEnv -> WarnsAndErrs -> LResult Bool) -> LintM Bool)
-> (LintEnv -> WarnsAndErrs -> LResult Bool) -> LintM Bool
forall a b. (a -> b) -> a -> b
$ \ LintEnv
env WarnsAndErrs
errs -> (Maybe Bool, WarnsAndErrs) -> LResult Bool
forall a. (Maybe a, WarnsAndErrs) -> LResult a
fromBoxedLResult (Bool -> Maybe Bool
forall a. a -> Maybe a
Just (LintEnv -> Bool
is_case_pat LintEnv
env), WarnsAndErrs
errs)
  where
    is_case_pat :: LintEnv -> Bool
is_case_pat (LE { le_loc :: LintEnv -> [LintLocInfo]
le_loc = CasePat {} : [LintLocInfo]
_ }) = Bool
True
    is_case_pat LintEnv
_other                           = Bool
False
addInScopeId :: Id -> LintedType -> LintM a -> LintM a
addInScopeId :: forall a. Var -> LintedType -> LintM a -> LintM a
addInScopeId Var
id LintedType
linted_ty LintM a
m
  = (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM ((LintEnv -> WarnsAndErrs -> LResult a) -> LintM a)
-> (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a b. (a -> b) -> a -> b
$ \ env :: LintEnv
env@(LE { le_ids :: LintEnv -> VarEnv (Var, LintedType)
le_ids = VarEnv (Var, LintedType)
id_set, le_joins :: LintEnv -> IdSet
le_joins = IdSet
join_set, le_ue_aliases :: LintEnv -> NameEnv UsageEnv
le_ue_aliases = NameEnv UsageEnv
aliases }) WarnsAndErrs
errs ->
    LintM a -> LintEnv -> WarnsAndErrs -> LResult a
forall a. LintM a -> LintEnv -> WarnsAndErrs -> LResult a
unLintM LintM a
m (LintEnv
env { le_ids   = extendVarEnv id_set id (id, linted_ty)
                   , le_joins = add_joins join_set
                   , le_ue_aliases = delFromNameEnv aliases (idName id) }) WarnsAndErrs
errs
                   
                   
                   
                   
  where
    add_joins :: IdSet -> IdSet
add_joins IdSet
join_set
      | Var -> Bool
isJoinId Var
id = IdSet -> Var -> IdSet
extendVarSet IdSet
join_set Var
id 
      | Bool
otherwise   = IdSet -> Var -> IdSet
delVarSet    IdSet
join_set Var
id 
getInScopeIds :: LintM (VarEnv (Id,LintedType))
getInScopeIds :: LintM (VarEnv (Var, LintedType))
getInScopeIds = (LintEnv -> WarnsAndErrs -> LResult (VarEnv (Var, LintedType)))
-> LintM (VarEnv (Var, LintedType))
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM (\LintEnv
env WarnsAndErrs
errs -> (Maybe (VarEnv (Var, LintedType)), WarnsAndErrs)
-> LResult (VarEnv (Var, LintedType))
forall a. (Maybe a, WarnsAndErrs) -> LResult a
fromBoxedLResult (VarEnv (Var, LintedType) -> Maybe (VarEnv (Var, LintedType))
forall a. a -> Maybe a
Just (LintEnv -> VarEnv (Var, LintedType)
le_ids LintEnv
env), WarnsAndErrs
errs))
extendTvSubstL :: TyVar -> Type -> LintM a -> LintM a
extendTvSubstL :: forall a. Var -> LintedType -> LintM a -> LintM a
extendTvSubstL Var
tv LintedType
ty LintM a
m
  = (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM ((LintEnv -> WarnsAndErrs -> LResult a) -> LintM a)
-> (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a b. (a -> b) -> a -> b
$ \ LintEnv
env WarnsAndErrs
errs ->
    LintM a -> LintEnv -> WarnsAndErrs -> LResult a
forall a. LintM a -> LintEnv -> WarnsAndErrs -> LResult a
unLintM LintM a
m (LintEnv
env { le_subst = Type.extendTvSubst (le_subst env) tv ty }) WarnsAndErrs
errs
updateSubst :: Subst -> LintM a -> LintM a
updateSubst :: forall a. Subst -> LintM a -> LintM a
updateSubst Subst
subst' LintM a
m
  = (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM ((LintEnv -> WarnsAndErrs -> LResult a) -> LintM a)
-> (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a b. (a -> b) -> a -> b
$ \ LintEnv
env WarnsAndErrs
errs -> LintM a -> LintEnv -> WarnsAndErrs -> LResult a
forall a. LintM a -> LintEnv -> WarnsAndErrs -> LResult a
unLintM LintM a
m (LintEnv
env { le_subst = subst' }) WarnsAndErrs
errs
markAllJoinsBad :: LintM a -> LintM a
markAllJoinsBad :: forall a. LintM a -> LintM a
markAllJoinsBad LintM a
m
  = (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM ((LintEnv -> WarnsAndErrs -> LResult a) -> LintM a)
-> (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a b. (a -> b) -> a -> b
$ \ LintEnv
env WarnsAndErrs
errs -> LintM a -> LintEnv -> WarnsAndErrs -> LResult a
forall a. LintM a -> LintEnv -> WarnsAndErrs -> LResult a
unLintM LintM a
m (LintEnv
env { le_joins = emptyVarSet }) WarnsAndErrs
errs
markAllJoinsBadIf :: Bool -> LintM a -> LintM a
markAllJoinsBadIf :: forall a. Bool -> LintM a -> LintM a
markAllJoinsBadIf Bool
True  LintM a
m = LintM a -> LintM a
forall a. LintM a -> LintM a
markAllJoinsBad LintM a
m
markAllJoinsBadIf Bool
False LintM a
m = LintM a
m
getValidJoins :: LintM IdSet
getValidJoins :: LintM IdSet
getValidJoins = (LintEnv -> WarnsAndErrs -> LResult IdSet) -> LintM IdSet
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM (\ LintEnv
env WarnsAndErrs
errs -> (Maybe IdSet, WarnsAndErrs) -> LResult IdSet
forall a. (Maybe a, WarnsAndErrs) -> LResult a
fromBoxedLResult (IdSet -> Maybe IdSet
forall a. a -> Maybe a
Just (LintEnv -> IdSet
le_joins LintEnv
env), WarnsAndErrs
errs))
getSubst :: LintM Subst
getSubst :: LintM Subst
getSubst = (LintEnv -> WarnsAndErrs -> LResult Subst) -> LintM Subst
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM (\ LintEnv
env WarnsAndErrs
errs -> (Maybe Subst, WarnsAndErrs) -> LResult Subst
forall a. (Maybe a, WarnsAndErrs) -> LResult a
fromBoxedLResult (Subst -> Maybe Subst
forall a. a -> Maybe a
Just (LintEnv -> Subst
le_subst LintEnv
env), WarnsAndErrs
errs))
getUEAliases :: LintM (NameEnv UsageEnv)
getUEAliases :: LintM (NameEnv UsageEnv)
getUEAliases = (LintEnv -> WarnsAndErrs -> LResult (NameEnv UsageEnv))
-> LintM (NameEnv UsageEnv)
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM (\ LintEnv
env WarnsAndErrs
errs -> (Maybe (NameEnv UsageEnv), WarnsAndErrs)
-> LResult (NameEnv UsageEnv)
forall a. (Maybe a, WarnsAndErrs) -> LResult a
fromBoxedLResult (NameEnv UsageEnv -> Maybe (NameEnv UsageEnv)
forall a. a -> Maybe a
Just (LintEnv -> NameEnv UsageEnv
le_ue_aliases LintEnv
env), WarnsAndErrs
errs))
getInScope :: LintM InScopeSet
getInScope :: LintM InScopeSet
getInScope = (LintEnv -> WarnsAndErrs -> LResult InScopeSet) -> LintM InScopeSet
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM (\ LintEnv
env WarnsAndErrs
errs -> (Maybe InScopeSet, WarnsAndErrs) -> LResult InScopeSet
forall a. (Maybe a, WarnsAndErrs) -> LResult a
fromBoxedLResult (InScopeSet -> Maybe InScopeSet
forall a. a -> Maybe a
Just (Subst -> InScopeSet
getSubstInScope (Subst -> InScopeSet) -> Subst -> InScopeSet
forall a b. (a -> b) -> a -> b
$ LintEnv -> Subst
le_subst LintEnv
env), WarnsAndErrs
errs))
lookupIdInScope :: Id -> LintM (Id, LintedType)
lookupIdInScope :: Var -> LintM (Var, LintedType)
lookupIdInScope Var
id_occ
  = do { VarEnv (Var, LintedType)
in_scope_ids <- LintM (VarEnv (Var, LintedType))
getInScopeIds
       ; case VarEnv (Var, LintedType) -> Var -> Maybe (Var, LintedType)
forall a. VarEnv a -> Var -> Maybe a
lookupVarEnv VarEnv (Var, LintedType)
in_scope_ids Var
id_occ of
           Just (Var
id_bndr, LintedType
linted_ty)
             -> do { Bool -> SDoc -> LintM ()
checkL (Bool -> Bool
not (Var -> Bool
bad_global Var
id_bndr)) (SDoc -> LintM ()) -> SDoc -> LintM ()
forall a b. (a -> b) -> a -> b
$ Var -> SDoc
global_in_scope Var
id_bndr
                   ; (Var, LintedType) -> LintM (Var, LintedType)
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Var
id_bndr, LintedType
linted_ty) }
           Maybe (Var, LintedType)
Nothing -> do { Bool -> SDoc -> LintM ()
checkL (Bool -> Bool
not Bool
is_local) SDoc
local_out_of_scope
                         ; (Var, LintedType) -> LintM (Var, LintedType)
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Var
id_occ, Var -> LintedType
idType Var
id_occ) } }
                      
                      
  where
    is_local :: Bool
is_local = Var -> Bool
mustHaveLocalBinding Var
id_occ
    local_out_of_scope :: SDoc
local_out_of_scope = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Out of scope:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> BindingSite -> Var -> SDoc
forall a. OutputableBndr a => BindingSite -> a -> SDoc
pprBndr BindingSite
LetBind Var
id_occ
    global_in_scope :: Var -> SDoc
global_in_scope Var
id_bndr = SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Occurrence is GlobalId, but binding is LocalId")
                                 JoinArity
2 (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"occurrence:") JoinArity
2 (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ BindingSite -> Var -> SDoc
forall a. OutputableBndr a => BindingSite -> a -> SDoc
pprBndr BindingSite
LetBind Var
id_occ
                                          ,SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"binder    :") JoinArity
2 (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ BindingSite -> Var -> SDoc
forall a. OutputableBndr a => BindingSite -> a -> SDoc
pprBndr BindingSite
LetBind Var
id_bndr
                                          ]
    bad_global :: Var -> Bool
bad_global Var
id_bnd = Var -> Bool
isGlobalId Var
id_occ
                     Bool -> Bool -> Bool
&& Var -> Bool
isLocalId Var
id_bnd
                     Bool -> Bool -> Bool
&& Bool -> Bool
not (Var -> Bool
forall thing. NamedThing thing => thing -> Bool
isWiredIn Var
id_occ)
       
       
       
       
       
       
       
       
       
lookupJoinId :: Id -> LintM (Maybe JoinArity)
lookupJoinId :: Var -> LintM (Maybe JoinArity)
lookupJoinId Var
id
  = do { IdSet
join_set <- LintM IdSet
getValidJoins
       ; case IdSet -> Var -> Maybe Var
lookupVarSet IdSet
join_set Var
id of
            Just Var
id' -> Maybe JoinArity -> LintM (Maybe JoinArity)
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Var -> Maybe JoinArity
isJoinId_maybe Var
id')
            Maybe Var
Nothing  -> Maybe JoinArity -> LintM (Maybe JoinArity)
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe JoinArity
forall a. Maybe a
Nothing }
addAliasUE :: Id -> UsageEnv -> LintM a -> LintM a
addAliasUE :: forall a. Var -> UsageEnv -> LintM a -> LintM a
addAliasUE Var
id UsageEnv
ue LintM a
thing_inside = (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a. (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
LintM ((LintEnv -> WarnsAndErrs -> LResult a) -> LintM a)
-> (LintEnv -> WarnsAndErrs -> LResult a) -> LintM a
forall a b. (a -> b) -> a -> b
$ \ LintEnv
env WarnsAndErrs
errs ->
  let new_ue_aliases :: NameEnv UsageEnv
new_ue_aliases =
        NameEnv UsageEnv -> Name -> UsageEnv -> NameEnv UsageEnv
forall a. NameEnv a -> Name -> a -> NameEnv a
extendNameEnv (LintEnv -> NameEnv UsageEnv
le_ue_aliases LintEnv
env) (Var -> Name
forall a. NamedThing a => a -> Name
getName Var
id) UsageEnv
ue
  in
    LintM a -> LintEnv -> WarnsAndErrs -> LResult a
forall a. LintM a -> LintEnv -> WarnsAndErrs -> LResult a
unLintM LintM a
thing_inside (LintEnv
env { le_ue_aliases = new_ue_aliases }) WarnsAndErrs
errs
varCallSiteUsage :: Id -> LintM UsageEnv
varCallSiteUsage :: Var -> LintM UsageEnv
varCallSiteUsage Var
id =
  do NameEnv UsageEnv
m <- LintM (NameEnv UsageEnv)
getUEAliases
     UsageEnv -> LintM UsageEnv
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return (UsageEnv -> LintM UsageEnv) -> UsageEnv -> LintM UsageEnv
forall a b. (a -> b) -> a -> b
$ case NameEnv UsageEnv -> Name -> Maybe UsageEnv
forall a. NameEnv a -> Name -> Maybe a
lookupNameEnv NameEnv UsageEnv
m (Var -> Name
forall a. NamedThing a => a -> Name
getName Var
id) of
         Maybe UsageEnv
Nothing    -> Var -> UsageEnv
singleUsageUE Var
id
         Just UsageEnv
id_ue -> UsageEnv
id_ue
ensureEqTys :: LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys :: LintedType -> LintedType -> SDoc -> LintM ()
ensureEqTys LintedType
ty1 LintedType
ty2 SDoc
msg = Bool -> SDoc -> LintM ()
lintL (LintedType
ty1 LintedType -> LintedType -> Bool
`eqType` LintedType
ty2) SDoc
msg
ensureSubUsage :: Usage -> Mult -> SDoc -> LintM ()
ensureSubUsage :: Usage -> LintedType -> SDoc -> LintM ()
ensureSubUsage Usage
Bottom     LintedType
_              SDoc
_ = () -> LintM ()
forall a. a -> LintM a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
ensureSubUsage Usage
Zero       LintedType
described_mult SDoc
err_msg = LintedType -> LintedType -> SDoc -> LintM ()
ensureSubMult LintedType
ManyTy LintedType
described_mult SDoc
err_msg
ensureSubUsage (MUsage LintedType
m) LintedType
described_mult SDoc
err_msg = LintedType -> LintedType -> SDoc -> LintM ()
ensureSubMult LintedType
m LintedType
described_mult SDoc
err_msg
ensureSubMult :: Mult -> Mult -> SDoc -> LintM ()
ensureSubMult :: LintedType -> LintedType -> SDoc -> LintM ()
ensureSubMult LintedType
actual_mult LintedType
described_mult SDoc
err_msg = do
    LintFlags
flags <- LintM LintFlags
getLintFlags
    Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (LintFlags -> Bool
lf_check_linearity LintFlags
flags) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$
      Bool -> LintM () -> LintM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (LintedType -> LintedType -> Bool
deepSubMult LintedType
actual_mult LintedType
described_mult) (LintM () -> LintM ()) -> LintM () -> LintM ()
forall a b. (a -> b) -> a -> b
$
        SDoc -> LintM ()
addErrL SDoc
err_msg
  where
    
    
    
    
    
    
    
    
    
    
    
    deepSubMult :: Mult -> Mult -> Bool
    deepSubMult :: LintedType -> LintedType -> Bool
deepSubMult LintedType
m LintedType
n
      | Just (LintedType
m1, LintedType
m2) <- LintedType -> Maybe (LintedType, LintedType)
isMultMul LintedType
m = LintedType -> LintedType -> Bool
deepSubMult LintedType
m1 LintedType
n  Bool -> Bool -> Bool
&& LintedType -> LintedType -> Bool
deepSubMult LintedType
m2 LintedType
n
      | Just (LintedType
n1, LintedType
n2) <- LintedType -> Maybe (LintedType, LintedType)
isMultMul LintedType
n = LintedType -> LintedType -> Bool
deepSubMult LintedType
m  LintedType
n1 Bool -> Bool -> Bool
|| LintedType -> LintedType -> Bool
deepSubMult LintedType
m  LintedType
n2
      | IsSubmult
Submult <- LintedType
m LintedType -> LintedType -> IsSubmult
`submult` LintedType
n = Bool
True
      | Bool
otherwise = LintedType
m LintedType -> LintedType -> Bool
`eqType` LintedType
n
lintRole :: Outputable thing
          => thing     
          -> Role      
          -> Role      
          -> LintM ()
lintRole :: forall thing. Outputable thing => thing -> Role -> Role -> LintM ()
lintRole thing
co Role
r1 Role
r2
  = Bool -> SDoc -> LintM ()
lintL (Role
r1 Role -> Role -> Bool
forall a. Eq a => a -> a -> Bool
== Role
r2)
          (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Role incompatibility: expected" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Role -> SDoc
forall a. Outputable a => a -> SDoc
ppr Role
r1 SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+>
           String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"got" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Role -> SDoc
forall a. Outputable a => a -> SDoc
ppr Role
r2 SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$
           String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"in" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> thing -> SDoc
forall a. Outputable a => a -> SDoc
ppr thing
co)
dumpLoc :: LintLocInfo -> (SrcLoc, SDoc)
dumpLoc :: LintLocInfo -> (SrcLoc, SDoc)
dumpLoc (RhsOf Var
v)
  = (Var -> SrcLoc
forall a. NamedThing a => a -> SrcLoc
getSrcLoc Var
v, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In the RHS of" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [Var] -> SDoc
pp_binders [Var
v])
dumpLoc (OccOf Var
v)
  = (Var -> SrcLoc
forall a. NamedThing a => a -> SrcLoc
getSrcLoc Var
v, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In an occurrence of" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
pp_binder Var
v)
dumpLoc (LambdaBodyOf Var
b)
  = (Var -> SrcLoc
forall a. NamedThing a => a -> SrcLoc
getSrcLoc Var
b, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In the body of lambda with binder" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
pp_binder Var
b)
dumpLoc (RuleOf Var
b)
  = (Var -> SrcLoc
forall a. NamedThing a => a -> SrcLoc
getSrcLoc Var
b, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In a rule attached to" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
pp_binder Var
b)
dumpLoc (UnfoldingOf Var
b)
  = (Var -> SrcLoc
forall a. NamedThing a => a -> SrcLoc
getSrcLoc Var
b, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In the unfolding of" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
pp_binder Var
b)
dumpLoc (BodyOfLetRec [])
  = (SrcLoc
noSrcLoc, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In body of a letrec with no binders")
dumpLoc (BodyOfLetRec bs :: [Var]
bs@(Var
b:[Var]
_))
  = ( Var -> SrcLoc
forall a. NamedThing a => a -> SrcLoc
getSrcLoc Var
b, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In the body of letrec with binders" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [Var] -> SDoc
pp_binders [Var]
bs)
dumpLoc (AnExpr CoreExpr
e)
  = (SrcLoc
noSrcLoc, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In the expression:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
e)
dumpLoc (CaseAlt (Alt AltCon
con [Var]
args CoreExpr
_))
  = (SrcLoc
noSrcLoc, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In a case alternative:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (AltCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr AltCon
con SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [Var] -> SDoc
pp_binders [Var]
args))
dumpLoc (CasePat (Alt AltCon
con [Var]
args CoreExpr
_))
  = (SrcLoc
noSrcLoc, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In the pattern of a case alternative:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (AltCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr AltCon
con SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [Var] -> SDoc
pp_binders [Var]
args))
dumpLoc (CaseTy CoreExpr
scrut)
  = (SrcLoc
noSrcLoc, SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In the result-type of a case with scrutinee:")
                  JoinArity
2 (CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
scrut))
dumpLoc (IdTy Var
b)
  = (Var -> SrcLoc
forall a. NamedThing a => a -> SrcLoc
getSrcLoc Var
b, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In the type of a binder:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
b)
dumpLoc (ImportedUnfolding SrcLoc
locn)
  = (SrcLoc
locn, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In an imported unfolding")
dumpLoc LintLocInfo
TopLevelBindings
  = (SrcLoc
noSrcLoc, SDoc
forall doc. IsOutput doc => doc
Outputable.empty)
dumpLoc (InType LintedType
ty)
  = (SrcLoc
noSrcLoc, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In the type" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
quotes (LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty))
dumpLoc (InCo Coercion
co)
  = (SrcLoc
noSrcLoc, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In the coercion" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
quotes (Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co))
dumpLoc (InAxiom CoAxiom Branched
ax)
  = (CoAxiom Branched -> SrcLoc
forall a. NamedThing a => a -> SrcLoc
getSrcLoc CoAxiom Branched
ax, SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In the coercion axiom")
                      JoinArity
2 (CoAxiom Branched -> SDoc
forall (br :: BranchFlag). CoAxiom br -> SDoc
pprCoAxiom CoAxiom Branched
ax))
pp_binders :: [Var] -> SDoc
pp_binders :: [Var] -> SDoc
pp_binders [Var]
bs = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep (SDoc -> [SDoc] -> [SDoc]
forall doc. IsLine doc => doc -> [doc] -> [doc]
punctuate SDoc
forall doc. IsLine doc => doc
comma ((Var -> SDoc) -> [Var] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Var -> SDoc
pp_binder [Var]
bs))
pp_binder :: Var -> SDoc
pp_binder :: Var -> SDoc
pp_binder Var
b | Var -> Bool
isId Var
b    = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep [Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
b, SDoc
dcolon, LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> LintedType
idType Var
b)]
            | Bool
otherwise = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep [Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
b, SDoc
dcolon, LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> LintedType
tyVarKind Var
b)]
mkDefaultArgsMsg :: [Var] -> SDoc
mkDefaultArgsMsg :: [Var] -> SDoc
mkDefaultArgsMsg [Var]
args
  = SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"DEFAULT case with binders")
         JoinArity
4 ([Var] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Var]
args)
mkCaseAltMsg :: CoreExpr -> Type -> Type -> SDoc
mkCaseAltMsg :: CoreExpr -> LintedType -> LintedType -> SDoc
mkCaseAltMsg CoreExpr
e LintedType
ty1 LintedType
ty2
  = SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Type of case alternatives not the same as the annotation on case:")
         JoinArity
4 ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Actual type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty1,
                   String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Annotation on case:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty2,
                   String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Alt Rhs:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
e ])
mkScrutMsg :: Id -> Type -> Type -> Subst -> SDoc
mkScrutMsg :: Var -> LintedType -> LintedType -> Subst -> SDoc
mkScrutMsg Var
var LintedType
var_ty LintedType
scrut_ty Subst
subst
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Result binder in case doesn't match scrutinee:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
var,
          String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Result binder type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
var_ty,
          String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Scrutinee type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
scrut_ty,
     [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep [String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Current TCv subst", Subst -> SDoc
forall a. Outputable a => a -> SDoc
ppr Subst
subst]]
mkNonDefltMsg, mkNonIncreasingAltsMsg :: CoreExpr -> SDoc
mkNonDefltMsg :: CoreExpr -> SDoc
mkNonDefltMsg CoreExpr
e
  = SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Case expression with DEFAULT not at the beginning") JoinArity
4 (CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
e)
mkNonIncreasingAltsMsg :: CoreExpr -> SDoc
mkNonIncreasingAltsMsg CoreExpr
e
  = SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Case expression with badly-ordered alternatives") JoinArity
4 (CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
e)
nonExhaustiveAltsMsg :: CoreExpr -> SDoc
nonExhaustiveAltsMsg :: CoreExpr -> SDoc
nonExhaustiveAltsMsg CoreExpr
e
  = SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Case expression with non-exhaustive alternatives") JoinArity
4 (CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
e)
mkBadConMsg :: TyCon -> DataCon -> SDoc
mkBadConMsg :: TyCon -> DataCon -> SDoc
mkBadConMsg TyCon
tycon DataCon
datacon
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [
        String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In a case alternative, data constructor isn't in scrutinee type:",
        String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Scrutinee type constructor:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tycon,
        String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Data con:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> DataCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr DataCon
datacon
    ]
mkBadPatMsg :: Type -> Type -> SDoc
mkBadPatMsg :: LintedType -> LintedType -> SDoc
mkBadPatMsg LintedType
con_result_ty LintedType
scrut_ty
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [
        String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In a case alternative, pattern result type doesn't match scrutinee type:",
        String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Pattern result type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
con_result_ty,
        String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Scrutinee type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
scrut_ty
    ]
integerScrutinisedMsg :: SDoc
integerScrutinisedMsg :: SDoc
integerScrutinisedMsg
  = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"In a LitAlt, the literal is lifted (probably Integer)"
mkBadAltMsg :: Type -> CoreAlt -> SDoc
mkBadAltMsg :: LintedType -> Alt Var -> SDoc
mkBadAltMsg LintedType
scrut_ty Alt Var
alt
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Data alternative when scrutinee is not a tycon application",
           String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Scrutinee type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
scrut_ty,
           String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Alternative:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Alt Var -> SDoc
forall a. OutputableBndr a => Alt a -> SDoc
pprCoreAlt Alt Var
alt ]
mkNewTyDataConAltMsg :: Type -> CoreAlt -> SDoc
mkNewTyDataConAltMsg :: LintedType -> Alt Var -> SDoc
mkNewTyDataConAltMsg LintedType
scrut_ty Alt Var
alt
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Data alternative for newtype datacon",
           String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Scrutinee type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
scrut_ty,
           String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Alternative:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Alt Var -> SDoc
forall a. OutputableBndr a => Alt a -> SDoc
pprCoreAlt Alt Var
alt ]
mkAppMsg :: Type -> Type -> CoreExpr -> SDoc
mkAppMsg :: LintedType -> LintedType -> CoreExpr -> SDoc
mkAppMsg LintedType
expected_arg_ty LintedType
actual_arg_ty CoreExpr
arg
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Argument value doesn't match argument type:",
              SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Expected arg type:") JoinArity
4 (LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
expected_arg_ty),
              SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Actual arg type:") JoinArity
4 (LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
actual_arg_ty),
              SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Arg:") JoinArity
4 (CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
arg)]
mkNonFunAppMsg :: Type -> Type -> CoreExpr -> SDoc
mkNonFunAppMsg :: LintedType -> LintedType -> CoreExpr -> SDoc
mkNonFunAppMsg LintedType
fun_ty LintedType
arg_ty CoreExpr
arg
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Non-function type in function position",
              SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Fun type:") JoinArity
4 (LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
fun_ty),
              SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Arg type:") JoinArity
4 (LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
arg_ty),
              SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Arg:") JoinArity
4 (CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
arg)]
mkLetErr :: TyVar -> CoreExpr -> SDoc
mkLetErr :: Var -> CoreExpr -> SDoc
mkLetErr Var
bndr CoreExpr
rhs
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Bad `let' binding:",
          SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Variable:")
                 JoinArity
4 (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
bndr SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> LintedType
varType Var
bndr)),
          SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Rhs:")
                 JoinArity
4 (CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
rhs)]
mkTyAppMsg :: Type -> Type -> SDoc
mkTyAppMsg :: LintedType -> LintedType -> SDoc
mkTyAppMsg LintedType
ty LintedType
arg_ty
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Illegal type application:",
              SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Exp type:")
                 JoinArity
4 (LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
ty)),
              SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Arg type:")
                 JoinArity
4 (LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
arg_ty SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
arg_ty))]
emptyRec :: CoreExpr -> SDoc
emptyRec :: CoreExpr -> SDoc
emptyRec CoreExpr
e = SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Empty Rec binding:") JoinArity
2 (CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
e)
mkRhsMsg :: Id -> SDoc -> Type -> SDoc
mkRhsMsg :: Var -> SDoc -> LintedType -> SDoc
mkRhsMsg Var
binder SDoc
what LintedType
ty
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat
    [[SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep [String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"The type of this binder doesn't match the type of its" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
what SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
colon,
            Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
binder],
     [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep [String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Binder's type:", LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> LintedType
idType Var
binder)],
     [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep [String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Rhs type:", LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty]]
badBndrTyMsg :: Id -> SDoc -> SDoc
badBndrTyMsg :: Var -> SDoc -> SDoc
badBndrTyMsg Var
binder SDoc
what
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"The type of this binder is" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
what SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
colon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
binder
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Binder's type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> LintedType
idType Var
binder) ]
mkNonTopExportedMsg :: Id -> SDoc
mkNonTopExportedMsg :: Var -> SDoc
mkNonTopExportedMsg Var
binder
  = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep [String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Non-top-level binder is marked as exported:", Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
binder]
mkNonTopExternalNameMsg :: Id -> SDoc
mkNonTopExternalNameMsg :: Var -> SDoc
mkNonTopExternalNameMsg Var
binder
  = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep [String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Non-top-level binder has an external name:", Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
binder]
mkTopNonLitStrMsg :: Id -> SDoc
mkTopNonLitStrMsg :: Var -> SDoc
mkTopNonLitStrMsg Var
binder
  = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep [String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Top-level Addr# binder has a non-literal rhs:", Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
binder]
mkKindErrMsg :: TyVar -> Type -> SDoc
mkKindErrMsg :: Var -> LintedType -> SDoc
mkKindErrMsg Var
tyvar LintedType
arg_ty
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Kinds don't match in type application:",
          SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Type variable:")
                 JoinArity
4 (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
tyvar SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> LintedType
tyVarKind Var
tyvar)),
          SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Arg type:")
                 JoinArity
4 (LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
arg_ty SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HasDebugCallStack => LintedType -> LintedType
LintedType -> LintedType
typeKind LintedType
arg_ty))]
mkCastErr :: CoreExpr -> Coercion -> Type -> Type -> SDoc
mkCastErr :: CoreExpr -> Coercion -> LintedType -> LintedType -> SDoc
mkCastErr CoreExpr
expr = String
-> String -> SDoc -> Coercion -> LintedType -> LintedType -> SDoc
mk_cast_err String
"expression" String
"type" (CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
expr)
mkCastTyErr :: Type -> Coercion -> Kind -> Kind -> SDoc
mkCastTyErr :: LintedType -> Coercion -> LintedType -> LintedType -> SDoc
mkCastTyErr LintedType
ty = String
-> String -> SDoc -> Coercion -> LintedType -> LintedType -> SDoc
mk_cast_err String
"type" String
"kind" (LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty)
mk_cast_err :: String 
                      
            -> String 
                      
            -> SDoc   
            -> Coercion -> Type -> Type -> SDoc
mk_cast_err :: String
-> String -> SDoc -> Coercion -> LintedType -> LintedType -> SDoc
mk_cast_err String
thing_str String
co_str SDoc
pp_thing Coercion
co LintedType
from_ty LintedType
thing_ty
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [SDoc
from_msg SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"of Cast differs from" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
co_msg
            SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"of" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
enclosed_msg,
          SDoc
from_msg SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
colon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
from_ty,
          String -> SDoc
forall doc. IsLine doc => String -> doc
text (String -> String
capitalise String
co_str) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"of" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
enclosed_msg SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
colon
            SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
thing_ty,
          String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Actual" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
enclosed_msg SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
colon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
pp_thing,
          String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Coercion used in cast:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co
         ]
  where
    co_msg, from_msg, enclosed_msg :: SDoc
    co_msg :: SDoc
co_msg       = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
co_str
    from_msg :: SDoc
from_msg     = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"From-" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
co_msg
    enclosed_msg :: SDoc
enclosed_msg = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"enclosed" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
thing_str
mkBadUnivCoMsg :: LeftOrRight -> Coercion -> SDoc
mkBadUnivCoMsg :: LeftOrRight -> Coercion -> SDoc
mkBadUnivCoMsg LeftOrRight
lr Coercion
co
  = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Kind mismatch on the" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LeftOrRight -> SDoc
pprLeftOrRight LeftOrRight
lr SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+>
    String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"side of a UnivCo:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co
mkBadProofIrrelMsg :: Type -> Coercion -> SDoc
mkBadProofIrrelMsg :: LintedType -> Coercion -> SDoc
mkBadProofIrrelMsg LintedType
ty Coercion
co
  = SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Found a non-coercion in a proof-irrelevance UnivCo:")
       JoinArity
2 ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty
               , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"co:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co ])
mkBadTyVarMsg :: Var -> SDoc
mkBadTyVarMsg :: Var -> SDoc
mkBadTyVarMsg Var
tv
  = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Non-tyvar used in TyVarTy:"
      SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
tv SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> LintedType
varType Var
tv)
mkBadJoinBindMsg :: Var -> SDoc
mkBadJoinBindMsg :: Var -> SDoc
mkBadJoinBindMsg Var
var
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Bad join point binding:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
var
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Join points can be bound only by a non-top-level let" ]
mkInvalidJoinPointMsg :: Var -> Type -> SDoc
mkInvalidJoinPointMsg :: Var -> LintedType -> SDoc
mkInvalidJoinPointMsg Var
var LintedType
ty
  = SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Join point has invalid type:")
        JoinArity
2 (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
var SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
ty)
mkBadJoinArityMsg :: Var -> Int -> Int -> CoreExpr -> SDoc
mkBadJoinArityMsg :: Var -> JoinArity -> JoinArity -> CoreExpr -> SDoc
mkBadJoinArityMsg Var
var JoinArity
ar JoinArity
n CoreExpr
rhs
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Join point has too few lambdas",
           String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Join var:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
var,
           String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Join arity:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> JoinArity -> SDoc
forall a. Outputable a => a -> SDoc
ppr JoinArity
ar,
           String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Number of lambdas:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> JoinArity -> SDoc
forall a. Outputable a => a -> SDoc
ppr (JoinArity
ar JoinArity -> JoinArity -> JoinArity
forall a. Num a => a -> a -> a
- JoinArity
n),
           String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Rhs = " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
rhs
           ]
invalidJoinOcc :: Var -> SDoc
invalidJoinOcc :: Var -> SDoc
invalidJoinOcc Var
var
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Invalid occurrence of a join variable:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
var
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"The binder is either not a join point, or not valid here" ]
mkBadJumpMsg :: Var -> Int -> Int -> SDoc
mkBadJumpMsg :: Var -> JoinArity -> JoinArity -> SDoc
mkBadJumpMsg Var
var JoinArity
ar JoinArity
nargs
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Join point invoked with wrong number of arguments",
           String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Join var:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
var,
           String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Join arity:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> JoinArity -> SDoc
forall a. Outputable a => a -> SDoc
ppr JoinArity
ar,
           String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Number of arguments:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> JoinArity -> SDoc
forall doc. IsLine doc => JoinArity -> doc
int JoinArity
nargs ]
mkInconsistentRecMsg :: [Var] -> SDoc
mkInconsistentRecMsg :: [Var] -> SDoc
mkInconsistentRecMsg [Var]
bndrs
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Recursive let binders mix values and join points",
           String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Binders:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep ((Var -> SDoc) -> [Var] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Var -> SDoc
ppr_with_details [Var]
bndrs) ]
  where
    ppr_with_details :: Var -> SDoc
ppr_with_details Var
bndr = Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
bndr SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> IdDetails -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> IdDetails
idDetails Var
bndr)
mkJoinBndrOccMismatchMsg :: Var -> JoinArity -> JoinArity -> SDoc
mkJoinBndrOccMismatchMsg :: Var -> JoinArity -> JoinArity -> SDoc
mkJoinBndrOccMismatchMsg Var
bndr JoinArity
join_arity_bndr JoinArity
join_arity_occ
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Mismatch in join point arity between binder and occurrence"
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Var:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
bndr
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Arity at binding site:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> JoinArity -> SDoc
forall a. Outputable a => a -> SDoc
ppr JoinArity
join_arity_bndr
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Arity at occurrence:  " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> JoinArity -> SDoc
forall a. Outputable a => a -> SDoc
ppr JoinArity
join_arity_occ ]
mkBndrOccTypeMismatchMsg :: Var -> Var -> LintedType -> LintedType -> SDoc
mkBndrOccTypeMismatchMsg :: Var -> Var -> LintedType -> LintedType -> SDoc
mkBndrOccTypeMismatchMsg Var
bndr Var
var LintedType
bndr_ty LintedType
var_ty
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Mismatch in type between binder and occurrence"
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Binder:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
bndr SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
bndr_ty
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Occurrence:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
var SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LintedType
var_ty
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"  Before subst:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LintedType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> LintedType
idType Var
var) ]
mkBadJoinPointRuleMsg :: JoinId -> JoinArity -> CoreRule -> SDoc
mkBadJoinPointRuleMsg :: Var -> JoinArity -> CoreRule -> SDoc
mkBadJoinPointRuleMsg Var
bndr JoinArity
join_arity CoreRule
rule
  = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Join point has rule with wrong number of arguments"
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Var:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
bndr
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Join arity:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> JoinArity -> SDoc
forall a. Outputable a => a -> SDoc
ppr JoinArity
join_arity
         , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Rule:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> CoreRule -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreRule
rule ]
pprLeftOrRight :: LeftOrRight -> SDoc
pprLeftOrRight :: LeftOrRight -> SDoc
pprLeftOrRight LeftOrRight
CLeft  = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"left"
pprLeftOrRight LeftOrRight
CRight = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"right"
dupVars :: [NonEmpty Var] -> SDoc
dupVars :: [NonEmpty Var] -> SDoc
dupVars [NonEmpty Var]
vars
  = SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Duplicate variables brought into scope")
       JoinArity
2 ([[Var]] -> SDoc
forall a. Outputable a => a -> SDoc
ppr ((NonEmpty Var -> [Var]) -> [NonEmpty Var] -> [[Var]]
forall a b. (a -> b) -> [a] -> [b]
map NonEmpty Var -> [Var]
forall a. NonEmpty a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList [NonEmpty Var]
vars))
dupExtVars :: [NonEmpty Name] -> SDoc
dupExtVars :: [NonEmpty Name] -> SDoc
dupExtVars [NonEmpty Name]
vars
  = SDoc -> JoinArity -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Duplicate top-level variables with the same qualified name")
       JoinArity
2 ([[Name]] -> SDoc
forall a. Outputable a => a -> SDoc
ppr ((NonEmpty Name -> [Name]) -> [NonEmpty Name] -> [[Name]]
forall a b. (a -> b) -> [a] -> [b]
map NonEmpty Name -> [Name]
forall a. NonEmpty a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList [NonEmpty Name]
vars))
lintAnnots :: SDoc -> (ModGuts -> CoreM ModGuts) -> ModGuts -> CoreM ModGuts
lintAnnots :: SDoc -> (ModGuts -> CoreM ModGuts) -> ModGuts -> CoreM ModGuts
lintAnnots SDoc
pname ModGuts -> CoreM ModGuts
pass ModGuts
guts = {-# SCC "lintAnnots" #-} do
  
  DynFlags
dflags <- CoreM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
  Logger
logger <- CoreM Logger
forall (m :: * -> *). HasLogger m => m Logger
getLogger
  Bool -> CoreM () -> CoreM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_DoAnnotationLinting DynFlags
dflags) (CoreM () -> CoreM ()) -> CoreM () -> CoreM ()
forall a b. (a -> b) -> a -> b
$
    IO () -> CoreM ()
forall a. IO a -> CoreM a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> CoreM ()) -> IO () -> CoreM ()
forall a b. (a -> b) -> a -> b
$ Logger -> String -> IO ()
Err.showPass Logger
logger String
"Annotation linting - first run"
  
  
  if GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_DoAnnotationLinting DynFlags
dflags
    then do
      ModGuts
nguts <- ModGuts -> CoreM ModGuts
pass ModGuts
guts
      IO () -> CoreM ()
forall a. IO a -> CoreM a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> CoreM ()) -> IO () -> CoreM ()
forall a b. (a -> b) -> a -> b
$ Logger -> String -> IO ()
Err.showPass Logger
logger String
"Annotation linting - second run"
      ModGuts
nguts' <- (ModGuts -> CoreM ModGuts) -> ModGuts -> CoreM ModGuts
withoutAnnots ModGuts -> CoreM ModGuts
pass ModGuts
guts
      
      IO () -> CoreM ()
forall a. IO a -> CoreM a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> CoreM ()) -> IO () -> CoreM ()
forall a b. (a -> b) -> a -> b
$ Logger -> String -> IO ()
Err.showPass Logger
logger String
"Annotation linting - comparison"
      let binds :: [(Var, CoreExpr)]
binds = CoreProgram -> [(Var, CoreExpr)]
forall b. [Bind b] -> [(b, Expr b)]
flattenBinds (CoreProgram -> [(Var, CoreExpr)])
-> CoreProgram -> [(Var, CoreExpr)]
forall a b. (a -> b) -> a -> b
$ ModGuts -> CoreProgram
mg_binds ModGuts
nguts
          binds' :: [(Var, CoreExpr)]
binds' = CoreProgram -> [(Var, CoreExpr)]
forall b. [Bind b] -> [(b, Expr b)]
flattenBinds (CoreProgram -> [(Var, CoreExpr)])
-> CoreProgram -> [(Var, CoreExpr)]
forall a b. (a -> b) -> a -> b
$ ModGuts -> CoreProgram
mg_binds ModGuts
nguts'
          ([SDoc]
diffs,RnEnv2
_) = Bool
-> RnEnv2
-> [(Var, CoreExpr)]
-> [(Var, CoreExpr)]
-> ([SDoc], RnEnv2)
diffBinds Bool
True (InScopeSet -> RnEnv2
mkRnEnv2 InScopeSet
emptyInScopeSet) [(Var, CoreExpr)]
binds [(Var, CoreExpr)]
binds'
      Bool -> CoreM () -> CoreM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not ([SDoc] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [SDoc]
diffs)) (CoreM () -> CoreM ()) -> CoreM () -> CoreM ()
forall a b. (a -> b) -> a -> b
$ SDoc -> CoreM ()
GHC.Core.Opt.Monad.putMsg (SDoc -> CoreM ()) -> SDoc -> CoreM ()
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat
        [ String -> SDoc -> SDoc
lint_banner String
"warning" SDoc
pname
        , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Core changes with annotations:"
        , PprStyle -> SDoc -> SDoc
withPprStyle PprStyle
defaultDumpStyle (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ JoinArity -> SDoc -> SDoc
nest JoinArity
2 (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [SDoc]
diffs
        ]
      ModGuts -> CoreM ModGuts
forall a. a -> CoreM a
forall (m :: * -> *) a. Monad m => a -> m a
return ModGuts
nguts
    else
      ModGuts -> CoreM ModGuts
pass ModGuts
guts
withoutAnnots :: (ModGuts -> CoreM ModGuts) -> ModGuts -> CoreM ModGuts
withoutAnnots :: (ModGuts -> CoreM ModGuts) -> ModGuts -> CoreM ModGuts
withoutAnnots ModGuts -> CoreM ModGuts
pass ModGuts
guts = do
  
  
  let withoutFlag :: CoreM a -> CoreM a
withoutFlag = (DynFlags -> DynFlags) -> CoreM a -> CoreM a
forall a. (DynFlags -> DynFlags) -> CoreM a -> CoreM a
mapDynFlagsCoreM ((DynFlags -> DynFlags) -> CoreM a -> CoreM a)
-> (DynFlags -> DynFlags) -> CoreM a -> CoreM a
forall a b. (a -> b) -> a -> b
$ \(!DynFlags
dflags) -> DynFlags
dflags { debugLevel = 0 }
  
  
  
  let nukeTicks :: Expr b -> Expr b
nukeTicks = (CoreTickish -> Bool) -> Expr b -> Expr b
forall b. (CoreTickish -> Bool) -> Expr b -> Expr b
stripTicksE (Bool -> Bool
not (Bool -> Bool) -> (CoreTickish -> Bool) -> CoreTickish -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishIsCode)
      nukeAnnotsBind :: CoreBind -> CoreBind
      nukeAnnotsBind :: Bind Var -> Bind Var
nukeAnnotsBind Bind Var
bind = case Bind Var
bind of
        Rec [(Var, CoreExpr)]
bs     -> [(Var, CoreExpr)] -> Bind Var
forall b. [(b, Expr b)] -> Bind b
Rec ([(Var, CoreExpr)] -> Bind Var) -> [(Var, CoreExpr)] -> Bind Var
forall a b. (a -> b) -> a -> b
$ ((Var, CoreExpr) -> (Var, CoreExpr))
-> [(Var, CoreExpr)] -> [(Var, CoreExpr)]
forall a b. (a -> b) -> [a] -> [b]
map (\(Var
b,CoreExpr
e) -> (Var
b, CoreExpr -> CoreExpr
forall b. Expr b -> Expr b
nukeTicks CoreExpr
e)) [(Var, CoreExpr)]
bs
        NonRec Var
b CoreExpr
e -> Var -> CoreExpr -> Bind Var
forall b. b -> Expr b -> Bind b
NonRec Var
b (CoreExpr -> Bind Var) -> CoreExpr -> Bind Var
forall a b. (a -> b) -> a -> b
$ CoreExpr -> CoreExpr
forall b. Expr b -> Expr b
nukeTicks CoreExpr
e
      nukeAnnotsMod :: ModGuts -> ModGuts
nukeAnnotsMod mg :: ModGuts
mg@ModGuts{mg_binds :: ModGuts -> CoreProgram
mg_binds=CoreProgram
binds}
        = ModGuts
mg{mg_binds = map nukeAnnotsBind binds}
  
  
  CoreM ModGuts -> CoreM ModGuts
forall a. CoreM a -> CoreM a
dropSimplCount (CoreM ModGuts -> CoreM ModGuts) -> CoreM ModGuts -> CoreM ModGuts
forall a b. (a -> b) -> a -> b
$ CoreM ModGuts -> CoreM ModGuts
forall a. CoreM a -> CoreM a
withoutFlag (CoreM ModGuts -> CoreM ModGuts) -> CoreM ModGuts -> CoreM ModGuts
forall a b. (a -> b) -> a -> b
$ ModGuts -> CoreM ModGuts
pass (ModGuts -> ModGuts
nukeAnnotsMod ModGuts
guts)