Simon Peyton Jones pushed to branch wip/spj-apporv-Oct24 at Glasgow Haskell Compiler / GHC

Commits:

4 changed files:

Changes:

  • compiler/GHC/Hs/Expr.hs
    ... ... @@ -662,9 +662,13 @@ type instance XXExpr GhcTc = XXExprGhcTc
    662 662
     
    
    663 663
     -- See Note [Rebindable syntax and XXExprGhcRn]
    
    664 664
     -- See Note [Expanding HsDo with XXExprGhcRn] in `GHC.Tc.Gen.Do`
    
    665
    -data HsExpansion p = HSE { hs_ctxt :: HsCtxt -- The original source thing context to be used for error messages
    
    666
    -                         , expanded_expr :: LHsExpr p } -- The compiler generated, expanded expression
    
    667
    -                                                        -- This is located because of do statements (TODO ANI : Add Note)
    
    665
    +data HsExpansion p
    
    666
    +  = HSE { hse_ctxt :: HsCtxt      -- The original source thing context,
    
    667
    +                                  -- to be used for error messages
    
    668
    +        , hse_exp  :: LHsExpr p   -- The compiler generated expansion
    
    669
    +                                  -- This is located because of do statements
    
    670
    +                                  -- (TODO ANI : Add Note)
    
    671
    +        }
    
    668 672
     
    
    669 673
     data XXExprGhcRn
    
    670 674
       = ExpandedThingRn (HsExpansion GhcRn)  -- ^ Renamed/Pre Typecheck expanded expression
    

  • compiler/GHC/Tc/Gen/Do.hs
    ... ... @@ -46,7 +46,10 @@ import Data.List ((\\))
    46 46
     --   See Note [Expanding HsDo with XXExprGhcRn] below for `HsDo` specific commentary
    
    47 47
     --   and Note [Handling overloaded and rebindable constructs] for high level commentary
    
    48 48
     expandDoStmts :: HsDoFlavour -> XRec GhcRn [ExprLStmt GhcRn] -> TcM (HsExpansion GhcRn)
    
    49
    -expandDoStmts doFlav lstmts@(L _ stmts) = HSE (ExprCtxt (HsDo noExtField doFlav lstmts)) <$> expand_do_stmts doFlav stmts
    
    49
    +expandDoStmts doFlav lstmts@(L _ stmts)
    
    50
    +  = do { exp <- expand_do_stmts doFlav stmts
    
    51
    +       ; return $ HSE { hse_ctxt = ExprCtxt (HsDo noExtField doFlav lstmts)
    
    52
    +                      , hse_exp  = exp } }
    
    50 53
     
    
    51 54
     -- | The main work horse for expanding do block statements into applications of binds and thens
    
    52 55
     --   See Note [Expanding HsDo with XXExprGhcRn]
    

  • compiler/GHC/Tc/Gen/Expr.hs
    ... ... @@ -798,8 +798,8 @@ Example: Typechecking the do expression. The typechecker looks (somewhat) like t
    798 798
     
    
    799 799
     The `expandDoStmts` replaces the HsDo { x <- e1; return x }
    
    800 800
     with something like
    
    801
    -   HSE { hs_ctxt = e
    
    802
    -       , expanded_expr = e1 >>= \ x -> x }
    
    801
    +   HSE { hse_ctxt = ExprCtxt e
    
    802
    +       , hse_exp  = e1 >>= \ x -> x }
    
    803 803
     and we then typecheck the expression `e1 >>= \ x -> x`
    
    804 804
     
    
    805 805
     See also Note [Handling overloaded and rebindable constructs]
    
    ... ... @@ -812,8 +812,8 @@ The rest of this Note explains how that is done.
    812 812
     * The expansion process typically takes a user written thing
    
    813 813
            L lspan ue
    
    814 814
       and returns
    
    815
    -       L lspan (XExpr (ExpandedThingRn (HSE { hs_ctxt = ue
    
    816
    -                                            , expanded_expr = ee } ))
    
    815
    +       L lspan (XExpr (ExpandedThingRn (HSE { hse_ctxt = ue
    
    816
    +                                            , hse_exp  = ee } ))
    
    817 817
       where `ee` is the expansion of the user written thing `ue`
    
    818 818
     
    
    819 819
     * The type checker context has 3 key fields that describe the context:
    
    ... ... @@ -830,36 +830,32 @@ The rest of this Note explains how that is done.
    830 830
       The `tcl_in_gen_code` is a boolean that keeps track of whether
    
    831 831
       the current expression being typechecked is compiler generated
    
    832 832
       or user generated.
    
    833
    -  INVARIANT: `tcl_in_gen_code` is modified only in `setSrcSpan`.
    
    834 833
     
    
    834
    +  INVARIANT: `tcl_loc` and `tcl_in_gen_code` are modified only in `setSrcSpan`.
    
    835 835
     
    
    836 836
     * Now, when
    
    837 837
           tcMonoLExpr :: LHsExpr GhcRn -> ExpRhoType -> TcM (HsExpr GhcTc)
    
    838 838
       gets a located expression, it does 3 things:
    
    839 839
         (a) Calls `setSrcSpanA` to set the ambient source-code location
    
    840
    -    (b) Calls `addExprCtxt` to add a suitable `HsCtxt` on top of the `tcl_err_ctxt`.
    
    840
    +    (b) Calls `addExprCtxt` to push a suitable `HsCtxt` on top of the `tcl_err_ctxt`.
    
    841 841
         (c) Calls `tcExpr` to typecheck the expression.
    
    842 842
     
    
    843 843
     * In these calls, if the `span` is generated  (see `isGeneratedSrcSpan`), then
    
    844
    -     - `setSrcSpanA` sets `tcl_in_gen_code` to `True`
    
    845
    -     - `addErrCtxt` is a no-op if `tcl_in_gen_code` is True
    
    846
    -  This is how we avoid populating the TcLclCtxt with generated code.
    
    847
    -
    
    848
    -* The type checker error-stack element `GHC.Tc.Types.ErrCtxt.HsCtxt`
    
    849
    -  just stores an error message
    
    850
    -
    
    851
    -           type ErrCtxtStack = [HsCtxt]
    
    852
    -
    
    853
    -  When called on an `XExpr`, `addLExprCtxt`, adds the user written thing
    
    854
    -  `ue`, and the error message provided by the caller on the `ErrCtxtStack` See
    
    855
    -  Note [ErrCtxtStack Manipulation] for more details.
    
    856
    -
    
    844
    +     - `setSrcSpanA` sets `tcl_in_gen_code` to `True`, and leaves `tcl_loc` unchanged
    
    845
    +     - `addExprCtxt` is a no-op if `tcl_in_gen_code` is True
    
    846
    +  The result is that `tcl_loc` has the span from the innermost /user/ tree node;
    
    847
    +  and the ErrCtxtStack in `tcl_err_ctxt` only has contexts arisign from user code.
    
    848
    +
    
    849
    +* Note that inside an expansion we have sub-expressions from the original program.
    
    850
    +  As soon as we enter one of those, identified by a /user/ span, `setSrcSpanA` will
    
    851
    +  sets the `tcl_loc` to reflect that span, and switch off `tcl_in_gen_code`.  Nice!
    
    857 852
     -}
    
    858 853
     
    
    859 854
     tcHsExpansion :: HsExpansion GhcRn -> ExpRhoType -> TcM (HsExpr GhcTc)
    
    860
    -tcHsExpansion (HSE o e) res_ty
    
    861
    -   = do e' <- tcMonoLExpr e res_ty
    
    862
    -        return $ XExpr (ExpandedThingTc (HSE o e'))
    
    855
    +tcHsExpansion (HSE { hse_ctxt = o, hse_exp = e }) res_ty
    
    856
    +   = do { e' <- tcMonoLExpr e res_ty
    
    857
    +        ; return $ XExpr $ ExpandedThingTc $
    
    858
    +          HSE { hse_ctxt = o, hse_exp = e' } }
    
    863 859
     
    
    864 860
     
    
    865 861
     {-
    

  • compiler/GHC/Tc/Types/LclEnv.hs
    ... ... @@ -168,14 +168,12 @@ getLclEnvErrCtxt = tcl_err_ctxt . tcl_lcl_ctxt
    168 168
     setLclEnvErrCtxt :: ErrCtxtStack -> TcLclEnv -> TcLclEnv
    
    169 169
     setLclEnvErrCtxt ctxt = modifyLclCtxt (\env -> env { tcl_err_ctxt = ctxt })
    
    170 170
     
    
    171
    --- See Note [ErrCtxtStack Manipulation]
    
    172 171
     addLclEnvErrCtxt :: HsCtxt -> TcLclEnv -> TcLclEnv
    
    173 172
     addLclEnvErrCtxt ec = setLclEnvHsCtxt ec
    
    174 173
     
    
    175 174
     setLclEnvHsCtxt :: HsCtxt -> TcLclEnv -> TcLclEnv
    
    176 175
     setLclEnvHsCtxt ec = modifyLclCtxt (setLclCtxtHsCtxt ec)
    
    177 176
     
    
    178
    --- See Note [ErrCtxtStack Manipulation]
    
    179 177
     setLclCtxtHsCtxt :: HsCtxt -> TcLclCtxt -> TcLclCtxt
    
    180 178
     setLclCtxtHsCtxt ec lclCtxt
    
    181 179
       -- Never stack 2 statement error contexts on top of each other