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.hs339
1 files changed, 217 insertions, 122 deletions
diff --git a/compiler/rename/RnNames.hs b/compiler/rename/RnNames.hs
index 6197bc7480..8ded9c27db 100644
--- a/compiler/rename/RnNames.hs
+++ b/compiler/rename/RnNames.hs
@@ -20,11 +20,17 @@ module RnNames (
mkChildEnv,
findChildren,
dodgyMsg,
- dodgyMsgInsert
+ dodgyMsgInsert,
+ findImportUsage,
+ getMinimalImports,
+ printMinimalImports,
+ ImportDeclUsage
) where
#include "HsVersions.h"
+import GhcPrelude
+
import DynFlags
import HsSyn
import TcEnv
@@ -132,7 +138,7 @@ So there is an interesting design question in regards to transitive trust
checking. Say I have a module B compiled with -XSafe. B is dependent on a bunch
of modules and packages, some packages it requires to be trusted as its using
-XTrustworthy modules from them. Now if I have a module A that doesn't use safe
-haskell at all and simply imports B, should A inherit all the the trust
+haskell at all and simply imports B, should A inherit all the trust
requirements from B? Should A now also require that a package p is trusted since
B required it?
@@ -175,16 +181,71 @@ rnImports imports = do
return (decls, rdr_env, imp_avails, hpc_usage)
where
+ -- See Note [Combining ImportAvails]
combine :: [(LImportDecl GhcRn, GlobalRdrEnv, ImportAvails, AnyHpcUsage)]
-> ([LImportDecl GhcRn], GlobalRdrEnv, ImportAvails, AnyHpcUsage)
- combine = foldr plus ([], emptyGlobalRdrEnv, emptyImportAvails, False)
-
- plus (decl, gbl_env1, imp_avails1,hpc_usage1)
- (decls, gbl_env2, imp_avails2,hpc_usage2)
+ combine ss =
+ let (decls, rdr_env, imp_avails, hpc_usage, finsts) = foldr
+ plus
+ ([], emptyGlobalRdrEnv, emptyImportAvails, False, emptyModuleSet)
+ ss
+ in (decls, rdr_env, imp_avails { imp_finsts = moduleSetElts finsts },
+ hpc_usage)
+
+ plus (decl, gbl_env1, imp_avails1, hpc_usage1)
+ (decls, gbl_env2, imp_avails2, hpc_usage2, finsts_set)
= ( decl:decls,
gbl_env1 `plusGlobalRdrEnv` gbl_env2,
- imp_avails1 `plusImportAvails` imp_avails2,
- hpc_usage1 || hpc_usage2 )
+ imp_avails1' `plusImportAvails` imp_avails2,
+ hpc_usage1 || hpc_usage2,
+ extendModuleSetList finsts_set new_finsts )
+ where
+ imp_avails1' = imp_avails1 { imp_finsts = [] }
+ new_finsts = imp_finsts imp_avails1
+
+{-
+Note [Combining ImportAvails]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+imp_finsts in ImportAvails is a list of family instance modules
+transitively depended on by an import. imp_finsts for a currently
+compiled module is a union of all the imp_finsts of imports.
+Computing the union of two lists of size N is O(N^2) and if we
+do it to M imports we end up with O(M*N^2). That can get very
+expensive for bigger module hierarchies.
+
+Union can be optimized to O(N log N) if we use a Set.
+imp_finsts is converted back and forth between dep_finsts, so
+changing a type of imp_finsts means either paying for the conversions
+or changing the type of dep_finsts as well.
+
+I've measured that the conversions would cost 20% of allocations on my
+test case, so that can be ruled out.
+
+Changing the type of dep_finsts forces checkFamInsts to
+get the module lists in non-deterministic order. If we wanted to restore
+the deterministic order, we'd have to sort there, which is an additional
+cost. As far as I can tell, using a non-deterministic order is fine there,
+but that's a brittle nonlocal property which I'd like to avoid.
+
+Additionally, dep_finsts is read from an interface file, so its "natural"
+type is a list. Which makes it a natural type for imp_finsts.
+
+Since rnImports.combine is really the only place that would benefit from
+it being a Set, it makes sense to optimize the hot loop in rnImports.combine
+without changing the representation.
+
+So here's what we do: instead of naively merging ImportAvails with
+plusImportAvails in a loop, we make plusImportAvails merge empty imp_finsts
+and compute the union on the side using Sets. When we're done, we can
+convert it back to a list. One nice side effect of this approach is that
+if there's a lot of overlap in the imp_finsts of imports, the
+Set doesn't really need to grow and we don't need to allocate.
+
+Running generateModules from Trac #14693 with DEPTH=16, WIDTH=30 finishes in
+23s before, and 11s after.
+-}
+
+
-- | Given a located import declaration @decl@ from @this_mod@,
-- calculate the following pieces of information:
@@ -204,7 +265,9 @@ rnImports imports = do
rnImportDecl :: Module -> LImportDecl GhcPs
-> RnM (LImportDecl GhcRn, GlobalRdrEnv, ImportAvails, AnyHpcUsage)
rnImportDecl this_mod
- (L loc decl@(ImportDecl { ideclName = loc_imp_mod_name, ideclPkgQual = mb_pkg
+ (L loc decl@(ImportDecl { ideclExt = noExt
+ , ideclName = loc_imp_mod_name
+ , ideclPkgQual = mb_pkg
, ideclSource = want_boot, ideclSafe = mod_safe
, ideclQualified = qual_only, ideclImplicit = implicit
, ideclAs = as_mod, ideclHiding = imp_details }))
@@ -313,10 +376,11 @@ rnImportDecl this_mod
_ -> return ()
)
- let new_imp_decl = L loc (decl { ideclSafe = mod_safe'
+ let new_imp_decl = L loc (decl { ideclExt = noExt, ideclSafe = mod_safe'
, ideclHiding = new_imp_details })
return (new_imp_decl, gbl_env, imports, mi_hpc iface)
+rnImportDecl _ (L _ (XImportDecl _)) = panic "rnImportDecl"
-- | Calculate the 'ImportAvails' induced by an import of a particular
-- interface, but without 'imp_mods'.
@@ -499,7 +563,7 @@ extendGlobalRdrEnvRn avails new_fixities
; rdr_env2 <- foldlM add_gre rdr_env1 new_gres
- ; let fix_env' = foldl extend_fix_env fix_env new_gres
+ ; let fix_env' = foldl' extend_fix_env fix_env new_gres
gbl_env' = gbl_env { tcg_rdr_env = rdr_env2, tcg_fix_env = fix_env' }
; traceRn "extendGlobalRdrEnvRn 2" (pprGlobalRdrEnv True rdr_env2)
@@ -602,7 +666,7 @@ getLocalNonValBinders fixity_env
; traceRn "getLocalNonValBinders 3" (vcat [ppr flds, ppr field_env])
; return (envs, new_bndrs) } }
where
- ValBindsIn _val_binds val_sigs = binds
+ ValBinds _ _val_binds val_sigs = binds
for_hs_bndrs :: [Located RdrName]
for_hs_bndrs = hsForeignDeclsBinders foreign_decls
@@ -610,7 +674,7 @@ getLocalNonValBinders fixity_env
-- In a hs-boot file, the value binders come from the
-- *signatures*, and there should be no foreign binders
hs_boot_sig_bndrs = [ L decl_loc (unLoc n)
- | L decl_loc (TypeSig ns _) <- val_sigs, n <- ns]
+ | L decl_loc (TypeSig _ ns _) <- val_sigs, n <- ns]
-- the SrcSpan attached to the input should be the span of the
-- declaration, not just the name
@@ -637,24 +701,16 @@ getLocalNonValBinders fixity_env
-> [(Name, [FieldLabel])]
mk_fld_env d names flds = concatMap find_con_flds (dd_cons d)
where
- find_con_flds (L _ (ConDeclH98 { con_name = L _ rdr
- , con_details = RecCon cdflds }))
+ find_con_flds (L _ (ConDeclH98 { con_name = L _ rdr
+ , con_args = RecCon cdflds }))
= [( find_con_name rdr
, concatMap find_con_decl_flds (unLoc cdflds) )]
- find_con_flds (L _ (ConDeclGADT
- { con_names = rdrs
- , con_type = (HsIB { hsib_body = res_ty})}))
- = map (\ (L _ rdr) -> ( find_con_name rdr
- , concatMap find_con_decl_flds cdflds))
- rdrs
- where
- (_tvs, _cxt, tau) = splitLHsSigmaTy res_ty
- cdflds = case tau of
- L _ (HsFunTy
- (L _ (HsAppsTy
- [L _ (HsAppPrefix (L _ (HsRecTy flds)))])) _) -> flds
- L _ (HsFunTy (L _ (HsRecTy flds)) _) -> flds
- _ -> []
+ find_con_flds (L _ (ConDeclGADT { con_names = rdrs
+ , con_args = RecCon flds }))
+ = [ ( find_con_name rdr
+ , concatMap find_con_decl_flds (unLoc flds))
+ | L _ rdr <- rdrs ]
+
find_con_flds _ = []
find_con_name rdr
@@ -662,20 +718,22 @@ getLocalNonValBinders fixity_env
find (\ n -> nameOccName n == rdrNameOcc rdr) names
find_con_decl_flds (L _ x)
= map find_con_decl_fld (cd_fld_names x)
- find_con_decl_fld (L _ (FieldOcc (L _ rdr) _))
+
+ find_con_decl_fld (L _ (FieldOcc _ (L _ rdr)))
= expectJust "getLocalNonValBinders/find_con_decl_fld" $
find (\ fl -> flLabel fl == lbl) flds
where lbl = occNameFS (rdrNameOcc rdr)
+ find_con_decl_fld (L _ (XFieldOcc _)) = panic "getLocalNonValBinders"
new_assoc :: Bool -> LInstDecl GhcPs
-> RnM ([AvailInfo], [(Name, [FieldLabel])])
new_assoc _ (L _ (TyFamInstD {})) = return ([], [])
-- type instances don't bind new names
- new_assoc overload_ok (L _ (DataFamInstD d))
+ new_assoc overload_ok (L _ (DataFamInstD _ d))
= do { (avail, flds) <- new_di overload_ok Nothing d
; return ([avail], flds) }
- new_assoc overload_ok (L _ (ClsInstD (ClsInstDecl { cid_poly_ty = inst_ty
+ new_assoc overload_ok (L _ (ClsInstD _ (ClsInstDecl { cid_poly_ty = inst_ty
, cid_datafam_insts = adts })))
| Just (L loc cls_rdr) <- getLHsInstDeclClass_maybe inst_ty
= do { cls_nm <- setSrcSpan loc $ lookupGlobalOccRn cls_rdr
@@ -685,26 +743,32 @@ getLocalNonValBinders fixity_env
| otherwise
= return ([], []) -- Do not crash on ill-formed instances
-- Eg instance !Show Int Trac #3811c
+ new_assoc _ (L _ (ClsInstD _ (XClsInstDecl _))) = panic "new_assoc"
+ new_assoc _ (L _ (XInstDecl _)) = panic "new_assoc"
new_di :: Bool -> Maybe Name -> DataFamInstDecl GhcPs
-> RnM (AvailInfo, [(Name, [FieldLabel])])
- new_di overload_ok mb_cls ti_decl
- = do { main_name <- lookupFamInstName mb_cls (dfid_tycon ti_decl)
- ; let (bndrs, flds) = hsDataFamInstBinders ti_decl
+ new_di overload_ok mb_cls dfid@(DataFamInstDecl { dfid_eqn =
+ HsIB { hsib_body = ti_decl }})
+ = do { main_name <- lookupFamInstName mb_cls (feqn_tycon ti_decl)
+ ; let (bndrs, flds) = hsDataFamInstBinders dfid
; sub_names <- mapM newTopSrcBinder bndrs
; flds' <- mapM (newRecordSelector overload_ok sub_names) flds
; let avail = AvailTC (unLoc main_name) sub_names flds'
-- main_name is not bound here!
- fld_env = mk_fld_env (dfid_defn ti_decl) sub_names flds'
+ fld_env = mk_fld_env (feqn_rhs ti_decl) sub_names flds'
; return (avail, fld_env) }
+ new_di _ _ (DataFamInstDecl (XHsImplicitBndrs _)) = panic "new_di"
new_loc_di :: Bool -> Maybe Name -> LDataFamInstDecl GhcPs
-> RnM (AvailInfo, [(Name, [FieldLabel])])
new_loc_di overload_ok mb_cls (L _ d) = new_di overload_ok mb_cls d
+getLocalNonValBinders _ (XHsGroup _) = panic "getLocalNonValBinders"
newRecordSelector :: Bool -> [Name] -> LFieldOcc GhcPs -> RnM FieldLabel
newRecordSelector _ [] _ = error "newRecordSelector: datatype has no constructors!"
-newRecordSelector overload_ok (dc:_) (L loc (FieldOcc (L _ fld) _))
+newRecordSelector _ _ (L _ (XFieldOcc _)) = panic "newRecordSelector"
+newRecordSelector overload_ok (dc:_) (L loc (FieldOcc _ (L _ fld)))
= do { selName <- newTopSrcBinder $ L loc $ field
; return $ qualFieldLbl { flSelector = selName } }
where
@@ -803,7 +867,7 @@ filterImports iface decl_spec (Just (want_hiding, L l import_items))
-- NB the AvailInfo may have duplicates, and several items
-- for the same parent; e.g N(x) and N(y)
- names = availsToNameSet (map snd items2)
+ names = availsToNameSetWithSelectors (map snd items2)
keep n = not (n `elemNameSet` names)
pruned_avails = filterAvails keep all_avails
hiding_spec = ImpSpec { is_decl = decl_spec, is_item = ImpAll }
@@ -819,8 +883,9 @@ filterImports iface decl_spec (Just (want_hiding, L l import_items))
imp_occ_env :: OccEnv (Name, -- the name
AvailInfo, -- the export item providing the name
Maybe Name) -- the parent of associated types
- imp_occ_env = mkOccEnv_C combine [ (nameOccName n, (n, a, Nothing))
- | a <- all_avails, n <- availNames a]
+ imp_occ_env = mkOccEnv_C combine [ (occ, (n, a, Nothing))
+ | a <- all_avails
+ , (n, occ) <- availNamesWithOccs a]
where
-- See Note [Dealing with imports]
-- 'combine' is only called for associated data types which appear
@@ -835,10 +900,11 @@ filterImports iface decl_spec (Just (want_hiding, L l import_items))
else (name1, a2, Just p1)
combine x y = pprPanic "filterImports/combine" (ppr x $$ ppr y)
- lookup_name :: RdrName -> IELookupM (Name, AvailInfo, Maybe Name)
- lookup_name rdr | isQual rdr = failLookupWith (QualImportError rdr)
- | Just succ <- mb_success = return succ
- | otherwise = failLookupWith BadImport
+ lookup_name :: IE GhcPs -> RdrName -> IELookupM (Name, AvailInfo, Maybe Name)
+ lookup_name ie rdr
+ | isQual rdr = failLookupWith (QualImportError rdr)
+ | Just succ <- mb_success = return succ
+ | otherwise = failLookupWith (BadImport ie)
where
mb_success = lookupOccEnv imp_occ_env (rdrNameOcc rdr)
@@ -855,8 +921,8 @@ filterImports iface decl_spec (Just (want_hiding, L l import_items))
addWarn (Reason Opt_WarnDodgyImports) (dodgyImportWarn n)
emit_warning MissingImportList = whenWOptM Opt_WarnMissingImportList $
addWarn (Reason Opt_WarnMissingImportList) (missingImportListItem ieRdr)
- emit_warning BadImportW = whenWOptM Opt_WarnDodgyImports $
- addWarn (Reason Opt_WarnDodgyImports) (lookup_err_msg BadImport)
+ emit_warning (BadImportW ie) = whenWOptM Opt_WarnDodgyImports $
+ addWarn (Reason Opt_WarnDodgyImports) (lookup_err_msg (BadImport ie))
run_lookup :: IELookupM a -> TcRn (Maybe a)
run_lookup m = case m of
@@ -864,7 +930,7 @@ filterImports iface decl_spec (Just (want_hiding, L l import_items))
Succeeded a -> return (Just a)
lookup_err_msg err = case err of
- BadImport -> badImportItemErr iface decl_spec ieRdr all_avails
+ BadImport ie -> badImportItemErr iface decl_spec ie all_avails
IllegalImport -> illegalImportItemErr
QualImportError rdr -> qualImportItemErr rdr
@@ -882,13 +948,13 @@ filterImports iface decl_spec (Just (want_hiding, L l import_items))
-> IELookupM ([(IE GhcRn, AvailInfo)], [IELookupWarning])
lookup_ie ie = handle_bad_import $ do
case ie of
- IEVar (L l n) -> do
- (name, avail, _) <- lookup_name $ ieWrappedName n
- return ([(IEVar (L l (replaceWrappedName n name)),
+ IEVar _ (L l n) -> do
+ (name, avail, _) <- lookup_name ie $ ieWrappedName n
+ return ([(IEVar noExt (L l (replaceWrappedName n name)),
trimAvail avail name)], [])
- IEThingAll (L l tc) -> do
- (name, avail, mb_parent) <- lookup_name $ ieWrappedName tc
+ IEThingAll _ (L l tc) -> do
+ (name, avail, mb_parent) <- lookup_name ie $ ieWrappedName tc
let warns = case avail of
Avail {} -- e.g. f(..)
-> [DodgyImport $ ieWrappedName tc]
@@ -903,7 +969,7 @@ filterImports iface decl_spec (Just (want_hiding, L l import_items))
| otherwise
-> []
- renamed_ie = IEThingAll (L l (replaceWrappedName tc name))
+ renamed_ie = IEThingAll noExt (L l (replaceWrappedName tc name))
sub_avails = case avail of
Avail {} -> []
AvailTC name2 subs fs -> [(renamed_ie, AvailTC name2 (subs \\ [name]) fs)]
@@ -913,26 +979,30 @@ filterImports iface decl_spec (Just (want_hiding, L l import_items))
Just parent -> return ((renamed_ie, AvailTC parent [name] []) : sub_avails, warns)
-- associated type
- IEThingAbs (L l tc')
+ IEThingAbs _ (L l tc')
| want_hiding -- hiding ( C )
-- Here the 'C' can be a data constructor
-- *or* a type/class, or even both
-> let tc = ieWrappedName tc'
- tc_name = lookup_name tc
- dc_name = lookup_name (setRdrNameSpace tc srcDataName)
+ tc_name = lookup_name ie tc
+ dc_name = lookup_name ie (setRdrNameSpace tc srcDataName)
in
case catIELookupM [ tc_name, dc_name ] of
- [] -> failLookupWith BadImport
+ [] -> failLookupWith (BadImport ie)
names -> return ([mkIEThingAbs tc' l name | name <- names], [])
| otherwise
- -> do nameAvail <- lookup_name (ieWrappedName tc')
+ -> do nameAvail <- lookup_name ie (ieWrappedName tc')
return ([mkIEThingAbs tc' l nameAvail]
, [])
- IEThingWith (L l rdr_tc) wc rdr_ns' rdr_fs ->
+ IEThingWith xt ltc@(L l rdr_tc) wc rdr_ns rdr_fs ->
ASSERT2(null rdr_fs, ppr rdr_fs) do
- (name, AvailTC _ ns subflds, mb_parent)
- <- lookup_name (ieWrappedName rdr_tc)
+ (name, avail, mb_parent)
+ <- lookup_name (IEThingAbs noExt ltc) (ieWrappedName rdr_tc)
+
+ let (ns,subflds) = case avail of
+ AvailTC _ ns' subflds' -> (ns',subflds')
+ Avail _ -> panic "filterImports"
-- Look up the children in the sub-names of the parent
let subnames = case ns of -- The tc is first in ns,
@@ -940,15 +1010,20 @@ filterImports iface decl_spec (Just (want_hiding, L l import_items))
-- See the AvailTC Invariant in Avail.hs
(n1:ns1) | n1 == name -> ns1
| otherwise -> ns
- rdr_ns = map ieLWrappedName rdr_ns'
case lookupChildren (map Left subnames ++ map Right subflds) rdr_ns of
- Nothing -> failLookupWith BadImport
- Just (childnames, childflds) ->
+
+ Failed rdrs -> failLookupWith (BadImport (IEThingWith xt ltc wc rdrs []))
+ -- We are trying to import T( a,b,c,d ), and failed
+ -- to find 'b' and 'd'. So we make up an import item
+ -- to report as failing, namely T( b, d ).
+ -- c.f. Trac #15412
+
+ Succeeded (childnames, childflds) ->
case mb_parent of
-- non-associated ty/cls
Nothing
- -> return ([(IEThingWith (L l name') wc childnames'
- childflds,
+ -> return ([(IEThingWith noExt (L l name') wc childnames'
+ childflds,
AvailTC name (name:map unLoc childnames) (map unLoc childflds))],
[])
where name' = replaceWrappedName rdr_tc name
@@ -956,10 +1031,10 @@ filterImports iface decl_spec (Just (want_hiding, L l import_items))
-- childnames' = postrn_ies childnames
-- associated ty
Just parent
- -> return ([(IEThingWith (L l name') wc childnames'
+ -> return ([(IEThingWith noExt (L l name') wc childnames'
childflds,
AvailTC name (map unLoc childnames) (map unLoc childflds)),
- (IEThingWith (L l name') wc childnames'
+ (IEThingWith noExt (L l name') wc childnames'
childflds,
AvailTC parent [name] [])],
[])
@@ -972,25 +1047,26 @@ filterImports iface decl_spec (Just (want_hiding, L l import_items))
where
mkIEThingAbs tc l (n, av, Nothing )
- = (IEThingAbs (L l (replaceWrappedName tc n)), trimAvail av n)
+ = (IEThingAbs noExt (L l (replaceWrappedName tc n)), trimAvail av n)
mkIEThingAbs tc l (n, _, Just parent)
- = (IEThingAbs (L l (replaceWrappedName tc n)), AvailTC parent [n] [])
+ = (IEThingAbs noExt (L l (replaceWrappedName tc n))
+ , AvailTC parent [n] [])
handle_bad_import m = catchIELookup m $ \err -> case err of
- BadImport | want_hiding -> return ([], [BadImportW])
- _ -> failLookupWith err
+ BadImport ie | want_hiding -> return ([], [BadImportW ie])
+ _ -> failLookupWith err
type IELookupM = MaybeErr IELookupError
data IELookupWarning
- = BadImportW
+ = BadImportW (IE GhcPs)
| MissingImportList
| DodgyImport RdrName
-- NB. use the RdrName for reporting a "dodgy" import
data IELookupError
= QualImportError RdrName
- | BadImport
+ | BadImport (IE GhcPs)
| IllegalImport
failLookupWith :: IELookupError -> IELookupM a
@@ -1018,8 +1094,8 @@ gresFromIE decl_spec (L loc ie, avail)
= gresFromAvail prov_fn avail
where
is_explicit = case ie of
- IEThingAll (L _ name) -> \n -> n == ieWrappedName name
- _ -> \_ -> True
+ IEThingAll _ (L _ name) -> \n -> n == ieWrappedName name
+ _ -> \_ -> True
prov_fn name
= Just (ImpSpec { is_decl = decl_spec, is_item = item_spec })
where
@@ -1053,8 +1129,9 @@ mkChildEnv gres = foldr add emptyNameEnv gres
findChildren :: NameEnv [a] -> Name -> [a]
findChildren env n = lookupNameEnv env n `orElse` []
-lookupChildren :: [Either Name FieldLabel] -> [Located RdrName]
- -> Maybe ([Located Name], [Located FieldLabel])
+lookupChildren :: [Either Name FieldLabel] -> [LIEWrappedName RdrName]
+ -> MaybeErr [LIEWrappedName RdrName] -- The ones for which the lookup failed
+ ([Located Name], [Located FieldLabel])
-- (lookupChildren all_kids rdr_items) maps each rdr_item to its
-- corresponding Name all_kids, if the former exists
-- The matching is done by FastString, not OccName, so that
@@ -1063,17 +1140,27 @@ lookupChildren :: [Either Name FieldLabel] -> [Located RdrName]
-- the RdrName for AssocTy may have a (bogus) DataName namespace
-- (Really the rdr_items should be FastStrings in the first place.)
lookupChildren all_kids rdr_items
- = do xs <- mapM doOne rdr_items
- return (fmap concat (partitionEithers xs))
+ | null fails
+ = Succeeded (fmap concat (partitionEithers oks))
+ -- This 'fmap concat' trickily applies concat to the /second/ component
+ -- of the pair, whose type is ([Located Name], [[Located FieldLabel]])
+ | otherwise
+ = Failed fails
where
- doOne (L l r) = case (lookupFsEnv kid_env . occNameFS . rdrNameOcc) r of
- Just [Left n] -> Just (Left (L l n))
- Just rs | all isRight rs -> Just (Right (map (L l) (rights rs)))
- _ -> Nothing
+ mb_xs = map doOne rdr_items
+ fails = [ bad_rdr | Failed bad_rdr <- mb_xs ]
+ oks = [ ok | Succeeded ok <- mb_xs ]
+ oks :: [Either (Located Name) [Located FieldLabel]]
+
+ doOne item@(L l r)
+ = case (lookupFsEnv kid_env . occNameFS . rdrNameOcc . ieWrappedName) r of
+ Just [Left n] -> Succeeded (Left (L l n))
+ Just rs | all isRight rs -> Succeeded (Right (map (L l) (rights rs)))
+ _ -> Failed item
-- See Note [Children for duplicate record fields]
kid_env = extendFsEnvList_C (++) emptyFsEnv
- [(either (occNameFS . nameOccName) flLabel x, [x]) | x <- all_kids]
+ [(either (occNameFS . nameOccName) flLabel x, [x]) | x <- all_kids]
@@ -1181,7 +1268,7 @@ warnMissingSignatures gbl_env
pat_syns = tcg_patsyns gbl_env
-- Warn about missing signatures
- -- Do this only when we we have a type to offer
+ -- Do this only when we have a type to offer
; warn_missing_sigs <- woptM Opt_WarnMissingSignatures
; warn_only_exported <- woptM Opt_WarnMissingExportedSignatures
; warn_pat_syns <- woptM Opt_WarnMissingPatternSynonymSignatures
@@ -1275,13 +1362,13 @@ findImportUsage imports used_gres
_other -> emptyNameSet -- No explicit import list => no unused-name list
add_unused :: IE GhcRn -> NameSet -> NameSet
- add_unused (IEVar (L _ n)) acc
+ add_unused (IEVar _ (L _ n)) acc
= add_unused_name (ieWrappedName n) acc
- add_unused (IEThingAbs (L _ n)) acc
+ add_unused (IEThingAbs _ (L _ n)) acc
= add_unused_name (ieWrappedName n) acc
- add_unused (IEThingAll (L _ n)) acc
+ add_unused (IEThingAll _ (L _ n)) acc
= add_unused_all (ieWrappedName n) acc
- add_unused (IEThingWith (L _ p) wc ns fs) acc =
+ add_unused (IEThingWith _ (L _ p) wc ns fs) acc =
add_wc_all (add_unused_with (ieWrappedName p) xs acc)
where xs = map (ieWrappedName . unLoc) ns
++ map (flSelector . unLoc) fs
@@ -1305,6 +1392,7 @@ findImportUsage imports used_gres
-- If you use 'signum' from Num, then the user may well have
-- imported Num(signum). We don't want to complain that
-- Num is not itself mentioned. Hence the two cases in add_unused_with.
+ unused_decl (L _ (XImportDecl _)) = panic "unused_decl"
extendImportMap :: GlobalRdrElt -> ImportMap -> ImportMap
-- For each of a list of used GREs, find all the import decls that brought
@@ -1350,9 +1438,12 @@ warnUnusedImport flag fld_env (L loc decl, used, unused)
pp_mod = ppr (unLoc (ideclName decl))
pp_not_used = text "is redundant"
+ -- In warning message, pretty-print identifiers unqualified unconditionally
+ -- to improve the consistent for ambiguous/unambiguous identifiers.
+ -- See trac#14881.
ppr_possible_field n = case lookupNameEnv fld_env n of
- Just (fld, p) -> ppr p <> parens (ppr fld)
- Nothing -> ppr n
+ Just (fld, p) -> pprNameUnqualified p <> parens (ppr fld)
+ Nothing -> pprNameUnqualified n
-- Print unused names in a deterministic (lexicographic) order
sort_unused = pprWithCommas ppr_possible_field $
@@ -1381,28 +1472,9 @@ decls, and simply trim their import lists. NB that
from it. Instead we just trim to an empty import list
-}
-printMinimalImports :: [ImportDeclUsage] -> RnM ()
--- See Note [Printing minimal imports]
-printMinimalImports imports_w_usage
- = do { imports' <- mapM mk_minimal imports_w_usage
- ; this_mod <- getModule
- ; dflags <- getDynFlags
- ; liftIO $
- do { h <- openFile (mkFilename dflags this_mod) WriteMode
- ; printForUser dflags h neverQualify (vcat (map ppr imports')) }
- -- The neverQualify is important. We are printing Names
- -- but they are in the context of an 'import' decl, and
- -- we never qualify things inside there
- -- E.g. import Blag( f, b )
- -- not import Blag( Blag.f, Blag.g )!
- }
+getMinimalImports :: [ImportDeclUsage] -> RnM [LImportDecl GhcRn]
+getMinimalImports = mapM mk_minimal
where
- mkFilename dflags this_mod
- | Just d <- dumpDir dflags = d </> basefn
- | otherwise = basefn
- where
- basefn = moduleNameString (moduleName this_mod) ++ ".imports"
-
mk_minimal (L l decl, used, unused)
| null unused
, Just (False, _) <- ideclHiding decl
@@ -1422,25 +1494,25 @@ 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 (to_ie_post_rn $ noLoc n)]
+ = [IEVar noExt (to_ie_post_rn $ noLoc n)]
to_ie _ (AvailTC n [m] [])
- | n==m = [IEThingAbs (to_ie_post_rn $ noLoc n)]
+ | n==m = [IEThingAbs noExt (to_ie_post_rn $ noLoc n)]
to_ie iface (AvailTC n ns fs)
= case [(xs,gs) | AvailTC x xs gs <- mi_exports iface
, x == n
, x `elem` xs -- Note [Partial export]
] of
- [xs] | all_used xs -> [IEThingAll (to_ie_post_rn $ noLoc n)]
+ [xs] | all_used xs -> [IEThingAll noExt (to_ie_post_rn $ noLoc n)]
| otherwise ->
- [IEThingWith (to_ie_post_rn $ noLoc n) NoIEWildcard
+ [IEThingWith noExt (to_ie_post_rn $ noLoc n) NoIEWildcard
(map (to_ie_post_rn . noLoc) (filter (/= n) ns))
(map noLoc fs)]
-- Note [Overloaded field import]
_other | all_non_overloaded fs
- -> map (IEVar . to_ie_post_rn_var . noLoc) $ ns
+ -> map (IEVar noExt . to_ie_post_rn_var . noLoc) $ ns
++ map flSelector fs
| otherwise ->
- [IEThingWith (to_ie_post_rn $ noLoc n) NoIEWildcard
+ [IEThingWith noExt (to_ie_post_rn $ noLoc n) NoIEWildcard
(map (to_ie_post_rn . noLoc) (filter (/= n) ns))
(map noLoc fs)]
where
@@ -1453,6 +1525,29 @@ printMinimalImports imports_w_usage
all_non_overloaded = all (not . flIsOverloaded)
+printMinimalImports :: [ImportDeclUsage] -> RnM ()
+-- See Note [Printing minimal imports]
+printMinimalImports imports_w_usage
+ = do { imports' <- getMinimalImports imports_w_usage
+ ; this_mod <- getModule
+ ; dflags <- getDynFlags
+ ; liftIO $
+ do { h <- openFile (mkFilename dflags this_mod) WriteMode
+ ; printForUser dflags h neverQualify (vcat (map ppr imports')) }
+ -- The neverQualify is important. We are printing Names
+ -- but they are in the context of an 'import' decl, and
+ -- we never qualify things inside there
+ -- E.g. import Blag( f, b )
+ -- not import Blag( Blag.f, Blag.g )!
+ }
+ where
+ mkFilename dflags this_mod
+ | Just d <- dumpDir dflags = d </> basefn
+ | otherwise = basefn
+ where
+ basefn = moduleNameString (moduleName this_mod) ++ ".imports"
+
+
to_ie_post_rn_var :: (HasOccName name) => Located name -> LIEWrappedName name
to_ie_post_rn_var (L l n)
| isDataOcc $ occName n = L l (IEPattern (L l n))
@@ -1581,10 +1676,10 @@ dodgyMsg kind tc ie
quotes (ppr tc) <+> text "has (in-scope) constructors or class methods,",
text "but it has none" ]
-dodgyMsgInsert :: forall p . IdP p -> IE p
-dodgyMsgInsert tc = IEThingAll ii
+dodgyMsgInsert :: forall p . IdP (GhcPass p) -> IE (GhcPass p)
+dodgyMsgInsert tc = IEThingAll noExt ii
where
- ii :: LIEWrappedName (IdP p)
+ ii :: LIEWrappedName (IdP (GhcPass p))
ii = noLoc (IEName $ noLoc tc)