Admin message

Due to a large amount of spam we do not allow new users to create repositories, they are "external" users. If you are a new user and want to create a repository, for example for forking GHC, open a new issue on ghc/ghc using the "get-verified" issue template

Unify HsExpr and HsType
This ticket tracks a refactoring project within GHC, whose goal is to arrive at the following declaration: ```haskell type HsType = HsExpr ``` The rationale for this is to increase code reuse between the term- and type-level code in the compiler front-end (AST, parser, renamer, type checker). A more ambitious idea (also a bit more contentious) is to throw `Pat` into the mix, and it is discussed here: https://github.com/ghc-proposals/ghc-proposals/discussions/663. In this ticket we limit the scope to unifying `HsExpr` and `HsType`. The greatest piece of evidence that this unification is a good idea comes from the fact that we need to embed the entirety of type syntax in expressions (8b2f70a202ec0913515bf4945de789e959ff8cac) in order to implement GHC Proposal [#281](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0281-visible-forall.rst). So we need constructors in `HsExpr` to represent `forall tvs. t`, `ctx => t`, `a -> b`, etc. Previously those were unique to `HsType`, so a case could be made for keeping `HsType` separate; now `HsType` is morally a subset of `HsExpr` (technically there are a few discrepancies to be resolved, e.g. `NoGhcTc`, `HsBangTy`, `HsRecTy`). Here is how I propose to conduct this refactoring: 1. **Step 1.** Identify all discrepancies between `HsExpr` and `HsType`, and fix them one by one. List of already identified problems: * [x] #18782. `HsType` has constructors `HsRecTy` and `HsBangTy`. Arguably they shouldn't be there, so instead of adding them `HsExpr`, we can try removing them from `HsType`. Continue discussion at #18782 * [ ] #18758. `NoGhcTc` is only used in `HsExpr`, e.g. `HsAppType` has it whereas `HsAppKindTy` doesn't. We could either put `NoGhcTc` in more places or try to get rid of it. Continue discussion at #18758 * [ ] `HsTyVar` has a `PromotionFlag`, `HsVar` doesn't. Easily solved by adding `PromotionFlag` to `HsExpr`, even though it can't be parsed by the expression grammar. * [x] `HsOpTy` represents the operator with just its name (i.e. `LIdP pass`), whereas `OpApp` admits a subexpression (i.e. `HsExpr pass`). We can make the transition smoother if we use `HsType pass` in `HsOpTy`. * [x] `HsStarTy` doesn't exist in `HsExpr` * _Feel free to add to this list if you spot more discrepancies, or I will do that as I discover them during implementation_ 2. **Step 2.** Start using `HsExpr` instead of `HsType` in the existing code that works on types. If the previous step was done correctly, this should be a rather mechanical rewrite. The only issue I can foresee is that we'll need a bunch of `panic`s to deal with `HsExpr` constructors that do not actually occur in types. 3. **Step 3.** Identify opportunities for code reuse. * We can have just one parser for types and terms. (It would be up to the renamer or typechecker to then complain if it found, say, a list comprehension inside a type.) * We can have just one renamer that would work for both types and terms. We only need to parameterize it by the default namespace for lookups. * The T2T transformation in the type checker would no longer be necessary.
issue