Opened 3 years ago

Closed 3 years ago

Last modified 23 months ago

#10384 closed task (fixed)

"Can't splice the polymorphic local variable" check looks dead

Reported by: ezyang Owned by: ezyang
Priority: normal Milestone: 8.0.1
Component: Template Haskell Version: 7.11
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

While I was looking for TH checks which might want to be checked when Quotes are enabled ala #10382, I found the "Can't splice the polymorphic local variable" check in checkCrossStageLifting in TcExpr. I thought this was a bit odd, because there is another implementation of this very function in RnSplice.

So I went ahead and removed this check from the compiler, and it validated fine.

I then went and tried to see if I could tickle the problem. An old mailing list suggested the following test program to induce the error:

module TH_polymorphic where

import Language.Haskell.TH
import Language.Haskell.TH.Syntax

-- See https://mail.haskell.org/pipermail/template-haskell/2006-April/000552.html

test2 () = runQ [| foldr f z xs |]  
    where (f,z,xs) = undefined

but I get this error:

TH_polymorphic.hs:8:17: error:
    Could not deduce (Lift t0) arising from a use of ‘lift’
    from the context: Quasi m
      bound by the inferred type of test2 :: Quasi m => () -> m Exp
      at TH_polymorphic.hs:(8,1)-(9,30)  
    The type variable ‘t0’ is ambiguous
    Note: there are several potential instances:
      instance (Lift a, Lift b) => Lift (Either a b)
        -- Defined in ‘Language.Haskell.TH.Syntax’
      instance Lift a => Lift (Maybe a)
        -- Defined in ‘Language.Haskell.TH.Syntax’
      instance Lift Int16 -- Defined in ‘Language.Haskell.TH.Syntax’
      ...plus 24 others
    In the expression: lift xs
    In the first argument of ‘runQ’, namely
      ‘[| foldr f z xs |]
       pending(rn) [<xs, lift xs>, <z, lift z>, <f, lift f>]’
    In the expression:
      runQ
        [| foldr f z xs |]  
        pending(rn) [<xs, lift xs>, <z, lift z>, <f, lift f>]

which seems to be induced the check in RnSplice.

So is it dead? If so, let's remove it!

Change History (12)

comment:1 Changed 3 years ago by simonpj

I don't think it's dead:

  • In RnSplice.checkCrossStageLifting you'll see that it applies ONLY if the stage is RnPendingUntyped, i.e. we are renaming the body of an untyped bracket. It does nothing for typed brackets.

So what is happening in RnSplice is that we treat [| ...x...|] as equivalent to [| ...(lift x)... |], which seems right.

But what should happen for typed splices? Presumably, [|| ...x....||] should be equivalent to [|| ....$(tlift x).... ||], where

tlift :: Lift t => t -> TExp t

It shouldn't matter if x has a polymorphic type, because it'll be instantiated by its context. We might need to whiz up a new SplicePointName though.

But we don't seem to have tlift or anything like it. I'm puzzled.

Simon

comment:2 Changed 3 years ago by ezyang

Owner: set to ezyang

Looking at the Core of:

