Opened 6 years ago

Closed 6 years ago

Last modified 5 years ago

#9161 closed bug (fixed)

Pattern synonyms interact badly with data kinds

Reported by: Iceland_jack Owned by: cactus
Priority: lowest Milestone: 7.8.3
Component: Compiler (Type checker) Version: 7.8.2
Keywords: renamer, PatternSynonyms, data kinds Cc: cactus
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Compile-time crash Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


If we define a pattern A and use it as a type:

{-# LANGUAGE PatternSynonyms, DataKinds #-}

pattern A = ()

b :: A
b = undefined

we get the following error:

Prelude> :load tmp.XDGqzccOAV.hs
[1 of 1] Compiling Main             ( /tmp/tmp.XDGqzccOAV.hs, interpreted )

    GHC internal error: ‘A’ is not in scope during type checking, but it passed the renamer
    tcl_env of environment: []
    In the type signature for ‘blah’: blah :: A
Failed, modules loaded: none.

Also occurs with different arities of A (the arity of the pattern and type can differ) and defining it as an operator (enabling the TypeOperators pragma).

Change History (10)

comment:1 Changed 6 years ago by simonpj

Cc: cactus added
Owner: set to cactus

Probably we should not promote pattern synonyms to the type level, so the program should be rejected with "you can't use a pattern synonym as a type, even with DataKinds" error.

Gergo might you look at this?


comment:2 Changed 6 years ago by cactus

Component: CompilerCompiler (Type checker)
Operating System: LinuxUnknown/Multiple
Type of failure: None/UnknownCompile-time crash

This one is tricky...

One would expect in this scenario roughly the same code path as if you write

{-# LANGUAGE DataKinds #-}
data TYPE = CON

wrongLift :: CON
wrongLift = undefined

which BTW results in a reasonable error message:

Expected a type, but ‘CON’ has kind ‘TYPE’
In the type signature for ‘wrongLift’: wrongLift :: CON

However, since pattern synonyms are internally handled as binds, not TyClDecls, they are not yet in scope during kind checking (which is done by tcTyClsInstDecls) - hence the crash.

How do we even get to trying to kindcheck them? OccName.demoteOccName handles data constructor names and type constructor names the same way, since we don't differentiate between the two there.

So I think our best bet would be to have a bespoke internal kind for pattern synonyms, inject pattern synonyms at that kind before doing kind checking, and then barf on types of that kind with a meaningful error message.

Simon, does that sound like a good plan of action?

comment:3 Changed 6 years ago by simonpj

Basically yes. I suggest one of two things:

  • Add pattern synonyms as AGlobal (AConLike (PatSynCon (panic "..."))). Apart from the panic, this is exactly how imported pattern synonyms will appear, and TcHsType.tcTyVar will call wrongThingErr on it. It would make sense for local pattern synonmys to behave the same way. The panic won't be looked at because TcEnv.wrongThingErr doesn't look at the payload.
  • Short cut: don't extend the environment. Instead, in the "no in scope during type checking" error, test for DataName and instead complain about using a pattern synonym in a type. Better: do this only in the context of tcTyVar, by replicating a certain amount of the tcLookup code. This is bit of a hack; I'd rather not do it.


comment:4 Changed 6 years ago by cactus

Status: newmerge

comment:5 Changed 6 years ago by cactus

Fixed using Simon's approach #1.

comment:6 Changed 6 years ago by simonpj

The actual commit is

commit aa3166f42361cb605e046f4a063be3f9e1f48015
Author: Dr. ERDI Gergo <>
Date:   Sat Jun 21 22:37:50 2014 +0800

    Add fake entries into the global kind environment for pattern synonyms.
    This is needed to give meaningful error messages (instead of internal
    panics) when a program tries to lift a pattern synonym into a kind.
    (fixes T9161)


 compiler/typecheck/TcBinds.lhs                    | 23 ++++++++++++++++-------
 compiler/typecheck/TcHsType.lhs                   |  1 -
 testsuite/tests/patsyn/should_fail/T9161-1.hs     |  7 +++++++
 testsuite/tests/patsyn/should_fail/T9161-1.stderr |  4 ++++
 testsuite/tests/patsyn/should_fail/T9161-2.hs     |  9 +++++++++
 testsuite/tests/patsyn/should_fail/T9161-2.stderr |  5 +++++
 testsuite/tests/patsyn/should_fail/all.T          |  2 ++
 7 files changed, 43 insertions(+), 8 deletions(-)

comment:7 Changed 6 years ago by Simon Peyton Jones <simonpj@…>

In 0757831eaca96c8ebfd99fc51427560d3568cffa/ghc:

Add Note [Placeholder PatSyn kinds] in TcBinds

This is just documentation for the fix to Trac #9161

comment:8 Changed 6 years ago by cactus

Thanks for that note, which explains it much better than my original comment.

comment:9 Changed 6 years ago by thoughtpolice

Milestone: 7.8.3
Resolution: fixed
Status: mergeclosed

This was merged into GHC 7.8 for 7.8.3 (part of fixing #9175).

comment:10 Changed 5 years ago by cactus

Keywords: PatternSynonyms added; pattern synonyms removed
Note: See TracTickets for help on using tickets.