{-# LANGUAGE PatternSynonyms #-}
module GHC.Rename.Unbound
   ( mkUnboundName
   , mkUnboundNameRdr
   , isUnboundName
   , reportUnboundName
   , reportUnboundName'
   , unknownNameSuggestions
   , WhatLooking(..)
   , WhereLooking(..)
   , LookingFor(..)
   , unboundName
   , unboundNameX
   , notInScopeErr
   , nameSpacesRelated
   )
where
import GHC.Prelude
import GHC.Driver.Session
import GHC.Driver.Ppr
import GHC.Tc.Errors.Types
import GHC.Tc.Utils.Monad
import GHC.Builtin.Names ( mkUnboundName, isUnboundName, getUnique)
import GHC.Utils.Misc
import GHC.Data.Maybe
import GHC.Data.FastString
import qualified GHC.LanguageExtensions as LangExt
import GHC.Types.Hint
  ( GhcHint (SuggestExtension, RemindFieldSelectorSuppressed, ImportSuggestion, SuggestSimilarNames)
  , LanguageExtensionHint (SuggestSingleExtension)
  , ImportSuggestion(..), SimilarName(..), HowInScope(..) )
import GHC.Types.SrcLoc as SrcLoc
import GHC.Types.Name
import GHC.Types.Name.Reader
import GHC.Types.Unique.DFM (udfmToList)
import GHC.Unit.Module
import GHC.Unit.Module.Imported
import GHC.Unit.Home.ModInfo
import GHC.Data.Bag
import GHC.Utils.Outputable (empty)
import Data.List (sortBy, partition, nub)
import Data.List.NonEmpty ( pattern (:|), NonEmpty )
import Data.Function ( on )
data WhatLooking = WL_Anything    
                 | WL_Constructor 
                        
                        
                 | WL_RecField    
                        
                        
                 | WL_None        
                        
                        
                 deriving WhatLooking -> WhatLooking -> Bool
(WhatLooking -> WhatLooking -> Bool)
-> (WhatLooking -> WhatLooking -> Bool) -> Eq WhatLooking
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: WhatLooking -> WhatLooking -> Bool
== :: WhatLooking -> WhatLooking -> Bool
$c/= :: WhatLooking -> WhatLooking -> Bool
/= :: WhatLooking -> WhatLooking -> Bool
Eq
data WhereLooking = WL_Anywhere   
                  | WL_Global     
                  | WL_LocalTop   
                  | WL_LocalOnly
                        
                        
                        
                        
data LookingFor = LF { LookingFor -> WhatLooking
lf_which :: WhatLooking
                     , LookingFor -> WhereLooking
lf_where :: WhereLooking
                     }
mkUnboundNameRdr :: RdrName -> Name
mkUnboundNameRdr :: RdrName -> Name
mkUnboundNameRdr RdrName
rdr = OccName -> Name
mkUnboundName (RdrName -> OccName
rdrNameOcc RdrName
rdr)
reportUnboundName' :: WhatLooking -> RdrName -> RnM Name
reportUnboundName' :: WhatLooking -> RdrName -> RnM Name
reportUnboundName' WhatLooking
what_look RdrName
rdr = LookingFor -> RdrName -> RnM Name
unboundName (WhatLooking -> WhereLooking -> LookingFor
LF WhatLooking
what_look WhereLooking
WL_Anywhere) RdrName
rdr
reportUnboundName :: RdrName -> RnM Name
reportUnboundName :: RdrName -> RnM Name
reportUnboundName = WhatLooking -> RdrName -> RnM Name
reportUnboundName' WhatLooking
WL_Anything
unboundName :: LookingFor -> RdrName -> RnM Name
unboundName :: LookingFor -> RdrName -> RnM Name
unboundName LookingFor
lf RdrName
rdr = LookingFor -> RdrName -> [GhcHint] -> RnM Name
unboundNameX LookingFor
lf RdrName
rdr []
unboundNameX :: LookingFor -> RdrName -> [GhcHint] -> RnM Name
unboundNameX :: LookingFor -> RdrName -> [GhcHint] -> RnM Name
unboundNameX LookingFor
looking_for RdrName
rdr_name [GhcHint]
hints
  = do  { DynFlags
dflags <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
        ; let show_helpful_errors :: Bool
show_helpful_errors = GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_HelpfulErrors DynFlags
dflags
              err :: NotInScopeError
err = WhereLooking -> RdrName -> NotInScopeError
notInScopeErr (LookingFor -> WhereLooking
lf_where LookingFor
looking_for) RdrName
rdr_name
        ; if Bool -> Bool
not Bool
show_helpful_errors
          then TcRnMessage -> IOEnv (Env TcGblEnv TcLclEnv) ()
addErr (TcRnMessage -> IOEnv (Env TcGblEnv TcLclEnv) ())
-> TcRnMessage -> IOEnv (Env TcGblEnv TcLclEnv) ()
forall a b. (a -> b) -> a -> b
$ NotInScopeError
-> RdrName -> [ImportError] -> [GhcHint] -> TcRnMessage
TcRnNotInScope NotInScopeError
err RdrName
rdr_name [] [GhcHint]
hints
          else do { LocalRdrEnv
local_env  <- RnM LocalRdrEnv
getLocalRdrEnv
                  ; GlobalRdrEnv
global_env <- TcRn GlobalRdrEnv
getGlobalRdrEnv
                  ; ImportAvails
impInfo <- TcRn ImportAvails
getImports
                  ; Module
currmod <- IOEnv (Env TcGblEnv TcLclEnv) Module
forall (m :: * -> *). HasModule m => m Module
getModule
                  ; HomePackageTable
hpt <- TcRnIf TcGblEnv TcLclEnv HomePackageTable
forall gbl lcl. TcRnIf gbl lcl HomePackageTable
getHpt
                  ; let ([ImportError]
imp_errs, [GhcHint]
suggs) =
                          LookingFor
-> DynFlags
-> HomePackageTable
-> Module
-> GlobalRdrEnv
-> LocalRdrEnv
-> ImportAvails
-> RdrName
-> ([ImportError], [GhcHint])
unknownNameSuggestions_ LookingFor
looking_for
                            DynFlags
dflags HomePackageTable
hpt Module
currmod GlobalRdrEnv
global_env LocalRdrEnv
local_env ImportAvails
impInfo
                            RdrName
rdr_name
                  ; TcRnMessage -> IOEnv (Env TcGblEnv TcLclEnv) ()
addErr (TcRnMessage -> IOEnv (Env TcGblEnv TcLclEnv) ())
-> TcRnMessage -> IOEnv (Env TcGblEnv TcLclEnv) ()
forall a b. (a -> b) -> a -> b
$
                      NotInScopeError
-> RdrName -> [ImportError] -> [GhcHint] -> TcRnMessage
TcRnNotInScope NotInScopeError
err RdrName
rdr_name [ImportError]
imp_errs ([GhcHint]
hints [GhcHint] -> [GhcHint] -> [GhcHint]
forall a. [a] -> [a] -> [a]
++ [GhcHint]
suggs) }
        ; Name -> RnM Name
forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
forall (m :: * -> *) a. Monad m => a -> m a
return (RdrName -> Name
mkUnboundNameRdr RdrName
rdr_name) }
notInScopeErr :: WhereLooking -> RdrName -> NotInScopeError
notInScopeErr :: WhereLooking -> RdrName -> NotInScopeError
notInScopeErr WhereLooking
where_look RdrName
rdr_name
  | Just Name
name <- RdrName -> Maybe Name
isExact_maybe RdrName
rdr_name
  = Name -> NotInScopeError
NoExactName Name
name
  | WhereLooking
WL_LocalTop <- WhereLooking
where_look
  = NotInScopeError
NoTopLevelBinding
  | Bool
otherwise
  = NotInScopeError
NotInScope
unknownNameSuggestions :: WhatLooking -> DynFlags
                       -> HomePackageTable -> Module
                       -> GlobalRdrEnv -> LocalRdrEnv -> ImportAvails
                       -> RdrName -> ([ImportError], [GhcHint])
unknownNameSuggestions :: WhatLooking
-> DynFlags
-> HomePackageTable
-> Module
-> GlobalRdrEnv
-> LocalRdrEnv
-> ImportAvails
-> RdrName
-> ([ImportError], [GhcHint])
unknownNameSuggestions WhatLooking
what_look = LookingFor
-> DynFlags
-> HomePackageTable
-> Module
-> GlobalRdrEnv
-> LocalRdrEnv
-> ImportAvails
-> RdrName
-> ([ImportError], [GhcHint])
unknownNameSuggestions_ (WhatLooking -> WhereLooking -> LookingFor
LF WhatLooking
what_look WhereLooking
WL_Anywhere)
unknownNameSuggestions_ :: LookingFor -> DynFlags
                       -> HomePackageTable -> Module
                       -> GlobalRdrEnv -> LocalRdrEnv -> ImportAvails
                       -> RdrName -> ([ImportError], [GhcHint])
unknownNameSuggestions_ :: LookingFor
-> DynFlags
-> HomePackageTable
-> Module
-> GlobalRdrEnv
-> LocalRdrEnv
-> ImportAvails
-> RdrName
-> ([ImportError], [GhcHint])
unknownNameSuggestions_ LookingFor
looking_for DynFlags
dflags HomePackageTable
hpt Module
curr_mod GlobalRdrEnv
global_env LocalRdrEnv
local_env
                          ImportAvails
imports RdrName
tried_rdr_name = ([ImportError]
imp_errs, [GhcHint]
suggs)
  where
    suggs :: [GhcHint]
suggs = [[GhcHint]] -> [GhcHint]
forall a. Monoid a => [a] -> a
mconcat
      [ (NonEmpty SimilarName -> GhcHint) -> [SimilarName] -> [GhcHint]
forall a b. (NonEmpty a -> b) -> [a] -> [b]
if_ne (RdrName -> NonEmpty SimilarName -> GhcHint
SuggestSimilarNames RdrName
tried_rdr_name) ([SimilarName] -> [GhcHint]) -> [SimilarName] -> [GhcHint]
forall a b. (a -> b) -> a -> b
$
          LookingFor
-> DynFlags
-> GlobalRdrEnv
-> LocalRdrEnv
-> RdrName
-> [SimilarName]
similarNameSuggestions LookingFor
looking_for DynFlags
dflags GlobalRdrEnv
global_env LocalRdrEnv
local_env RdrName
tried_rdr_name
      , (ImportSuggestion -> GhcHint) -> [ImportSuggestion] -> [GhcHint]
forall a b. (a -> b) -> [a] -> [b]
map ImportSuggestion -> GhcHint
ImportSuggestion [ImportSuggestion]
imp_suggs
      , RdrName -> [GhcHint]
extensionSuggestions RdrName
tried_rdr_name
      , GlobalRdrEnv -> RdrName -> [GhcHint]
fieldSelectorSuggestions GlobalRdrEnv
global_env RdrName
tried_rdr_name ]
    ([ImportError]
imp_errs, [ImportSuggestion]
imp_suggs) = LookingFor
-> GlobalRdrEnv
-> HomePackageTable
-> Module
-> ImportAvails
-> RdrName
-> ([ImportError], [ImportSuggestion])
importSuggestions LookingFor
looking_for GlobalRdrEnv
global_env HomePackageTable
hpt Module
curr_mod ImportAvails
imports RdrName
tried_rdr_name
    if_ne :: (NonEmpty a -> b) -> [a] -> [b]
    if_ne :: forall a b. (NonEmpty a -> b) -> [a] -> [b]
if_ne NonEmpty a -> b
_ []       = []
    if_ne NonEmpty a -> b
f (a
a : [a]
as) = [NonEmpty a -> b
f (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
as)]
fieldSelectorSuggestions :: GlobalRdrEnv -> RdrName -> [GhcHint]
fieldSelectorSuggestions :: GlobalRdrEnv -> RdrName -> [GhcHint]
fieldSelectorSuggestions GlobalRdrEnv
global_env RdrName
tried_rdr_name
  | [GlobalRdrElt] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [GlobalRdrElt]
gres = []
  | Bool
otherwise = [RdrName -> [Name] -> GhcHint
RemindFieldSelectorSuppressed RdrName
tried_rdr_name [Name]
parents]
  where
    gres :: [GlobalRdrElt]
gres = (GlobalRdrElt -> Bool) -> [GlobalRdrElt] -> [GlobalRdrElt]
forall a. (a -> Bool) -> [a] -> [a]
filter GlobalRdrElt -> Bool
isNoFieldSelectorGRE ([GlobalRdrElt] -> [GlobalRdrElt])
-> [GlobalRdrElt] -> [GlobalRdrElt]
forall a b. (a -> b) -> a -> b
$
               RdrName -> GlobalRdrEnv -> [GlobalRdrElt]
lookupGRE_RdrName' RdrName
tried_rdr_name GlobalRdrEnv
global_env
    parents :: [Name]
parents = [ Name
parent | ParentIs Name
parent <- (GlobalRdrElt -> Parent) -> [GlobalRdrElt] -> [Parent]
forall a b. (a -> b) -> [a] -> [b]
map GlobalRdrElt -> Parent
gre_par [GlobalRdrElt]
gres ]
similarNameSuggestions :: LookingFor -> DynFlags
                       -> GlobalRdrEnv -> LocalRdrEnv
                       -> RdrName -> [SimilarName]
similarNameSuggestions :: LookingFor
-> DynFlags
-> GlobalRdrEnv
-> LocalRdrEnv
-> RdrName
-> [SimilarName]
similarNameSuggestions looking_for :: LookingFor
looking_for@(LF WhatLooking
what_look WhereLooking
where_look) DynFlags
dflags GlobalRdrEnv
global_env
                       LocalRdrEnv
local_env RdrName
tried_rdr_name
  = String -> [(String, SimilarName)] -> [SimilarName]
forall a. String -> [(String, a)] -> [a]
fuzzyLookup (DynFlags -> RdrName -> String
forall a. Outputable a => DynFlags -> a -> String
showPpr DynFlags
dflags RdrName
tried_rdr_name) [(String, SimilarName)]
all_possibilities
  where
    all_possibilities :: [(String, SimilarName)]
    all_possibilities :: [(String, SimilarName)]
all_possibilities = case WhatLooking
what_look of
      WhatLooking
WL_None -> []
      WhatLooking
_ -> [ (DynFlags -> RdrName -> String
forall a. Outputable a => DynFlags -> a -> String
showPpr DynFlags
dflags RdrName
r, RdrName -> HowInScope -> SimilarName
SimilarRdrName RdrName
r (SrcSpan -> HowInScope
LocallyBoundAt SrcSpan
loc))
           | (RdrName
r,SrcSpan
loc) <- LocalRdrEnv -> [(RdrName, SrcSpan)]
local_possibilities LocalRdrEnv
local_env ]
        [(String, SimilarName)]
-> [(String, SimilarName)] -> [(String, SimilarName)]
forall a. [a] -> [a] -> [a]
++ [ (DynFlags -> RdrName -> String
forall a. Outputable a => DynFlags -> a -> String
showPpr DynFlags
dflags RdrName
r, SimilarName
rp) | (RdrName
r, SimilarName
rp) <- GlobalRdrEnv -> [(RdrName, SimilarName)]
global_possibilities GlobalRdrEnv
global_env ]
    tried_occ :: OccName
tried_occ     = RdrName -> OccName
rdrNameOcc RdrName
tried_rdr_name
    tried_is_sym :: Bool
tried_is_sym  = OccName -> Bool
isSymOcc OccName
tried_occ
    tried_ns :: NameSpace
tried_ns      = OccName -> NameSpace
occNameSpace OccName
tried_occ
    tried_is_qual :: Bool
tried_is_qual = RdrName -> Bool
isQual RdrName
tried_rdr_name
    correct_name_space :: OccName -> Bool
correct_name_space OccName
occ =
      (DynFlags -> WhatLooking -> NameSpace -> NameSpace -> Bool
nameSpacesRelated DynFlags
dflags WhatLooking
what_look NameSpace
tried_ns (OccName -> NameSpace
occNameSpace OccName
occ))
      Bool -> Bool -> Bool
&& OccName -> Bool
isSymOcc OccName
occ Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
tried_is_sym
        
        
        
    local_ok :: Bool
local_ok = case WhereLooking
where_look of { WhereLooking
WL_Anywhere  -> Bool
True
                                  ; WhereLooking
WL_LocalOnly -> Bool
True
                                  ; WhereLooking
_            -> Bool
False }
    local_possibilities :: LocalRdrEnv -> [(RdrName, SrcSpan)]
    local_possibilities :: LocalRdrEnv -> [(RdrName, SrcSpan)]
local_possibilities LocalRdrEnv
env
      | Bool
tried_is_qual = []
      | Bool -> Bool
not Bool
local_ok  = []
      | Bool
otherwise     = [ (OccName -> RdrName
mkRdrUnqual OccName
occ, Name -> SrcSpan
nameSrcSpan Name
name)
                        | Name
name <- LocalRdrEnv -> [Name]
localRdrEnvElts LocalRdrEnv
env
                        , let occ :: OccName
occ = Name -> OccName
nameOccName Name
name
                        , OccName -> Bool
correct_name_space OccName
occ]
    global_possibilities :: GlobalRdrEnv -> [(RdrName, SimilarName)]
    global_possibilities :: GlobalRdrEnv -> [(RdrName, SimilarName)]
global_possibilities GlobalRdrEnv
global_env
      | Bool
tried_is_qual = [ (RdrName
rdr_qual, RdrName -> HowInScope -> SimilarName
SimilarRdrName RdrName
rdr_qual HowInScope
how)
                        | GlobalRdrElt
gre <- GlobalRdrEnv -> [GlobalRdrElt]
globalRdrEnvElts GlobalRdrEnv
global_env
                        , LookingFor -> GlobalRdrElt -> Bool
isGreOk LookingFor
looking_for GlobalRdrElt
gre
                        , let occ :: OccName
occ = GlobalRdrElt -> OccName
greOccName GlobalRdrElt
gre
                        , OccName -> Bool
correct_name_space OccName
occ
                        , (ModuleName
mod, HowInScope
how) <- GlobalRdrElt -> [(ModuleName, HowInScope)]
qualsInScope GlobalRdrElt
gre
                        , let rdr_qual :: RdrName
rdr_qual = ModuleName -> OccName -> RdrName
mkRdrQual ModuleName
mod OccName
occ ]
      | Bool
otherwise = [ (RdrName
rdr_unqual, SimilarName
sim)
                    | GlobalRdrElt
gre <- GlobalRdrEnv -> [GlobalRdrElt]
globalRdrEnvElts GlobalRdrEnv
global_env
                    , LookingFor -> GlobalRdrElt -> Bool
isGreOk LookingFor
looking_for GlobalRdrElt
gre
                    , let occ :: OccName
occ = GlobalRdrElt -> OccName
greOccName GlobalRdrElt
gre
                          rdr_unqual :: RdrName
rdr_unqual = OccName -> RdrName
mkRdrUnqual OccName
occ
                    , OccName -> Bool
correct_name_space OccName
occ
                    , SimilarName
sim <- case (GlobalRdrElt -> [HowInScope]
unquals_in_scope GlobalRdrElt
gre, GlobalRdrElt -> [SimilarName]
quals_only GlobalRdrElt
gre) of
                                (HowInScope
how:[HowInScope]
_, [SimilarName]
_)    -> [ RdrName -> HowInScope -> SimilarName
SimilarRdrName RdrName
rdr_unqual HowInScope
how ]
                                ([],    SimilarName
pr:[SimilarName]
_) -> [ SimilarName
pr ]  
                                ([],    [])   -> [] ]
              
              
              
              
              
              
              
              
              
              
    
    unquals_in_scope :: GlobalRdrElt -> [HowInScope]
    unquals_in_scope :: GlobalRdrElt -> [HowInScope]
unquals_in_scope (gre :: GlobalRdrElt
gre@GRE { gre_lcl :: GlobalRdrElt -> Bool
gre_lcl = Bool
lcl, gre_imp :: GlobalRdrElt -> Bag ImportSpec
gre_imp = Bag ImportSpec
is })
      | Bool
lcl       = [ SrcSpan -> HowInScope
LocallyBoundAt (GlobalRdrElt -> SrcSpan
greDefinitionSrcSpan GlobalRdrElt
gre) ]
      | Bool
otherwise = [ ImpDeclSpec -> HowInScope
ImportedBy ImpDeclSpec
ispec
                    | ImportSpec
i <- Bag ImportSpec -> [ImportSpec]
forall a. Bag a -> [a]
bagToList Bag ImportSpec
is, let ispec :: ImpDeclSpec
ispec = ImportSpec -> ImpDeclSpec
is_decl ImportSpec
i
                    , Bool -> Bool
not (ImpDeclSpec -> Bool
is_qual ImpDeclSpec
ispec) ]
    
    quals_only :: GlobalRdrElt -> [SimilarName]
    
    quals_only :: GlobalRdrElt -> [SimilarName]
quals_only (gre :: GlobalRdrElt
gre@GRE { gre_imp :: GlobalRdrElt -> Bag ImportSpec
gre_imp = Bag ImportSpec
is })
      = [ (RdrName -> HowInScope -> SimilarName
SimilarRdrName (ModuleName -> OccName -> RdrName
mkRdrQual (ImpDeclSpec -> ModuleName
is_as ImpDeclSpec
ispec) (GlobalRdrElt -> OccName
greOccName GlobalRdrElt
gre)) (ImpDeclSpec -> HowInScope
ImportedBy ImpDeclSpec
ispec))
        | ImportSpec
i <- Bag ImportSpec -> [ImportSpec]
forall a. Bag a -> [a]
bagToList Bag ImportSpec
is, let ispec :: ImpDeclSpec
ispec = ImportSpec -> ImpDeclSpec
is_decl ImportSpec
i, ImpDeclSpec -> Bool
is_qual ImpDeclSpec
ispec ]
importSuggestions :: LookingFor
                  -> GlobalRdrEnv
                  -> HomePackageTable -> Module
                  -> ImportAvails -> RdrName -> ([ImportError], [ImportSuggestion])
importSuggestions :: LookingFor
-> GlobalRdrEnv
-> HomePackageTable
-> Module
-> ImportAvails
-> RdrName
-> ([ImportError], [ImportSuggestion])
importSuggestions LookingFor
looking_for GlobalRdrEnv
global_env HomePackageTable
hpt Module
currMod ImportAvails
imports RdrName
rdr_name
  | WhereLooking
WL_LocalOnly <- LookingFor -> WhereLooking
lf_where LookingFor
looking_for       = ([], [])
  | WhereLooking
WL_LocalTop  <- LookingFor -> WhereLooking
lf_where LookingFor
looking_for       = ([], [])
  | Bool -> Bool
not (RdrName -> Bool
isQual RdrName
rdr_name Bool -> Bool -> Bool
|| RdrName -> Bool
isUnqual RdrName
rdr_name) = ([], [])
  | [(Module, ImportedModsVal)] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Module, ImportedModsVal)]
