Apoorv Ingle pushed to branch wip/ani/kill-popErrCtxt at Glasgow Haskell Compiler / GHC
Commits:
-
e95889e1
by Apoorv Ingle at 2025-09-14T22:26:20-05:00
5 changed files:
- compiler/GHC/Tc/Gen/Do.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Types/ErrCtxt.hs
- compiler/GHC/Tc/Types/LclEnv.hs
- compiler/GHC/Tc/Utils/Monad.hs
Changes:
| ... | ... | @@ -485,11 +485,11 @@ It stores the original statement (with location) and the expanded expression |
| 485 | 485 | |
| 486 | 486 | |
| 487 | 487 | -- | Wrap a located expression with a `PopErrCtxt`
|
| 488 | -mkPopErrCtxtExpr :: HsExpr GhcRn -> HsExpr GhcRn
|
|
| 489 | -mkPopErrCtxtExpr a = XExpr (PopErrCtxt a)
|
|
| 488 | +-- mkPopErrCtxtExpr :: HsExpr GhcRn -> HsExpr GhcRn
|
|
| 489 | +-- mkPopErrCtxtExpr a = XExpr (PopErrCtxt a)
|
|
| 490 | 490 | |
| 491 | 491 | genPopErrCtxtExpr :: LHsExpr GhcRn -> LHsExpr GhcRn
|
| 492 | -genPopErrCtxtExpr (L loc a) = L loc (mkPopErrCtxtExpr a)
|
|
| 492 | +genPopErrCtxtExpr x = x
|
|
| 493 | 493 | |
| 494 | 494 | mkExpandedPatRn :: Pat GhcRn -> HsExpr GhcRn -> HsExpr GhcRn
|
| 495 | 495 | mkExpandedPatRn pat e = XExpr (ExpandedThingRn (OrigPat pat) e) |
| ... | ... | @@ -1109,5 +1109,5 @@ 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 (PopErrCtxt _) -> thing_inside -- popErrCtxt shouldn't push ctxt. see typechecking let stmts
|
|
| 1112 | + XExpr (ExpandedThingRn o _) -> setInGeneratedCode o thing_inside
|
|
| 1113 | 1113 | _ -> addErrCtxt (ExprCtxt e) thing_inside -- no op in generated code |
| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | {-# LANGUAGE UndecidableInstances #-}
|
| 5 | 5 | |
| 6 | 6 | module GHC.Tc.Types.ErrCtxt
|
| 7 | - ( ErrCtxt, ErrCtxtMsg(..)
|
|
| 7 | + ( ErrCtxt (..), ErrCtxtMsg(..), srcCodeOriginErrCtxMsg
|
|
| 8 | 8 | , UserSigType(..), FunAppCtxtFunArg(..)
|
| 9 | 9 | , TyConInstFlavour(..)
|
| 10 | 10 | )
|
| ... | ... | @@ -23,7 +23,7 @@ import GHC.Tc.Zonk.Monad ( ZonkM ) |
| 23 | 23 | |
| 24 | 24 | import GHC.Types.Basic ( TyConFlavour )
|
| 25 | 25 | import GHC.Types.Name ( Name )
|
| 26 | -import GHC.Types.SrcLoc ( SrcSpan )
|
|
| 26 | +import GHC.Types.SrcLoc ( SrcSpan, unLoc )
|
|
| 27 | 27 | import GHC.Types.Var ( Id, TyCoVar )
|
| 28 | 28 | import GHC.Types.Var.Env ( TidyEnv )
|
| 29 | 29 | |
| ... | ... | @@ -50,13 +50,18 @@ import qualified Data.List.NonEmpty as NE |
| 50 | 50 | |
| 51 | 51 | -- | Additional context to include in an error message, e.g.
|
| 52 | 52 | -- "In the type signature ...", "In the ambiguity check for ...", etc.
|
| 53 | -type ErrCtxt = (Bool, TidyEnv -> ZonkM (TidyEnv, ErrCtxtMsg))
|
|
| 53 | +data ErrCtxt = UserCodeCtxt (Bool, TidyEnv -> ZonkM (TidyEnv, ErrCtxtMsg))
|
|
| 54 | 54 | -- Monadic so that we have a chance
|
| 55 | 55 | -- to deal with bound type variables just before error
|
| 56 | 56 | -- message construction
|
| 57 | 57 | |
| 58 | 58 | -- Bool: True <=> this is a landmark context; do not
|
| 59 | 59 | -- discard it when trimming for display
|
| 60 | + | GeneratedCodeCtxt SrcCodeOrigin
|
|
| 61 | + -- The payload is a SrcCodeOrigin because it is used to generate
|
|
| 62 | + -- 1. The CtOrigin for CtLoc, and
|
|
| 63 | + -- 2. ErrCtxtMsg in error messages
|
|
| 64 | + |
|
| 60 | 65 | |
| 61 | 66 | --------------------------------------------------------------------------------
|
| 62 | 67 | -- Error message contexts
|
| ... | ... | @@ -221,3 +226,9 @@ data ErrCtxtMsg |
| 221 | 226 | | MergeSignaturesCtxt !UnitState !ModuleName ![InstantiatedModule]
|
| 222 | 227 | -- | While checking that a module implements a Backpack signature.
|
| 223 | 228 | | CheckImplementsCtxt !UnitState !Module !InstantiatedModule
|
| 229 | + |
|
| 230 | + |
|
| 231 | +srcCodeOriginErrCtxMsg :: SrcCodeOrigin -> ErrCtxtMsg
|
|
| 232 | +srcCodeOriginErrCtxMsg (OrigExpr e) = ExprCtxt e
|
|
| 233 | +srcCodeOriginErrCtxMsg (OrigStmt s f) = StmtErrCtxt (HsDoStmt f) (unLoc s)
|
|
| 234 | +srcCodeOriginErrCtxMsg (OrigPat p) = PatCtxt p |
| ... | ... | @@ -28,7 +28,7 @@ module GHC.Tc.Types.LclEnv ( |
| 28 | 28 | |
| 29 | 29 | , addLclEnvErrCtxt
|
| 30 | 30 | |
| 31 | - , ErrCtxtStack (..)
|
|
| 31 | + , ErrCtxtStack
|
|
| 32 | 32 | , ArrowCtxt(..)
|
| 33 | 33 | , ThBindEnv
|
| 34 | 34 | , TcTypeEnv
|
| ... | ... | @@ -109,36 +109,24 @@ This data structure keeps track of two things: |
| 109 | 109 | |
| 110 | 110 | |
| 111 | 111 | -- See Note [Error Context Stack]
|
| 112 | -data ErrCtxtStack
|
|
| 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
|
|
| 112 | +type ErrCtxtStack = [ErrCtxt]
|
|
| 116 | 113 | |
| 117 | 114 | -- | Are we in a generated context?
|
| 118 | 115 | isGeneratedCodeCtxt :: ErrCtxtStack -> Bool
|
| 119 | -isGeneratedCodeCtxt UserCodeCtxt{} = False
|
|
| 120 | -isGeneratedCodeCtxt _ = True
|
|
| 116 | +isGeneratedCodeCtxt (GeneratedCodeCtxt{} : _) = True
|
|
| 117 | +isGeneratedCodeCtxt _ = False
|
|
| 121 | 118 | |
| 122 | 119 | -- | Get the original source code
|
| 123 | 120 | get_src_code_origin :: ErrCtxtStack -> Maybe SrcCodeOrigin
|
| 124 | -get_src_code_origin (UserCodeCtxt{}) = Nothing
|
|
| 125 | - -- we are in user code, so blame the expression in hand
|
|
| 126 | -get_src_code_origin es = Just $ src_code_origin es
|
|
| 121 | +get_src_code_origin (GeneratedCodeCtxt es : _) = Just es
|
|
| 127 | 122 | -- we are in generated code, so extract the original expression
|
| 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
|
|
| 133 | -modify_err_ctxt_stack :: ([ErrCtxt] -> [ErrCtxt]) -> ErrCtxtStack -> ErrCtxtStack
|
|
| 134 | -modify_err_ctxt_stack f (UserCodeCtxt e) = UserCodeCtxt (f e)
|
|
| 135 | -modify_err_ctxt_stack _ c = c -- any updates on the err context in a generated context should be ignored
|
|
| 136 | - |
|
| 123 | +get_src_code_origin _ = Nothing
|
|
| 124 | + -- we are in user code, so blame the expression in hand
|
|
| 137 | 125 | |
| 138 | 126 | data TcLclCtxt
|
| 139 | 127 | = TcLclCtxt {
|
| 140 | 128 | tcl_loc :: RealSrcSpan, -- Source span
|
| 141 | - tcl_ctxt :: ErrCtxtStack, -- See Note [Error Context Stack]
|
|
| 129 | + tcl_err_ctxt :: ErrCtxtStack, -- See Note [Error Context Stack]
|
|
| 142 | 130 | tcl_tclvl :: TcLevel,
|
| 143 | 131 | tcl_bndrs :: TcBinderStack, -- Used for reporting relevant bindings,
|
| 144 | 132 | -- and for tidying type
|
| ... | ... | @@ -203,25 +191,30 @@ getLclEnvLoc :: TcLclEnv -> RealSrcSpan |
| 203 | 191 | getLclEnvLoc = tcl_loc . tcl_lcl_ctxt
|
| 204 | 192 | |
| 205 | 193 | getLclEnvErrCtxt :: TcLclEnv -> [ErrCtxt]
|
| 206 | -getLclEnvErrCtxt = lcl_err_ctxt . tcl_ctxt . tcl_lcl_ctxt
|
|
| 194 | +getLclEnvErrCtxt = tcl_err_ctxt . tcl_lcl_ctxt
|
|
| 207 | 195 | |
| 208 | 196 | setLclEnvErrCtxt :: [ErrCtxt] -> TcLclEnv -> TcLclEnv
|
| 209 | -setLclEnvErrCtxt ctxt = modifyLclCtxt (\env -> env { tcl_ctxt = modify_err_ctxt_stack (\ _ -> ctxt) (tcl_ctxt env) })
|
|
| 197 | +setLclEnvErrCtxt ctxt = modifyLclCtxt (\env -> env { tcl_err_ctxt = ctxt })
|
|
| 210 | 198 | |
| 211 | 199 | addLclEnvErrCtxt :: ErrCtxt -> TcLclEnv -> TcLclEnv
|
| 212 | -addLclEnvErrCtxt ec = modifyLclCtxt (\env -> env { tcl_ctxt = modify_err_ctxt_stack (\ctxt -> ec : ctxt) (tcl_ctxt env) })
|
|
| 200 | +addLclEnvErrCtxt (GeneratedCodeCtxt co) = setLclEnvSrcCodeOrigin co
|
|
| 201 | +addLclEnvErrCtxt ec = modifyLclCtxt (\env -> env { tcl_err_ctxt = ec : (tcl_err_ctxt env) })
|
|
| 213 | 202 | |
| 214 | 203 | getLclEnvSrcCodeOrigin :: TcLclEnv -> Maybe SrcCodeOrigin
|
| 215 | -getLclEnvSrcCodeOrigin = get_src_code_origin . tcl_ctxt . tcl_lcl_ctxt
|
|
| 204 | +getLclEnvSrcCodeOrigin = get_src_code_origin . tcl_err_ctxt . tcl_lcl_ctxt
|
|
| 216 | 205 | |
| 217 | 206 | setLclEnvSrcCodeOrigin :: SrcCodeOrigin -> TcLclEnv -> TcLclEnv
|
| 218 | 207 | setLclEnvSrcCodeOrigin o = modifyLclCtxt (setLclCtxtSrcCodeOrigin o)
|
| 219 | 208 | |
| 220 | 209 | setLclCtxtSrcCodeOrigin :: SrcCodeOrigin -> TcLclCtxt -> TcLclCtxt
|
| 221 | -setLclCtxtSrcCodeOrigin o ctxt = ctxt { tcl_ctxt = GeneratedCodeCtxt o (lcl_err_ctxt $ tcl_ctxt ctxt) }
|
|
| 210 | +setLclCtxtSrcCodeOrigin o lclCtxt
|
|
| 211 | + | (GeneratedCodeCtxt _ : ec) <- tcl_err_ctxt lclCtxt
|
|
| 212 | + = lclCtxt { tcl_err_ctxt = GeneratedCodeCtxt o : ec }
|
|
| 213 | + | otherwise
|
|
| 214 | + = lclCtxt { tcl_err_ctxt = GeneratedCodeCtxt o : tcl_err_ctxt lclCtxt }
|
|
| 222 | 215 | |
| 223 | 216 | lclCtxtInGeneratedCode :: TcLclCtxt -> Bool
|
| 224 | -lclCtxtInGeneratedCode = isGeneratedCodeCtxt . tcl_ctxt
|
|
| 217 | +lclCtxtInGeneratedCode = isGeneratedCodeCtxt . tcl_err_ctxt
|
|
| 225 | 218 | |
| 226 | 219 | lclEnvInGeneratedCode :: TcLclEnv -> Bool
|
| 227 | 220 | lclEnvInGeneratedCode = lclCtxtInGeneratedCode . tcl_lcl_ctxt
|
| ... | ... | @@ -168,6 +168,7 @@ import GHC.Tc.Types -- Re-export all |
| 168 | 168 | import GHC.Tc.Types.Constraint
|
| 169 | 169 | import GHC.Tc.Types.CtLoc
|
| 170 | 170 | import GHC.Tc.Types.Evidence
|
| 171 | +import GHC.Tc.Types.ErrCtxt
|
|
| 171 | 172 | import GHC.Tc.Types.LclEnv
|
| 172 | 173 | import GHC.Tc.Types.Origin
|
| 173 | 174 | import GHC.Tc.Types.TcRef
|
| ... | ... | @@ -401,7 +402,7 @@ initTcWithGbl hsc_env gbl_env loc do_this |
| 401 | 402 | tcl_lcl_ctxt = TcLclCtxt {
|
| 402 | 403 | tcl_loc = loc,
|
| 403 | 404 | -- tcl_loc should be over-ridden very soon!
|
| 404 | - tcl_ctxt = UserCodeCtxt [],
|
|
| 405 | + tcl_err_ctxt = [],
|
|
| 405 | 406 | tcl_rdr = emptyLocalRdrEnv,
|
| 406 | 407 | tcl_th_ctxt = topLevel,
|
| 407 | 408 | tcl_th_bndrs = emptyNameEnv,
|
| ... | ... | @@ -983,9 +984,7 @@ inGeneratedCode = lclEnvInGeneratedCode <$> getLclEnv |
| 983 | 984 | setSrcSpan :: SrcSpan -> TcRn a -> TcRn a
|
| 984 | 985 | -- See Note [Error contexts in generated code]
|
| 985 | 986 | setSrcSpan (RealSrcSpan loc _) thing_inside
|
| 986 | - = updLclCtxt (\env -> env { tcl_loc = loc
|
|
| 987 | - , tcl_ctxt = UserCodeCtxt (lcl_err_ctxt $ tcl_ctxt env)})
|
|
| 988 | - thing_inside
|
|
| 987 | + = updLclCtxt (\env -> env { tcl_loc = loc }) thing_inside
|
|
| 989 | 988 | |
| 990 | 989 | setSrcSpan (UnhelpfulSpan _) thing_inside
|
| 991 | 990 | = thing_inside
|
| ... | ... | @@ -1252,7 +1251,7 @@ addErrCtxt msg = addErrCtxtM (\env -> return (env, msg)) |
| 1252 | 1251 | -- See Note [Rebindable syntax and XXExprGhcRn] in GHC.Hs.Expr
|
| 1253 | 1252 | addErrCtxtM :: (TidyEnv -> ZonkM (TidyEnv, ErrCtxtMsg)) -> TcM a -> TcM a
|
| 1254 | 1253 | {-# INLINE addErrCtxtM #-} -- Note [Inlining addErrCtxt]
|
| 1255 | -addErrCtxtM ctxt = pushCtxt (False, ctxt)
|
|
| 1254 | +addErrCtxtM ctxt = pushCtxt (UserCodeCtxt (False, ctxt))
|
|
| 1256 | 1255 | |
| 1257 | 1256 | -- | Add a fixed landmark message to the error context. A landmark
|
| 1258 | 1257 | -- message is always sure to be reported, even if there is a lot of
|
| ... | ... | @@ -1266,7 +1265,7 @@ addLandmarkErrCtxt msg = addLandmarkErrCtxtM (\env -> return (env, msg)) |
| 1266 | 1265 | -- and tidying.
|
| 1267 | 1266 | addLandmarkErrCtxtM :: (TidyEnv -> ZonkM (TidyEnv, ErrCtxtMsg)) -> TcM a -> TcM a
|
| 1268 | 1267 | {-# INLINE addLandmarkErrCtxtM #-} -- Note [Inlining addErrCtxt]
|
| 1269 | -addLandmarkErrCtxtM ctxt = pushCtxt (True, ctxt)
|
|
| 1268 | +addLandmarkErrCtxtM ctxt = pushCtxt (UserCodeCtxt (True, ctxt))
|
|
| 1270 | 1269 | |
| 1271 | 1270 | -- | NB. no op in generated code
|
| 1272 | 1271 | -- See Note [Rebindable syntax and XXExprGhcRn] in GHC.Hs.Expr
|
| ... | ... | @@ -1277,9 +1276,7 @@ pushCtxt ctxt = updLclEnv (updCtxt ctxt) |
| 1277 | 1276 | updCtxt :: ErrCtxt -> TcLclEnv -> TcLclEnv
|
| 1278 | 1277 | -- Do not update the context if we are in generated code
|
| 1279 | 1278 | -- See Note [Rebindable syntax and XXExprGhcRn] in GHC.Hs.Expr
|
| 1280 | -updCtxt ctxt env
|
|
| 1281 | - | lclEnvInGeneratedCode env = env
|
|
| 1282 | - | otherwise = addLclEnvErrCtxt ctxt env
|
|
| 1279 | +updCtxt ctxt env = addLclEnvErrCtxt ctxt env
|
|
| 1283 | 1280 | |
| 1284 | 1281 | popErrCtxt :: TcM a -> TcM a
|
| 1285 | 1282 | popErrCtxt thing_inside = updLclEnv (\env -> setLclEnvErrCtxt (pop $ getLclEnvErrCtxt env) env) $
|
| ... | ... | @@ -1740,7 +1737,7 @@ mkErrCtxt env ctxts |
| 1740 | 1737 | where
|
| 1741 | 1738 | go :: Bool -> Int -> TidyEnv -> [ErrCtxt] -> TcM [ErrCtxtMsg]
|
| 1742 | 1739 | go _ _ _ [] = return []
|
| 1743 | - go dbg n env ((is_landmark, ctxt) : ctxts)
|
|
| 1740 | + go dbg n env (UserCodeCtxt (is_landmark, ctxt) : ctxts)
|
|
| 1744 | 1741 | | is_landmark || n < mAX_CONTEXTS -- Too verbose || dbg
|
| 1745 | 1742 | = do { (env', msg) <- liftZonkM $ ctxt env
|
| 1746 | 1743 | ; let n' = if is_landmark then n else n+1
|
| ... | ... | @@ -1748,6 +1745,13 @@ mkErrCtxt env ctxts |
| 1748 | 1745 | ; return (msg : rest) }
|
| 1749 | 1746 | | otherwise
|
| 1750 | 1747 | = go dbg n env ctxts
|
| 1748 | + go dbg n env (GeneratedCodeCtxt co : ctxts)
|
|
| 1749 | + | n < mAX_CONTEXTS -- Too verbose || dbg
|
|
| 1750 | + = do { let msg = srcCodeOriginErrCtxMsg co
|
|
| 1751 | + ; rest <- go dbg (n+1) env ctxts
|
|
| 1752 | + ; return (msg : rest) }
|
|
| 1753 | + | otherwise
|
|
| 1754 | + = go dbg n env ctxts
|
|
| 1751 | 1755 | |
| 1752 | 1756 | |
| 1753 | 1757 | mAX_CONTEXTS :: Int -- No more than this number of non-landmark contexts
|