| ... |
... |
@@ -572,7 +572,8 @@ tcExpr (HsDo _ do_or_lc stmts) res_ty |
|
572
|
572
|
= do hse <- expandDoStmts do_or_lc stmts
|
|
573
|
573
|
tcHsExpansion hse res_ty
|
|
574
|
574
|
| otherwise
|
|
575
|
|
- -- ListComp, MonadComp are handled by tcDoStmts
|
|
|
575
|
+ -- ListComp and MonadComp are handled by legacy tcDoStmts for now,
|
|
|
576
|
+ -- The ultimate goal is to handle them via expandDoStmts.
|
|
576
|
577
|
-- GHCiStmts are handled completely separate
|
|
577
|
578
|
= tcDoStmts do_or_lc stmts res_ty
|
|
578
|
579
|
|
| ... |
... |
@@ -786,15 +787,16 @@ directly, it's much easier to |
|
786
|
787
|
* Expand (or desugar) the code to something simpler
|
|
787
|
788
|
* Typecheck that simpler expression
|
|
788
|
789
|
|
|
789
|
|
-Example: record updates. The typechecker looks like this:
|
|
|
790
|
+Example: Typechecking the do expression. The typechecker looks (somewhat) like this:
|
|
790
|
791
|
|
|
791
|
|
- tcExpr e@(HsDo{}) rho = do { ee <- expandExpr e
|
|
792
|
|
- ; tcExpr ee rho }
|
|
|
792
|
+ tcExpr e@(HsDo _ stmts) rho = do { hse <- expandDoStmts stmts
|
|
|
793
|
+ ; tcHsExpansion hse rho }
|
|
793
|
794
|
|
|
794
|
|
-The `expandExpr` replaces the HsDo { x <- e1; return x }
|
|
|
795
|
+The `expandDoStmts` replaces the HsDo { x <- e1; return x }
|
|
795
|
796
|
with something like
|
|
796
|
|
- e1 >>= \ x -> x
|
|
797
|
|
-and we then typecheck the latter.
|
|
|
797
|
+ HSE { hs_ctxt = e
|
|
|
798
|
+ , expanded_expr = e1 >>= \ x -> x }
|
|
|
799
|
+and we then typecheck the expression `e1 >>= \ x -> x`
|
|
798
|
800
|
|
|
799
|
801
|
See also Note [Handling overloaded and rebindable constructs]
|
|
800
|
802
|
and Note [Doing XXExprGhcRn in the Renamer vs Typechecker]
|
| ... |
... |
@@ -806,8 +808,8 @@ The rest of this Note explains how that is done. |
|
806
|
808
|
* The expansion process typically takes a user written thing
|
|
807
|
809
|
L lspan ue
|
|
808
|
810
|
and returns
|
|
809
|
|
- L lspan (XExpr (ExpandedThingRn { xrn_orig = ue
|
|
810
|
|
- , xrn_expanded = ee } ))
|
|
|
811
|
+ L lspan (XExpr (ExpandedThingRn (HSE { hs_ctxt = ue
|
|
|
812
|
+ , expanded_expr = ee } ))
|
|
811
|
813
|
where `ee` is the expansion of the user written thing `ue`
|
|
812
|
814
|
|
|
813
|
815
|
* The type checker context has 3 key fields that describe the context:
|
| ... |
... |
@@ -824,30 +826,29 @@ The rest of this Note explains how that is done. |
|
824
|
826
|
The `tcl_in_gen_code` is a boolean that keeps track of whether
|
|
825
|
827
|
the current expression being typechecked is compiler generated
|
|
826
|
828
|
or user generated.
|
|
|
829
|
+ INVARIANT: `tcl_in_gen_code` is modified only in `setSrcSpan`.
|
|
827
|
830
|
|
|
828
|
|
- The `tcl_in_gen_code` is a boolean that keeps track of whether
|
|
829
|
|
- the current expression being typechecked is compiler generated
|
|
830
|
|
- or user generated.
|
|
831
|
831
|
|
|
832
|
832
|
* Now, when
|
|
833
|
833
|
tcMonoLExpr :: LHsExpr GhcRn -> ExpRhoType -> TcM (HsExpr GhcTc)
|
|
834
|
834
|
gets a located expression, it does 2 things:
|
|
835
|
|
- * Calls `addLExprCtxt` to perform error context management
|
|
836
|
|
- * Calls `tcExpr` to typecheck the expression.
|
|
|
835
|
+ (a) Calls `addLExprCtxt` to perform error context management
|
|
|
836
|
+ (b) Calls `tcExpr` to typecheck the expression.
|
|
837
|
837
|
|
|
838
|
|
-* `addLExprCtxt span expr`
|
|
|
838
|
+(a) `addLExprCtxt span expr`
|
|
839
|
839
|
(1) updates the location of `tcl_loc` with the `span` above,
|
|
840
|
840
|
(2) adds an `ErrCtxt` on top of the `tcl_err_ctxt`.
|
|
841
|
841
|
|
|
842
|
842
|
* However, if the `span` is generated (see `isGeneratedSrcSpan`), then
|
|
843
|
|
- `addLExprCtxt` is a no-op. Crucially, when we generate code in `expandExpr`,
|
|
|
843
|
+ `addLExprCtxt` sets `tcl_in_gen_code` to `True` via a call to `setSrcSpan`
|
|
|
844
|
+ and the `tcl_err_ctxt` is left untouched. Crucially, when we generate code in `expandExpr`,
|
|
844
|
845
|
all the generated AST notes are tagged with a `GeneratedSrcSpan`. This
|
|
845
|
846
|
is how we avoid populating the TcLclCtxt with generated code.
|
|
846
|
847
|
|
|
847
|
|
-* The type checker error-stack element `GHC.Tc.Types.ErrCtxt.ErrCtxt`
|
|
848
|
|
- type ErrCtxt = HsCtxt
|
|
|
848
|
+* The type checker error-stack element `GHC.Tc.Types.ErrCtxt.HsCtxt`
|
|
|
849
|
+ just stores an error message
|
|
849
|
850
|
|
|
850
|
|
- just stores an error message
|
|
|
851
|
+ type ErrCtxt = HsCtxt
|
|
851
|
852
|
|
|
852
|
853
|
When called on an `XExpr`, `addLExprCtxt`, adds the user written thing
|
|
853
|
854
|
`ue`, and the error message provided by the caller on the `ErrCtxtStack` See
|
| ... |
... |
@@ -857,10 +858,9 @@ The rest of this Note explains how that is done. |
|
857
|
858
|
|
|
858
|
859
|
tcHsExpansion :: HsExpansion GhcRn -> ExpRhoType -> TcM (HsExpr GhcTc)
|
|
859
|
860
|
tcHsExpansion (HSE o e) res_ty
|
|
860
|
|
- = mkExpandedTc o <$> -- necessary for hpc ticks
|
|
861
|
|
- -- Need to call tcExpr and not tcApp
|
|
862
|
|
- -- as e can be let statement which tcApp cannot gracefully handle
|
|
863
|
|
- tcMonoLExpr e res_ty
|
|
|
861
|
+ = do e' <- tcMonoLExpr e res_ty
|
|
|
862
|
+ return $ XExpr (ExpandedThingTc (HSE o e'))
|
|
|
863
|
+
|
|
864
|
864
|
|
|
865
|
865
|
{-
|
|
866
|
866
|
************************************************************************
|