From fa9f19cc68a3bb52bd0ac3a21225a486f4cd2beb Mon Sep 17 00:00:00 2001 From: simonpj Date: Thu, 28 Jan 1999 14:22:17 +0000 Subject: [PATCH] [project @ 1999-01-28 14:22:15 by simonpj] Fix erroneous name-clash report when a module ends up importing itself (eg TcEnv) --- ghc/compiler/rename/RnEnv.lhs | 20 ++++++++++++-------- ghc/compiler/rename/RnIfaces.lhs | 31 +++++++++++++++++++++++++++---- ghc/compiler/rename/RnNames.lhs | 1 + 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/ghc/compiler/rename/RnEnv.lhs b/ghc/compiler/rename/RnEnv.lhs index ca8d876..ebe6af2 100644 --- a/ghc/compiler/rename/RnEnv.lhs +++ b/ghc/compiler/rename/RnEnv.lhs @@ -462,8 +462,8 @@ combine_globals :: [Name] -- Old combine_globals ns_old ns_new -- ns_new is often short = foldr add ns_old ns_new where - add n ns | all (no_conflict n) ns_old = map choose ns -- Eliminate duplicates - | otherwise = n:ns + add n ns | any (is_duplicate n) ns_old = map choose ns -- Eliminate duplicates + | otherwise = n:ns where choose n' | n==n' && better_provenance n n' = n | otherwise = n' @@ -479,12 +479,16 @@ better_provenance n1 n2 (NonLocalDef (UserImport _ _ _ ) _, NonLocalDef ImplicitImport _) -> True other -> False -no_conflict :: Name -> Name -> Bool -no_conflict n1 n2 | isLocallyDefined n1 && isLocallyDefined n2 = False - | otherwise = n1 == n2 - -- We complain of a conflict if one RdrName maps to two different Names, - -- OR if one RdrName maps to the same *locally-defined* Name. The latter - -- case is to catch two separate, local definitions of the same thing. +is_duplicate :: Name -> Name -> Bool +is_duplicate n1 n2 | isLocallyDefined n1 && isLocallyDefined n2 = False + | otherwise = n1 == n2 + -- We treat two bindings of a locally-defined name as a duplicate, + -- because they might be two separate, local defns and we want to report + -- and error for that, *not* eliminate a duplicate. + + -- On the other hand, if you import the same name from two different + -- import statements, we *do* want to eliminate the duplicate, not report + -- an error. -- -- If a module imports itself then there might be a local defn and an imported -- defn of the same name; in this case the names will compare as equal, but diff --git a/ghc/compiler/rename/RnIfaces.lhs b/ghc/compiler/rename/RnIfaces.lhs index 0407764..5010eed 100644 --- a/ghc/compiler/rename/RnIfaces.lhs +++ b/ghc/compiler/rename/RnIfaces.lhs @@ -203,16 +203,21 @@ loadInterface doc_str load_mod -- LOAD IT INTO Ifaces -- First set the module - setModuleRn load_mod $ -- NB: *first* we do loadDecl, so that the provenance of all the locally-defined --- names is done correctly (notably, whether this is an .hi file or .hi-boot file). -- If we do loadExport first the wrong info gets into the cache (unless we -- explicitly tag each export which seems a bit of a bore) + + getModuleRn `thenRn` \ this_mod -> + setModuleRn load_mod $ -- First set the module name of the module being loaded, + -- so that unqualified occurrences in the interface file + -- get the right qualifer foldlRn loadDecl (iDecls ifaces) rd_decls `thenRn` \ new_decls -> foldlRn loadFixDecl (iFixes ifaces) rd_decls `thenRn` \ new_fixities -> - mapRn loadExport exports `thenRn` \ avails_s -> foldlRn loadInstDecl insts rd_insts `thenRn` \ new_insts -> + + mapRn (loadExport this_mod) exports `thenRn` \ avails_s -> let mod_details = (new_hif, mod_vers, concat avails_s) @@ -229,8 +234,26 @@ loadInterface doc_str load_mod returnRn new_ifaces }} -loadExport :: ExportItem -> RnMG [AvailInfo] -loadExport (mod, entities) +loadExport :: Module -> ExportItem -> RnMG [AvailInfo] +loadExport this_mod (mod, entities) + | mod == this_mod = returnRn [] + -- If the module exports anything defined in this module, just ignore it. + -- Reason: otherwise it looks as if there are two local definition sites + -- for the thing, and an error gets reported. Easiest thing is just to + -- filter them out up front. This situation only arises if a module + -- imports itself, or another module that imported it. (Necessarily, + -- this invoves a loop.) Consequence: if you say + -- module A where + -- import B( AType ) + -- type AType = ... + -- + -- module B( AType ) where + -- import {-# SOURCE #-} A( AType ) + -- + -- then you'll get a 'B does not export AType' message. A bit bogus + -- but it's a bogus thing to do! + + | otherwise = mapRn load_entity entities where new_name occ = newImportedGlobalName mod occ diff --git a/ghc/compiler/rename/RnNames.lhs b/ghc/compiler/rename/RnNames.lhs index a0dbf46..926fd59 100644 --- a/ghc/compiler/rename/RnNames.lhs +++ b/ghc/compiler/rename/RnNames.lhs @@ -73,6 +73,7 @@ getGlobalNames (HsModule this_mod _ exports imports decls mod_loc) rec_unqual_fn = unQualInScope rec_rn_env in setOmitQualFn rec_unqual_fn $ + setModuleRn this_mod $ -- PROCESS LOCAL DECLS -- Do these *first* so that the correct provenance gets -- 1.7.10.4