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

Commits:

6 changed files:

Changes:

  • compiler/GHC/Tc/Solver/Default.hs
    ... ... @@ -395,9 +395,11 @@ tryConstraintDefaulting wc
    395 395
       | isEmptyWC wc
    
    396 396
       = return wc
    
    397 397
       | otherwise
    
    398
    -  = do { (unif_happened, better_wc) <- reportCoarseGrainUnifications $
    
    399
    -                                       go_wc False wc
    
    400
    -         -- We may have done unifications; so solve again
    
    398
    +  = do { (outermost_unif_lvl, better_wc) <- reportCoarseGrainUnifications $
    
    399
    +                                            go_wc False wc
    
    400
    +
    
    401
    +       -- We may have done unifications; if so, solve again
    
    402
    +       ; let unif_happened = not (isInfiniteTcLevel outermost_unif_lvl)
    
    401 403
            ; solveAgainIf unif_happened better_wc }
    
    402 404
       where
    
    403 405
         go_wc :: Bool -> WantedConstraints -> TcS WantedConstraints
    
    ... ... @@ -414,14 +416,17 @@ tryConstraintDefaulting wc
    414 416
                            else return (Just ct) }
    
    415 417
     
    
    416 418
         go_implic :: Bool -> Implication -> TcS Implication
    
    417
    -    go_implic encl_eqs implic@(Implic { ic_status = status, ic_wanted = wanteds
    
    418
    -                                       , ic_given_eqs = given_eqs, ic_binds = binds })
    
    419
    +    go_implic encl_eqs implic@(Implic { ic_tclvl = tclvl
    
    420
    +                                      , ic_status = status, ic_wanted = wanteds
    
    421
    +                                      , ic_given_eqs = given_eqs, ic_binds = binds })
    
    419 422
           | isSolvedStatus status
    
    420 423
           = return implic  -- Nothing to solve inside here
    
    421 424
           | otherwise
    
    422 425
           = do { let encl_eqs' = encl_eqs || given_eqs /= NoGivenEqs
    
    423 426
     
    
    424
    -           ; wanteds' <- setEvBindsTcS binds $
    
    427
    +           ; wanteds' <- setTcLevelTcS tclvl $
    
    428
    +                         -- Set the levels so that reportCoareseGrainUnifications works
    
    429
    +                         setEvBindsTcS binds $
    
    425 430
                              -- defaultCallStack sets a binding, so
    
    426 431
                              -- we must set the correct binding group
    
    427 432
                              go_wc encl_eqs' wanteds
    
    ... ... @@ -660,7 +665,9 @@ Wrinkles:
    660 665
          f x = case x of T1 -> True
    
    661 666
     
    
    662 667
       Should we infer f :: T a -> Bool, or f :: T a -> a.  Both are valid, but
    
    663
    -  neither is more general than the other.
    
    668
    +  neither is more general than the other.   But by the time defaulting takes
    
    669
    +  place all let-bound variables have got their final types; defaulting won't
    
    670
    +  affect let-generalisation.
    
    664 671
     
    
    665 672
     (DE2) We still can't unify if there is a skolem-escape check, or an occurs check,
    
    666 673
       or it it'd mean unifying a TyVarTv with a non-tyvar.  It's only the
    

  • compiler/GHC/Tc/Solver/Monad.hs
    ... ... @@ -1877,18 +1877,18 @@ reportFineGrainUnifications (TcS thing_inside)
    1877 1877
            ; recordUnifications outer_wu unif_tvs
    
    1878 1878
            ; return (unif_tvs, res) }
    
    1879 1879
     
    
    1880
    -reportCoarseGrainUnifications :: TcS a -> TcS (Bool, a)
    
    1880
    +reportCoarseGrainUnifications :: TcS a -> TcS (TcLevel, a)
    
    1881 1881
     -- Record whether any useful unifications are done by thing_inside
    
    1882
    +-- Specifically: return the TcLevel of the outermost (smallest level)
    
    1883
    +--   unification variable that has been unified, or infiniteTcLevel if none
    
    1882 1884
     -- Remember to propagate the information to the enclosing context
    
    1883 1885
     reportCoarseGrainUnifications (TcS thing_inside)
    
    1884 1886
       = TcS $ \ env@(TcSEnv { tcs_what = outer_what }) ->
    
    1885 1887
         case outer_what of
    
    1886
    -      WU_None
    
    1887
    -        -> do { (unif_happened, _, res) <- report_coarse_grain_unifs env thing_inside
    
    1888
    -              ; return (unif_happened, res) }
    
    1888
    +      WU_None -> report_coarse_grain_unifs env thing_inside
    
    1889 1889
     
    
    1890 1890
           WU_Coarse outer_ul_ref
    
    1891
    -        -> do { (unif_happened, inner_ul, res) <- report_coarse_grain_unifs env thing_inside
    
    1891
    +        -> do { (inner_ul, res) <- report_coarse_grain_unifs env thing_inside
    
    1892 1892
     
    
    1893 1893
                   -- Propagate to outer_ul_ref
    
    1894 1894
                   ; outer_ul <- TcM.readTcRef outer_ul_ref
    
    ... ... @@ -1897,31 +1897,32 @@ reportCoarseGrainUnifications (TcS thing_inside)
    1897 1897
     
    
    1898 1898
                   ; TcM.traceTc "reportCoarse(Coarse)" $
    
    1899 1899
                     vcat [ text "outer_ul" <+> ppr outer_ul
    
    1900
    -                     , text "inner_ul" <+> ppr inner_ul
    
    1901
    -                     , text "unif_happened" <+> ppr unif_happened ]
    
    1902
    -              ; return (unif_happened, res) }
    
    1900
    +                     , text "inner_ul" <+> ppr inner_ul]
    
    1901
    +              ; return (inner_ul, res) }
    
    1903 1902
     
    
    1904 1903
           WU_Fine outer_tvs_ref
    
    1905 1904
             -> do { (unif_tvs,res) <- report_fine_grain_unifs env thing_inside
    
    1906
    -              ; let unif_happened = not (isEmptyVarSet unif_tvs)
    
    1907
    -              ; when unif_happened $
    
    1908
    -                TcM.updTcRef outer_tvs_ref (`unionVarSet` unif_tvs)
    
    1905
    +
    
    1906
    +              -- Propagate to outer_tvs_rev
    
    1907
    +              ; TcM.updTcRef outer_tvs_ref (`unionVarSet` unif_tvs)
    
    1908
    +
    
    1909
    +              ; let outermost_unif_lvl = minTcTyVarSetLevel unif_tvs
    
    1909 1910
                   ; TcM.traceTc "reportCoarse(Fine)" $
    
    1910 1911
                     vcat [ text "unif_tvs" <+> ppr unif_tvs
    
    1911
    -                     , text "unif_happened" <+> ppr unif_happened ]
    
    1912
    -              ; return (unif_happened, res) }
    
    1912
    +                     , text "unif_happened" <+> ppr outermost_unif_lvl ]
    
    1913
    +              ; return (outermost_unif_lvl, res) }
    
    1913 1914
     
    
    1914 1915
     report_coarse_grain_unifs :: TcSEnv -> (TcSEnv -> TcM a)
    
    1915
    -                          -> TcM (Bool, TcLevel, a)
    
    1916
    --- Returns (unif_happened, coarse_inner_ul, res)
    
    1916
    +                          -> TcM (TcLevel, a)
    
    1917
    +-- Returns the level number of the outermost
    
    1918
    +-- unification variable that is unified
    
    1917 1919
     report_coarse_grain_unifs env thing_inside
    
    1918 1920
       = do { inner_ul_ref <- TcM.newTcRef infiniteTcLevel
    
    1919 1921
            ; res <- thing_inside (env { tcs_what = WU_Coarse inner_ul_ref })
    
    1920
    -       ; inner_ul    <- TcM.readTcRef inner_ul_ref
    
    1921
    -       ; ambient_lvl <- TcM.getTcLevel
    
    1922
    -       ; let unif_happened = ambient_lvl `deeperThanOrSame` inner_ul
    
    1923
    -       ; return (unif_happened, inner_ul, res) }
    
    1924
    -
    
    1922
    +       ; inner_ul <- TcM.readTcRef inner_ul_ref
    
    1923
    +       ; TcM.traceTc "report_coarse" $
    
    1924
    +         text "inner_lvl ="   <+> ppr inner_ul
    
    1925
    +       ; return (inner_ul, res) }
    
    1925 1926
     
    
    1926 1927
     report_fine_grain_unifs :: TcSEnv -> (TcSEnv -> TcM a)
    
    1927 1928
                             -> TcM (TcTyVarSet, a)
    

  • compiler/GHC/Tc/Solver/Solve.hs
    ... ... @@ -118,28 +118,34 @@ simplify_loop n limit definitely_redo_implications
    118 118
                                 , int (lengthBag simples) <+> text "simples to solve" ])
    
    119 119
            ; traceTcS "simplify_loop: wc =" (ppr wc)
    
    120 120
     
    
    121
    -       ; (simple_unif_happened, wc1)
    
    121
    +       ; ambient_lvl <- getTcLevel
    
    122
    +       ; (simple_unif_lvl, wc1)
    
    122 123
                  <- reportCoarseGrainUnifications $  -- See Note [Superclass iteration]
    
    123 124
                     solveSimpleWanteds simples
    
    124 125
                     -- Any insoluble constraints are in 'simples' and so get rewritten
    
    125 126
                     -- See Note [Rewrite insolubles] in GHC.Tc.Solver.InertSet
    
    126 127
     
    
    127 128
            -- Next, solve implications from wc_impl
    
    128
    -       ; (impl_unif_happened, implics')
    
    129
    +       ; let simple_unif_happened = ambient_lvl `deeperThanOrSame` simple_unif_lvl
    
    130
    +       ; (implic_unif_lvl, implics')
    
    129 131
                  <- if not (definitely_redo_implications   -- See Note [Superclass iteration]
    
    130 132
                             || simple_unif_happened)       -- for this conditional
    
    131
    -                then return (False, implics)
    
    133
    +                then return (infiniteTcLevel, implics)
    
    132 134
                     else reportCoarseGrainUnifications $
    
    133 135
                          solveNestedImplications implics
    
    134 136
     
    
    135 137
            ; let wc' = wc1 { wc_impl = wc_impl wc1 `unionBags` implics' }
    
    136 138
     
    
    137
    -       ; csTraceTcS $ text "unif_happened" <+> ppr impl_unif_happened
    
    138
    -
    
    139 139
              -- We iterate the loop only if the /implications/ did some relevant
    
    140
    -         -- unification.  Even if the /simples/ did unifications we don't need
    
    141
    -         -- to re-do them.
    
    142
    -       ; maybe_simplify_again (n+1) limit impl_unif_happened wc' }
    
    140
    +         -- unification, hence looking only at `implic_unif_lvl`.  (Even if the
    
    141
    +         -- /simples/ did unifications we don't need to re-do them.)
    
    142
    +         -- Also note that we only iterate if `implic_unify_lvl` is /equal to/
    
    143
    +         -- the current level; if it is less , we'll iterate some outer level,
    
    144
    +         -- which will bring us back here anyway.
    
    145
    +         -- See Note [When to iterate the solver: unifications]
    
    146
    +       ; let implic_unif_happened = implic_unif_lvl `sameDepthAs` ambient_lvl
    
    147
    +       ; csTraceTcS $ text "implic_unif_happened" <+> ppr implic_unif_happened
    
    148
    +       ; maybe_simplify_again (n+1) limit implic_unif_happened wc' }
    
    143 149
     
    
    144 150
     data NextAction
    
    145 151
       = NA_Stop                 -- Just return the WantedConstraints
    
    ... ... @@ -148,7 +154,9 @@ data NextAction
    148 154
             Bool                -- See `definitely_redo_implications` in the comment
    
    149 155
                                 --    for `simplify_loop`
    
    150 156
     
    
    151
    -maybe_simplify_again :: Int -> IntWithInf -> Bool
    
    157
    +maybe_simplify_again :: Int -> IntWithInf
    
    158
    +                     -> Bool   -- True <=> Solving the implications did some unifications
    
    159
    +                               --          at the current level; so iterate
    
    152 160
                          -> WantedConstraints -> TcS WantedConstraints
    
    153 161
     maybe_simplify_again n limit unif_happened wc@(WC { wc_simple = simples })
    
    154 162
       = do { -- Look for reasons to stop or continue
    
    ... ... @@ -222,10 +230,10 @@ and if so it seems a pity to waste time iterating the implications (forall b. bl
    222 230
     (If we add new Given superclasses it's a different matter: it's really worth looking
    
    223 231
     at the implications.)
    
    224 232
     
    
    225
    -Hence the definitely_redo_implications flag to simplify_loop.  It's usually
    
    226
    -True, but False in the case where the only reason to iterate is new Wanted
    
    227
    -superclasses.  In that case we check whether the new Wanteds actually led to
    
    228
    -any new unifications, and iterate the implications only if so.
    
    233
    +Hence the `definitely_redo_implications` flag to `simplify_loop`.  It's usually True,
    
    234
    +but False in the case where the only reason to iterate is new Wanted superclasses.
    
    235
    +In that case we check whether the new Wanteds actually led to any new unifications
    
    236
    +(at all), and iterate the implications only if so.
    
    229 237
     
    
    230 238
     Note [When to iterate the solver: unifications]
    
    231 239
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    

  • compiler/GHC/Tc/Utils/TcType.hs
    ... ... @@ -45,7 +45,7 @@ module GHC.Tc.Utils.TcType (
    45 45
       TcLevel(..), topTcLevel, pushTcLevel, isTopTcLevel,
    
    46 46
       strictlyDeeperThan, deeperThanOrSame, sameDepthAs,
    
    47 47
       tcTypeLevel, tcTyVarLevel, maxTcLevel, minTcLevel,
    
    48
    -  infiniteTcLevel,
    
    48
    +  infiniteTcLevel, isInfiniteTcLevel,
    
    49 49
     
    
    50 50
       --------------------------------
    
    51 51
       -- MetaDetails
    
    ... ... @@ -879,6 +879,10 @@ isTopTcLevel :: TcLevel -> Bool
    879 879
     isTopTcLevel (TcLevel 0) = True
    
    880 880
     isTopTcLevel _            = False
    
    881 881
     
    
    882
    +isInfiniteTcLevel :: TcLevel -> Bool
    
    883
    +isInfiniteTcLevel QLInstVar = True
    
    884
    +isInfiniteTcLevel _         = False
    
    885
    +
    
    882 886
     pushTcLevel :: TcLevel -> TcLevel
    
    883 887
     -- See Note [TcLevel assignment]
    
    884 888
     pushTcLevel (TcLevel us) = TcLevel (us + 1)
    

  • testsuite/tests/typecheck/should_compile/T26582.hs
    1
    +{-# LANGUAGE GADTs #-}
    
    2
    +
    
    3
    +module T26582 where
    
    4
    +
    
    5
    +sametype :: a -> a -> Int
    
    6
    +sametype = sametype
    
    7
    +
    
    8
    +f :: Eq a => (a->Int) -> Int
    
    9
    +f = f
    
    10
    +
    
    11
    +data T b where T1 :: T Bool
    
    12
    +
    
    13
    +g1 :: T b -> Int
    
    14
    +g1 v = f (\x -> case v of { T1 -> sametype x True })
    
    15
    +
    
    16
    +g2 :: Eq c => c -> T b -> Int
    
    17
    +g2 c v = f (\x -> case v of { T1 -> sametype x c })
    
    18
    +
    
    19
    +{- The point is that we get something like
    
    20
    +
    
    21
    +     Wanted: [W] d : Eq alpha[1]
    
    22
    +     Implication
    
    23
    +       level:  2
    
    24
    +       Given:  b~Bool
    
    25
    +
    
    26
    +       Wanted: [W] alpha[1]~Bool       -- For g1
    
    27
    +       Wanted: [W] alpha[1]~c          -- For g2
    
    28
    +
    
    29
    +So alpha is untouchable under the (b~Bool) from the GADT.
    
    30
    +And yet in the end it's easy to solve
    
    31
    +via alpha:=Bool, or alpha:=c resp
    
    32
    +
    
    33
    +But having done that defaulting we must then remember to
    
    34
    +solved that `d : Eq alpha`!  We forgot to so so in #26582.
    
    35
    +-}

  • testsuite/tests/typecheck/should_compile/all.T
    ... ... @@ -956,3 +956,4 @@ test('T26457', normal, compile, [''])
    956 956
     test('T17705', normal, compile, [''])
    
    957 957
     test('T14745', normal, compile, [''])
    
    958 958
     test('T26451', normal, compile, [''])
    
    959
    +test('T26582', normal, compile, [''])