-
Simon Peyton Jones authored
With constructor unpacking, it's possible for constructors and record selectors to have non-trivial code, which should be optimised before being fed to the code generator. Example: data Foo = Foo { get :: {-# UNPACK #-} !Int } Then we do not want to get this: T2070.get = \ (tpl_B1 :: T2070.Foo) -> case tpl_B1 of tpl1_B2 { T2070.Foo rb_B4 -> let { ipv_B3 [Just S] :: GHC.Base.Int [Str: DmdType m] ipv_B3 = GHC.Base.I# rb_B4 } in ipv_B3 } If this goes through to codegen, we'll generate bad code. Admittedly, this only matters when the selector is used in a curried way (e.g map get xs), but nevertheless it's silly. This patch injects the implicit bindings in SimplCore, before the simplifier runs. That slows the simplifier a little, because it has to look at some extra bindings; but it's probably a slight effect. If it turns out to matter I suppose we can always inject them later, e.g. just before the final simplification. An unexpected (to me) consequence is that we get some specialisation rules for class-method selectors. E.g. we get a rule RULE (==) Int dInt = eqInt There's no harm in this, but not much benefit either, because the same result will happen when we inline (==) and dInt, but it's perhaps more direct.
5952ef0d