#13043: GHC 7.10->8.0 regression: GHC code-generates duplicate _closures -------------------------------------+------------------------------------- Reporter: hvr | Owner: Type: bug | Status: new Priority: normal | Milestone: 8.0.2 Component: Compiler | Version: 8.0.2-rc2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Compile-time | Unknown/Multiple crash or panic | Test Case: Blocked By: | Blocking: Related Tickets: #12595 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by bgamari): I did a bit of digging into what is happening here: early in simplification we have the core, {{{#!hs scServerState [InlPrag=NOINLINE] :: SCServerState scServerState = ... foo_s1Sx :: State# RealWorld -> (# State# RealWorld, Int #) foo_s1Sx = \ (eta_B1 [OS=OneShot] :: State# RealWorld) -> case case scServerState of _ [InlPrag=NOINLINE, Occ=Dead] { SCServerState ipv_s1S8 -> GHC.Tuple.() } of _ [Occ=Dead] { () -> ... }}} Eventually case-of-case (and perhaps something else) fires, giving us, {{{#!hs foo_s1Sx = \ (eta_B1 [OS=OneShot] :: State# GHC.Prim.RealWorld) -> case scServerState of scServerState [InlPrag=NOINLINE] { SCServerState ipv_s1S8 -> case scServerState of _ [Occ=Dead] { SCServerState ds_d1Qj -> ... }}} Note that we are now shadowing the `scServerState` binder. This already seems suspicious. This then gets transformed to a `let` by the lifted case elimination simplification (see `Note [Case elimination: lifted case]`), {{{#!hs -- from phase foo_s1Sx = \ (eta_B1 [Dmd=<S,U>, OS=OneShot] :: State# GHC.Prim.RealWorld) -> let { scServerState [InlPrag=NOINLINE, Dmd=<S(S(S)),1*U(1*U(U))>] :: SCServerState [LclId, Str=DmdType, Unf=Unf{Src=<vanilla>, TopLvl=False, Value=False, ConLike=False, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)}] scServerState = scServerState } in case scServerState of _ [Occ=Dead, Dmd=<L,A>] { SCServerState ds_d1Qj [Dmd=<S(S),1*U(U)>] -> ... }}} The let-bound `scServerState` is then floated to the top-level, resulting in the duplicate closures we see here. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13043#comment:5> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler