module GHC.Rename.Unbound
( mkUnboundName
, mkUnboundNameRdr
, isUnboundName
, reportUnboundName
, unknownNameSuggestions
, WhereLooking(..)
, unboundName
, unboundNameX
, notInScopeErr
, exactNameErr
)
where
import GHC.Prelude
import GHC.Driver.Session
import GHC.Driver.Ppr
import GHC.Tc.Utils.Monad
import GHC.Builtin.Names ( mkUnboundName, isUnboundName, getUnique)
import GHC.Utils.Outputable as Outputable
import GHC.Utils.Misc
import GHC.Data.Maybe
import GHC.Data.FastString
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 Data.List (sortBy, partition, nub)
import Data.Function ( on )
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 <- 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 <- forall (m :: * -> *). HasModule m => m Module
getModule
; HomePackageTable
hpt <- 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) }
; 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 (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 SDoc -> SDoc -> SDoc
$$
GlobalRdrEnv -> RdrName -> SDoc
fieldSelectorSuggestions GlobalRdrEnv
global_env RdrName
tried_rdr_name
fieldSelectorSuggestions :: GlobalRdrEnv -> RdrName -> SDoc
fieldSelectorSuggestions :: GlobalRdrEnv -> RdrName -> SDoc
fieldSelectorSuggestions GlobalRdrEnv
global_env RdrName
tried_rdr_name
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null [GlobalRdrElt]
gres = SDoc
Outputable.empty
| Bool
otherwise = String -> SDoc
text String
"NB:"
SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (forall a. Outputable a => a -> SDoc
ppr RdrName
tried_rdr_name)
SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"is a field selector" SDoc -> SDoc -> SDoc
<+> SDoc
whose
SDoc -> SDoc -> SDoc
$$ String -> SDoc
text String
"that has been suppressed by NoFieldSelectors"
where
gres :: [GlobalRdrElt]
gres = forall a. (a -> Bool) -> [a] -> [a]
filter GlobalRdrElt -> Bool
isNoFieldSelectorGRE 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 <- forall a b. (a -> b) -> [a] -> [b]
map GlobalRdrElt -> Parent
gre_par [GlobalRdrElt]
gres ]
whose :: SDoc
whose | forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Name]
parents = SDoc
empty
| Bool
otherwise = String -> SDoc
text String
"belonging to the type" SDoc -> SDoc -> SDoc
<> forall a. [a] -> SDoc
plural [Name]
parents
SDoc -> SDoc -> SDoc
<+> forall a. Outputable a => [a] -> SDoc
pprQuotedList [Name]
parents
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 (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
= [ (forall a. Outputable a => DynFlags -> a -> String
showPpr DynFlags
dflags RdrName
r, (RdrName
r, forall a b. a -> Either a b
Left SrcSpan
loc))
| (RdrName
r,SrcSpan
loc) <- LocalRdrEnv -> [(RdrName, SrcSpan)]
local_possibilities LocalRdrEnv
local_env ]
forall a. [a] -> [a] -> [a]
++ [ (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 = forall a. String -> [(String, a)] -> [a]
fuzzyLookup (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 (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 (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 (forall a. Outputable a => a -> SDoc
ppr RdrName
rdr) SDoc -> SDoc -> SDoc
<+>
SDoc -> SDoc
parens (String -> SDoc
text String
"imported from" SDoc -> SDoc -> 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 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 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
, Bool -> Bool
not (GlobalRdrElt -> Bool
isNoFieldSelectorGRE 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, (RdrName, HowInScope)
pair)
| GlobalRdrElt
gre <- GlobalRdrEnv -> [GlobalRdrElt]
globalRdrEnvElts GlobalRdrEnv
global_env
, WhereLooking -> GlobalRdrElt -> Bool
isGreOk WhereLooking
where_look GlobalRdrElt
gre
, Bool -> Bool
not (GlobalRdrElt -> Bool
isNoFieldSelectorGRE 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
, (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 :: GlobalRdrElt
gre@GRE { gre_lcl :: GlobalRdrElt -> Bool
gre_lcl = Bool
lcl, gre_imp :: GlobalRdrElt -> [ImportSpec]
gre_imp = [ImportSpec]
is })
| Bool
lcl = [ forall a b. a -> Either a b
Left (GlobalRdrElt -> SrcSpan
greDefinitionSrcSpan GlobalRdrElt
gre) ]
| Bool
otherwise = [ 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 :: GlobalRdrElt
gre@GRE { gre_imp :: GlobalRdrElt -> [ImportSpec]
gre_imp = [ImportSpec]
is })
= [ (ModuleName -> OccName -> RdrName
mkRdrQual (ImpDeclSpec -> ModuleName
is_as ImpDeclSpec
ispec) (GlobalRdrElt -> OccName
greOccName GlobalRdrElt
gre), 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
| 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 (forall a. Outputable a => a -> SDoc
ppr ModuleName
name)
, String -> SDoc
text String
"is imported."
]
| Bool
is_qualified
, 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 (forall a. Outputable a => a -> SDoc
ppr Module
mod)
, String -> SDoc
text String
"does not export"
, SDoc -> SDoc
quotes (forall a. Outputable a => a -> SDoc
ppr OccName
occ_name) SDoc -> SDoc -> SDoc
<> SDoc
dot
]
| Bool
is_qualified
, forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Module, ImportedModsVal)]
helpful_imports
, Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Module, ImportedModsVal)]
interesting_imports)
, [Module]
mods <- forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst [(Module, ImportedModsVal)]
interesting_imports
= [SDoc] -> SDoc
hsep
[ String -> SDoc
text String
"Neither"
, [SDoc] -> SDoc
quotedListWithNor (forall a b. (a -> b) -> [a] -> [b]
map forall a. Outputable a => a -> SDoc
ppr [Module]
mods)
, String -> SDoc
text String
"exports"
, SDoc -> SDoc
quotes (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 (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 (forall a. Outputable a => a -> SDoc
ppr Module
mod)
, SDoc -> SDoc
parens (forall a. Outputable a => a -> SDoc
ppr (ImportedModsVal -> SrcSpan
imv_span ImportedModsVal
imv)) SDoc -> SDoc -> SDoc
<> SDoc
dot
]
| Bool -> Bool
not (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 (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 (forall a. Outputable a => a -> SDoc
ppr Module
mod) SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
parens (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 (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 (forall a. Outputable a => a -> SDoc
ppr Module
mod)
, SDoc -> SDoc
parens (forall a. Outputable a => a -> SDoc
ppr (ImportedModsVal -> SrcSpan
imv_span ImportedModsVal
imv)) SDoc -> SDoc -> SDoc
<> SDoc
dot
]
| Bool -> Bool
not (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 (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 (forall a. Outputable a => a -> SDoc
ppr Module
mod) SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
parens (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 -> (forall a. Maybe a
Nothing, OccName
occ_name)
Qual ModuleName
mod_name OccName
occ_name -> (forall a. a -> Maybe a
Just ModuleName
mod_name, OccName
occ_name)
RdrName
_ -> 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) <- forall a. ModuleEnv a -> [(Module, a)]
moduleEnvToList (ImportAvails -> ImportedMods
imp_mods ImportAvails
imports)
, Just ImportedModsVal
imp <- forall (m :: * -> *) a. Monad m => a -> m a
return 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 = forall a. [a] -> Maybe a
listToMaybe forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy ImportedModsVal -> ImportedModsVal -> Ordering
cmp forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 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 =
(forall a. Ord a => a -> a -> Ordering
compare 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 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 = forall a. (a -> Bool) -> [a] -> [a]
filter (Module, ImportedModsVal) -> Bool
helpful [(Module, ImportedModsVal)]
interesting_imports
where helpful :: (Module, ImportedModsVal) -> Bool
helpful (Module
_,ImportedModsVal
imv)
= Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> Bool
null 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)
= forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (ImportedModsVal -> Bool
imv_is_hiding forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [ModuleName]
globMods = Bool
False
| forall unit. GenModule unit -> ModuleName
moduleName Module
currMod forall a. Eq a => a -> a -> Bool
== ModuleName
modnam = Bool
False
| 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 = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst (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 = forall a. [a] -> a
last [Unique]
uniqs forall a. Eq a => a -> a -> Bool
== forall a. Uniquable a => a -> Unique
getUnique a
modnam
globMods :: [ModuleName]
globMods = 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 forall a. Eq a => a -> a -> Bool
== NameSpace -> FastString -> RdrName
mkUnqual NameSpace
varName (String -> FastString
fsLit String
"mdo") Bool -> Bool -> Bool
||
RdrName
rdrName 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 :: GlobalRdrElt
gre@GRE { gre_lcl :: GlobalRdrElt -> Bool
gre_lcl = Bool
lcl, gre_imp :: GlobalRdrElt -> [ImportSpec]
gre_imp = [ImportSpec]
is }
| Bool
lcl = case GlobalRdrElt -> Maybe Module
greDefinitionModule GlobalRdrElt
gre of
Maybe Module
Nothing -> []
Just Module
m -> [(forall unit. GenModule unit -> ModuleName
moduleName Module
m, forall a b. a -> Either a b
Left (GlobalRdrElt -> SrcSpan
greDefinitionSrcSpan GlobalRdrElt
gre))]
| Bool
otherwise = [ (ImpDeclSpec -> ModuleName
is_as ImpDeclSpec
ispec, 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 -> forall a b. a -> b -> a
const Bool
False
WhereLooking
_ -> 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 (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" ])