Make TTG extension constructor fields strict to avoid noExtCon boilerplate
The empty NoExtCon
data type was first proposed in #15247 (closed) as a way to avoid the use of panic
in large swaths of TTG-related code that deals with unused extension constructors, such as XHsDecl
. Unfortunately, the use of panic
was simply replaced with different boilerplate:
ex :: HsDecl GhcPs -> HsDecl GhcRn
...
ex (XHsDecl nec) = noExtCon nec
Wouldn't it be great if we could get rid of this boilerplate? Luckily, we can! Richard notes in #15305 (comment 157320) that the pattern-match coverage checker is now smart enough to reason about strict fields that cannot be inhabited, so if we were to define unused TTG extension constructors like this:
data HsDecl pass
= ...
| XHsDecl !(XXHsDecl pass)
type instance XXHsDecl (GhcPass _) = NoExtCon
Then we could remove the XHsDecl
case from ex
above, as it would be unreachable. This new coverage-checking power first debuted in GHC 8.8, which is now the minimum supported bootstrapping compiler. This means that we can finally proceed with ripping out nearly all uses of noExtCon
as described in this issue.