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

Commits:

1 changed file:

Changes:

  • compiler/GHC/Core/Opt/Specialise.hs
    ... ... @@ -1628,13 +1628,11 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
    1628 1628
             do { let all_call_args | is_dfun   = saturating_call_args -- See Note [Specialising DFuns]
    
    1629 1629
                                    | otherwise = call_args
    
    1630 1630
                      saturating_call_args = call_args ++ map mk_extra_dfun_arg (dropList call_args rhs_bndrs)
    
    1631
    -                 mk_extra_dfun_arg bndr | isTyVar bndr = UnspecType
    
    1632
    -                                        | otherwise = UnspecArg
    
    1631
    +                 mk_extra_dfun_arg bndr | isTyVar bndr = UnspecType (tyVarKind bndr)  -- ToDo: right?
    
    1632
    +                                        | otherwise    = UnspecArg (idType bndr)
    
    1633 1633
     
    
    1634 1634
                ; (useful, rule_bndrs, rule_lhs_args, spec_bndrs1, spec_args) <- specHeader env all_call_args
    
    1635 1635
     
    
    1636
    -
    
    1637
    -
    
    1638 1636
     --           ; pprTrace "spec_call" (vcat
    
    1639 1637
     --                [ text "fun:       "  <+> ppr fn
    
    1640 1638
     --                , text "call info: "  <+> ppr _ci
    
    ... ... @@ -1642,7 +1640,6 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
    1642 1640
     --                , text "rule_bndrs:"  <+> ppr rule_bndrs
    
    1643 1641
     --                , text "lhs_args:  "  <+> ppr rule_lhs_args
    
    1644 1642
     --                , text "spec_bndrs1:" <+> ppr spec_bndrs1
    
    1645
    ---                , text "leftover_bndrs:" <+> pprIds leftover_bndrs
    
    1646 1643
     --                , text "spec_args: "  <+> ppr spec_args
    
    1647 1644
     --                , text "dx_binds:  "  <+> ppr dx_binds
    
    1648 1645
     --                , text "rhs_bndrs"     <+> ppr rhs_bndrs
    
    ... ... @@ -1664,12 +1661,9 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
    1664 1661
                ; (rhs_body', rhs_uds) <- specRhs env rhs_bndrs rhs_body spec_args
    
    1665 1662
                     -- Add the { d1' = dx1; d2' = dx2 } usage stuff
    
    1666 1663
                     -- to the rhs_uds; see Note [Specialising Calls]
    
    1667
    -           ; let rhs_uds_w_dx   = dx_binds `consDictBinds` rhs_uds
    
    1668
    -                 spec_rhs_bndrs = spec_bndrs1 ++ leftover_bndrs
    
    1669
    -                 (spec_uds, dumped_dbs) = dumpUDs spec_rhs_bndrs rhs_uds_w_dx
    
    1670
    -                 spec_rhs1 = mkLams spec_rhs_bndrs $
    
    1664
    +           ; let (spec_uds, dumped_dbs) = dumpUDs spec_bndrs1 rhs_uds
    
    1665
    +                 spec_rhs1 = mkLams spec_bndrs1 $
    
    1671 1666
                                  wrapDictBindsE dumped_dbs rhs_body'
    
    1672
    -
    
    1673 1667
                      spec_fn_ty1 = exprType spec_rhs1
    
    1674 1668
     
    
    1675 1669
                      -- Maybe add a void arg to the specialised function,
    
    ... ... @@ -1690,7 +1684,7 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
    1690 1684
                      -- The wrap_unf_body applies the original unfolding to the specialised
    
    1691 1685
                      -- arguments, not forgetting to wrap the dx_binds around the outside (#22358)
    
    1692 1686
                      simpl_opts = initSimpleOpts dflags
    
    1693
    -                 wrap_unf_body body = foldr (Let . db_bind) (body `mkApps` spec_args) dx_binds
    
    1687
    +                 wrap_unf_body body = body `mkApps` spec_args
    
    1694 1688
                      spec_unf = specUnfolding simpl_opts spec_bndrs wrap_unf_body
    
    1695 1689
                                               rule_lhs_args fn_unf
    
    1696 1690
     
    
    ... ... @@ -1769,6 +1763,33 @@ alreadyCovered env bndrs fn args is_active rules
    1769 1763
       where
    
    1770 1764
         in_scope = substInScopeSet (se_subst env)
    
    1771 1765
     
    
    1766
    +specRhs :: SpecEnv -> [Var] -> CoreExpr -> [CoreExpr]
    
    1767
    +        -> SpecM (CoreExpr, UsageDetails)
    
    1768
    +
    
    1769
    +specRhs env bndrs body []
    
    1770
    +  = specLam env bndrs body
    
    1771
    +
    
    1772
    +specRhs env [] body args
    
    1773
    +  = -- The caller should have ensured that there are no more
    
    1774
    +    -- args than we have binders on the RHS
    
    1775
    +    pprPanic "specRhs:too many args" (ppr args $$ ppr body)
    
    1776
    +
    
    1777
    +specRhs env@(SE { se_subst = subst }) (bndr:bndrs) body (arg:args)
    
    1778
    +  | exprIsTrivial arg
    
    1779
    +  , let env' = env { se_subst = Core.extendSubst subst bndr arg }
    
    1780
    +  = specRhs env' bndrs body args
    
    1781
    +
    
    1782
    +
    
    1783
    +  | otherwise  -- Non-trivial argument; it must be a dictionary
    
    1784
    +  = do { fresh_dict_id <- newIdBndr "dx" (idType bndr)
    
    1785
    +       ; let fresh_dict_id' = fresh_dict_id `addDictUnfolding` arg
    
    1786
    +             dict_bind = mkDB (NonRec fresh_dict_id' arg)
    
    1787
    +             env2 = env1 { se_subst = Core.extendSubst subst bndr (Var fresh_dict_id')
    
    1788
    +                                      `Core.extendSubstInScope` fresh_dict_id' }
    
    1789
    +                                      -- Ensure the new unfolding is in the in-scope set
    
    1790
    +       ; (body', uds) <- specRhs env2 bndrs body args
    
    1791
    +       ; return (body', dict_bind `consDictBind` uds) }
    
    1792
    +
    
    1772 1793
     -- Convenience function for invoking lookupRule from Specialise
    
    1773 1794
     -- The SpecEnv's InScopeSet should include all the Vars in the [CoreExpr]
    
    1774 1795
     specLookupRule :: SpecEnv -> Id -> [CoreExpr]
    
    ... ... @@ -2426,7 +2447,7 @@ data SpecArg
    2426 2447
         SpecType Type
    
    2427 2448
     
    
    2428 2449
         -- | Type arguments that should remain polymorphic.
    
    2429
    -  | UnspecType
    
    2450
    +  | UnspecType Kind
    
    2430 2451
     
    
    2431 2452
         -- | Dictionaries that should be specialised. mkCallUDs ensures
    
    2432 2453
         -- that only "interesting" dictionary arguments get a SpecDict;
    
    ... ... @@ -2434,25 +2455,25 @@ data SpecArg
    2434 2455
       | SpecDict DictExpr
    
    2435 2456
     
    
    2436 2457
         -- | Value arguments that should not be specialised.
    
    2437
    -  | UnspecArg
    
    2458
    +  | UnspecArg Type
    
    2438 2459
     
    
    2439 2460
     instance Outputable SpecArg where
    
    2440
    -  ppr (SpecType t) = text "SpecType" <+> ppr t
    
    2441
    -  ppr UnspecType   = text "UnspecType"
    
    2442
    -  ppr (SpecDict d) = text "SpecDict" <+> ppr d
    
    2443
    -  ppr UnspecArg    = text "UnspecArg"
    
    2461
    +  ppr (SpecType t)   = text "SpecType" <+> ppr t
    
    2462
    +  ppr (UnspecType k) = text "UnspecType"
    
    2463
    +  ppr (SpecDict d)   = text "SpecDict" <+> ppr d
    
    2464
    +  ppr (UnspecArg t)  = text "UnspecArg"
    
    2444 2465
     
    
    2445 2466
     specArgFreeIds :: SpecArg -> IdSet
    
    2446
    -specArgFreeIds (SpecType {}) = emptyVarSet
    
    2447
    -specArgFreeIds (SpecDict dx) = exprFreeIds dx
    
    2448
    -specArgFreeIds UnspecType    = emptyVarSet
    
    2449
    -specArgFreeIds UnspecArg     = emptyVarSet
    
    2467
    +specArgFreeIds (SpecType {})   = emptyVarSet
    
    2468
    +specArgFreeIds (SpecDict dx)   = exprFreeIds dx
    
    2469
    +specArgFreeIds (UnspecType {}) = emptyVarSet
    
    2470
    +specArgFreeIds (UnspecArg {})  = emptyVarSet
    
    2450 2471
     
    
    2451 2472
     specArgFreeVars :: SpecArg -> VarSet
    
    2452
    -specArgFreeVars (SpecType ty) = tyCoVarsOfType ty
    
    2453
    -specArgFreeVars (SpecDict dx) = exprFreeVars dx
    
    2454
    -specArgFreeVars UnspecType    = emptyVarSet
    
    2455
    -specArgFreeVars UnspecArg     = emptyVarSet
    
    2473
    +specArgFreeVars (SpecType ty)   = tyCoVarsOfType ty
    
    2474
    +specArgFreeVars (UnspecType ki) = tyCoVarsOfType ki
    
    2475
    +specArgFreeVars (SpecDict dx)   = exprFreeVars dx
    
    2476
    +specArgFreeVars (UnspecArg ty)  = tyCoVarsOfType ty
    
    2456 2477
     
    
    2457 2478
     isSpecDict :: SpecArg -> Bool
    
    2458 2479
     isSpecDict (SpecDict {}) = True
    
    ... ... @@ -2521,7 +2542,7 @@ specHeader
    2521 2542
     -- We want to specialise on type 'T1', and so we must construct a substitution
    
    2522 2543
     -- 'a->T1', as well as a LHS argument for the resulting RULE and unfolding
    
    2523 2544
     -- details.
    
    2524
    -specHeader env (bndr : bndrs) (SpecType ty : args)
    
    2545
    +specHeader env (SpecType ty : args)
    
    2525 2546
       = do { -- Find qvars, the type variables to add to the binders for the rule
    
    2526 2547
              -- Namely those free in `ty` that aren't in scope
    
    2527 2548
              -- See (MP2) in Note [Specialising polymorphic dictionaries]
    
    ... ... @@ -2529,7 +2550,7 @@ specHeader env (bndr : bndrs) (SpecType ty : args)
    2529 2550
                  qvars    = scopedSort $
    
    2530 2551
                             filterOut (`elemInScopeSet` in_scope) $
    
    2531 2552
                             tyCoVarsOfTypeList ty
    
    2532
    -       ; (useful, rule_bs, rule_args, spec_bs, spec_args) <- specHeader env2 args
    
    2553
    +       ; (useful, rule_bs, rule_args, spec_bs, spec_args) <- specHeader env args
    
    2533 2554
            ; pure ( useful
    
    2534 2555
                   , qvars ++ rule_bs
    
    2535 2556
                   , Type ty : rule_args
    
    ... ... @@ -2542,17 +2563,13 @@ specHeader env (bndr : bndrs) (SpecType ty : args)
    2542 2563
     -- a substitution on it (in case the type refers to 'a'). Additionally, we need
    
    2543 2564
     -- to produce a binder, LHS argument and RHS argument for the resulting rule,
    
    2544 2565
     -- /and/ a binder for the specialised body.
    
    2545
    -specHeader env (bndr : bndrs) (UnspecType : args)
    
    2546
    -  = do { let (env', bndr') = substBndr env bndr
    
    2547
    -       ; (useful, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args)
    
    2548
    -            <- specHeader env' bndrs args
    
    2566
    +specHeader env (UnspecType kind : args)
    
    2567
    +  = do { (useful, rule_bs, rule_es, spec_bs, spec_args)  <- specHeader env' bndrs args
    
    2568
    +       ; tv <- newTyVarBndr kind
    
    2549 2569
            ; pure ( useful
    
    2550
    -              , env''
    
    2551
    -              , leftover_bndrs
    
    2552 2570
                   , bndr' : rule_bs
    
    2553 2571
                   , varToCoreExpr bndr' : rule_es
    
    2554
    -              , bndr' : bs'
    
    2555
    -              , dx
    
    2572
    +              , bndr' : spec_bs
    
    2556 2573
                   , varToCoreExpr bndr' : spec_args
    
    2557 2574
                   )
    
    2558 2575
            }
    
    ... ... @@ -2560,27 +2577,21 @@ specHeader env (bndr : bndrs) (UnspecType : args)
    2560 2577
     -- Next we want to specialise the 'Eq a' dict away. We need to construct
    
    2561 2578
     -- a wildcard binder to match the dictionary (See Note [Specialising Calls] for
    
    2562 2579
     -- the nitty-gritty), as a LHS rule and unfolding details.
    
    2563
    -specHeader env (bndr : bndrs) (SpecDict d : args)
    
    2580
    +specHeader env (SpecDict dict_arg : args)
    
    2564 2581
       | not (isDeadBinder bndr)
    
    2565 2582
       , allVarSet (`elemInScopeSet` in_scope) (exprFreeVars d)
    
    2566 2583
         -- See Note [Weird special case for SpecDict]
    
    2567
    -  = do { (env1, bndr') <- newDictBndr env bndr -- See Note [Zap occ info in rule binders]
    
    2568
    -       ; let (env2, dx_bind, spec_dict) = bindAuxiliaryDict env1 bndr bndr' d
    
    2569
    -       ; (_, env3, leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args)
    
    2570
    -             <- specHeader env2 bndrs args
    
    2584
    +  = do { (_, rule_bs, rule_es, spec_bs, spec_args) <- specHeader env bndrs args
    
    2585
    +       ; new_dict_id <- newIdBndr "dx" (exprType dict_arg)
    
    2586
    +       ; let new_dict_expr = varToCoreExpr new_dict_id
    
    2587
    +                      -- See Note [Evidence foralls]
    
    2571 2588
            ; pure ( True      -- Ha!  A useful specialisation!
    
    2572
    -              , env3
    
    2573
    -              , leftover_bndrs
    
    2574
    -              -- See Note [Evidence foralls]
    
    2575
    -              , exprFreeIdsList (varToCoreExpr bndr') ++ rule_bs
    
    2576
    -              , varToCoreExpr bndr' : rule_es
    
    2577
    -              , bs'
    
    2578
    -              , maybeToList dx_bind ++ dx
    
    2579
    -              , spec_dict : spec_args
    
    2589
    +              , exprFreeIdsList new_dict_expr ++ rule_bs
    
    2590
    +              , new_dict_expr : rule_es
    
    2591
    +              , spec_bs
    
    2592
    +              , dict_arg : spec_args
    
    2580 2593
                   )
    
    2581 2594
            }
    
    2582
    -   where
    
    2583
    -     in_scope = Core.substInScopeSet (se_subst env)
    
    2584 2595
     
    
    2585 2596
     -- Finally, we don't want to specialise on this argument 'i':
    
    2586 2597
     --   - It's an UnSpecArg, or
    
    ... ... @@ -2592,13 +2603,14 @@ specHeader env (bndr : bndrs) (SpecDict d : args)
    2592 2603
     -- why 'i' doesn't appear in our RULE above. But we have no guarantee that
    
    2593 2604
     -- there aren't 'UnspecArg's which come /before/ all of the dictionaries, so
    
    2594 2605
     -- this case must be here.
    
    2595
    -specHeader env (bndr : bndrs) (_ : args)
    
    2606
    +specHeader env (arg : args)
    
    2596 2607
         -- The "_" can be UnSpecArg, or SpecDict where the bndr is dead
    
    2597 2608
       = do { -- see Note [Zap occ info in rule binders]
    
    2598
    -         let (env', bndr') = substBndr env (zapIdOccInfo bndr)
    
    2599
    -       ; (useful, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args)
    
    2600
    -             <- specHeader env' bndrs args
    
    2609
    +       ; (useful, rule_bs, rule_es, spec_bs, spec_args) <- specHeader env bndrs args
    
    2601 2610
     
    
    2611
    +       ; spec_bndr <- case arg of
    
    2612
    +                        SpecDict d  -> newIdBndr "dx" (exprType d)
    
    2613
    +                        UnspecArg t -> newIdBndr "x"  t
    
    2602 2614
            ; let bndr_ty = idType bndr'
    
    2603 2615
     
    
    2604 2616
                  -- See Note [Drop dead args from specialisations]
    
    ... ... @@ -2611,14 +2623,11 @@ specHeader env (bndr : bndrs) (_ : args)
    2611 2623
                     = (Just bndr', varToCoreExpr bndr')
    
    2612 2624
     
    
    2613 2625
            ; pure ( useful
    
    2614
    -              , env''
    
    2615
    -              , leftover_bndrs
    
    2616 2626
                   , bndr' : rule_bs
    
    2617 2627
                   , varToCoreExpr bndr' : rule_es
    
    2618 2628
                   , case mb_spec_bndr of
    
    2619
    -                  Just b' -> b' : bs'
    
    2620
    -                  Nothing -> bs'
    
    2621
    -              , dx
    
    2629
    +                  Just b  -> b : spec_bs
    
    2630
    +                  Nothing -> spec_bs
    
    2622 2631
                   , spec_arg : spec_args
    
    2623 2632
                   )
    
    2624 2633
            }
    
    ... ... @@ -2636,6 +2645,7 @@ specHeader env bndrs []
    2636 2645
         (env', bndrs') = substBndrs env bndrs
    
    2637 2646
     
    
    2638 2647
     
    
    2648
    +{-
    
    2639 2649
     -- | Binds a dictionary argument to a fresh name, to preserve sharing
    
    2640 2650
     bindAuxiliaryDict
    
    2641 2651
       :: SpecEnv
    
    ... ... @@ -2662,7 +2672,7 @@ bindAuxiliaryDict env@(SE { se_subst = subst })
    2662 2672
                                     -- Ensure the new unfolding is in the in-scope set
    
    2663 2673
         in -- pprTrace "bindAuxiliaryDict:non-trivial" (ppr orig_dict_id <+> ppr fresh_dict_id') $
    
    2664 2674
            (env', Just dict_bind, Var fresh_dict_id')
    
    2665
    -
    
    2675
    +-}
    
    2666 2676
     addDictUnfolding :: Id -> CoreExpr -> Id
    
    2667 2677
     -- Add unfolding for freshly-bound Ids: see Note [Make the new dictionaries interesting]
    
    2668 2678
     -- and Note [Specialisation modulo dictionary selectors]
    
    ... ... @@ -2977,16 +2987,13 @@ singleCall spec_env id args
    2977 2987
                          unitBag (CI { ci_key  = args
    
    2978 2988
                                      , ci_fvs  = call_fvs }) }
    
    2979 2989
       where
    
    2980
    -    call_fvs =
    
    2981
    -      foldr (unionVarSet . free_var_fn) emptyVarSet args
    
    2990
    +    call_fvs = foldr (unionVarSet . free_var_fn) emptyVarSet args
    
    2982 2991
     
    
    2983 2992
         free_var_fn =
    
    2984 2993
           if gopt Opt_PolymorphicSpecialisation (se_dflags spec_env)
    
    2985 2994
             then specArgFreeIds
    
    2986 2995
             else specArgFreeVars
    
    2987 2996
     
    
    2988
    -
    
    2989
    -
    
    2990 2997
             -- specArgFreeIds: we specifically look for free Ids, not TyVars
    
    2991 2998
             --    see (MP1) in Note [Specialising polymorphic dictionaries]
    
    2992 2999
             --
    
    ... ... @@ -3022,12 +3029,13 @@ mkCallUDs' env f args
    3022 3029
                  -- Establish (CI-KEY): drop trailing args until we get to a SpecDict
    
    3023 3030
     
    
    3024 3031
         mk_spec_arg :: OutExpr -> PiTyBinder -> SpecArg
    
    3025
    -    mk_spec_arg arg (Named bndr)
    
    3032
    +    mk_spec_arg (Type ty) (Named bndr)
    
    3026 3033
           |  binderVar bndr `elemVarSet` constrained_tyvars
    
    3027
    -      = case arg of
    
    3028
    -          Type ty -> SpecType ty
    
    3029
    -          _       -> pprPanic "ci_key" $ ppr arg
    
    3030
    -      |  otherwise = UnspecType
    
    3034
    +      = SpecType ty
    
    3035
    +      | otherwise
    
    3036
    +      = UnspecType (typeKind ty)
    
    3037
    +    mk_spec_arg non_type_arg (Named bndr)
    
    3038
    +      = = pprPanic "ci_key" $ (ppr non_type_arg $$ ppr bndr)
    
    3031 3039
     
    
    3032 3040
         -- For "invisibleFunArg", which are the type-class dictionaries,
    
    3033 3041
         -- we decide on a case by case basis if we want to specialise
    
    ... ... @@ -3038,7 +3046,7 @@ mkCallUDs' env f args
    3038 3046
                   -- See Note [Interesting dictionary arguments]
    
    3039 3047
           = SpecDict arg
    
    3040 3048
     
    
    3041
    -      | otherwise = UnspecArg
    
    3049
    +      | otherwise = UnspecArg (exprType arg)
    
    3042 3050
     
    
    3043 3051
     {-
    
    3044 3052
     Note [Ticks on applications]
    
    ... ... @@ -3277,10 +3285,10 @@ snocDictBinds uds@MkUD{ud_binds=FDB{ fdb_binds = binds, fdb_bndrs = bs }} dbs
    3277 3285
       = uds { ud_binds = FDB { fdb_binds = binds `appOL`        (toOL dbs)
    
    3278 3286
                              , fdb_bndrs = bs    `extendVarSetList` bindersOfDictBinds dbs } }
    
    3279 3287
     
    
    3280
    -consDictBinds :: [DictBind] -> UsageDetails -> UsageDetails
    
    3281
    -consDictBinds dbs uds@MkUD{ud_binds=FDB{fdb_binds = binds, fdb_bndrs = bs}}
    
    3282
    -  = uds { ud_binds = FDB{ fdb_binds = toOL dbs `appOL` binds
    
    3283
    -                        , fdb_bndrs = bs `extendVarSetList` bindersOfDictBinds dbs } }
    
    3288
    +consDictBind :: DictBind -> UsageDetails -> UsageDetails
    
    3289
    +consDictBind db uds@MkUD{ud_binds=FDB{fdb_binds = binds, fdb_bndrs = bs}}
    
    3290
    +  = uds { ud_binds = FDB{ fdb_binds = db `consOL` binds
    
    3291
    +                        , fdb_bndrs = bs `extendVarSetList` bindersOfDictBind db } }
    
    3284 3292
     
    
    3285 3293
     wrapDictBinds :: FloatedDictBinds -> [CoreBind] -> [CoreBind]
    
    3286 3294
     wrapDictBinds (FDB { fdb_binds = dbs }) binds
    
    ... ... @@ -3394,10 +3402,10 @@ beats_or_same (CI { ci_key = args1 }) (CI { ci_key = args2 })
    3394 3402
         go  _ _ = False
    
    3395 3403
     
    
    3396 3404
         go_arg (SpecType ty1) (SpecType ty2) = isJust (tcMatchTy ty1 ty2)
    
    3397
    -    go_arg UnspecType     UnspecType     = True
    
    3398
    -    go_arg (SpecDict {})  (SpecDict {})  = True
    
    3399
    -    go_arg UnspecArg      UnspecArg      = True
    
    3400
    -    go_arg _              _              = False
    
    3405
    +    go_arg (UnspecType {}) (UnspecType {}) = True
    
    3406
    +    go_arg (SpecDict {})   (SpecDict {})   = True
    
    3407
    +    go_arg (UnspecArg {})  (UnspecArg {})  = True
    
    3408
    +    go_arg _               _               = False
    
    3401 3409
     
    
    3402 3410
     ----------------------
    
    3403 3411
     splitDictBinds :: FloatedDictBinds -> IdSet -> (FloatedDictBinds, OrdList DictBind, IdSet)
    
    ... ... @@ -3504,17 +3512,6 @@ cloneRecBndrsSM env@(SE { se_subst = subst }) bndrs
    3504 3512
            ; let env' = env { se_subst = subst' }
    
    3505 3513
            ; return (env', bndrs') }
    
    3506 3514
     
    
    3507
    -newDictBndr :: SpecEnv -> CoreBndr -> SpecM (SpecEnv, CoreBndr)
    
    3508
    --- Make up completely fresh binders for the dictionaries
    
    3509
    --- Their bindings are going to float outwards
    
    3510
    -newDictBndr env@(SE { se_subst = subst }) b
    
    3511
    -  = do { uniq <- getUniqueM
    
    3512
    -       ; let n    = idName b
    
    3513
    -             ty'  = substTyUnchecked subst (idType b)
    
    3514
    -             b'   = mkUserLocal (nameOccName n) uniq ManyTy ty' (getSrcSpan n)
    
    3515
    -             env' = env { se_subst = subst `Core.extendSubstInScope` b' }
    
    3516
    -       ; pure (env', b') }
    
    3517
    -
    
    3518 3515
     newSpecIdSM :: Name -> Type -> IdDetails -> IdInfo -> SpecM Id
    
    3519 3516
         -- Give the new Id a similar occurrence name to the old one
    
    3520 3517
     newSpecIdSM old_name new_ty details info
    
    ... ... @@ -3524,6 +3521,19 @@ newSpecIdSM old_name new_ty details info
    3524 3521
             ; return (assert (not (isCoVarType new_ty)) $
    
    3525 3522
                       mkLocalVar details new_name ManyTy new_ty info) }
    
    3526 3523
     
    
    3524
    +newIdBndr :: String -> Type -> SpecM (SpecEnv, CoreBndr)
    
    3525
    +-- Make up completely fresh binders for the dictionaries
    
    3526
    +-- Their bindings are going to float outwards
    
    3527
    +newIdBndr env@(SE { se_subst = subst }) str ty
    
    3528
    +  = do { uniq <- getUniqueM
    
    3529
    +       ; return (mkUserLocal (mkVarOcc str) uniq ManyTy ty noSrcSpan) }
    
    3530
    +
    
    3531
    +newTyVarBndr :: Kind -> SpecM TyVar
    
    3532
    +newTyVarBndr kind
    
    3533
    +  = do { uniq <- getUniqueM
    
    3534
    +       ; let name = mkInternalName uniq (mkTyVarOcc "a") noSrcSpan
    
    3535
    +       ; return (mkTyVar name kind }
    
    3536
    +
    
    3527 3537
     {-
    
    3528 3538
                     Old (but interesting) stuff about unboxed bindings
    
    3529 3539
                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -3535,7 +3545,7 @@ What should we do when a value is specialised to a *strict* unboxed value?
    3535 3545
                                in h:t
    
    3536 3546
     
    
    3537 3547
     Could convert let to case:
    
    3538
    -
    
    3548
    + 
    
    3539 3549
             map_*_Int# f (x:xs) = case f x of h# ->
    
    3540 3550
                                   let t = map f xs
    
    3541 3551
                                   in h#:t