Simon Peyton Jones pushed to branch wip/ani/tc-expand at Glasgow Haskell Compiler / GHC
Commits:
-
87447590
by Simon Peyton Jones at 2026-03-26T13:04:10+00:00
7 changed files:
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/Match.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Tc/Utils/Unify.hs
Changes:
| ... | ... | @@ -1915,8 +1915,12 @@ quickLookArg1 pos app_lspan (fun, fun_lspan) larg@(L _ arg) sc_arg_ty@(Scaled _ |
| 1915 | 1915 | -- generated by calls in arg
|
| 1916 | 1916 | do { ((rn_fun_arg, fun_lspan_arg), rn_args) <- splitHsApps arg
|
| 1917 | 1917 | |
| 1918 | + ; if tooComplicatedForQuickLook rn_fun_arg
|
|
| 1919 | + then skipQuickLook app_lspan larg sc_arg_ty
|
|
| 1920 | + else
|
|
| 1921 | + |
|
| 1918 | 1922 | -- Step 1: get the type of the head of the argument
|
| 1919 | - ; (fun_ue, (tc_fun_arg_head, fun_sigma_arg_head)) <- tcCollectingUsage $ tcInferExprSigma rn_fun_arg
|
|
| 1923 | + do { (fun_ue, (tc_fun_arg_head, fun_sigma_arg_head)) <- tcCollectingUsage $ tcInferExprSigma rn_fun_arg
|
|
| 1920 | 1924 | -- tcCollectingUsage: the use of an Id at the head generates usage-info
|
| 1921 | 1925 | -- See the call to `tcEmitBindingUsage` in `check_local_id`. So we must
|
| 1922 | 1926 | -- capture and save it in the `EValArgQL`. See (QLA6) in
|
| ... | ... | @@ -1978,7 +1982,7 @@ quickLookArg1 pos app_lspan (fun, fun_lspan) larg@(L _ arg) sc_arg_ty@(Scaled _ |
| 1978 | 1982 | , eaql_wanted = wanted
|
| 1979 | 1983 | , eaql_encl = arg_influences_enclosing_call
|
| 1980 | 1984 | , eaql_res_rho = app_res_rho })
|
| 1981 | - }
|
|
| 1985 | + }}
|
|
| 1982 | 1986 | |
| 1983 | 1987 | |
| 1984 | 1988 | mk_origin :: SrcSpan -- SrcSpan of the function
|
| ... | ... | @@ -1999,6 +2003,16 @@ mk_origin fun_lspan rn_fun |
| 1999 | 2003 | }
|
| 2000 | 2004 | |
| 2001 | 2005 | |
| 2006 | +tooComplicatedForQuickLook :: HsExpr GhcRn -> Bool
|
|
| 2007 | +tooComplicatedForQuickLook expr
|
|
| 2008 | + = case expr of
|
|
| 2009 | + HsVar {} -> False
|
|
| 2010 | + ExprWithTySig {} -> False
|
|
| 2011 | + XExpr (HsRecSelRn {}) -> False
|
|
| 2012 | + HsOverLit {} -> False
|
|
| 2013 | + _ -> True -- Too complicated
|
|
| 2014 | + |
|
| 2015 | + |
|
| 2002 | 2016 | {- *********************************************************************
|
| 2003 | 2017 | * *
|
| 2004 | 2018 | Folding over instantiation variables
|
| ... | ... | @@ -323,6 +323,7 @@ tcExpr :: HsExpr GhcRn |
| 323 | 323 | -- Se Note [Typechecking by expansion: overview]
|
| 324 | 324 | tcExpr e@(HsVar _ v_rn) res_ty
|
| 325 | 325 | = do { (v_tc, sigma_ty) <- tcInferId v_rn
|
| 326 | + ; traceTc "tcExpr:HsVar" (ppr v_tc <+> dcolon <+> ppr sigma_ty $$ ppr res_ty)
|
|
| 326 | 327 | ; tcWrapResult e v_tc sigma_ty res_ty }
|
| 327 | 328 | |
| 328 | 329 | tcExpr e@(ExprWithTySig _ e_rn e_ty) res_ty
|
| ... | ... | @@ -545,8 +546,9 @@ tcExpr (HsCase ctxt scrut matches) res_ty |
| 545 | 546 | |
| 546 | 547 | tcExpr (HsIf x pred b1 b2) res_ty
|
| 547 | 548 | = do { pred' <- tcCheckMonoExpr pred boolTy
|
| 548 | - ; (u1,b1') <- tcCollectingUsage $ tcMonoLExpr b1 res_ty
|
|
| 549 | - ; (u2,b2') <- tcCollectingUsage $ tcMonoLExpr b2 res_ty
|
|
| 549 | + ; let res_ty' = adjustExpTypeForCaseBranches res_ty [b1,b2]
|
|
| 550 | + ; (u1,b1') <- tcCollectingUsage $ tcMonoLExpr b1 res_ty'
|
|
| 551 | + ; (u2,b2') <- tcCollectingUsage $ tcMonoLExpr b2 res_ty'
|
|
| 550 | 552 | ; tcEmitBindingUsage (supUE u1 u2)
|
| 551 | 553 | ; return (HsIf x pred' b1' b2') }
|
| 552 | 554 |
| ... | ... | @@ -232,6 +232,7 @@ splitHsApps e = go e noSrcSpan [] |
| 232 | 232 | go (HsAppType _ (L l fun) ty) lspan args = go fun (locA l) (mkETypeArg lspan ty : args)
|
| 233 | 233 | go (HsApp _ (L l fun) arg) lspan args = go fun (locA l) (mkEValArg lspan arg : args)
|
| 234 | 234 | |
| 235 | +{-
|
|
| 235 | 236 | -- See Note [Looking through Template Haskell splices in splitHsApps]
|
| 236 | 237 | go e@(HsUntypedSplice splice_res splice) _ args
|
| 237 | 238 | = do { fun <- getUntypedSpliceBody splice_res
|
| ... | ... | @@ -242,6 +243,7 @@ splitHsApps e = go e noSrcSpan [] |
| 242 | 243 | HsUntypedSpliceExpr _ (L l _) -> locA l -- l :: SrcAnn AnnListItem
|
| 243 | 244 | HsQuasiQuote _ _ (L l _) -> locA l -- l :: SrcAnn NoEpAnns
|
| 244 | 245 | (XUntypedSplice (HsImplicitLiftSplice _ _ _ (L l _))) -> locA l
|
| 246 | +-}
|
|
| 245 | 247 | |
| 246 | 248 | -- See Note [Desugar OpApp in the typechecker]
|
| 247 | 249 | go e@(OpApp _ arg1 (L l op) arg2) _ args
|
| ... | ... | @@ -342,6 +344,8 @@ where |
| 342 | 344 | |
| 343 | 345 | Note [Looking through ExpandedThingRn]
|
| 344 | 346 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 347 | +**** TODO **** this note is out of date. Fix me.
|
|
| 348 | + |
|
| 345 | 349 | When creating an application chain in splitHsApps, we must deal with
|
| 346 | 350 | ExpandedThingRn f1 (f `HsApp` e1) `HsApp` e2 `HsApp` e3
|
| 347 | 351 |
| ... | ... | @@ -219,10 +219,10 @@ tcMatches :: (AnnoBody body, Outputable (body GhcTc)) |
| 219 | 219 | -> MatchGroup GhcRn (LocatedA (body GhcRn))
|
| 220 | 220 | -> TcM (MatchGroup GhcTc (LocatedA (body GhcTc)))
|
| 221 | 221 | |
| 222 | -tcMatches ctxt tc_body pat_tys rhs_ty (MG { mg_alts = L l matches
|
|
| 222 | +tcMatches ctxt tc_body pat_tys exp_ty (MG { mg_alts = L l matches
|
|
| 223 | 223 | , mg_ext = origin })
|
| 224 | 224 | | null matches -- Deal with case e of {}
|
| 225 | - -- Since there are no branches, no one else will fill in rhs_ty
|
|
| 225 | + -- Since there are no branches, no one else will fill in exp_ty
|
|
| 226 | 226 | -- when in inference mode, so we must do it ourselves,
|
| 227 | 227 | -- here, using expTypeToType
|
| 228 | 228 | = do { tcEmitBindingUsage bottomUE
|
| ... | ... | @@ -233,17 +233,19 @@ tcMatches ctxt tc_body pat_tys rhs_ty (MG { mg_alts = L l matches |
| 233 | 233 | [ExpForAllPatTy tvb] -> failWithTc $ TcRnEmptyCase ctxt (EmptyCaseForall tvb)
|
| 234 | 234 | [] -> panic "tcMatches: no arguments in EmptyCase"
|
| 235 | 235 | _t1:(_t2:_ts) -> panic "tcMatches: multiple arguments in EmptyCase"
|
| 236 | - ; rhs_ty <- expTypeToType rhs_ty
|
|
| 236 | + ; rhs_ty <- expTypeToType exp_ty
|
|
| 237 | 237 | ; return (MG { mg_alts = L l []
|
| 238 | 238 | , mg_ext = MatchGroupTc [pat_ty] rhs_ty origin
|
| 239 | 239 | }) }
|
| 240 | 240 | |
| 241 | 241 | | otherwise
|
| 242 | - = do { umatches <- mapM (tcCollectingUsage . tcMatch tc_body pat_tys rhs_ty) matches
|
|
| 243 | - ; let (usages, matches') = unzip umatches
|
|
| 242 | + = do { let exp_ty' = adjustExpTypeForCaseBranches exp_ty matches
|
|
| 243 | + tc_match match = tcCollectingUsage $
|
|
| 244 | + tcMatch tc_body pat_tys exp_ty' match
|
|
| 245 | + ; (usages, matches') <- mapAndUnzipM tc_match matches
|
|
| 244 | 246 | ; tcEmitBindingUsage $ supUEs usages
|
| 245 | 247 | ; pat_tys <- mapM readScaledExpType (filter_out_forall_pat_tys pat_tys)
|
| 246 | - ; rhs_ty <- readExpType rhs_ty
|
|
| 248 | + ; rhs_ty <- readExpType exp_ty'
|
|
| 247 | 249 | ; traceTc "tcMatches" (ppr matches' $$ ppr pat_tys $$ ppr rhs_ty)
|
| 248 | 250 | ; return (MG { mg_alts = L l matches'
|
| 249 | 251 | , mg_ext = MatchGroupTc pat_tys rhs_ty origin
|
| ... | ... | @@ -63,7 +63,7 @@ module GHC.Tc.Utils.TcMType ( |
| 63 | 63 | mkCheckExpType, newInferExpType, newInferExpTypeFRR,
|
| 64 | 64 | runInfer, runInferRho, runInferSigma, runInferKind, runInferRhoFRR, runInferSigmaFRR,
|
| 65 | 65 | readExpType, readExpType_maybe, readScaledExpType,
|
| 66 | - expTypeToType, scaledExpTypeToType,
|
|
| 66 | + expTypeToType, scaledExpTypeToType, adjustExpTypeForCaseBranches,
|
|
| 67 | 67 | checkingExpType_maybe, checkingExpType,
|
| 68 | 68 | inferResultToType, ensureMonoType, promoteTcType,
|
| 69 | 69 | |
| ... | ... | @@ -499,6 +499,17 @@ inferResultToType (IR { ir_uniq = u, ir_lvl = tc_lvl |
| 499 | 499 | ; let conc_orig = ConcreteFRR $ FixedRuntimeRepOrigin tau frr
|
| 500 | 500 | ; return tau }
|
| 501 | 501 | |
| 502 | +adjustExpTypeForCaseBranches :: ExpRhoType -> [branch] -> ExpRhoType
|
|
| 503 | +-- See Note [fillInferResult: multiple branches]
|
|
| 504 | +adjustExpTypeForCaseBranches exp_ty branches
|
|
| 505 | + = case exp_ty of
|
|
| 506 | + Infer ir | IR { ir_inst = IIF_Sigma } <- ir
|
|
| 507 | + , branches `lengthAtLeast` 2
|
|
| 508 | + -> Infer (ir { ir_inst = IIF_DeepRho })
|
|
| 509 | + | otherwise
|
|
| 510 | + -> exp_ty
|
|
| 511 | + Check {} -> exp_ty
|
|
| 512 | + |
|
| 502 | 513 | {- Note [inferResultToType]
|
| 503 | 514 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 504 | 515 | expTypeToType and inferResultType convert an InferResult to a monotype.
|
| ... | ... | @@ -441,11 +441,12 @@ data InferInstFlag -- Specifies whether the inference should return an uninstan |
| 441 | 441 | |
| 442 | 442 | | IIF_ShallowRho -- Trying to infer a shallow RhoType (no foralls or => at the top)
|
| 443 | 443 | -- Top-instantiate (only, regardless of DeepSubsumption) before filling the hole
|
| 444 | - -- Typically used when inferring the type of an expression
|
|
| 444 | + -- Used only for view patterns; see Note [View patterns and polymorphism]
|
|
| 445 | 445 | |
| 446 | 446 | | IIF_DeepRho -- Trying to infer a possibly-deep RhoType (depending on DeepSubsumption)
|
| 447 | 447 | -- If DeepSubsumption is off, same as IIF_ShallowRho
|
| 448 | 448 | -- If DeepSubsumption is on, instantiate deeply before filling the hole
|
| 449 | + -- Typically used when inferring the type of an expression
|
|
| 449 | 450 | |
| 450 | 451 | type ExpSigmaType = ExpType
|
| 451 | 452 | type ExpRhoType = ExpType
|
| ... | ... | @@ -1197,13 +1197,15 @@ There are two things to worry about: |
| 1197 | 1197 | 1. What if it is under a GADT or existential pattern match?
|
| 1198 | 1198 | - GADTs: a unification variable (and Infer's hole is similar) is untouchable
|
| 1199 | 1199 | - Existentials: be careful about skolem-escape
|
| 1200 | + See Note [fillInferResult: GADTs and existentials]
|
|
| 1200 | 1201 | |
| 1201 | 1202 | 2. What if it is filled in more than once? E.g. multiple branches of a case
|
| 1202 | 1203 | case e of
|
| 1203 | 1204 | T1 -> e1
|
| 1204 | 1205 | T2 -> e2
|
| 1206 | + See Note [fillInferResult: multiple branches]
|
|
| 1205 | 1207 | |
| 1206 | -Our typing rules are:
|
|
| 1208 | +In general our typing rules are:
|
|
| 1207 | 1209 | |
| 1208 | 1210 | * The RHS of a existential or GADT alternative must always be a
|
| 1209 | 1211 | monotype, regardless of the number of alternatives.
|
| ... | ... | @@ -1218,17 +1220,13 @@ Our typing rules are: |
| 1218 | 1220 | We use choice (2) in that Section.
|
| 1219 | 1221 | (GHC 8.10 and earlier used choice (1).)
|
| 1220 | 1222 | |
| 1221 | - But note that
|
|
| 1222 | - case e of
|
|
| 1223 | - True -> hr
|
|
| 1224 | - False -> \x -> hr x
|
|
| 1225 | - will fail, because we still /infer/ both branches, so the \x will get
|
|
| 1226 | - a (monotype) unification variable, which will fail to unify with
|
|
| 1227 | - (forall a. a->a)
|
|
| 1223 | +Note [fillInferResult: GADTs and existentials]
|
|
| 1224 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1225 | +We can detect the GADT/existential situation, case (1) of Note [fillInferResult],
|
|
| 1226 | +by seeing that the current TcLevel is greater than that stored in ir_lvl of the
|
|
| 1227 | +Infer ExpType. We bump the level whenever we go past a GADT/existential match.
|
|
| 1228 | 1228 | |
| 1229 | -For (1) we can detect the GADT/existential situation by seeing that
|
|
| 1230 | -the current TcLevel is greater than that stored in ir_lvl of the Infer
|
|
| 1231 | -ExpType. We bump the level whenever we go past a GADT/existential match.
|
|
| 1229 | +We insist that the RHS has a monotype, regardless of the number of alternatives.
|
|
| 1232 | 1230 | |
| 1233 | 1231 | Then, before filling the hole use promoteTcType to promote the type
|
| 1234 | 1232 | to the outer ir_lvl. promoteTcType does this
|
| ... | ... | @@ -1239,11 +1237,6 @@ That forces the type to be a monotype (since unification variables can |
| 1239 | 1237 | only unify with monotypes); and catches skolem-escapes because the
|
| 1240 | 1238 | alpha is untouchable until the equality floats out.
|
| 1241 | 1239 | |
| 1242 | -For (2), we simply look to see if the hole is filled already.
|
|
| 1243 | - - if not, we promote (as above) and fill the hole
|
|
| 1244 | - - if it is filled, we simply unify with the type that is
|
|
| 1245 | - already there
|
|
| 1246 | - |
|
| 1247 | 1240 | (FIR1) There is one wrinkle. Suppose we have
|
| 1248 | 1241 | case e of
|
| 1249 | 1242 | T1 -> e1 :: (forall a. a->a) -> Int
|
| ... | ... | @@ -1258,7 +1251,36 @@ For (2), we simply look to see if the hole is filled already. |
| 1258 | 1251 | So if we check G2 second, we still want to emit a constraint that restricts
|
| 1259 | 1252 | the RHS to be a monotype. This is done by ensureMonoType, and it works
|
| 1260 | 1253 | by simply generating a constraint (alpha ~ ty), where alpha is a fresh
|
| 1261 | -unification variable. We discard the evidence.
|
|
| 1254 | + unification variable. We discard the evidence.
|
|
| 1255 | + |
|
| 1256 | +Note [fillInferResult: multiple branches]
|
|
| 1257 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1258 | +If there are multiple case branches, case (2) of Note [fillInferResult]
|
|
| 1259 | +we simply look to see if the hole is filled already.
|
|
| 1260 | + - if not, we promote (as above) and fill the hole
|
|
| 1261 | + - if it is filled, we simply unify with the type that is already there
|
|
| 1262 | + |
|
| 1263 | +But consider
|
|
| 1264 | + case x of
|
|
| 1265 | + True -> True
|
|
| 1266 | + False -> error "urk"
|
|
| 1267 | +and suppose we call `tcInferSigma` on this expression, so that the `ir_inst`
|
|
| 1268 | +field of the expected result type is `IIF_Sigma`. The danger is that we'll
|
|
| 1269 | +fill the hole with `Bool` (from the `True`) and then reject when we try to
|
|
| 1270 | +unify that with `forall a. a->a`, from the call to `error`.
|
|
| 1271 | + |
|
| 1272 | +To avoid this, we never infer a sigma-type from a multi-branch `case`. Instead
|
|
| 1273 | +we just zap the `IIF_Sigma` to `IIF_DeepRho` when walking inside the branches
|
|
| 1274 | +of multi-arm case-expression, or an if-expression. See calls to
|
|
| 1275 | +`adjustExpTypeForCaseBranches`.
|
|
| 1276 | + |
|
| 1277 | +Note that
|
|
| 1278 | + case e of
|
|
| 1279 | + True -> hr
|
|
| 1280 | + False -> \x -> hr x
|
|
| 1281 | + where hr :: (forall a. a->a) -> Int
|
|
| 1282 | +will fail, because we still /infer/ both branches, so the \x will get a
|
|
| 1283 | +(monotype) unification variable, which will fail to unify with (forall a. a->a)
|
|
| 1262 | 1284 | |
| 1263 | 1285 | Note [Instantiation of InferResult]
|
| 1264 | 1286 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -1316,7 +1338,7 @@ HOWEVER, not always! Here are places where we want `IIF_Sigma` meaning |
| 1316 | 1338 | but /not/ deeply instantiate (#26331). See Note [View patterns and polymorphism]
|
| 1317 | 1339 | in GHC.Tc.Gen.Pat. This the only place we use IIF_ShallowRho.
|
| 1318 | 1340 | |
| 1319 | -Why do we want to deeply instantiate, ever? Why isn't top-instantiation enough?
|
|
| 1341 | +Why do we want to /deeply/ instantiate, ever? Why isn't top-instantiation enough?
|
|
| 1320 | 1342 | Answer: to accept the following program (T26225b) with -XDeepSubsumption, we
|
| 1321 | 1343 | need to deeply instantiate when inferring in checkResultTy:
|
| 1322 | 1344 |