module GHC.Rename.Unbound
( mkUnboundName
, mkUnboundNameRdr
, isUnboundName
, reportUnboundName
, unknownNameSuggestions
, WhereLooking(..)
, unboundName
, unboundNameX
, notInScopeErr
, exactNameErr
)
where
import GHC.Prelude
import GHC.Types.Name.Reader
import GHC.Driver.Types
import GHC.Tc.Utils.Monad
import GHC.Types.Name
import GHC.Unit.Module
import GHC.Types.SrcLoc as SrcLoc
import GHC.Utils.Outputable as Outputable
import GHC.Builtin.Names ( mkUnboundName, isUnboundName, getUnique)
import GHC.Utils.Misc
import GHC.Data.Maybe
import GHC.Driver.Session
import GHC.Data.FastString
import Data.List
import Data.Function ( on )
import GHC.Types.Unique.DFM (udfmToList)
data WhereLooking = WL_Any
| WL_Global
| WL_LocalTop
| WL_LocalOnly
mkUnboundNameRdr :: RdrName -> Name
mkUnboundNameRdr :: RdrName -> Name
mkUnboundNameRdr RdrName
rdr = OccName -> Name
mkUnboundName (RdrName -> OccName
rdrNameOcc RdrName
rdr)
reportUnboundName :: RdrName -> RnM Name
reportUnboundName :: RdrName -> RnM Name
reportUnboundName RdrName
rdr = WhereLooking -> RdrName -> RnM Name
unboundName WhereLooking
WL_Any RdrName
rdr
unboundName :: WhereLooking -> RdrName -> RnM Name
unboundName :: WhereLooking -> RdrName -> RnM Name
unboundName WhereLooking
wl RdrName
rdr = WhereLooking -> RdrName -> SDoc -> RnM Name
unboundNameX WhereLooking
wl RdrName
rdr SDoc
Outputable.empty
unboundNameX :: WhereLooking -> RdrName -> SDoc -> RnM Name
unboundNameX :: WhereLooking -> RdrName -> SDoc -> RnM Name
unboundNameX WhereLooking
where_look RdrName
rdr_name SDoc
extra
= 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 :: SDoc
err = RdrName -> SDoc
notInScopeErr RdrName
rdr_name SDoc -> SDoc -> SDoc
$$ SDoc
extra
; if Bool -> Bool
not Bool
show_helpful_errors
then SDoc -> TcRn ()
addErr SDoc
err
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 suggestions :: SDoc
suggestions = WhereLooking
-> DynFlags
-> HomePackageTable
-> Module
-> GlobalRdrEnv
-> LocalRdrEnv
-> ImportAvails
-> RdrName
-> SDoc
unknownNameSuggestions_ WhereLooking
where_look
DynFlags
dflags HomePackageTable
hpt Module
currmod GlobalRdrEnv
global_env LocalRdrEnv
local_env ImportAvails
impInfo
RdrName
rdr_name
; SDoc -> TcRn ()
addErr (SDoc
err SDoc -> SDoc -> SDoc
$$ SDoc
suggestions) }
; Name -> RnM Name
forall (m :: * -> *) a. Monad m => a -> m a
return (RdrName -> Name
mkUnboundNameRdr RdrName
rdr_name) }
notInScopeErr :: RdrName -> SDoc
notInScopeErr :: RdrName -> SDoc
notInScopeErr RdrName
rdr_name
= case RdrName -> Maybe Name
isExact_maybe RdrName
rdr_name of
Just Name
name -> Name -> SDoc
exactNameErr Name
name
Maybe Name
Nothing -> SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text String
"Not in scope:")
Int
2 (SDoc
what SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (RdrName -> SDoc
forall a. Outputable a => a -> SDoc
ppr RdrName
rdr_name))
where
what :: SDoc
what = NameSpace -> SDoc
pprNonVarNameSpace (OccName -> NameSpace
occNameSpace (RdrName -> OccName
rdrNameOcc RdrName
rdr_name))
type HowInScope = Either SrcSpan ImpDeclSpec
unknownNameSuggestions :: DynFlags
-> HomePackageTable -> Module
-> GlobalRdrEnv -> LocalRdrEnv -> ImportAvails
-> RdrName -> SDoc
unknownNameSuggestions :: DynFlags
-> HomePackageTable
-> Module
-> GlobalRdrEnv
-> LocalRdrEnv
-> ImportAvails
-> RdrName
-> SDoc
unknownNameSuggestions = WhereLooking
-> DynFlags
-> HomePackageTable
-> Module
-> GlobalRdrEnv
-> LocalRdrEnv
-> ImportAvails
-> RdrName
-> SDoc
unknownNameSuggestions_ WhereLooking
WL_Any
unknownNameSuggestions_ :: WhereLooking -> DynFlags
-> HomePackageTable -> Module
-> GlobalRdrEnv -> LocalRdrEnv -> ImportAvails
-> RdrName -> SDoc
unknownNameSuggestions_ :: WhereLooking
-> DynFlags
-> HomePackageTable
-> Module
-> GlobalRdrEnv
-> LocalRdrEnv
-> ImportAvails
-> RdrName
-> SDoc
unknownNameSuggestions_ WhereLooking
where_look DynFlags
dflags HomePackageTable
hpt Module
curr_mod GlobalRdrEnv
global_env LocalRdrEnv
local_env
ImportAvails
imports RdrName
tried_rdr_name =
WhereLooking
-> DynFlags -> GlobalRdrEnv -> LocalRdrEnv -> RdrName -> SDoc
similarNameSuggestions WhereLooking
where_look DynFlags
dflags GlobalRdrEnv
global_env LocalRdrEnv
local_env RdrName
tried_rdr_name SDoc -> SDoc -> SDoc
$$
WhereLooking
-> GlobalRdrEnv
-> HomePackageTable
-> Module
-> ImportAvails
-> RdrName
-> SDoc
importSuggestions WhereLooking
where_look GlobalRdrEnv
global_env HomePackageTable
hpt
Module
curr_mod ImportAvails
imports RdrName
tried_rdr_name SDoc -> SDoc -> SDoc
$$
RdrName -> SDoc
extensionSuggestions RdrName
tried_rdr_name
similarNameSuggestions :: WhereLooking -> DynFlags
-> GlobalRdrEnv -> LocalRdrEnv
-> RdrName -> SDoc
similarNameSuggestions :: WhereLooking
-> DynFlags -> GlobalRdrEnv -> LocalRdrEnv -> RdrName -> SDoc
similarNameSuggestions WhereLooking
where_look DynFlags
dflags GlobalRdrEnv
global_env
LocalRdrEnv
local_env RdrName
tried_rdr_name
= case [(RdrName, HowInScope)]
suggest of
[] -> SDoc
Outputable.empty
[(RdrName, HowInScope)
p] -> SDoc
perhaps SDoc -> SDoc -> SDoc
<+> (RdrName, HowInScope) -> SDoc
pp_item (RdrName, HowInScope)
p
[(RdrName, HowInScope)]
ps -> [SDoc] -> SDoc
sep [ SDoc
perhaps SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"one of these:"
, Int -> SDoc -> SDoc
nest Int
2 (((RdrName, HowInScope) -> SDoc) -> [(RdrName, HowInScope)] -> SDoc
forall a. (a -> SDoc) -> [a] -> SDoc
pprWithCommas (RdrName, HowInScope) -> SDoc
pp_item [(RdrName, HowInScope)]
ps) ]
where
all_possibilities :: [(String, (RdrName, HowInScope))]
all_possibilities :: [(String, (RdrName, HowInScope))]
all_possibilities
= [ (DynFlags -> RdrName -> String
forall a. Outputable a => DynFlags -> a -> String
showPpr DynFlags
dflags RdrName
r, (RdrName
r, SrcSpan -> HowInScope
forall a b. a -> Either a b
Left SrcSpan
loc))
| (RdrName
r,SrcSpan
loc) <- LocalRdrEnv -> [(RdrName, SrcSpan)]
local_possibilities LocalRdrEnv
local_env ]
[(String, (RdrName, HowInScope))]
-> [(String, (RdrName, HowInScope))]
-> [(String, (RdrName, HowInScope))]
forall a. [a] -> [a] -> [a]
++ [ (DynFlags -> RdrName -> String
forall a. Outputable a => DynFlags -> a -> String
showPpr DynFlags
dflags RdrName
r, (RdrName, HowInScope)
rp) | (RdrName
r, (RdrName, HowInScope)
rp) <- GlobalRdrEnv -> [(RdrName, (RdrName, HowInScope))]
global_possibilities GlobalRdrEnv
global_env ]
suggest :: [(RdrName, HowInScope)]
suggest = String
-> [(String, (RdrName, HowInScope))] -> [(RdrName, HowInScope)]
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, (RdrName, HowInScope))]
all_possibilities
perhaps :: SDoc
perhaps = String -> SDoc
text String
"Perhaps you meant"
pp_item :: (RdrName, HowInScope) -> SDoc
pp_item :: (RdrName, HowInScope) -> SDoc
pp_item (RdrName
rdr, Left SrcSpan
loc) = RdrName -> SDoc
pp_ns RdrName
rdr SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (RdrName -> SDoc
forall a. Outputable a => a -> SDoc
ppr RdrName
rdr) SDoc -> SDoc -> SDoc
<+> SDoc
loc'
where loc' :: SDoc
loc' = case SrcSpan
loc of
UnhelpfulSpan UnhelpfulSpanReason
l -> SDoc -> SDoc
parens (UnhelpfulSpanReason -> SDoc
forall a. Outputable a => a -> SDoc
ppr UnhelpfulSpanReason
l)
RealSrcSpan RealSrcSpan
l Maybe BufSpan
_ -> SDoc -> SDoc
parens (String -> SDoc
text String
"line" SDoc -> SDoc -> SDoc
<+> Int -> SDoc
int (RealSrcSpan -> Int
srcSpanStartLine RealSrcSpan
l))
pp_item (RdrName
rdr, Right ImpDeclSpec
is) = RdrName -> SDoc
pp_ns RdrName
rdr SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (RdrName -> SDoc
forall a. Outputable a => a -> SDoc
ppr RdrName
rdr) SDoc -> SDoc -> SDoc
<+>
SDoc -> SDoc
parens (String -> SDoc
text String
"imported from" SDoc -> SDoc -> SDoc
<+> ModuleName -> SDoc
forall a. Outputable a => a -> SDoc
ppr (ImpDeclSpec -> ModuleName
is_mod ImpDeclSpec
is))
pp_ns :: RdrName -> SDoc
pp_ns :: RdrName -> SDoc
pp_ns RdrName
rdr | NameSpace
ns NameSpace -> NameSpace -> Bool
forall a. Eq a => a -> a -> Bool
/= NameSpace
tried_ns = NameSpace -> SDoc
pprNameSpace NameSpace
ns
| Bool
otherwise = SDoc
Outputable.empty
where ns :: NameSpace
ns = RdrName -> NameSpace
rdrNameSpace RdrName
rdr
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 = NameSpace -> NameSpace -> Bool
nameSpacesRelated (OccName -> NameSpace
occNameSpace OccName
occ) NameSpace
tried_ns
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_Any -> 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, (RdrName, HowInScope))]
global_possibilities :: GlobalRdrEnv -> [(RdrName, (RdrName, HowInScope))]
global_possibilities GlobalRdrEnv
global_env
| Bool
tried_is_qual = [ (RdrName
rdr_qual, (RdrName
rdr_qual, HowInScope
how))
| GlobalRdrElt
gre <- GlobalRdrEnv -> [GlobalRdrElt]
globalRdrEnvElts GlobalRdrEnv
global_env
, WhereLooking -> GlobalRdrElt -> Bool
isGreOk WhereLooking
where_look GlobalRdrElt
gre
, let name :: Name
name = GlobalRdrElt -> Name
gre_name GlobalRdrElt
gre
occ :: OccName
occ = Name -> OccName
nameOccName Name
name
, 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, (RdrName, HowInScope)
pair)
| GlobalRdrElt
gre <- GlobalRdrEnv -> [GlobalRdrElt]
globalRdrEnvElts GlobalRdrEnv
global_env
, WhereLooking -> GlobalRdrElt -> Bool
isGreOk WhereLooking
where_look GlobalRdrElt
gre
, let name :: Name
name = GlobalRdrElt -> Name
gre_name GlobalRdrElt
gre
occ :: OccName
occ = Name -> OccName
nameOccName Name
name
rdr_unqual :: RdrName
rdr_unqual = OccName -> RdrName
mkRdrUnqual OccName
occ
, OccName -> Bool
correct_name_space OccName
occ
, (RdrName, HowInScope)
pair <- case (GlobalRdrElt -> [HowInScope]
unquals_in_scope GlobalRdrElt
gre, GlobalRdrElt -> [(RdrName, HowInScope)]
quals_only GlobalRdrElt
gre) of
(HowInScope
how:[HowInScope]
_, [(RdrName, HowInScope)]
_) -> [ (RdrName
rdr_unqual, HowInScope
how) ]
([], (RdrName, HowInScope)
pr:[(RdrName, HowInScope)]
_) -> [ (RdrName, HowInScope)
pr ]
([], []) -> [] ]
unquals_in_scope :: GlobalRdrElt -> [HowInScope]
unquals_in_scope :: GlobalRdrElt -> [HowInScope]
unquals_in_scope (GRE { gre_name :: GlobalRdrElt -> Name
gre_name = Name
n, gre_lcl :: GlobalRdrElt -> Bool
gre_lcl = Bool
lcl, gre_imp :: GlobalRdrElt -> [ImportSpec]
gre_imp = [ImportSpec]
is })
| Bool
lcl = [ SrcSpan -> HowInScope
forall a b. a -> Either a b
Left (Name -> SrcSpan
nameSrcSpan Name
n) ]
| Bool
otherwise = [ ImpDeclSpec -> HowInScope
forall a b. b -> Either a b
Right ImpDeclSpec
ispec
| ImportSpec
i <- [ImportSpec]
is, let ispec :: ImpDeclSpec
ispec = ImportSpec -> ImpDeclSpec
is_decl ImportSpec
i
, Bool -> Bool
not (ImpDeclSpec -> Bool
is_qual ImpDeclSpec
ispec) ]
quals_only :: GlobalRdrElt -> [(RdrName, HowInScope)]
quals_only :: GlobalRdrElt -> [(RdrName, HowInScope)]
quals_only (GRE { gre_name :: GlobalRdrElt -> Name
gre_name = Name
n, gre_imp :: GlobalRdrElt -> [ImportSpec]
gre_imp = [ImportSpec]
is })
= [ (ModuleName -> OccName -> RdrName
mkRdrQual (ImpDeclSpec -> ModuleName
is_as ImpDeclSpec
ispec) (Name -> OccName
nameOccName Name
n), ImpDeclSpec -> HowInScope
forall a b. b -> Either a b
Right ImpDeclSpec
ispec)
| ImportSpec
i <- [ImportSpec]
is, let ispec :: ImpDeclSpec
ispec = ImportSpec -> ImpDeclSpec
is_decl ImportSpec
i, ImpDeclSpec -> Bool
is_qual ImpDeclSpec
ispec ]
importSuggestions :: WhereLooking
-> GlobalRdrEnv
-> HomePackageTable -> Module
-> ImportAvails -> RdrName -> SDoc
importSuggestions :: WhereLooking
-> GlobalRdrEnv
-> HomePackageTable
-> Module
-> ImportAvails
-> RdrName
-> SDoc
importSuggestions WhereLooking
where_look GlobalRdrEnv
global_env HomePackageTable
hpt Module
currMod ImportAvails
imports RdrName
rdr_name
| WhereLooking
WL_LocalOnly <- WhereLooking
where_look = SDoc
Outputable.empty
| Bool -> Bool
not (RdrName -> Bool
isQual RdrName
rdr_name Bool -> Bool -> Bool
|| RdrName -> Bool
isUnqual RdrName
rdr_name) = SDoc
Outputable.empty
| [(Module, ImportedModsVal)] -> 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
= [SDoc] -> SDoc
hsep
[ String -> SDoc
text String
"No module named"
, SDoc -> SDoc
quotes (ModuleName -> SDoc
forall a. Outputable a => a -> SDoc
ppr ModuleName
name)
, String -> SDoc
text String
"is imported."
]
| Bool
is_qualified
, [(Module, ImportedModsVal)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Module, ImportedModsVal)]
helpful_imports
, [(Module
mod,ImportedModsVal
_)] <- [(Module, ImportedModsVal)]
interesting_imports
= [SDoc] -> SDoc
hsep
[ String -> SDoc
text String
"Module"
, SDoc -> SDoc
quotes (Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr Module
mod)
, String -> SDoc
text String
"does not export"
, SDoc -> SDoc
quotes (OccName -> SDoc
forall a. Outputable a => a -> SDoc
ppr OccName
occ_name) SDoc -> SDoc -> SDoc
<> SDoc
dot
]
| Bool
is_qualified
, [(Module, ImportedModsVal)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Module, ImportedModsVal)]
helpful_imports
, Bool -> Bool
not ([(Module, ImportedModsVal)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Module, ImportedModsVal)]
interesting_imports)
, [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
= [SDoc] -> SDoc
hsep
[ String -> SDoc
text String
"Neither"
, [SDoc] -> SDoc
quotedListWithNor ((Module -> SDoc) -> [Module] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Module]
mods)
, String -> SDoc
text String
"exports"
, SDoc -> SDoc
quotes (OccName -> SDoc
forall a. Outputable a => a -> SDoc
ppr OccName
occ_name) SDoc -> SDoc -> SDoc
<> SDoc
dot
]
| [(Module
mod,ImportedModsVal
imv)] <- [(Module, ImportedModsVal)]
helpful_imports_non_hiding
= [SDoc] -> SDoc
fsep
[ String -> SDoc
text String
"Perhaps you want to add"
, SDoc -> SDoc
quotes (OccName -> SDoc
forall a. Outputable a => a -> SDoc
ppr OccName
occ_name)
, String -> SDoc
text String
"to the import list"
, String -> SDoc
text String
"in the import of"
, SDoc -> SDoc
quotes (Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr Module
mod)
, SDoc -> SDoc
parens (SrcSpan -> SDoc
forall a. Outputable a => a -> SDoc
ppr (ImportedModsVal -> SrcSpan
imv_span ImportedModsVal
imv)) SDoc -> SDoc -> SDoc
<> SDoc
dot
]
| Bool -> Bool
not ([(Module, ImportedModsVal)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Module, ImportedModsVal)]
helpful_imports_non_hiding)
= [SDoc] -> SDoc
fsep
[ String -> SDoc
text String
"Perhaps you want to add"
, SDoc -> SDoc
quotes (OccName -> SDoc
forall a. Outputable a => a -> SDoc
ppr OccName
occ_name)
, String -> SDoc
text String
"to one of these import lists:"
]
SDoc -> SDoc -> SDoc
$$
Int -> SDoc -> SDoc
nest Int
2 ([SDoc] -> SDoc
vcat
[ SDoc -> SDoc
quotes (Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr Module
mod) SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
parens (SrcSpan -> SDoc
forall a. Outputable a => a -> SDoc
ppr (ImportedModsVal -> SrcSpan
imv_span ImportedModsVal
imv))
| (Module
mod,ImportedModsVal
imv) <- [(Module, ImportedModsVal)]
helpful_imports_non_hiding
])
| [(Module
mod,ImportedModsVal
imv)] <- [(Module, ImportedModsVal)]
helpful_imports_hiding
= [SDoc] -> SDoc
fsep
[ String -> SDoc
text String
"Perhaps you want to remove"
, SDoc -> SDoc
quotes (OccName -> SDoc
forall a. Outputable a => a -> SDoc
ppr OccName
occ_name)
, String -> SDoc
text String
"from the explicit hiding list"
, String -> SDoc
text String
"in the import of"
, SDoc -> SDoc
quotes (Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr Module
mod)
, SDoc -> SDoc
parens (SrcSpan -> SDoc
forall a. Outputable a => a -> SDoc
ppr (ImportedModsVal -> SrcSpan
imv_span ImportedModsVal
imv)) SDoc -> SDoc -> SDoc
<> SDoc
dot
]
| Bool -> Bool
not ([(Module, ImportedModsVal)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Module, ImportedModsVal)]
helpful_imports_hiding)
= [SDoc] -> SDoc
fsep
[ String -> SDoc
text String
"Perhaps you want to remove"
, SDoc -> SDoc
quotes (OccName -> SDoc
forall a. Outputable a => a -> SDoc
ppr OccName
occ_name)
, String -> SDoc
text String
"from the hiding clauses"
, String -> SDoc
text String
"in one of these imports:"
]
SDoc -> SDoc -> SDoc
$$
Int -> SDoc -> SDoc
nest Int
2 ([SDoc] -> SDoc
vcat
[ SDoc -> SDoc
quotes (Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr Module
mod) SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
parens (SrcSpan -> SDoc
forall a. Outputable a => a -> SDoc
ppr (ImportedModsVal -> SrcSpan
imv_span ImportedModsVal
imv))
| (Module
mod,ImportedModsVal
imv) <- [(Module, ImportedModsVal)]
helpful_imports_hiding
])
| Bool
otherwise
= SDoc
Outputable.empty
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 (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
forall {a}. (a, ImportedModsVal) -> Bool
helpful [(Module, ImportedModsVal)]
interesting_imports
where helpful :: (a, ImportedModsVal) -> Bool
helpful (a
_,ImportedModsVal
imv)
= Bool -> Bool
not (Bool -> Bool)
-> ([GlobalRdrElt] -> Bool) -> [GlobalRdrElt] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [GlobalRdrElt] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([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 (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [ModuleName]
globMods = 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. [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
globMods :: [ModuleName]
globMods = [ModuleName] -> [ModuleName]
forall a. Eq a => [a] -> [a]
nub [ ModuleName
mod
| GlobalRdrElt
gre <- GlobalRdrEnv -> [GlobalRdrElt]
globalRdrEnvElts GlobalRdrEnv
global_env
, WhereLooking -> GlobalRdrElt -> Bool
isGreOk WhereLooking
where_look GlobalRdrElt
gre
, (ModuleName
mod, HowInScope
_) <- GlobalRdrElt -> [(ModuleName, HowInScope)]
qualsInScope GlobalRdrElt
gre
]
extensionSuggestions :: RdrName -> SDoc
extensionSuggestions :: RdrName -> SDoc
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")
= String -> SDoc
text String
"Perhaps you meant to use RecursiveDo"
| Bool
otherwise = SDoc
Outputable.empty
qualsInScope :: GlobalRdrElt -> [(ModuleName, HowInScope)]
qualsInScope :: GlobalRdrElt -> [(ModuleName, HowInScope)]
qualsInScope GRE { gre_name :: GlobalRdrElt -> Name
gre_name = Name
n, gre_lcl :: GlobalRdrElt -> Bool
gre_lcl = Bool
lcl, gre_imp :: GlobalRdrElt -> [ImportSpec]
gre_imp = [ImportSpec]
is }
| Bool
lcl = case Name -> Maybe Module
nameModule_maybe Name
n of
Maybe Module
Nothing -> []
Just Module
m -> [(Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName Module
m, SrcSpan -> HowInScope
forall a b. a -> Either a b
Left (Name -> SrcSpan
nameSrcSpan Name
n))]
| Bool
otherwise = [ (ImpDeclSpec -> ModuleName
is_as ImpDeclSpec
ispec, ImpDeclSpec -> HowInScope
forall a b. b -> Either a b
Right ImpDeclSpec
ispec)
| ImportSpec
i <- [ImportSpec]
is, let ispec :: ImpDeclSpec
ispec = ImportSpec -> ImpDeclSpec
is_decl ImportSpec
i ]
isGreOk :: WhereLooking -> GlobalRdrElt -> Bool
isGreOk :: WhereLooking -> GlobalRdrElt -> Bool
isGreOk WhereLooking
where_look = case WhereLooking
where_look of
WhereLooking
WL_LocalTop -> GlobalRdrElt -> Bool
isLocalGRE
WhereLooking
WL_LocalOnly -> Bool -> GlobalRdrElt -> Bool
forall a b. a -> b -> a
const Bool
False
WhereLooking
_ -> Bool -> GlobalRdrElt -> Bool
forall a b. a -> b -> a
const Bool
True
exactNameErr :: Name -> SDoc
exactNameErr :: Name -> SDoc
exactNameErr Name
name =
SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text String
"The exact Name" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr Name
name) SDoc -> SDoc -> SDoc
<+> PtrString -> SDoc
ptext (String -> PtrString
sLit String
"is not in scope"))
Int
2 ([SDoc] -> SDoc
vcat [ String -> SDoc
text String
"Probable cause: you used a unique Template Haskell name (NameU), "
, String -> SDoc
text String
"perhaps via newName, but did not bind it"
, String -> SDoc
text String
"If that's it, then -ddump-splices might be useful" ])