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) |