interesting_imports
  , Just ModuleName
name <- Maybe ModuleName
mod_name
  , ModuleName -> Bool
show_not_imported_line ModuleName
name
  = ([ModuleName -> ImportError
MissingModule ModuleName
name], [])
  | Bool
is_qualified
  , [(Module, ImportedModsVal)] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Module, ImportedModsVal)]
helpful_imports
  , (Module
mod : [Module]
mods) <- ((Module, ImportedModsVal) -> Module)
-> [(Module, ImportedModsVal)] -> [Module]
forall a b. (a -> b) -> [a] -> [b]
map (Module, ImportedModsVal) -> Module
forall a b. (a, b) -> a
fst [(Module, ImportedModsVal)]
interesting_imports
  = ([NonEmpty Module -> OccName -> ImportError
ModulesDoNotExport (Module
mod Module -> [Module] -> NonEmpty Module
forall a. a -> [a] -> NonEmpty a
:| [Module]
mods) OccName
occ_name], [])
  | (Module, ImportedModsVal)
mod : [(Module, ImportedModsVal)]
mods <- [(Module, ImportedModsVal)]
helpful_imports_non_hiding
  = ([], [NonEmpty (Module, ImportedModsVal) -> OccName -> ImportSuggestion
CouldImportFrom ((Module, ImportedModsVal)
mod (Module, ImportedModsVal)
-> [(Module, ImportedModsVal)]
-> NonEmpty (Module, ImportedModsVal)
forall a. a -> [a] -> NonEmpty a
:| [(Module, ImportedModsVal)]
mods) OccName
occ_name])
  | (Module, ImportedModsVal)
