Skip to content
  • Simon Peyton Jones's avatar
    Hurrah! This major commit adds support for scoped kind variables, · 3bf54e78
    Simon Peyton Jones authored
    which (finally) fills out the functionality of polymorphic kinds.
    It also fixes numerous bugs.
    
    Main changes are:
    
    Renaming stuff
    ~~~~~~~~~~~~~~
    * New type in HsTypes:
         data HsBndrSig sig = HsBSig sig [Name]
      which is used for type signatures in patterns, and kind signatures
      in types.  So when you say
           f (x :: [a]) = x ++ x
      or
           data T (f :: k -> *) (x :: *) = MkT (f x)
      the signatures in both cases are a HsBndrSig.
    
    * The [Name] in HsBndrSig records the variables bound by the
      pattern, that is 'a' in the first example, 'k' in the second,
      and nothing in the third.  The renamer initialises the field.
    
    * As a result I was able to get rid of
         RnHsSyn.extractHsTyNames :: LHsType Name -> NameSet
      and its friends altogether.  Deleted the entire module!
      This led to some knock-on refactoring; in particular the
      type renamer now returns the free variables just like the
      term renamer.
    
    Kind-checking types: mainly TcHsType
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    A major change is that instead of kind-checking types in two
    passes, we now do one. Under the old scheme, the first pass did
    kind-checking and (hackily) annotated the HsType with the
    inferred kinds; and the second pass desugared the HsType to a
    Type.  But now that we have kind variables inside types, the
    first pass (TcHsType.tc_hs_type) can go straight to Type, and
    zonking will squeeze out any kind unification variables later.
    
    This is much nicer, but it was much more fiddly than I had expected.
    
    The nastiest corner is this: it's very important that tc_hs_type
    uses lazy constructors to build the returned type. See
    Note [Zonking inside the knot] in TcHsType.
    
    Type-checking type and class declarations: mainly TcTyClsDecls
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    I did tons of refactoring in TcTyClsDecls.  Simpler and nicer now.
    
    Typechecking bindings: mainly TcBinds
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    I rejigged (yet again) the handling of type signatures in TcBinds.
    It's a bit simpler now.  The main change is that tcTySigs goes
    right through to a TcSigInfo in one step; previously it was split
    into two, part here and part later.
    
    Unsafe coercions
    ~~~~~~~~~~~~~~~~
    Usually equality coercions have exactly the same kind on both
    sides.  But we do allow an *unsafe* coercion between Int# and Bool,
    say, used in
        case error Bool "flah" of { True -> 3#; False -> 0# }
    -->
        (error Bool "flah") |> unsafeCoerce Bool Int#
    
    So what is the instantiation of (~#) here?
       unsafeCoerce Bool Int# :: (~#) ??? Bool Int#
    I'm using OpenKind here for now, but it's un-satisfying that
    the lhs and rhs of the ~ don't have precisely the same kind.
    
    More minor
    ~~~~~~~~~~
    * HsDecl.TySynonym has its free variables attached, which makes
      the cycle computation in TcTyDecls.mkSynEdges easier.
    
    * Fixed a nasty reversed-comparison bug in FamInstEnv:
      @@ -490,7 +490,7 @@ lookup_fam_inst_env' match_fun one_sided ie fam tys
         n_tys = length tys
         extra_tys = drop arity tys
         (match_tys, add_extra_tys)
    -       | arity > n_tys = (take arity tys, \res_tys -> res_tys ++ extra_tys)
    +       | arity < n_tys = (take arity tys, \res_tys -> res_tys ++ extra_tys)
            | otherwise     = (tys,            \res_tys -> res_tys)
    3bf54e78