summaryrefslogtreecommitdiff
path: root/compiler/GHC/Hs/Extension.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Hs/Extension.hs')
-rw-r--r--compiler/GHC/Hs/Extension.hs33
1 files changed, 14 insertions, 19 deletions
diff --git a/compiler/GHC/Hs/Extension.hs b/compiler/GHC/Hs/Extension.hs
index 45753eaf47..b24bdf19b8 100644
--- a/compiler/GHC/Hs/Extension.hs
+++ b/compiler/GHC/Hs/Extension.hs
@@ -181,32 +181,27 @@ following:
type instance XXHsDecl (GhcPass _) = NoExtCon
data HsDecl p
= ...
- | XHsDecl (XXHsDecl p)
+ | XHsDecl !(XXHsDecl p)
-This means that any function that wishes to consume an HsDecl will need to
-have a case for XHsDecl. This might look like this:
+The field of type `XXHsDecl p` is strict for a good reason: it allows the
+pattern-match coverage checker to conclude that any matches against XHsDecl
+are unreachable whenever `p ~ GhcPass _`. To see why this is the case, consider
+the following function which consumes an HsDecl:
ex :: HsDecl GhcPs -> HsDecl GhcRn
...
ex (XHsDecl nec) = noExtCon nec
-Ideally, we wouldn't need a case for XHsDecl at all (it /is/ supposed to be
-an unused extension constructor, after all). There is a way to achieve this
-on GHC 8.8 or later: make the field of XHsDecl strict:
-
- data HsDecl p
- = ...
- | XHsDecl !(XXHsDecl p)
-
-If this is done, GHC's pattern-match coverage checker is clever enough to
-figure out that the XHsDecl case of `ex` is unreachable, so it can simply be
-omitted. (See Note [Extensions to GADTs Meet Their Match] in Check for more on
-how this works.)
+Because `p` equals GhcPs (i.e., GhcPass 'Parsed), XHsDecl's field has the type
+NoExtCon. But since (1) the field is strict and (2) NoExtCon is an empty data
+type, there is no possible way to reach the right-hand side of the XHsDecl
+case. As a result, the coverage checker concludes that the XHsDecl case is
+inaccessible, so it can be removed.
+(See Note [Strict argument type constraints] in GHC.HsToCore.PmCheck.Oracle for
+more on how this works.)
-When GHC drops support for bootstrapping with GHC 8.6 and earlier, we can make
-the strict field changes described above and delete gobs of code involving
-`noExtCon`. Until then, it is necessary to use, so be aware of it when writing
-code that consumes unused extension constructors.
+Bottom line: if you add a TTG extension constructor that uses NoExtCon, make
+sure that any uses of it as a field are strict.
-}
-- | Used as a data type index for the hsSyn AST; also serves