mod : [(Module, ImportedModsVal)]
mods <- [(Module, ImportedModsVal)]
helpful_imports_hiding
  = ([], [NonEmpty (Module, ImportedModsVal) -> OccName -> ImportSuggestion
CouldUnhideFrom ((Module, ImportedModsVal)
mod (Module, ImportedModsVal)
-> [(Module, ImportedModsVal)]
-> NonEmpty (Module, ImportedModsVal)
forall a. a -> [a] -> NonEmpty a
:| [(Module, ImportedModsVal)]
mods) OccName
occ_name])
  | Bool
otherwise
  = ([], [])
 where
  is_qualified :: Bool
is_qualified = RdrName -> Bool
isQual RdrName
rdr_name
  (Maybe ModuleName
mod_name, OccName
occ_name) = case RdrName
rdr_name of
    Unqual OccName
occ_name        -> (Maybe ModuleName
forall a. Maybe a
Nothing, OccName
occ_name)
    Qual ModuleName
mod_name OccName
occ_name -> (ModuleName -> Maybe ModuleName
forall a. a -> Maybe a
Just ModuleName
mod_name, OccName
occ_name)
    RdrName
_                      -> String -> (Maybe ModuleName, OccName)
forall a. HasCallStack => String -> a
error String
"importSuggestions: dead code"
  
  
  interesting_imports :: [(Module, ImportedModsVal)]
