• simonpj@microsoft.com's avatar
    Add the notion of "constructor-like" Ids for rule-matching · 4bc25e8c
    simonpj@microsoft.com authored
    This patch adds an optional CONLIKE modifier to INLINE/NOINLINE pragmas, 
       {-# NOINLINE CONLIKE [1] f #-}
    The effect is to allow applications of 'f' to be expanded in a potential
    rule match.  Example
      {-# RULE "r/f" forall v. r (f v) = f (v+1) #-}
    
    Consider the term
         let x = f v in ..x...x...(r x)...
    Normally the (r x) would not match the rule, because GHC would be scared
    about duplicating the redex (f v). However the CONLIKE modifier says to
    treat 'f' like a constructor in this situation, and "look through" the
    unfolding for x.  So (r x) fires, yielding (f (v+1)).
    
    The main changes are:
      - Syntax
    
      - The inlinePragInfo field of an IdInfo has a RuleMatchInfo
        component, which records whether or not the Id is CONLIKE.
        Of course, this needs to be serialised in interface files too.
    
      - The occurrence analyser (OccAnal) and simplifier (Simplify) treat
        CONLIKE thing like constructors, by ANF-ing them
    
      - New function coreUtils.exprIsExpandable is like exprIsCheap, but
        additionally spots applications of CONLIKE functions
    
      - A CoreUnfolding has a field that caches exprIsExpandable
    
      - The rule matcher consults this field.  See 
        Note [Expanding variables] in Rules.lhs.
    
    On the way I fixed a lurking variable bug in the way variables are
    expanded.  See Note [Do not expand locally-bound variables] in
    Rule.lhs.  I also did a bit of reformatting and refactoring in
    Rules.lhs, so the module has more lines changed than are really
    different.
    4bc25e8c
BasicTypes.lhs 19.4 KB