mirrored from https://gitlab.haskell.org/ghc/ghc.git
/
TcSimplify.lhs
1462 lines (1217 loc) · 62.3 KB
/
TcSimplify.lhs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\begin{code}
{-# OPTIONS -fno-warn-tabs -Wwarn #-}
-- The above warning supression flag is a temporary kludge.
-- While working on this module you are encouraged to remove it and
-- detab the module (please do the detabbing in a separate patch). See
-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
-- for details
module TcSimplify(
simplifyInfer, simplifyAmbiguityCheck,
simplifyDefault, simplifyDeriv,
simplifyRule, simplifyTop, simplifyInteractive
) where
#include "HsVersions.h"
import TcRnMonad
import TcErrors
import TcMType
import TcType
import TcSMonad
import TcInteract
import InstEnv ( lookupInstEnv )
import Inst
import Unify ( niFixTvSubst, niSubstTvSet )
import Type ( classifyPredType, getClassPredTys, getClassPredTys_maybe, PredTree(..) )
import Var
import VarSet
import VarEnv
import TcEvidence
import TypeRep
import Name
import Bag
import ListSetOps
import Util
import PrelInfo
import PrelNames
import Class ( classKey )
import BasicTypes ( RuleName )
import Control.Monad ( when )
import Data.List ( partition )
import Outputable
import FastString
import TrieMap () -- DV: for now
import DynFlags
\end{code}
*********************************************************************************
* *
* External interface *
* *
*********************************************************************************
\begin{code}
simplifyTop :: WantedConstraints -> TcM (Bag EvBind)
-- Simplify top-level constraints
-- Usually these will be implications,
-- but when there is nothing to quantify we don't wrap
-- in a degenerate implication, so we do that here instead
simplifyTop wanteds
= simplifyCheck (SimplCheck (ptext (sLit "top level"))) wanteds
------------------
simplifyAmbiguityCheck :: Name -> WantedConstraints -> TcM (Bag EvBind)
simplifyAmbiguityCheck name wanteds
= simplifyCheck (SimplCheck (ptext (sLit "ambiguity check for") <+> ppr name)) wanteds
------------------
simplifyInteractive :: WantedConstraints -> TcM (Bag EvBind)
simplifyInteractive wanteds
= simplifyCheck SimplInteractive wanteds
------------------
simplifyDefault :: ThetaType -- Wanted; has no type variables in it
-> TcM () -- Succeeds iff the constraint is soluble
simplifyDefault theta
= do { wanted <- newFlatWanteds DefaultOrigin theta
; _ignored_ev_binds <- simplifyCheck (SimplCheck (ptext (sLit "defaults")))
(mkFlatWC wanted)
; return () }
\end{code}
***********************************************************************************
* *
* Deriving *
* *
***********************************************************************************
\begin{code}
simplifyDeriv :: CtOrigin
-> PredType
-> [TyVar]
-> ThetaType -- Wanted
-> TcM ThetaType -- Needed
-- Given instance (wanted) => C inst_ty
-- Simplify 'wanted' as much as possibles
-- Fail if not possible
simplifyDeriv orig pred tvs theta
= do { (skol_subst, tvs_skols) <- tcInstSkolTyVars tvs -- Skolemize
-- The constraint solving machinery
-- expects *TcTyVars* not TyVars.
-- We use *non-overlappable* (vanilla) skolems
-- See Note [Overlap and deriving]
; let subst_skol = zipTopTvSubst tvs_skols $ map mkTyVarTy tvs
skol_set = mkVarSet tvs_skols
doc = parens $ ptext (sLit "deriving") <+> parens (ppr pred)
; wanted <- newFlatWanteds orig (substTheta skol_subst theta)
; traceTc "simplifyDeriv" (pprTvBndrs tvs $$ ppr theta $$ ppr wanted)
; (residual_wanted, _ev_binds1)
<- runTcS (SimplInfer doc) NoUntouchables emptyInert emptyWorkList $
solveWanteds $ mkFlatWC wanted
; let (good, bad) = partitionBagWith get_good (wc_flat residual_wanted)
-- See Note [Exotic derived instance contexts]
get_good :: Ct -> Either PredType Ct
get_good ct | validDerivPred skol_set p = Left p
| otherwise = Right ct
where p = ctPred ct
-- We never want to defer these errors because they are errors in the
-- compiler! Hence the `False` below
; _ev_binds2 <- reportUnsolved False (residual_wanted { wc_flat = bad })
; let min_theta = mkMinimalBySCs (bagToList good)
; return (substTheta subst_skol min_theta) }
\end{code}
Note [Overlap and deriving]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider some overlapping instances:
data Show a => Show [a] where ..
data Show [Char] where ...
Now a data type with deriving:
data T a = MkT [a] deriving( Show )
We want to get the derived instance
instance Show [a] => Show (T a) where...
and NOT
instance Show a => Show (T a) where...
so that the (Show (T Char)) instance does the Right Thing
It's very like the situation when we're inferring the type
of a function
f x = show [x]
and we want to infer
f :: Show [a] => a -> String
BOTTOM LINE: use vanilla, non-overlappable skolems when inferring
the context for the derived instance.
Hence tcInstSkolTyVars not tcInstSuperSkolTyVars
Note [Exotic derived instance contexts]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In a 'derived' instance declaration, we *infer* the context. It's a
bit unclear what rules we should apply for this; the Haskell report is
silent. Obviously, constraints like (Eq a) are fine, but what about
data T f a = MkT (f a) deriving( Eq )
where we'd get an Eq (f a) constraint. That's probably fine too.
One could go further: consider
data T a b c = MkT (Foo a b c) deriving( Eq )
instance (C Int a, Eq b, Eq c) => Eq (Foo a b c)
Notice that this instance (just) satisfies the Paterson termination
conditions. Then we *could* derive an instance decl like this:
instance (C Int a, Eq b, Eq c) => Eq (T a b c)
even though there is no instance for (C Int a), because there just
*might* be an instance for, say, (C Int Bool) at a site where we
need the equality instance for T's.
However, this seems pretty exotic, and it's quite tricky to allow
this, and yet give sensible error messages in the (much more common)
case where we really want that instance decl for C.
So for now we simply require that the derived instance context
should have only type-variable constraints.
Here is another example:
data Fix f = In (f (Fix f)) deriving( Eq )
Here, if we are prepared to allow -XUndecidableInstances we
could derive the instance
instance Eq (f (Fix f)) => Eq (Fix f)
but this is so delicate that I don't think it should happen inside
'deriving'. If you want this, write it yourself!
NB: if you want to lift this condition, make sure you still meet the
termination conditions! If not, the deriving mechanism generates
larger and larger constraints. Example:
data Succ a = S a
data Seq a = Cons a (Seq (Succ a)) | Nil deriving Show
Note the lack of a Show instance for Succ. First we'll generate
instance (Show (Succ a), Show a) => Show (Seq a)
and then
instance (Show (Succ (Succ a)), Show (Succ a), Show a) => Show (Seq a)
and so on. Instead we want to complain of no instance for (Show (Succ a)).
The bottom line
~~~~~~~~~~~~~~~
Allow constraints which consist only of type variables, with no repeats.
*********************************************************************************
* *
* Inference
* *
***********************************************************************************
Note [Which variables to quantify]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Suppose the inferred type of a function is
T kappa (alpha:kappa) -> Int
where alpha is a type unification variable and
kappa is a kind unification variable
Then we want to quantify over *both* alpha and kappa. But notice that
kappa appears "at top level" of the type, as well as inside the kind
of alpha. So it should be fine to just look for the "top level"
kind/type variables of the type, without looking transitively into the
kinds of those type variables.
\begin{code}
simplifyInfer :: Bool
-> Bool -- Apply monomorphism restriction
-> [(Name, TcTauType)] -- Variables to be generalised,
-- and their tau-types
-> WantedConstraints
-> TcM ([TcTyVar], -- Quantify over these type variables
[EvVar], -- ... and these constraints
Bool, -- The monomorphism restriction did something
-- so the results type is not as general as
-- it could be
TcEvBinds) -- ... binding these evidence variables
simplifyInfer top_lvl apply_mr name_taus wanteds
| isEmptyWC wanteds
= do { gbl_tvs <- tcGetGlobalTyVars -- Already zonked
; zonked_taus <- zonkTcTypes (map snd name_taus)
; let tvs_to_quantify = varSetElems (tyVarsOfTypes zonked_taus `minusVarSet` gbl_tvs)
-- tvs_to_quantify can contain both kind and type vars
-- See Note [Which variables to quantify]
; qtvs <- zonkQuantifiedTyVars tvs_to_quantify
; return (qtvs, [], False, emptyTcEvBinds) }
| otherwise
= do { zonked_wanteds <- zonkWC wanteds
; gbl_tvs <- tcGetGlobalTyVars
; zonked_tau_tvs <- zonkTyVarsAndFV (tyVarsOfTypes (map snd name_taus))
; runtimeCoercionErrors <- doptM Opt_DeferTypeErrors
; traceTc "simplifyInfer {" $ vcat
[ ptext (sLit "names =") <+> ppr (map fst name_taus)
, ptext (sLit "taus =") <+> ppr (map snd name_taus)
, ptext (sLit "tau_tvs (zonked) =") <+> ppr zonked_tau_tvs
, ptext (sLit "gbl_tvs =") <+> ppr gbl_tvs
, ptext (sLit "closed =") <+> ppr top_lvl
, ptext (sLit "apply_mr =") <+> ppr apply_mr
, ptext (sLit "wanted =") <+> ppr zonked_wanteds
]
-- Step 2
-- Now simplify the possibly-bound constraints
; let ctxt = SimplInfer (ppr (map fst name_taus))
; (simpl_results, _binds)
<- runTcS ctxt NoUntouchables emptyInert emptyWorkList $
simplifyWithApprox zonked_wanteds
-- Step 3
-- Split again simplified_perhaps_bound, because some unifications
-- may have happened, and emit the free constraints.
; gbl_tvs <- tcGetGlobalTyVars
; zonked_tau_tvs <- zonkTyVarsAndFV zonked_tau_tvs
; zonked_results <- zonkWC simpl_results
; (quantifiable_preds, rest_wc) <- quantifiablePreds apply_mr zonked_results
; let full_gbl_tvs = gbl_tvs `unionVarSet` tyVarsOfWC rest_wc
init_tvs = zonked_tau_tvs `minusVarSet` full_gbl_tvs
qtvs = growPreds1 full_gbl_tvs quantifiable_preds init_tvs
minimal_flat_preds = filter (quantifyMe qtvs) quantifiable_preds
-- Monomorphism restriction bites if the natural polymorphsim
-- (tau_tvs - gbl_tvs) is not the same as the actual polymorphism
mr_bites = not ((zonked_tau_tvs `minusVarSet` gbl_tvs) `subVarSet` qtvs)
; let skol_info = InferSkol [ (name, mkSigmaTy [] minimal_flat_preds ty)
| (name, ty) <- name_taus ]
-- Don't add the quantified variables here, because
-- they are also bound in ic_skols and we want them to be
-- tidied uniformly
; qtvs_to_return <- zonkQuantifiedTyVars (varSetElems qtvs)
; minimal_bound_ev_vars <- mapM TcMType.newEvVar minimal_flat_preds
; ev_binds_var <- newTcEvBinds
; lcl_env <- getLclTypeEnv
; gloc <- getCtLoc skol_info
; let implic = Implic { ic_untch = NoUntouchables
, ic_env = lcl_env
, ic_skols = qtvs_to_return
, ic_given = minimal_bound_ev_vars
, ic_wanted = wanteds
, ic_insol = False
, ic_binds = ev_binds_var
, ic_loc = gloc }
; emitImplication implic
; traceTc "} simplifyInfer/produced residual implication for quantification" $
vcat [ ptext (sLit "implic =") <+> ppr implic
-- ic_skols, ic_given give rest of result
, ptext (sLit "qtvs =") <+> ppr qtvs
, ptext (sLit "qtvs_to_return =") <+> ppr qtvs_to_return
, ptext (sLit "init_tvs =") <+> ppr init_tvs
, ptext (sLit "full_gbl_tvs =") <+> ppr full_gbl_tvs
, ptext (sLit "rest_wc =") <+> ppr rest_wc
, ptext (sLit "spb =") <+> ppr quantifiable_preds
, ptext (sLit "bound =") <+> ppr minimal_flat_preds ]
; return ( qtvs_to_return, minimal_bound_ev_vars
, mr_bites, TcEvBinds ev_binds_var) }
------------
{-
-- Step 1
-- Make a guess at the quantified type variables
-- Then split the constraints on the baisis of those tyvars
-- to avoid unnecessarily simplifying a class constraint
-- See Note [Avoid unecessary constraint simplification]
; let proto_qtvs = growWanteds gbl_tvs zonked_wanteds $
zonked_tau_tvs `minusVarSet` gbl_tvs
(perhaps_bound, surely_free)
= partitionBag (quantifyMe proto_qtvs) (wc_flat zonked_wanteds)
; traceTc "simplifyInfer proto" $ vcat
[ ptext (sLit "zonked_tau_tvs =") <+> ppr zonked_tau_tvs
, ptext (sLit "proto_qtvs =") <+> ppr proto_qtvs
, ptext (sLit "surely_fref =") <+> ppr surely_free
]
; emitFlats surely_free
; traceTc "sinf" $ vcat
[ ptext (sLit "perhaps_bound =") <+> ppr perhaps_bound
, ptext (sLit "surely_free =") <+> ppr surely_free
]
-- Step 2
-- Now simplify the possibly-bound constraints
; let ctxt = SimplInfer (ppr (map fst name_taus))
; (simpl_results, tc_binds)
<- runTcS ctxt NoUntouchables emptyInert emptyWorkList $
simplifyWithApprox (zonked_wanteds { wc_flat = perhaps_bound })
-- Fail fast if there is an insoluble constraint,
-- unless we are deferring errors to runtime
; when (not runtimeCoercionErrors && insolubleWC simpl_results) $
do { _ev_binds <- reportUnsolved False simpl_results
; failM }
-- Step 3
-- Split again simplified_perhaps_bound, because some unifications
-- may have happened, and emit the free constraints.
; gbl_tvs <- tcGetGlobalTyVars
; zonked_tau_tvs <- zonkTyVarsAndFV zonked_tau_tvs
; zonked_flats <- zonkCts (wc_flat simpl_results)
; let init_tvs = zonked_tau_tvs `minusVarSet` gbl_tvs
poly_qtvs = growWantedEVs gbl_tvs zonked_flats init_tvs
(pbound, pfree) = partitionBag (quantifyMe poly_qtvs) zonked_flats
-- Monomorphism restriction
mr_qtvs = init_tvs `minusVarSet` constrained_tvs
constrained_tvs = tyVarsOfCts zonked_flats
mr_bites = apply_mr && not (isEmptyBag pbound)
(qtvs, (bound, free))
| mr_bites = (mr_qtvs, (emptyBag, zonked_flats))
| otherwise = (poly_qtvs, (pbound, pfree))
; emitFlats free
; if isEmptyVarSet qtvs && isEmptyBag bound
then ASSERT( isEmptyBag (wc_insol simpl_results) )
do { traceTc "} simplifyInfer/no quantification" empty
; emitImplications (wc_impl simpl_results)
; return ([], [], mr_bites, EvBinds tc_binds) }
else do
-- Step 4, zonk quantified variables
{ qtvs_to_return <- zonkQuantifiedTyVars (varSetElems qtvs)
-- Step 5
-- Minimize `bound' and emit an implication
; minimal_flat_preds <- predsToQuantify bound
}
; let skol_info = InferSkol [ (name, mkSigmaTy [] minimal_flat_preds ty)
| (name, ty) <- name_taus ]
-- Don't add the quantified variables here, because
-- they are also bound in ic_skols and we want them to be
-- tidied uniformly
; minimal_bound_ev_vars <- mapM TcMType.newEvVar minimal_flat_preds
; ev_binds_var <- newTcEvBinds
; mapBagM_ (\(EvBind evar etrm) -> addTcEvBind ev_binds_var evar etrm)
tc_binds
; lcl_env <- getLclTypeEnv
; gloc <- getCtLoc skol_info
; let implic = Implic { ic_untch = NoUntouchables
, ic_env = lcl_env
, ic_skols = qtvs_to_return
, ic_given = minimal_bound_ev_vars
, ic_wanted = simpl_results { wc_flat = bound }
, ic_insol = False
, ic_binds = ev_binds_var
, ic_loc = gloc }
; emitImplication implic
; traceTc "} simplifyInfer/produced residual implication for quantification" $
vcat [ ptext (sLit "implic =") <+> ppr implic
-- ic_skols, ic_given give rest of result
, ptext (sLit "qtvs =") <+> ppr qtvs_to_return
, ptext (sLit "spb =") <+> ppr zonked_flats
, ptext (sLit "bound =") <+> ppr bound ]
; return ( qtvs_to_return, minimal_bound_ev_vars
, mr_bites, TcEvBinds ev_binds_var) } }
-}
quantifiablePreds :: Bool -> WantedConstraints -> TcM ([PredType], WantedConstraints)
-- From a bunch of (non-insoluble) flat constraints, pick the ones to generalise
-- an inferred type over. In particular:
-- * Omit superclasses: (Eq a, Ord a) ---> Ord a
-- * Reject non-tyvar clases: (Eq a, Show (Tree b)) --> Eq a
quantifiablePreds apply_mr wc
| apply_mr
= return ([], wc)
| otherwise
= do { inst_envs <- tcGetInstEnvs
; let (quant_flats, non_quant_flats) = partitionBag quantifiable (wc_flat wc)
quantifiable ct
| Just (cls, tys) <- getClassPredTys_maybe (ctPred ct)
= isTyVarClassApp cls tys
|| case lookupInstEnv inst_envs cls tys of
([], [], _) -> False
(_, _, _) -> True
| otherwise
= True
; return (map ctPred (bagToList quant_flats), wc { wc_flat = non_quant_flats }) }
\end{code}
Note [Minimize by Superclasses]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When we quantify over a constraint, in simplifyInfer we need to
quantify over a constraint that is minimal in some sense: For
instance, if the final wanted constraint is (Eq alpha, Ord alpha),
we'd like to quantify over Ord alpha, because we can just get Eq alpha
from superclass selection from Ord alpha. This minimization is what
mkMinimalBySCs does. Then, simplifyInfer uses the minimal constraint
to check the original wanted.
\begin{code}
simplifyWithApprox :: WantedConstraints -> TcS WantedConstraints
-- Post: returns only wanteds (no deriveds)
simplifyWithApprox wanted
= do { traceTcS "simplifyApproxLoop" (ppr wanted)
; let all_flats = wc_flat wanted `unionBags` keepWanted (wc_insol wanted)
; implics_from_flats <- solveInteractCts $ bagToList all_flats
; unsolved_implics <- simpl_loop 1 (wc_impl wanted `unionBags`
implics_from_flats)
; let (residual_implics,floats) = approximateImplications unsolved_implics
-- Solve extra stuff for real: notice that all the extra unsolved constraints will
-- be in the inerts of the monad, so we are OK
; traceTcS "simplifyApproxLoop" $ text "Calling solve_wanteds!"
; wants_or_ders <- solve_wanteds (WC { wc_flat = floats -- They are floated so they are not in the evvar cache
, wc_impl = residual_implics
, wc_insol = emptyBag })
; return $
wants_or_ders { wc_flat = keepWanted (wc_flat wants_or_ders) } }
approximateImplications :: Bag Implication -> (Bag Implication, Cts)
-- Extracts any nested constraints that don't mention the skolems
approximateImplications impls
= do_bag (float_implic emptyVarSet) impls
where
do_bag :: forall a b c. (a -> (Bag b, Bag c)) -> Bag a -> (Bag b, Bag c)
do_bag f = foldrBag (plus . f) (emptyBag, emptyBag)
plus :: forall b c. (Bag b, Bag c) -> (Bag b, Bag c) -> (Bag b, Bag c)
plus (a1,b1) (a2,b2) = (a1 `unionBags` a2, b1 `unionBags` b2)
float_implic :: TyVarSet -> Implication -> (Bag Implication, Cts)
float_implic skols imp
= (unitBag (imp { ic_wanted = wanted' }), floats)
where
(wanted', floats) = float_wc (skols `extendVarSetList` ic_skols imp) (ic_wanted imp)
float_wc skols wc@(WC { wc_flat = flat, wc_impl = implic })
= (wc { wc_flat = flat', wc_impl = implic' }, floats1 `unionBags` floats2)
where
(flat', floats1) = do_bag (float_flat skols) flat
(implic', floats2) = do_bag (float_implic skols) implic
float_flat :: TcTyVarSet -> Ct -> (Cts, Cts)
float_flat skols ct
| tyVarsOfCt ct `disjointVarSet` skols = (emptyBag, unitBag ct)
| otherwise = (unitBag ct, emptyBag)
\end{code}
\begin{code}
-- (growX gbls wanted tvs) grows a seed 'tvs' against the
-- X-constraint 'wanted', nuking the 'gbls' at each stage
-- It's conservative in that if the seed could *possibly*
-- grow to include a type variable, then it does
growWanteds :: TyVarSet -> WantedConstraints -> TyVarSet -> TyVarSet
growWanteds gbl_tvs wc = fixVarSet (growWC gbl_tvs wc)
growWantedEVs :: TyVarSet -> Cts -> TyVarSet -> TyVarSet
growWantedEVs gbl_tvs ws tvs
| isEmptyBag ws = tvs
| otherwise = fixVarSet (growPreds gbl_tvs ctPred ws) tvs
-------- Helper functions, do not do fixpoint ------------------------
growWC :: TyVarSet -> WantedConstraints -> TyVarSet -> TyVarSet
growWC gbl_tvs wc = growImplics gbl_tvs (wc_impl wc) .
growPreds gbl_tvs ctPred (wc_flat wc) .
growPreds gbl_tvs ctPred (wc_insol wc)
growImplics :: TyVarSet -> Bag Implication -> TyVarSet -> TyVarSet
growImplics gbl_tvs implics tvs
= foldrBag grow_implic tvs implics
where
grow_implic implic tvs
= grow tvs `delVarSetList` ic_skols implic
where
grow = growWC gbl_tvs (ic_wanted implic) .
growPreds gbl_tvs evVarPred (listToBag (ic_given implic))
-- We must grow from givens too; see test IPRun
growPreds :: TyVarSet -> (a -> PredType) -> Bag a -> TyVarSet -> TyVarSet
growPreds gbl_tvs get_pred items tvs
= foldrBag extend tvs items
where
extend item tvs = tvs `unionVarSet`
(growPredTyVars (get_pred item) tvs `minusVarSet` gbl_tvs)
growPreds1 :: TyVarSet -> [PredType] -> TyVarSet -> TyVarSet
growPreds1 gbl_tvs items tvs
= foldr extend tvs items
where
extend item tvs = tvs `unionVarSet`
(growPredTyVars item tvs `minusVarSet` gbl_tvs)
--------------------
quantifyMe :: TyVarSet -- Quantifying over these
-> PredType
-> Bool -- True <=> quantify over this wanted
quantifyMe qtvs pred
| isIPPred pred = True -- Note [Inheriting implicit parameters]
| otherwise = tyVarsOfType pred `intersectsVarSet` qtvs
\end{code}
Note [Avoid unecessary constraint simplification]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When inferring the type of a let-binding, with simplifyInfer,
try to avoid unnecessariliy simplifying class constraints.
Doing so aids sharing, but it also helps with delicate
situations like
instance C t => C [t] where ..
f :: C [t] => ....
f x = let g y = ...(constraint C [t])...
in ...
When inferring a type for 'g', we don't want to apply the
instance decl, because then we can't satisfy (C t). So we
just notice that g isn't quantified over 't' and partition
the contraints before simplifying.
This only half-works, but then let-generalisation only half-works.
Note [Inheriting implicit parameters]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider this:
f x = (x::Int) + ?y
where f is *not* a top-level binding.
From the RHS of f we'll get the constraint (?y::Int).
There are two types we might infer for f:
f :: Int -> Int
(so we get ?y from the context of f's definition), or
f :: (?y::Int) => Int -> Int
At first you might think the first was better, becuase then
?y behaves like a free variable of the definition, rather than
having to be passed at each call site. But of course, the WHOLE
IDEA is that ?y should be passed at each call site (that's what
dynamic binding means) so we'd better infer the second.
BOTTOM LINE: when *inferring types* you *must* quantify
over implicit parameters. See the predicate isFreeWhenInferring.
*********************************************************************************
* *
* RULES *
* *
***********************************************************************************
See note [Simplifying RULE consraints] in TcRule
Note [RULE quanfification over equalities]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Decideing which equalities to quantify over is tricky:
* We do not want to quantify over insoluble equalities (Int ~ Bool)
(a) because we prefer to report a LHS type error
(b) because if such things end up in 'givens' we get a bogus
"inaccessible code" error
* But we do want to quantify over things like (a ~ F b), where
F is a type function.
The difficulty is that it's hard to tell what is insoluble!
So we see whether the simplificaiotn step yielded any type errors,
and if so refrain from quantifying over *any* equalites.
\begin{code}
simplifyRule :: RuleName
-> WantedConstraints -- Constraints from LHS
-> WantedConstraints -- Constraints from RHS
-> TcM ([EvVar], WantedConstraints) -- LHS evidence varaibles
-- See Note [Simplifying RULE constraints] in TcRule
simplifyRule name lhs_wanted rhs_wanted
= do { zonked_all <- zonkWC (lhs_wanted `andWC` rhs_wanted)
; let doc = ptext (sLit "LHS of rule") <+> doubleQuotes (ftext name)
untch = NoUntouchables
-- We allow ourselves to unify environment
-- variables; hence NoUntouchables
; (resid_wanted, _) <- runTcS (SimplInfer doc) untch emptyInert emptyWorkList $
solveWanteds zonked_all
; zonked_lhs <- zonkWC lhs_wanted
; let (q_cts, non_q_cts) = partitionBag quantify_me (wc_flat zonked_lhs)
quantify_me -- Note [RULE quantification over equalities]
| insolubleWC resid_wanted = quantify_insol
| otherwise = quantify_normal
quantify_insol ct = not (isEqPred (ctPred ct))
quantify_normal ct
| EqPred t1 t2 <- classifyPredType (ctPred ct)
= not (t1 `eqType` t2)
| otherwise
= True
; traceTc "simplifyRule" $
vcat [ text "zonked_lhs" <+> ppr zonked_lhs
, text "q_cts" <+> ppr q_cts ]
; return (map ctId (bagToList q_cts), zonked_lhs { wc_flat = non_q_cts }) }
\end{code}
*********************************************************************************
* *
* Main Simplifier *
* *
***********************************************************************************
\begin{code}
simplifyCheck :: SimplContext
-> WantedConstraints -- Wanted
-> TcM (Bag EvBind)
-- Solve a single, top-level implication constraint
-- e.g. typically one created from a top-level type signature
-- f :: forall a. [a] -> [a]
-- f x = rhs
-- We do this even if the function has no polymorphism:
-- g :: Int -> Int
-- g y = rhs
-- (whereas for *nested* bindings we would not create
-- an implication constraint for g at all.)
--
-- Fails if can't solve something in the input wanteds
simplifyCheck ctxt wanteds
= do { wanteds <- zonkWC wanteds
; traceTc "simplifyCheck {" (vcat
[ ptext (sLit "wanted =") <+> ppr wanteds ])
; (unsolved, eb1)
<- runTcS ctxt NoUntouchables emptyInert emptyWorkList $
solveWanteds wanteds
; traceTc "simplifyCheck }" $ ptext (sLit "unsolved =") <+> ppr unsolved
; traceTc "reportUnsolved {" empty
-- See Note [Deferring coercion errors to runtime]
; runtimeCoercionErrors <- doptM Opt_DeferTypeErrors
; eb2 <- reportUnsolved runtimeCoercionErrors unsolved
; traceTc "reportUnsolved }" empty
; return (eb1 `unionBags` eb2) }
\end{code}
Note [Deferring coercion errors to runtime]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
While developing, sometimes it is desirable to allow compilation to succeed even
if there are type errors in the code. Consider the following case:
module Main where
a :: Int
a = 'a'
main = print "b"
Even though `a` is ill-typed, it is not used in the end, so if all that we're
interested in is `main` it is handy to be able to ignore the problems in `a`.
Since we treat type equalities as evidence, this is relatively simple. Whenever
we run into a type mismatch in TcUnify, we normally just emit an error. But it
is always safe to defer the mismatch to the main constraint solver. If we do
that, `a` will get transformed into
co :: Int ~ Char
co = ...
a :: Int
a = 'a' `cast` co
The constraint solver would realize that `co` is an insoluble constraint, and
emit an error with `reportUnsolved`. But we can also replace the right-hand side
of `co` with `error "Deferred type error: Int ~ Char"`. This allows the program
to compile, and it will run fine unless we evaluate `a`. This is what
`deferErrorsToRuntime` does.
It does this by keeping track of which errors correspond to which coercion
in TcErrors (with ErrEnv). TcErrors.reportTidyWanteds does not print the errors
and does not fail if -fwarn-type-errors is on, so that we can continue
compilation. The errors are turned into warnings in `reportUnsolved`.
\begin{code}
solveWanteds :: WantedConstraints -> TcS WantedConstraints
-- Returns: residual constraints, plus evidence bindings
-- NB: When we are called from TcM there are no inerts to pass down to TcS
solveWanteds wanted
= do { wc_out <- solve_wanteds wanted
; let wc_ret = wc_out { wc_flat = keepWanted (wc_flat wc_out) }
-- Discard Derived
; return wc_ret }
solve_wanteds :: WantedConstraints
-> TcS WantedConstraints -- NB: wc_flats may be wanted *or* derived now
solve_wanteds wanted@(WC { wc_flat = flats, wc_impl = implics, wc_insol = insols })
= do { traceTcS "solveWanteds {" (ppr wanted)
-- Try the flat bit
-- Discard from insols all the derived/given constraints
-- because they will show up again when we try to solve
-- everything else. Solving them a second time is a bit
-- of a waste, but the code is simple, and the program is
-- wrong anyway!
; let all_flats = flats `unionBags` keepWanted insols
; impls_from_flats <- solveInteractCts $ bagToList all_flats
-- solve_wanteds iterates when it is able to float equalities
-- out of one or more of the implications.
; unsolved_implics <- simpl_loop 1 (implics `unionBags` impls_from_flats)
; (insoluble_flats,unsolved_flats) <- extractUnsolvedTcS
; bb <- getTcEvBindsMap
; tb <- getTcSTyBindsMap
; traceTcS "solveWanteds }" $
vcat [ text "unsolved_flats =" <+> ppr unsolved_flats
, text "unsolved_implics =" <+> ppr unsolved_implics
, text "current evbinds =" <+> ppr (evBindMapBinds bb)
, text "current tybinds =" <+> vcat (map ppr (varEnvElts tb))
]
; (subst, remaining_unsolved_flats) <- solveCTyFunEqs unsolved_flats
-- See Note [Solving Family Equations]
-- NB: remaining_flats has already had subst applied
; traceTcS "solveWanteds finished with" $
vcat [ text "remaining_unsolved_flats =" <+> ppr remaining_unsolved_flats
, text "subst =" <+> ppr subst
]
; return $
WC { wc_flat = mapBag (substCt subst) remaining_unsolved_flats
, wc_impl = mapBag (substImplication subst) unsolved_implics
, wc_insol = mapBag (substCt subst) insoluble_flats }
}
simpl_loop :: Int
-> Bag Implication
-> TcS (Bag Implication)
simpl_loop n implics
| n > 10
= traceTcS "solveWanteds: loop!" empty >> return implics
| otherwise
= do { (implic_eqs, unsolved_implics) <- solveNestedImplications implics
; inerts <- getTcSInerts
; let ((_,unsolved_flats),_) = extractUnsolved inerts
; improve_eqs <- if not (isEmptyBag implic_eqs)
then return implic_eqs
else applyDefaultingRules unsolved_flats
; traceTcS "solveWanteds: simpl_loop end" $
vcat [ text "improve_eqs =" <+> ppr improve_eqs
, text "unsolved_flats =" <+> ppr unsolved_flats
, text "unsolved_implics =" <+> ppr unsolved_implics ]
; if isEmptyBag improve_eqs then return unsolved_implics
else do { impls_from_eqs <- solveInteractCts $ bagToList improve_eqs
; simpl_loop (n+1) (unsolved_implics `unionBags`
impls_from_eqs)} }
solveNestedImplications :: Bag Implication
-> TcS (Cts, Bag Implication)
-- Precondition: the TcS inerts may contain unsolved flats which have
-- to be converted to givens before we go inside a nested implication.
solveNestedImplications implics
| isEmptyBag implics
= return (emptyBag, emptyBag)
| otherwise
= do { inerts <- getTcSInerts
; let ((_insoluble_flats, unsolved_flats),thinner_inerts) = extractUnsolved inerts
; (implic_eqs, unsolved_implics)
<- doWithInert thinner_inerts $
do { let pushed_givens = givens_from_wanteds unsolved_flats
tcs_untouchables = filterVarSet isFlexiTcsTv $
tyVarsOfCts unsolved_flats
-- See Note [Preparing inert set for implications]
-- Push the unsolved wanteds inwards, but as givens
; traceTcS "solveWanteds: preparing inerts for implications {" $
vcat [ppr tcs_untouchables, ppr pushed_givens]
; impls_from_givens <- solveInteractCts pushed_givens
; MASSERT (isEmptyBag impls_from_givens)
; traceTcS "solveWanteds: } now doing nested implications {" empty
; flatMapBagPairM (solveImplication tcs_untouchables) implics }
-- ... and we are back in the original TcS inerts
-- Notice that the original includes the _insoluble_flats so it was safe to ignore
-- them in the beginning of this function.
; traceTcS "solveWanteds: done nested implications }" $
vcat [ text "implic_eqs =" <+> ppr implic_eqs
, text "unsolved_implics =" <+> ppr unsolved_implics ]
; return (implic_eqs, unsolved_implics) }
where givens_from_wanteds = foldrBag get_wanted []
get_wanted cc rest_givens
| pushable_wanted cc
= let fl = cc_flavor cc
wloc = flav_wloc fl
gfl = Given (mkGivenLoc wloc UnkSkol) (flav_evar fl)
this_given = cc { cc_flavor = gfl }
in this_given : rest_givens
| otherwise = rest_givens
pushable_wanted :: Ct -> Bool
pushable_wanted cc
| isWantedCt cc
= isEqPred (ctPred cc) -- see Note [Preparing inert set for implications]
| otherwise = False
solveImplication :: TcTyVarSet -- Untouchable TcS unification variables
-> Implication -- Wanted
-> TcS (Cts, -- All wanted or derived floated equalities: var = type
Bag Implication) -- Unsolved rest (always empty or singleton)
-- Precondition: The TcS monad contains an empty worklist and given-only inerts
-- which after trying to solve this implication we must restore to their original value
solveImplication tcs_untouchables
imp@(Implic { ic_untch = untch
, ic_binds = ev_binds
, ic_skols = skols
, ic_given = givens
, ic_wanted = wanteds
, ic_loc = loc })
= nestImplicTcS ev_binds (untch, tcs_untouchables) $
recoverTcS (return (emptyBag, emptyBag)) $
-- Recover from nested failures. Even the top level is
-- just a bunch of implications, so failing at the first one is bad
do { traceTcS "solveImplication {" (ppr imp)
-- Solve flat givens
; impls_from_givens <- solveInteractGiven loc givens
; MASSERT (isEmptyBag impls_from_givens)
-- Simplify the wanteds
; WC { wc_flat = unsolved_flats
, wc_impl = unsolved_implics
, wc_insol = insols } <- solve_wanteds wanteds
; let (res_flat_free, res_flat_bound)
= floatEqualities skols givens unsolved_flats
final_flat = keepWanted res_flat_bound
; let res_wanted = WC { wc_flat = final_flat
, wc_impl = unsolved_implics
, wc_insol = insols }
res_implic = unitImplication $
imp { ic_wanted = res_wanted
, ic_insol = insolubleWC res_wanted }
; evbinds <- getTcEvBindsMap
; traceTcS "solveImplication end }" $ vcat
[ text "res_flat_free =" <+> ppr res_flat_free
, text "implication evbinds = " <+> ppr (evBindMapBinds evbinds)
, text "res_implic =" <+> ppr res_implic ]
; return (res_flat_free, res_implic) }
-- and we are back to the original inerts
floatEqualities :: [TcTyVar] -> [EvVar] -> Cts -> (Cts, Cts)
-- Post: The returned FlavoredEvVar's are only Wanted or Derived
-- and come from the input wanted ev vars or deriveds
floatEqualities skols can_given wantders
| hasEqualities can_given = (emptyBag, wantders)
-- Note [Float Equalities out of Implications]
| otherwise = partitionBag is_floatable wantders
-- TODO: Maybe we should try out /not/ floating constraints that contain touchables only,
-- since they are inert and not going to interact with anything more in a more global scope.
where skol_set = mkVarSet skols
is_floatable :: Ct -> Bool
is_floatable ct
| ct_predty <- ctPred ct
, isEqPred ct_predty
= skol_set `disjointVarSet` tvs_under_fsks ct_predty
is_floatable _ct = False
tvs_under_fsks :: Type -> TyVarSet
-- ^ NB: for type synonyms tvs_under_fsks does /not/ expand the synonym
tvs_under_fsks (TyVarTy tv)
| not (isTcTyVar tv) = unitVarSet tv
| FlatSkol ty <- tcTyVarDetails tv = tvs_under_fsks ty
| otherwise = unitVarSet tv
tvs_under_fsks (TyConApp _ tys) = unionVarSets (map tvs_under_fsks tys)
tvs_under_fsks (LitTy {}) = emptyVarSet
tvs_under_fsks (FunTy arg res) = tvs_under_fsks arg `unionVarSet` tvs_under_fsks res
tvs_under_fsks (AppTy fun arg) = tvs_under_fsks fun `unionVarSet` tvs_under_fsks arg
tvs_under_fsks (ForAllTy tv ty) -- The kind of a coercion binder
-- can mention type variables!
| isTyVar tv = inner_tvs `delVarSet` tv
| otherwise {- Coercion -} = -- ASSERT( not (tv `elemVarSet` inner_tvs) )
inner_tvs `unionVarSet` tvs_under_fsks (tyVarKind tv)
where
inner_tvs = tvs_under_fsks ty
\end{code}
Note [Preparing inert set for implications]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Before solving the nested implications, we convert any unsolved flat wanteds
to givens, and add them to the inert set. Reasons:
a) In checking mode, suppresses unnecessary errors. We already have
on unsolved-wanted error; adding it to the givens prevents any
consequential errors from showing up
b) More importantly, in inference mode, we are going to quantify over this
constraint, and we *don't* want to quantify over any constraints that
are deducible from it.
c) Flattened type-family equalities must be exposed to the nested
constraints. Consider
F b ~ alpha, (forall c. F b ~ alpha)
Obviously this is soluble with [alpha := F b]. But the
unification is only done by solveCTyFunEqs, right at the end of
solveWanteds, and if we aren't careful we'll end up with an
unsolved goal inside the implication. We need to "push" the
as-yes-unsolved (F b ~ alpha) inwards, as a *given*, so that it
can be used to solve the inner (F b
~ alpha). See Trac #4935.