| ... |
... |
@@ -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 "|>"
|