interesting_imports = [ (Module
mod, ImportedModsVal
imp)
    | (Module
mod, [ImportedBy]
mod_imports) <- ModuleEnv [ImportedBy] -> [(Module, [ImportedBy])]
forall a. ModuleEnv a -> [(Module, a)]
moduleEnvToList (ImportAvails -> ModuleEnv [ImportedBy]
imp_mods ImportAvails
imports)
    , Just ImportedModsVal
imp <- Maybe ImportedModsVal -> [Maybe ImportedModsVal]
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe ImportedModsVal -> [Maybe ImportedModsVal])
-> Maybe ImportedModsVal -> [Maybe ImportedModsVal]
forall a b. (a -> b) -> a -> b
$ [ImportedModsVal] -> Maybe ImportedModsVal
pick ([ImportedBy] -> [ImportedModsVal]
importedByUser [ImportedBy]
mod_imports)
    ]
  
  
  pick :: [ImportedModsVal] -> Maybe ImportedModsVal
  pick :: [ImportedModsVal] -> Maybe ImportedModsVal
pick = [ImportedModsVal] -> Maybe ImportedModsVal
forall a. [a] -> Maybe a
listToMaybe ([ImportedModsVal] -> Maybe ImportedModsVal)
-> ([ImportedModsVal] -> [ImportedModsVal])
-> [ImportedModsVal]
-> Maybe ImportedModsVal
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ImportedModsVal -> ImportedModsVal -> Ordering)
-> [ImportedModsVal] -> [ImportedModsVal]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy ImportedModsVal -> ImportedModsVal -> Ordering
cmp ([ImportedModsVal] -> [ImportedModsVal])
-> ([ImportedModsVal] -> [ImportedModsVal])
-> [ImportedModsVal]
-> [ImportedModsVal]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ImportedModsVal -> Bool) -> [ImportedModsVal] -> [ImportedModsVal]
forall a. (a -> Bool) -> [a] -> [a]
filter ImportedModsVal -> Bool
select
    where select :: ImportedModsVal -> Bool
