Apoorv Ingle pushed to branch wip/spj-apporv-Oct24 at Glasgow Haskell Compiler / GHC
Commits:
-
b312c7ba
by Apoorv Ingle at 2025-06-02T11:34:36-05:00
7 changed files:
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/App.hs-boot
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Instance/Class.hs
- compiler/GHC/Tc/Types/Origin.hs
- testsuite/tests/typecheck/should_fail/T8603.stderr
Changes:
... | ... | @@ -179,17 +179,17 @@ tcInferSigma :: Bool -> LHsExpr GhcRn -> TcM TcSigmaType |
179 | 179 | tcInferSigma inst (L loc rn_expr)
|
180 | 180 | = addExprCtxt rn_expr $
|
181 | 181 | setSrcSpanA loc $
|
182 | - do { (_, app_res_sigma) <- tcExprSigma inst rn_expr
|
|
182 | + do { (_, app_res_sigma) <- tcExprSigma inst (exprCtOrigin rn_expr) rn_expr
|
|
183 | 183 | ; return app_res_sigma }
|
184 | 184 | |
185 | --- Very similar to tcApp, but returns a sigma type
|
|
185 | +-- Very similar to tcApp, but returns a sigma (uninstantiated) type
|
|
186 | 186 | -- cf. T19167. the head is an expanded expression applied to a type
|
187 | -tcExprSigma :: Bool -> HsExpr GhcRn -> TcM (HsExpr GhcTc, TcSigmaType)
|
|
188 | -tcExprSigma inst rn_expr
|
|
187 | +tcExprSigma :: Bool -> CtOrigin -> HsExpr GhcRn -> TcM (HsExpr GhcTc, TcSigmaType)
|
|
188 | +tcExprSigma inst fun_orig rn_expr
|
|
189 | 189 | = do { (fun@(rn_fun,fun_ctxt), rn_args) <- splitHsApps rn_expr
|
190 | 190 | ; do_ql <- wantQuickLook rn_fun
|
191 | 191 | ; (tc_fun, fun_sigma) <- tcInferAppHead fun
|
192 | - ; (inst_args, app_res_sigma) <- tcInstFun do_ql inst (tc_fun, rn_fun, fun_ctxt) fun_sigma rn_args
|
|
192 | + ; (inst_args, app_res_sigma) <- tcInstFun do_ql inst fun_orig (tc_fun, fun_ctxt) fun_sigma rn_args
|
|
193 | 193 | ; tc_args <- tcValArgs do_ql inst_args
|
194 | 194 | ; let tc_expr = rebuildHsApps (tc_fun, fun_ctxt) tc_args
|
195 | 195 | ; return (tc_expr, app_res_sigma) }
|
... | ... | @@ -397,11 +397,12 @@ Unify result type /before/ typechecking the args |
397 | 397 | The latter is much better. That is why we call checkResultType before tcValArgs.
|
398 | 398 | -}
|
399 | 399 | |
400 | -tcApp :: HsExpr GhcRn
|
|
400 | +tcApp :: CtOrigin
|
|
401 | + -> HsExpr GhcRn
|
|
401 | 402 | -> ExpRhoType -- When checking, -XDeepSubsumption <=> deeply skolemised
|
402 | 403 | -> TcM (HsExpr GhcTc)
|
403 | 404 | -- See Note [tcApp: typechecking applications]
|
404 | -tcApp rn_expr exp_res_ty
|
|
405 | +tcApp fun_orig rn_expr exp_res_ty
|
|
405 | 406 | = do { -- Step 1: Split the application chain
|
406 | 407 | (fun@(rn_fun, fun_ctxt), rn_args) <- splitHsApps rn_expr
|
407 | 408 | ; traceTc "tcApp {" $
|
... | ... | @@ -421,7 +422,7 @@ tcApp rn_expr exp_res_ty |
421 | 422 | , text "do_ql:" <+> ppr do_ql]
|
422 | 423 | |
423 | 424 | ; (inst_args, app_res_rho)
|
424 | - <- tcInstFun do_ql True (tc_fun, rn_fun, fun_ctxt) fun_sigma rn_args
|
|
425 | + <- tcInstFun do_ql True fun_orig (tc_fun, fun_ctxt) fun_sigma rn_args
|
|
425 | 426 | |
426 | 427 | ; case do_ql of
|
427 | 428 | NoQL -> do { traceTc "tcApp:NoQL" (ppr rn_fun $$ ppr app_res_rho)
|
... | ... | @@ -654,15 +655,17 @@ tcInstFun :: QLFlag |
654 | 655 | -- in tcInferSigma, which is used only to implement :type
|
655 | 656 | -- Otherwise we do eager instantiation; in Fig 5 of the paper
|
656 | 657 | -- |-inst returns a rho-type
|
657 | - -> (HsExpr GhcTc, HsExpr GhcRn, AppCtxt)
|
|
658 | + -> CtOrigin
|
|
659 | + -> (HsExpr GhcTc, AppCtxt)
|
|
658 | 660 | -> TcSigmaType -> [HsExprArg 'TcpRn]
|
659 | 661 | -> TcM ( [HsExprArg 'TcpInst]
|
660 | 662 | , TcSigmaType )
|
661 | 663 | -- This crucial function implements the |-inst judgement in Fig 4, plus the
|
662 | 664 | -- modification in Fig 5, of the QL paper:
|
663 | 665 | -- "A quick look at impredicativity" (ICFP'20).
|
664 | -tcInstFun do_ql inst_final (tc_fun, rn_fun, fun_ctxt) fun_sigma rn_args
|
|
665 | - = do { traceTc "tcInstFun" (vcat [ text "tc_fun" <+> ppr tc_fun
|
|
666 | +tcInstFun do_ql inst_final fun_orig (tc_fun, fun_ctxt) fun_sigma rn_args
|
|
667 | + = do { traceTc "tcInstFun" (vcat [ text "origin" <+> ppr fun_orig
|
|
668 | + , text "tc_fun" <+> ppr tc_fun
|
|
666 | 669 | , text "fun_sigma" <+> ppr fun_sigma
|
667 | 670 | , text "args:" <+> ppr rn_args
|
668 | 671 | , text "do_ql" <+> ppr do_ql
|
... | ... | @@ -671,8 +674,6 @@ tcInstFun do_ql inst_final (tc_fun, rn_fun, fun_ctxt) fun_sigma rn_args |
671 | 674 | -- Note [tcApp: typechecking applications]
|
672 | 675 | go 1 [] fun_sigma rn_args }
|
673 | 676 | where
|
674 | - fun_orig = exprCtOrigin rn_fun
|
|
675 | - |
|
676 | 677 | -- These are the type variables which must be instantiated to concrete
|
677 | 678 | -- types. See Note [Representation-polymorphic Ids with no binding]
|
678 | 679 | -- in GHC.Tc.Utils.Concrete
|
... | ... | @@ -1775,7 +1776,7 @@ quickLookArg1 ctxt larg@(L _ arg) sc_arg_ty@(Scaled _ orig_arg_rho) |
1775 | 1776 | ; do_ql <- wantQuickLook rn_fun
|
1776 | 1777 | ; ((inst_args, app_res_rho), wanted)
|
1777 | 1778 | <- captureConstraints $
|
1778 | - tcInstFun do_ql True (tc_fun, rn_fun, fun_ctxt) fun_sigma rn_args
|
|
1779 | + tcInstFun do_ql True (exprCtOrigin arg) (tc_fun, fun_ctxt) fun_sigma rn_args
|
|
1779 | 1780 | -- We must capture type-class and equality constraints here, but
|
1780 | 1781 | -- not equality constraints. See (QLA6) in Note [Quick Look at
|
1781 | 1782 | -- value arguments]
|
... | ... | @@ -2,9 +2,10 @@ module GHC.Tc.Gen.App where |
2 | 2 | |
3 | 3 | import GHC.Hs ( HsExpr )
|
4 | 4 | import GHC.Tc.Types ( TcM )
|
5 | +import GHC.Tc.Types.Origin ( CtOrigin )
|
|
5 | 6 | import GHC.Tc.Utils.TcType ( TcSigmaType )
|
6 | 7 | import GHC.Hs.Extension ( GhcRn, GhcTc )
|
7 | 8 | |
8 | 9 | import GHC.Prelude (Bool)
|
9 | 10 | |
10 | -tcExprSigma :: Bool -> HsExpr GhcRn -> TcM (HsExpr GhcTc, TcSigmaType) |
|
\ No newline at end of file | ||
11 | +tcExprSigma :: Bool -> CtOrigin -> HsExpr GhcRn -> TcM (HsExpr GhcTc, TcSigmaType) |
|
\ No newline at end of file |
... | ... | @@ -175,7 +175,7 @@ tcPolyExprCheck expr res_ty |
175 | 175 | |
176 | 176 | -- The special case for lambda: go to tcLambdaMatches, passing pat_tys
|
177 | 177 | tc_body e@(HsLam x lam_variant matches)
|
178 | - = do { (wrap, matches') <- tcLambdaMatches e lam_variant matches pat_tys
|
|
178 | + = do { (wrap, matches') <- tcLambdaMatches e lam_variant matches pat_tys
|
|
179 | 179 | (mkCheckExpType rho_ty)
|
180 | 180 | -- NB: tcLambdaMatches concludes with deep skolemisation,
|
181 | 181 | -- if DeepSubsumption is on; hence no need to do that here
|
... | ... | @@ -265,6 +265,15 @@ tcMonoExprNC (L loc expr) res_ty |
265 | 265 | do { expr' <- tcExpr expr res_ty
|
266 | 266 | ; return (L loc expr') }
|
267 | 267 | |
268 | + |
|
269 | +routes_via_tcApp :: HsExpr GhcRn -> Bool
|
|
270 | +routes_via_tcApp (HsVar {}) = True
|
|
271 | +routes_via_tcApp (HsApp {}) = True
|
|
272 | +routes_via_tcApp (OpApp {}) = True
|
|
273 | +routes_via_tcApp (HsAppType {}) = True
|
|
274 | +routes_via_tcApp (ExprWithTySig {}) = True
|
|
275 | +routes_via_tcApp _ = False
|
|
276 | + |
|
268 | 277 | ---------------
|
269 | 278 | tcExpr :: HsExpr GhcRn
|
270 | 279 | -> ExpRhoType -- DeepSubsumption <=> when checking, this type
|
... | ... | @@ -286,14 +295,14 @@ tcExpr :: HsExpr GhcRn |
286 | 295 | -- These constructors are the union of
|
287 | 296 | -- - ones taken apart by GHC.Tc.Gen.Head.splitHsApps
|
288 | 297 | -- - ones understood by GHC.Tc.Gen.Head.tcInferAppHead_maybe
|
289 | --- See Note [Application chains and heads] in GHC.Tc.Gen.App
|
|
290 | -tcExpr e@(HsVar {}) res_ty = tcApp e res_ty
|
|
291 | -tcExpr e@(HsApp {}) res_ty = tcApp e res_ty
|
|
292 | -tcExpr e@(OpApp {}) res_ty = tcApp e res_ty
|
|
293 | -tcExpr e@(HsAppType {}) res_ty = tcApp e res_ty
|
|
294 | -tcExpr e@(ExprWithTySig {}) res_ty = tcApp e res_ty
|
|
298 | +-- See Note [Application chains and heads] in GHC.Tc.Gen.Ap
|
|
299 | +tcExpr e@(HsVar {}) res_ty = tcApp (exprCtOrigin e) e res_ty
|
|
300 | +tcExpr e@(HsApp {}) res_ty = tcApp (exprCtOrigin e) e res_ty
|
|
301 | +tcExpr e@(OpApp {}) res_ty = tcApp (exprCtOrigin e) e res_ty
|
|
302 | +tcExpr e@(HsAppType {}) res_ty = tcApp (exprCtOrigin e) e res_ty
|
|
303 | +tcExpr e@(ExprWithTySig {}) res_ty = tcApp (exprCtOrigin e) e res_ty
|
|
295 | 304 | |
296 | -tcExpr (XExpr e) res_ty = tcXExpr e res_ty
|
|
305 | +tcExpr (XExpr e') res_ty = tcXExpr e' res_ty
|
|
297 | 306 | |
298 | 307 | -- Typecheck an occurrence of an unbound Id
|
299 | 308 | --
|
... | ... | @@ -362,7 +371,7 @@ tcExpr e@(HsOverLit _ lit) res_ty |
362 | 371 | -- See Note [Short cut for overloaded literals] in GHC.Tc.Utils.TcMType
|
363 | 372 | ; case mb_res of
|
364 | 373 | Just lit' -> return (HsOverLit noExtField lit')
|
365 | - Nothing -> tcApp e res_ty }
|
|
374 | + Nothing -> tcApp (exprCtOrigin e) e res_ty }
|
|
366 | 375 | -- Why go via tcApp? See Note [Typechecking overloaded literals]
|
367 | 376 | |
368 | 377 | {- Note [Typechecking overloaded literals]
|
... | ... | @@ -743,16 +752,19 @@ tcExpr (SectionR {}) ty = pprPanic "tcExpr:SectionR" (ppr ty) |
743 | 752 | tcXExpr :: XXExprGhcRn -> ExpRhoType -> TcM (HsExpr GhcTc)
|
744 | 753 | |
745 | 754 | tcXExpr (PopErrCtxt e) res_ty
|
746 | - = popErrCtxt $ -- See Part 3 of Note [Expanding HsDo with XXExprGhcRn] in `GHC.Tc.Gen.Do`
|
|
747 | - addExprCtxt e $
|
|
748 | - tcExpr e res_ty
|
|
755 | + = do popErrCtxt $ -- See Part 3 of Note [Expanding HsDo with XXExprGhcRn] in `GHC.Tc.Gen.Do`
|
|
756 | + addExprCtxt e $
|
|
757 | + tcExpr e res_ty
|
|
749 | 758 | |
750 | -tcXExpr (ExpandedThingRn o e) res_ty
|
|
759 | +tcXExpr xe@(ExpandedThingRn o e) res_ty
|
|
751 | 760 | = mkExpandedTc o <$> -- necessary for breakpoints
|
752 | - do setInGeneratedCode $ tcExpr e res_ty
|
|
761 | + do setInGeneratedCode $
|
|
762 | + if routes_via_tcApp e
|
|
763 | + then tcApp (exprCtOrigin (XExpr xe)) e res_ty
|
|
764 | + else tcExpr e res_ty
|
|
753 | 765 | |
754 | 766 | -- For record selection, same as HsVar case
|
755 | -tcXExpr xe res_ty = tcApp (XExpr xe) res_ty
|
|
767 | +tcXExpr xe res_ty = tcApp (exprCtOrigin (XExpr xe)) (XExpr xe) res_ty
|
|
756 | 768 | |
757 | 769 | |
758 | 770 | {-
|
... | ... | @@ -17,7 +17,7 @@ |
17 | 17 | |
18 | 18 | module GHC.Tc.Gen.Head
|
19 | 19 | ( HsExprArg(..), TcPass(..), QLFlag(..), EWrap(..)
|
20 | - , AppCtxt(..), appCtxtLoc, insideExpansion
|
|
20 | + , AppCtxt(..), appCtxtLoc, insideExpansion, appCtxtExpr
|
|
21 | 21 | , splitHsApps, rebuildHsApps
|
22 | 22 | , addArgWrap, isHsValArg
|
23 | 23 | , leadingValArgs, isVisibleArg
|
... | ... | @@ -247,7 +247,10 @@ appCtxtLoc :: AppCtxt -> SrcSpan |
247 | 247 | appCtxtLoc (VACall _ _ l) = l
|
248 | 248 | |
249 | 249 | insideExpansion :: AppCtxt -> Bool
|
250 | -insideExpansion (VACall _ _ loc) = isGeneratedSrcSpan loc
|
|
250 | +insideExpansion ctxt = isGeneratedSrcSpan (appCtxtLoc ctxt)
|
|
251 | + |
|
252 | +appCtxtExpr :: AppCtxt -> HsExpr GhcRn
|
|
253 | +appCtxtExpr (VACall e _ _) = e
|
|
251 | 254 | |
252 | 255 | instance Outputable QLFlag where
|
253 | 256 | ppr DoQL = text "DoQL"
|
... | ... | @@ -531,14 +534,15 @@ tcInferAppHead_maybe :: HsExpr GhcRn |
531 | 534 | -> TcM (Maybe (HsExpr GhcTc, TcSigmaType))
|
532 | 535 | -- See Note [Application chains and heads] in GHC.Tc.Gen.App
|
533 | 536 | -- Returns Nothing for a complicated head
|
534 | -tcInferAppHead_maybe fun
|
|
535 | - = case fun of
|
|
537 | +tcInferAppHead_maybe fun =
|
|
538 | + case fun of
|
|
536 | 539 | HsVar _ nm -> Just <$> tcInferId nm
|
537 | 540 | XExpr (HsRecSelRn f) -> Just <$> tcInferRecSelId f
|
538 | - XExpr (ExpandedThingRn _ e) -> Just <$> (setInGeneratedCode $ tcExprSigma False e) -- We do not want to instantiate e c.f. T19167
|
|
541 | + XExpr (ExpandedThingRn _ e) -> Just <$> (setInGeneratedCode $ -- We do not want to instantiate c.f. T19167
|
|
542 | + tcExprSigma False (exprCtOrigin fun) e)
|
|
539 | 543 | XExpr (PopErrCtxt e) -> tcInferAppHead_maybe e
|
540 | 544 | ExprWithTySig _ e hs_ty -> Just <$> tcExprWithSig e hs_ty
|
541 | - HsOverLit _ lit -> Just <$> tcInferOverLit lit -- TODO: Do we need this?
|
|
545 | + HsOverLit _ lit -> Just <$> tcInferOverLit lit
|
|
542 | 546 | _ -> return Nothing
|
543 | 547 | |
544 | 548 | addHeadCtxt :: AppCtxt -> TcM a -> TcM a
|
... | ... | @@ -22,7 +22,7 @@ import GHC.Tc.Instance.Typeable |
22 | 22 | import GHC.Tc.Utils.TcMType
|
23 | 23 | import GHC.Tc.Types.Evidence
|
24 | 24 | import GHC.Tc.Types.CtLoc
|
25 | -import GHC.Tc.Types.Origin ( InstanceWhat (..), SafeOverlapping, CtOrigin(OccurrenceOf) )
|
|
25 | +import GHC.Tc.Types.Origin ( InstanceWhat (..), SafeOverlapping, CtOrigin(GetFieldOrigin) )
|
|
26 | 26 | import GHC.Tc.Instance.Family( tcGetFamInstEnvs, tcInstNewTyCon_maybe, tcLookupDataFamInst, FamInstEnvs )
|
27 | 27 | import GHC.Rename.Env( addUsedGRE, addUsedDataCons, DeprecationWarnings (..) )
|
28 | 28 | |
... | ... | @@ -1327,7 +1327,8 @@ warnIncompleteRecSel dflags sel_id ct_loc |
1327 | 1327 | |
1328 | 1328 | -- GHC.Tc.Gen.App.tcInstFun arranges that the CtOrigin of (r.x) is GetFieldOrigin,
|
1329 | 1329 | -- despite the expansion to (getField @"x" r)
|
1330 | - isGetFieldOrigin (OccurrenceOf f) = f `hasKey` getFieldClassOpKey
|
|
1330 | + isGetFieldOrigin (GetFieldOrigin {}) = True
|
|
1331 | + -- isGetFieldOrigin (OccurrenceOf f) = f `hasKey` getFieldClassOpKey
|
|
1331 | 1332 | isGetFieldOrigin _ = False
|
1332 | 1333 | |
1333 | 1334 | lookupHasFieldLabel
|
... | ... | @@ -758,8 +758,9 @@ exprCtOrigin (HsHole _) = Shouldn'tHappenOrigin "hole expression" |
758 | 758 | exprCtOrigin (HsForAll {}) = Shouldn'tHappenOrigin "forall telescope" -- See Note [Types in terms]
|
759 | 759 | exprCtOrigin (HsQual {}) = Shouldn'tHappenOrigin "constraint context" -- See Note [Types in terms]
|
760 | 760 | exprCtOrigin (HsFunArr {}) = Shouldn'tHappenOrigin "function arrow" -- See Note [Types in terms]
|
761 | -exprCtOrigin (XExpr (ExpandedThingRn{})) = Shouldn'tHappenOrigin "XExpr ExpandedThingRn"
|
|
762 | -exprCtOrigin (XExpr (PopErrCtxt {})) = Shouldn'tHappenOrigin "PopErrCtxt"
|
|
761 | +exprCtOrigin (XExpr (ExpandedThingRn (OrigStmt {}) _)) = DoOrigin
|
|
762 | +exprCtOrigin (XExpr (ExpandedThingRn (OrigExpr e) _)) = exprCtOrigin e
|
|
763 | +exprCtOrigin (XExpr (PopErrCtxt e)) = exprCtOrigin e
|
|
763 | 764 | exprCtOrigin (XExpr (HsRecSelRn f)) = OccurrenceOfRecSel (foExt f)
|
764 | 765 | |
765 | 766 | -- | Extract a suitable CtOrigin from a MatchGroup
|
... | ... | @@ -14,15 +14,3 @@ T8603.hs:33:17: error: [GHC-18872] |
14 | 14 | do prize <- lift uniform [1, 2, ....]
|
15 | 15 | return False
|
16 | 16 | |
17 | -T8603.hs:33:22: error: [GHC-83865]
|
|
18 | - • Couldn't match type: RV a1
|
|
19 | - with: StateT s RV a0
|
|
20 | - Expected: [a1] -> StateT s RV a0
|
|
21 | - Actual: [a1] -> RV a1
|
|
22 | - • In the first argument of ‘lift’, namely ‘uniform’
|
|
23 | - In the expression: lift uniform [1, 2, 3]
|
|
24 | - In the expression:
|
|
25 | - do prize <- lift uniform [1, 2, ....]
|
|
26 | - return False
|
|
27 | - • Relevant bindings include
|
|
28 | - testRVState1 :: RVState s Bool (bound at T8603.hs:32:1) |