1. 19 Apr, 2018 1 commit
    • Ryan Scott's avatar
      Fix #14710 with more validity checks during renaming · 447d1264
      Ryan Scott authored
      #14710 revealed two unfortunate regressions related to kind
      polymorphism that had crept in in recent GHC releases:
      1. While GHC was able to catch illegal uses of kind polymorphism
         (i.e., if `PolyKinds` wasn't enabled) in limited situations, it
         wasn't able to catch kind polymorphism of the following form:
      f :: forall a. a -> a
      f x = const x g
          g :: Proxy (x :: a)
          g = Proxy
      Note that the variable `a` is being used as a kind variable in the
      type signature of `g`, but GHC happily accepts it, even without
      the use of `PolyKinds`.
      2. If you have `PolyKinds` (but not `TypeInType`) enabled, then GHC
         incorrectly accepts the following definition:
      f :: forall k (a :: k). Proxy a
      f = Proxy
      Even though `k` is explicitly bound and then later used as a kind
      variable within the same telescope.
      This patch fixes these two bugs as follows:
      1. Whenever we rename any `HsTyVar`, we check if the following three
         criteria are met:
         (a) It's a type variable
         (b) It's used at the kind level
         (c) `PolyKinds` is not enabled
         If so, then we have found an illegal use of kind polymorphism, so
         throw an error.
         This check replaces the `checkBadKindBndrs` function, which could
         only catch illegal uses of kind polymorphism in very limited
         situations (when the bad kind variable happened to be implicitly
         quantified in the same type signature).
      2. In `extract_hs_tv_bndrs`, we must error if `TypeInType` is not
         enabled and either of the following criteria are met:
         (a) An explicitly bound type variable is used in kind position
             in the body of a `forall` type.
         (b) An explicitly bound type variable is used in kind position
             in the kind of a bound type variable in a `forall` type.
         `extract_hs_tv_bndrs` was checking (a), but not (b). Easily fixed.
      Test Plan: ./validate
      Reviewers: goldfire, simonpj, bgamari, hvr
      Reviewed By: simonpj
      Subscribers: thomie, carter
      GHC Trac Issues: #14710
      Differential Revision: https://phabricator.haskell.org/D4554
  2. 29 Aug, 2017 1 commit
    • Simon Peyton Jones's avatar
      Refactor bindHsQTyVars and friends · 0257dacf
      Simon Peyton Jones authored
      This work was triggered by Trac #13738, which revealed to me that
      the code RnTypes.bindHsQTyVars and bindLHsTyVarBndrs was a huge
      tangled mess -- and outright wrong on occasion as the ticket showed.
      The big problem was that bindLHsTyVarBndrs (which is invoked at every
      HsForAll, including nested higher rank ones) was attempting to bind
      implicit kind variables, which it has absolutely no busineess doing.
      Imlicit kind quantification is done at the outside only, in fact
      precisely where we have HsImplicitBndrs or LHsQTyVars (which also
      has implicit binders).
      Achieving this move was surprisingly hard, because more and more
      barnacles had accreted aroud the original mistake.  It's much
      much better now.
      Summary of changes.  Almost all the action is in RnTypes.
      * Implicit kind variables are bound only by
        - By bindHsQTyVars, which deals with LHsQTyVars
        - By rnImplicitBndrs, which deals with HsImplicitBndrs
      * bindLHsTyVarBndrs, and bindLHsTyVarBndr are radically simplified.
        They simply does far less, and have lots their forest of
        incomprehensible accumulating parameters.  (To be fair, some of
        the code in bindLHsTyVarBndrs just moved to bindHsQTyVars, but
        in much more perspicuous form.)
      * The code that checks if a variable appears in both a kind and
        a type (triggering RnTypes.mixedVarsErr) was bizarre.  E.g.
        we had this in RnTypes.extract_hs_tv_bndrs
             ; check_for_mixed_vars bndr_kvs acc_tvs
             ; check_for_mixed_vars bndr_kvs body_tvs
             ; check_for_mixed_vars body_tvs acc_kvs
             ; check_for_mixed_vars body_kvs acc_tvs
             ; check_for_mixed_vars locals body_kvs
        I cleaned all this up; now we check for mixed use at binding
        sites only.
      * Checks for "Variable used as a kind before being bound", like
           data T (a :: k) k = rhs
        now just show up straightforwardly as "k is not in scope".
        See Note [Kind variable ordering]
      * There are some knock-on simplifications in RnSource.