Skip to content
  • 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
    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,
Loading