{-# LANGUAGE TemplateHaskell, FlexibleInstances, IncoherentInstances #-}
module A where
import Language.Haskell.TH.Syntax
instance Lift a where
    lift = undefined
x = \y -> [|| y ||]

we can see that it goes through Lift, and then an unsafeTExpCoerce, so there's no need for a separate tlift typeclass. (tcTypedBracket is responsible for typechecking the expression and then coercing it.)

But that was enough of a hint to let me figure out how to tickle this case.

{-# LANGUAGE TemplateHaskell, RankNTypes, ScopedTypeVariables #-}
module A where
x = \(y :: forall a. a -> a) -> [|| y ||]
A.hs:3:37:
    Can't splice the polymorphic local variable ‘y’
    In the Template Haskell quotation [|| y ||]
    In the expression: [|| y ||]
    In the expression: \ (y :: forall a. a -> a) -> [|| y ||]

I'll add a test-case for it.

comment:3 Changed 3 years ago by Edward Z. Yang <ezyang@…>

In 341a76641426a452fc27d3b9383945b9744c600a/ghc:

Doc: checkCrossStageLifting, RnSplice/TcExpr is untyped/typed brackets (#10384)

Clarify that repeated checkCrossStageLifting in RnSplice/TcExpr
check untyped/typed brackets, respectively.

Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>

comment:4 Changed 3 years ago by Simon Peyton Jones <simonpj@…>

In 931d014d4276d4213d8de4b1f5e51f0219b724dd/ghc:

A bit of refactoring RnSplice

...to make clearer what the cross-stage lifting code
applies to (c.f. Trac #10384)

comment:5 Changed 3 years ago by Edward Z. Yang <ezyang@…>

In 9a43b2c1f78b3cf684646af64b9b67dc8079f58f/ghc:

Always do polymorphic typed quote check, c.f. #10384

Summary:
Since quotes are enabled in stage1, we need to do the
staging check.  This also "fixes" #10384 by adding
a test for the polymorphic local variable test.

Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>

Test Plan: validate

Reviewers: simonpj, austin

Subscribers: bgamari, thomie

Differential Revision: https://phabricator.haskell.org/D880

GHC Trac Issues: #10384

comment:6 Changed 3 years ago by ezyang

Resolution: fixed
Status: newclosed

comment:7 Changed 3 years ago by Edward Z. Yang <ezyang@…>

In 5c459eefcb17ff97beebdc08ccfca21bd8fa5201/ghc:

Revert stage 1 template-haskell. This is a combination of 5 commits.

Revert "Quick fix: drop base bound on template-haskell."

This reverts commit 3c70ae032e4361b203dfcf22b0a424e8838a5037.

Revert "Always do polymorphic typed quote check, c.f. #10384"

This reverts commit 9a43b2c1f78b3cf684646af64b9b67dc8079f58f.

Revert "RnSplice's staging test should be applied for quotes in stage1."

This reverts commit eb0ed4030374af542c0a459480d32c8d4525e48d.

Revert "Split off quotes/ from th/ for tests that can be done on stage1 compiler."

This reverts commit 21c72e7d38c96ac80d31addf67ae4b3c7a6c3bbb.

Revert "Support stage 1 Template Haskell (non-quasi) quotes, fixes #10382."

This reverts commit 28257cae77023f2ccc4cc1c0cd1fbbd329947a00.

comment:8 Changed 3 years ago by simonpj

Edward, I'm confused. The ticket is closed, but all patches seem to have been reverted. What's up?

comment:9 Changed 3 years ago by rwbarton

Owner: ezyang deleted
Resolution: fixed
Status: closednew

I think Edward said in IRC that the template-haskell library needs to be fixed up to build with 7.8 again first, since the commits in this ticket cause it to be built as a boot library and we need to be able to bootstrap with 7.8.

comment:10 Changed 3 years ago by rwbarton

Owner: set to ezyang

comment:11 Changed 3 years ago by ezyang

Resolution: fixed
Status: newclosed

Re-committed as:

commit f16ddcee0c64a92ab911a7841a8cf64e3ac671fd
Author: Edward Z. Yang <ezyang@cs.stanford.edu>
Date:   Mon May 4 16:10:05 2015 -0700

    Support stage 1 Template Haskell (non-quasi) quotes, fixes #10382.
    
    Summary:
    This commit adds stage 1 support for Template Haskell
    quoting, e.g. [| ... expr ... |], which is useful
    for authors of quasiquoter libraries that do not actually
    need splices.  The TemplateHaskell extension now does not
    unconditionally fail; it only fails if the renamer encounters
    a splice that it can't run.
      
    In order to make sure the referenced data structures
    are consistent, template-haskell is now a boot library.
    There are some minor BC changes to template-haskell to make it boot
    on GHC 7.8.
    
    Note for reviewer: big diff changes are simply code
    being moved out of an ifdef; there was no other substantive
    change to that code.
    
    Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
    
    Test Plan: validate
    
    Reviewers: simonpj, austin, goldfire
    
    Subscribers: bgamari, thomie
    
    Differential Revision: https://phabricator.haskell.org/D876
    
    GHC Trac Issues: #10382

which merged all the patches together.

comment:12 Changed 23 months ago by thomie

Milestone: 8.0.1
Note: See TracTickets for help on using tickets.