[Git][ghc/ghc][wip/expand-do] adding Note and references

Apoorv Ingle (@ani) gitlab at gitlab.haskell.org
Mon Aug 7 15:37:54 UTC 2023



Apoorv Ingle pushed to branch wip/expand-do at Glasgow Haskell Compiler / GHC


Commits:
2a6f531e by Apoorv Ingle at 2023-08-07T10:37:41-05:00
adding Note and references

- - - - -


5 changed files:

- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Match.hs
- + compiler/GHC/Tc/Types/.#Origin.hs
- compiler/GHC/Types/Basic.hs


Changes:

=====================================
compiler/GHC/Hs/Expr.hs
=====================================
@@ -559,7 +559,7 @@ mkExpandedExprTc a b = XExpr (ExpansionExpr (HsExpanded a b))
 --   The two components of the expansion are: original statement and
 --   expanded typechecked expression.
 mkExpandedStmtTc
-  :: ExprLStmt GhcRn           -- ^ source expression
+  :: ExprLStmt GhcRn        -- ^ source expression
   -> HsExpr GhcTc           -- ^ expanded typechecked expression
   -> HsExpr GhcTc           -- ^ suitably wrapped 'HsExpansion'
 mkExpandedStmtTc a b = XExpr (ExpansionStmt (HsExpanded a b))


