Simon Peyton Jones pushed to branch wip/T23162-part2 at Glasgow Haskell Compiler / GHC

Commits:

6 changed files:

Changes:

  • compiler/GHC/Tc/Errors/Ppr.hs
    ... ... @@ -167,9 +167,11 @@ instance Diagnostic TcRnMessage where
    167 167
           -> mkSimpleDecorated $ pprSolverReportWithCtxt msg
    
    168 168
         TcRnSolverDepthError ty depth -> mkSimpleDecorated msg
    
    169 169
           where
    
    170
    +        pp_type_or_constraint | isConstraintLikeKind (typeKind ty) = text "constraint"
    
    171
    +                              | otherwise                          = text "type"
    
    170 172
             msg =
    
    171 173
               vcat [ text "Reduction stack overflow; size =" <+> ppr depth
    
    172
    -               , hang (text "When simplifying the following type:")
    
    174
    +               , hang (text "When simplifying the following" <+> pp_type_or_constraint <> colon)
    
    173 175
                         2 (ppr ty) ]
    
    174 176
         TcRnRedundantConstraints redundants (info, show_info)
    
    175 177
           -> mkSimpleDecorated $
    

  • compiler/GHC/Tc/Solver/Equality.hs
    ... ... @@ -349,11 +349,11 @@ can_eq_nc True _rdr_env _envs ev ReprEq ty1 _ ty2 _
    349 349
     can_eq_nc _rewritten rdr_env envs ev eq_rel ty1 ps_ty1 ty2 ps_ty2
    
    350 350
       | ReprEq <- eq_rel
    
    351 351
       , Just stuff1 <- tcTopNormaliseNewTypeTF_maybe envs rdr_env ty1
    
    352
    -  = can_eq_newtype_nc rdr_env envs ev NotSwapped ty1 stuff1 ty2 ps_ty2
    
    352
    +  = can_eq_newtype_nc rdr_env envs ev NotSwapped stuff1 ty2 ps_ty2
    
    353 353
     
    
    354 354
       | ReprEq <- eq_rel
    
    355 355
       , Just stuff2 <- tcTopNormaliseNewTypeTF_maybe envs rdr_env ty2
    
    356
    -  = can_eq_newtype_nc rdr_env envs ev IsSwapped ty2 stuff2 ty1 ps_ty1
    
    356
    +  = can_eq_newtype_nc rdr_env envs ev IsSwapped stuff2 ty1 ps_ty1
    
    357 357
     
    
    358 358
     -- Then, get rid of casts
    
    359 359
     can_eq_nc rewritten rdr_env envs ev eq_rel (CastTy ty1 co1) _ ty2 ps_ty2
    
    ... ... @@ -777,18 +777,17 @@ though, because we check our depth in `can_eq_newtype_nc`.
    777 777
     can_eq_newtype_nc :: GlobalRdrEnv -> FamInstEnvs
    
    778 778
                       -> CtEvidence           -- ^ :: ty1 ~ ty2
    
    779 779
                       -> SwapFlag
    
    780
    -                  -> TcType                                    -- ^ ty1
    
    781 780
                       -> ((Bag GlobalRdrElt, TcCoercion), TcType)  -- ^ :: ty1 ~ ty1'
    
    782 781
                       -> TcType               -- ^ ty2
    
    783 782
                       -> TcType               -- ^ ty2, with type synonyms
    
    784 783
                       -> TcS (StopOrContinue (Either IrredCt EqCt))
    
    785
    -can_eq_newtype_nc rdr_env envs ev swapped ty1 ((gres, co1), ty1') ty2 ps_ty2
    
    784
    +can_eq_newtype_nc rdr_env envs ev swapped ((gres, co1), ty1') ty2 ps_ty2
    
    786 785
       = do { traceTcS "can_eq_newtype_nc" $
    
    787 786
              vcat [ ppr ev, ppr swapped, ppr co1, ppr gres, ppr ty1', ppr ty2 ]
    
    788 787
     
    
    789 788
              -- Check for blowing our stack, and increase the depth
    
    790 789
              -- See Note [Newtypes can blow the stack]
    
    791
    -       ; loc' <- bumpReductionDepth (ctEvLoc ev) ty1
    
    790
    +       ; loc' <- bumpReductionDepth (ctEvLoc ev) (ctEvPred ev)
    
    792 791
            ; let ev' = ev `setCtEvLoc` loc'
    
    793 792
     
    
    794 793
              -- Next, we record uses of newtype constructors, since coercing
    

  • compiler/GHC/Tc/Solver/FunDeps.hs
    ... ... @@ -38,6 +38,7 @@ import GHC.Utils.Panic
    38 38
     
    
    39 39
     import GHC.Data.Pair
    
    40 40
     import Data.Maybe( isNothing, isJust, mapMaybe )
    
    41
    +import Control.Monad( void )
    
    41 42
     
    
    42 43
     
    
    43 44
     {- Note [Overview of functional dependencies in type inference]
    
    ... ... @@ -303,17 +304,20 @@ tryDictFunDeps :: DictCt -> SolverStage ()
    303 304
     
    
    304 305
     tryDictFunDeps dict_ct
    
    305 306
       = do { -- Note [Do local fundeps before top-level instances]
    
    306
    -         tryDictFunDepsLocal dict_ct
    
    307
    -       ; tryDictFunDepsTop   dict_ct }
    
    307
    +         insoluble <- tryDictFunDepsLocal dict_ct
    
    308
    +       ; if insoluble
    
    309
    +         then nopStage ()
    
    310
    +         else tryDictFunDepsTop dict_ct }
    
    308 311
     
    
    309
    -tryDictFunDepsLocal :: DictCt -> SolverStage ()
    
    312
    +tryDictFunDepsLocal :: DictCt -> SolverStage Bool
    
    310 313
     -- Using functional dependencies, interact the DictCt with the
    
    311 314
     -- inert Givens and Wanteds, to produce new equalities
    
    315
    +-- Returns True if the fundeps are insoluble
    
    312 316
     tryDictFunDepsLocal dict_ct@(DictCt { di_cls = cls, di_ev = work_ev })
    
    313 317
       | isGiven work_ev
    
    314 318
       = -- If work_ev is Given, there could in principle be some inert Wanteds
    
    315 319
         -- but in practice there never are because we solve Givens first
    
    316
    -    nopStage ()
    
    320
    +    nopStage False
    
    317 321
     
    
    318 322
       | otherwise
    
    319 323
       = Stage $
    
    ... ... @@ -324,14 +328,15 @@ tryDictFunDepsLocal dict_ct@(DictCt { di_cls = cls, di_ev = work_ev })
    324 328
            ; let eqns :: [FunDepEqns]
    
    325 329
                  eqns = foldr ((++) . do_interaction) [] $
    
    326 330
                         findDictsByClass (inert_dicts inerts) cls
    
    327
    -       ; imp <- solveFunDeps work_ev eqns
    
    331
    +       ; (insoluble, unif_happened) <- solveFunDeps work_ev eqns
    
    328 332
     
    
    329 333
            ; traceTcS "tryDictFunDepsLocal }" $
    
    330
    -         text "imp =" <+> ppr imp $$ text "eqns = " <+> ppr eqns
    
    334
    +         text "unif =" <+> ppr unif_happened $$ text "eqns = " <+> ppr eqns
    
    331 335
     
    
    332
    -       ; if imp then startAgainWith (CDictCan dict_ct)
    
    333
    -                     -- See (DFL1) of Note [Do fundeps last]
    
    334
    -                else continueWith () }
    
    336
    +       -- See (DFL1) of Note [Do fundeps last]
    
    337
    +       ; if insoluble          then continueWith True
    
    338
    +         else if unif_happened then startAgainWith (CDictCan dict_ct)
    
    339
    +                               else continueWith False }
    
    335 340
       where
    
    336 341
         work_pred     = ctEvPred work_ev
    
    337 342
         work_is_given = isGiven work_ev
    
    ... ... @@ -356,11 +361,12 @@ tryDictFunDepsTop dict_ct@(DictCt { di_ev = ev, di_cls = cls, di_tys = xis })
    356 361
            ; traceTcS "tryDictFunDepsTop {" (ppr dict_ct)
    
    357 362
            ; let eqns :: [FunDepEqns]
    
    358 363
                  eqns = improveFromInstEnv inst_envs cls xis
    
    359
    -       ; imp <- solveFunDeps ev eqns
    
    360
    -       ; traceTcS "tryDictFunDepsTop }" (text "imp =" <+> ppr imp)
    
    364
    +       ; (insoluble, unif_happened) <- solveFunDeps ev eqns
    
    365
    +       ; traceTcS "tryDictFunDepsTop }" (text "unif =" <+> ppr unif_happened)
    
    361 366
     
    
    362
    -       ; if imp then startAgainWith (CDictCan dict_ct)
    
    363
    -                else continueWith () }
    
    367
    +       ; if not insoluble && unif_happened
    
    368
    +         then startAgainWith (CDictCan dict_ct)
    
    369
    +         else continueWith () }
    
    364 370
     
    
    365 371
     {- Note [No Given/Given fundeps]
    
    366 372
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -481,12 +487,12 @@ tryFamEqFunDeps eqs_for_me fam_tc work_args
    481 487
       = if isGiven ev
    
    482 488
         then tryGivenBuiltinFamEqFDs eqs_for_me fam_tc ops work_args work_item
    
    483 489
         else do { -- Note [Do local fundeps before top-level instances]
    
    484
    -              tryFDEqns fam_tc work_args work_item $
    
    485
    -              mkLocalBuiltinFamEqFDs eqs_for_me fam_tc ops work_args work_rhs
    
    490
    +              insoluble <- tryFDEqns fam_tc work_args work_item $
    
    491
    +                           mkLocalBuiltinFamEqFDs eqs_for_me fam_tc ops work_args work_rhs
    
    486 492
     
    
    487
    -            ; if hasRelevantGiven eqs_for_me work_args work_item
    
    493
    +            ; if insoluble || hasRelevantGiven eqs_for_me work_args work_item
    
    488 494
                 ; then nopStage ()
    
    489
    -              else tryFDEqns fam_tc work_args work_item $
    
    495
    +              else void $ tryFDEqns fam_tc work_args work_item $
    
    490 496
                        mkTopBuiltinFamEqFDs fam_tc ops work_args work_rhs }
    
    491 497
     
    
    492 498
       | isGiven ev    -- See (INJFAM:Given)
    
    ... ... @@ -496,15 +502,16 @@ tryFamEqFunDeps eqs_for_me fam_tc work_args
    496 502
     
    
    497 503
       | otherwise   -- Wanted, user-defined type families
    
    498 504
       = do { -- Note [Do local fundeps before top-level instances]
    
    499
    -         case tyConInjectivityInfo fam_tc of
    
    500
    -           NotInjective  -> nopStage()
    
    505
    +         insoluble <- case tyConInjectivityInfo fam_tc of
    
    506
    +           NotInjective  -> nopStage False
    
    501 507
                Injective inj -> tryFDEqns fam_tc work_args work_item $
    
    502 508
                                 mkLocalFamEqFDs eqs_for_me fam_tc inj work_args work_rhs
    
    503 509
     
    
    504
    -       ; if hasRelevantGiven eqs_for_me work_args work_item
    
    510
    +       ; if insoluble || hasRelevantGiven eqs_for_me work_args work_item
    
    505 511
              then nopStage ()
    
    506
    -         else tryFDEqns fam_tc work_args work_item $
    
    507
    -              mkTopFamEqFDs fam_tc work_args work_rhs }
    
    512
    +         else void $ tryFDEqns fam_tc work_args work_item $
    
    513
    +              mkTopFamEqFDs fam_tc work_args work_rhs
    
    514
    +       ; nopStage () }
    
    508 515
     
    
    509 516
     mkTopFamEqFDs :: TyCon -> [TcType] -> Xi -> TcS [FunDepEqns]
    
    510 517
     mkTopFamEqFDs fam_tc work_args work_rhs
    
    ... ... @@ -526,17 +533,19 @@ mkTopFamEqFDs fam_tc work_args work_rhs
    526 533
         -- closed type families with no equations (isClosedFamilyTyCon_maybe returns Nothing)
    
    527 534
         return []
    
    528 535
     
    
    529
    -tryFDEqns :: TyCon -> [TcType] -> EqCt -> TcS [FunDepEqns] -> SolverStage ()
    
    536
    +tryFDEqns :: TyCon -> [TcType] -> EqCt -> TcS [FunDepEqns] -> SolverStage Bool
    
    537
    +-- Returns True <=> some of the fundep eqns were insoluble
    
    530 538
     tryFDEqns fam_tc work_args work_item@(EqCt { eq_ev = ev, eq_rhs= rhs }) mk_fd_eqns
    
    531 539
       = Stage $
    
    532 540
         do { fd_eqns <- mk_fd_eqns
    
    533 541
            ; traceTcS "tryFDEqns" (vcat [ text "lhs:" <+> ppr fam_tc <+> ppr work_args
    
    534 542
                                         , text "rhs:" <+> ppr rhs
    
    535 543
                                         , text "eqns:" <+> ppr fd_eqns ])
    
    536
    -       ; imp <- solveFunDeps ev fd_eqns
    
    544
    +       ; (insoluble, unif_happened) <- solveFunDeps ev fd_eqns
    
    537 545
     
    
    538
    -       ; if imp then startAgainWith (CEqCan work_item)
    
    539
    -                else continueWith () }
    
    546
    +       ; if insoluble          then continueWith True
    
    547
    +         else if unif_happened then startAgainWith (CEqCan work_item)
    
    548
    +                               else continueWith False }
    
    540 549
     
    
    541 550
     -----------------------------------------
    
    542 551
     --  User-defined type families
    
    ... ... @@ -878,7 +887,8 @@ solving.
    878 887
     
    
    879 888
     solveFunDeps :: CtEvidence  -- The work item
    
    880 889
                  -> [FunDepEqns]
    
    881
    -             -> TcS Bool
    
    890
    +             -> TcS ( Bool   -- True <=> some insoluble fundeps
    
    891
    +                    , Bool ) -- True <=> unifications happened
    
    882 892
     -- Solve a bunch of type-equality equations, generated by functional dependencies
    
    883 893
     -- By "solve" we mean: (only) do unifications.  We do not generate evidence, and
    
    884 894
     -- other than unifications there should be no effects whatsoever
    
    ... ... @@ -888,12 +898,13 @@ solveFunDeps :: CtEvidence -- The work item
    888 898
     -- See (SOLVE-FD) in Note [Overview of functional dependencies in type inference]
    
    889 899
     solveFunDeps work_ev fd_eqns
    
    890 900
       | null fd_eqns
    
    891
    -  = return False -- Common case no-op
    
    901
    +  = return (False, False) -- Common case no-op
    
    892 902
     
    
    893 903
       | otherwise
    
    894
    -  = do { loc' <- bumpReductionDepth (ctEvLoc work_ev) (ctEvPred work_ev)
    
    904
    +  = do { traceTcS "bumping" (ppr work_ev)
    
    905
    +       ; loc' <- bumpReductionDepth (ctEvLoc work_ev) (ctEvPred work_ev)
    
    895 906
     
    
    896
    -       ; (unifs, _res)
    
    907
    +       ; (unifs, residual)
    
    897 908
                  <- reportFineGrainUnifications $
    
    898 909
                     nestFunDepsTcS              $
    
    899 910
                     TcS.pushTcLevelM_           $
    
    ... ... @@ -911,7 +922,7 @@ solveFunDeps work_ev fd_eqns
    911 922
            -- that were unified by the fundep
    
    912 923
            ; kickOutAfterUnification unifs
    
    913 924
     
    
    914
    -       ; return (not (isEmptyVarSet unifs)) }
    
    925
    +       ; return (insolubleWC residual, not (isEmptyVarSet unifs)) }
    
    915 926
       where
    
    916 927
         do_fundeps :: UnifyEnv -> TcM ()
    
    917 928
         do_fundeps env = mapM_ (do_one env) fd_eqns
    

  • compiler/GHC/Tc/Solver/Monad.hs
    ... ... @@ -2182,7 +2182,8 @@ newWantedNC loc rewriters pty
    2182 2182
     
    
    2183 2183
     -- | Checks if the depth of the given location is too much. Fails if
    
    2184 2184
     -- it's too big, with an appropriate error message.
    
    2185
    -bumpReductionDepth :: CtLoc -> TcType   -- ^ type being reduced
    
    2185
    +bumpReductionDepth :: CtLoc
    
    2186
    +                   -> TcType   -- ^ type or constraint being reduced
    
    2186 2187
                        -> TcS CtLoc
    
    2187 2188
     bumpReductionDepth loc ty
    
    2188 2189
       = do { dflags <- getDynFlags
    

  • compiler/GHC/Tc/Solver/Rewrite.hs
    ... ... @@ -11,7 +11,7 @@ import GHC.Tc.Types ( TcGblEnv(tcg_tc_plugin_rewriters),
    11 11
                           RewriteEnv(..),
    
    12 12
                           runTcPluginM )
    
    13 13
     import GHC.Tc.Types.Constraint
    
    14
    -import GHC.Tc.Types.CtLoc( CtLoc )
    
    14
    +import GHC.Tc.Types.CtLoc( CtLoc, resetCtLocDepth )
    
    15 15
     import GHC.Core.Predicate
    
    16 16
     import GHC.Tc.Utils.TcType
    
    17 17
     import GHC.Core.Type
    
    ... ... @@ -90,7 +90,8 @@ runRewriteCtEv ev
    90 90
     runRewrite :: CtLoc -> CtFlavour -> EqRel -> RewriteM a -> TcS (a, CoHoleSet)
    
    91 91
     runRewrite loc flav eq_rel thing_inside
    
    92 92
       = do { rewriters_ref <- newTcRef emptyCoHoleSet
    
    93
    -       ; let fmode = RE { re_loc       = loc
    
    93
    +       ; let fmode = RE { re_loc       = resetCtLocDepth loc
    
    94
    +                            -- Start reducing from zero
    
    94 95
                             , re_flavour   = flav
    
    95 96
                             , re_eq_rel    = eq_rel
    
    96 97
                             , re_rewriters = rewriters_ref }
    
    ... ... @@ -792,8 +793,7 @@ rewrite_fam_app tc tys -- Can be over-saturated
    792 793
     -- See Note [How to normalise a family application]
    
    793 794
     rewrite_exact_fam_app :: TyCon -> [TcType] -> RewriteM Reduction
    
    794 795
     rewrite_exact_fam_app tc tys
    
    795
    -  = bumpReductionDepthRM (mkTyConApp tc tys) $
    
    796
    -    do { -- Query the typechecking plugins for all their rewriting functions
    
    796
    +  = do { -- Query the typechecking plugins for all their rewriting functions
    
    797 797
              -- which apply to a type family application headed by the TyCon 'tc'.
    
    798 798
            ; tc_rewriters <- getTcPluginRewritersForTyCon tc
    
    799 799
     
    
    ... ... @@ -876,7 +876,8 @@ rewrite_exact_fam_app tc tys
    876 876
                -> Reduction -> RewriteM Reduction
    
    877 877
         finish use_cache redn
    
    878 878
           = do { -- rewrite the result: FINISH 1
    
    879
    -             final_redn <- rewrite_reduction redn
    
    879
    +             final_redn <- bumpReductionDepthRM (mkTyConApp tc tys) $
    
    880
    +                           rewrite_reduction redn
    
    880 881
                ; eq_rel <- getEqRel
    
    881 882
     
    
    882 883
                  -- extend the cache: FINISH 2
    

  • compiler/GHC/Tc/Types/CtLoc.hs
    ... ... @@ -3,7 +3,8 @@ module GHC.Tc.Types.CtLoc (
    3 3
       -- * CtLoc
    
    4 4
       CtLoc(..), ctLocSpan, ctLocEnv, ctLocLevel, ctLocOrigin,
    
    5 5
       ctLocTypeOrKind_maybe, toInvisibleLoc,
    
    6
    -  ctLocDepth, bumpCtLocDepth, isGivenLoc, mkGivenLoc, mkKindEqLoc,
    
    6
    +  ctLocDepth, bumpCtLocDepth, resetCtLocDepth,
    
    7
    +  isGivenLoc, mkGivenLoc, mkKindEqLoc,
    
    7 8
       setCtLocOrigin, updateCtLocOrigin, setCtLocEnv, setCtLocSpan,
    
    8 9
       pprCtLoc, adjustCtLoc, adjustCtLocTyConBinder,
    
    9 10
     
    
    ... ... @@ -196,6 +197,9 @@ setCtLocSpan ctl@(CtLoc { ctl_env = lcl }) loc = setCtLocEnv ctl (setCtLocRealLo
    196 197
     bumpCtLocDepth :: CtLoc -> CtLoc
    
    197 198
     bumpCtLocDepth loc@(CtLoc { ctl_depth = d }) = loc { ctl_depth = bumpSubGoalDepth d }
    
    198 199
     
    
    200
    +resetCtLocDepth :: CtLoc -> CtLoc
    
    201
    +resetCtLocDepth loc = loc { ctl_depth = initialSubGoalDepth }
    
    202
    +
    
    199 203
     setCtLocOrigin :: CtLoc -> CtOrigin -> CtLoc
    
    200 204
     setCtLocOrigin ctl orig = ctl { ctl_origin = orig }
    
    201 205