summaryrefslogtreecommitdiff
path: root/compiler/deSugar/DsExpr.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/deSugar/DsExpr.hs')
-rw-r--r--compiler/deSugar/DsExpr.hs20
1 files changed, 19 insertions, 1 deletions
diff --git a/compiler/deSugar/DsExpr.hs b/compiler/deSugar/DsExpr.hs
index 0f1386d76d..45d208b3db 100644
--- a/compiler/deSugar/DsExpr.hs
+++ b/compiler/deSugar/DsExpr.hs
@@ -601,7 +601,7 @@ ds_expr _ expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = fields
-- constructor arguments.
; alts <- mapM (mk_alt upd_fld_env) cons_to_upd
; ([discrim_var], matching_code)
- <- matchWrapper RecUpd Nothing
+ <- matchWrapper RecUpd (Just record_expr) -- See Note [Scrutinee in Record updates]
(MG { mg_alts = noLoc alts
, mg_ext = MatchGroupTc [in_ty] out_ty
, mg_origin = FromSource })
@@ -707,6 +707,24 @@ ds_expr _ expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = fields
, pat_wrap = req_wrap }
; return (mkSimpleMatch RecUpd [pat] wrapped_rhs) }
+{- Note [Scrutinee in Record updates]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider #17783:
+
+ data PartialRec = No
+ | Yes { a :: Int, b :: Bool }
+ update No = No
+ update r@(Yes {}) = r { b = False }
+
+In the context of pattern-match checking, the occurrence of @r@ in
+@r { b = False }@ is to be treated as if it was a scrutinee, as can be seen by
+the following desugaring:
+
+ r { b = False } ==> case r of Yes a b -> Yes a False
+
+Thus, we pass @r@ as the scrutinee expression to @matchWrapper@ above.
+-}
+
-- Here is where we desugar the Template Haskell brackets and escapes
-- Template Haskell stuff