select ImportedModsVal
imv = case Maybe ModuleName
mod_name of Just ModuleName
name -> ImportedModsVal -> ModuleName
imv_name ImportedModsVal
imv ModuleName -> ModuleName -> Bool
forall a. Eq a => a -> a -> Bool
== ModuleName
name
                                        Maybe ModuleName
Nothing   -> Bool -> Bool
not (ImportedModsVal -> Bool
imv_qualified ImportedModsVal
imv)
          cmp :: ImportedModsVal -> ImportedModsVal -> Ordering
cmp ImportedModsVal
a ImportedModsVal
b =
            (Bool -> Bool -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Bool -> Bool -> Ordering)
-> (ImportedModsVal -> Bool)
-> ImportedModsVal
-> ImportedModsVal
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` ImportedModsVal -> Bool
imv_is_hiding) ImportedModsVal
a ImportedModsVal
b
              Ordering -> Ordering -> Ordering
`thenCmp`
            (SrcSpan -> SrcSpan -> Ordering
SrcLoc.leftmost_smallest (SrcSpan -> SrcSpan -> Ordering)
-> (ImportedModsVal -> SrcSpan)
-> ImportedModsVal
-> ImportedModsVal
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` ImportedModsVal -> SrcSpan
imv_span) ImportedModsVal
a ImportedModsVal
b
  
  
  
  helpful_imports :: [(Module, ImportedModsVal)]
