module RnUnbound ( mkUnboundName
                 , mkUnboundNameRdr
                 , isUnboundName
                 , reportUnboundName
                 , unknownNameSuggestions
                 , WhereLooking(..)
                 , unboundName
                 , unboundNameX
                 , notInScopeErr ) where
import GhcPrelude
import RdrName
import HscTypes
import TcRnMonad
import Name
import Module
import SrcLoc
import Outputable
import PrelNames ( mkUnboundName, isUnboundName, getUnique)
import Util
import Maybes
import DynFlags
import FastString
import Data.List
import Data.Function ( on )
import UniqDFM (udfmToList)
data WhereLooking = WL_Any        
                  | WL_Global     
                  | WL_LocalTop   
                  | WL_LocalOnly
                        
                        
                        
mkUnboundNameRdr :: RdrName -> Name
mkUnboundNameRdr :: RdrName -> Name
mkUnboundNameRdr rdr :: RdrName
rdr = OccName -> Name
mkUnboundName (RdrName -> OccName
rdrNameOcc RdrName
rdr)
reportUnboundName :: RdrName -> RnM Name
reportUnboundName :: RdrName -> RnM Name
reportUnboundName rdr :: RdrName
rdr = WhereLooking -> RdrName -> RnM Name
unboundName WhereLooking
WL_Any RdrName
rdr
unboundName :: WhereLooking -> RdrName -> RnM Name
unboundName :: WhereLooking -> RdrName -> RnM Name
unboundName wl :: WhereLooking
wl rdr :: 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 where_look :: WhereLooking
where_look rdr_name :: RdrName
rdr_name extra :: 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 rdr_name :: RdrName
rdr_name
  = SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "Not in scope:")
       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_ where_look :: WhereLooking
where_look dflags :: DynFlags
dflags hpt :: HomePackageTable
hpt curr_mod :: Module
curr_mod global_env :: GlobalRdrEnv
global_env local_env :: LocalRdrEnv
local_env
                          imports :: ImportAvails
imports tried_rdr_name :: 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 where_look :: WhereLooking
where_look dflags :: DynFlags
dflags global_env :: GlobalRdrEnv
global_env
                        local_env :: LocalRdrEnv
local_env tried_rdr_name :: RdrName
tried_rdr_name
  = case [(RdrName, HowInScope)]
suggest of
      []  -> SDoc
Outputable.empty
      [p :: (RdrName, HowInScope)
p] -> SDoc
perhaps SDoc -> SDoc -> SDoc
<+> (RdrName, HowInScope) -> SDoc
pp_item (RdrName, HowInScope)
p
      ps :: [(RdrName, HowInScope)]
