-- | extendInteractiveContext is called with new TyThings recently defined to update the
-- InteractiveContext to include them.  Ids are easily removed when shadowed,
-- but Classes and TyCons are not.  Some work could be done to determine
-- whether they are entirely shadowed, but as you could still have references
-- to them (e.g. instances for classes or values of the type for TyCons), it's
-- not clear whether removing them is even the appropriate behavior.
extendInteractiveContext :: InteractiveContext
                         -> [Id] -> [TyCon]
                         -> [ClsInst] -> [FamInst]
                         -> Maybe [Type]
                         -> [PatSyn]
                         -> InteractiveContext
extendInteractiveContext ictxt ids tcs new_cls_insts new_fam_insts defaults new_patsyns
  = ictxt { ic_mod_index  = ic_mod_index ictxt + 1
                            -- Always bump this; even instances should create
                            -- a new mod_index (Trac #9426)
          , ic_tythings   = new_tythings ++ old_tythings
          , ic_rn_gbl_env = ic_rn_gbl_env ictxt `icExtendGblRdrEnv` new_tythings
          , ic_instances  = ( new_cls_insts ++ old_cls_insts
                            , new_fam_insts ++ old_fam_insts )
          , ic_default    = defaults }
  where
    new_tythings = map AnId ids ++ map ATyCon tcs ++ map (AConLike . PatSynCon) new_patsyns
    old_tythings = filterOut (shadowed_by ids) (ic_tythings ictxt)

    -- Discard old instances that have been fully overrridden
    -- See Note [Override identical instances in GHCi]
    (cls_insts, fam_insts) = ic_instances ictxt
    old_cls_insts = filterOut (\i -> any (identicalClsInstHead i) new_cls_insts) cls_insts
    old_fam_insts = filterOut (\i -> any (identicalFamInstHead i) new_fam_insts) fam_insts
extendInteractiveContext :: InteractiveContext
                         -> [Id] -> [TyCon]
                         -> [ClsInst] -> [FamInst]
                         -> Maybe [Type]
                         -> [PatSyn]
                         -> InteractiveContext
extendInteractiveContext ictxt ids tcs new_cls_insts new_fam_insts defaults new_patsyns
  = ictxt { ic_mod_index  = ic_mod_index ictxt + 1
                            -- Always bump this; even instances should create
                            -- a new mod_index (Trac #9426)
          , ic_tythings   = new_tythings ++ old_tythings
          , ic_rn_gbl_env = ic_rn_gbl_env ictxt `icExtendGblRdrEnv` new_tythings
          , ic_instances  = ( new_cls_insts ++ old_cls_insts
                            , new_fam_insts ++ old_fam_insts )
          , ic_default    = defaults }
  where
    new_tythings = map AnId ids ++ map ATyCon tcs ++ map (AConLike . PatSynCon) new_patsyns
    old_tythings = filterOut (shadowed_by ids) (ic_tythings ictxt)

    -- Discard old instances that have been fully overrridden
    -- See Note [Override identical instances in GHCi]
    (cls_insts, fam_insts) = ic_instances ictxt
    old_cls_insts = filterOut (\i -> any (identicalClsInstHead i) new_cls_insts) cls_insts
    old_fam_insts = filterOut (\i -> any (identicalFamInstHead i) new_fam_insts) fam_insts
extendInteractiveContext ictxt ids tcs new_cls_insts new_fam_insts defaults new_patsyns
  = ictxt { ic_mod_index  = ic_mod_index ictxt + 1
                            -- Always bump this; even instances should create
                            -- a new mod_index (Trac #9426)
          , ic_tythings   = new_tythings ++ old_tythings
          , ic_rn_gbl_env = ic_rn_gbl_env ictxt `icExtendGblRdrEnv` new_tythings
          , ic_instances  = ( new_cls_insts ++ old_cls_insts
                            , new_fam_insts ++ old_fam_insts )
          , ic_default    = defaults }
  where
    new_tythings = map AnId ids ++ map ATyCon tcs ++ map (AConLike . PatSynCon) new_patsyns
    old_tythings = filterOut (shadowed_by ids) (ic_tythings ictxt)

    -- Discard old instances that have been fully overrridden
    -- See Note [Override identical instances in GHCi]
    (cls_insts, fam_insts) = ic_instances ictxt
    old_cls_insts = filterOut (\i -> any (identicalClsInstHead i) new_cls_insts) cls_insts
    old_fam_insts = filterOut (\i -> any (identicalFamInstHead i) new_fam_insts) fam_insts