[Git][ghc/ghc][wip/T24190] Allow untyped brackets in typed splices and vice versa.
Oleg Grenrus (@phadej)
gitlab at gitlab.haskell.org
Thu Dec 7 20:45:26 UTC 2023
Oleg Grenrus pushed to branch wip/T24190 at Glasgow Haskell Compiler / GHC
Commits:
67f373cc by Oleg Grenrus at 2023-12-07T22:45:15+02:00
Allow untyped brackets in typed splices and vice versa.
Resolves #24190
Apparently the check was essentially always (as far as I can trace back: d0d47ba76f8f0501cf3c4966bc83966ab38cac27),
and while it does catch some mismatches, the type-checker will catch
them too. OTOH, it prevents writing completely reasonable programs.
- - - - -
6 changed files:
- compiler/GHC/Rename/Splice.hs
- + testsuite/tests/th/T24190.hs
- + testsuite/tests/th/T24190.stdout
- testsuite/tests/th/TH_NestedSplicesFail3.stderr
- testsuite/tests/th/TH_NestedSplicesFail4.stderr
- testsuite/tests/th/all.T
Changes:
=====================================
compiler/GHC/Rename/Splice.hs
=====================================
@@ -85,6 +85,31 @@ checkForTemplateHaskellQuotes e =
unlessXOptM LangExt.TemplateHaskellQuotes $
failWith $ thSyntaxError $ IllegalTHQuotes e
+{-
+Note [Untyped quotes in typed splices and vice versa]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider this typed splice
+ $$(f [| x |])
+
+Is there anything wrong with that /typed/ splice containing an /untyped/
+quote [| x |]? One could ask the same about an /untpyed/ slice containing a
+/typed/ quote.
+
+In fact, both are fine (#24190). Presumably f's type looks something like:
+ f :: Q Expr -> Code Q Int
+
+It is pretty hard for `f` to use its (untyped code) argument to build a typed
+syntax tree, but not impossible:
+* `f` could use `unsafeCodeCoerce :: Q Exp -> Code Q a`
+* `f` could just perform case analysis on the tree
+
+But in the end all that matters is that in $$( e ), the expression `e` has the
+right type. It doesn't matter how `e` is built.
+
+(Historical note: GHC used to unnecessarily check that a typed quote only
+occurred in a typed splice: #24190.)
+-}
+
rnTypedBracket :: HsExpr GhcPs -> LHsExpr GhcPs -> RnM (HsExpr GhcRn, FreeVars)
rnTypedBracket e br_body
= addErrCtxt (typedQuotationCtxtDoc br_body) $
@@ -93,9 +118,8 @@ rnTypedBracket e br_body
-- Check for nested brackets
; cur_stage <- getStage
; case cur_stage of
- { Splice Typed -> return ()
- ; Splice Untyped -> failWithTc $ thSyntaxError
- $ MismatchedSpliceType Untyped IsBracket
+ { Splice _ -> return ()
+ -- See Note [Untyped quotes in typed splices and vice versa]
; RunSplice _ ->
-- See Note [RunSplice ThLevel] in GHC.Tc.Types.
pprPanic "rnTypedBracket: Renaming typed bracket when running a splice"
@@ -123,9 +147,8 @@ rnUntypedBracket e br_body
-- Check for nested brackets
; cur_stage <- getStage
; case cur_stage of
- { Splice Typed -> failWithTc $ thSyntaxError
- $ MismatchedSpliceType Typed IsBracket
- ; Splice Untyped -> return ()
+ { Splice _ -> return ()
+ -- See Note [Untyped quotes in typed splices and vice versa]
; RunSplice _ ->
-- See Note [RunSplice ThLevel] in GHC.Tc.Types.
pprPanic "rnUntypedBracket: Renaming untyped bracket when running a splice"
=====================================
testsuite/tests/th/T24190.hs
=====================================
@@ -0,0 +1,11 @@
+module Main (main) where
+
+import Language.Haskell.TH
+
+main :: IO ()
+main = do
+ -- type annotations are needed so the monad is not ambiguous.
+ -- we also highlight that the monad can be different:
+ -- brackets are "just" syntax.
+ print $$(const [|| 'x' ||] ([| 'y' |] :: IO Exp))
+ print $( const [| 'x' |] ([|| 'y' ||] :: Code IO Char))
=====================================
testsuite/tests/th/T24190.stdout
=====================================
@@ -0,0 +1,2 @@
+'x'
+'x'
=====================================
testsuite/tests/th/TH_NestedSplicesFail3.stderr
=====================================
@@ -1,5 +1,8 @@
-TH_NestedSplicesFail3.hs:4:12: error: [GHC-45108]
- • Untyped brackets may not appear in typed splices.
- • In the Template Haskell quotation [| 'x' |]
- In the typed splice: $$([| 'x' |])
+TH_NestedSplicesFail3.hs:4:12: error: [GHC-39999]
+ • No instance for ‘Language.Haskell.TH.Syntax.Quote
+ (Language.Haskell.TH.Syntax.Code Language.Haskell.TH.Syntax.Q)’
+ arising from a quotation bracket
+ • In the expression: [| 'x' |]
+ In the Template Haskell splice $$([| 'x' |])
+ In the expression: $$([| 'x' |])
=====================================
testsuite/tests/th/TH_NestedSplicesFail4.stderr
=====================================
@@ -1,5 +1,9 @@
-TH_NestedSplicesFail4.hs:4:11: error: [GHC-45108]
- • Typed brackets may not appear in untyped splices.
- • In the Template Haskell typed quotation [|| 'y' ||]
+TH_NestedSplicesFail4.hs:4:11: error: [GHC-83865]
+ • Couldn't match type: Language.Haskell.TH.Syntax.Code m0 Char
+ with: Language.Haskell.TH.Syntax.Q Language.Haskell.TH.Syntax.Exp
+ Expected: Language.Haskell.TH.Lib.Internal.ExpQ
+ Actual: Language.Haskell.TH.Syntax.Code m0 Char
+ • In the Template Haskell quotation [|| 'y' ||]
+ In the expression: [|| 'y' ||]
In the untyped splice: $([|| 'y' ||])
=====================================
testsuite/tests/th/all.T
=====================================
@@ -598,3 +598,4 @@ test('T23968', normal, compile_and_run, [''])
test('T23971', normal, compile_and_run, [''])
test('T23986', normal, compile_and_run, [''])
test('T24111', normal, compile_and_run, [''])
+test('T24190', normal, compile_and_run, [''])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/67f373ccde2cfb7e16e0fe34d47704690263762a
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/67f373ccde2cfb7e16e0fe34d47704690263762a
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20231207/6e90cde3/attachment-0001.html>
More information about the ghc-commits
mailing list