diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2020-07-23 12:57:10 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-07-30 07:12:52 -0400 |
commit | ebe2cf4538fa46994ef67663ac8fd5e579579803 (patch) | |
tree | b38f3979c3cc44b68d9fde3b94ef5a70579ad43a | |
parent | d47324ce49b0c4f419823cbd7fd47e134a1b255a (diff) | |
download | haskell-ebe2cf4538fa46994ef67663ac8fd5e579579803.tar.gz |
Remove an incorrect WARN in extendLocalRdrEnv
I noticed this warning going off, and discovered that it's
really fine. This small patch removes the warning, and docments
what is going on.
-rw-r--r-- | compiler/GHC/Rename/Pat.hs | 29 | ||||
-rw-r--r-- | compiler/GHC/Types/Name/Reader.hs | 32 |
2 files changed, 41 insertions, 20 deletions
diff --git a/compiler/GHC/Rename/Pat.hs b/compiler/GHC/Rename/Pat.hs index 09e2ea8cbe..06a1036b5c 100644 --- a/compiler/GHC/Rename/Pat.hs +++ b/compiler/GHC/Rename/Pat.hs @@ -236,19 +236,30 @@ newPatName (LetMk is_top fix_env) rdr_name do { name <- case is_top of NotTopLevel -> newLocalBndrRn rdr_name TopLevel -> newTopSrcBinder rdr_name - ; bindLocalNames [name] $ -- Do *not* use bindLocalNameFV here - -- See Note [View pattern usage] + ; bindLocalNames [name] $ + -- Do *not* use bindLocalNameFV here; + -- see Note [View pattern usage] + -- For the TopLevel case + -- see Note [bindLocalNames for an External name] addLocalFixities fix_env [name] $ thing_inside name }) - -- Note: the bindLocalNames is somewhat suspicious - -- because it binds a top-level name as a local name. - -- however, this binding seems to work, and it only exists for - -- the duration of the patterns and the continuation; - -- then the top-level name is added to the global env - -- before going on to the RHSes (see GHC.Rename.Module). +{- Note [bindLocalNames for an External name] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In the TopLevel case, the use of bindLocalNames here is somewhat +suspicious because it binds a top-level External name in the +LocalRdrEnv. c.f. Note [LocalRdrEnv] in GHC.Types.Name.Reader. + +However, this only happens when renaming the LHS (only) of a top-level +pattern binding. Even though this only the LHS, we need to bring the +binder into scope in the pattern itself in case the binder is used in +subsequent view patterns. A bit bizarre, something like + (x, Just y <- f x) = e + +Anyway, bindLocalNames does work, and the binding only exists for the +duration of the pattern; then the top-level name is added to the +global env before going on to the RHSes (see GHC.Rename.Module). -{- Note [View pattern usage] ~~~~~~~~~~~~~~~~~~~~~~~~~ Consider diff --git a/compiler/GHC/Types/Name/Reader.hs b/compiler/GHC/Types/Name/Reader.hs index b6f4bbce44..32b59eaa30 100644 --- a/compiler/GHC/Types/Name/Reader.hs +++ b/compiler/GHC/Types/Name/Reader.hs @@ -338,13 +338,24 @@ instance Ord RdrName where ************************************************************************ -} +{- Note [LocalRdrEnv] +~~~~~~~~~~~~~~~~~~~~~ +The LocalRdrEnv is used to store local bindings (let, where, lambda, case). + +* It is keyed by OccName, because we never use it for qualified names. + +* It maps the OccName to a Name. That Name is almost always an + Internal Name, but (hackily) it can be External too for top-level + pattern bindings. See Note [bindLocalNames for an External name] + in GHC.Rename.Pat + +* We keep the current mapping (lre_env), *and* the set of all Names in + scope (lre_in_scope). Reason: see Note [Splicing Exact names] in + GHC.Rename.Env. +-} + -- | Local Reader Environment --- --- This environment is used to store local bindings --- (@let@, @where@, lambda, @case@). --- It is keyed by OccName, because we never use it for qualified names --- We keep the current mapping, *and* the set of all Names in scope --- Reason: see Note [Splicing Exact names] in "GHC.Rename.Env" +-- See Note [LocalRdrEnv] data LocalRdrEnv = LRE { lre_env :: OccEnv Name , lre_in_scope :: NameSet } @@ -364,16 +375,15 @@ emptyLocalRdrEnv = LRE { lre_env = emptyOccEnv , lre_in_scope = emptyNameSet } extendLocalRdrEnv :: LocalRdrEnv -> Name -> LocalRdrEnv --- The Name should be a non-top-level thing +-- See Note [LocalRdrEnv] extendLocalRdrEnv lre@(LRE { lre_env = env, lre_in_scope = ns }) name - = WARN( isExternalName name, ppr name ) - lre { lre_env = extendOccEnv env (nameOccName name) name + = lre { lre_env = extendOccEnv env (nameOccName name) name , lre_in_scope = extendNameSet ns name } extendLocalRdrEnvList :: LocalRdrEnv -> [Name] -> LocalRdrEnv +-- See Note [LocalRdrEnv] extendLocalRdrEnvList lre@(LRE { lre_env = env, lre_in_scope = ns }) names - = WARN( any isExternalName names, ppr names ) - lre { lre_env = extendOccEnvList env [(nameOccName n, n) | n <- names] + = lre { lre_env = extendOccEnvList env [(nameOccName n, n) | n <- names] , lre_in_scope = extendNameSetList ns names } lookupLocalRdrEnv :: LocalRdrEnv -> RdrName -> Maybe Name |