[GHC] #16288: Core Lint error: Occurrence is GlobalId, but binding is LocalId

GHC ghc-devs at haskell.org
Wed Feb 6 23:28:01 UTC 2019


#16288: Core Lint error: Occurrence is GlobalId, but binding is LocalId
-------------------------------------+-------------------------------------
        Reporter:  monoidal          |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.7
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  Compile-time      |  Unknown/Multiple
  crash or panic                     |            Test Case:
      Blocked By:                    |             Blocking:  15840
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 OK I see what is happening.

 First, read `OccurAnal`
 * `Note [Binder swap]`
 * `Note [Binder swap on GlobalId scrutinees]`.  (This case happens in the
 program concerned, with scrutinee `pretV`.)

 The trouble is that the binder-swap, done by the occurrence analyser,
 transforms
 {{{
  case A.foo{r872} of bar {
    K x -> ...(A.foo{r872})...
  }

 ===>

   case A.foo{r872} of bar {
     K x -> let foo{r872} = bar
            in ...(A.foo{r872})...
 }}}
 where `A.foo{r872}` is a `GlobalId` with unique `r872`.  In the binder-
 swap we make a `LocalId` for `foo{r872}` ''with the same unique'', which
 deliberately shadows the global binding.  After the simplifer substitutes
 it out we'll get
 {{{
   case A.foo{r872} of bar {
     K x -> ...(bar)...
 }}}
 which is what we want.  Alas, the intermediate form does not satisfy
 Lint's rules, because a `GlobalId` occurrence is bound by a `LocalId`
 binding.  Mostly this does not show up, because we run the simplifier
 before linting.  But ''unfoldings'' are occurrence-analysed (so that they
 are all ready for inlining) so the linter sees the occurrence-analysed
 form and barfs.

 -----------
 What to do?  A quick fix is simply not to do the binder-swap when
 occurrence analysing unfoldings.  Replace the calls to `occurAnalyseExpr`
 in `CoreUnfold` with `occurAnalyseExpr_NoBinderSwap`.

 But that just makes things yet a bit more complicated.

 An alternative, and I think nicer, solution is to make the occcurrence
 analyser do the binder-swap substitution as it goes. Instead of adding a
 let-binding (as now) and doing some fancy footwork to gather the right
 occurrence info (as now -- e.g. `occ_gbl_scruts`), we can simply carry a
 substitution, and apply it to every variable.

 I'm not completely sure of the best path here.  Maybe try both?

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/16288#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list