From 310424d05836ee8788c7c79f98243ef92330f5f1 Mon Sep 17 00:00:00 2001 From: Matthew Pickering <matthewtpickering@gmail.com> Date: Mon, 3 Jan 2022 15:53:43 +0000 Subject: [PATCH] Correct type of static forms in hsExprType The simplest way to do this seemed to be to persist the whole type in the extension field from the typechecker so that the few relevant places * Desugaring can work out the return type by splitting this type rather than calling `dsExpr` (slightly more efficient). * hsExprType can just return the correct type. * Zonking has to now zonk the type as well The other option we considered was wiring in StaticPtr but that is actually quite tricky because StaticPtr refers to StaticPtrInfo which has field selectors (which we can't easily wire in). Fixes #20150 --- compiler/GHC/Builtin/Types.hs | 1 - compiler/GHC/Hs/Expr.hs | 4 +++- compiler/GHC/Hs/Syn/Type.hs | 2 +- compiler/GHC/HsToCore/Expr.hs | 4 ++-- compiler/GHC/Iface/Ext/Ast.hs | 1 - compiler/GHC/Tc/Gen/Expr.hs | 3 ++- compiler/GHC/Tc/Utils/Zonk.hs | 5 +++-- compiler/Language/Haskell/Syntax/Expr.hs | 2 +- testsuite/tests/ghci/scripts/T20150.hs | 9 +++++++++ testsuite/tests/ghci/scripts/T20150.script | 3 +++ testsuite/tests/ghci/scripts/T20150.stdout | 6 ++++++ testsuite/tests/ghci/scripts/all.T | 1 + 12 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 testsuite/tests/ghci/scripts/T20150.hs create mode 100644 testsuite/tests/ghci/scripts/T20150.script create mode 100644 testsuite/tests/ghci/scripts/T20150.stdout diff --git a/compiler/GHC/Builtin/Types.hs b/compiler/GHC/Builtin/Types.hs index 6be9ecd29305..2096e27a2b91 100644 --- a/compiler/GHC/Builtin/Types.hs +++ b/compiler/GHC/Builtin/Types.hs @@ -158,7 +158,6 @@ module GHC.Builtin.Types ( naturalTy, naturalTyCon, naturalTyConName, naturalNSDataCon, naturalNSDataConName, naturalNBDataCon, naturalNBDataConName - ) where import GHC.Prelude diff --git a/compiler/GHC/Hs/Expr.hs b/compiler/GHC/Hs/Expr.hs index 6228b7d90e43..8c77966e18d1 100644 --- a/compiler/GHC/Hs/Expr.hs +++ b/compiler/GHC/Hs/Expr.hs @@ -351,7 +351,9 @@ type instance XProc (GhcPass _) = EpAnn [AddEpAnn] type instance XStatic GhcPs = EpAnn [AddEpAnn] type instance XStatic GhcRn = NameSet -type instance XStatic GhcTc = NameSet +type instance XStatic GhcTc = (NameSet, Type) + -- Free variables and type of expression, this is stored for convenience as wiring in + -- StaticPtr is a bit tricky (see #20150) type instance XPragE (GhcPass _) = NoExtField diff --git a/compiler/GHC/Hs/Syn/Type.hs b/compiler/GHC/Hs/Syn/Type.hs index 1501abbb9eb2..c985c9237cf0 100644 --- a/compiler/GHC/Hs/Syn/Type.hs +++ b/compiler/GHC/Hs/Syn/Type.hs @@ -138,7 +138,7 @@ hsExprType e@(HsSpliceE{}) = pprPanic "hsExprType: Unexpected HsSpliceE" -- can't use `dataConCantHappen` since they are still present before -- than in the typechecked AST. hsExprType (HsProc _ _ lcmd_top) = lhsCmdTopType lcmd_top -hsExprType (HsStatic _ e) = lhsExprType e +hsExprType (HsStatic (_, ty) _s) = ty hsExprType (HsPragE _ _ e) = lhsExprType e hsExprType (XExpr (WrapExpr (HsWrap wrap e))) = hsWrapperType wrap $ hsExprType e hsExprType (XExpr (ExpansionExpr (HsExpanded _ tc_e))) = hsExprType tc_e diff --git a/compiler/GHC/HsToCore/Expr.hs b/compiler/GHC/HsToCore/Expr.hs index c2501de16535..4e4eca8cef16 100644 --- a/compiler/GHC/HsToCore/Expr.hs +++ b/compiler/GHC/HsToCore/Expr.hs @@ -418,9 +418,9 @@ See Note [Grand plan for static forms] in GHC.Iface.Tidy.StaticPtrTable for an o g = ... makeStatic loc f ... -} -dsExpr (HsStatic _ expr@(L loc _)) = do +dsExpr (HsStatic (_, whole_ty) expr@(L loc _)) = do expr_ds <- dsLExpr expr - let ty = exprType expr_ds + let (_, [ty]) = splitTyConApp whole_ty makeStaticId <- dsLookupGlobalId makeStaticName dflags <- getDynFlags diff --git a/compiler/GHC/Iface/Ext/Ast.hs b/compiler/GHC/Iface/Ext/Ast.hs index 0c74db385d4f..83eb475a7886 100644 --- a/compiler/GHC/Iface/Ext/Ast.hs +++ b/compiler/GHC/Iface/Ext/Ast.hs @@ -737,7 +737,6 @@ instance HiePass p => HasType (LocatedA (HsExpr (GhcPass p))) where HsLet _ _ _ _ body -> computeLType body RecordCon con_expr _ _ -> computeType con_expr ExprWithTySig _ e _ -> computeLType e - HsStatic _ e -> computeLType e HsPragE _ _ e -> computeLType e XExpr (ExpansionExpr (HsExpanded _ e)) -> computeType e XExpr (HsTick _ e) -> computeLType e diff --git a/compiler/GHC/Tc/Gen/Expr.hs b/compiler/GHC/Tc/Gen/Expr.hs index 0c1d4faf249c..8bff4b7e5382 100644 --- a/compiler/GHC/Tc/Gen/Expr.hs +++ b/compiler/GHC/Tc/Gen/Expr.hs @@ -455,9 +455,10 @@ tcExpr (HsStatic fvs expr) res_ty [p_ty] ; let wrap = mkWpEvVarApps [typeable_ev] <.> mkWpTyApps [expr_ty] ; loc <- getSrcSpanM + ; static_ptr_ty_con <- tcLookupTyCon staticPtrTyConName ; return $ mkHsWrapCo co $ HsApp noComments (L (noAnnSrcSpan loc) $ mkHsWrap wrap fromStaticPtr) - (L (noAnnSrcSpan loc) (HsStatic fvs expr')) + (L (noAnnSrcSpan loc) (HsStatic (fvs, mkTyConApp static_ptr_ty_con [expr_ty]) expr')) } {- diff --git a/compiler/GHC/Tc/Utils/Zonk.hs b/compiler/GHC/Tc/Utils/Zonk.hs index fec8d90d5de6..6a65d5d3833d 100644 --- a/compiler/GHC/Tc/Utils/Zonk.hs +++ b/compiler/GHC/Tc/Utils/Zonk.hs @@ -920,8 +920,9 @@ zonkExpr env (HsProc x pat body) ; return (HsProc x new_pat new_body) } -- StaticPointers extension -zonkExpr env (HsStatic fvs expr) - = HsStatic fvs <$> zonkLExpr env expr +zonkExpr env (HsStatic (fvs, ty) expr) + = do new_ty <- zonkTcTypeToTypeX env ty + HsStatic (fvs, new_ty) <$> zonkLExpr env expr zonkExpr env (XExpr (WrapExpr (HsWrap co_fn expr))) = do (env1, new_co_fn) <- zonkCoFn env co_fn diff --git a/compiler/Language/Haskell/Syntax/Expr.hs b/compiler/Language/Haskell/Syntax/Expr.hs index e6ce12f8aec0..0baaeaa1481f 100644 --- a/compiler/Language/Haskell/Syntax/Expr.hs +++ b/compiler/Language/Haskell/Syntax/Expr.hs @@ -637,7 +637,7 @@ data HsExpr p -- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnStatic', -- For details on above see note [exact print annotations] in GHC.Parser.Annotation - | HsStatic (XStatic p) -- Free variables of the body + | HsStatic (XStatic p) -- Free variables of the body, and type after typechecking (LHsExpr p) -- Body --------------------------------------- diff --git a/testsuite/tests/ghci/scripts/T20150.hs b/testsuite/tests/ghci/scripts/T20150.hs new file mode 100644 index 000000000000..e1706dedc407 --- /dev/null +++ b/testsuite/tests/ghci/scripts/T20150.hs @@ -0,0 +1,9 @@ +{-# LANGUAGE StaticPointers #-} +module T20150 where + +import GHC.StaticPtr + +foo :: StaticPtr Int +foo = static 0 + + diff --git a/testsuite/tests/ghci/scripts/T20150.script b/testsuite/tests/ghci/scripts/T20150.script new file mode 100644 index 000000000000..0b5d132cdd0f --- /dev/null +++ b/testsuite/tests/ghci/scripts/T20150.script @@ -0,0 +1,3 @@ +:set +c +:l T20150.hs +:all-types diff --git a/testsuite/tests/ghci/scripts/T20150.stdout b/testsuite/tests/ghci/scripts/T20150.stdout new file mode 100644 index 000000000000..e55ee89ea95b --- /dev/null +++ b/testsuite/tests/ghci/scripts/T20150.stdout @@ -0,0 +1,6 @@ +Collecting type info for 1 module(s) ... +T20150.hs:(7,1)-(7,3): GHC.StaticPtr.StaticPtr GHC.Types.Int +T20150.hs:(7,14)-(7,14): GHC.Types.Int +T20150.hs:(7,7)-(7,14): GHC.StaticPtr.StaticPtr GHC.Types.Int +T20150.hs:(7,7)-(7,14): GHC.StaticPtr.StaticPtr GHC.Types.Int -> GHC.StaticPtr.StaticPtr GHC.Types.Int +T20150.hs:(7,7)-(7,14): GHC.StaticPtr.StaticPtr GHC.Types.Int diff --git a/testsuite/tests/ghci/scripts/all.T b/testsuite/tests/ghci/scripts/all.T index 5e9aea056dee..71e0ea80a5ad 100755 --- a/testsuite/tests/ghci/scripts/all.T +++ b/testsuite/tests/ghci/scripts/all.T @@ -354,3 +354,4 @@ test('T20473b', normal, ghci_script, ['T20473b.script']) test('T20587', [extra_files(['../shell.hs'])], ghci_script, ['T20587.script']) test('T20909', normal, ghci_script, ['T20909.script']) +test('T20150', normal, ghci_script, ['T20150.script']) -- GitLab