helpful_imports = ((Module, ImportedModsVal) -> Bool)
-> [(Module, ImportedModsVal)] -> [(Module, ImportedModsVal)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Module, ImportedModsVal) -> Bool
helpful [(Module, ImportedModsVal)]
interesting_imports
    where helpful :: (Module, ImportedModsVal) -> Bool
helpful (Module
_,ImportedModsVal
imv)
            = (GlobalRdrElt -> Bool) -> [GlobalRdrElt] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (LookingFor -> GlobalRdrElt -> Bool
isGreOk LookingFor
looking_for) ([GlobalRdrElt] -> Bool) -> [GlobalRdrElt] -> Bool
forall a b. (a -> b) -> a -> b
$
              GlobalRdrEnv -> OccName -> [GlobalRdrElt]
lookupGlobalRdrEnv (ImportedModsVal -> GlobalRdrEnv
imv_all_exports ImportedModsVal
imv) OccName
occ_name
  
  
  ([(Module, ImportedModsVal)]
helpful_imports_hiding, [(Module, ImportedModsVal)]
helpful_imports_non_hiding)
    = ((Module, ImportedModsVal) -> Bool)
-> [(Module, ImportedModsVal)]
-> ([(Module, ImportedModsVal)], [(Module, ImportedModsVal)])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (ImportedModsVal -> Bool
imv_is_hiding (ImportedModsVal -> Bool)
-> ((Module, ImportedModsVal) -> ImportedModsVal)
-> (Module, ImportedModsVal)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Module, ImportedModsVal) -> ImportedModsVal
forall a b. (a, b) -> b
snd) [(Module, ImportedModsVal)]
helpful_imports
  
  show_not_imported_line :: ModuleName -> Bool                    
  show_not_imported_line :: ModuleName -> Bool
