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

Commits:

12 changed files:

Changes:

  • compiler/GHC/Core/Lint.hs
    ... ... @@ -3063,17 +3063,12 @@ Note [Checking StaticPtrs]
    3063 3063
     ~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    3064 3064
     See Note [Grand plan for static forms] in GHC.Iface.Tidy.StaticPtrTable for an overview.
    
    3065 3065
     
    
    3066
    -Every occurrence of the function 'makeStatic' should be moved to the
    
    3067
    -top level by the FloatOut pass.  It's vital that we don't have nested
    
    3068
    -'makeStatic' occurrences after CorePrep, because we populate the Static
    
    3069
    -Pointer Table from the top-level bindings. See SimplCore Note [Grand
    
    3070
    -plan for static forms].
    
    3071
    -
    
    3072
    -The linter checks that no occurrence is left behind, nested within an
    
    3073
    -expression. The check is enabled only after the FloatOut, CorePrep,
    
    3074
    -and CoreTidy passes and only if the module uses the StaticPointers
    
    3075
    -language extension. Checking more often doesn't help since the condition
    
    3076
    -doesn't hold until after the first FloatOut pass.
    
    3066
    +Every occurrence of the function 'makeStatic' should be at top level.
    
    3067
    +It's vital that we don't have nested 'makeStatic' occurrences after
    
    3068
    +CorePrep, because we populate the Static Pointer Table from the
    
    3069
    +top-level bindings. See SimplCore Note [Grand plan for static forms].
    
    3070
    +
    
    3071
    +The linter checks that no occurrence or `makeStatic` occurs nested.
    
    3077 3072
     
    
    3078 3073
     Note [Type substitution]
    
    3079 3074
     ~~~~~~~~~~~~~~~~~~~~~~~~
    

  • compiler/GHC/Core/Opt/Pipeline.hs
    ... ... @@ -64,7 +64,6 @@ import GHC.Types.Var ( Var )
    64 64
     import GHC.Types.Unique.Supply ( UniqueTag(..) )
    
    65 65
     
    
    66 66
     import Control.Monad
    
    67
    -import qualified GHC.LanguageExtensions as LangExt
    
    68 67
     import GHC.Unit.Module
    
    69 68
     
    
    70 69
     {-
    
    ... ... @@ -206,14 +205,14 @@ getCoreToDo dflags hpt_rule_base extra_vars
    206 205
             -- so that overloaded functions have all their dictionary lambdas manifest
    
    207 206
             runWhen do_specialise CoreDoSpecialising,
    
    208 207
     
    
    209
    -        runWhen full_laziness $
    
    210
    -           CoreDoFloatOutwards $ FloatOutSwitches
    
    208
    +        runWhen full_laziness
    
    209
    +           (CoreDoFloatOutwards $ FloatOutSwitches
    
    211 210
                     { floatOutLambdas     = Just 0
    
    212 211
                     , floatOutConstants   = True
    
    213 212
                     , floatOutOverSatApps = False
    
    214 213
                     , floatToTopLevelOnly = False
    
    215 214
                     , floatJoinsToTop     = False  -- Initially, don't float join points at all
    
    216
    -                }
    
    215
    +                }),
    
    217 216
                     -- I have no idea why, but not floating constants to
    
    218 217
                     -- top level is very bad in some cases.
    
    219 218
                     --
    

  • compiler/GHC/Core/Opt/SetLevels.hs
    ... ... @@ -109,7 +109,7 @@ import GHC.Types.Var.Env
    109 109
     import GHC.Types.Literal      ( litIsTrivial )
    
    110 110
     import GHC.Types.Demand       ( DmdSig, prependArgsDmdSig )
    
    111 111
     import GHC.Types.Cpr          ( CprSig, prependArgsCprSig )
    
    112
    -import GHC.Types.Name         ( getOccName, mkSystemVarName )
    
    112
    +import GHC.Types.Name         ( getOccName )
    
    113 113
     import GHC.Types.Name.Occurrence ( occNameFS )
    
    114 114
     import GHC.Types.Unique       ( hasKey )
    
    115 115
     import GHC.Types.Tickish      ( tickishIsCode )
    

  • compiler/GHC/Tc/Errors/Ppr.hs
    ... ... @@ -5504,7 +5504,7 @@ suggestAddSig ctxt ty1 _ty2
    5504 5504
         find [] _ _ = []
    
    5505 5505
         find (implic:implics) seen_eqs tv
    
    5506 5506
            | tv `elem` ic_skols implic
    
    5507
    -       , InferSkol _ prs <- ic_info implic
    
    5507
    +       , InferSkol prs <- ic_info implic
    
    5508 5508
            , seen_eqs
    
    5509 5509
            = map fst prs
    
    5510 5510
            | otherwise
    
    ... ... @@ -5578,7 +5578,7 @@ ctxtFixes (CEC {cec_encl = implics}) has_ambig_tvs pred
    5578 5578
       , isTyVarClassPred pred   -- Don't suggest adding (Eq T) to the context, say
    
    5579 5579
       , (skol:skols) <- usefulContext implics pred
    
    5580 5580
       , let what | null skols
    
    5581
    -             , SigSkol _ (PatSynCtxt {}) _ _ <- skol
    
    5581
    +             , SigSkol (PatSynCtxt {}) _ _ <- skol
    
    5582 5582
                  = text "\"required\""
    
    5583 5583
                  | otherwise
    
    5584 5584
                  = empty
    
    ... ... @@ -5618,7 +5618,7 @@ usefulContext implics pred
    5618 5618
           | implausible_info (ic_info ic) = True
    
    5619 5619
           | otherwise                     = False
    
    5620 5620
     
    
    5621
    -    implausible_info (SigSkol _ (InfSigCtxt {}) _ _) = True
    
    5621
    +    implausible_info (SigSkol (InfSigCtxt {}) _ _) = True
    
    5622 5622
         implausible_info _                             = False
    
    5623 5623
         -- Do not suggest adding constraints to an *inferred* type signature
    
    5624 5624
     
    
    ... ... @@ -5713,17 +5713,17 @@ tidySkolemInfo env (SkolemInfo u sk_anon) = SkolemInfo u (tidySkolemInfoAnon env
    5713 5713
     ----------------
    
    5714 5714
     tidySkolemInfoAnon :: TidyEnv -> SkolemInfoAnon -> SkolemInfoAnon
    
    5715 5715
     tidySkolemInfoAnon env (DerivSkol ty)         = DerivSkol (tidyType env ty)
    
    5716
    -tidySkolemInfoAnon env (SigSkol st cx ty tv_prs) = tidySigSkol env st cx ty tv_prs
    
    5717
    -tidySkolemInfoAnon env (InferSkol st ids)     = InferSkol st (mapSnd (tidyType env) ids)
    
    5716
    +tidySkolemInfoAnon env (SigSkol cx ty tv_prs) = tidySigSkol env cx ty tv_prs
    
    5717
    +tidySkolemInfoAnon env (InferSkol ids)        = InferSkol (mapSnd (tidyType env) ids)
    
    5718 5718
     tidySkolemInfoAnon env (UnifyForAllSkol ty)   = UnifyForAllSkol (tidyType env ty)
    
    5719 5719
     tidySkolemInfoAnon _   info                   = info
    
    5720 5720
     
    
    5721
    -tidySigSkol :: TidyEnv -> StaticFlag -> UserTypeCtxt
    
    5721
    +tidySigSkol :: TidyEnv -> UserTypeCtxt
    
    5722 5722
                 -> TcType -> [(Name,TcTyVar)] -> SkolemInfoAnon
    
    5723 5723
     -- We need to take special care when tidying SigSkol
    
    5724 5724
     -- See Note [SigSkol SkolemInfo] in "GHC.Tc.Types.Origin"
    
    5725
    -tidySigSkol env st cx ty tv_prs
    
    5726
    -  = SigSkol st cx (tidy_ty env ty) tv_prs'
    
    5725
    +tidySigSkol env cx ty tv_prs
    
    5726
    +  = SigSkol cx (tidy_ty env ty) tv_prs'
    
    5727 5727
       where
    
    5728 5728
         tv_prs' = mapSnd (tidyTyCoVarOcc env) tv_prs
    
    5729 5729
         inst_env = mkNameEnv tv_prs'
    

  • compiler/GHC/Tc/Errors/Types.hs
    ... ... @@ -23,7 +23,6 @@ module GHC.Tc.Errors.Types (
    23 23
       , SuggestUnliftedTypes(..)
    
    24 24
       , DataSort(..), ppDataSort
    
    25 25
       , AllowedDataResKind(..)
    
    26
    -  , NotClosedReason(..)
    
    27 26
       , SuggestPartialTypeSignatures(..)
    
    28 27
       , suggestPartialTypeSignatures
    
    29 28
       , DeriveInstanceErrReason(..)
    
    ... ... @@ -1829,7 +1828,7 @@ data TcRnMessage where
    1829 1828
         Test cases: rename/should_fail/RnStaticPointersFail01
    
    1830 1829
                     rename/should_fail/RnStaticPointersFail03
    
    1831 1830
       -}
    
    1832
    -  TcRnStaticFormNotClosed :: Name -> NotClosedReason -> TcRnMessage
    
    1831
    +  TcRnStaticFormNotClosed :: Name -> TcRnMessage
    
    1833 1832
     
    
    1834 1833
       {-| TcRnUselessTypeable is a warning (controlled by -Wderiving-typeable) that
    
    1835 1834
           occurs when trying to derive an instance of the 'Typeable' class. Deriving
    
    ... ... @@ -4627,12 +4626,6 @@ data AllowedDataResKind
    4627 4626
       | AnyBoxedKind
    
    4628 4627
       | LiftedKind
    
    4629 4628
     
    
    4630
    --- | A data type to describe why a variable is not closed.
    
    4631
    --- See Note [Not-closed error messages] in GHC.Tc.Gen.Expr
    
    4632
    -data NotClosedReason = NotLetBoundReason
    
    4633
    -                     | NotTypeClosed VarSet
    
    4634
    -                     | NotClosed Name NotClosedReason
    
    4635
    -
    
    4636 4629
     data SuggestPartialTypeSignatures
    
    4637 4630
       = YesSuggestPartialTypeSignatures
    
    4638 4631
       | NoSuggestPartialTypeSignatures
    
    ... ... @@ -5533,8 +5526,8 @@ discardProvCtxtGivens orig givens -- See Note [discardProvCtxtGivens]
    5533 5526
       | otherwise
    
    5534 5527
       = givens
    
    5535 5528
       where
    
    5536
    -    discard n (Implic { ic_info = SigSkol _ (PatSynCtxt n') _ _ }) = n == n'
    
    5537
    -    discard _ _                                                    = False
    
    5529
    +    discard n (Implic { ic_info = SigSkol (PatSynCtxt n') _ _ }) = n == n'
    
    5530
    +    discard _ _                                                  = False
    
    5538 5531
     
    
    5539 5532
     
    
    5540 5533
     -- | An error reported after constraint solving.
    

  • compiler/GHC/Tc/Types.hs
    ... ... @@ -45,8 +45,7 @@ module GHC.Tc.Types(
    45 45
             TcTypeEnv, TcBinderStack, TcBinder(..),
    
    46 46
             TcTyThing(..), tcTyThingTyCon_maybe,
    
    47 47
             PromotionErr(..),
    
    48
    -        IdBindingInfo(..), ClosedTypeId, RhsNames,
    
    49
    -        IsGroupClosed(..),
    
    48
    +        IdBindingInfo(..), ClosedTypeId,
    
    50 49
             SelfBootInfo(..), bootExports,
    
    51 50
             tcTyThingCategory, pprTcTyThingCategory,
    
    52 51
             peCategory, pprPECategory,
    

  • compiler/GHC/Tc/Types/BasicTypes.hs
    ... ... @@ -14,8 +14,6 @@ module GHC.Tc.Types.BasicTypes (
    14 14
       -- * TcTyThing
    
    15 15
       , TcTyThing(..)
    
    16 16
       , IdBindingInfo(..)
    
    17
    -  , IsGroupClosed(..)
    
    18
    -  , RhsNames
    
    19 17
       , ClosedTypeId
    
    20 18
       , tcTyThingCategory
    
    21 19
       , tcTyThingTyCon_maybe
    
    ... ... @@ -33,11 +31,8 @@ import GHC.Types.Var
    33 31
     import GHC.Types.SrcLoc
    
    34 32
     import GHC.Types.Name
    
    35 33
     import GHC.Types.TyThing
    
    36
    -import GHC.Types.Name.Env
    
    37
    -import GHC.Types.Name.Set
    
    38 34
     
    
    39 35
     import GHC.Hs.Extension ( GhcRn )
    
    40
    -import GHC.Hs.Binds ( StaticFlag )
    
    41 36
     
    
    42 37
     import Language.Haskell.Syntax.Type ( LHsSigWcType )
    
    43 38
     
    
    ... ... @@ -505,10 +500,9 @@ in the type environment.
    505 500
     -}
    
    506 501
     
    
    507 502
     instance Outputable IdBindingInfo where
    
    508
    -  ppr NotLetBound = text "NotLetBound"
    
    509
    -  ppr (LetBound { lb_static = top_lvl, lb_fvs = fvs, lb_closed = cls })
    
    510
    -    = text "LetBound" <> braces (sep [ ppr top_lvl, text "closed-type=" <+> ppr cls
    
    511
    -                                     , ppr fvs ])
    
    503
    +  ppr NotLetBound    = text "NotLetBound"
    
    504
    +  ppr (LetBound cls) = text "LetBound"
    
    505
    +                       <> if cls then text "(closed)" else text "(not-closed)"
    
    512 506
     
    
    513 507
     --------------
    
    514 508
     pprTcTyThingCategory :: TcTyThing -> SDoc
    

  • compiler/GHC/Tc/Types/Constraint.hs
    ... ... @@ -2158,8 +2158,8 @@ checkSkolInfoAnon :: SkolemInfoAnon -- From the implication
    2158 2158
     -- So it doesn't matter much if its's incomplete
    
    2159 2159
     checkSkolInfoAnon sk1 sk2 = go sk1 sk2
    
    2160 2160
       where
    
    2161
    -    go (SigSkol _ c1 t1 s1) (SigSkol _ c2 t2 s2) = c1==c2 && t1 `tcEqType` t2 && s1==s2
    
    2162
    -    go (InferSkol _ ids1)   (InferSkol _ ids2)   = equalLength ids1 ids2 &&
    
    2161
    +    go (SigSkol c1 t1 s1) (SigSkol c2 t2 s2)     = c1==c2 && t1 `tcEqType` t2 && s1==s2
    
    2162
    +    go (InferSkol ids1)   (InferSkol ids2)       = equalLength ids1 ids2 &&
    
    2163 2163
                                                        and (zipWith eq_pr ids1 ids2)
    
    2164 2164
         go (SigTypeSkol cx1)    (SigTypeSkol cx2)    = cx1==cx2
    
    2165 2165
     
    

  • compiler/GHC/Tc/Types/Origin.hs
    ... ... @@ -262,14 +262,12 @@ data SkolemInfoAnon
    262 262
                 -- a programmer-supplied type signature
    
    263 263
                 -- Location of the binding site is on the TyVar
    
    264 264
                 -- See Note [SigSkol SkolemInfo]
    
    265
    -       StaticFlag
    
    266 265
            UserTypeCtxt        -- What sort of signature
    
    267 266
            TcType              -- Original type signature (before skolemisation)
    
    268 267
            [(Name,TcTyVar)]    -- Maps the original name of the skolemised tyvar
    
    269 268
                                -- to its instantiated version
    
    270 269
     
    
    271 270
       | InferSkol
    
    272
    -       StaticFlag
    
    273 271
            [(Name,TcType)]  -- We have inferred a type for these (mutually recursive)
    
    274 272
                             -- polymorphic Ids, and are now checking that their RHS
    
    275 273
                             -- constraints are satisfied.
    
    ... ... @@ -364,7 +362,7 @@ instance Outputable SkolemInfoAnon where
    364 362
     
    
    365 363
     pprSkolInfo :: SkolemInfoAnon -> SDoc
    
    366 364
     -- Complete the sentence "is a rigid type variable bound by..."
    
    367
    -pprSkolInfo (SigSkol _ cx ty _) = pprSigSkolInfo cx ty
    
    365
    +pprSkolInfo (SigSkol cx ty _) = pprSigSkolInfo cx ty
    
    368 366
     pprSkolInfo (SigTypeSkol cx)  = pprUserTypeCtxt cx
    
    369 367
     pprSkolInfo (ForAllSkol tvs)  = text "an explicit forall" <+> ppr tvs
    
    370 368
     pprSkolInfo (IPSkol ips)      = text "the implicit-parameter binding" <> plural ips <+> text "for"
    
    ... ... @@ -382,7 +380,7 @@ pprSkolInfo (RuleSkol name) = text "the RULE" <+> pprRuleName name
    382 380
     pprSkolInfo (SpecESkol name)  = text "a SPECIALISE pragma for" <+> quotes (ppr name)
    
    383 381
     pprSkolInfo (PatSkol cl mc)   = sep [ pprPatSkolInfo cl
    
    384 382
                                         , text "in" <+> pprMatchContext mc ]
    
    385
    -pprSkolInfo (InferSkol _ ids) = hang (text "the inferred type" <> plural ids <+> text "of")
    
    383
    +pprSkolInfo (InferSkol ids)   = hang (text "the inferred type" <> plural ids <+> text "of")
    
    386 384
                                        2 (vcat [ ppr name <+> dcolon <+> ppr ty
    
    387 385
                                                | (name,ty) <- ids ])
    
    388 386
     pprSkolInfo (UnifyForAllSkol ty)  = text "the type" <+> ppr ty
    
    ... ... @@ -462,10 +460,8 @@ in the right place. So we proceed as follows:
    462 460
     -}
    
    463 461
     
    
    464 462
     isStaticSkolInfo :: SkolemInfoAnon -> Bool
    
    465
    -isStaticSkolInfo StaticFormSkol           = True
    
    466
    -isStaticSkolInfo (SigSkol IsStatic _ _ _) = True
    
    467
    -isStaticSkolInfo (InferSkol IsStatic  _)  = True
    
    468
    -isStaticSkolInfo _                        = False
    
    463
    +isStaticSkolInfo StaticFormSkol = True
    
    464
    +isStaticSkolInfo _              = False
    
    469 465
     
    
    470 466
     
    
    471 467
     {- *********************************************************************
    

  • compiler/GHC/Tc/Utils/Env.hs
    ... ... @@ -116,7 +116,7 @@ import GHC.Utils.Misc ( HasDebugCallStack )
    116 116
     
    
    117 117
     import GHC.Data.FastString
    
    118 118
     import GHC.Data.List.SetOps
    
    119
    -import GHC.Data.Maybe( MaybeErr(..), orElse, maybeToList, fromMaybe )
    
    119
    +import GHC.Data.Maybe( MaybeErr(..), maybeToList, fromMaybe )
    
    120 120
     
    
    121 121
     import GHC.Types.SrcLoc
    
    122 122
     import GHC.Types.Basic hiding( SuccessFlag(..) )
    
    ... ... @@ -671,12 +671,12 @@ tcExtendRecIds :: [(Name, TcId)] -> TcM a -> TcM a
    671 671
     -- Does not extend the TcBinderStack
    
    672 672
     tcExtendRecIds pairs thing_inside
    
    673 673
       = tc_extend_local_env NotTopLevel
    
    674
    -          [ (name, ATcId { tct_id   = let_id
    
    675
    -                         , tct_info = LetBound { lb_static = NotStatic
    
    676
    -                                               , lb_fvs = emptyNameSet
    
    677
    -                                               , lb_closed = False } })
    
    674
    +          [ (name, ATcId { tct_id   = let_id, tct_info = info  })
    
    678 675
               | (name, let_id) <- pairs ] $
    
    679 676
         thing_inside
    
    677
    +  where
    
    678
    +    is_closed = False
    
    679
    +    info = LetBound is_closed
    
    680 680
     
    
    681 681
     tcExtendSigIds :: TopLevelFlag -> [TcId] -> TcM a -> TcM a
    
    682 682
     -- Used for binding the Ids that have a complete user type signature
    
    ... ... @@ -688,32 +688,22 @@ tcExtendSigIds top_lvl sig_ids thing_inside
    688 688
                                   , tct_info = info })
    
    689 689
               | id <- sig_ids
    
    690 690
               , let closed = isTypeClosedLetBndr id
    
    691
    -                info   = LetBound { lb_static = NotStatic
    
    692
    -                                  , lb_fvs = emptyNameSet
    
    693
    -                                  , lb_closed = closed } ]
    
    691
    +                info   = LetBound closed ]
    
    694 692
          thing_inside
    
    695 693
     
    
    696 694
     
    
    697
    -tcExtendLetEnv :: TopLevelFlag -> TcSigFun -> IsGroupClosed
    
    695
    +tcExtendLetEnv :: TopLevelFlag -> TcSigFun -> ClosedTypeId
    
    698 696
                       -> [Scaled TcId] -> TcM a
    
    699 697
                       -> TcM a
    
    700 698
     -- Used for both top-level value bindings and nested let/where-bindings
    
    701 699
     -- Used for a single NonRec or a single Rec
    
    702 700
     -- Adds to the TcBinderStack too
    
    703
    -tcExtendLetEnv top_lvl _sig_fn
    
    704
    -               (IsGroupClosed {gc_static = group_static, gc_fvs = fv_env})
    
    705
    -               ids thing_inside
    
    701
    +tcExtendLetEnv top_lvl _sig_fn closed ids thing_inside
    
    706 702
       = tcExtendBinderStack [TcIdBndr id top_lvl | Scaled _ id <- ids] $
    
    707 703
         tc_extend_local_env top_lvl
    
    708
    -          [ (idName id, ATcId { tct_id   = id
    
    709
    -                              , tct_info = mk_tct_info id })
    
    704
    +          [ (idName id, ATcId { tct_id = id, tct_info = LetBound closed })
    
    710 705
               | Scaled _ id <- ids ] $
    
    711 706
         foldr tcCheckUsage thing_inside ids
    
    712
    -  where
    
    713
    -    mk_tct_info id
    
    714
    -      = LetBound { lb_static = group_static
    
    715
    -                 , lb_fvs = lookupNameEnv fv_env (idName id) `orElse` emptyNameSet
    
    716
    -                 , lb_closed = isTypeClosedLetBndr id }
    
    717 707
     
    
    718 708
     tcExtendIdEnv :: [TcId] -> TcM a -> TcM a
    
    719 709
     -- For lambda-bound and case-bound Ids
    

  • compiler/GHC/Tc/Zonk/TcType.hs
    ... ... @@ -521,10 +521,10 @@ zonkSkolemInfo :: SkolemInfo -> ZonkM SkolemInfo
    521 521
     zonkSkolemInfo (SkolemInfo u sk) = SkolemInfo u <$> zonkSkolemInfoAnon sk
    
    522 522
     
    
    523 523
     zonkSkolemInfoAnon :: SkolemInfoAnon -> ZonkM SkolemInfoAnon
    
    524
    -zonkSkolemInfoAnon (SigSkol st cx ty tv_prs) = do { ty' <- zonkTcType ty
    
    525
    -                                                  ; return (SigSkol st cx ty' tv_prs) }
    
    526
    -zonkSkolemInfoAnon (InferSkol st ntys) = do { ntys' <- mapM do_one ntys
    
    527
    -                                            ; return (InferSkol st ntys') }
    
    524
    +zonkSkolemInfoAnon (SigSkol cx ty tv_prs) = do { ty' <- zonkTcType ty
    
    525
    +                                               ; return (SigSkol cx ty' tv_prs) }
    
    526
    +zonkSkolemInfoAnon (InferSkol ntys) = do { ntys' <- mapM do_one ntys
    
    527
    +                                         ; return (InferSkol ntys') }
    
    528 528
       where
    
    529 529
         do_one (n, ty) = do { ty' <- zonkTcType ty; return (n, ty') }
    
    530 530
     zonkSkolemInfoAnon skol_info = return skol_info
    

  • compiler/GHC/Tc/Zonk/Type.hs
    ... ... @@ -681,7 +681,7 @@ zonkLocalBinds (HsValBinds x (XValBindsLR (HsVBG binds sigs)))
    681 681
       = do  { new_binds <- mapM go binds
    
    682 682
             ; return (HsValBinds x (XValBindsLR (HsVBG new_binds sigs))) }
    
    683 683
       where
    
    684
    -    go (r,b,s) = do { b' <- zonkRecMonoBinds b; return (r,b',s) }
    
    684
    +    go (r,b) = do { b' <- zonkRecMonoBinds b; return (r,b') }
    
    685 685
     
    
    686 686
     zonkLocalBinds (HsIPBinds x (IPBinds dict_binds binds )) = do
    
    687 687
         new_binds <- noBinders $ mapM (wrapLocZonkMA zonk_ip_bind) binds