-
Notifications
You must be signed in to change notification settings - Fork 236
Default 'RuntimeRep' arguments unless otherwise specified #941
Default 'RuntimeRep' arguments unless otherwise specified #941
Conversation
This means all 'RuntimeRep' tyvars will be muted, unless the user explicitly asks that they be shown by speciying {-# OPTIONS_HADDOCK print-runtime-reps #-} This design is going make it possible to have the same type be displayed differently depending on which module it is exported from (eg. the Prelude or GHC.Exts).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks quite reasonable to me.
I forget: is there a users' guide description of all the flags that Haddock accepts? If so, it would be worth mentioning this flag in there as well.
Some minor comments inline.
| tv `elemVarEnv` subs | ||
= TyConApp liftedRepDataConTyCon [] | ||
| otherwise | ||
= TyVarTy (updateTyVarKind (go subs) tv) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's unnecessary to recurse into tv
's kind here. (At least, IfaceType.defaultRuntimeRepVars
doesn't do this.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is necessary, since we do recurse into type variable's kinds when computing the inferred order of type variables (in tyCoFVsBndr'
). Perhaps we should not recurse into the type variables kind there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Upon further thought, maybe it's better if we do recurse here.
For pretty-printing purposes, it's probably overkill, since if you have a type like:
forall (r :: RuntimeRep) (a :: TYPE r). Int -> a
Then after defaulting, it'll still display as:
forall a. Int -> a
Regardless of whether you recurse into the kind of a
(in Int -> a
) or not. On the other hand, if you don't recurse into the kind of a
, then you have a strange situation where the kind of a
in forall a
is Type
, but the kind of a
in Int -> a
is TYPE r
. I suppose the only way that could ever really bite you is if you were to run Core Lint on these types (which I certainly don't imagine happens today), but for the sake of consistency, it might be best just to update the kind of a
in Int -> a
anyways.
parseOption "not-home" = return (Just OptNotHome) | ||
parseOption "show-extensions" = return (Just OptShowExtensions) | ||
parseOption "print-runtime-reps" = return (Just OptPrintRuntimeRep) | ||
parseOption "print-explicit-runtime-reps" = return (Just OptPrintRuntimeRep) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason for having two flags with the same effect? Why not just standardize on a single flag?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No particular reason. I want this flag to be called print-runtime-reps
, but I anticipate some confusion with GHC's -fprint-explicit-runtime-reps
(cf. Cabal's hyperlink-source
option vs Haddock's hyperlinked-source
option). Do you have an opinion one way or another?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My inclination would be to have -fprint-explicit-runtime-reps
be the shared name of the flag across GHC and Haddock. I suppose I would be fine with picking -fprint-runtime-reps
to be the name of the Haddock flag as well, but I definitely think we shouldn't come up with two different ways of referring to the same flag—that just seems like a recipe for confusion.
haddock-api/src/Haddock/Convert.hs
Outdated
annot_ts = zipWith3 annotHsType is_poly_tvs ts ts' | ||
is_poly_tvs = mkIsPolyTvs (tyConVisibleTyVars cls_tycon) | ||
synifyClsIdSig = synifyIdSig DeleteTopLevelQuantification vs | ||
synifyClsIdSig = synifyIdSig True DeleteTopLevelQuantification vs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you hardcode PrintRuntimeReps
to True
here instead of consulting the flag?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. So this brings up a bigger question: should we thread through the RuntimeRep
defaulting logic to everything involving Type
in this module? Perhaps so, but that is going to be a fair bit of plumbing.
I think it is simpler to start with defaulting only top-level signatures, but I'm willing to be told otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If your goal is to avoid having any RuntimeRep
quantification unless explicitly enabled, I think you'll eventually need to tackle class instances as well. After all, you can define levity polymorphic instances like so:
λ> class C a
λ> instance forall (r :: RuntimeRep) a (b :: TYPE r). C (a -> b)
λ> :i C
class C (a :: k) -- Defined at <interactive>:2:1
instance [safe] forall a b. C (a -> b)
-- Defined at <interactive>:3:10
λ> :set -fprint-explicit-runtime-reps
λ> :i C
class C (a :: k) -- Defined at <interactive>:2:1
instance [safe] forall (r :: RuntimeRep) a (b :: TYPE r).
C (a -> b)
-- Defined at <interactive>:3:10
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gah. Alright. Thanks for the motivating example. 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Upon further inspection: I can't convince Haddock to ever print out runtime reps for instances. I'm inclined to leave this be for the moment. Plus this part of the wip/hi-haddock
branch, so I'm trying to stay away from far-reaching changes.
Also patched up 'synifyTyCon' to do a better job on '(->)'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few wibbles. :)
doc/cheatsheet/haddocks.md
Outdated
{-# OPTIONS_HADDOCK show-extensions #-} | ||
Show all enabled LANGUAGE extensions | ||
{-# OPTIONS_HADDOCK print-explicit-runtime-reps #-} | ||
Don't default 'RuntimeRep' type variables |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sentence seems to be missing a print
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I missed that default
is the verb here. I guess this could confuse other people too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the description you used for the option parser:
Render runtime reps for this module (see the GHC @-fprint-explicit-runtime-reps@ flag)
haddock-api/src/Haddock/Convert.hs
Outdated
-- | Whether or not to default 'RuntimeRep' variables to 'LiftedRep'. Check | ||
-- out Note [Defaulting RuntimeRep variables] in IfaceType.hs for the | ||
-- motivation. | ||
type PrintRuntimeReps = Bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have a newtype or a custom type instead of the alias here?
Aliases tend to be refactored to the underlying types in my experience. Also, an explicit True
or False
doesn't say much about its purpose.
let renamer = docIdEnvRenamer (docs_id_env mod_iface_docs) | ||
|
||
opts <- liftErrMsg $ mkDocOpts (docs_haddock_opts mod_iface_docs) flags mdl | ||
let prr = OptPrintRuntimeRep `elem` opts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather have a more meaningful variable name in this module.
Thanks! :) |
This adds a module level Haddock option called
print-runtime-reps
which behaves like the GHC-fprint-explicit-runtime-reps
flag. Hopefully this will let us restore beginner-friendliness to thePrelude
types, without having to compromise for simplified types inGHC.Prim
.See the discussion in #838 for more.