Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC

Commits:

7 changed files:

Changes:

  • compiler/GHC/HsToCore/Monad.hs
    ... ... @@ -58,6 +58,7 @@ module GHC.HsToCore.Monad (
    58 58
     import GHC.Prelude
    
    59 59
     
    
    60 60
     import GHC.Driver.Env
    
    61
    +import GHC.Driver.Env.KnotVars
    
    61 62
     import GHC.Driver.DynFlags
    
    62 63
     import GHC.Driver.Ppr
    
    63 64
     import GHC.Driver.Config.Diagnostic
    
    ... ... @@ -117,7 +118,7 @@ import GHC.Utils.Panic
    117 118
     import qualified GHC.Data.Strict as Strict
    
    118 119
     
    
    119 120
     import Data.IORef
    
    120
    -import GHC.Driver.Env.KnotVars
    
    121
    +
    
    121 122
     import GHC.IO.Unsafe (unsafeInterleaveIO)
    
    122 123
     
    
    123 124
     {-
    

  • compiler/GHC/Tc/Module.hs
    ... ... @@ -26,6 +26,7 @@ module GHC.Tc.Module (
    26 26
             runTcInteractive,    -- Used by GHC API clients (#8878)
    
    27 27
             withTcPlugins,       -- Used by GHC API clients (#20499)
    
    28 28
             withHoleFitPlugins,  -- Used by GHC API clients (#20499)
    
    29
    +        withDefaultingPlugins,
    
    29 30
             tcRnLookupName,
    
    30 31
             tcRnGetInfo,
    
    31 32
             tcRnModule, tcRnModuleTcRnM,
    
    ... ... @@ -53,7 +54,6 @@ import GHC.Driver.DynFlags
    53 54
     import GHC.Driver.Config.Diagnostic
    
    54 55
     import GHC.IO.Unsafe ( unsafeInterleaveIO )
    
    55 56
     
    
    56
    -import GHC.Tc.Errors.Hole.Plugin ( HoleFitPluginR (..) )
    
    57 57
     import GHC.Tc.Errors.Types
    
    58 58
     import {-# SOURCE #-} GHC.Tc.Gen.Splice ( finishTH, runRemoteModFinalizers )
    
    59 59
     import GHC.Tc.Gen.HsType
    
    ... ... @@ -141,7 +141,6 @@ import GHC.Types.Id as Id
    141 141
     import GHC.Types.Id.Info( IdDetails(..) )
    
    142 142
     import GHC.Types.Var.Env
    
    143 143
     import GHC.Types.TypeEnv
    
    144
    -import GHC.Types.Unique.FM
    
    145 144
     import GHC.Types.Name
    
    146 145
     import GHC.Types.Name.Env
    
    147 146
     import GHC.Types.Name.Set
    
    ... ... @@ -212,10 +211,6 @@ tcRnModule hsc_env mod_sum save_rn_syntax
    212 211
                   (text "Renamer/typechecker"<+>brackets (ppr this_mod))
    
    213 212
                   (const ()) $
    
    214 213
        initTc hsc_env hsc_src save_rn_syntax this_mod real_loc $
    
    215
    -          withTcPlugins hsc_env $
    
    216
    -          withDefaultingPlugins hsc_env $
    
    217
    -          withHoleFitPlugins hsc_env $
    
    218
    -
    
    219 214
               tcRnModuleTcRnM hsc_env mod_sum parsedModule this_mod
    
    220 215
     
    
    221 216
       | otherwise
    
    ... ... @@ -3182,72 +3177,11 @@ hasTopUserName x
    3182 3177
     {-
    
    3183 3178
     ********************************************************************************
    
    3184 3179
     
    
    3185
    -Type Checker Plugins
    
    3180
    +                         Running plugins
    
    3186 3181
     
    
    3187 3182
     ********************************************************************************
    
    3188 3183
     -}
    
    3189 3184
     
    
    3190
    -withTcPlugins :: HscEnv -> TcM a -> TcM a
    
    3191
    -withTcPlugins hsc_env m =
    
    3192
    -    case catMaybes $ mapPlugins (hsc_plugins hsc_env) tcPlugin of
    
    3193
    -       []      -> m  -- Common fast case
    
    3194
    -       plugins -> do
    
    3195
    -                (solvers, rewriters, stops) <-
    
    3196
    -                  unzip3 `fmap` mapM start_plugin plugins
    
    3197
    -                let
    
    3198
    -                  rewritersUniqFM :: UniqFM TyCon [TcPluginRewriter]
    
    3199
    -                  !rewritersUniqFM = sequenceUFMList rewriters
    
    3200
    -                -- The following ensures that tcPluginStop is called even if a type
    
    3201
    -                -- error occurs during compilation (Fix of #10078)
    
    3202
    -                eitherRes <- tryM $
    
    3203
    -                  updGblEnv (\e -> e { tcg_tc_plugin_solvers   = solvers
    
    3204
    -                                     , tcg_tc_plugin_rewriters = rewritersUniqFM }) m
    
    3205
    -                mapM_ runTcPluginM stops
    
    3206
    -                case eitherRes of
    
    3207
    -                  Left _ -> failM
    
    3208
    -                  Right res -> return res
    
    3209
    -  where
    
    3210
    -  start_plugin (TcPlugin start solve rewrite stop) =
    
    3211
    -    do s <- runTcPluginM start
    
    3212
    -       return (solve s, rewrite s, stop s)
    
    3213
    -
    
    3214
    -withDefaultingPlugins :: HscEnv -> TcM a -> TcM a
    
    3215
    -withDefaultingPlugins hsc_env m =
    
    3216
    -  do case catMaybes $ mapPlugins (hsc_plugins hsc_env) defaultingPlugin of
    
    3217
    -       [] -> m  -- Common fast case
    
    3218
    -       plugins  -> do (plugins,stops) <- mapAndUnzipM start_plugin plugins
    
    3219
    -                      -- This ensures that dePluginStop is called even if a type
    
    3220
    -                      -- error occurs during compilation
    
    3221
    -                      eitherRes <- tryM $ do
    
    3222
    -                        updGblEnv (\e -> e { tcg_defaulting_plugins = plugins }) m
    
    3223
    -                      mapM_ runTcPluginM stops
    
    3224
    -                      case eitherRes of
    
    3225
    -                        Left _ -> failM
    
    3226
    -                        Right res -> return res
    
    3227
    -  where
    
    3228
    -  start_plugin (DefaultingPlugin start fill stop) =
    
    3229
    -    do s <- runTcPluginM start
    
    3230
    -       return (fill s, stop s)
    
    3231
    -
    
    3232
    -withHoleFitPlugins :: HscEnv -> TcM a -> TcM a
    
    3233
    -withHoleFitPlugins hsc_env m =
    
    3234
    -  case catMaybes $ mapPlugins (hsc_plugins hsc_env) holeFitPlugin of
    
    3235
    -    [] -> m  -- Common fast case
    
    3236
    -    plugins -> do (plugins,stops) <- mapAndUnzipM start_plugin plugins
    
    3237
    -                  -- This ensures that hfPluginStop is called even if a type
    
    3238
    -                  -- error occurs during compilation.
    
    3239
    -                  eitherRes <- tryM $
    
    3240
    -                    updGblEnv (\e -> e { tcg_hf_plugins = plugins }) m
    
    3241
    -                  sequence_ stops
    
    3242
    -                  case eitherRes of
    
    3243
    -                    Left _ -> failM
    
    3244
    -                    Right res -> return res
    
    3245
    -  where
    
    3246
    -    start_plugin (HoleFitPluginR init plugin stop) =
    
    3247
    -      do ref <- init
    
    3248
    -         return (plugin ref, stop ref)
    
    3249
    -
    
    3250
    -
    
    3251 3185
     runRenamerPlugin :: TcGblEnv
    
    3252 3186
                      -> HsGroup GhcRn
    
    3253 3187
                      -> TcM (TcGblEnv, HsGroup GhcRn)
    

  • compiler/GHC/Tc/Utils/Monad.hs
    ... ... @@ -31,6 +31,9 @@ module GHC.Tc.Utils.Monad(
    31 31
       updateEps, updateEps_,
    
    32 32
       getHpt, getEpsAndHug,
    
    33 33
     
    
    34
    +  -- * Initialising TcM plugins
    
    35
    +  withTcPlugins, withDefaultingPlugins, withHoleFitPlugins,
    
    36
    +
    
    34 37
       -- * Arrow scopes
    
    35 38
       newArrowScope, escapeArrowScope,
    
    36 39
     
    
    ... ... @@ -163,6 +166,7 @@ import GHC.Builtin.Names
    163 166
     import GHC.Builtin.Types( zonkAnyTyCon )
    
    164 167
     
    
    165 168
     import GHC.Tc.Errors.Types
    
    169
    +import GHC.Tc.Errors.Hole.Plugin ( HoleFitPluginR (..) )
    
    166 170
     import GHC.Tc.Types     -- Re-export all
    
    167 171
     import GHC.Tc.Types.Constraint
    
    168 172
     import GHC.Tc.Types.CtLoc
    
    ... ... @@ -183,13 +187,17 @@ import GHC.Unit.Module.Warnings
    183 187
     import GHC.Unit.Home.PackageTable
    
    184 188
     
    
    185 189
     import GHC.Core.UsageEnv
    
    190
    +
    
    191
    +import GHC.Core.Coercion ( isReflCo )
    
    186 192
     import GHC.Core.Multiplicity
    
    187 193
     import GHC.Core.InstEnv
    
    188 194
     import GHC.Core.FamInstEnv
    
    189 195
     import GHC.Core.Type( mkNumLitTy )
    
    196
    +import GHC.Core.TyCon ( TyCon )
    
    190 197
     
    
    191 198
     import GHC.Driver.Env
    
    192 199
     import GHC.Driver.Env.KnotVars
    
    200
    +import GHC.Driver.Plugins ( Plugin(..), mapPlugins )
    
    193 201
     import GHC.Driver.Session
    
    194 202
     import GHC.Driver.Config.Diagnostic
    
    195 203
     
    
    ... ... @@ -226,7 +234,7 @@ import GHC.Types.SrcLoc
    226 234
     import GHC.Types.Name.Env
    
    227 235
     import GHC.Types.Name.Set
    
    228 236
     import GHC.Types.Name.Ppr
    
    229
    -import GHC.Types.Unique.FM ( emptyUFM )
    
    237
    +import GHC.Types.Unique.FM ( UniqFM, emptyUFM, sequenceUFMList )
    
    230 238
     import GHC.Types.Unique.DFM
    
    231 239
     import GHC.Types.Unique.Supply
    
    232 240
     import GHC.Types.Annotations
    
    ... ... @@ -240,8 +248,6 @@ import Data.IORef
    240 248
     import Control.Monad
    
    241 249
     
    
    242 250
     import qualified Data.Map as Map
    
    243
    -import GHC.Core.Coercion (isReflCo)
    
    244
    -
    
    245 251
     
    
    246 252
     {-
    
    247 253
     ************************************************************************
    
    ... ... @@ -263,129 +269,139 @@ initTc :: HscEnv
    263 269
                     -- (error messages should have been printed already)
    
    264 270
     
    
    265 271
     initTc hsc_env hsc_src keep_rn_syntax mod loc do_this
    
    266
    - = do { keep_var     <- newIORef emptyNameSet ;
    
    267
    -        used_gre_var <- newIORef [] ;
    
    268
    -        th_var       <- newIORef False ;
    
    269
    -        infer_var    <- newIORef True ;
    
    270
    -        infer_reasons_var <- newIORef emptyMessages ;
    
    271
    -        dfun_n_var   <- newIORef emptyOccSet ;
    
    272
    -        zany_n_var   <- newIORef 0 ;
    
    273
    -        let { type_env_var = hsc_type_env_vars hsc_env };
    
    274
    -
    
    275
    -        dependent_files_var <- newIORef [] ;
    
    276
    -        dependent_dirs_var <- newIORef [] ;
    
    277
    -        static_wc_var       <- newIORef emptyWC ;
    
    278
    -        cc_st_var           <- newIORef newCostCentreState ;
    
    279
    -        th_topdecls_var      <- newIORef [] ;
    
    280
    -        th_foreign_files_var <- newIORef [] ;
    
    281
    -        th_topnames_var      <- newIORef emptyNameSet ;
    
    282
    -        th_modfinalizers_var <- newIORef [] ;
    
    283
    -        th_coreplugins_var <- newIORef [] ;
    
    284
    -        th_state_var         <- newIORef Map.empty ;
    
    285
    -        th_remote_state_var  <- newIORef Nothing ;
    
    286
    -        th_docs_var          <- newIORef Map.empty ;
    
    287
    -        th_needed_deps_var   <- newIORef ([], emptyUDFM) ;
    
    288
    -        next_wrapper_num     <- newIORef emptyModuleEnv ;
    
    289
    -        let {
    
    290
    -             -- bangs to avoid leaking the env (#19356)
    
    291
    -             !dflags = hsc_dflags hsc_env ;
    
    292
    -             !mhome_unit = hsc_home_unit_maybe hsc_env;
    
    293
    -             !logger = hsc_logger hsc_env ;
    
    294
    -
    
    295
    -             maybe_rn_syntax :: forall a. a -> Maybe a ;
    
    296
    -             maybe_rn_syntax empty_val
    
    297
    -                | logHasDumpFlag logger Opt_D_dump_rn_ast = Just empty_val
    
    298
    -
    
    299
    -                | gopt Opt_WriteHie dflags       = Just empty_val
    
    300
    -
    
    301
    -                  -- We want to serialize the documentation in the .hi-files,
    
    302
    -                  -- and need to extract it from the renamed syntax first.
    
    303
    -                  -- See 'GHC.HsToCore.Docs.extractDocs'.
    
    304
    -                | gopt Opt_Haddock dflags       = Just empty_val
    
    305
    -
    
    306
    -                | keep_rn_syntax                = Just empty_val
    
    307
    -                | otherwise                     = Nothing ;
    
    308
    -
    
    309
    -             gbl_env = TcGblEnv {
    
    310
    -                tcg_th_topdecls      = th_topdecls_var,
    
    311
    -                tcg_th_foreign_files = th_foreign_files_var,
    
    312
    -                tcg_th_topnames      = th_topnames_var,
    
    313
    -                tcg_th_modfinalizers = th_modfinalizers_var,
    
    314
    -                tcg_th_coreplugins = th_coreplugins_var,
    
    315
    -                tcg_th_state         = th_state_var,
    
    316
    -                tcg_th_remote_state  = th_remote_state_var,
    
    317
    -                tcg_th_docs          = th_docs_var,
    
    318
    -
    
    319
    -                tcg_mod            = mod,
    
    320
    -                tcg_semantic_mod   = homeModuleInstantiation mhome_unit mod,
    
    321
    -                tcg_src            = hsc_src,
    
    322
    -                tcg_rdr_env        = emptyGlobalRdrEnv,
    
    323
    -                tcg_fix_env        = emptyNameEnv,
    
    324
    -                tcg_default        = emptyDefaultEnv,
    
    325
    -                tcg_default_exports = emptyDefaultEnv,
    
    326
    -                tcg_type_env       = emptyNameEnv,
    
    327
    -                tcg_type_env_var   = type_env_var,
    
    328
    -                tcg_inst_env       = emptyInstEnv,
    
    329
    -                tcg_fam_inst_env   = emptyFamInstEnv,
    
    330
    -                tcg_ann_env        = emptyAnnEnv,
    
    331
    -                tcg_complete_match_env = [],
    
    332
    -                tcg_th_used        = th_var,
    
    333
    -                tcg_th_needed_deps = th_needed_deps_var,
    
    334
    -                tcg_exports        = [],
    
    335
    -                tcg_imports        = emptyImportAvails,
    
    336
    -                tcg_import_decls   = [],
    
    337
    -                tcg_used_gres     = used_gre_var,
    
    338
    -                tcg_dus            = emptyDUs,
    
    339
    -
    
    340
    -                tcg_rn_imports     = [],
    
    341
    -                tcg_rn_exports     =
    
    342
    -                    if hsc_src == HsigFile
    
    343
    -                        -- Always retain renamed syntax, so that we can give
    
    344
    -                        -- better errors.  (TODO: how?)
    
    345
    -                        then Just []
    
    346
    -                        else maybe_rn_syntax [],
    
    347
    -                tcg_rn_decls       = maybe_rn_syntax emptyRnGroup,
    
    348
    -                tcg_tr_module      = Nothing,
    
    349
    -                tcg_binds          = emptyLHsBinds,
    
    350
    -                tcg_imp_specs      = [],
    
    351
    -                tcg_sigs           = emptyNameSet,
    
    352
    -                tcg_ksigs          = emptyNameSet,
    
    353
    -                tcg_ev_binds       = emptyBag,
    
    354
    -                tcg_warns          = emptyWarn,
    
    355
    -                tcg_anns           = [],
    
    356
    -                tcg_tcs            = [],
    
    357
    -                tcg_insts          = [],
    
    358
    -                tcg_fam_insts      = [],
    
    359
    -                tcg_rules          = [],
    
    360
    -                tcg_fords          = [],
    
    361
    -                tcg_patsyns        = [],
    
    362
    -                tcg_merged         = [],
    
    363
    -                tcg_dfun_n         = dfun_n_var,
    
    364
    -                tcg_zany_n         = zany_n_var,
    
    365
    -                tcg_keep           = keep_var,
    
    366
    -                tcg_hdr_info        = (Nothing,Nothing),
    
    367
    -                tcg_main           = Nothing,
    
    368
    -                tcg_self_boot      = NoSelfBoot,
    
    369
    -                tcg_safe_infer     = infer_var,
    
    370
    -                tcg_safe_infer_reasons = infer_reasons_var,
    
    371
    -                tcg_dependent_files = dependent_files_var,
    
    372
    -                tcg_dependent_dirs  = dependent_dirs_var,
    
    373
    -                tcg_tc_plugin_solvers   = [],
    
    374
    -                tcg_tc_plugin_rewriters = emptyUFM,
    
    375
    -                tcg_defaulting_plugins  = [],
    
    376
    -                tcg_hf_plugins     = [],
    
    377
    -                tcg_top_loc        = loc,
    
    378
    -                tcg_static_wc      = static_wc_var,
    
    379
    -                tcg_complete_matches = [],
    
    380
    -                tcg_cc_st          = cc_st_var,
    
    381
    -                tcg_next_wrapper_num = next_wrapper_num
    
    382
    -             } ;
    
    383
    -        } ;
    
    272
    + = do { gbl_env <- initTcGblEnv hsc_env hsc_src keep_rn_syntax mod loc
    
    384 273
     
    
    385 274
             -- OK, here's the business end!
    
    386
    -        initTcWithGbl hsc_env gbl_env loc do_this
    
    275
    +      ;  initTcWithGbl hsc_env gbl_env loc $
    
    276
    +
    
    277
    +          -- Make sure to initialise all TcM plugins from the ambient HscEnv.
    
    278
    +          --
    
    279
    +          -- This ensures that all callers of 'initTc' enable plugins (#26395).
    
    280
    +          withTcPlugins hsc_env $
    
    281
    +          withDefaultingPlugins hsc_env $
    
    282
    +          withHoleFitPlugins hsc_env $
    
    283
    +
    
    284
    +            do_this
    
    387 285
         }
    
    388 286
     
    
    287
    +-- | Create an empty 'TcGblEnv'.
    
    288
    +initTcGblEnv :: HscEnv -> HscSource -> Bool -> Module -> RealSrcSpan -> IO TcGblEnv
    
    289
    +initTcGblEnv hsc_env hsc_src keep_rn_syntax mod loc =
    
    290
    +  do { keep_var             <- newIORef emptyNameSet
    
    291
    +     ; used_gre_var         <- newIORef []
    
    292
    +     ; th_var               <- newIORef False
    
    293
    +     ; infer_var            <- newIORef True
    
    294
    +     ; infer_reasons_var    <- newIORef emptyMessages
    
    295
    +     ; dfun_n_var           <- newIORef emptyOccSet
    
    296
    +     ; zany_n_var           <- newIORef 0
    
    297
    +     ; dependent_files_var  <- newIORef []
    
    298
    +     ; dependent_dirs_var   <- newIORef []
    
    299
    +     ; static_wc_var        <- newIORef emptyWC
    
    300
    +     ; cc_st_var            <- newIORef newCostCentreState
    
    301
    +     ; th_topdecls_var      <- newIORef []
    
    302
    +     ; th_foreign_files_var <- newIORef []
    
    303
    +     ; th_topnames_var      <- newIORef emptyNameSet
    
    304
    +     ; th_modfinalizers_var <- newIORef []
    
    305
    +     ; th_coreplugins_var   <- newIORef []
    
    306
    +     ; th_state_var         <- newIORef Map.empty
    
    307
    +     ; th_remote_state_var  <- newIORef Nothing
    
    308
    +     ; th_docs_var          <- newIORef Map.empty
    
    309
    +     ; th_needed_deps_var   <- newIORef ([], emptyUDFM)
    
    310
    +     ; next_wrapper_num     <- newIORef emptyModuleEnv
    
    311
    +     ; let
    
    312
    +        -- bangs to avoid leaking the env (#19356)
    
    313
    +        !dflags = hsc_dflags hsc_env
    
    314
    +        !mhome_unit = hsc_home_unit_maybe hsc_env
    
    315
    +        !logger = hsc_logger hsc_env
    
    316
    +
    
    317
    +        maybe_rn_syntax :: forall a. a -> Maybe a ;
    
    318
    +        maybe_rn_syntax empty_val
    
    319
    +           | logHasDumpFlag logger Opt_D_dump_rn_ast = Just empty_val
    
    320
    +
    
    321
    +           | gopt Opt_WriteHie dflags       = Just empty_val
    
    322
    +
    
    323
    +             -- We want to serialize the documentation in the .hi-files,
    
    324
    +             -- and need to extract it from the renamed syntax first.
    
    325
    +             -- See 'GHC.HsToCore.Docs.extractDocs'.
    
    326
    +           | gopt Opt_Haddock dflags       = Just empty_val
    
    327
    +
    
    328
    +           | keep_rn_syntax                = Just empty_val
    
    329
    +           | otherwise                     = Nothing ;
    
    330
    +
    
    331
    +      ; return $ TcGblEnv
    
    332
    +          { tcg_th_topdecls        = th_topdecls_var
    
    333
    +          , tcg_th_foreign_files   = th_foreign_files_var
    
    334
    +          , tcg_th_topnames        = th_topnames_var
    
    335
    +          , tcg_th_modfinalizers   = th_modfinalizers_var
    
    336
    +          , tcg_th_coreplugins     = th_coreplugins_var
    
    337
    +          , tcg_th_state           = th_state_var
    
    338
    +          , tcg_th_remote_state    = th_remote_state_var
    
    339
    +          , tcg_th_docs            = th_docs_var
    
    340
    +
    
    341
    +          , tcg_mod                = mod
    
    342
    +          , tcg_semantic_mod       = homeModuleInstantiation mhome_unit mod
    
    343
    +          , tcg_src                = hsc_src
    
    344
    +          , tcg_rdr_env            = emptyGlobalRdrEnv
    
    345
    +          , tcg_fix_env            = emptyNameEnv
    
    346
    +          , tcg_default            = emptyDefaultEnv
    
    347
    +          , tcg_default_exports    = emptyDefaultEnv
    
    348
    +          , tcg_type_env           = emptyNameEnv
    
    349
    +          , tcg_type_env_var       = hsc_type_env_vars hsc_env
    
    350
    +          , tcg_inst_env           = emptyInstEnv
    
    351
    +          , tcg_fam_inst_env       = emptyFamInstEnv
    
    352
    +          , tcg_ann_env            = emptyAnnEnv
    
    353
    +          , tcg_complete_match_env = []
    
    354
    +          , tcg_th_used            = th_var
    
    355
    +          , tcg_th_needed_deps     = th_needed_deps_var
    
    356
    +          , tcg_exports            = []
    
    357
    +          , tcg_imports            = emptyImportAvails
    
    358
    +          , tcg_import_decls       = []
    
    359
    +          , tcg_used_gres          = used_gre_var
    
    360
    +          , tcg_dus                = emptyDUs
    
    361
    +
    
    362
    +          , tcg_rn_imports = []
    
    363
    +          , tcg_rn_exports = if hsc_src == HsigFile
    
    364
    +                             -- Always retain renamed syntax, so that we can give
    
    365
    +                             -- better errors.  (TODO: how?)
    
    366
    +                             then Just []
    
    367
    +                             else maybe_rn_syntax []
    
    368
    +          , tcg_rn_decls            = maybe_rn_syntax emptyRnGroup
    
    369
    +          , tcg_tr_module           = Nothing
    
    370
    +          , tcg_binds               = emptyLHsBinds
    
    371
    +          , tcg_imp_specs           = []
    
    372
    +          , tcg_sigs                = emptyNameSet
    
    373
    +          , tcg_ksigs               = emptyNameSet
    
    374
    +          , tcg_ev_binds            = emptyBag
    
    375
    +          , tcg_warns               = emptyWarn
    
    376
    +          , tcg_anns                = []
    
    377
    +          , tcg_tcs                 = []
    
    378
    +          , tcg_insts               = []
    
    379
    +          , tcg_fam_insts           = []
    
    380
    +          , tcg_rules               = []
    
    381
    +          , tcg_fords               = []
    
    382
    +          , tcg_patsyns             = []
    
    383
    +          , tcg_merged              = []
    
    384
    +          , tcg_dfun_n              = dfun_n_var
    
    385
    +          , tcg_zany_n              = zany_n_var
    
    386
    +          , tcg_keep                = keep_var
    
    387
    +          , tcg_hdr_info            = (Nothing,Nothing)
    
    388
    +          , tcg_main                = Nothing
    
    389
    +          , tcg_self_boot           = NoSelfBoot
    
    390
    +          , tcg_safe_infer          = infer_var
    
    391
    +          , tcg_safe_infer_reasons  = infer_reasons_var
    
    392
    +          , tcg_dependent_files     = dependent_files_var
    
    393
    +          , tcg_dependent_dirs      = dependent_dirs_var
    
    394
    +          , tcg_tc_plugin_solvers   = []
    
    395
    +          , tcg_tc_plugin_rewriters = emptyUFM
    
    396
    +          , tcg_defaulting_plugins  = []
    
    397
    +          , tcg_hf_plugins          = []
    
    398
    +          , tcg_top_loc             = loc
    
    399
    +          , tcg_static_wc           = static_wc_var
    
    400
    +          , tcg_complete_matches    = []
    
    401
    +          , tcg_cc_st               = cc_st_var
    
    402
    +          , tcg_next_wrapper_num    = next_wrapper_num
    
    403
    +      } }
    
    404
    +
    
    389 405
     -- | Run a 'TcM' action in the context of an existing 'GblEnv'.
    
    390 406
     initTcWithGbl :: HscEnv
    
    391 407
                   -> TcGblEnv
    
    ... ... @@ -686,6 +702,83 @@ withIfaceErr ctx do_this = do
    686 702
               liftIO $ throwGhcExceptionIO (ProgramError (renderWithContext ctx msg))
    
    687 703
             Succeeded result -> return result
    
    688 704
     
    
    705
    +{-
    
    706
    +************************************************************************
    
    707
    +*                                                                      *
    
    708
    +                 Initialising plugins for TcM
    
    709
    +*                                                                      *
    
    710
    +************************************************************************
    
    711
    +-}
    
    712
    +
    
    713
    +-- | Initialise typechecker plugins, run the inner action, then stop
    
    714
    +-- the typechecker plugins.
    
    715
    +withTcPlugins :: HscEnv -> TcM a -> TcM a
    
    716
    +withTcPlugins hsc_env m =
    
    717
    +    case catMaybes $ mapPlugins (hsc_plugins hsc_env) tcPlugin of
    
    718
    +       []      -> m  -- Common fast case
    
    719
    +       plugins -> do
    
    720
    +                (solvers, rewriters, stops) <-
    
    721
    +                  unzip3 `fmap` mapM start_plugin plugins
    
    722
    +                let
    
    723
    +                  rewritersUniqFM :: UniqFM TyCon [TcPluginRewriter]
    
    724
    +                  !rewritersUniqFM = sequenceUFMList rewriters
    
    725
    +                -- The following ensures that tcPluginStop is called even if a type
    
    726
    +                -- error occurs during compilation (Fix of #10078)
    
    727
    +                eitherRes <- tryM $
    
    728
    +                  updGblEnv (\e -> e { tcg_tc_plugin_solvers   = solvers
    
    729
    +                                     , tcg_tc_plugin_rewriters = rewritersUniqFM })
    
    730
    +                    m
    
    731
    +                mapM_ runTcPluginM stops
    
    732
    +                case eitherRes of
    
    733
    +                  Left _ -> failM
    
    734
    +                  Right res -> return res
    
    735
    +  where
    
    736
    +  start_plugin (TcPlugin start solve rewrite stop) =
    
    737
    +    do s <- runTcPluginM start
    
    738
    +       return (solve s, rewrite s, stop s)
    
    739
    +
    
    740
    +-- | Initialise defaulting plugins, run the inner action, then stop
    
    741
    +-- the defaulting plugins.
    
    742
    +withDefaultingPlugins :: HscEnv -> TcM a -> TcM a
    
    743
    +withDefaultingPlugins hsc_env m =
    
    744
    +  do case catMaybes $ mapPlugins (hsc_plugins hsc_env) defaultingPlugin of
    
    745
    +       [] -> m  -- Common fast case
    
    746
    +       plugins  -> do (plugins,stops) <- mapAndUnzipM start_plugin plugins
    
    747
    +                      -- This ensures that dePluginStop is called even if a type
    
    748
    +                      -- error occurs during compilation
    
    749
    +                      eitherRes <- tryM $ do
    
    750
    +                        updGblEnv (\e -> e { tcg_defaulting_plugins = plugins })
    
    751
    +                          m
    
    752
    +                      mapM_ runTcPluginM stops
    
    753
    +                      case eitherRes of
    
    754
    +                        Left _ -> failM
    
    755
    +                        Right res -> return res
    
    756
    +  where
    
    757
    +  start_plugin (DefaultingPlugin start fill stop) =
    
    758
    +    do s <- runTcPluginM start
    
    759
    +       return (fill s, stop s)
    
    760
    +
    
    761
    +-- | Initialise hole fit plugins, run the inner action, then stop
    
    762
    +-- the hole fit plugins.
    
    763
    +withHoleFitPlugins :: HscEnv -> TcM a -> TcM a
    
    764
    +withHoleFitPlugins hsc_env m =
    
    765
    +  case catMaybes $ mapPlugins (hsc_plugins hsc_env) holeFitPlugin of
    
    766
    +    [] -> m  -- Common fast case
    
    767
    +    plugins -> do (plugins,stops) <- mapAndUnzipM start_plugin plugins
    
    768
    +                  -- This ensures that hfPluginStop is called even if a type
    
    769
    +                  -- error occurs during compilation.
    
    770
    +                  eitherRes <- tryM $
    
    771
    +                    updGblEnv (\e -> e { tcg_hf_plugins = plugins })
    
    772
    +                      m
    
    773
    +                  sequence_ stops
    
    774
    +                  case eitherRes of
    
    775
    +                    Left _ -> failM
    
    776
    +                    Right res -> return res
    
    777
    +  where
    
    778
    +    start_plugin (HoleFitPluginR init plugin stop) =
    
    779
    +      do ref <- init
    
    780
    +         return (plugin ref, stop ref)
    
    781
    +
    
    689 782
     {-
    
    690 783
     ************************************************************************
    
    691 784
     *                                                                      *
    

  • testsuite/tests/tcplugins/T26395.hs
    1
    +
    
    2
    +{-# LANGUAGE DataKinds #-}
    
    3
    +{-# LANGUAGE GADTs #-}
    
    4
    +{-# LANGUAGE StandaloneKindSignatures #-}
    
    5
    +{-# LANGUAGE TypeFamilies #-}
    
    6
    +{-# LANGUAGE TypeOperators #-}
    
    7
    +{-# LANGUAGE UnliftedDatatypes #-}
    
    8
    +
    
    9
    +{-# OPTIONS_GHC -fplugin=T26395_Plugin #-}
    
    10
    +
    
    11
    +{-# OPTIONS_GHC -Wincomplete-patterns #-}
    
    12
    +{-# OPTIONS_GHC -Winaccessible-code #-}
    
    13
    +{-# OPTIONS_GHC -Woverlapping-patterns #-}
    
    14
    +
    
    15
    +module T26395 where
    
    16
    +
    
    17
    +import Data.Kind
    
    18
    +import GHC.TypeNats
    
    19
    +import GHC.Exts ( UnliftedType )
    
    20
    +
    
    21
    +-- This test verifies that typechecker plugins are enabled
    
    22
    +-- when we run the solver for pattern-match checking.
    
    23
    +
    
    24
    +type Peano :: Nat -> UnliftedType
    
    25
    +data Peano n where
    
    26
    +  Z :: Peano 0
    
    27
    +  S :: Peano n -> Peano (1 + n)
    
    28
    +
    
    29
    +test1 :: Peano n -> Peano n -> Int
    
    30
    +test1 Z      Z    = 0
    
    31
    +test1 (S n) (S m) = 1 + test1 n m
    
    32
    +
    
    33
    +{-
    
    34
    +The following test doesn't work properly due to #26401:
    
    35
    +the pattern-match checker reports a missing equation
    
    36
    +
    
    37
    +  Z (S _) _
    
    38
    +
    
    39
    +but there is no invocation of the solver of the form
    
    40
    +
    
    41
    +  [G] n ~ 0
    
    42
    +  [G] m ~ 1 + m1
    
    43
    +  [G] (n-m) ~ m2
    
    44
    +
    
    45
    +for which we could report the Givens as contradictory.
    
    46
    +
    
    47
    +test2 :: Peano n -> Peano m -> Peano (n - m) -> Int
    
    48
    +test2  Z     Z     Z    = 0
    
    49
    +test2 (S _) (S _)  _    = 1
    
    50
    +test2 (S _)  Z    (S _) = 2
    
    51
    +-}

  • testsuite/tests/tcplugins/T26395.stderr
    1
    +[1 of 2] Compiling T26395_Plugin    ( T26395_Plugin.hs, T26395_Plugin.o )
    
    2
    +[2 of 2] Compiling T26395           ( T26395.hs, T26395.o )

  • testsuite/tests/tcplugins/T26395_Plugin.hs
    1
    +{-# LANGUAGE RecordWildCards #-}
    
    2
    +{-# LANGUAGE LambdaCase #-}
    
    3
    +{-# LANGUAGE MultiWayIf #-}
    
    4
    +{-# LANGUAGE BlockArguments #-}
    
    5
    +{-# LANGUAGE ViewPatterns #-}
    
    6
    +
    
    7
    +{-# OPTIONS_GHC -Wall -Wno-orphans #-}
    
    8
    +
    
    9
    +module T26395_Plugin where
    
    10
    +
    
    11
    +-- base
    
    12
    +import Prelude hiding ( (<>) )
    
    13
    +import qualified Data.Semigroup as S
    
    14
    +import Data.List ( partition )
    
    15
    +import Data.Maybe
    
    16
    +import GHC.TypeNats
    
    17
    +
    
    18
    +-- ghc
    
    19
    +import GHC.Builtin.Types.Literals
    
    20
    +import GHC.Core.Predicate
    
    21
    +import GHC.Core.TyCo.Rep
    
    22
    +import GHC.Plugins
    
    23
    +import GHC.Tc.Plugin
    
    24
    +import GHC.Tc.Types
    
    25
    +import GHC.Tc.Types.Constraint
    
    26
    +import GHC.Tc.Types.Evidence
    
    27
    +import GHC.Tc.Utils.TcType
    
    28
    +import GHC.Types.Unique.Map
    
    29
    +
    
    30
    +--------------------------------------------------------------------------------
    
    31
    +
    
    32
    +plugin :: Plugin
    
    33
    +plugin =
    
    34
    +  defaultPlugin
    
    35
    +    { pluginRecompile = purePlugin
    
    36
    +    , tcPlugin = \ _-> Just $
    
    37
    +        TcPlugin
    
    38
    +          { tcPluginInit    = pure ()
    
    39
    +          , tcPluginSolve   = \ _ -> solve
    
    40
    +          , tcPluginRewrite = \ _ -> emptyUFM
    
    41
    +          , tcPluginStop    = \ _ -> pure ()
    
    42
    +          }
    
    43
    +    }
    
    44
    +
    
    45
    +solve :: EvBindsVar -> [Ct] -> [Ct] -> TcPluginM TcPluginSolveResult
    
    46
    +solve _ givens wanteds
    
    47
    +  -- This plugin only reports inconsistencies among Given constraints.
    
    48
    +  | not $ null wanteds
    
    49
    +  = pure $ TcPluginOk [] []
    
    50
    +  | otherwise
    
    51
    +  = do { let givenLinearExprs = mapMaybe linearExprCt_maybe givens
    
    52
    +             sols = solutions givenLinearExprs
    
    53
    +
    
    54
    +        ; tcPluginTrace "solveLinearExprs" $
    
    55
    +            vcat [ text "givens:" <+> ppr givens
    
    56
    +                 , text "linExprs:" <+> ppr givenLinearExprs
    
    57
    +                 , text "sols:" <+> ppr (take 1 sols)
    
    58
    +                 ]
    
    59
    +        ; return $
    
    60
    +            if null sols
    
    61
    +            then TcPluginContradiction givens
    
    62
    +            else TcPluginOk [] []
    
    63
    +       }
    
    64
    +
    
    65
    +data LinearExpr =
    
    66
    +  LinearExpr
    
    67
    +    { constant :: Integer
    
    68
    +    , coeffs   :: UniqMap TyVar Integer
    
    69
    +    }
    
    70
    +instance Semigroup LinearExpr where
    
    71
    +  LinearExpr c xs <> LinearExpr d ys =
    
    72
    +    LinearExpr ( c + d ) ( plusMaybeUniqMap_C comb xs ys )
    
    73
    +    where
    
    74
    +      comb a1 a2 =
    
    75
    +        let a = a1 + a2
    
    76
    +        in if a == 0
    
    77
    +           then Nothing
    
    78
    +           else Just a
    
    79
    +
    
    80
    +instance Monoid LinearExpr where
    
    81
    +  mempty = LinearExpr 0 emptyUniqMap
    
    82
    +
    
    83
    +mapLinearExpr :: (Integer -> Integer) -> LinearExpr -> LinearExpr
    
    84
    +mapLinearExpr f (LinearExpr c xs) = LinearExpr (f c) (mapUniqMap f xs)
    
    85
    +
    
    86
    +minusLinearExpr :: LinearExpr -> LinearExpr -> LinearExpr
    
    87
    +minusLinearExpr a b = a S.<> mapLinearExpr negate b
    
    88
    +
    
    89
    +instance Outputable LinearExpr where
    
    90
    +  ppr ( LinearExpr c xs ) =
    
    91
    +    hcat $ punctuate ( text " + " ) $
    
    92
    +      ( ppr c : map ppr_var ( nonDetUniqMapToList xs ) )
    
    93
    +    where
    
    94
    +      ppr_var ( tv, i )
    
    95
    +        | i == 1
    
    96
    +        = ppr tv
    
    97
    +        | i < 0
    
    98
    +        = parens ( text "-" <> ppr (abs i) ) <> text "*" <> ppr tv
    
    99
    +        | otherwise
    
    100
    +        = ppr i <> text "*" <> ppr tv
    
    101
    +
    
    102
    +maxCoeff :: LinearExpr -> Double
    
    103
    +maxCoeff ( LinearExpr c xs ) =
    
    104
    +  maximum ( map fromInteger ( c : nonDetEltsUniqMap xs ) )
    
    105
    +
    
    106
    +
    
    107
    +linearExprCt_maybe :: Ct -> Maybe LinearExpr
    
    108
    +linearExprCt_maybe ct =
    
    109
    +  case classifyPredType (ctPred ct) of
    
    110
    +    EqPred NomEq lhs rhs
    
    111
    +      | all isNaturalTy [ typeKind lhs, typeKind rhs ]
    
    112
    +      , Just e1 <- linearExprTy_maybe lhs
    
    113
    +      , Just e2 <- linearExprTy_maybe rhs
    
    114
    +      -> Just $ e1 `minusLinearExpr` e2
    
    115
    +    _ -> Nothing
    
    116
    +
    
    117
    +isNat :: Type -> Maybe Integer
    
    118
    +isNat ty
    
    119
    +  | Just (NumTyLit n) <- isLitTy ty
    
    120
    +  = Just n
    
    121
    +  | otherwise
    
    122
    +  = Nothing
    
    123
    +
    
    124
    +linearExprTy_maybe :: Type -> Maybe LinearExpr
    
    125
    +linearExprTy_maybe ty
    
    126
    +  | Just n <- isNat ty
    
    127
    +  = Just $ LinearExpr n emptyUniqMap
    
    128
    +  | Just (tc, args) <- splitTyConApp_maybe ty
    
    129
    +  = if | tc == typeNatAddTyCon
    
    130
    +       , [x, y] <- args
    
    131
    +       , Just e1 <- linearExprTy_maybe x
    
    132
    +       , Just e2 <- linearExprTy_maybe y
    
    133
    +       -> Just $ e1 S.<> e2
    
    134
    +       | tc == typeNatSubTyCon
    
    135
    +       , [x,y] <- args
    
    136
    +       , Just e1 <- linearExprTy_maybe x
    
    137
    +       , Just e2 <- linearExprTy_maybe y
    
    138
    +       -> Just $ e1 `minusLinearExpr` e2
    
    139
    +       | tc == typeNatMulTyCon
    
    140
    +       , [x, y] <- args
    
    141
    +       ->
    
    142
    +        if | Just ( LinearExpr n xs ) <- linearExprTy_maybe x
    
    143
    +           , isNullUniqMap xs
    
    144
    +           , Just e <- linearExprTy_maybe y
    
    145
    +           -> Just $
    
    146
    +                if n == 0
    
    147
    +                then mempty
    
    148
    +                else mapLinearExpr (n *) e
    
    149
    +           | Just ( LinearExpr n ys ) <- linearExprTy_maybe y
    
    150
    +           , isNullUniqMap ys
    
    151
    +           , Just e <- linearExprTy_maybe x
    
    152
    +           -> Just $
    
    153
    +                if n == 0
    
    154
    +                then mempty
    
    155
    +                else mapLinearExpr (fromIntegral n *) e
    
    156
    +           | otherwise
    
    157
    +           -> Nothing
    
    158
    +       | otherwise
    
    159
    +       -> Nothing
    
    160
    +  | Just tv <- getTyVar_maybe ty
    
    161
    +  = Just $ LinearExpr 0 ( unitUniqMap tv 1 )
    
    162
    +  | otherwise
    
    163
    +  = Nothing
    
    164
    +
    
    165
    +-- Brute force algorithm to check whether a system of Diophantine
    
    166
    +-- linear equations is solvable in natural numbers.
    
    167
    +solutions :: [ LinearExpr ] -> [ UniqMap TyVar Natural ]
    
    168
    +solutions eqs =
    
    169
    +  let
    
    170
    +    (constEqs, realEqs) = partition (isNullUniqMap . coeffs) eqs
    
    171
    +    d   = length realEqs
    
    172
    +    fvs = nonDetKeysUniqMap $ plusUniqMapList ( map coeffs realEqs )
    
    173
    +  in
    
    174
    +    if | any ( ( /= 0 ) . evalLinearExpr emptyUniqMap ) constEqs
    
    175
    +       -> []
    
    176
    +       | d == 0
    
    177
    +       -> [ emptyUniqMap ]
    
    178
    +       | otherwise
    
    179
    +       ->
    
    180
    +          let
    
    181
    +            m = maximum $ map maxCoeff realEqs
    
    182
    +            hadamardBound = sqrt ( fromIntegral $ d ^ d ) * m ^ d
    
    183
    +            tests = mkAssignments ( floor hadamardBound ) fvs
    
    184
    +          in
    
    185
    +            filter ( \ test -> isSolution test realEqs ) tests
    
    186
    +
    
    187
    +
    
    188
    +mkAssignments :: Natural -> [ TyVar ] -> [ UniqMap TyVar Natural ]
    
    189
    +mkAssignments _ [] = [ emptyUniqMap ]
    
    190
    +mkAssignments b (v : vs) =
    
    191
    +  [ addToUniqMap rest v n
    
    192
    +  | n <- [ 0 .. b ]
    
    193
    +  , rest <- mkAssignments b vs
    
    194
    +  ]
    
    195
    +
    
    196
    +isSolution :: UniqMap TyVar Natural -> [ LinearExpr ] -> Bool
    
    197
    +isSolution assig =
    
    198
    +  all ( \ expr -> evalLinearExpr assig expr == 0 )
    
    199
    +
    
    200
    +evalLinearExpr :: UniqMap TyVar Natural -> LinearExpr -> Integer
    
    201
    +evalLinearExpr vals ( LinearExpr c xs ) = nonDetFoldUniqMap aux c xs
    
    202
    +  where
    
    203
    +    aux ( tv, coeff ) !acc = acc + coeff * val
    
    204
    +      where
    
    205
    +        val :: Integer
    
    206
    +        val = case lookupUniqMap vals tv of
    
    207
    +                 Nothing -> pprPanic "evalLinearExpr: missing tv" (ppr tv)
    
    208
    +                 Just v  -> fromIntegral v

  • testsuite/tests/tcplugins/all.T
    ... ... @@ -110,6 +110,19 @@ test('TcPlugin_CtId'
    110 110
           , '-dynamic -package ghc' if have_dynamic() else '-package ghc' ]
    
    111 111
         )
    
    112 112
     
    
    113
    +# Checks that we run type-checker plugins for pattern-match warnings.
    
    114
    +test('T26395'
    
    115
    +    , [ extra_files(
    
    116
    +        [ 'T26395_Plugin.hs'
    
    117
    +        , 'T26395.hs'
    
    118
    +        ])
    
    119
    +      , req_th
    
    120
    +      ]
    
    121
    +    , multimod_compile
    
    122
    +    , [ 'T26395.hs'
    
    123
    +      , '-dynamic -package ghc' if have_dynamic() else '-package ghc' ]
    
    124
    +    )
    
    125
    +
    
    113 126
     test('T11462', [js_broken(22261), req_th, req_plugins], multi_compile,
    
    114 127
          [None, [('T11462_Plugin.hs', '-package ghc'), ('T11462.hs', '')],
    
    115 128
           '-dynamic' if have_dynamic() else ''])