show_not_imported_line ModuleName
modnam
      | ModuleName
modnam ModuleName -> [ModuleName] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [ModuleName]
glob_mods               = Bool
False    
      | Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName Module
currMod ModuleName -> ModuleName -> Bool
forall a. Eq a => a -> a -> Bool
== ModuleName
modnam          = Bool
False                  
      | ModuleName -> [Unique] -> Bool
forall {a}. Uniquable a => a -> [Unique] -> Bool
is_last_loaded_mod ModuleName
modnam [Unique]
hpt_uniques = Bool
False                  
      | Bool
otherwise                             = Bool
True
    where
      hpt_uniques :: [Unique]
hpt_uniques = ((Unique, HomeModInfo) -> Unique)
-> [(Unique, HomeModInfo)] -> [Unique]
forall a b. (a -> b) -> [a] -> [b]
map (Unique, HomeModInfo) -> Unique
forall a b. (a, b) -> a
fst (HomePackageTable -> [(Unique, HomeModInfo)]
forall key elt. UniqDFM key elt -> [(Unique, elt)]
udfmToList HomePackageTable
hpt)
      is_last_loaded_mod :: a -> [Unique] -> Bool
is_last_loaded_mod a
_ []         = Bool
False
      is_last_loaded_mod a
modnam [Unique]
uniqs = [Unique] -> Unique
forall a. HasCallStack => [a] -> a
last [Unique]
uniqs Unique -> Unique -> Bool
forall a. Eq a => a -> a -> Bool
== a -> Unique
forall a. Uniquable a => a -> Unique
getUnique a
modnam
      glob_mods :: [ModuleName]
glob_mods = [ModuleName] -> [ModuleName]
forall a. Eq a => [a] -> [a]
nub [ ModuleName
mod
                     | GlobalRdrElt
gre <- GlobalRdrEnv -> [GlobalRdrElt]
globalRdrEnvElts GlobalRdrEnv
global_env
                     , (ModuleName
mod, HowInScope
_) <- GlobalRdrElt -> [(ModuleName, HowInScope)]
qualsInScope GlobalRdrElt
gre
                     ]
extensionSuggestions :: RdrName -> [GhcHint]
extensionSuggestions :: RdrName -> [GhcHint]
extensionSuggestions RdrName
rdrName
  | RdrName
rdrName RdrName -> RdrName -> Bool
forall a. Eq a => a -> a -> Bool
== NameSpace -> FastString -> RdrName
mkUnqual NameSpace
varName (String -> FastString
fsLit String
"mdo") Bool -> Bool -> Bool
||
    RdrName
rdrName RdrName -> RdrName -> Bool
forall a. Eq a => a -> a -> Bool
== NameSpace -> FastString -> RdrName
mkUnqual NameSpace
varName (String -> FastString
fsLit String
"rec")
  = [LanguageExtensionHint -> GhcHint
SuggestExtension (LanguageExtensionHint -> GhcHint)
-> LanguageExtensionHint -> GhcHint
forall a b. (a -> b) -> a -> b
$ SDoc -> Extension -> LanguageExtensionHint
SuggestSingleExtension SDoc
empty Extension
LangExt.RecursiveDo]
  | Bool
otherwise
  = []
