Apoorv Ingle pushed to branch wip/ani/kill-popErrCtxt at Glasgow Haskell Compiler / GHC
Commits:
-
58ba3ecc
by Apoorv Ingle at 2025-09-22T18:00:08-05:00
9 changed files:
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Do.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Types/LclEnv.hs
- compiler/GHC/Tc/Utils/Monad.hs
- testsuite/tests/typecheck/should_fail/DoExpansion1.stderr
- testsuite/tests/typecheck/should_fail/DoExpansion2.stderr
Changes:
| ... | ... | @@ -7238,10 +7238,6 @@ pprTyConInstFlavour |
| 7238 | 7238 | pprErrCtxtMsg :: ErrCtxtMsg -> SDoc
|
| 7239 | 7239 | pprErrCtxtMsg = \case
|
| 7240 | 7240 | ExprCtxt expr
|
| 7241 | - | XExpr (ExpandedThingRn (OrigStmt (L _ stmt) flav) _) <- expr
|
|
| 7242 | - -> hang (text "In a stmt of" <+> pprAStmtContext @(LIdP GhcRn) (HsDoStmt flav) <> colon)
|
|
| 7243 | - 2 (ppr_stmt stmt)
|
|
| 7244 | - | otherwise
|
|
| 7245 | 7241 | -> hang (text "In the expression:")
|
| 7246 | 7242 | 2 (ppr (stripParensHsExpr expr))
|
| 7247 | 7243 | ThetaCtxt ctxt theta ->
|
| ... | ... | @@ -396,8 +396,10 @@ tcApp :: HsExpr GhcRn |
| 396 | 396 | tcApp rn_expr exp_res_ty
|
| 397 | 397 | = do { -- Step 1: Split the application chain
|
| 398 | 398 | (fun@(rn_fun, fun_loc), rn_args) <- splitHsApps rn_expr
|
| 399 | + ; inGenCode <- inGeneratedCode
|
|
| 399 | 400 | ; traceTc "tcApp {" $
|
| 400 | - vcat [ text "rn_expr:" <+> ppr rn_expr
|
|
| 401 | + vcat [ text "generated? " <+> ppr inGenCode
|
|
| 402 | + , text "rn_expr:" <+> ppr rn_expr
|
|
| 401 | 403 | , text "rn_fun:" <+> ppr rn_fun
|
| 402 | 404 | , text "fun_loc:" <+> ppr fun_loc
|
| 403 | 405 | , text "rn_args:" <+> ppr rn_args ]
|
| ... | ... | @@ -580,7 +582,7 @@ tcValArg do_ql _ _ (EWrap (EHsWrap w)) = do { whenQL do_ql $ qlMonoHsWrapper w |
| 580 | 582 | -- qlMonoHsWrapper: see Note [Monomorphise instantiation variables]
|
| 581 | 583 | tcValArg _ _ _ (EWrap ew) = return (EWrap ew)
|
| 582 | 584 | |
| 583 | -tcValArg do_ql pos fun (EValArg { ea_loc_span = ctxt
|
|
| 585 | +tcValArg do_ql pos fun (EValArg { ea_loc_span = lspan
|
|
| 584 | 586 | , ea_arg = larg@(L arg_loc arg)
|
| 585 | 587 | , ea_arg_ty = sc_arg_ty })
|
| 586 | 588 | = addArgCtxt pos fun larg $
|
| ... | ... | @@ -597,7 +599,7 @@ tcValArg do_ql pos fun (EValArg { ea_loc_span = ctxt |
| 597 | 599 | DoQL -> liftZonkM $ zonkScaledTcType sc_arg_ty
|
| 598 | 600 | NoQL -> return sc_arg_ty
|
| 599 | 601 | ; traceTc "tcValArg {" $
|
| 600 | - vcat [ text "ctxt:" <+> ppr ctxt
|
|
| 602 | + vcat [ text "lspan:" <+> ppr lspan
|
|
| 601 | 603 | , text "sigma_type" <+> ppr (mkCheckExpType exp_arg_ty)
|
| 602 | 604 | , text "arg:" <+> ppr larg
|
| 603 | 605 | ]
|
| ... | ... | @@ -608,13 +610,13 @@ tcValArg do_ql pos fun (EValArg { ea_loc_span = ctxt |
| 608 | 610 | tcPolyExpr arg (mkCheckExpType exp_arg_ty)
|
| 609 | 611 | ; traceTc "tcValArg" $ vcat [ ppr arg'
|
| 610 | 612 | , text "}" ]
|
| 611 | - ; return (EValArg { ea_loc_span = ctxt
|
|
| 613 | + ; return (EValArg { ea_loc_span = lspan
|
|
| 612 | 614 | , ea_arg = L arg_loc arg'
|
| 613 | 615 | , ea_arg_ty = noExtField }) }
|
| 614 | 616 | |
| 615 | 617 | tcValArg _ pos fun (EValArgQL {
|
| 616 | 618 | eaql_wanted = wanted
|
| 617 | - , eaql_loc_span = ctxt
|
|
| 619 | + , eaql_loc_span = lspan
|
|
| 618 | 620 | , eaql_arg_ty = sc_arg_ty
|
| 619 | 621 | , eaql_larg = larg@(L arg_loc rn_expr)
|
| 620 | 622 | , eaql_tc_fun = tc_head
|
| ... | ... | @@ -659,7 +661,7 @@ tcValArg _ pos fun (EValArgQL { |
| 659 | 661 | ; traceTc "tcEValArgQL }" $
|
| 660 | 662 | vcat [ text "app_res_rho:" <+> ppr app_res_rho ]
|
| 661 | 663 | |
| 662 | - ; return (EValArg { ea_loc_span = ctxt
|
|
| 664 | + ; return (EValArg { ea_loc_span = lspan
|
|
| 663 | 665 | , ea_arg = L arg_loc (mkHsWrap wrap arg')
|
| 664 | 666 | , ea_arg_ty = noExtField }) }
|
| 665 | 667 | |
| ... | ... | @@ -931,11 +933,12 @@ looks_like_type_arg _ = False |
| 931 | 933 | addArgCtxt :: Int -> HsExpr GhcRn -> LHsExpr GhcRn
|
| 932 | 934 | -> TcM a -> TcM a
|
| 933 | 935 | -- There are 2 cases:
|
| 934 | --- 1. In the normal case, we add an informative context
|
|
| 935 | --- "In the third argument of f, namely blah"
|
|
| 936 | --- 2. If we are deep inside generated code (<=> `isGeneratedCode` is `True`)
|
|
| 937 | --- "In the expression: arg"
|
|
| 938 | --- If the arg is also a generated thing, i.e. `arg_loc` is `generatedSrcSpan`, we would print nothing.
|
|
| 936 | +-- 1. In the normal case, we add an informative context (<=> `isGeneratedCode` is `False`)
|
|
| 937 | +-- "In the third argument of f, namely blah"
|
|
| 938 | +-- 2. If we are inside generated code (<=> `isGeneratedCode` is `True`)
|
|
| 939 | +-- (i) If arg_loc is generated do nothing to to LclEnv/LclCtxt
|
|
| 940 | +-- (ii) If arg_loc is Unhelpful UnhelpfulNoLocationInfo set `tcl_in_gen_code` to `True`
|
|
| 941 | +-- (iii) if arg_loc is RealSrcLoc then update tcl_loc and add "In the expression: arg" to ErrCtxtStack
|
|
| 939 | 942 | -- See Note [Rebindable syntax and XXExprGhcRn] in GHC.Hs.Expr
|
| 940 | 943 | -- See Note [Expanding HsDo with XXExprGhcRn] in GHC.Tc.Gen.Do
|
| 941 | 944 | addArgCtxt arg_no fun (L arg_loc arg) thing_inside
|
| ... | ... | @@ -944,12 +947,24 @@ addArgCtxt arg_no fun (L arg_loc arg) thing_inside |
| 944 | 947 | , text "arg: " <+> ppr arg
|
| 945 | 948 | , text "arg_loc" <+> ppr arg_loc])
|
| 946 | 949 | ; if in_generated_code
|
| 947 | - then do setSrcSpanA arg_loc $
|
|
| 948 | - addExprCtxt arg $ -- Auto-suppressed if arg_loc is generated
|
|
| 950 | + then updCtxtForArg (locA arg_loc) arg $
|
|
| 949 | 951 | thing_inside
|
| 950 | 952 | else do setSrcSpanA arg_loc $
|
| 951 | 953 | addErrCtxt (FunAppCtxt (FunAppCtxtExpr fun arg) arg_no) $
|
| 952 | 954 | thing_inside }
|
| 955 | + where
|
|
| 956 | + updCtxtForArg :: SrcSpan -> HsExpr GhcRn -> TcRn a -> TcRn a
|
|
| 957 | + updCtxtForArg l@(RealSrcSpan{}) e thing_inside = -- See 2.iii above
|
|
| 958 | + do setSrcSpan l $
|
|
| 959 | + addExprCtxt e $
|
|
| 960 | + thing_inside
|
|
| 961 | + updCtxtForArg (UnhelpfulSpan UnhelpfulGenerated) _ thing_inside = -- See 2.i above
|
|
| 962 | + thing_inside
|
|
| 963 | + updCtxtForArg (UnhelpfulSpan {}) _ thing_inside = -- See 2.ii above
|
|
| 964 | + do setInUserCode $
|
|
| 965 | + thing_inside
|
|
| 966 | + |
|
| 967 | + |
|
| 953 | 968 | |
| 954 | 969 | {- *********************************************************************
|
| 955 | 970 | * *
|
| ... | ... | @@ -126,7 +126,7 @@ expand_do_stmts doFlavour (stmt@(L loc (BodyStmt _ e (SyntaxExprRn then_op) _)) |
| 126 | 126 | -- e ; stmts ~~> (>>) e stmts'
|
| 127 | 127 | do expand_stmts_expr <- expand_do_stmts doFlavour lstmts
|
| 128 | 128 | let expansion = genHsExpApps then_op -- (>>)
|
| 129 | - [ e -- Span is set becuase of statement loc
|
|
| 129 | + [ wrapNoSpan $ unLoc e -- Span is set because of statement loc
|
|
| 130 | 130 | , expand_stmts_expr ]
|
| 131 | 131 | return $ L loc (mkExpandedStmt stmt doFlavour expansion)
|
| 132 | 132 |
| ... | ... | @@ -662,10 +662,11 @@ tcExpr expr@(RecordUpd { rupd_expr = record_expr |
| 662 | 662 | res_ty
|
| 663 | 663 | = assert (notNull rbnds) $
|
| 664 | 664 | do { -- Expand the record update. See Note [Record Updates].
|
| 665 | + |
|
| 665 | 666 | ; (ds_expr, ds_res_ty, err_msg)
|
| 666 | 667 | <- expandRecordUpd record_expr possible_parents rbnds res_ty
|
| 667 | 668 | ; addErrCtxt err_msg $
|
| 668 | - setInGeneratedCode (OrigExpr expr) $
|
|
| 669 | + ; setInGeneratedCode (OrigExpr expr) $
|
|
| 669 | 670 | do { -- Typecheck the expanded expression.
|
| 670 | 671 | expr' <- tcExpr ds_expr (Check ds_res_ty)
|
| 671 | 672 | -- NB: it's important to use ds_res_ty and not res_ty here.
|
| ... | ... | @@ -217,7 +217,7 @@ type family XPass (p :: TcPass) where |
| 217 | 217 | |
| 218 | 218 | mkEValArg :: SrcSpan -> LHsExpr GhcRn -> HsExprArg 'TcpRn
|
| 219 | 219 | mkEValArg src_loc e = EValArg { ea_arg = e, ea_loc_span = src_loc
|
| 220 | - , ea_arg_ty = noExtField }
|
|
| 220 | + , ea_arg_ty = noExtField }
|
|
| 221 | 221 | |
| 222 | 222 | mkETypeArg :: SrcSpan -> LHsWcType GhcRn -> HsExprArg 'TcpRn
|
| 223 | 223 | mkETypeArg src_loc hs_ty =
|
| ... | ... | @@ -244,18 +244,18 @@ splitHsApps e = go e noSrcSpan [] |
| 244 | 244 | go :: HsExpr GhcRn -> SrcSpan -> [HsExprArg 'TcpRn]
|
| 245 | 245 | -> TcM ((HsExpr GhcRn, SrcSpan), [HsExprArg 'TcpRn])
|
| 246 | 246 | -- Modify the SrcSpan as we walk inwards, so it describes the next argument
|
| 247 | - go (HsPar _ (L l fun)) sloc args = go fun (locA l) (EWrap (EPar sloc) : args)
|
|
| 248 | - go (HsPragE _ p (L l fun)) sloc args = go fun (locA l) (EPrag sloc p : args)
|
|
| 249 | - go (HsAppType _ (L l fun) ty) sloc args = go fun (locA l) (mkETypeArg sloc ty : args)
|
|
| 250 | - go (HsApp _ (L l fun) arg) sloc args = go fun (locA l) (mkEValArg sloc arg : args)
|
|
| 247 | + go (HsPar _ (L l fun)) lspan args = go fun (locA l) (EWrap (EPar lspan) : args)
|
|
| 248 | + go (HsPragE _ p (L l fun)) lspan args = go fun (locA l) (EPrag lspan p : args)
|
|
| 249 | + go (HsAppType _ (L l fun) ty) lspan args = go fun (locA l) (mkETypeArg lspan ty : args)
|
|
| 250 | + go (HsApp _ (L l fun) arg) lspan args = go fun (locA l) (mkEValArg lspan arg : args)
|
|
| 251 | 251 | |
| 252 | 252 | -- See Note [Looking through Template Haskell splices in splitHsApps]
|
| 253 | 253 | go e@(HsUntypedSplice splice_res splice) _ args
|
| 254 | 254 | = do { fun <- getUntypedSpliceBody splice_res
|
| 255 | - ; go fun sloc' (EWrap (EExpand e) : args) }
|
|
| 255 | + ; go fun lspan' (EWrap (EExpand e) : args) }
|
|
| 256 | 256 | where
|
| 257 | - sloc' :: SrcSpan
|
|
| 258 | - sloc' = case splice of
|
|
| 257 | + lspan' :: SrcSpan
|
|
| 258 | + lspan' = case splice of
|
|
| 259 | 259 | HsUntypedSpliceExpr _ (L l _) -> locA l -- l :: SrcAnn AnnListItem
|
| 260 | 260 | HsQuasiQuote _ _ (L l _) -> locA l -- l :: SrcAnn NoEpAnns
|
| 261 | 261 | (XUntypedSplice (HsImplicitLiftSplice _ _ _ (L l _))) -> locA l
|
| ... | ... | @@ -269,11 +269,11 @@ splitHsApps e = go e noSrcSpan [] |
| 269 | 269 | -- and its hard to say exactly what that is
|
| 270 | 270 | : EWrap (EExpand e)
|
| 271 | 271 | : args )
|
| 272 | - go (XExpr (PopErrCtxt fun)) sloc args = go fun sloc args
|
|
| 272 | + go (XExpr (PopErrCtxt fun)) lspan args = go fun lspan args
|
|
| 273 | 273 | -- look through PopErrCtxt (cf. T17594f) we do not want to lose the opportunity of calling tcEValArgQL
|
| 274 | 274 | -- unlike HsPar, it is okay to forget about the PopErrCtxts as it does not persist over in GhcTc land
|
| 275 | 275 | |
| 276 | - go e sloc args = pure ((e, sloc), args)
|
|
| 276 | + go e lspan args = pure ((e, lspan), args)
|
|
| 277 | 277 | |
| 278 | 278 | |
| 279 | 279 | -- | Rebuild an application: takes a type-checked application head
|
| ... | ... | @@ -1109,4 +1109,6 @@ addExprCtxt e thing_inside |
| 1109 | 1109 | -- f x = _
|
| 1110 | 1110 | -- when we don't want to say "In the expression: _",
|
| 1111 | 1111 | -- because it is mentioned in the error message itself
|
| 1112 | + XExpr{} -> thing_inside -- the err ctxt management done is done by setInGeneratedCode
|
|
| 1113 | + HsPar{} -> thing_inside -- the err ctxt management done is done by setInGeneratedCode
|
|
| 1112 | 1114 | _ -> addErrCtxt (ExprCtxt e) thing_inside -- no op in generated code |
| ... | ... | @@ -26,6 +26,7 @@ module GHC.Tc.Types.LclEnv ( |
| 26 | 26 | , setLclCtxtSrcCodeOrigin
|
| 27 | 27 | , lclEnvInGeneratedCode
|
| 28 | 28 | , setLclCtxtInGenCode
|
| 29 | + , setLclCtxtInUserCode
|
|
| 29 | 30 | |
| 30 | 31 | , addLclEnvErrCtxt
|
| 31 | 32 | |
| ... | ... | @@ -210,6 +211,9 @@ setLclEnvSrcCodeOrigin o = modifyLclCtxt (setLclCtxtSrcCodeOrigin o) |
| 210 | 211 | setLclCtxtInGenCode :: TcLclCtxt -> TcLclCtxt
|
| 211 | 212 | setLclCtxtInGenCode lclCtxt = lclCtxt { tcl_in_gen_code = True }
|
| 212 | 213 | |
| 214 | +setLclCtxtInUserCode :: TcLclCtxt -> TcLclCtxt
|
|
| 215 | +setLclCtxtInUserCode lclCtxt = lclCtxt { tcl_in_gen_code = False }
|
|
| 216 | + |
|
| 213 | 217 | -- See Note [ErrCtxt Stack Manipulation]
|
| 214 | 218 | setLclCtxtSrcCodeOrigin :: SrcCodeOrigin -> TcLclCtxt -> TcLclCtxt
|
| 215 | 219 | setLclCtxtSrcCodeOrigin o lclCtxt
|
| ... | ... | @@ -60,7 +60,7 @@ module GHC.Tc.Utils.Monad( |
| 60 | 60 | -- * Error management
|
| 61 | 61 | getSrcCodeOrigin,
|
| 62 | 62 | getSrcSpanM, setSrcSpan, setSrcSpanA, addLocM,
|
| 63 | - inGeneratedCode, setInGeneratedCode,
|
|
| 63 | + inGeneratedCode, setInGeneratedCode, setInUserCode,
|
|
| 64 | 64 | wrapLocM, wrapLocFstM, wrapLocFstMA, wrapLocSndM, wrapLocSndMA, wrapLocM_,
|
| 65 | 65 | wrapLocMA_,wrapLocMA,
|
| 66 | 66 | getErrsVar, setErrsVar,
|
| ... | ... | @@ -991,7 +991,12 @@ setSrcSpan (UnhelpfulSpan _) thing_inside |
| 991 | 991 | = updLclCtxt setLclCtxtInGenCode thing_inside
|
| 992 | 992 | |
| 993 | 993 | getSrcCodeOrigin :: TcRn (Maybe SrcCodeOrigin)
|
| 994 | -getSrcCodeOrigin = getLclEnvSrcCodeOrigin <$> getLclEnv
|
|
| 994 | +getSrcCodeOrigin =
|
|
| 995 | + do inGenCode <- inGeneratedCode
|
|
| 996 | + if inGenCode
|
|
| 997 | + then getLclEnvSrcCodeOrigin <$> getLclEnv
|
|
| 998 | + else return Nothing
|
|
| 999 | + |
|
| 995 | 1000 | |
| 996 | 1001 | -- | Mark the inner computation as being done inside generated code.
|
| 997 | 1002 | --
|
| ... | ... | @@ -1002,6 +1007,9 @@ setInGeneratedCode sco thing_inside = |
| 1002 | 1007 | updLclCtxt setLclCtxtInGenCode $
|
| 1003 | 1008 | updLclCtxt (setLclCtxtSrcCodeOrigin sco) thing_inside
|
| 1004 | 1009 | |
| 1010 | +setInUserCode :: TcRn a -> TcRn a
|
|
| 1011 | +setInUserCode = updLclCtxt setLclCtxtInUserCode
|
|
| 1012 | + |
|
| 1005 | 1013 | setSrcSpanA :: EpAnn ann -> TcRn a -> TcRn a
|
| 1006 | 1014 | setSrcSpanA l = setSrcSpan (locA l)
|
| 1007 | 1015 |
| ... | ... | @@ -22,7 +22,7 @@ DoExpansion1.hs:15:54: warning: [GHC-39999] [-Wdeferred-type-errors (in -Wdefaul |
| 22 | 22 | DoExpansion1.hs:19:21: warning: [GHC-39999] [-Wdeferred-type-errors (in -Wdefault)]
|
| 23 | 23 | • No instance for ‘Num String’ arising from the literal ‘1’
|
| 24 | 24 | • In the first argument of ‘putStrLn’, namely ‘1’
|
| 25 | - In the expression: putStrLn 1
|
|
| 25 | + In a stmt of a 'do' block: putStrLn 1
|
|
| 26 | 26 | In the expression:
|
| 27 | 27 | do putStrLn 1
|
| 28 | 28 | putStrLn "r2"
|
| ... | ... | @@ -31,7 +31,7 @@ DoExpansion1.hs:19:21: warning: [GHC-39999] [-Wdeferred-type-errors (in -Wdefaul |
| 31 | 31 | DoExpansion1.hs:25:21: warning: [GHC-39999] [-Wdeferred-type-errors (in -Wdefault)]
|
| 32 | 32 | • No instance for ‘Num String’ arising from the literal ‘2’
|
| 33 | 33 | • In the first argument of ‘putStrLn’, namely ‘2’
|
| 34 | - In the expression: putStrLn 2
|
|
| 34 | + In a stmt of a 'do' block: putStrLn 2
|
|
| 35 | 35 | In the expression:
|
| 36 | 36 | do putStrLn "r1"
|
| 37 | 37 | putStrLn 2
|
| ... | ... | @@ -57,9 +57,7 @@ DoExpansion2.hs:34:22: warning: [GHC-83865] [-Wdeferred-type-errors (in -Wdefaul |
| 57 | 57 | • The function ‘getVal’ is applied to two visible arguments,
|
| 58 | 58 | but its type ‘Int -> IO String’ has only one
|
| 59 | 59 | In the expression: getVal 3 4
|
| 60 | - In the expression:
|
|
| 61 | - do Just x <- getVal 3 4
|
|
| 62 | - return x
|
|
| 60 | + In a stmt of a 'do' block: Just x <- getVal 3 4
|
|
| 63 | 61 | |
| 64 | 62 | DoExpansion2.hs:39:19: warning: [GHC-83865] [-Wdeferred-type-errors (in -Wdefault)]
|
| 65 | 63 | • Couldn't match type ‘[Char]’ with ‘Int’
|