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

Commits:

3 changed files:

Changes:

  • compiler/GHC/Tc/Utils/Unify.hs
    ... ... @@ -1853,8 +1853,8 @@ where we eta-expanded that (:). But now foldr expects an argument
    1853 1853
     with ->{Many} and gets an argument with ->{m1} or ->{m2}, and Lint
    
    1854 1854
     complains.
    
    1855 1855
     
    
    1856
    -The easiest solution was to use tcEqMult in tc_sub_type_deep, and
    
    1857
    -insist on equality. This is only in the DeepSubsumption code anyway.
    
    1856
    +The easiest solution was to unify the multiplicities in tc_sub_type_deep,
    
    1857
    +insisting on equality. This is only in the DeepSubsumption code anyway.
    
    1858 1858
     
    
    1859 1859
     Note [FunTy vs non-FunTy case in tc_sub_type_deep]
    
    1860 1860
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -2047,10 +2047,7 @@ tc_sub_type_deep pos unify inst_orig ctxt ty_actual ty_expected
    2047 2047
                               -- GenSigCtxt: See Note [Setting the argument context]
    
    2048 2048
                ; res_wrap  <- tc_sub_type_deep (Result pos) unify inst_orig ctxt act_res exp_res
    
    2049 2049
     
    
    2050
    -             -- See Note [Multiplicity in deep subsumption]
    
    2051
    -           ; tcEqMult inst_orig act_mult exp_mult
    
    2052
    -
    
    2053
    -           ; mkWpFun_FRR pos
    
    2050
    +           ; mkWpFun_FRR unify pos
    
    2054 2051
                    act_af act_mult act_arg act_res
    
    2055 2052
                    exp_af exp_mult exp_arg exp_res
    
    2056 2053
                    arg_wrap res_wrap
    
    ... ... @@ -2058,20 +2055,32 @@ tc_sub_type_deep pos unify inst_orig ctxt ty_actual ty_expected
    2058 2055
           where
    
    2059 2056
             given_orig = GivenOrigin (SigSkol GenSigCtxt exp_arg [])
    
    2060 2057
     
    
    2061
    --- | Like 'mkWpFun', except that it performs representation-polymorphism
    
    2062
    --- checks on the argument type.
    
    2058
    +-- | Like 'mkWpFun', except that it performs the necessary
    
    2059
    +-- representation-polymorphism checks on the argument type in the case that
    
    2060
    +-- we introduce a lambda abstraction.
    
    2063 2061
     mkWpFun_FRR
    
    2064
    -  :: Position p
    
    2062
    +  :: (TcType -> TcType -> TcM TcCoercionN) -- ^ how to unify
    
    2063
    +  -> Position p
    
    2065 2064
       -> FunTyFlag -> Type -> TcType -> Type --   actual FunTy
    
    2066 2065
       -> FunTyFlag -> Type -> TcType -> Type -- expected FunTy
    
    2067 2066
       -> HsWrapper -- ^ exp_arg ~> act_arg
    
    2068 2067
       -> HsWrapper -- ^ act_res ~> exp_res
    
    2069 2068
       -> TcM HsWrapper -- ^ act_funTy ~> exp_funTy
    
    2070
    -mkWpFun_FRR pos act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res arg_wrap res_wrap
    
    2071
    -  | needs_eta
    
    2072
    -  -- See Wrinkle [Representation-polymorphism checking during subtyping]
    
    2073
    -  = do { (exp_arg_co,  exp_arg_frr) <- hasFixedRuntimeRep (FRRDeepSubsumption True pos) exp_arg
    
    2074
    -       ; (act_arg_co, _act_arg_frr) <- hasFixedRuntimeRep (FRRDeepSubsumption False pos) act_arg
    
    2069
    +mkWpFun_FRR unify pos act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res arg_wrap res_wrap
    
    2070
    +  = do { ((exp_arg_co, exp_arg_frr), (act_arg_co, _act_arg_frr)) <-
    
    2071
    +            if needs_frr_checks
    
    2072
    +              -- See Wrinkle [Representation-polymorphism checking during subtyping]
    
    2073
    +            then do { exp_frr_wrap <- hasFixedRuntimeRep (frr_ctxt True ) exp_arg
    
    2074
    +                    ; act_frr_wrap <- hasFixedRuntimeRep (frr_ctxt False) act_arg
    
    2075
    +                    ; return (exp_frr_wrap, act_frr_wrap) }
    
    2076
    +            else return ((mkNomReflCo exp_arg, exp_arg), (mkNomReflCo act_arg, act_arg))
    
    2077
    +
    
    2078
    +         -- Enforce equality of multiplicities (not the more natural sub-multiplicity).
    
    2079
    +         -- See Note [Multiplicity in deep subsumption]
    
    2080
    +       ; act_arg_mult_co <- unify act_mult exp_mult
    
    2081
    +           -- NB: don't use tcEqMult: that would require the evidence for
    
    2082
    +           -- equality to be Refl, but it might well not be (#26332).
    
    2083
    +
    
    2075 2084
            ; let
    
    2076 2085
                 exp_arg_fun_co =
    
    2077 2086
                   mkFunCo Nominal exp_af
    
    ... ... @@ -2080,7 +2089,7 @@ mkWpFun_FRR pos act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res
    2080 2089
                      (mkReflCo Nominal exp_res)
    
    2081 2090
                 act_arg_fun_co =
    
    2082 2091
                   mkFunCo Nominal act_af
    
    2083
    -                 (mkReflCo Nominal act_mult)
    
    2092
    +                 act_arg_mult_co
    
    2084 2093
                      act_arg_co
    
    2085 2094
                      (mkReflCo Nominal act_res)
    
    2086 2095
                 arg_wrap_frr =
    
    ... ... @@ -2090,24 +2099,16 @@ mkWpFun_FRR pos act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res
    2090 2099
                    --  arg_wrap :: exp_arg ~> act_arg
    
    2091 2100
                    --  arg_wrap_frr :: exp_arg_frr ~> act_arg_frr
    
    2092 2101
     
    
    2093
    -       -- NB: because of the needs_eta guard, we know that mkWpFun will
    
    2094
    -       -- return (WpFun ...); so we might as well just use the WpFun constructor.
    
    2095 2102
            ; return $
    
    2096 2103
                 mkWpCastN exp_arg_fun_co
    
    2097 2104
                   <.>
    
    2098
    -            WpFun arg_wrap_frr res_wrap (Scaled exp_mult exp_arg_frr)
    
    2105
    +            mkWpFun arg_wrap_frr res_wrap (Scaled exp_mult exp_arg_frr) exp_res
    
    2099 2106
                   <.>
    
    2100
    -            mkWpCastN act_arg_fun_co }
    
    2101
    -  | otherwise
    
    2102
    -  = return $
    
    2103
    -      mkWpFun arg_wrap res_wrap (Scaled exp_mult exp_arg) exp_res
    
    2104
    -        -- NB: because of 'needs_eta', this will never actually be a WpFun.
    
    2105
    -        -- mkWpFun will turn it into a WpHole or WpCast, which is why
    
    2106
    -        -- we can skip the hasFixedRuntimeRep checks in this case.
    
    2107
    -        -- See Wrinkle [Representation-polymorphism checking during subtyping]
    
    2107
    +            mkWpCastN act_arg_fun_co
    
    2108
    +       }
    
    2108 2109
       where
    
    2109
    -    needs_eta :: Bool
    
    2110
    -    needs_eta =
    
    2110
    +    needs_frr_checks :: Bool
    
    2111
    +    needs_frr_checks =
    
    2111 2112
           not (hole_or_cast arg_wrap)
    
    2112 2113
             ||
    
    2113 2114
           not (hole_or_cast res_wrap)
    
    ... ... @@ -2115,6 +2116,12 @@ mkWpFun_FRR pos act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res
    2115 2116
         hole_or_cast WpHole = True
    
    2116 2117
         hole_or_cast (WpCast {}) = True
    
    2117 2118
         hole_or_cast _ = False
    
    2119
    +    frr_ctxt :: Bool -> FixedRuntimeRepContext
    
    2120
    +    frr_ctxt is_exp_ty =
    
    2121
    +      FRRDeepSubsumption
    
    2122
    +        { frrDSExpected = is_exp_ty
    
    2123
    +        , frrDSPosition = pos
    
    2124
    +        }
    
    2118 2125
     
    
    2119 2126
     -----------------------
    
    2120 2127
     deeplySkolemise :: SkolemInfo -> TcSigmaType
    

  • testsuite/tests/linear/should_compile/T26332.hs
    1
    +{-# LANGUAGE DeepSubsumption #-}
    
    2
    +{-# LANGUAGE LinearTypes #-}
    
    3
    +
    
    4
    +module T26332 where
    
    5
    +
    
    6
    +import Unsafe.Coerce
    
    7
    +
    
    8
    +toLinear
    
    9
    +  :: forall a b p q.
    
    10
    +     (a %p-> b) %1-> (a %q-> b)
    
    11
    +toLinear f = case unsafeEqualityProof @p @q of
    
    12
    +  UnsafeRefl -> f

  • testsuite/tests/linear/should_compile/all.T
    ... ... @@ -41,6 +41,7 @@ test('T19400', unless(compiler_debugged(), skip), compile, [''])
    41 41
     test('T20023', normal, compile, [''])
    
    42 42
     test('T22546', normal, compile, [''])
    
    43 43
     test('T23025', normal, compile, ['-dlinear-core-lint'])
    
    44
    +test('T26332', normal, compile, ['-O -dlinear-core-lint'])
    
    44 45
     test('LinearRecUpd', normal, compile, [''])
    
    45 46
     test('T23814', normal, compile, [''])
    
    46 47
     test('LinearLet', normal, compile, [''])