qualsInScope :: GlobalRdrElt -> [(ModuleName, HowInScope)]
qualsInScope :: GlobalRdrElt -> [(ModuleName, HowInScope)]
qualsInScope gre :: GlobalRdrElt
gre@GRE { gre_lcl :: GlobalRdrElt -> Bool
gre_lcl = Bool
lcl, gre_imp :: GlobalRdrElt -> Bag ImportSpec
gre_imp = Bag ImportSpec
is }
      | Bool
lcl = case GlobalRdrElt -> Maybe Module
greDefinitionModule GlobalRdrElt
gre of
                Maybe Module
Nothing -> []
                Just Module
m  -> [(Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName Module
m, SrcSpan -> HowInScope
LocallyBoundAt (GlobalRdrElt -> SrcSpan
greDefinitionSrcSpan GlobalRdrElt
gre))]
      | Bool
otherwise = [ (ImpDeclSpec -> ModuleName
is_as ImpDeclSpec
ispec, ImpDeclSpec -> HowInScope
ImportedBy ImpDeclSpec
ispec)
                    | ImportSpec
i <- Bag ImportSpec -> [ImportSpec]
forall a. Bag a -> [a]
bagToList Bag ImportSpec
is, let ispec :: ImpDeclSpec
ispec = ImportSpec -> ImpDeclSpec
is_decl ImportSpec
i ]
isGreOk :: LookingFor -> GlobalRdrElt -> Bool
isGreOk :: LookingFor -> GlobalRdrElt -> Bool
isGreOk (LF WhatLooking
what_look WhereLooking
where_look) GlobalRdrElt
gre = Bool
what_ok Bool -> Bool -> Bool
&& Bool
where_ok
  where
    
    
    
    
    what_ok :: Bool
what_ok  = case WhatLooking
what_look of
                 WhatLooking
WL_RecField -> GlobalRdrElt -> Bool
isRecFldGRE GlobalRdrElt
gre
                 WhatLooking
_           -> Bool -> Bool
not (GlobalRdrElt -> Bool
isNoFieldSelectorGRE GlobalRdrElt
gre)
    where_ok :: Bool
where_ok = case WhereLooking
where_look of
                 WhereLooking
WL_LocalTop  -> GlobalRdrElt -> Bool
isLocalGRE GlobalRdrElt
gre
                 WhereLooking
WL_LocalOnly -> Bool
False
                 WhereLooking
_            -> Bool
True
nameSpacesRelated :: DynFlags    
                  -> WhatLooking 
                  -> NameSpace   
                  -> NameSpace   
                  -> Bool
nameSpacesRelated :: DynFlags -> WhatLooking -> NameSpace -> NameSpace -> Bool
nameSpacesRelated DynFlags
dflags WhatLooking
what_looking NameSpace
ns NameSpace
ns'
  = NameSpace
ns' NameSpace -> [NameSpace] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` NameSpace
ns NameSpace -> [NameSpace] -> [NameSpace]
forall a. a -> [a] -> [a]
: [ NameSpace
other_ns
                    | (NameSpace
orig_ns, [(NameSpace, [WhatLooking])]
others) <- [(NameSpace, [(NameSpace, [WhatLooking])])]
other_namespaces
                    , NameSpace
ns NameSpace -> NameSpace -> Bool
forall a. Eq a => a -> a -> Bool
== NameSpace
orig_ns
                    , (NameSpace
other_ns, [WhatLooking]
wls) <- [(NameSpace, [WhatLooking])]
others
                    , WhatLooking
what_looking WhatLooking -> [WhatLooking] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` WhatLooking
WL_Anything WhatLooking -> [WhatLooking] -> [WhatLooking]
forall a. a -> [a] -> [a]
: [WhatLooking]
wls
                    ]
  where
    
    
    
    
    
    other_namespaces :: [(NameSpace, [(NameSpace, [WhatLooking])])]
other_namespaces =
      [ (NameSpace
varName  , [(NameSpace
dataName, [WhatLooking
WL_Constructor])])
      , (NameSpace
dataName , [(NameSpace
varName , [WhatLooking
WL_RecField])])
      , (NameSpace
tvName   , (NameSpace
tcClsName, [WhatLooking
WL_Constructor]) (NameSpace, [WhatLooking])
-> [(NameSpace, [WhatLooking])] -> [(NameSpace, [WhatLooking])]
forall a. a -> [a] -> [a]
: [(NameSpace, [WhatLooking])]
promoted_datacons)
      , (NameSpace
tcClsName, (NameSpace
tvName   , []) (NameSpace, [WhatLooking])
-> [(NameSpace, [WhatLooking])] -> [(NameSpace, [WhatLooking])]
forall a. a -> [a] -> [a]
: [(NameSpace, [WhatLooking])]
promoted_datacons)
      ]
    
    
    data_kinds :: Bool
data_kinds = Extension -> DynFlags -> Bool
xopt Extension
LangExt.DataKinds DynFlags
dflags
    promoted_datacons :: [(NameSpace, [WhatLooking])]
promoted_datacons = [(NameSpace
dataName, [WhatLooking
WL_Constructor]) | Bool
data_kinds]