summaryrefslogtreecommitdiff
path: root/compiler/rename/RnNames.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rename/RnNames.hs')
-rw-r--r--compiler/rename/RnNames.hs139
1 files changed, 89 insertions, 50 deletions
diff --git a/compiler/rename/RnNames.hs b/compiler/rename/RnNames.hs
index 102deb0b4e..0fed3933d6 100644
--- a/compiler/rename/RnNames.hs
+++ b/compiler/rename/RnNames.hs
@@ -44,7 +44,7 @@ import ListSetOps
import Control.Monad
import Data.Map ( Map )
import qualified Data.Map as Map
-import Data.List ( partition, (\\), find )
+import Data.List ( partition, find )
import qualified Data.Set as Set
import System.FilePath ((</>))
import System.IO
@@ -555,12 +555,12 @@ getLocalNonValBinders fixity_env
-- declaration, not just the name
new_simple :: Located RdrName -> RnM AvailInfo
new_simple rdr_name = do{ nm <- newTopSrcBinder rdr_name
- ; return (Avail nm) }
+ ; return (mkAvail nm) }
new_tc tc_decl -- NOT for type/data instances
= do { let bndrs = hsLTyClDeclBinders tc_decl
; names@(main_name : _) <- mapM newTopSrcBinder bndrs
- ; return (AvailTC main_name names) }
+ ; return (mkAvailTC main_name names) }
new_assoc :: LInstDecl RdrName -> RnM [AvailInfo]
new_assoc (L _ (TyFamInstD {})) = return []
@@ -583,9 +583,14 @@ getLocalNonValBinders fixity_env
new_di mb_cls ti_decl
= do { main_name <- lookupFamInstName mb_cls (dfid_tycon ti_decl)
; sub_names <- mapM newTopSrcBinder (hsDataFamInstBinders ti_decl)
- ; return (AvailTC (unLoc main_name) sub_names) }
+ ; return (mkAvailTC (unLoc main_name) sub_names) }
-- main_name is not bound here!
+ -- XXX
+ mkNameWarn n = NameWarn n Nothing
+ mkAvail n = Avail (mkNameWarn n)
+ mkAvailTC n ns = AvailTC (mkNameWarn n) (map mkNameWarn ns)
+
{-
Note [Looking up family names in family instances]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -647,7 +652,7 @@ filterImports
filterImports iface decl_spec Nothing
= return (Nothing, gresFromAvails prov (concatMap mi_exports iface))
where
- prov = Imported [ImpSpec { is_decl = decl_spec, is_item = ImpAll }]
+ prov mw = Imported [ImpSpec { is_decl = decl_spec, is_item = ImpAll, is_warning = mw }]
filterImports ifaces decl_spec (Just (want_hiding, L l import_items))
@@ -662,7 +667,7 @@ filterImports ifaces decl_spec (Just (want_hiding, L l import_items))
names = availsToNameSet (map snd items2)
keep n = not (n `elemNameSet` names)
pruned_avails = filterAvails keep all_avails
- hiding_prov = Imported [ImpSpec { is_decl = decl_spec, is_item = ImpAll }]
+ hiding_prov mw = Imported [ImpSpec { is_decl = decl_spec, is_item = ImpAll, is_warning = mw }]
gres | want_hiding = gresFromAvails hiding_prov pruned_avails
| otherwise = concatMap (gresFromIE decl_spec) items2
@@ -682,11 +687,15 @@ filterImports ifaces decl_spec (Just (want_hiding, L l import_items))
-- 'combine' is only called for associated types which appear twice
-- in the all_avails. In the example, we combine
-- T(T,T1,T2,T3) and C(C,T) to give (T, T(T,T1,T2,T3), Just C)
+ combine :: (Name, AvailInfo, Maybe Name)
+ -> (Name, AvailInfo, Maybe Name)
+ -> (Name, AvailInfo, Maybe Name)
combine (name1, a1@(AvailTC p1 _), mp1)
(name2, a2@(AvailTC p2 _), mp2)
= ASSERT( name1 == name2 && isNothing mp1 && isNothing mp2 )
- if p1 == name1 then (name1, a1, Just p2)
- else (name1, a2, Just p1)
+ -- XXX?
+ if nameWarnName p1 == name1 then (name1, a1, Just (nameWarnName p2))
+ else (name1, a2, Just (nameWarnName p1))
combine x y = pprPanic "filterImports/combine" (ppr x $$ ppr y)
lookup_name :: RdrName -> IELookupM (Name, AvailInfo, Maybe Name)
@@ -749,11 +758,12 @@ filterImports ifaces decl_spec (Just (want_hiding, L l import_items))
-- non-associated ty/cls
Nothing -> return ([(IEThingAll (L l name), avail)], warns)
-- associated ty
- Just parent -> return ([(IEThingAll (L l name),
- AvailTC name2 (subs \\ [name])),
- (IEThingAll (L l name),
- AvailTC parent [name])],
- warns)
+ Just parent -> let subs' = filter ((name /=) . nameWarnName) subs
+ in return ([(IEThingAll (L l name),
+ AvailTC name2 subs'),
+ (IEThingAll (L l name),
+ mkAvailTC parent [name])],
+ warns)
IEThingAbs (L l tc)
| want_hiding -- hiding ( C )
@@ -776,9 +786,9 @@ filterImports ifaces decl_spec (Just (want_hiding, L l import_items))
let subnames = case ns of -- The tc is first in ns,
[] -> [] -- if it is there at all
-- See the AvailTC Invariant in Avail.hs
- (n1:ns1) | n1 == name -> ns1
+ (n1:ns1) | nameWarnName n1 == name -> ns1
| otherwise -> ns
- mb_children = lookupChildren subnames rdr_ns
+ mb_children = lookupChildren (map nameWarnName subnames) rdr_ns
children <- if any isNothing mb_children
then failLookupWith BadImport
@@ -787,13 +797,13 @@ filterImports ifaces decl_spec (Just (want_hiding, L l import_items))
case mb_parent of
-- non-associated ty/cls
Nothing -> return ([(IEThingWith (L l name) children,
- AvailTC name (name:map unLoc children))],
+ mkAvailTC name (name:map unLoc children))],
[])
-- associated ty
Just parent -> return ([(IEThingWith (L l name) children,
- AvailTC name (map unLoc children)),
+ mkAvailTC name (map unLoc children)),
(IEThingWith (L l name) children,
- AvailTC parent [name])],
+ mkAvailTC parent [name])],
[])
_other -> failLookupWith IllegalImport
@@ -804,12 +814,17 @@ filterImports ifaces decl_spec (Just (want_hiding, L l import_items))
mkIEThingAbs l (n, av, Nothing ) = (IEThingAbs (L l n),
trimAvail av n)
mkIEThingAbs l (n, _, Just parent) = (IEThingAbs (L l n),
- AvailTC parent [n])
+ mkAvailTC parent [n])
handle_bad_import m = catchIELookup m $ \err -> case err of
BadImport | want_hiding -> return ([], [BadImportW])
_ -> failLookupWith err
+
+ -- XXX
+ mkNameWarn n = NameWarn n Nothing
+ mkAvailTC n ns = AvailTC (mkNameWarn n) (map mkNameWarn ns)
+
type IELookupM = MaybeErr IELookupError
data IELookupWarning
@@ -845,11 +860,12 @@ catIELookupM ms = [ a | Succeeded a <- ms ]
greExportAvail :: GlobalRdrElt -> AvailInfo
greExportAvail gre
= case gre_par gre of
- ParentIs p -> AvailTC p [me]
- NoParent | isTyConName me -> AvailTC me [me]
- | otherwise -> Avail me
+ ParentIs p -> AvailTC (NameWarn p Nothing) [me]
+ NoParent | isTyConName me' -> AvailTC me [me]
+ | otherwise -> Avail me
where
- me = gre_name gre
+ me' = gre_name gre
+ me = NameWarn me' Nothing -- XXX Wrong?
plusAvail :: AvailInfo -> AvailInfo -> AvailInfo
plusAvail a1 a2
@@ -868,7 +884,8 @@ plusAvail a1 a2 = pprPanic "RnEnv.plusAvail" (hsep [ppr a1,ppr a2])
trimAvail :: AvailInfo -> Name -> AvailInfo
trimAvail (Avail n) _ = Avail n
-trimAvail (AvailTC n ns) m = ASSERT( m `elem` ns) AvailTC n [m]
+-- XXX Wrong?:
+trimAvail (AvailTC n ns) m = ASSERT( m `elem` map nameWarnName ns) AvailTC n [NameWarn m Nothing]
-- | filters 'AvailInfo's by the given predicate
filterAvails :: (Name -> Bool) -> [AvailInfo] -> [AvailInfo]
@@ -878,10 +895,10 @@ filterAvails keep avails = foldr (filterAvail keep) [] avails
filterAvail :: (Name -> Bool) -> AvailInfo -> [AvailInfo] -> [AvailInfo]
filterAvail keep ie rest =
case ie of
- Avail n | keep n -> ie : rest
- | otherwise -> rest
+ Avail n | keep (nameWarnName n) -> ie : rest
+ | otherwise -> rest
AvailTC tc ns ->
- let left = filter keep ns in
+ let left = filter (keep . nameWarnName) ns in
if null left then rest else AvailTC tc left : rest
-- | Given an import\/export spec, construct the appropriate 'GlobalRdrElt's.
@@ -892,9 +909,9 @@ gresFromIE decl_spec (L loc ie, avail)
is_explicit = case ie of
IEThingAll (L _ name) -> \n -> n == name
_ -> \_ -> True
- prov_fn name = Imported [imp_spec]
+ prov_fn name mw = Imported [imp_spec]
where
- imp_spec = ImpSpec { is_decl = decl_spec, is_item = item_spec }
+ imp_spec = ImpSpec { is_decl = decl_spec, is_item = item_spec, is_warning = mw }
item_spec = ImpSome { is_explicit = is_explicit name, is_iloc = loc }
mkChildEnv :: [GlobalRdrElt] -> NameEnv [Name]
@@ -985,11 +1002,12 @@ type ExportAccum -- The type of the accumulating parameter of
-- the main worker function in rnExports
= ([LIE Name], -- Export items with Names
ExportOccMap, -- Tracks exported occurrence names
- [AvailInfo]) -- The accumulated exported stuff
+ [AvailInfo], -- The accumulated exported stuff
-- Not nub'd!
+ Map Name WarningTxt) -- Warnings attached to exports
emptyExportAccum :: ExportAccum
-emptyExportAccum = ([], emptyOccEnv, [])
+emptyExportAccum = ([], emptyOccEnv, [], Map.empty)
type ExportOccMap = OccEnv (Name, IE RdrName)
-- Tracks what a particular exported OccName
@@ -1060,8 +1078,11 @@ exports_from_avail Nothing rdr_env _imports _this_mod
return (Nothing, avails)
exports_from_avail (Just (L _ rdr_items)) rdr_env imports this_mod
- = do (ie_names, _, exports) <- foldlM do_litem emptyExportAccum rdr_items
- return (Just ie_names, exports)
+ = do (ie_names, _, exports, warnMap) <- foldlM do_litem emptyExportAccum rdr_items
+ -- XXX TODO: Ought to check that everything in the warnMap is
+ -- actually exported
+
+ return (Just ie_names, addAvailInfoWarnings warnMap exports)
where
do_litem :: ExportAccum -> LIE RdrName -> RnM ExportAccum
do_litem acc lie = setSrcSpan (getLoc lie) (exports_from_item acc lie)
@@ -1074,7 +1095,7 @@ exports_from_avail (Just (L _ rdr_items)) rdr_env imports this_mod
(qual_name, _, _, _) <- xs ]
exports_from_item :: ExportAccum -> LIE RdrName -> RnM ExportAccum
- exports_from_item acc@(ie_names, occs, exports)
+ exports_from_item acc@(ie_names, occs, exports, warnMap)
(L loc (IEModuleContents (L lm mod)))
| let earlier_mods = [ mod
| (L _ (IEModuleContents (L _ mod))) <- ie_names ]
@@ -1112,12 +1133,17 @@ exports_from_avail (Just (L _ rdr_items)) rdr_env imports this_mod
; traceRn (vcat [ text "export mod" <+> ppr mod
, ppr new_exports ])
; return (L loc (IEModuleContents (L lm mod)) : ie_names,
- occs', new_exports ++ exports) }
+ occs', new_exports ++ exports, warnMap) }
- exports_from_item acc@(lie_names, occs, exports) (L loc ie)
+ exports_from_item (lie_names, occs, exports, warnMap)
+ (L _ (IEWarning (Warning (L _ rdr:_) w)))
+ = do n <- lookupGlobalOccRn rdr -- XXX only handles head of warnings
+ return (lie_names, occs, exports, Map.insert n w warnMap)
+
+ exports_from_item acc@(lie_names, occs, exports, warnMap) (L loc ie)
| isDoc ie
= do new_ie <- lookup_doc_ie ie
- return (L loc new_ie : lie_names, occs, exports)
+ return (L loc new_ie : lie_names, occs, exports, warnMap)
| otherwise
= do (new_ie, avail) <- lookup_ie ie
@@ -1127,7 +1153,7 @@ exports_from_avail (Just (L _ rdr_items)) rdr_env imports this_mod
occs' <- check_occs ie occs (availNames avail)
- return (L loc new_ie : lie_names, occs', avail : exports)
+ return (L loc new_ie : lie_names, occs', avail : exports, warnMap)
-------------
lookup_ie :: IE RdrName -> RnM (IE Name, AvailInfo)
@@ -1153,24 +1179,28 @@ exports_from_avail (Just (L _ rdr_items)) rdr_env imports this_mod
-- only import T abstractly, or T is a synonym.
addErr (exportItemErr ie)
- return (IEThingAll (L l name), AvailTC name (name:kids))
+ return (IEThingAll (L l name), mkAvailTC name (name:kids))
lookup_ie ie@(IEThingWith (L l rdr) sub_rdrs)
= do name <- lookupGlobalOccRn rdr
if isUnboundName name
- then return (IEThingWith (L l name) [], AvailTC name [name])
+ then return (IEThingWith (L l name) [], mkAvailTC name [name])
else do
let mb_names = lookupChildren (findChildren kids_env name) sub_rdrs
if any isNothing mb_names
then do addErr (exportItemErr ie)
- return (IEThingWith (L l name) [], AvailTC name [name])
+ return (IEThingWith (L l name) [], mkAvailTC name [name])
else do let names = catMaybes mb_names
addUsedKids rdr (map unLoc names)
return (IEThingWith (L l name) names
- , AvailTC name (name:map unLoc names))
+ , mkAvailTC name (name:map unLoc names))
lookup_ie _ = panic "lookup_ie" -- Other cases covered earlier
+ -- XXX
+ mkNameWarn n = NameWarn n Nothing
+ mkAvailTC n ns = AvailTC (mkNameWarn n) (map mkNameWarn ns)
+
-------------
lookup_doc_ie :: IE RdrName -> RnM (IE Name)
lookup_doc_ie (IEGroup lev doc) = do rn_doc <- rnHsDoc doc
@@ -1195,6 +1225,13 @@ isDoc (IEDocNamed _) = True
isDoc (IEGroup _ _) = True
isDoc _ = False
+addAvailInfoWarnings :: Map Name WarningTxt -> [AvailInfo] -> [AvailInfo]
+addAvailInfoWarnings m = map f
+ where f (Avail n) = Avail (g n)
+ f (AvailTC n ns) = AvailTC (g n) (map g ns)
+
+ g (NameWarn n _) = NameWarn n (Map.lookup n m)
+
-------------------------------
isModuleExported :: Bool -> ModuleName -> GlobalRdrElt -> Bool
-- True if the thing is in scope *both* unqualified, *and* with qualifier M
@@ -1409,7 +1446,7 @@ findImportUsage imports rdr_env rdrs
used_avails = Map.lookup (srcSpanEnd loc) import_usage `orElse` []
-- srcSpanEnd: see Note [The ImportMap]
used_names = availsToNameSet used_avails
- used_parents = mkNameSet [n | AvailTC n _ <- used_avails]
+ used_parents = mkNameSet [n | AvailTC (NameWarn n _) _ <- used_avails]
unused_imps -- Not trivial; see eg Trac #7454
= case imps of
@@ -1568,20 +1605,22 @@ printMinimalImports imports_w_usage
-- we want to say "T(..)", but if we're importing only a subset we want
-- to say "T(A,B,C)". So we have to find out what the module exports.
to_ie _ (Avail n)
- = [IEVar (noLoc n)]
+ = [IEVar (noLoc (nameWarnName n))]
to_ie _ (AvailTC n [m])
- | n==m = [IEThingAbs (noLoc n)]
+ | n==m = [IEThingAbs (noLoc (nameWarnName n))]
to_ie ifaces (AvailTC n ns)
= case [xs | iface <- ifaces
, AvailTC x xs <- mi_exports iface
, x == n
, x `elem` xs -- Note [Partial export]
] of
- [xs] | all_used xs -> [IEThingAll (noLoc n)]
- | otherwise -> [IEThingWith (noLoc n)
- (map noLoc (filter (/= n) ns))]
- _other -> map (IEVar . noLoc) ns
+ [xs] | all_used xs -> [IEThingAll (noLoc n')]
+ | otherwise -> [IEThingWith (noLoc n')
+ (map noLoc (filter (/= n') ns'))]
+ _other -> map (IEVar . noLoc) ns'
where
+ n' = nameWarnName n
+ ns' = map nameWarnName ns
all_used avail_occs = all (`elem` ns) avail_occs
{-
@@ -1664,7 +1703,7 @@ badImportItemErr is_boot decl_spec ie avails
Nothing -> badImportItemErrStd is_boot decl_spec ie
where
checkIfDataCon (AvailTC _ ns) =
- case find (\n -> importedFS == nameOccNameFS n) ns of
+ case find (\n -> importedFS == nameOccNameFS n) (map nameWarnName ns) of
Just n -> isDataConName n
Nothing -> False
checkIfDataCon _ = False