{-# LANGUAGE PatternSynonyms #-}
module GHC.Rename.Unbound
( mkUnboundName
, mkUnboundNameRdr
, mkUnboundGRE
, mkUnboundGRERdr
, isUnboundName
, reportUnboundName
, reportUnboundName'
, unknownNameSuggestions
, similarNameSuggestions
, fieldSelectorSuggestions
, WhatLooking(..)
, WhereLooking(..)
, LookingFor(..)
, unboundName
, unboundNameX
, unboundTermNameInTypes
, IsTermInTypes(..)
, notInScopeErr
, nameSpacesRelated
, termNameInType
)
where
import GHC.Prelude
import GHC.Driver.DynFlags
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.Utils.Panic (panic)
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 )
import qualified Data.Semigroup as S
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
}
data IsTermInTypes = UnknownTermInTypes RdrName | TermInTypes RdrName | NoTermInTypes
mkUnboundNameRdr :: RdrName -> Name
mkUnboundNameRdr :: RdrName -> Name
mkUnboundNameRdr RdrName
rdr = OccName -> Name
mkUnboundName (RdrName -> OccName
rdrNameOcc RdrName
rdr)
mkUnboundGRE :: OccName -> GlobalRdrElt
mkUnboundGRE :: OccName -> GlobalRdrElt
mkUnboundGRE OccName
occ = GREInfo -> Parent -> Name -> GlobalRdrElt
mkLocalGRE GREInfo
UnboundGRE Parent
NoParent (Name -> GlobalRdrElt) -> Name -> GlobalRdrElt
forall a b. (a -> b) -> a -> b
$ OccName -> Name
mkUnboundName OccName
occ
mkUnboundGRERdr :: RdrName -> GlobalRdrElt
mkUnboundGRERdr :: RdrName -> GlobalRdrElt
mkUnboundGRERdr RdrName
rdr = GREInfo -> Parent -> Name -> GlobalRdrElt
mkLocalGRE GREInfo
UnboundGRE Parent
NoParent (Name -> GlobalRdrElt) -> Name -> GlobalRdrElt
forall a b. (a -> b) -> a -> b
$ RdrName -> Name
mkUnboundNameRdr 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
= IsTermInTypes -> LookingFor -> RdrName -> [GhcHint] -> RnM Name
unboundNameOrTermInType IsTermInTypes
NoTermInTypes LookingFor
looking_for RdrName
rdr_name [GhcHint]
hints
unboundTermNameInTypes :: LookingFor -> RdrName -> RdrName -> RnM Name
unboundTermNameInTypes :: LookingFor -> RdrName -> RdrName -> RnM Name
unboundTermNameInTypes LookingFor
looking_for RdrName
rdr_name RdrName
demoted_rdr_name
= IsTermInTypes -> LookingFor -> RdrName -> [GhcHint] -> RnM Name
unboundNameOrTermInType (RdrName -> IsTermInTypes
UnknownTermInTypes RdrName
demoted_rdr_name) LookingFor
looking_for RdrName
rdr_name []
termNameInType :: LookingFor -> RdrName -> RdrName -> [GhcHint] -> RnM Name
termNameInType :: LookingFor -> RdrName -> RdrName -> [GhcHint] -> RnM Name
termNameInType LookingFor
looking_for RdrName
rdr_name RdrName
demoted_rdr_name [GhcHint]
external_hints
= IsTermInTypes -> LookingFor -> RdrName -> [GhcHint] -> RnM Name
unboundNameOrTermInType (RdrName -> IsTermInTypes
TermInTypes RdrName
demoted_rdr_name) LookingFor
looking_for RdrName
rdr_name [GhcHint]
external_hints
unboundNameOrTermInType :: IsTermInTypes -> LookingFor -> RdrName -> [GhcHint] -> RnM Name
unboundNameOrTermInType :: IsTermInTypes -> LookingFor -> RdrName -> [GhcHint] -> RnM Name
unboundNameOrTermInType IsTermInTypes
if_term_in_type LookingFor
looking_for RdrName
rdr_name [GhcHint]
hints
= do { dflags <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; let show_helpful_errors = GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_HelpfulErrors DynFlags
dflags
; if not show_helpful_errors
then addErr $ make_error [] hints
else do { local_env <- getLocalRdrEnv
; global_env <- getGlobalRdrEnv
; impInfo <- getImports
; currmod <- getModule
; hpt <- getHpt
; let (imp_errs, suggs) =
unknownNameSuggestions_ looking_for
dflags hpt currmod global_env local_env impInfo
rdr_name
; addErr $
make_error imp_errs (hints ++ suggs) }
; return (mkUnboundNameRdr rdr_name) }
where
name_to_search :: RdrName
name_to_search = case IsTermInTypes
if_term_in_type of
IsTermInTypes
NoTermInTypes -> RdrName
rdr_name
UnknownTermInTypes RdrName
demoted_name -> RdrName
demoted_name
TermInTypes RdrName
demoted_name -> RdrName
demoted_name
err :: NotInScopeError
err = WhereLooking -> RdrName -> NotInScopeError
notInScopeErr (LookingFor -> WhereLooking
lf_where LookingFor
looking_for) RdrName
name_to_search
make_error :: [ImportError] -> [GhcHint] -> TcRnMessage
make_error [ImportError]
imp_errs [GhcHint]
hints = case IsTermInTypes
if_term_in_type of
TermInTypes RdrName
demoted_name -> RdrName -> [GhcHint] -> TcRnMessage
TcRnTermNameInType RdrName
demoted_name [GhcHint]
hints
IsTermInTypes
_ -> NotInScopeError
-> RdrName -> [ImportError] -> [GhcHint] -> TcRnMessage
TcRnNotInScope NotInScopeError
err RdrName
name_to_search [ImportError]
imp_errs [GhcHint]
hints
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 :: LocalRdrEnv -> WhatLooking -> RdrName -> RnM ([ImportError], [GhcHint])
unknownNameSuggestions :: LocalRdrEnv
-> WhatLooking -> RdrName -> RnM ([ImportError], [GhcHint])
unknownNameSuggestions LocalRdrEnv
lcl_env WhatLooking
what_look RdrName
tried_rdr_name =
do { dflags <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; hpt <- getHpt
; rdr_env <- getGlobalRdrEnv
; imp_info <- getImports
; curr_mod <- getModule
; return $
unknownNameSuggestions_
(LF what_look WL_Anywhere)
dflags hpt curr_mod rdr_env lcl_env imp_info tried_rdr_name }
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 (OccName -> ImportSuggestion -> GhcHint
ImportSuggestion (OccName -> ImportSuggestion -> GhcHint)
-> OccName -> ImportSuggestion -> GhcHint
forall a b. (a -> b) -> a -> b
$ RdrName -> OccName
rdrNameOcc RdrName
tried_rdr_name) [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
$ GlobalRdrEnv -> LookupGRE GREInfo -> [GlobalRdrElt]
forall info.
GlobalRdrEnvX info -> LookupGRE info -> [GlobalRdrEltX info]
lookupGRE GlobalRdrEnv
global_env (RdrName -> WhichGREs GREInfo -> LookupGRE GREInfo
forall info. RdrName -> WhichGREs info -> LookupGRE info
LookupRdrName RdrName
tried_rdr_name WhichGREs GREInfo
AllRelevantGREs)
parents :: [Name]
parents = [ Name
parent | ParentIs Name
parent <- (GlobalRdrElt -> Parent) -> [GlobalRdrElt] -> [Parent]
forall a b. (a -> b) -> [a] -> [b]
map GlobalRdrElt -> Parent
forall info. GlobalRdrEltX info -> Parent
greParent [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 -> Maybe HowInScope -> SimilarName
SimilarRdrName RdrName
r (HowInScope -> Maybe HowInScope
forall a. a -> Maybe a
Just (HowInScope -> Maybe HowInScope) -> HowInScope -> Maybe HowInScope
forall a b. (a -> b) -> a -> b
$ 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 -> Maybe HowInScope -> SimilarName
SimilarRdrName RdrName
rdr_qual (HowInScope -> Maybe HowInScope
forall a. a -> Maybe a
Just HowInScope
how))
| GlobalRdrElt
gre <- GlobalRdrEnv -> [GlobalRdrElt]
forall info. GlobalRdrEnvX info -> [GlobalRdrEltX info]
globalRdrEnvElts GlobalRdrEnv
global_env
, LookingFor -> GlobalRdrElt -> Bool
isGreOk LookingFor
looking_for GlobalRdrElt
gre
, let occ :: OccName
occ = GlobalRdrElt -> OccName
forall info. GlobalRdrEltX info -> 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]
forall info. GlobalRdrEnvX info -> [GlobalRdrEltX info]
globalRdrEnvElts GlobalRdrEnv
global_env
, LookingFor -> GlobalRdrElt -> Bool
isGreOk LookingFor
looking_for GlobalRdrElt
gre
, let occ :: OccName
occ = GlobalRdrElt -> OccName
forall info. GlobalRdrEltX info -> 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 -> Maybe HowInScope -> SimilarName
SimilarRdrName RdrName
rdr_unqual (HowInScope -> Maybe HowInScope
forall a. a -> Maybe a
Just 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 :: forall info. GlobalRdrEltX info -> Bool
gre_lcl = Bool
lcl, gre_imp :: forall info. GlobalRdrEltX info -> Bag ImportSpec
gre_imp = Bag ImportSpec
is })
| Bool
lcl = [ SrcSpan -> HowInScope
LocallyBoundAt (GlobalRdrElt -> SrcSpan
forall info. GlobalRdrEltX info -> 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 :: forall info. GlobalRdrEltX info -> Bag ImportSpec
gre_imp = Bag ImportSpec
is })
= [ (RdrName -> Maybe HowInScope -> SimilarName
SimilarRdrName (ModuleName -> OccName -> RdrName
mkRdrQual (ImpDeclSpec -> ModuleName
is_as ImpDeclSpec
ispec) (GlobalRdrElt -> OccName
forall info. GlobalRdrEltX info -> OccName
greOccName GlobalRdrElt
gre)) (HowInScope -> Maybe HowInScope
forall a. a -> Maybe a
Just (HowInScope -> Maybe HowInScope) -> HowInScope -> Maybe HowInScope
forall a b. (a -> b) -> a -> b
$ 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) -> ImportSuggestion
CouldImportFrom ((Module, ImportedModsVal)
mod (Module, ImportedModsVal)
-> [(Module, ImportedModsVal)]
-> NonEmpty (Module, ImportedModsVal)
forall a. a -> [a] -> NonEmpty a
:| [(Module, ImportedModsVal)]
mods)])
| (Module, ImportedModsVal)
mod : [(Module, ImportedModsVal)]
mods <- [(Module, ImportedModsVal)]
helpful_imports_hiding
= ([], [NonEmpty (Module, ImportedModsVal) -> ImportSuggestion
CouldUnhideFrom ((Module, ImportedModsVal)
mod (Module, ImportedModsVal)
-> [(Module, ImportedModsVal)]
-> NonEmpty (Module, ImportedModsVal)
forall a. a -> [a] -> NonEmpty a
:| [(Module, ImportedModsVal)]
mods)])
| 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
panic 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 = (Bool -> Bool -> Ordering)
-> (ImportedModsVal -> Bool)
-> ImportedModsVal
-> ImportedModsVal
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
on Bool -> Bool -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ImportedModsVal -> Bool
imv_is_hiding (ImportedModsVal -> ImportedModsVal -> Ordering)
-> (ImportedModsVal -> ImportedModsVal -> Ordering)
-> ImportedModsVal
-> ImportedModsVal
-> Ordering
forall a. Semigroup a => a -> a -> a
S.<> (SrcSpan -> SrcSpan -> Ordering)
-> (ImportedModsVal -> SrcSpan)
-> ImportedModsVal
-> ImportedModsVal
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
on SrcSpan -> SrcSpan -> Ordering
SrcLoc.leftmost_smallest ImportedModsVal -> SrcSpan
imv_span
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 -> LookupGRE GREInfo -> [GlobalRdrElt]
forall info.
GlobalRdrEnvX info -> LookupGRE info -> [GlobalRdrEltX info]
lookupGRE (ImportedModsVal -> GlobalRdrEnv
imv_all_exports ImportedModsVal
imv)
(OccName -> WhichGREs GREInfo -> LookupGRE GREInfo
forall info. OccName -> WhichGREs info -> LookupGRE info
LookupOccName OccName
occ_name (WhichGREs GREInfo -> LookupGRE GREInfo)
-> WhichGREs GREInfo -> LookupGRE GREInfo
forall a b. (a -> b) -> a -> b
$ FieldsOrSelectors -> WhichGREs GREInfo
RelevantGREsFOS FieldsOrSelectors
WantNormal)
([(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 {k} (key :: k) elt. UniqDFM key elt -> [(Unique, elt)]
udfmToList HomePackageTable
hpt)
is_last_loaded_mod :: a -> [Unique] -> Bool
is_last_loaded_mod a
modnam [Unique]
uniqs = [Unique] -> Maybe Unique
forall a. [a] -> Maybe a
lastMaybe [Unique]
uniqs Maybe Unique -> Maybe Unique -> Bool
forall a. Eq a => a -> a -> Bool
== Unique -> Maybe Unique
forall a. a -> Maybe a
Just (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]
forall info. GlobalRdrEnvX info -> [GlobalRdrEltX info]
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
forall doc. IsOutput doc => doc
empty Extension
LangExt.RecursiveDo]
| Bool
otherwise
= []
qualsInScope :: GlobalRdrElt -> [(ModuleName, HowInScope)]
qualsInScope :: GlobalRdrElt -> [(ModuleName, HowInScope)]
qualsInScope gre :: GlobalRdrElt
gre@GRE { gre_lcl :: forall info. GlobalRdrEltX info -> Bool
gre_lcl = Bool
lcl, gre_imp :: forall info. GlobalRdrEltX info -> Bag ImportSpec
gre_imp = Bag ImportSpec
is }
| Bool
lcl = case GlobalRdrElt -> Maybe Module
forall info. GlobalRdrEltX info -> 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
forall info. GlobalRdrEltX info -> 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
forall info. GlobalRdrEltX info -> 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
forall info. GlobalRdrEltX info -> 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
== NameSpace
ns'
= Bool
True
| Bool
otherwise
= [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
or [ NameSpace -> Bool
other_ns NameSpace
ns'
| (NameSpace -> Bool
orig_ns, [(NameSpace -> Bool, [WhatLooking])]
others) <- [(NameSpace -> Bool, [(NameSpace -> Bool, [WhatLooking])])]
other_namespaces
, NameSpace -> Bool
orig_ns NameSpace
ns
, (NameSpace -> Bool
other_ns, [WhatLooking]
wls) <- [(NameSpace -> Bool, [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 -> Bool, [(NameSpace -> Bool, [WhatLooking])])]
other_namespaces =
[ (NameSpace -> Bool
isVarNameSpace , [(NameSpace -> Bool
isFieldNameSpace , [WhatLooking
WL_RecField])
,(NameSpace -> Bool
isDataConNameSpace, [WhatLooking
WL_Constructor])])
, (NameSpace -> Bool
isDataConNameSpace , [(NameSpace -> Bool
isVarNameSpace , [WhatLooking
WL_RecField])])
, (NameSpace -> Bool
isTvNameSpace , (NameSpace -> Bool
isTcClsNameSpace , [WhatLooking
WL_Constructor])
(NameSpace -> Bool, [WhatLooking])
-> [(NameSpace -> Bool, [WhatLooking])]
-> [(NameSpace -> Bool, [WhatLooking])]
forall a. a -> [a] -> [a]
: [(NameSpace -> Bool, [WhatLooking])]
promoted_datacons)
, (NameSpace -> Bool
isTcClsNameSpace , (NameSpace -> Bool
isTvNameSpace , [])
(NameSpace -> Bool, [WhatLooking])
-> [(NameSpace -> Bool, [WhatLooking])]
-> [(NameSpace -> Bool, [WhatLooking])]
forall a. a -> [a] -> [a]
: [(NameSpace -> Bool, [WhatLooking])]
promoted_datacons)
]
data_kinds :: Bool
data_kinds = Extension -> DynFlags -> Bool
xopt Extension
LangExt.DataKinds DynFlags
dflags
promoted_datacons :: [(NameSpace -> Bool, [WhatLooking])]
promoted_datacons = [(NameSpace -> Bool
isDataConNameSpace, [WhatLooking
WL_Constructor]) | Bool
data_kinds]