Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC

Commits:

5 changed files:

Changes:

  • compiler/GHC/Tc/Utils/Unify.hs
    ... ... @@ -1948,6 +1948,41 @@ the LHS vs the new RHS. And vice-versa (if it's the RHS that is a FunTy).
    1948 1948
     
    
    1949 1949
     See T11305 and T26225 for examples of when this is important.
    
    1950 1950
     
    
    1951
    +Wrinkle [Avoiding a loop in tc_sub_type_deep]
    
    1952
    +
    
    1953
    +  In #26823, we had:
    
    1954
    +
    
    1955
    +    alpha  <=  a -> alpha
    
    1956
    +
    
    1957
    +  If we simply unified the two types, the occurs-check would trigger.
    
    1958
    +  In deep subsumption however, we need to be careful, as we might do the
    
    1959
    +  following:
    
    1960
    +
    
    1961
    +    A1. Create fresh metavariables beta, gamma
    
    1962
    +    A2. Unify alpha ~ beta -> gamma
    
    1963
    +    A3. Decompose  "beta -> gamma <= a -> (beta -> gamma)", obtaining
    
    1964
    +              a <= beta  and  gamma <= beta -> gamma
    
    1965
    +    A4. Recur with gamma <= beta -> gamma
    
    1966
    +
    
    1967
    +  If we do this, we enter an infinite loop and GHC hangs at compile time.
    
    1968
    +  To avoid this, we must first recur, before unifying. So the above becomes:
    
    1969
    +
    
    1970
    +    B1 (like A1). Create fresh metavariables beta, gamma
    
    1971
    +    B2 (like A3). Decompose  "beta -> gamma <= a -> alpha", obtaining
    
    1972
    +          a <= beta  and  gamma <= alpha
    
    1973
    +    B3. Solve these two sub-problems by unification
    
    1974
    +          a ~ beta,   gamma ~ alpha
    
    1975
    +    B4 (like A2). Then, and only then, unify alpha ~ beta->gamma
    
    1976
    +
    
    1977
    +    With this approach, GHC will be left with the following unifications:
    
    1978
    +
    
    1979
    +      - alpha ~ (beta -> gamma)
    
    1980
    +      - a ~ beta
    
    1981
    +      - gamma ~ alpha
    
    1982
    +
    
    1983
    +    GHC will fail to solve this unification problem due to an occurs check
    
    1984
    +    failure, thus rejecting the program with a type error (as desired).
    
    1985
    +
    
    1951 1986
     Note [Deep subsumption and required foralls]
    
    1952 1987
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1953 1988
     A required forall, (forall a -> ty) behaves like a "rho-type", one with no
    
    ... ... @@ -2117,8 +2152,9 @@ tc_sub_type_deep fun_pos@(tc_fun, pos) ds_depth unify inst_orig ctxt ty_actual t
    2117 2152
                ; exp_arg  <- newOpenFlexiTyVarTy -- NB: no FRR check needed; we might not need to eta-expand
    
    2118 2153
                ; exp_res  <- newOpenFlexiTyVarTy
    
    2119 2154
                ; let exp_funTy = FunTy { ft_af = af1, ft_mult = exp_mult, ft_arg = exp_arg, ft_res = exp_res }
    
    2120
    -           ; unify_wrap <- just_unify exp_funTy ty_e
    
    2155
    +             -- Recur before unifying; see Wrinkle [Avoiding a loop in tc_sub_type_deep]
    
    2121 2156
                ; fun_wrap <- go_fun af1 act_mult act_arg act_res af1 exp_mult exp_arg exp_res
    
    2157
    +           ; unify_wrap <- just_unify exp_funTy ty_e
    
    2122 2158
                ; return $ unify_wrap <.> fun_wrap
    
    2123 2159
                  -- unify_wrap :: exp_funTy ~~> ty_e
    
    2124 2160
                  -- fun_wrap :: ty_a ~~> exp_funTy
    
    ... ... @@ -2129,8 +2165,9 @@ tc_sub_type_deep fun_pos@(tc_fun, pos) ds_depth unify inst_orig ctxt ty_actual t
    2129 2165
                ; act_arg  <- newOpenFlexiTyVarTy -- NB: no FRR check needed; we might not need to eta-expand
    
    2130 2166
                ; act_res  <- newOpenFlexiTyVarTy
    
    2131 2167
                ; let act_funTy = FunTy { ft_af = af2, ft_mult = act_mult, ft_arg = act_arg, ft_res = act_res }
    
    2132
    -           ; unify_wrap <- just_unify ty_a act_funTy
    
    2168
    +             -- Recur before unifying; see Wrinkle [Avoiding a loop in tc_sub_type_deep]
    
    2133 2169
                ; fun_wrap <- go_fun af2 act_mult act_arg act_res af2 exp_mult exp_arg exp_res
    
    2170
    +           ; unify_wrap <- just_unify ty_a act_funTy
    
    2134 2171
                ; return $ fun_wrap <.> unify_wrap
    
    2135 2172
                  -- unify_wrap :: ty_a ~~> act_funTy
    
    2136 2173
                  -- fun_wrap :: act_funTy ~~> ty_e
    

  • testsuite/tests/typecheck/should_compile/T26225.hs
    ... ... @@ -26,7 +26,7 @@ ex0 =
    26 26
       in g f
    
    27 27
     
    
    28 28
     -- ((∀ a. a->a) -> Int) -> Bool  ⊑  α[tau]
    
    29
    --- Rejected by GHC up to and including 9.14.
    
    29
    +-- Rejected by GHC up to and including 9.12.
    
    30 30
     ex1' :: ()
    
    31 31
     ex1' =
    
    32 32
       let
    
    ... ... @@ -38,7 +38,7 @@ ex1' =
    38 38
         -- Couldn't match expected type ‘α’ with actual type ‘((∀ a. a -> a) -> Int) -> Bool’
    
    39 39
     
    
    40 40
     -- ((∀ a. a->a) -> Int) -> Bool  ⊑  β[tau] Bool
    
    41
    --- Rejected by GHC up to and including 9.14.
    
    41
    +-- Rejected by GHC up to and including 9.12.
    
    42 42
     ex2' :: ()
    
    43 43
     ex2' =
    
    44 44
       let
    
    ... ... @@ -50,7 +50,7 @@ ex2' =
    50 50
         -- Couldn't match expected type ‘β’ with actual type ‘(->) ((∀ a. a -> a) -> Int)’
    
    51 51
     
    
    52 52
     -- ex3 ::  β[tau] Bool  ⊑  (∀ a. a->a) -> Bool
    
    53
    --- Rejected by GHC up to and including 9.14.
    
    53
    +-- Rejected by GHC up to and including 9.12.
    
    54 54
     ex3 :: ()
    
    55 55
     ex3 =
    
    56 56
       let
    
    ... ... @@ -62,7 +62,7 @@ ex3 =
    62 62
         -- Couldn't match expected type ‘β’ with actual type ‘(->) (∀ a. a -> a)’
    
    63 63
     
    
    64 64
     -- ex3' :: F Int Bool  ⊑  (∀ a. a->a) -> Bool, where F Int = (->) (Int -> Int)
    
    65
    --- Rejected by GHC up to and including 9.14.
    
    65
    +-- Rejected by GHC up to and including 9.12.
    
    66 66
     ex3' :: ()
    
    67 67
     ex3' =
    
    68 68
       let
    

  • testsuite/tests/typecheck/should_fail/T26823.hs
    1
    +{-# LANGUAGE DeepSubsumption #-}
    
    2
    +
    
    3
    +module T26823 where
    
    4
    +
    
    5
    +allocArray :: Int -> IO ()
    
    6
    +allocArray n = do
    
    7
    +  let
    
    8
    +    !off    = 18
    
    9
    +    !size   = 8
    
    10
    +    !vecAli = size
    
    11
    +
    
    12
    +    !rem   = off `rem` vecAli
    
    13
    +    !start = if rem == 0 then off else off + ( vecAli - rem )
    
    14
    +
    
    15
    +  return ()

  • testsuite/tests/typecheck/should_fail/T26823.stderr
    1
    +T26823.hs:12:14: error: [GHC-25897]
    
    2
    +    • Couldn't match expected type ‘a0 -> a0 -> t’ with actual type ‘t’
    
    3
    +      ‘t’ is a rigid type variable bound by
    
    4
    +        the inferred type of rem :: a0 -> a0 -> t
    
    5
    +        at T26823.hs:12:5-29
    
    6
    +    • In the expression: off `rem` vecAli
    
    7
    +      In an equation for ‘rem’: !rem = off `rem` vecAli
    
    8
    +      In a stmt of a 'do' block:
    
    9
    +        let !off = 18
    
    10
    +            !size = 8
    
    11
    +            !vecAli = size
    
    12
    +            !rem = off `rem` vecAli
    
    13
    +            !start = if rem == 0 then off else off + (vecAli - rem)
    
    14
    +    • Relevant bindings include
    
    15
    +        rem :: a0 -> a0 -> t (bound at T26823.hs:12:6)
    
    16
    +        off :: a0 (bound at T26823.hs:8:6)
    
    17
    +        vecAli :: a0 (bound at T26823.hs:10:6)
    
    18
    +        size :: a0 (bound at T26823.hs:9:6)
    
    19
    +
    
    20
    +T26823.hs:13:57: error: [GHC-27958]
    
    21
    +    • Couldn't match expected type ‘a0’
    
    22
    +                  with actual type ‘a0 -> a0 -> t0’
    
    23
    +    • In the second argument of ‘(-)’, namely ‘rem’
    
    24
    +      In the second argument of ‘(+)’, namely ‘(vecAli - rem)’
    
    25
    +      In the expression: off + (vecAli - rem)
    
    26
    +    • Relevant bindings include
    
    27
    +        start :: a0 (bound at T26823.hs:13:6)
    
    28
    +        rem :: forall {t}. a0 -> a0 -> t (bound at T26823.hs:12:6)
    
    29
    +        off :: a0 (bound at T26823.hs:8:6)
    
    30
    +        vecAli :: a0 (bound at T26823.hs:10:6)
    
    31
    +        size :: a0 (bound at T26823.hs:9:6)
    
    32
    +

  • testsuite/tests/typecheck/should_fail/all.T
    ... ... @@ -755,5 +755,6 @@ test('T23162a', normal, compile_fail, [''])
    755 755
     test('T23162b', normal, compile_fail, [''])
    
    756 756
     test('T23162c', normal, compile, [''])
    
    757 757
     test('T23162d', normal, compile, [''])
    
    758
    +test('T26823', normal, compile_fail, [''])
    
    758 759
     test('T26861', normal, compile_fail, [''])
    
    759 760
     test('T26862', normal, compile_fail, [''])