ps  -> [SDoc] -> SDoc
sep [ SDoc
perhaps SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "one of these:"
                 , Int -> SDoc -> SDoc
nest 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))
          | (r :: RdrName
r,loc :: 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) | (r :: RdrName
r, rp :: (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 "Perhaps you meant"
    pp_item :: (RdrName, HowInScope) -> SDoc
    pp_item :: (RdrName, HowInScope) -> SDoc
pp_item (rdr :: RdrName
rdr, Left loc :: 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 l :: FastString
l -> SDoc -> SDoc
parens (FastString -> SDoc
forall a. Outputable a => a -> SDoc
ppr FastString
l)
                     RealSrcSpan l :: RealSrcSpan
l -> SDoc -> SDoc
parens (String -> SDoc
text "line" SDoc -> SDoc -> SDoc
<+> Int -> SDoc
int (RealSrcSpan -> Int
srcSpanStartLine RealSrcSpan
l))
    pp_item (rdr :: RdrName
rdr, Right is :: 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 "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 rdr :: 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 occ :: 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 { WL_Any -> Bool
True
                                  ; WL_LocalOnly -> Bool
True
                                  ; _ -> Bool
False }
    local_possibilities :: LocalRdrEnv -> [(RdrName, SrcSpan)]
    local_possibilities :: LocalRdrEnv -> [(RdrName, SrcSpan)]
local_possibilities env :: 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 global_env :: 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
                        , (mod :: ModuleName
mod, how :: 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
                                (how :: HowInScope
how:_, _)    -> [ (RdrName
rdr_unqual, HowInScope
how) ]
                                ([],    pr :: (RdrName, HowInScope)
pr:_) -> [ (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 where_look :: WhereLooking
where_look global_env :: GlobalRdrEnv
global_env hpt :: HomePackageTable
hpt currMod :: Module
currMod imports :: ImportAvails
imports rdr_name :: 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 name :: ModuleName
name <- Maybe ModuleName
mod_name
  , ModuleName -> Bool
show_not_imported_line ModuleName
name
  = [SDoc] -> SDoc
hsep
      [ String -> SDoc
text "No module named"
      , SDoc -> SDoc
quotes (ModuleName -> SDoc
forall a. Outputable a => a -> SDoc
ppr ModuleName
name)
      , String -> SDoc
text "is imported."
      ]
  | Bool
is_qualified
  , [(Module, ImportedModsVal)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Module, ImportedModsVal)]
helpful_imports
  , [(mod :: Module
mod,_)] <- [(Module, ImportedModsVal)]
interesting_imports
  = [SDoc] -> SDoc
hsep
      [ String -> SDoc
text "Module"
      , SDoc -> SDoc
quotes (Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr Module
mod)
      , String -> SDoc
text "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 "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 "exports"
      , SDoc -> SDoc
quotes (OccName -> SDoc
forall a. Outputable a => a -> SDoc
ppr OccName
occ_name) SDoc -> SDoc -> SDoc
<> SDoc
dot
      ]
  | [(mod :: Module
mod,imv :: ImportedModsVal
imv)] <- [(Module, ImportedModsVal)]
helpful_imports_non_hiding
  = [SDoc] -> SDoc
fsep
      [ String -> SDoc
text "Perhaps you want to add"
      , SDoc -> SDoc
quotes (OccName -> SDoc
forall a. Outputable a => a -> SDoc
ppr OccName
occ_name)
      , String -> SDoc
text "to the import list"
      , String -> SDoc
text "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 "Perhaps you want to add"
      , SDoc -> SDoc
quotes (OccName -> SDoc
forall a. Outputable a => a -> SDoc
ppr OccName
occ_name)
      , String -> SDoc
text "to one of these import lists:"
      ]
    SDoc -> SDoc -> SDoc
$$
    Int -> SDoc -> SDoc
nest 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))
        | (mod :: Module
mod,imv :: ImportedModsVal
imv) <- [(Module, ImportedModsVal)]
helpful_imports_non_hiding
        ])
  | [(mod :: Module
mod,imv :: ImportedModsVal
imv)] <- [(Module, ImportedModsVal)]
helpful_imports_hiding
  = [SDoc] -> SDoc
fsep
      [ String -> SDoc
text "Perhaps you want to remove"
      , SDoc -> SDoc
quotes (OccName -> SDoc
forall a. Outputable a => a -> SDoc
ppr OccName
occ_name)
      , String -> SDoc
text "from the explicit hiding list"
      , String -> SDoc
text "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 "Perhaps you want to remove"
      , SDoc -> SDoc
quotes (OccName -> SDoc
forall a. Outputable a => a -> SDoc
ppr OccName
occ_name)
      , String -> SDoc
text "from the hiding clauses"
      , String -> SDoc
text "in one of these imports:"
      ]
    SDoc -> SDoc -> SDoc
$$
    Int -> SDoc -> SDoc
nest 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))
        | (mod :: Module
mod,imv :: ImportedModsVal
imv) <- [(Module, ImportedModsVal)]
helpful_imports_hiding
        ])
  | Bool
otherwise
  = SDoc
Outputable.empty
 where
  is_qualified :: Bool
