From 6f60f1f541cafdb3bfdd71d48eb9dd7f0a708bda Mon Sep 17 00:00:00 2001 From: Simon Peyton Jones Date: Sat, 11 Jun 2011 14:19:44 +0100 Subject: [PATCH] Fix tracking of what RdrNames are used (fixes Trac #5211) The issue here was: what import declaration brings into scope the 'op here import qualified Foo( op ) import Bar( C(op) ) instance C Int where op = ... Well, the import of Bar, obviously. But what if the import Bar had been import Bar( C ) Then the instance is still supposed to work, getting op from the Foo.op imported from Foo. (I'm assuming its the same op, of course.) --- compiler/basicTypes/RdrName.lhs | 2 +- compiler/ghci/Debugger.hs | 1 - compiler/rename/RnEnv.lhs | 35 ++++++++++++++++++++++++++--------- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/compiler/basicTypes/RdrName.lhs b/compiler/basicTypes/RdrName.lhs index 355facd..3b19356 100644 --- a/compiler/basicTypes/RdrName.lhs +++ b/compiler/basicTypes/RdrName.lhs @@ -570,7 +570,7 @@ data Provenance -- INVARIANT: the list of 'ImportSpec' is non-empty data ImportSpec = ImpSpec { is_decl :: ImpDeclSpec, - is_item :: ImpItemSpec } + is_item :: ImpItemSpec } deriving( Eq, Ord ) -- | Describes a particular import declaration and is diff --git a/compiler/ghci/Debugger.hs b/compiler/ghci/Debugger.hs index 141a513..55ac4c0 100644 --- a/compiler/ghci/Debugger.hs +++ b/compiler/ghci/Debugger.hs @@ -24,7 +24,6 @@ import VarSet import UniqSupply import TcType import GHC -import InteractiveEval import Outputable import PprTyThing import MonadUtils diff --git a/compiler/rename/RnEnv.lhs b/compiler/rename/RnEnv.lhs index b333373..4492b52 100644 --- a/compiler/rename/RnEnv.lhs +++ b/compiler/rename/RnEnv.lhs @@ -288,7 +288,7 @@ lookupSubBndr parent doc rdr_name -- NB: lookupGlobalRdrEnv, not lookupGRE_RdrName! -- The latter does pickGREs, but we want to allow 'x' -- even if only 'M.x' is in scope - [gre] -> do { addUsedRdrNames (used_rdr_names gre) + [gre] -> do { addUsedRdrName gre (used_rdr_name gre) ; return (gre_name gre) } [] -> do { addErr (unknownSubordinateErr doc rdr_name) ; traceRn (text "RnEnv.lookup_sub_bndr" <+> (ppr rdr_name $$ ppr gres)) @@ -296,6 +296,8 @@ lookupSubBndr parent doc rdr_name gres -> do { addNameClashErrRn rdr_name gres ; return (gre_name (head gres)) } } where + rdr_occ = rdrNameOcc rdr_name + pick NoParent gres -- Normal lookup = pickGREs rdr_name gres pick (ParentIs p) gres -- Disambiguating lookup @@ -306,13 +308,20 @@ lookupSubBndr parent doc rdr_name right_parent _ _ = False -- Note [Usage for sub-bndrs] - used_rdr_names gre - | isQual rdr_name = [rdr_name] + used_rdr_name gre + | isQual rdr_name = rdr_name | otherwise = case gre_prov gre of - LocalDef -> [rdr_name] - Imported is -> map mk_qual_rdr is - mk_qual_rdr imp_spec = mkRdrQual (is_as (is_decl imp_spec)) rdr_occ - rdr_occ = rdrNameOcc rdr_name + LocalDef -> rdr_name + Imported is -> used_rdr_name_from_is is + + used_rdr_name_from_is imp_specs -- rdr_name is unqualified + | not (all (is_qual . is_decl) imp_specs) + = rdr_name -- An unqualified import is available + | otherwise + = -- Only qualified imports available, so make up + -- a suitable qualifed name from the first imp_spec + ASSERT( not (null imp_specs) ) + mkRdrQual (is_as (is_decl (head imp_specs))) rdr_occ newIPNameRn :: IPName RdrName -> TcRnIf m n (IPName Name) newIPNameRn ip_rdr = newIPName (mapIPName rdrNameOcc ip_rdr) @@ -334,13 +343,21 @@ Note [Usage for sub-bndrs] ~~~~~~~~~~~~~~~~~~~~~~~~~~ If you have this import qualified M( C( f ) ) - intance M.C T where + instance M.C T where f x = x then is the qualified import M.f used? Obviously yes. But the RdrName used in the instance decl is unqualified. In effect, we fill in the qualification by looking for f's whose class is M.C But when adding to the UsedRdrNames we must make that qualification -explicit, otherwise we get "Redundant import of M.C". +explicit (saying "used M.f"), otherwise we get "Redundant import of M.f". + +So we make up a suitable (fake) RdrName. But be careful + import qualifed M + import M( C(f) ) + instance C T where + f x = x +Here we want to record a use of 'f', not of 'M.f', otherwise +we'll miss the fact that the qualified import is redundant. -------------------------------------------------- -- Occurrences -- 1.7.10.4