Skip to content
Snippets Groups Projects
  • Simon Peyton Jones's avatar
    393531ff
    Specialising expressions -- at last · 393531ff
    Simon Peyton Jones authored and Marge Bot's avatar Marge Bot committed
    This MR addresses #24359, which implements the GHC proposal 493 on SPECIALISE pragmas.
    
    * The old code path (using SpecSig and SpecPrag) still exists.
    * The new code path (using SpecSigE and SpecPragE) runs alongside it.
    * All SPECIALISE pragmas are routed through the new code path, except
      if you give multiple type sigs, when the old code path is still used.
    * Main documentation: Note [Handling new-form SPECIALISE pragmas] in
      GHC.Tc.Gen.Sig`
    
    Thanks to @sheaf for helping with this MR.
    
    The Big Thing is to introduce
    
      {-# SPECIALISE forall x.  f @Int x True #-}
    
    where you can give type arguments and value argument to specialise; and
    you can quantify them with forall, just as in Rules.
    
    I thought it was going to be pretty simple, but it was a Long, Long Saga.
    
    Highlights
    
    * Overview Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig
      - New data constructor `SpecSigE` in data type `L.H.S.Binds.Sig`
      - New data construtor `SpecPragE` in data type `GHC.Hs.Binds.TcSpecPrag`
      - Renamer: uses `checkSpecESigShape` to decide which function to assocate the
                 SPECIALISE pragma with
      - Some of the action is in `GHC.Tc.Gen.Sig.tcSpecPrag`
      - The rest is in `GHC.HsToCore.Binds.dsSpec`
    
    * We use a new TcS mode, TcSFullySolve, when simplifying the Wanteds
      that arise from the specialise expression. The mechanism is explained
      in Note [TcSFullySolve] in GHC.Tc.Solver.Monad. The reason why we need
      to do this is explained in Note [Fully solving constraints for specialisation]
      in GHC.Tc.Gen.Sig.
    
    * All of GHC.Tc.Gen.Rule is moved into GHC.Tc.Gen.Sig, because the code is
      very closely related.
    
    * The forall'd binders for SPECIALISE are the same as those for a RULE, so I
      refactored, introducing data type `L.H.S.Binds.RuleBndrs`, with functions
      to rename, zonk, typecheck it.  I refactored this data type a bit; nicer now.
    
    * On the LHS of RULES, or SPECIALISE, we want to disable the tricky mechanims
      described in Note [Desugaring non-canonical evidence] in GHC.HsToCore.Expr.
      Previously it wasn't fully disabled (just set to the empty set), and that
      didn't quite work in the new regime.
    
    * There are knock-on changes to Template Haskell.
    
    * For the LHS of a RULE and a SPECIALISE expression, I wanted to simplify
      it /without/ inlining the let-bindings for evidence variables.  I added
      a flag `so_inline` to the SimpleOpt optimiser to support this.  The
      entry point is `GHC.Core.SimpleOpt.simpleOptExprNoInline`
    
    * Since forever we have had a hack for type variables on the LHS of
      RULES. I took the opportunity to tidy this up.  The main action is
      in the zonker.  See GHC.Tc.Zonk.Type Note [Free tyvars on rule LHS],
      and especially data construtor `SkolemiseFlexi`
      in data type `GHC.Tc.Zonk.Env.ZonkFlexi`
    
    * Move `scopedSort` from GHC.Core.TyCo.FVs to GHC.Core.Predicate
      Reason: it now works for Ids as well, and I wanted to use isEvVar,
              which is defined in GHC.Core.Predicate
      Avoiding module loops meant that instead of exporting GHC.Core.TyCo.Tidy
      from GHC.Core.Type, modules now import the former directly.
    
      I also took the opportunity to remove unused exports
      from GHC.Core.Type.hs-boot
    
    * Flag stuff:
      - Add flag `-Wdeprecated-pragmas` and use it to control the warning when
        using old-style SPECIALISE pragmas with multiple type ascriptions,
    
      - Add flag `-Wuseless-specialisations` and use it to control the warning emitted
        when GHC determines that a SPECIALISE pragma would have no effect. Don't
        want if the SPECIALISE is SPECIALISE INLINE (#4444)
    
        In response to #25389, we continue to generate these seemingly code for these
        seemingly useless SPECIALISE pragmas
    
      - Adds deprecations to Template Haskell `pragSpecD` and `pracSpecInlD`,
    
    * Split up old-style SPECIALISE pragmas in GHC.Internal.Float,
      GHC.Internal.Numeric, GHC.Internal.Real
    
    * Remove useless SPECIALISE pragmas in Data.Array (updating the array submodule)
    
    Smaller things:
    
    - Update the Users Guide
    
    - Add mention of the changes to the 9.14 release notes as well as
      the Template Haskell changelog,
    393531ff
    History
    Specialising expressions -- at last
    Simon Peyton Jones authored and Marge Bot's avatar Marge Bot committed
    This MR addresses #24359, which implements the GHC proposal 493 on SPECIALISE pragmas.
    
    * The old code path (using SpecSig and SpecPrag) still exists.
    * The new code path (using SpecSigE and SpecPragE) runs alongside it.
    * All SPECIALISE pragmas are routed through the new code path, except
      if you give multiple type sigs, when the old code path is still used.
    * Main documentation: Note [Handling new-form SPECIALISE pragmas] in
      GHC.Tc.Gen.Sig`
    
    Thanks to @sheaf for helping with this MR.
    
    The Big Thing is to introduce
    
      {-# SPECIALISE forall x.  f @Int x True #-}
    
    where you can give type arguments and value argument to specialise; and
    you can quantify them with forall, just as in Rules.
    
    I thought it was going to be pretty simple, but it was a Long, Long Saga.
    
    Highlights
    
    * Overview Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig
      - New data constructor `SpecSigE` in data type `L.H.S.Binds.Sig`
      - New data construtor `SpecPragE` in data type `GHC.Hs.Binds.TcSpecPrag`
      - Renamer: uses `checkSpecESigShape` to decide which function to assocate the
                 SPECIALISE pragma with
      - Some of the action is in `GHC.Tc.Gen.Sig.tcSpecPrag`
      - The rest is in `GHC.HsToCore.Binds.dsSpec`
    
    * We use a new TcS mode, TcSFullySolve, when simplifying the Wanteds
      that arise from the specialise expression. The mechanism is explained
      in Note [TcSFullySolve] in GHC.Tc.Solver.Monad. The reason why we need
      to do this is explained in Note [Fully solving constraints for specialisation]
      in GHC.Tc.Gen.Sig.
    
    * All of GHC.Tc.Gen.Rule is moved into GHC.Tc.Gen.Sig, because the code is
      very closely related.
    
    * The forall'd binders for SPECIALISE are the same as those for a RULE, so I
      refactored, introducing data type `L.H.S.Binds.RuleBndrs`, with functions
      to rename, zonk, typecheck it.  I refactored this data type a bit; nicer now.
    
    * On the LHS of RULES, or SPECIALISE, we want to disable the tricky mechanims
      described in Note [Desugaring non-canonical evidence] in GHC.HsToCore.Expr.
      Previously it wasn't fully disabled (just set to the empty set), and that
      didn't quite work in the new regime.
    
    * There are knock-on changes to Template Haskell.
    
    * For the LHS of a RULE and a SPECIALISE expression, I wanted to simplify
      it /without/ inlining the let-bindings for evidence variables.  I added
      a flag `so_inline` to the SimpleOpt optimiser to support this.  The
      entry point is `GHC.Core.SimpleOpt.simpleOptExprNoInline`
    
    * Since forever we have had a hack for type variables on the LHS of
      RULES. I took the opportunity to tidy this up.  The main action is
      in the zonker.  See GHC.Tc.Zonk.Type Note [Free tyvars on rule LHS],
      and especially data construtor `SkolemiseFlexi`
      in data type `GHC.Tc.Zonk.Env.ZonkFlexi`
    
    * Move `scopedSort` from GHC.Core.TyCo.FVs to GHC.Core.Predicate
      Reason: it now works for Ids as well, and I wanted to use isEvVar,
              which is defined in GHC.Core.Predicate
      Avoiding module loops meant that instead of exporting GHC.Core.TyCo.Tidy
      from GHC.Core.Type, modules now import the former directly.
    
      I also took the opportunity to remove unused exports
      from GHC.Core.Type.hs-boot
    
    * Flag stuff:
      - Add flag `-Wdeprecated-pragmas` and use it to control the warning when
        using old-style SPECIALISE pragmas with multiple type ascriptions,
    
      - Add flag `-Wuseless-specialisations` and use it to control the warning emitted
        when GHC determines that a SPECIALISE pragma would have no effect. Don't
        want if the SPECIALISE is SPECIALISE INLINE (#4444)
    
        In response to #25389, we continue to generate these seemingly code for these
        seemingly useless SPECIALISE pragmas
    
      - Adds deprecations to Template Haskell `pragSpecD` and `pracSpecInlD`,
    
    * Split up old-style SPECIALISE pragmas in GHC.Internal.Float,
      GHC.Internal.Numeric, GHC.Internal.Real
    
    * Remove useless SPECIALISE pragmas in Data.Array (updating the array submodule)
    
    Smaller things:
    
    - Update the Users Guide
    
    - Add mention of the changes to the 9.14 release notes as well as
      the Template Haskell changelog,
Code owners
Assign users and groups as approvers for specific file changes. Learn more.