=====================================
compiler/GHC/Tc/Gen/Expr.hs
=====================================
@@ -271,14 +271,16 @@ tcExpr (HsLam _ match) res_ty
   = do  { (wrap, match') <- tcMatchLambda herald match_ctxt match res_ty
         ; return (mkHsWrap wrap (HsLam noExtField match')) }
   where
-    match_ctxt | isDoExpansionGenerated (mg_ext match)
-               = MC { mc_what = StmtCtxt (HsDoStmt (DoExpr Nothing))
-                    , mc_body = tcBodyNC -- NB: Do not add any error contexts
-                                         -- It has already been done
-                    }
-               | otherwise
-               = MC { mc_what = LambdaExpr
-                    , mc_body = tcBody }
+    match_ctxt
+      | isDoExpansionGenerated (mg_ext match)
+      -- See Part 3. of Note [Expanding HsDo with HsExpansion]
+      = MC { mc_what = StmtCtxt (HsDoStmt (DoExpr Nothing))
+           , mc_body = tcBodyNC -- NB: Do not add any error contexts
+                                -- It has already been done
+           }
+      | otherwise
+      = MC { mc_what = LambdaExpr
+           , mc_body = tcBody }
     herald = ExpectedFunTyLam match
 
 tcExpr e@(HsLamCase x lc_variant matches) res_ty


=====================================
compiler/GHC/Tc/Gen/Match.hs
=====================================
@@ -1386,9 +1386,9 @@ mk_fail_block _ _ _ = pprPanic "mk_fail_block: impossible happened" empty
 {- Note [Expanding HsDo with HsExpansion]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 We expand do blocks before typechecking it rather than after type checking it using the
-HsExpansions similar to HsIf expansions for rebindable syntax.
-The main reason to implement this is to make impredicatively typed expression statements typechec in do blocks.
-(#18324 and #23147).
+HsExpansions similar to HsIf with rebindable syntax and RecordSyntax.
+The main reason to implement this is to make impredicatively typed expression statements typecheck in do blocks.
+See #18324, #23147, #15598, #22086, #22788
 
 Consider a do expression written in by the user
 
@@ -1412,33 +1412,36 @@ The 3 main points to consider are:
 
 Part 1. Decorate failable patterns with fail blocks
 ---------------------------------------------------
-If p is a pattern that is failable
-the expansion of the statements
+If p is a pattern that is failable we need to decorate it with a fail block.
+For example, the expansion of the do block
 
         do p <- e1
            e2
 
-will be
+(approximately) will be
 
         (>>=)
-             e1
-
-             /     -- anonymous lambda
-             \ p -> e
-             _   -> fail "failable pattern p at location"
+             (e1)
+             (\case     -- anonymous lambda case
+                 \ p -> e2
+                 _   -> fail "failable pattern p at location")
 
 Why an anonymous lambda?
-A lambda is needed so as for the types to work out: this expression is a second
-argument to bind.
-And it is anonymous because we do not want to introduce a new name that will
+We need a lambda for the types to match: this expression is a second
+argument to bind so it needs to be of type `a -> m b`
+It is anonymous because we do not want to introduce a new name that will
 never be seen by the user anyway.
 
-* Caveat: For pattern synonyms (see testcase Typeable1.hs)
-We always decorate it with a fail block. But then during desugaring
-we would get pattern match redundant warnings. To avoid such
-warnings we filter out those type patterns that appear in a do expansion generated match
+* Caveat 1: For pattern synonyms (see testcase Typeable1.hs)
+We always decorate it with a fail block as the irrefutable pattern checker returns false
+But then during desugaring we would then get pattern match redundant warnings. To avoid such
+spurious warnings we filter out those type patterns that appear in a do expansion generated match
 in HsToCore.Match.matchWrapper
 
+* Caveat 2: MonadFail arrising due to generated `fail` statements. (See testcase MonadFailErrors.hs)
+In the error messages we need to say "pattern p" is failable so we need MonadFail and we are
+deep inside a generated code.
+
 Part 2. Generate warnings for discarded body statement results
 --------------------------------------------------------------
 If the do blocks body statement is an expression that returns a
@@ -1455,23 +1458,76 @@ expands to
    >> e1 e2
 
 now if e1 returns a non-() value then we emit a warning. This check is done during desugaring
-HsToCore.dsExpr HsApp case calls warnUnusedBindValue
+HsToCore.dsExpr HsApp case calls `warnUnusedBindValue`
 The decision function to trigger the warning is if the function is a `>>` and it is a compiler generated
 
-Part 3. Blaming Appropriate Code and Generating Appropriate Error Messages
---------------------------------------------------------------------------
+Part 3. Blaming offending source code and Generating Appropriate Error Messages
+-------------------------------------------------------------------------------
+To ensure we correctly track source of the offending
 
 When we step through each of the do statements, we need to keep track of
-which statement expansion is the typechecker is currently typechecking.
-For this purpose we use the XXExprGhcRn.ExpandedStmt and XXExprGhcTc.ExpansionStmt
-The `ExpandedStmt` stores the original statement (with location) and the expanded expression
+which statement expansion the typechecker is currently typechecking.
+For this purpose we use the XXExprGhcRn.ExpandedStmt which
+stores the original statement (with location) and the expanded expression
 
+For example, the do expression
 
+    do e1
+       e2
 
-After typechecking a satement and before moving to the next statement,
+expands to
+
+   ExpandedExpr
+       (do e1                                                 -- Original
+           e2)                                                -- Statement
+       {ExpandedStmt e1                                       --
+                     ({(>>) e1}                               --  Expanded
+                     <PopErrCtxt> (ExpandedStmt e2            --  Expression
+                                                {e2}))        --
+       }
+
+Whenever the typechecker steps through and ExpandedStmt,
+we push the origninal statement in the error context and type check the expanded expression.
+This is similar to vanilla HsExpansion and rebindable syntax
+See Note [Rebindable syntax and HsExpansion] in GHC.Hs.Expr.
+We associate the application ((>>) (e1)) with `ExpandedStmt` to ensure
+we do not mention compiler generated (>>) in
+the error context, rather when we typecheck the application, we push
+the "In the stmt of do block .." in the error context stack.
+See Note [splitHsApps]
+
+After a statement is typechecked and before moving to the next statement,
 we need to first pop the top of the error context which contains the error message
-"In the statemen of a do block: p <- e".
+"In the stmt of a do block: e1".
 This is explicitly encoded in the expansion expression using the `XXExprGhcRn.PopErrCtxt`.
-Whenever `tcExpr` encounters a PopErrCtxt it calls popErrCtxt to pop of the top of error context stack.
+Whenever `tcExpr` encounters a `PopErrCtxt` it calls `popErrCtxt` to pop of the top of error context stack.
+See <PopErrCtxt> in the example above.
+
+
+For example, the do expression with a bind statement
+
+    do p <- e1
+       e2
+
+expands to
+
+   ExpandedExpr
+       (do p <- e1                                                -- Original
+           e2                                                     -- Statement
+       )                                                          --
+       {ExpandedStmt (p <- e1)                                    --
+                     ({(>>=) e1}                                  -- Expanded
+                     <PopErrCtxt> (ExpandedStmt (e2)              -- Expression
+                                                {\ p -> e2}))     --
+       }
+
+
+However the expansion lambda (\ p -> e2) is special as it is generated from a do block expansion
+and if type checker error occurs in the pattern p, we need to say
+"in a pattern binding in a do block" and not "in a lambda abstraction" (cf. Typeable1.hs)
+hence we use a tag GenReason in Ghc.Tc.Origin. When typechecking a `HsLam` in Tc.Gen.Expr.tcExpr
+the match_ctxt is set to a StmtCtxt if GenOrigin is DoExpansion.
+
+
 
 -}


=====================================
compiler/GHC/Tc/Types/.#Origin.hs
=====================================
@@ -0,0 +1 @@
+aningle at CS-M030.77677
\ No newline at end of file


=====================================
compiler/GHC/Types/Basic.hs
=====================================
@@ -597,8 +597,8 @@ isGenerated Generated {} = True
 isGenerated FromSource   = False
 
 -- | Why was the piece of code generated?
---
--- See Note [Expanding HsDo with HsExpansion].
+--   It is useful for generating the right error context
+-- See Part 3 in Note [Expanding HsDo with HsExpansion]
 data GenReason = DoExpansion
                | OtherExpansion
                deriving (Eq, Data)



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2a6f531ec71f229f70ee1a542061e1fc16a89a01

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2a6f531ec71f229f70ee1a542061e1fc16a89a01
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20230807/35c687d4/attachment-0001.html>


More information about the ghc-commits mailing list