Apoorv Ingle pushed to branch wip/spj-apporv-Oct24 at Glasgow Haskell Compiler / GHC

Commits:

7 changed files:

Changes:

  • compiler/GHC/Hs/Expr.hs
    ... ... @@ -675,11 +675,11 @@ type instance XXExpr GhcTc = XXExprGhcTc
    675 675
     data SrcCodeOrigin
    
    676 676
       = OrigExpr (HsExpr GhcRn)                -- ^ The source, user written, expression
    
    677 677
       | OrigStmt (ExprLStmt GhcRn) HsDoFlavour -- ^ which kind of do-block did this statement come from
    
    678
    -  | OrigPat  (Pat GhcRn)                  -- ^ Used for failable patterns that trigger MonadFail constraints
    
    678
    +  | OrigPat  (Pat GhcRn)                   -- ^ Used for failable patterns that trigger MonadFail constraints
    
    679 679
     
    
    680 680
     data XXExprGhcRn
    
    681
    -  = ExpandedThingRn { xrn_orig     :: SrcCodeOrigin       -- The original source thing to be used for error messages
    
    682
    -                    , xrn_expanded :: HsExpr GhcRn    -- The compiler generated expanded thing
    
    681
    +  = ExpandedThingRn { xrn_orig     :: SrcCodeOrigin   -- The original source thing to be used for error messages
    
    682
    +                    , xrn_expanded :: HsExpr GhcRn    -- The compiler generated, expanded thing
    
    683 683
                         }
    
    684 684
     
    
    685 685
       | PopErrCtxt                                     -- A hint for typechecker to pop
    

  • compiler/GHC/Tc/Gen/App.hs
    ... ... @@ -544,17 +544,18 @@ tcValArgs do_ql fun args = go do_ql 0 args
    544 544
         go do_ql pos (arg : args) =
    
    545 545
           do { arg' <- tcValArg do_ql pos' fun arg
    
    546 546
              ; args' <- go do_ql pos' args
    
    547
    -         ; return (arg' : args')
    
    548
    -         }
    
    547
    +         ; return (arg' : args') }
    
    549 548
           where
    
    550 549
         -- increment position if the argument is user written type or value argument
    
    551 550
             pos' | EValArg{} <- arg
    
    552 551
                  = pos + 1
    
    553 552
                  | EValArgQL{} <- arg
    
    554 553
                  = pos + 1
    
    555
    -             | ETypeArg{ ea_ctxt = l } <- arg
    
    556
    -             , not (isGeneratedSrcSpan l) = pos + 1
    
    557
    -             | otherwise = pos
    
    554
    +             | ETypeArg{ ea_loc_span = l } <- arg
    
    555
    +             , not (isGeneratedSrcSpan l)
    
    556
    +             = pos + 1
    
    557
    +             | otherwise
    
    558
    +             = pos
    
    558 559
     
    
    559 560
     
    
    560 561
     tcValArg :: QLFlag -> Int -> HsExpr GhcRn -> HsExprArg 'TcpInst    -- Actual argument
    
    ... ... @@ -566,7 +567,7 @@ tcValArg do_ql _ _ (EWrap (EHsWrap w)) = do { whenQL do_ql $ qlMonoHsWrapper w
    566 567
       -- qlMonoHsWrapper: see Note [Monomorphise instantiation variables]
    
    567 568
     tcValArg _     _ _ (EWrap ew)          = return (EWrap ew)
    
    568 569
     
    
    569
    -tcValArg do_ql pos fun (EValArg { ea_ctxt   = ctxt
    
    570
    +tcValArg do_ql pos fun (EValArg { ea_loc_span   = ctxt
    
    570 571
                                 , ea_arg    = larg@(L arg_loc arg)
    
    571 572
                                 , ea_arg_ty = sc_arg_ty })
    
    572 573
       = addArgCtxt pos fun larg $
    
    ... ... @@ -594,20 +595,21 @@ tcValArg do_ql pos fun (EValArg { ea_ctxt = ctxt
    594 595
                      tcPolyExpr arg (mkCheckExpType exp_arg_ty)
    
    595 596
            ; traceTc "tcValArg" $ vcat [ ppr arg'
    
    596 597
                                        , text "}" ]
    
    597
    -       ; return (EValArg { ea_ctxt = ctxt
    
    598
    +       ; return (EValArg { ea_loc_span = ctxt
    
    598 599
                              , ea_arg = L arg_loc arg'
    
    599 600
                              , ea_arg_ty = noExtField }) }
    
    600 601
     
    
    601
    -tcValArg _ pos fun (EValArgQL { eaql_wanted  = wanted
    
    602
    -                      , eaql_ctxt    = ctxt
    
    603
    -                      , eaql_arg_ty  = sc_arg_ty
    
    604
    -                      , eaql_larg    = larg@(L arg_loc rn_expr)
    
    605
    -                      , eaql_tc_fun  = tc_head
    
    606
    -                      , eaql_rn_fun  = rn_fun
    
    607
    -                      , eaql_fun_ue  = head_ue
    
    608
    -                      , eaql_args    = inst_args
    
    609
    -                      , eaql_encl    = arg_influences_enclosing_call
    
    610
    -                      , eaql_res_rho = app_res_rho })
    
    602
    +tcValArg _ pos fun (EValArgQL {
    
    603
    +                        eaql_wanted   = wanted
    
    604
    +                      , eaql_loc_span = ctxt
    
    605
    +                      , eaql_arg_ty   = sc_arg_ty
    
    606
    +                      , eaql_larg     = larg@(L arg_loc rn_expr)
    
    607
    +                      , eaql_tc_fun   = tc_head
    
    608
    +                      , eaql_rn_fun   = rn_fun
    
    609
    +                      , eaql_fun_ue   = head_ue
    
    610
    +                      , eaql_args     = inst_args
    
    611
    +                      , eaql_encl     = arg_influences_enclosing_call
    
    612
    +                      , eaql_res_rho  = app_res_rho })
    
    611 613
       = addArgCtxt pos fun larg $
    
    612 614
         do { -- Expose QL results to tcSkolemise, as in EValArg case
    
    613 615
              Scaled mult exp_arg_ty <- liftZonkM $ zonkScaledTcType sc_arg_ty
    
    ... ... @@ -644,7 +646,7 @@ tcValArg _ pos fun (EValArgQL { eaql_wanted = wanted
    644 646
            ; traceTc "tcEValArgQL }" $
    
    645 647
                vcat [ text "app_res_rho:" <+> ppr app_res_rho ]
    
    646 648
     
    
    647
    -       ; return (EValArg { ea_ctxt   = ctxt
    
    649
    +       ; return (EValArg { ea_loc_span   = ctxt
    
    648 650
                              , ea_arg    = L arg_loc (mkHsWrap wrap arg')
    
    649 651
                              , ea_arg_ty = noExtField }) }
    
    650 652
     
    
    ... ... @@ -814,10 +816,10 @@ tcInstFun do_ql inst_final fun_orig (tc_fun, rn_fun, fun_ctxt) fun_sigma rn_args
    814 816
           = go1 pos (EPrag sp prag : acc) fun_ty args
    
    815 817
     
    
    816 818
         -- Rule ITYARG from Fig 4 of the QL paper
    
    817
    -    go1 pos acc fun_ty ( ETypeArg { ea_ctxt = ctxt, ea_hs_ty = hs_ty }
    
    819
    +    go1 pos acc fun_ty ( ETypeArg { ea_loc_span = ctxt, ea_hs_ty = hs_ty }
    
    818 820
                                  : rest_args )
    
    819 821
           = do { (ty_arg, inst_ty) <- tcVTA fun_conc_tvs fun_ty hs_ty
    
    820
    -           ; let arg' = ETypeArg { ea_ctxt = ctxt, ea_hs_ty = hs_ty, ea_ty_arg = ty_arg }
    
    822
    +           ; let arg' = ETypeArg { ea_loc_span = ctxt, ea_hs_ty = hs_ty, ea_ty_arg = ty_arg }
    
    821 823
                ; go pos (arg' : acc) inst_ty rest_args }
    
    822 824
     
    
    823 825
         -- Rule IVAR from Fig 4 of the QL paper:
    
    ... ... @@ -857,7 +859,7 @@ tcInstFun do_ql inst_final fun_orig (tc_fun, rn_fun, fun_ctxt) fun_sigma rn_args
    857 859
     
    
    858 860
         -- Rule IARG from Fig 4 of the QL paper:
    
    859 861
         go1 pos acc fun_ty
    
    860
    -        (EValArg { ea_arg = arg, ea_ctxt = ctxt } : rest_args)
    
    862
    +        (EValArg { ea_arg = arg, ea_loc_span = ctxt } : rest_args)
    
    861 863
           = do { let herald = mk_herald tc_fun (unLoc arg)
    
    862 864
                ; (wrap, arg_ty, res_ty) <-
    
    863 865
                     -- NB: matchActualFunTy does the rep-poly check.
    
    ... ... @@ -924,9 +926,9 @@ addArgCtxt :: Int -> HsExpr GhcRn -> LHsExpr GhcRn
    924 926
     -- There are 2 cases:
    
    925 927
     -- 1. In the normal case, we add an informative context
    
    926 928
     --          "In the third argument of f, namely blah"
    
    927
    --- 2. If we are deep inside generated code (`isGeneratedCode` is `True`)
    
    929
    +-- 2. If we are deep inside generated code (<=> `isGeneratedCode` is `True`)
    
    928 930
     --          "In the expression: arg"
    
    929
    ---  If the arg is also a generated thing, i.e. arg_loc is generatedSrcSpan, we would print do nothing.
    
    931
    +--  If the arg is also a generated thing, i.e. `arg_loc` is `generatedSrcSpan`, we would print nothing.
    
    930 932
     --  See Note [Rebindable syntax and XXExprGhcRn] in GHC.Hs.Expr
    
    931 933
     --  See Note [Expanding HsDo with XXExprGhcRn] in GHC.Tc.Gen.Do
    
    932 934
     addArgCtxt arg_no fun (L arg_loc arg) thing_inside
    
    ... ... @@ -1733,7 +1735,7 @@ quickLookArg DoQL pos ctxt fun larg orig_arg_ty
    1733 1735
     skipQuickLook :: SrcSpan -> LHsExpr GhcRn -> Scaled TcRhoType
    
    1734 1736
                   -> TcM (HsExprArg 'TcpInst)
    
    1735 1737
     skipQuickLook ctxt larg arg_ty
    
    1736
    -  = return (EValArg { ea_ctxt   = ctxt
    
    1738
    +  = return (EValArg { ea_loc_span   = ctxt
    
    1737 1739
                         , ea_arg    = larg
    
    1738 1740
                         , ea_arg_ty = arg_ty })
    
    1739 1741
     
    
    ... ... @@ -1834,16 +1836,16 @@ quickLookArg1 pos ctxt fun larg@(L _ arg) sc_arg_ty@(Scaled _ orig_arg_rho)
    1834 1836
     
    
    1835 1837
            ; traceTc "quickLookArg done }" (ppr rn_fun)
    
    1836 1838
     
    
    1837
    -       ; return (EValArgQL { eaql_ctxt    = ctxt
    
    1838
    -                           , eaql_arg_ty  = sc_arg_ty
    
    1839
    -                           , eaql_larg    = larg
    
    1840
    -                           , eaql_tc_fun  = tc_head
    
    1841
    -                           , eaql_rn_fun  = rn_fun
    
    1842
    -                           , eaql_fun_ue  = fun_ue
    
    1843
    -                           , eaql_args    = inst_args
    
    1844
    -                           , eaql_wanted  = wanted
    
    1845
    -                           , eaql_encl    = arg_influences_enclosing_call
    
    1846
    -                           , eaql_res_rho = app_res_rho }) }}}
    
    1839
    +       ; return (EValArgQL { eaql_loc_span = ctxt
    
    1840
    +                           , eaql_arg_ty   = sc_arg_ty
    
    1841
    +                           , eaql_larg     = larg
    
    1842
    +                           , eaql_tc_fun   = tc_head
    
    1843
    +                           , eaql_rn_fun   = rn_fun
    
    1844
    +                           , eaql_fun_ue   = fun_ue
    
    1845
    +                           , eaql_args     = inst_args
    
    1846
    +                           , eaql_wanted   = wanted
    
    1847
    +                           , eaql_encl     = arg_influences_enclosing_call
    
    1848
    +                           , eaql_res_rho  = app_res_rho }) }}}
    
    1847 1849
     
    
    1848 1850
     {- *********************************************************************
    
    1849 1851
     *                                                                      *
    

  • compiler/GHC/Tc/Gen/Do.hs
    ... ... @@ -75,7 +75,7 @@ expand_do_stmts _ (stmt@(L _ (XStmtLR ApplicativeStmt{})): _) =
    75 75
     
    
    76 76
     expand_do_stmts _ [] = pprPanic "expand_do_stmts: impossible happened. Empty stmts" empty
    
    77 77
     
    
    78
    -expand_do_stmts flav [stmt@(L sloc (LastStmt _ body@(L body_loc _) _ ret_expr))]
    
    78
    +expand_do_stmts _flav [_stmt@(L _sloc (LastStmt _ body@(L body_loc _) _ ret_expr))]
    
    79 79
     -- See  Note [Expanding HsDo with XXExprGhcRn] Equation (5) below
    
    80 80
     -- last statement of a list comprehension, needs to explicitly return it
    
    81 81
     -- See `checkLastStmt` and `Syntax.Expr.StmtLR.LastStmt`
    
    ... ... @@ -83,7 +83,7 @@ expand_do_stmts flav [stmt@(L sloc (LastStmt _ body@(L body_loc _) _ ret_expr))]
    83 83
        -- Last statement is just body if we are not in ListComp context. See Syntax.Expr.LastStmt
    
    84 84
        -- = return $ L sloc (mkExpandedStmt stmt flav (HsPar noExtField body))
    
    85 85
        = return body
    
    86
    -   | SyntaxExprRn ret <- ret_expr
    
    86
    +   | SyntaxExprRn ret <- ret_expr  -- We have unfortunately lost the location on the return function :(
    
    87 87
        --
    
    88 88
        --    ------------------------------------------------
    
    89 89
        --               return e  ~~> return e
    
    ... ... @@ -230,7 +230,7 @@ mk_fail_block _ _ _ _ = pprPanic "mk_fail_block: impossible happened" empty
    230 230
     
    
    231 231
     {- Note [Expanding HsDo with XXExprGhcRn]
    
    232 232
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    233
    -We expand `do`-blocks before typechecking it, by re-using the existing `XXExprGhcRns` and `RebindableSyntax` machinery.
    
    233
    +We expand `do`-blocks before typechecking it, by re-using the existing `XXExprGhcRn` and `RebindableSyntax` machinery.
    
    234 234
     This is very similar to:
    
    235 235
       1. Expansions done in `GHC.Rename.Expr.rnHsIf` for expanding `HsIf`; and
    
    236 236
       2. `desugarRecordUpd` in `GHC.Tc.Gen.Expr.tcExpr` for expanding `RecordUpd`
    
    ... ... @@ -275,14 +275,15 @@ They capture the essence of statement expansions as implemented in `expand_do_st
    275 275
     
    
    276 276
       DO【 _ 】 maps a sequence of do statements and recursively converts them into expressions
    
    277 277
     
    
    278
    -          (1) DO【 s; ss 】      = ‹ExpansionStmt s›((>>) s (‹PopErrCtxt›DO【 ss 】))
    
    278
    +          (1) DO【 s; ss 】      = ‹ExpansionStmt s›((>>) (‹PopErrCtxt› s) (‹PopErrCtxt› DO【 ss 】))
    
    279 279
     
    
    280 280
               (2) DO【 p <- e; ss 】 = if p is irrefutable
    
    281 281
                                        then ‹ExpansionStmt (p <- e)›
    
    282
    -                                          (>>=) s ((\ p -> ‹PopExprCtxt› DO【 ss 】))
    
    282
    +                                          (>>=) (‹PopExprCtxt› s) ((\ p -> ‹PopExprCtxt› DO【 ss 】))
    
    283 283
                                        else ‹ExpansionStmt (p <- e)›
    
    284
    -                                          (>>=) s ((\case p -> ‹PopExprCtxt› DO【 ss 】
    
    285
    -                                                          _ -> fail "pattern p failure"))
    
    284
    +                                          (>>=) (‹PopExprCtxt› s)
    
    285
    +                                                (\case p -> ‹PopExprCtxt› DO【 ss 】
    
    286
    +                                                       _ -> fail "pattern p failure")
    
    286 287
     
    
    287 288
               (3) DO【 let x = e; ss 】
    
    288 289
                                      = ‹ExpansionStmt (let x = e)› (let x = e in (‹PopErrCtxt›DO【 ss 】))
    
    ... ... @@ -313,8 +314,8 @@ The expanded version (performed by `expand_do_stmts`) looks like:
    313 314
                        {g2} (>>) ({l2} g p)
    
    314 315
                                  ({l3} return p))
    
    315 316
     
    
    316
    -The {l1} etc are location/source span information stored in the AST by the parser,
    
    317
    -{g1} are compiler generated source spans.
    
    317
    +The {l1}, {l2}, etc. are the location/source span information stored in the AST by the parser,
    
    318
    +{g1}, {g2}, etc. are the compiler generated source spans.
    
    318 319
     
    
    319 320
     
    
    320 321
     The 3 non-obvious points to consider are:
    
    ... ... @@ -427,10 +428,10 @@ It stores the original statement (with location) and the expanded expression
    427 428
           ‹ExpandedThingRn do { e1; e2; e3 }›                        -- Original Do Expression
    
    428 429
                                                                      -- Expanded Do Expression
    
    429 430
               (‹ExpandedThingRn e1›                                  -- Original Statement
    
    430
    -               ({(>>) e1}                                        -- Expanded Expression
    
    431
    -                  ‹PopErrCtxt› (‹ExpandedThingRn e2›
    
    432
    -                         ({(>>) e2}
    
    433
    -                            ‹PopErrCtxt› (‹ExpandedThingRn e3› {e3})))))
    
    431
    +               ({(>>) ‹PopErrCtxt› e1}                           -- Expanded Expression
    
    432
    +                      ‹PopErrCtxt› (‹ExpandedThingRn e2›
    
    433
    +                         ({(>>) ‹PopErrCtxt› e2}
    
    434
    +                                ‹PopErrCtxt› (‹ExpandedThingRn e3› {e3})))))
    
    434 435
     
    
    435 436
       * Whenever the typechecker steps through an `ExpandedThingRn`,
    
    436 437
         we push the original statement in the error context, set the error location to the
    
    ... ... @@ -445,7 +446,7 @@ It stores the original statement (with location) and the expanded expression
    445 446
         as precise as possible, and not just blame the complete `do`-block.
    
    446 447
         Thus, when we typecheck the application `(>>) e1`, we push the "In the stmt of do block e1" with
    
    447 448
         the source location of `e1` in the error context stack as we walk inside an `ExpandedThingRn`.
    
    448
    -    See also Note [splitHsApps].
    
    449
    +    See also Note [splitHsApps] and Note [Error Context Stack]
    
    449 450
     
    
    450 451
       * After the expanded expression of a `do`-statement is typechecked
    
    451 452
         and before moving to the next statement of the `do`-block, we need to first pop the top
    

  • compiler/GHC/Tc/Gen/Expr.hs
    ... ... @@ -648,9 +648,9 @@ tcExpr expr@(RecordUpd { rupd_expr = record_expr
    648 648
            res_ty
    
    649 649
       = assert (notNull rbnds) $
    
    650 650
         do  { -- Expand the record update. See Note [Record Updates].
    
    651
    -        ; (ds_expr, ds_res_ty, err_ctxt)
    
    651
    +        ; (ds_expr, ds_res_ty, err_msg)
    
    652 652
                 <- expandRecordUpd record_expr possible_parents rbnds res_ty
    
    653
    -        ; addErrCtxt err_ctxt $
    
    653
    +        ; addErrCtxt err_msg $
    
    654 654
               setInGeneratedCode (OrigExpr expr) $
    
    655 655
               do { -- Typecheck the expanded expression.
    
    656 656
                    expr' <- tcExpr ds_expr (Check ds_res_ty)
    
    ... ... @@ -748,9 +748,11 @@ tcXExpr (PopErrCtxt e) res_ty
    748 748
              tcExpr e res_ty
    
    749 749
     
    
    750 750
     tcXExpr (ExpandedThingRn o e) res_ty
    
    751
    -   = mkExpandedTc o <$> -- necessary for breakpoints
    
    752
    -      do setInGeneratedCode o $
    
    753
    -           tcExpr e res_ty
    
    751
    +   = setInGeneratedCode o $
    
    752
    +     -- e is the expanded expression of o, so we need to set the error ctxt to generated
    
    753
    +     -- see Note [Error Context Stack] in `GHC.Tc.Type.LclEnv`
    
    754
    +        mkExpandedTc o <$> -- necessary for hpc ticks
    
    755
    +          tcExpr e res_ty
    
    754 756
     
    
    755 757
     -- For record selection, same as HsVar case
    
    756 758
     tcXExpr xe res_ty = tcApp (XExpr xe) res_ty
    
    ... ... @@ -1441,7 +1443,7 @@ expandRecordUpd record_expr possible_parents rbnds res_ty
    1441 1443
     
    
    1442 1444
            -- STEP 2 (b): expand to HsCase, as per note [Record Updates]
    
    1443 1445
            ; let ds_expr :: HsExpr GhcRn
    
    1444
    -             ds_expr = HsLet noExtField let_binds (L gen case_expr)
    
    1446
    +             ds_expr = HsLet noExtField let_binds (wrapGenSpan case_expr)
    
    1445 1447
     
    
    1446 1448
                  case_expr :: HsExpr GhcRn
    
    1447 1449
                  case_expr = HsCase RecUpd record_expr
    
    ... ... @@ -1456,11 +1458,10 @@ expandRecordUpd record_expr possible_parents rbnds res_ty
    1456 1458
                  upd_ids_lhs = [ (NonRecursive, [genSimpleFunBind (idName id) [] rhs])
    
    1457 1459
                                | (_, (id, rhs)) <- upd_ids ]
    
    1458 1460
                  mk_idSig :: (Name, (Id, LHsExpr GhcRn)) -> LSig GhcRn
    
    1459
    -             mk_idSig (_, (id, _)) = L gen $ XSig $ IdSig id
    
    1461
    +             mk_idSig (_, (id, _)) = wrapGenSpan (XSig $ IdSig id)
    
    1460 1462
                    -- We let-bind variables using 'IdSig' in order to accept
    
    1461 1463
                    -- record updates involving higher-rank types.
    
    1462 1464
                    -- See Wrinkle [Using IdSig] in Note [Record Updates].
    
    1463
    -             gen = noAnnSrcSpan generatedSrcSpan
    
    1464 1465
     
    
    1465 1466
             ; traceTc "expandRecordUpd" $
    
    1466 1467
                 vcat [ text "relevant_con:" <+> ppr relevant_con
    

  • compiler/GHC/Tc/Gen/Head.hs
    ... ... @@ -152,6 +152,7 @@ takes apart either an HsApp, or an infix OpApp, returning
    152 152
       innermost un-expanded head as the "error head".
    
    153 153
     
    
    154 154
     * A list of HsExprArg, the arguments
    
    155
    +* We do not look through expanded expressions (except PopErrCtxt.)
    
    155 156
     -}
    
    156 157
     
    
    157 158
     data TcPass = TcpRn     -- Arguments decomposed
    
    ... ... @@ -161,14 +162,14 @@ data TcPass = TcpRn -- Arguments decomposed
    161 162
     data HsExprArg (p :: TcPass) where -- See Note [HsExprArg]
    
    162 163
     
    
    163 164
       -- Data constructor EValArg represents a value argument
    
    164
    -  EValArg :: { ea_ctxt   :: SrcSpan
    
    165
    +  EValArg :: { ea_loc_span   :: SrcSpan
    
    165 166
                  , ea_arg_ty :: !(XEVAType p)
    
    166 167
                  , ea_arg    :: LHsExpr (GhcPass (XPass p)) }
    
    167 168
               -> HsExprArg p
    
    168 169
     
    
    169 170
       -- Data constructor EValArgQL represents an argument that has been
    
    170 171
       -- partly-type-checked by Quick Look; see Note [EValArgQL]
    
    171
    -  EValArgQL :: { eaql_ctxt    :: SrcSpan
    
    172
    +  EValArgQL :: { eaql_loc_span    :: SrcSpan
    
    172 173
                    , eaql_arg_ty  :: Scaled TcSigmaType  -- Argument type expected by function
    
    173 174
                    , eaql_larg    :: LHsExpr GhcRn       -- Original application, for
    
    174 175
                                                          -- location and error msgs
    
    ... ... @@ -182,7 +183,7 @@ data HsExprArg (p :: TcPass) where -- See Note [HsExprArg]
    182 183
                    , eaql_res_rho :: TcRhoType }           -- Result type of the application
    
    183 184
                 -> HsExprArg 'TcpInst  -- Only exists in TcpInst phase
    
    184 185
     
    
    185
    -  ETypeArg :: { ea_ctxt   :: SrcSpan
    
    186
    +  ETypeArg :: { ea_loc_span   :: SrcSpan
    
    186 187
                   , ea_hs_ty  :: LHsWcType GhcRn  -- The type arg
    
    187 188
                   , ea_ty_arg :: !(XETAType p) }  -- Kind-checked type arg
    
    188 189
                -> HsExprArg p
    
    ... ... @@ -215,12 +216,12 @@ type family XPass (p :: TcPass) where
    215 216
       XPass 'TcpTc   = 'Typechecked
    
    216 217
     
    
    217 218
     mkEValArg :: SrcSpan -> LHsExpr GhcRn -> HsExprArg 'TcpRn
    
    218
    -mkEValArg ctxt e = EValArg { ea_arg = e, ea_ctxt = ctxt
    
    219
    +mkEValArg src_loc e = EValArg { ea_arg = e, ea_loc_span = src_loc
    
    219 220
                                , ea_arg_ty = noExtField }
    
    220 221
     
    
    221 222
     mkETypeArg :: SrcSpan -> LHsWcType GhcRn -> HsExprArg 'TcpRn
    
    222
    -mkETypeArg ctxt hs_ty =
    
    223
    -  ETypeArg { ea_ctxt = ctxt
    
    223
    +mkETypeArg src_loc hs_ty =
    
    224
    +  ETypeArg { ea_loc_span = src_loc
    
    224 225
                , ea_hs_ty = hs_ty
    
    225 226
                , ea_ty_arg = noExtField }
    
    226 227
     
    
    ... ... @@ -291,9 +292,9 @@ rebuildHsApps :: (HsExpr GhcTc, SrcSpan)
    291 292
     rebuildHsApps (fun, _) [] = fun
    
    292 293
     rebuildHsApps (fun, sloc) (arg : args)
    
    293 294
       = case arg of
    
    294
    -      EValArg { ea_arg = arg, ea_ctxt = sloc' }
    
    295
    +      EValArg { ea_arg = arg, ea_loc_span = sloc' }
    
    295 296
             -> rebuildHsApps (HsApp noExtField lfun arg, sloc') args
    
    296
    -      ETypeArg { ea_hs_ty = hs_ty, ea_ty_arg = ty, ea_ctxt = sloc' }
    
    297
    +      ETypeArg { ea_hs_ty = hs_ty, ea_ty_arg = ty, ea_loc_span = sloc' }
    
    297 298
             -> rebuildHsApps (HsAppType ty lfun hs_ty, sloc') args
    
    298 299
           EPrag sloc' p
    
    299 300
             -> rebuildHsApps (HsPragE noExtField p lfun, sloc') args
    
    ... ... @@ -330,7 +331,7 @@ instance OutputableBndrId (XPass p) => Outputable (HsExprArg p) where
    330 331
       ppr (EPrag _ p)                     = text "EPrag" <+> ppr p
    
    331 332
       ppr (ETypeArg { ea_hs_ty = hs_ty }) = char '@' <> ppr hs_ty
    
    332 333
       ppr (EWrap wrap)                    = ppr wrap
    
    333
    -  ppr (EValArg { ea_arg = arg, ea_ctxt = sloc })
    
    334
    +  ppr (EValArg { ea_arg = arg, ea_loc_span = sloc })
    
    334 335
         = text "EValArg" <> braces (ppr sloc) <+> ppr arg
    
    335 336
       ppr (EValArgQL { eaql_tc_fun = fun, eaql_args = args, eaql_res_rho = ty})
    
    336 337
         = hang (text "EValArgQL" <+> ppr fun)
    

  • compiler/GHC/Tc/Types/LclEnv.hs
    ... ... @@ -91,29 +91,54 @@ data TcLclEnv -- Changes as we move inside an expression
    91 91
             tcl_errs :: TcRef (Messages TcRnMessage)     -- Place to accumulate diagnostics
    
    92 92
         }
    
    93 93
     
    
    94
    +{-
    
    95
    +Note [Error Context Stack]
    
    96
    +~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    97
    +This data structure keeps track of two things:
    
    98
    +1. Are we type checking a compiler generated/non-user written code.
    
    99
    +2. The trail of the error messages that have been added in route to the current expression
    
    100
    +
    
    101
    +* When the `ErrCtxtStack` is a `UserCodeCtxt`,
    
    102
    +  - the current expression being typechecked is user written
    
    103
    +* When the `ErrorCtxtStack` is a `GeneratedCodeCtxt`
    
    104
    +  - the current expression being typechecked is compiler generated;
    
    105
    +  - the original, possibly user written, source code thing is stored in `src_code_origin` field.
    
    106
    +  - the `src_code_origin` is what will be blamed in the error message
    
    107
    +
    
    108
    +-}
    
    109
    +
    
    94 110
     
    
    111
    +-- See Note [Error Context Stack]
    
    95 112
     data ErrCtxtStack
    
    96
    -  = UserCodeCtxt {err_ctxt :: [ErrCtxt]}
    
    97
    -  | GeneratedCodeCtxt { src_code_origin :: SrcCodeOrigin
    
    98
    -                      , err_ctxt ::  [ErrCtxt] }
    
    113
    +  = UserCodeCtxt { lcl_err_ctxt :: [ErrCtxt] } -- ^ Trail of error messages
    
    114
    +  | GeneratedCodeCtxt { src_code_origin :: SrcCodeOrigin -- ^ Original, user written code
    
    115
    +                      , lcl_err_ctxt ::  [ErrCtxt] } -- ^ Trail of error messages
    
    99 116
     
    
    117
    +-- | Are we in a generated context?
    
    100 118
     isGeneratedCodeCtxt :: ErrCtxtStack -> Bool
    
    101 119
     isGeneratedCodeCtxt UserCodeCtxt{} = False
    
    102 120
     isGeneratedCodeCtxt _ = True
    
    103 121
     
    
    122
    +-- | Get the original source code
    
    104 123
     get_src_code_origin :: ErrCtxtStack -> Maybe SrcCodeOrigin
    
    105 124
     get_src_code_origin (UserCodeCtxt{}) = Nothing
    
    125
    +                                -- we are in user code, so blame the expression in hand
    
    106 126
     get_src_code_origin es = Just $ src_code_origin es
    
    127
    +                   -- we are in generated code, so extract the original expression
    
    107 128
     
    
    129
    +-- | Modify the error context stack
    
    130
    +--   N.B. If we are in a generated context, any updates to the context stack are ignored.
    
    131
    +--   We want to blame the errors that appear in a generated expression
    
    132
    +--   to the original, user written code
    
    108 133
     modify_err_ctxt_stack :: ([ErrCtxt] -> [ErrCtxt]) -> ErrCtxtStack -> ErrCtxtStack
    
    109 134
     modify_err_ctxt_stack f (UserCodeCtxt e) =  UserCodeCtxt (f e)
    
    110
    -modify_err_ctxt_stack _ c = c -- any updates on the err context in generated context should be ignored
    
    135
    +modify_err_ctxt_stack _ c = c -- any updates on the err context in a generated context should be ignored
    
    111 136
     
    
    112 137
     
    
    113 138
     data TcLclCtxt
    
    114 139
       = TcLclCtxt {
    
    115 140
             tcl_loc        :: RealSrcSpan,     -- Source span
    
    116
    -        tcl_ctxt       :: ErrCtxtStack,
    
    141
    +        tcl_ctxt       :: ErrCtxtStack,    -- See Note [Error Context Stack]
    
    117 142
             tcl_tclvl      :: TcLevel,
    
    118 143
             tcl_bndrs      :: TcBinderStack,   -- Used for reporting relevant bindings,
    
    119 144
                                                -- and for tidying type
    
    ... ... @@ -178,7 +203,7 @@ getLclEnvLoc :: TcLclEnv -> RealSrcSpan
    178 203
     getLclEnvLoc = tcl_loc . tcl_lcl_ctxt
    
    179 204
     
    
    180 205
     getLclEnvErrCtxt :: TcLclEnv -> [ErrCtxt]
    
    181
    -getLclEnvErrCtxt = err_ctxt . tcl_ctxt . tcl_lcl_ctxt
    
    206
    +getLclEnvErrCtxt = lcl_err_ctxt . tcl_ctxt . tcl_lcl_ctxt
    
    182 207
     
    
    183 208
     setLclEnvErrCtxt :: [ErrCtxt] -> TcLclEnv -> TcLclEnv
    
    184 209
     setLclEnvErrCtxt ctxt = modifyLclCtxt (\env -> env { tcl_ctxt = modify_err_ctxt_stack (\ _ -> ctxt) (tcl_ctxt env) })
    
    ... ... @@ -193,7 +218,7 @@ setLclEnvSrcCodeOrigin :: SrcCodeOrigin -> TcLclEnv -> TcLclEnv
    193 218
     setLclEnvSrcCodeOrigin o = modifyLclCtxt (setLclCtxtSrcCodeOrigin o)
    
    194 219
     
    
    195 220
     setLclCtxtSrcCodeOrigin :: SrcCodeOrigin -> TcLclCtxt -> TcLclCtxt
    
    196
    -setLclCtxtSrcCodeOrigin o ctxt = ctxt { tcl_ctxt = GeneratedCodeCtxt o (err_ctxt $ tcl_ctxt ctxt) }
    
    221
    +setLclCtxtSrcCodeOrigin o ctxt = ctxt { tcl_ctxt = GeneratedCodeCtxt o (lcl_err_ctxt $ tcl_ctxt ctxt) }
    
    197 222
     
    
    198 223
     lclCtxtInGeneratedCode :: TcLclCtxt -> Bool
    
    199 224
     lclCtxtInGeneratedCode = isGeneratedCodeCtxt . tcl_ctxt
    

  • compiler/GHC/Tc/Utils/Monad.hs
    ... ... @@ -974,9 +974,9 @@ inGeneratedCode = lclEnvInGeneratedCode <$> getLclEnv
    974 974
     
    
    975 975
     setSrcSpan :: SrcSpan -> TcRn a -> TcRn a
    
    976 976
     -- See Note [Error contexts in generated code]
    
    977
    --- for the tcl_in_gen_code manipulation
    
    978 977
     setSrcSpan (RealSrcSpan loc _) thing_inside
    
    979
    -  = updLclCtxt (\env -> env { tcl_loc = loc, tcl_ctxt = UserCodeCtxt (err_ctxt $ tcl_ctxt env)})
    
    978
    +  = updLclCtxt (\env -> env { tcl_loc = loc
    
    979
    +                            , tcl_ctxt = UserCodeCtxt (lcl_err_ctxt $ tcl_ctxt env)})
    
    980 980
                   thing_inside
    
    981 981
     
    
    982 982
     setSrcSpan (UnhelpfulSpan _) thing_inside
    
    ... ... @@ -988,6 +988,7 @@ getSrcCodeOrigin = getLclEnvSrcCodeOrigin <$> getLclEnv
    988 988
     -- | Mark the inner computation as being done inside generated code.
    
    989 989
     --
    
    990 990
     -- See Note [Error contexts in generated code]
    
    991
    +-- See Note [Error Context Stack]
    
    991 992
     setInGeneratedCode :: SrcCodeOrigin -> TcRn a -> TcRn a
    
    992 993
     setInGeneratedCode sco thing_inside =
    
    993 994
       updLclCtxt (setLclCtxtSrcCodeOrigin sco) thing_inside
    
    ... ... @@ -1210,17 +1211,17 @@ problem.
    1210 1211
     
    
    1211 1212
     Note [Error contexts in generated code]
    
    1212 1213
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1213
    -* setSrcSpan sets tcl_in_gen_code to True if the SrcSpan is GeneratedSrcSpan,
    
    1214
    -  and back to False when we get a useful SrcSpan
    
    1214
    +* If the `SrcSpan` is a `RealSrcSpan`, `setSrcSpan` updates the `tcl_loc`,
    
    1215
    +  and makes the `ErrCtxStack` a `UserCodeCtxt`
    
    1216
    +* it is a no-op otherwise
    
    1215 1217
     
    
    1216
    -* When tcl_in_gen_code is True, addErrCtxt becomes a no-op.
    
    1218
    +So, it's better to do a `setSrcSpan` /before/ `addErrCtxt`.
    
    1217 1219
     
    
    1218
    -So typically it's better to do setSrcSpan /before/ addErrCtxt.
    
    1219
    -
    
    1220
    -See Note [Rebindable syntax and XXExprGhcRn] in GHC.Hs.Expr for
    
    1221
    -more discussion of this fancy footwork, as well as
    
    1222
    -Note [Generated code and pattern-match checking] in GHC.Types.Basic for the
    
    1223
    -relation with pattern-match checks.
    
    1220
    +- See Note [Rebindable syntax and XXExprGhcRn] in `GHC.Hs.Expr` for
    
    1221
    +more discussion of this fancy footwork
    
    1222
    +- See Note [Generated code and pattern-match checking] in `GHC.Types.Basic` for the
    
    1223
    +relation with pattern-match checks
    
    1224
    +- See Note [Error Context Stack] in `GHC.Tc.Types.LclEnv` for info about `ErrCtxtStack`
    
    1224 1225
     -}
    
    1225 1226
     
    
    1226 1227
     getErrCtxt :: TcM [ErrCtxt]