Skip to content
This repository was archived by the owner on Aug 3, 2024. It is now read-only.

Miscellaneous improvements to Convert #1020

Merged
merged 17 commits into from
Feb 4, 2019

Conversation

harpocrates
Copy link
Collaborator

Now that Haddock is moving towards working entirely over .hi and .hie files,
all declarations and types are going to be synthesized via the Convert module.
In preparation for this change, here are a bunch of fixes to this module:

  • Add kind annotations to type variables in forall's whose kind is not Type,
    unless the kind can be inferred from some later use of the variable. See
    implicitForAll and noKindTyVars in particular if you wish to dive into this.

  • Properly detect HsQualTy in synifyType. This is done by following suit with
    what GHC's toIfaceTypeX does and checking the first argument of
    FunTy{} :: Type to see if it classified as a given/wanted in the typechecker
    (see isPredTy).

  • Beef up the logic around figuring out when an explicit forall is needed. This
    includes: observing if any of the type variables will need kind signatures, if the
    inferred type variable order without a forall will still match the one GHC
    claims, and some other small things.

  • Add some (not yet used) functionality for default levity polymorphic type
    signatures. This functionality similar to fprint-explicit-runtime-reps.

Couple other smaller fixes only worth mentioning:

  • Show the family result signature only when it isn't Type
  • Fix rendering of implicit parameters in the LaTeX and Hoogle backends
  • Better handling of the return kind of polykinded H98 data declarations
  • Class decls produced by tyThingToLHsDecl now contain associated type
    defaults and default method signatures when appropriate
  • Filter out more forall's in pattern synonyms

This makes 'TypeFamilies3' pass.
This mirrors similar logic in 'toIfaceTypeX' which converts 'Type' into
'IfaceType'. The idea is to check the first argument of 'FunTy{} :: Type'
to see if it classified as a given/wanted in the typechecker (see 'isPredTy').
Then, we use the same logic as 'ForAllTy{} :: Type' to try to extract an
'HsQualTy'.

This makes the 'ImplicitParams' test pass again.
This makes sure that, for example, a context containing only an
implicit parameter still ends up being parenthesized.
This means that the kinds do not get completely swallowed up in
signatures where they matter, like

     foo :: forall proxy (a :: ()). proxy a

It also means that _all_ higher-kinded type variables now have
explicit kinds.
The idea is to hide kind signatures for type variables where the kind can be
inferred from at least one use of the type variable in the given type. This
seems to strike a nice balance between maintaining existing behaviour and
showing something that isn't incorrect.
* filter out more 'forall's in class decls/instance decls
* extract default class methods too
* filter out more 'forall's in pattern synonym decls
When deciding if we want to have an explicit 'forall', one of the things
to check is if the deduced type variable order would match the explicit
one. Turns out that we need to roll our own function for that.

One example of where this got fixed in the Prelude:

  fst :: forall a b. (a, b) -> a

turned back into

  fst :: (a, b) -> a
This is especially nice for bundled pattern synonyms, where the
synonyms go back to looking (almost always) like plain constructors.

In 'BundledPatterns', this renders

    pattern (:>) :: a -> Vec n a -> Vec (n + 1) a

instead of

    pattern (:>) :: forall a (n :: Nat). a -> Vec n a -> Vec (n + 1) a

since the kind of `n` can be inferred from its use in `Vec n a`.
Class decls produced by 'tyThingToLHsDecl' now contain associated type
defaults when appropriate.
Fixes the 'Semigroup' method:

  stimes :: forall b. Integral b => b -> a -> a

Into

  stimes :: Integral b => b -> a -> a
This should make it clearer why we need to define our copies of some of
these functions.
This fixes the empty forall on the 'pattern Blub'.

Before:  pattern Blub :: forall. () => forall x. Show x => x -> BlubType
After:   pattern Blub :: () => Show x => x -> BlubType
'synifyDataTyConReturnKind' was behaving badly with kind signatures
involving foralls and kind tyvars. Thankfully, 'TyCon's already have
'tyConResKind' for figuring out the return kind of type constructors.

Consider `data (a :: *) >< b = Empty` with `-XPolyKinds`. Here is the
header we generate:

Before: data a >< (b :: k) :: forall k. Type -> k -> Type
After:  data a >< (b :: k)
...when the other method is let through.
Misc issues:

  * when synifying, avoid producing empty contexts
  * when synifying, guess at the fixity from the name
  * don't skip printing type variables with kinds in hoogle
@harpocrates harpocrates merged commit aa9644f into haskell:ghc-head Feb 4, 2019
@harpocrates harpocrates deleted the convert-fixes branch February 4, 2019 06:59
synifyType s forallty@(ForAllTy _tv _ty) =
let (tvs, ctx, tau) = tcSplitSigmaTyPreserveSynonyms forallty
synifyType s vs funty@(FunTy t1 t2)
| isPredTy t1 = synifyForAllType s vs funty
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NB: I'm working on a patch (Trac #16185) that will add a flag to FunTy to make this test much easier.

I don't wan to to block this change, just call to attention that wen #16185 lands we can simplify code here slightly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad to hear, that seems like a useful change!

I've subscribed to the ticket in the meantime. Thanks for the head's up.

@harpocrates harpocrates mentioned this pull request Sep 13, 2019
4 tasks
alanz pushed a commit that referenced this pull request Mar 25, 2020
Now that Haddock is moving towards working entirely over `.hi` and `.hie` files,
all declarations and types are going to be synthesized via the `Convert` module.
In preparation for this change, here are a bunch of fixes to this module:

  * Add kind annotations to type variables in `forall`'s whose kind is not `Type`,
    unless the kind can be inferred from some later use of the variable. See
    `implicitForAll` and `noKindTyVars` in particular if you wish to dive into this.

  * Properly detect `HsQualTy` in `synifyType`. This is done by following suit with
    what GHC's `toIfaceTypeX` does and checking the first argument of
    `FunTy{} :: Type` to see if it classified as a given/wanted in the typechecker
    (see `isPredTy`). 

  * Beef up the logic around figuring out when an explicit `forall` is needed. This
    includes: observing if any of the type variables will need kind signatures, if the
    inferred type variable order _without_ a forall will still match the one GHC
    claims, and some other small things.

  * Add some (not yet used) functionality for default levity polymorphic type
    signatures. This functionality similar to `fprint-explicit-runtime-reps`.

Couple other smaller fixes only worth mentioning:

  * Show the family result signature only when it isn't `Type`
  * Fix rendering of implicit parameters in the LaTeX and Hoogle backends
  * Better handling of the return kind of polykinded H98 data declarations
  * Class decls produced by `tyThingToLHsDecl` now contain associated type
    defaults and default method signatures when appropriate
  * Filter out more `forall`'s in pattern synonyms
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants