Simon Peyton Jones pushed to branch wip/T26115 at Glasgow Haskell Compiler / GHC

Commits:

4 changed files:

Changes:

  • compiler/GHC/HsToCore/Binds.hs
    ... ... @@ -1168,17 +1168,18 @@ dsSpec_help poly_nm poly_id poly_rhs spec_inl orig_bndrs ds_call
    1168 1168
                  is_local v = v `elemVarSet` locals
    
    1169 1169
     
    
    1170 1170
                  rule_bndrs = scopedSort (exprsSomeFreeVarsList is_local rule_lhs_args)
    
    1171
    -             rn_binds   = getRenamings orig_bndrs binds rule_bndrs
    
    1172 1171
     
    
    1173
    -             spec_binds = pickSpecBinds is_local (mkVarSet rule_bndrs) binds
    
    1172
    +             rn_binds     = getRenamings orig_bndrs binds rule_bndrs
    
    1173
    +             known_vars   = mkVarSet rule_bndrs `extendVarSetList` bindersOfBinds rn_binds
    
    1174
    +             picked_binds = pickSpecBinds is_local known_vars binds
    
    1174 1175
     
    
    1175 1176
                  -- Make spec_bndrs, the variables to pass to the specialised
    
    1176 1177
                  -- function, by filtering out the rule_bndrs that aren't needed
    
    1177
    -             spec_binds_bndr_set = mkVarSet (bindersOfBinds spec_binds)
    
    1178
    +             spec_binds_bndr_set = mkVarSet (bindersOfBinds picked_binds)
    
    1178 1179
                                        `minusVarSet` exprsFreeVars (rhssOfBinds rn_binds)
    
    1179 1180
                  spec_bndrs = filterOut (`elemVarSet` spec_binds_bndr_set) rule_bndrs
    
    1180 1181
     
    
    1181
    -             mk_spec_body fn_body = mkLets (rn_binds ++ spec_binds)  $
    
    1182
    +             mk_spec_body fn_body = mkLets (rn_binds ++ picked_binds)  $
    
    1182 1183
                                         mkApps fn_body rule_lhs_args
    
    1183 1184
                                         -- ToDo: not mkCoreApps!  That uses exprType on fun which
    
    1184 1185
                                         --       fails in specUnfolding, sigh
    
    ... ... @@ -1227,7 +1228,7 @@ dsSpec_help poly_nm poly_id poly_rhs spec_inl orig_bndrs ds_call
    1227 1228
                   , text "rule_bndrs" <+> ppr rule_bndrs
    
    1228 1229
                   , text "spec_bndrs" <+> ppr spec_bndrs
    
    1229 1230
                   , text "rn_binds" <+> ppr rn_binds
    
    1230
    -              , text "spec_binds" <+> ppr spec_binds ]
    
    1231
    +              , text "picked_binds" <+> ppr picked_binds ]
    
    1231 1232
     
    
    1232 1233
            ; dsWarnOrphanRule rule
    
    1233 1234
     
    

  • compiler/GHC/Tc/Solver/Solve.hs
    ... ... @@ -1301,7 +1301,8 @@ tryInertQCs qc
    1301 1301
     try_inert_qcs :: QCInst -> [QCInst] -> TcS (StopOrContinue ())
    
    1302 1302
     try_inert_qcs (QCI { qci_ev = ev_w }) inerts =
    
    1303 1303
       case mapMaybe matching_inert inerts of
    
    1304
    -    [] -> continueWith ()
    
    1304
    +    [] -> do { traceTcS "tryInertQCs:nothing" (ppr ev_w $$ ppr inerts)
    
    1305
    +             ; continueWith () }
    
    1305 1306
         ev_i:_ ->
    
    1306 1307
           do { traceTcS "tryInertQCs:KeepInert" (ppr ev_i)
    
    1307 1308
              ; setEvBindIfWanted ev_w EvCanonical (ctEvTerm ev_i)
    
    ... ... @@ -1700,108 +1701,3 @@ runTcPluginSolvers solvers all_cts
    1700 1701
         addOne (givens, wanteds) (ev,ct) = case ctEvidence ct of
    
    1701 1702
           CtGiven  {} -> (ct:givens, wanteds)
    
    1702 1703
           CtWanted {} -> (givens, (ev,ct):wanteds)
    1703
    -
    
    1704
    ---------------------------------------------------------------------------------
    
    1705
    -
    
    1706
    -{-
    
    1707
    --- | If the mode is 'TcSSpecPrag', attempt to fully solve the Wanted
    
    1708
    --- constraints that arise from solving 'Ct'.
    
    1709
    ---
    
    1710
    --- If not in 'TcSSpecPrag' mode, simply run 'thing_inside'.
    
    1711
    ---
    
    1712
    --- See Note [TcSSpecPrag] in GHC.Tc.Solver.Monad.
    
    1713
    -solveCompletelyIfRequired :: Ct -> TcS (StopOrContinue a) -> TcS (StopOrContinue a)
    
    1714
    -solveCompletelyIfRequired ct (TcS thing_inside)
    
    1715
    -  = TcS $ \ env@(TcSEnv { tcs_ev_binds = outer_ev_binds_var
    
    1716
    -                        , tcs_unified  = outer_unified_var
    
    1717
    -                        , tcs_unif_lvl = outer_unif_lvl_var
    
    1718
    -                        , tcs_inerts   = outer_inert_var
    
    1719
    -                        , tcs_count    = outer_count
    
    1720
    -                        , tcs_mode     = mode
    
    1721
    -                        }) ->
    
    1722
    -  case mode of
    
    1723
    -    TcSSpecPrag ->
    
    1724
    -      do { traceTc "solveCompletelyIfRequired {" empty
    
    1725
    -           -- Create a fresh environment for the inner computation
    
    1726
    -         ; outer_inerts <- TcM.readTcRef outer_inert_var
    
    1727
    -         ; let outer_givens = inertGivens outer_inerts
    
    1728
    -           -- Keep the ambient Given inerts, but drop the Wanteds.
    
    1729
    -         ; new_inert_var    <- TcM.newTcRef outer_givens
    
    1730
    -         ; new_wl_var       <- TcM.newTcRef emptyWorkList
    
    1731
    -         ; new_ev_binds_var <- TcM.newTcEvBinds
    
    1732
    -
    
    1733
    -         ; let
    
    1734
    -            inner_env =
    
    1735
    -              TcSEnv
    
    1736
    -                -- KEY part: recur with TcSVanilla
    
    1737
    -                { tcs_mode     = TcSVanilla
    
    1738
    -
    
    1739
    -                -- Use new variables for evidence bindings, inerts; and
    
    1740
    -                -- the work list. We may want to discard all of these if the
    
    1741
    -                -- inner computation doesn't fully solve all the constraints.
    
    1742
    -                , tcs_ev_binds = new_ev_binds_var
    
    1743
    -                , tcs_inerts   = new_inert_var
    
    1744
    -                , tcs_worklist = new_wl_var
    
    1745
    -
    
    1746
    -                -- Inherit the other variables. In particular, inherit the
    
    1747
    -                -- variables to do with unification, as filling metavariables
    
    1748
    -                -- is a side-effect that we are not reverting, even when we
    
    1749
    -                -- discard the result of the inner computation.
    
    1750
    -                , tcs_unif_lvl = outer_unif_lvl_var
    
    1751
    -                , tcs_unified  = outer_unified_var
    
    1752
    -                , tcs_count    = outer_count
    
    1753
    -                }
    
    1754
    -
    
    1755
    -           -- Solve the constraint
    
    1756
    -         ; let wc = emptyWC { wc_simple = unitBag ct }
    
    1757
    -         ; traceTc "solveCompletelyIfRequired solveWanteds" $
    
    1758
    -            vcat [ text "ct:" <+> ppr ct
    
    1759
    -                 ]
    
    1760
    -         ; solved_wc <- unTcS (solveWanteds wc) inner_env
    
    1761
    -            -- NB: it would probably make more sense to call 'thing_inside',
    
    1762
    -            -- collecting all constraints that were added to the work list as
    
    1763
    -            -- a result, and calling 'solveWanteds' on that. This would avoid
    
    1764
    -            -- restarting from the top of the solver pipeline.
    
    1765
    -            -- For the time being, we just call 'solveWanteds' on the original
    
    1766
    -            -- constraint, which is simpler
    
    1767
    -
    
    1768
    -         ; if isSolvedWC solved_wc
    
    1769
    -           then
    
    1770
    -             do { -- The constraint was fully solved. Continue with
    
    1771
    -                  -- the inner solver state.
    
    1772
    -                ; traceTc "solveCompletelyIfRequired: fully solved }" $
    
    1773
    -                   vcat [ text "ct:" <+> ppr ct
    
    1774
    -                        , text "solved_wc:" <+> ppr solved_wc ]
    
    1775
    -
    
    1776
    -                  -- Add new evidence bindings to the existing ones
    
    1777
    -                ; inner_ev_binds <- TcM.getTcEvBindsMap new_ev_binds_var
    
    1778
    -                ; addTcEvBinds outer_ev_binds_var inner_ev_binds
    
    1779
    -
    
    1780
    -                  -- Keep the outer inert set and work list: the inner work
    
    1781
    -                  -- list is empty, and there are no leftover unsolved
    
    1782
    -                  -- Wanteds.
    
    1783
    -                  -- However, we **must not** drop solved implications, due
    
    1784
    -                  -- to Note [Free vars of EvFun] in GHC.Tc.Types.Evidence;
    
    1785
    -                  -- so we re-emit them here.
    
    1786
    -                ; let re_emit_implic impl = unTcS ( TcS.emitImplication impl ) env
    
    1787
    -                ; traverse_ re_emit_implic $ wc_impl solved_wc
    
    1788
    -                ; return $ Stop (ctEvidence ct) (text "Fully solved:" <+> ppr ct)
    
    1789
    -                }
    
    1790
    -           else
    
    1791
    -             do { traceTc "solveCompletelyIfRequired: unsolved }" $
    
    1792
    -                   vcat [ text "ct:" <+> ppr ct
    
    1793
    -                        , text "solved_wc:" <+> ppr solved_wc ]
    
    1794
    -                  -- Failed to fully solve the constraint:
    
    1795
    -                  --
    
    1796
    -                  --  - discard the inner solver state,
    
    1797
    -                  --  - add the original constraint as an inert.
    
    1798
    -                ; unTcS (updInertIrreds (IrredCt (ctEvidence ct) IrredShapeReason)) env
    
    1799
    -                    -- NB: currently we only call 'solveCompletelyIfRequired'
    
    1800
    -                    -- from 'solveForAll'; so we just stash the unsolved quantified
    
    1801
    -                    -- constraint in the irreds.
    
    1802
    -
    
    1803
    -                 ; return $ Stop (ctEvidence ct) (text "Not fully solved; kept as inert:" <+> ppr ct)
    
    1804
    -                 } }
    
    1805
    -    _notFullySolveMode ->
    
    1806
    -      thing_inside env
    
    1807
    --}

  • testsuite/tests/simplCore/should_compile/T26115.stderr
    1 1
     [GblId[DFunId],
    
    2
    - Unf=DFun: \ (@b_awW) ->
    
    2
    + Unf=DFun: \ (@b) ->
    
    3 3
     [GblId[DFunId],
    
    4
    - Unf=DFun: \ (@b_aBU) ->
    
    4
    + Unf=DFun: \ (@b) ->
    
    5 5
     [GblId[DFunId],
    
    6
    - Unf=DFun: \ (@p_awR) (@q_awS) (v_B1 :: C p_awR q_awS) ->
    6
    + Unf=DFun: \ (@p) (@q) (v :: C p q) ->

  • testsuite/tests/simplCore/should_compile/all.T
    ... ... @@ -548,6 +548,6 @@ test('T25965', normal, compile, ['-O'])
    548 548
     test('T25703',  [grep_errmsg(r'SPEC')], compile, ['-O -fpolymorphic-specialisation -ddump-rule-firings'])
    
    549 549
     test('T25703a', [grep_errmsg(r'SPEC')], compile, ['-O -fpolymorphic-specialisation -ddump-rule-firings'])
    
    550 550
     
    
    551
    -test('T26115', [grep_errmsg(r'DFun')], compile, ['-O -ddump-simpl'])
    
    551
    +test('T26115', [grep_errmsg(r'DFun')], compile, ['-O -ddump-simpl -dsuppress-uniques'])
    
    552 552
     test('T26116', normal, compile, ['-O -ddump-rules'])
    
    553 553