summaryrefslogtreecommitdiff
path: root/compiler/Language
diff options
context:
space:
mode:
authorromes <rodrigo.m.mesquita@gmail.com>2022-03-19 17:42:46 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-06-01 07:44:44 -0400
commit7975202ba9010c581918413808ee06fbab9ac85f (patch)
treeffebdbd9d9fcef2300b1a6d3950bb5dd3f8435c4 /compiler/Language
parent392ce3fca5d33688add52309a05914efa163e6f6 (diff)
downloadhaskell-7975202ba9010c581918413808ee06fbab9ac85f.tar.gz
TTG: Rework and improve splices
This commit redefines the structure of Splices in the AST. We get rid of `HsSplice` which used to represent typed and untyped splices, quasi quotes, and the result of splicing either an expression, a type or a pattern. Instead we have `HsUntypedSplice` which models an untyped splice or a quasi quoter, which works in practice just like untyped splices. The `HsExpr` constructor `HsSpliceE` which used to be constructed with an `HsSplice` is split into `HsTypedSplice` and `HsUntypedSplice`. The former is directly constructed with an `HsExpr` and the latter now takes an `HsUntypedSplice`. Both `HsType` and `Pat` constructors `HsSpliceTy` and `SplicePat` now take an `HsUntypedSplice` instead of a `HsSplice` (remember only /untyped splices/ can be spliced as types or patterns). The result of splicing an expression, type, or pattern is now comfortably stored in the extension fields `XSpliceTy`, `XSplicePat`, `XUntypedSplice` as, respectively, `HsUntypedSpliceResult (HsType GhcRn)`, `HsUntypedSpliceResult (Pat GhcRn)`, and `HsUntypedSpliceResult (HsExpr GhcRn)` Overall the TTG extension points are now better used to make invalid states unrepresentable and model the progression between stages better. See Note [Lifecycle of an untyped splice, and PendingRnSplice] and Note [Lifecycle of an typed splice, and PendingTcSplice] for more details. Updates haddock submodule Fixes #21263 ------------------------- Metric Decrease: hard_hole_fits -------------------------
Diffstat (limited to 'compiler/Language')
-rw-r--r--compiler/Language/Haskell/Syntax/Decls.hs19
-rw-r--r--compiler/Language/Haskell/Syntax/Expr.hs101
-rw-r--r--compiler/Language/Haskell/Syntax/Expr.hs-boot4
-rw-r--r--compiler/Language/Haskell/Syntax/Extension.hs13
-rw-r--r--compiler/Language/Haskell/Syntax/Pat.hs4
-rw-r--r--compiler/Language/Haskell/Syntax/Type.hs4
6 files changed, 47 insertions, 98 deletions
diff --git a/compiler/Language/Haskell/Syntax/Decls.hs b/compiler/Language/Haskell/Syntax/Decls.hs
index 026080d3f6..303105e3d4 100644
--- a/compiler/Language/Haskell/Syntax/Decls.hs
+++ b/compiler/Language/Haskell/Syntax/Decls.hs
@@ -66,7 +66,7 @@ module Language.Haskell.Syntax.Decls (
-- ** @default@ declarations
DefaultDecl(..), LDefaultDecl,
-- ** Template haskell declaration splice
- SpliceExplicitFlag(..),
+ SpliceDecoration(..),
SpliceDecl(..), LSpliceDecl,
-- ** Foreign function interface declarations
ForeignDecl(..), LForeignDecl, ForeignImport(..), ForeignExport(..),
@@ -95,7 +95,7 @@ module Language.Haskell.Syntax.Decls (
import GHC.Prelude
import {-# SOURCE #-} Language.Haskell.Syntax.Expr
- ( HsExpr, HsSplice )
+ ( HsExpr, HsUntypedSplice )
-- Because Expr imports Decls via HsBracket
import Language.Haskell.Syntax.Binds
@@ -245,10 +245,21 @@ type LSpliceDecl pass = XRec pass (SpliceDecl pass)
data SpliceDecl p
= SpliceDecl -- Top level splice
(XSpliceDecl p)
- (XRec p (HsSplice p))
- SpliceExplicitFlag
+ (XRec p (HsUntypedSplice p))
+ SpliceDecoration -- Whether $( ) variant found, for pretty printing
| XSpliceDecl !(XXSpliceDecl p)
+-- | A splice can appear with various decorations wrapped around it. This data
+-- type captures explicitly how it was originally written, for use in the pretty
+-- printer.
+data SpliceDecoration
+ = DollarSplice -- ^ $splice
+ | BareSplice -- ^ bare splice
+ deriving (Data, Eq, Show)
+
+instance Outputable SpliceDecoration where
+ ppr x = text $ show x
+
{-
************************************************************************
* *
diff --git a/compiler/Language/Haskell/Syntax/Expr.hs b/compiler/Language/Haskell/Syntax/Expr.hs
index f964c5d3f6..051edda97f 100644
--- a/compiler/Language/Haskell/Syntax/Expr.hs
+++ b/compiler/Language/Haskell/Syntax/Expr.hs
@@ -46,13 +46,9 @@ import GHC.Data.FastString
-- libraries:
import Data.Data hiding (Fixity(..))
-import qualified Data.Data as Data (Fixity(..))
import Data.List.NonEmpty ( NonEmpty )
-import GHCi.RemoteTypes ( ForeignRef )
-import qualified Language.Haskell.TH as TH (Q)
-
{- Note [RecordDotSyntax field updates]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The extensions @OverloadedRecordDot@ @OverloadedRecordUpdate@ together
@@ -603,7 +599,8 @@ data HsExpr p
-- 'GHC.Parser.Annotation.AnnClose'
-- For details on above see Note [exact print annotations] in GHC.Parser.Annotation
- | HsSpliceE (XSpliceE p) (HsSplice p)
+ | HsTypedSplice (XTypedSplice p) (LHsExpr p) -- `$$z` or `$$(f 4)`
+ | HsUntypedSplice (XUntypedSplice p) (HsUntypedSplice p)
-----------------------------------------------------------
-- Arrow notation extension
@@ -1542,87 +1539,29 @@ Workshop 2007).
Briefly, one writes
[p| stuff |]
-and the arbitrary string "stuff" gets parsed by the parser 'p', whose
-type should be Language.Haskell.TH.Quote.QuasiQuoter. 'p' must be
-defined in another module, because we are going to run it here. It's
-a bit like a TH splice:
- $(p "stuff")
-
-However, you can do this in patterns as well as terms. Because of this,
-the splice is run by the *renamer* rather than the type checker.
+and the arbitrary string "stuff" gets parsed by the parser 'p', whose type
+should be Language.Haskell.TH.Quote.QuasiQuoter. 'p' must be defined in
+another module, because we are going to run it here. It's a bit like an
+/untyped/ TH splice where the parser is applied the "stuff" as a string, thus:
+ $(p "stuff")
+
+Notice that it's an /untyped/ TH splice: it can occur in patterns and types, as well
+as in expressions; and it runs in the renamer.
-}
-- | Haskell Splice
-data HsSplice id
- = HsTypedSplice -- $$z or $$(f 4)
- (XTypedSplice id)
- SpliceDecoration -- Whether $$( ) variant found, for pretty printing
- (IdP id) -- A unique name to identify this splice point
- (LHsExpr id) -- See Note [Pending Splices]
-
- | HsUntypedSplice -- $z or $(f 4)
- (XUntypedSplice id)
- SpliceDecoration -- Whether $( ) variant found, for pretty printing
- (IdP id) -- A unique name to identify this splice point
- (LHsExpr id) -- See Note [Pending Splices]
-
- | HsQuasiQuote -- See Note [Quasi-quote overview]
- (XQuasiQuote id)
- (IdP id) -- Splice point
- (IdP id) -- Quoter
- SrcSpan -- The span of the enclosed string
- FastString -- The enclosed string
-
- -- AZ:TODO: use XSplice instead of HsSpliced
- | HsSpliced -- See Note [Delaying modFinalizers in untyped splices] in
- -- GHC.Rename.Splice.
- -- This is the result of splicing a splice. It is produced by
- -- the renamer and consumed by the typechecker. It lives only
- -- between the two.
- (XSpliced id)
- ThModFinalizers -- TH finalizers produced by the splice.
- (HsSplicedThing id) -- The result of splicing
- | XSplice !(XXSplice id) -- Extension point; see Note [Trees That Grow]
- -- in Language.Haskell.Syntax.Extension
-
--- | A splice can appear with various decorations wrapped around it. This data
--- type captures explicitly how it was originally written, for use in the pretty
--- printer.
-data SpliceDecoration
- = DollarSplice -- ^ $splice or $$splice
- | BareSplice -- ^ bare splice
- deriving (Data, Eq, Show)
-
-instance Outputable SpliceDecoration where
- ppr x = text $ show x
-
-
-isTypedSplice :: HsSplice id -> Bool
-isTypedSplice (HsTypedSplice {}) = True
-isTypedSplice _ = False -- Quasi-quotes are untyped splices
-
--- | Finalizers produced by a splice with
--- 'Language.Haskell.TH.Syntax.addModFinalizer'
---
--- See Note [Delaying modFinalizers in untyped splices] in GHC.Rename.Splice. For how
--- this is used.
---
-newtype ThModFinalizers = ThModFinalizers [ForeignRef (TH.Q ())]
+data HsUntypedSplice id
+ = HsUntypedSpliceExpr -- $z or $(f 4)
+ (XUntypedSpliceExpr id)
+ (LHsExpr id)
--- A Data instance which ignores the argument of 'ThModFinalizers'.
-instance Data ThModFinalizers where
- gunfold _ z _ = z $ ThModFinalizers []
- toConstr a = mkConstr (dataTypeOf a) "ThModFinalizers" [] Data.Prefix
- dataTypeOf a = mkDataType "HsExpr.ThModFinalizers" [toConstr a]
-
--- | Haskell Spliced Thing
---
--- Values that can result from running a splice.
-data HsSplicedThing id
- = HsSplicedExpr (HsExpr id) -- ^ Haskell Spliced Expression
- | HsSplicedTy (HsType id) -- ^ Haskell Spliced Type
- | HsSplicedPat (Pat id) -- ^ Haskell Spliced Pattern
+ | HsQuasiQuote -- See Note [Quasi-quote overview]
+ (XQuasiQuote id)
+ (IdP id) -- The quoter (the bit between `[` and `|`)
+ (XRec id FastString) -- The enclosed string
+ | XUntypedSplice !(XXUntypedSplice id) -- Extension point; see Note [Trees That Grow]
+ -- in Language.Haskell.Syntax.Extension
-- | Haskell (Untyped) Quote = Expr + Pat + Type + Var
data HsQuote p
diff --git a/compiler/Language/Haskell/Syntax/Expr.hs-boot b/compiler/Language/Haskell/Syntax/Expr.hs-boot
index 3ea7e32708..b6a0d79431 100644
--- a/compiler/Language/Haskell/Syntax/Expr.hs-boot
+++ b/compiler/Language/Haskell/Syntax/Expr.hs-boot
@@ -12,9 +12,9 @@ import Data.Kind ( Type )
type role HsExpr nominal
type role MatchGroup nominal nominal
type role GRHSs nominal nominal
-type role HsSplice nominal
+type role HsUntypedSplice nominal
data HsExpr (i :: Type)
-data HsSplice (i :: Type)
+data HsUntypedSplice (i :: Type)
data MatchGroup (a :: Type) (body :: Type)
data GRHSs (a :: Type) (body :: Type)
type family SyntaxExpr (i :: Type)
diff --git a/compiler/Language/Haskell/Syntax/Extension.hs b/compiler/Language/Haskell/Syntax/Extension.hs
index dc39d10c99..5cffd96690 100644
--- a/compiler/Language/Haskell/Syntax/Extension.hs
+++ b/compiler/Language/Haskell/Syntax/Extension.hs
@@ -431,7 +431,8 @@ type family XExprWithTySig x
type family XArithSeq x
type family XTypedBracket x
type family XUntypedBracket x
-type family XSpliceE x
+type family XTypedSplice x
+type family XUntypedSplice x
type family XProc x
type family XStatic x
type family XTick x
@@ -463,12 +464,10 @@ type family XMissing x
type family XXTupArg x
-- -------------------------------------
--- HsSplice type families
-type family XTypedSplice x
-type family XUntypedSplice x
-type family XQuasiQuote x
-type family XSpliced x
-type family XXSplice x
+-- HsUntypedSplice type families
+type family XUntypedSpliceExpr x
+type family XQuasiQuote x
+type family XXUntypedSplice x
-- -------------------------------------
-- HsQuoteBracket type families
diff --git a/compiler/Language/Haskell/Syntax/Pat.hs b/compiler/Language/Haskell/Syntax/Pat.hs
index 2f96d107c0..0e9f11dc1b 100644
--- a/compiler/Language/Haskell/Syntax/Pat.hs
+++ b/compiler/Language/Haskell/Syntax/Pat.hs
@@ -31,7 +31,7 @@ module Language.Haskell.Syntax.Pat (
import GHC.Prelude
-import {-# SOURCE #-} Language.Haskell.Syntax.Expr (SyntaxExpr, LHsExpr, HsSplice)
+import {-# SOURCE #-} Language.Haskell.Syntax.Expr (SyntaxExpr, LHsExpr, HsUntypedSplice)
-- friends:
import Language.Haskell.Syntax.Lit
@@ -161,7 +161,7 @@ data Pat p
-- For details on above see Note [exact print annotations] in GHC.Parser.Annotation
| SplicePat (XSplicePat p)
- (HsSplice p) -- ^ Splice Pattern (Includes quasi-quotes)
+ (HsUntypedSplice p) -- ^ Splice Pattern (Includes quasi-quotes)
------------ Literal and n+k patterns ---------------
| LitPat (XLitPat p)
diff --git a/compiler/Language/Haskell/Syntax/Type.hs b/compiler/Language/Haskell/Syntax/Type.hs
index 0c84e9faa6..e394628f25 100644
--- a/compiler/Language/Haskell/Syntax/Type.hs
+++ b/compiler/Language/Haskell/Syntax/Type.hs
@@ -58,7 +58,7 @@ module Language.Haskell.Syntax.Type (
import GHC.Prelude
-import {-# SOURCE #-} Language.Haskell.Syntax.Expr ( HsSplice )
+import {-# SOURCE #-} Language.Haskell.Syntax.Expr ( HsUntypedSplice )
import Language.Haskell.Syntax.Extension
@@ -836,7 +836,7 @@ data HsType pass
-- For details on above see Note [exact print annotations] in GHC.Parser.Annotation
| HsSpliceTy (XSpliceTy pass)
- (HsSplice pass) -- Includes quasi-quotes
+ (HsUntypedSplice pass) -- Includes quasi-quotes
-- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'$('@,
-- 'GHC.Parser.Annotation.AnnClose' @')'@