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

Commits:

5 changed files:

Changes:

  • compiler/GHC/Hs/Syn/Type.hs
    ... ... @@ -191,6 +191,7 @@ hsWrapperType :: HsWrapper -> Type -> Type
    191 191
     hsWrapperType wrap ty = prTypeType $ go wrap (ty,[])
    
    192 192
       where
    
    193 193
         go WpHole              = id
    
    194
    +    go (WpSubType w)       = go w
    
    194 195
         go (w1 `WpCompose` w2) = go w1 . go w2
    
    195 196
         go (WpFun _ w2 (Scaled m exp_arg) _) = liftPRType $ \t ->
    
    196 197
           let act_res = funResultTy t
    

  • compiler/GHC/HsToCore/Binds.hs
    ... ... @@ -1598,9 +1598,10 @@ ds_hs_wrapper :: HsWrapper
    1598 1598
                   -> ((CoreExpr -> CoreExpr) -> DsM a)
    
    1599 1599
                   -> DsM a
    
    1600 1600
     ds_hs_wrapper hs_wrap
    
    1601
    -  = go (optHsWrapper hs_wrap)
    
    1601
    +  = go hs_wrap
    
    1602 1602
       where
    
    1603 1603
         go WpHole            k = k $ \e -> e
    
    1604
    +    go (WpSubType w)     k = go (optSubTypeHsWrapper w) k
    
    1604 1605
         go (WpTyApp ty)      k = k $ \e -> App e (Type ty)
    
    1605 1606
         go (WpEvLam ev)      k = k $ Lam ev
    
    1606 1607
         go (WpTyLam tv)      k = k $ Lam tv
    

  • compiler/GHC/Tc/Types/Evidence.hs
    ... ... @@ -8,11 +8,11 @@ module GHC.Tc.Types.Evidence (
    8 8
       -- * HsWrapper
    
    9 9
       HsWrapper(..),
    
    10 10
       (<.>), mkWpTyApps, mkWpEvApps, mkWpEvVarApps, mkWpTyLams, mkWpForAllCast,
    
    11
    -  mkWpEvLams, mkWpLet, mkWpFun, mkWpCastN, mkWpCastR, mkWpEta,
    
    11
    +  mkWpEvLams, mkWpLet, mkWpFun, mkWpCastN, mkWpCastR, mkWpEta, mkWpSubType,
    
    12 12
       collectHsWrapBinders,
    
    13 13
       idHsWrapper, isIdHsWrapper,
    
    14 14
       pprHsWrapper, hsWrapDictBinders,
    
    15
    -  optHsWrapper,
    
    15
    +  optSubTypeHsWrapper,
    
    16 16
     
    
    17 17
       -- * Evidence bindings
    
    18 18
       TcEvBinds(..), EvBindsVar(..),
    
    ... ... @@ -135,11 +135,20 @@ maybeSymCo NotSwapped co = co
    135 135
     ************************************************************************
    
    136 136
     -}
    
    137 137
     
    
    138
    +{- Note [WpSubType]
    
    139
    +~~~~~~~~~~~~~~~~~~~
    
    140
    +(WpSubType wp) means the same as `wp`, but with the added promise that
    
    141
    +the binders in `wp` do not scope over the hole
    
    142
    +-}
    
    143
    +
    
    138 144
     -- We write    wrap :: t1 ~> t2
    
    139 145
     -- if       wrap[ e::t1 ] :: t2
    
    140 146
     data HsWrapper
    
    141 147
       = WpHole                      -- The identity coercion
    
    142 148
     
    
    149
    +  | WpSubType HsWrapper   -- (WpSubType wp) Means the same as `wp`
    
    150
    +                          -- But see Note [WpSubType]
    
    151
    +
    
    143 152
       | WpCompose HsWrapper HsWrapper
    
    144 153
            -- (wrap1 `WpCompose` wrap2)[e] = wrap1[ wrap2[ e ]]
    
    145 154
            --
    
    ... ... @@ -246,6 +255,11 @@ mkWpFun w_arg w_res t1 t2 = WpFun w_arg w_res t1 t2
    246 255
       -- Unfortunately, we can't check this with an assertion here, because of
    
    247 256
       -- [Wrinkle: Typed Template Haskell] in Note [hasFixedRuntimeRep] in GHC.Tc.Utils.Concrete.
    
    248 257
     
    
    258
    +mkWpSubType :: HsWrapper -> HsWrapper
    
    259
    +mkWpSubType WpHole      = WpHole
    
    260
    +mkWpSubType (WpCast co) = WpCast co
    
    261
    +mkWpSubType w           = WpSubType w
    
    262
    +
    
    249 263
     mkWpEta :: Type -> [Id] -> HsWrapper -> HsWrapper
    
    250 264
     -- (mkWpEta [x1, x2] wrap) [e]
    
    251 265
     --   = \x1. \x2.  wrap[e x1 x2]
    
    ... ... @@ -336,6 +350,7 @@ hsWrapDictBinders wrap = go wrap
    336 350
        go (w1 `WpCompose` w2) = go w1 `unionBags` go w2
    
    337 351
        go (WpFun _ w _ _)     = go w
    
    338 352
        go WpHole              = emptyBag
    
    353
    +   go (WpSubType {})      = emptyBag  -- See Note [WpSubType]
    
    339 354
        go (WpCast  {})        = emptyBag
    
    340 355
        go (WpEvApp {})        = emptyBag
    
    341 356
        go (WpTyLam {})        = emptyBag
    
    ... ... @@ -351,6 +366,7 @@ collectHsWrapBinders wrap = go wrap []
    351 366
         go :: HsWrapper -> [HsWrapper] -> ([Var], HsWrapper)
    
    352 367
         go (WpEvLam v)       wraps = add_lam v (gos wraps)
    
    353 368
         go (WpTyLam v)       wraps = add_lam v (gos wraps)
    
    369
    +    go (WpSubType w)     wraps = go w wraps
    
    354 370
         go (WpCompose w1 w2) wraps = go w1 (w2:wraps)
    
    355 371
         go wrap              wraps = ([], foldl' (<.>) wrap wraps)
    
    356 372
     
    
    ... ... @@ -360,124 +376,113 @@ collectHsWrapBinders wrap = go wrap []
    360 376
         add_lam v (vs,w) = (v:vs, w)
    
    361 377
     
    
    362 378
     
    
    363
    -optHsWrapper :: HsWrapper -> HsWrapper
    
    364
    -optHsWrapper wrap
    
    365
    -  = foldr (<.>) WpHole (norm wrap [])
    
    366
    -    -- let wrap' = foldr (<.>) WpHole (norm wrap [])
    
    367
    -    -- in pprTrace "optHsWrapper" (vcat [ text "in:" <+> ppr wrap, text "out:" <+> ppr wrap' ]) $
    
    368
    -    --    wrap'
    
    379
    +optSubTypeHsWrapper :: HsWrapper -> HsWrapper
    
    380
    +optSubTypeHsWrapper wrap
    
    381
    +  = pprTrace "optHsWrapper" (vcat [ text "in:" <+> ppr wrap, text "out:" <+> ppr (opt wrap) ]) $
    
    382
    +    opt wrap
    
    369 383
       where
    
    370
    -    norm :: HsWrapper -> [HsWrapper] -> [HsWrapper]
    
    371
    -    -- norm w ws = w <.> (foldr <.> WpHole ws)
    
    372
    -    -- INVARIANT: ws:[HsWrapper] is normalised
    
    373
    -    norm WpHole                 ws = ws
    
    374
    -    norm (w1 `WpCompose` w2)    ws = norm w1 (norm w2 ws)
    
    375
    -    norm (WpCast co)            ws = norm_co co ws
    
    376
    -    norm (WpEvLam ev)           ws = norm_ev_lam ev ws
    
    377
    -    norm (WpTyLam tv)           ws = norm_ty_lam tv ws
    
    378
    -    norm (WpLet binds)          ws = norm_let binds ws
    
    379
    -    norm (WpFun w1 w2 sty1 ty2) ws = norm_fun w1 w2 sty1 ty2 ws
    
    380
    -    norm w@(WpTyApp {})         ws = w : ws
    
    381
    -    norm w@(WpEvApp {})         ws = w : ws
    
    384
    +    opt :: HsWrapper -> HsWrapper
    
    385
    +    opt w = foldr (<.>) WpHole (opt1 w [])
    
    386
    +
    
    387
    +    opt1 :: HsWrapper -> [HsWrapper] -> [HsWrapper]
    
    388
    +    -- opt1 w ws = w <.> (foldr <.> WpHole ws)
    
    389
    +    -- INVARIANT: ws:[HsWrapper] is optimised
    
    390
    +    opt1 WpHole                 ws = ws
    
    391
    +    opt1 (WpSubType w)          ws = opt1 w ws
    
    392
    +    opt1 (w1 `WpCompose` w2)    ws = opt1 w1 (opt1 w2 ws)
    
    393
    +    opt1 (WpCast co)            ws = opt_co co ws
    
    394
    +    opt1 (WpEvLam ev)           ws = opt_ev_lam ev ws
    
    395
    +    opt1 (WpTyLam tv)           ws = opt_ty_lam tv ws
    
    396
    +    opt1 (WpLet binds)          ws = opt_let binds ws
    
    397
    +    opt1 (WpFun w1 w2 sty1 ty2) ws = mk_wp_fun (opt w1) (opt w2) sty1 ty2 ws
    
    398
    +    opt1 w@(WpTyApp {})         ws = w : ws
    
    399
    +    opt1 w@(WpEvApp {})         ws = w : ws
    
    382 400
     
    
    383 401
         ------------------
    
    384
    -    norm_let b@(EvBinds bs) ws | isEmptyBag bs = ws
    
    385
    -                               | otherwise     = WpLet b : ws
    
    386
    -    norm_let (TcEvBinds {}) _  = pprPanic "optHsWrapper1" (ppr wrap)
    
    402
    +    opt_let b@(EvBinds bs) ws | isEmptyBag bs = ws
    
    403
    +                              | otherwise     = WpLet b : ws
    
    404
    +    opt_let (TcEvBinds {}) _  = pprPanic "optHsWrapper1" (ppr wrap)
    
    387 405
     
    
    388 406
         -----------------
    
    389 407
         -- (WpTyLam a <+> WpTyApp a <+> w) = w
    
    390
    -    norm_ty_lam tv (WpTyApp ty : ws)
    
    408
    +    opt_ty_lam tv (WpTyApp ty : ws)
    
    391 409
           | Just tv' <- getTyVar_maybe ty
    
    392 410
           , tv==tv'
    
    393 411
           = ws
    
    394 412
     
    
    395 413
         -- (WpTyLam a <+> WpCastCo co <+> w)
    
    396 414
         --    = WpCast (ForAllCo a co) (WpTyLam <.> w)
    
    397
    -    norm_ty_lam tv (WpCast co : ws)
    
    398
    -      = norm_co (mkHomoForAllCo tv co) (norm_ty_lam tv ws)
    
    415
    +    opt_ty_lam tv (WpCast co : ws)
    
    416
    +      = opt_co (mkHomoForAllCo tv co) (opt_ty_lam tv ws)
    
    399 417
     
    
    400
    -    norm_ty_lam tv (WpLet bs : ws)
    
    418
    +    opt_ty_lam tv (WpLet bs : ws)
    
    401 419
           | Just ws' <- pushWpLet bs ws
    
    402
    -      = norm_ty_lam tv ws'
    
    420
    +      = opt_ty_lam tv ws'
    
    403 421
     
    
    404
    -    norm_ty_lam tv ws
    
    422
    +    opt_ty_lam tv ws
    
    405 423
           = WpTyLam tv : ws
    
    406 424
     
    
    407 425
         -----------------
    
    408 426
         -- (WpEvLam ev <+> WpEvAp ev <+> w) = w
    
    409
    -    norm_ev_lam ev (WpEvApp ev_tm : ws)
    
    427
    +    opt_ev_lam ev (WpEvApp ev_tm : ws)
    
    410 428
           | EvExpr (Var ev') <- ev_tm
    
    411 429
           , ev == ev'
    
    412 430
           = ws
    
    413 431
     
    
    414 432
         -- (WpEvLam ev <.> WpCast co <.> w)
    
    415 433
         --    = WpCast (FunCo ev co) (WpEvLam <.> w)
    
    416
    -    norm_ev_lam ev (WpCast co : ws)
    
    417
    -      = norm_co fun_co (norm_ev_lam ev ws)
    
    434
    +    opt_ev_lam ev (WpCast co : ws)
    
    435
    +      = opt_co fun_co (opt_ev_lam ev ws)
    
    418 436
           where
    
    419 437
             fun_co = mkFunCo Representational FTF_C_T
    
    420 438
                             (mkNomReflCo ManyTy)
    
    421 439
                             (mkRepReflCo (idType ev))
    
    422 440
                             co
    
    423
    -    norm_ev_lam ev (WpLet bs : ws)
    
    441
    +    opt_ev_lam ev (WpLet bs : ws)
    
    424 442
           | Just ws' <- pushWpLet bs ws
    
    425
    -      = norm_ev_lam ev ws'
    
    443
    +      = opt_ev_lam ev ws'
    
    426 444
     
    
    427
    -    norm_ev_lam ev ws
    
    445
    +    opt_ev_lam ev ws
    
    428 446
           = WpEvLam ev : ws
    
    429 447
     
    
    430 448
         -----------------
    
    431 449
         -- WpCast co <.> WpCast co' <+> ws = WpCast (co;co') ws
    
    432
    -    norm_co co (WpCast co' : ws)     = norm_co (co `mkTransCo` co') ws
    
    433
    -    norm_co co ws | isReflexiveCo co = ws
    
    434
    -                  | otherwise        = WpCast co : ws
    
    450
    +    opt_co co (WpCast co' : ws)     = opt_co (co `mkTransCo` co') ws
    
    451
    +    opt_co co ws | isReflexiveCo co = ws
    
    452
    +                 | otherwise        = WpCast co : ws
    
    435 453
     
    
    436 454
         ------------------
    
    437
    -    norm_fun w1 w2 (Scaled w t1) t2 ws
    
    438
    -      = case (optHsWrapper w1, optHsWrapper w2) of
    
    455
    +    mk_wp_fun w1 w2 sty1@(Scaled w t1) ty2 ws
    
    456
    +      = case (w1, w2) of
    
    439 457
               (WpHole,     WpHole)     -> ws
    
    440
    -          (WpLet {},   WpHole)     -> ws
    
    441 458
               (WpHole,     WpCast co2) -> co_ify (mkRepReflCo t1) co2
    
    442
    -          (WpCast co1, WpHole)     -> co_ify (mkSymCo co1)    (mkRepReflCo t2)
    
    459
    +          (WpCast co1, WpHole)     -> co_ify (mkSymCo co1)    (mkRepReflCo ty2)
    
    443 460
               (WpCast co1, WpCast co2) -> co_ify (mkSymCo co1)    co2
    
    444
    -          (w1',        w2')        -> WpFun w1' w2' (Scaled w t1) t2 : ws
    
    461
    +          (w1',        w2')        -> WpFun w1' w2' sty1 ty2 : ws
    
    445 462
           where
    
    446
    -        co_ify co1 co2 = norm_co (mk_wp_fun_co w co1 co2) ws
    
    463
    +        co_ify co1 co2 = opt_co (mk_wp_fun_co w co1 co2) ws
    
    447 464
     
    
    448 465
     pushWpLet :: TcEvBinds -> [HsWrapper] -> Maybe [HsWrapper]
    
    449 466
     pushWpLet tc_ev_binds ws
    
    450 467
       | EvBinds binds <- tc_ev_binds
    
    451 468
       , Just env <- evBindIdSwizzle binds
    
    452
    -  = case go env ws of
    
    453
    -         WpLet {} : _  -> Nothing
    
    454
    -         ws'           -> Just ws'
    
    469
    +  = go env ws
    
    455 470
       | otherwise
    
    456 471
       = Nothing
    
    457 472
       where
    
    458
    -    go :: IdEnv Id -> [HsWrapper] -> [HsWrapper]
    
    459
    -    go env (WpTyApp ty : ws') = WpTyApp ty : go env ws'
    
    460
    -    go env (WpCast co  : ws') = WpCast co  : go env ws'
    
    461
    -    go env (WpTyLam tv : ws')
    
    462
    -       | not (tv_captures env tv)
    
    463
    -       = WpTyLam tv : go env ws'
    
    464
    -
    
    465
    -    go env (WpEvLam ev : ws')
    
    466
    -       | not (ev `elemVarEnv` env)   -- `ev` must not be in the domain
    
    467
    -       , not (anyVarEnv (== ev) env) --      or range of `env`
    
    468
    -       = WpEvLam ev : go env ws'
    
    469
    -
    
    470
    -    go env (WpEvApp (EvExpr (Var v)) : ws')
    
    471
    -       | Just v' <- swizzleId env v
    
    472
    -       = WpEvApp (EvExpr (Var v')) : go env ws'
    
    473
    -
    
    474
    -    go _ ws = WpLet tc_ev_binds : ws
    
    475
    -
    
    476
    -    tv_captures :: IdEnv Id -> TyVar -> Bool
    
    477
    -    tv_captures env tv = anyVarEnv bad env
    
    478
    -        where
    
    479
    -          bad id = anyFreeVarsOfType (== tv) (idType id)
    
    480
    -
    
    473
    +    go :: IdEnv Id -> [HsWrapper] -> Maybe [HsWrapper]
    
    474
    +    go env (WpCast co  : ws) = do { ws' <- go env ws
    
    475
    +                                  ; return (WpCast co  : ws') }
    
    476
    +    go env (WpTyApp ty : ws) = do { ws' <- go env ws
    
    477
    +                                  ; return (WpTyApp ty : ws') }
    
    478
    +    go env (WpEvApp (EvExpr (Var v)) : ws)
    
    479
    +       = do { v'  <- swizzleId env v
    
    480
    +            ; ws' <- go env ws
    
    481
    +            ; return (WpEvApp (EvExpr (Var v')) : ws') }
    
    482
    +
    
    483
    +    go _ ws = case ws of
    
    484
    +                 []    -> Just []
    
    485
    +                 (_:_) -> Nothing  -- Could not fully eliminate it
    
    481 486
     
    
    482 487
     swizzleId :: IdEnv Id -> Id -> Maybe Id
    
    483 488
     -- Nothing <=> ran out of fuel
    
    ... ... @@ -1158,7 +1163,8 @@ pprHsWrapper wrap pp_thing_inside
    1158 1163
         -- True  <=> appears in function application position
    
    1159 1164
         -- False <=> appears as body of let or lambda
    
    1160 1165
         help it WpHole             = it
    
    1161
    -    help it (WpCompose f1 f2)  = help (help it f2) f1
    
    1166
    +    help it (WpCompose w1 w2)  = help (help it w2) w1
    
    1167
    +    help it (WpSubType w)      = no_parens $ text "subtype" <> braces (help it w False)
    
    1162 1168
         help it (WpFun f1 f2 (Scaled w t1) _) = add_parens $ text "\\(x" <> dcolon <> brackets (ppr w) <> ppr t1 <> text ")." <+>
    
    1163 1169
                                                 help (\_ -> it True <+> help (\_ -> text "x") f1 True) f2 False
    
    1164 1170
         help it (WpCast co)   = add_parens $ sep [it False, nest 2 (text "|>"
    

  • compiler/GHC/Tc/Utils/Unify.hs
    ... ... @@ -1426,11 +1426,12 @@ tcSubTypeDS :: HsExpr GhcRn
    1426 1426
                                -- DeepSubsumption <=> when checking, this type
    
    1427 1427
                                --                     is deeply skolemised
    
    1428 1428
                 -> TcM HsWrapper
    
    1429
    --- Only one call site, in GHC.Tc.Gen.App.tcApp
    
    1429
    +-- Only one call site, in GHC.Tc.Gen.App.checkResultTy
    
    1430 1430
     tcSubTypeDS rn_expr act_rho exp_rho
    
    1431
    -  = tc_sub_type_deep Top (unifyExprType rn_expr) orig GenSigCtxt act_rho exp_rho
    
    1432
    -  where
    
    1433
    -    orig = exprCtOrigin rn_expr
    
    1431
    +  = do { wrap <- tc_sub_type_deep Top (unifyExprType rn_expr)
    
    1432
    +                                  (exprCtOrigin rn_expr)
    
    1433
    +                                  GenSigCtxt act_rho exp_rho
    
    1434
    +       ; return (mkWpSubType wrap) }
    
    1434 1435
     
    
    1435 1436
     ---------------
    
    1436 1437
     
    
    ... ... @@ -1503,7 +1504,8 @@ tc_sub_type :: (TcType -> TcType -> TcM TcCoercionN) -- How to unify
    1503 1504
     ----------------------
    
    1504 1505
     tc_sub_type unify inst_orig ctxt ty_actual ty_expected
    
    1505 1506
       = do { ds_flag <- getDeepSubsumptionFlag
    
    1506
    -       ; tc_sub_type_ds Top ds_flag unify inst_orig ctxt ty_actual ty_expected }
    
    1507
    +       ; wrap <- tc_sub_type_ds Top ds_flag unify inst_orig ctxt ty_actual ty_expected
    
    1508
    +       ; return (mkWpSubType wrap) }
    
    1507 1509
     
    
    1508 1510
     ----------------------
    
    1509 1511
     tc_sub_type_ds :: Position p -- ^ position in the type (for error messages only)
    

  • compiler/GHC/Tc/Zonk/Type.hs
    ... ... @@ -1231,6 +1231,8 @@ zonk_cmd_top (HsCmdTop (CmdTopTc stack_tys ty ids) cmd)
    1231 1231
     -------------------------------------------------------------------------
    
    1232 1232
     zonkCoFn :: HsWrapper -> ZonkBndrTcM HsWrapper
    
    1233 1233
     zonkCoFn WpHole   = return WpHole
    
    1234
    +zonkCoFn (WpSubType w)     = do { w' <- zonkCoFn w
    
    1235
    +                                ; return (WpSubType w') }
    
    1234 1236
     zonkCoFn (WpCompose c1 c2) = do { c1' <- zonkCoFn c1
    
    1235 1237
                                     ; c2' <- zonkCoFn c2
    
    1236 1238
                                     ; return (WpCompose c1' c2') }