[GHC] #15954: LiberalTypeSynonyms unsaturation check doesn't kick in

GHC ghc-devs at haskell.org
Mon Nov 26 23:27:58 UTC 2018


#15954: LiberalTypeSynonyms unsaturation check doesn't kick in
-------------------------------------+-------------------------------------
        Reporter:  RyanGlScott       |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:  8.6.3
       Component:  Compiler (Type    |              Version:  8.6.2
  checker)                           |
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  GHC accepts       |  Unknown/Multiple
  invalid program                    |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by RyanGlScott):

 The culprit appears to be the
 [http://git.haskell.org/ghc.git/blob/984b75de7082689ebcc6e9d17b37f2c9b3702f71:/compiler/typecheck/TcValidity.hs#l467
 first case] of `check_type`:

 {{{#!hs
 check_type env ctxt rank ty
   | not (null tvbs && null theta)
   = do  { traceTc "check_type" (ppr ty $$ ppr (forAllAllowed rank))
         ; checkTcM (forAllAllowed rank) (forAllTyErr env rank ty)
                 -- Reject e.g. (Maybe (?x::Int => Int)),
                 -- with a decent error message

         ; check_valid_theta env' SigmaCtxt theta
                 -- Allow     type T = ?x::Int => Int -> Int
                 -- but not   type T = ?x::Int

         ; check_type env' ctxt rank tau      -- Allow foralls to right of
 arrow

         ; checkTcM (not (any (`elemVarSet` tyCoVarsOfType phi_kind) tvs))
                    (forAllEscapeErr env' ty tau_kind)
         }
   where
     (tvbs, phi)  = tcSplitForAllVarBndrs ty
     (theta, tau) = tcSplitPhiTy phi

     tvs          = binderVars tvbs
     (env', _)    = tidyVarBndrs env tvs

     tau_kind              = typeKind tau
     phi_kind | null theta = tau_kind
              | otherwise  = liftedTypeKind
         -- If there are any constraints, the kind is *. (#11405)
 }}}

 In particular, this function uses `tcSplitForAllVarBndrs` and
 `tcSplitPhiTy` to decompose the right-hand side of a type synonym. What
 happens when that right-hand side is `B A` (from comment:1)? Well, as it
 happens, both `tcSplitForAllVarBndrs` and `tcSplitPhiTy` //expand type
 synonyms//, so `check_type` actually checks `forall x. x -> x` for
 validity, not `B A`! In other words, GHC is completely oblivious to the
 fact that `A` is unsaturated, since it's not checking the type `B A` in
 the first place.

 I suppose the prudent thing to do here would be to conjure up variations
 of `tcSplitForAllVarBndrs` and `tcSplitPhiTy` that don't expand type
 synonyms?

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15954#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list