is_qualified = RdrName -> Bool
isQual RdrName
rdr_name
  (mod_name :: Maybe ModuleName
mod_name, occ_name :: OccName
occ_name) = case RdrName
rdr_name of
    Unqual occ_name :: OccName
occ_name        -> (Maybe ModuleName
forall a. Maybe a
Nothing, OccName
occ_name)
    Qual mod_name :: ModuleName
mod_name occ_name :: OccName
occ_name -> (ModuleName -> Maybe ModuleName
forall a. a -> Maybe a
Just ModuleName
mod_name, OccName
occ_name)
    _                      -> String -> (Maybe ModuleName, OccName)
forall a. HasCallStack => String -> a
error "importSuggestions: dead code"
  
  
  interesting_imports :: [(Module, ImportedModsVal)]
interesting_imports = [ (Module
mod, ImportedModsVal
imp)
    | (mod :: Module
mod, mod_imports :: [ImportedBy]
mod_imports) <- ModuleEnv [ImportedBy] -> [(Module, [ImportedBy])]
forall a. ModuleEnv a -> [(Module, a)]
moduleEnvToList (ImportAvails -> ModuleEnv [ImportedBy]
imp_mods ImportAvails
imports)
    , Just imp :: 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 ((Bool, SrcSpan) -> (Bool, SrcSpan) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ((Bool, SrcSpan) -> (Bool, SrcSpan) -> Ordering)
-> (ImportedModsVal -> (Bool, SrcSpan))
-> ImportedModsVal
-> ImportedModsVal
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` ImportedModsVal -> (Bool, SrcSpan)
prefer) ([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 imv :: ImportedModsVal
imv = case Maybe ModuleName
mod_name of Just name :: ModuleName
name -> ImportedModsVal -> ModuleName
imv_name ImportedModsVal
imv ModuleName -> ModuleName -> Bool
forall a. Eq a => a -> a -> Bool
== ModuleName
name
                                        Nothing   -> Bool -> Bool
not (ImportedModsVal -> Bool
imv_qualified ImportedModsVal
imv)
          prefer :: ImportedModsVal -> (Bool, SrcSpan)
prefer imv :: ImportedModsVal
imv = (ImportedModsVal -> Bool
imv_is_hiding ImportedModsVal
imv, ImportedModsVal -> SrcSpan
imv_span ImportedModsVal
imv)
  
  
  
  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 (_,imv :: 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
  
  
  (helpful_imports_hiding :: [(Module, ImportedModsVal)]
helpful_imports_hiding, helpful_imports_non_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 modnam :: 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
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 elt. UniqDFM elt -> [(Unique, elt)]
udfmToList HomePackageTable
hpt)
      is_last_loaded_mod :: a -> [Unique] -> Bool
is_last_loaded_mod _ []         = Bool
False
      is_last_loaded_mod modnam :: a
modnam uniqs :: [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
                     , (mod :: ModuleName
mod, _) <- GlobalRdrElt -> [(ModuleName, HowInScope)]
qualsInScope GlobalRdrElt
gre
                     ]
extensionSuggestions :: RdrName -> SDoc
extensionSuggestions :: RdrName -> SDoc
extensionSuggestions rdrName :: RdrName
rdrName
  | RdrName
rdrName RdrName -> RdrName -> Bool
forall a. Eq a => a -> a -> Bool
== NameSpace -> FastString -> RdrName
mkUnqual NameSpace
varName (String -> FastString
fsLit "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 "rec")
      = String -> SDoc
text "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
                Nothing -> []
                Just m :: Module
m  -> [(Module -> 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 where_look :: WhereLooking
where_look = case WhereLooking
where_look of
                         WL_LocalTop  -> GlobalRdrElt -> Bool
isLocalGRE
                         WL_LocalOnly -> Bool -> GlobalRdrElt -> Bool
forall a b. a -> b -> a
const Bool
False
                         _            -> Bool -> GlobalRdrElt -> Bool
forall a b. a -> b -> a
const Bool
True