Opened 7 years ago

Closed 4 years ago

Last modified 4 years ago

#4846 closed bug (fixed)

Newtype derving used wrongly

Reported by: simonpj Owned by:
Priority: low Milestone: 7.6.2
Component: Compiler Version: 7.0.1
Keywords: Cc: emax@…, sweirich@…, dimitris@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case: deriving/should_fail/T4846
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

Emil Axelsson reports: I attach a program Test.hs which I suspect demonstrates a bug in GHC. The important lines are:

   showType :: forall a . Expr a -> String
   showType (Lit _) = show (typeOf (undefined :: a))

   test1 = showType (mk     :: Expr BOOL) -- Prints "Bool" (wrong?)
   test2 = showType (Lit mk :: Expr BOOL) -- Prints "Main.BOOL" (correct)

test1 and test2 give different results, even though showType shouldn't be able to tell them apart. It seems that the Typeable context packed with the Lit constructor is wrong in test2.

Attachments (1)

T4846.hs (845 bytes) - added by simonpj 7 years ago.

Download all attachments as: .zip

Change History (9)

Changed 7 years ago by simonpj

Attachment: T4846.hs added

comment:1 Changed 7 years ago by simonpj

Cc: sweirich@… dimitris@… added

Good catch. I had a look, and it turns out to be another example of the nasty #1496 newtype-deriving bug.

In this case, GHC is making this type equality:

Expr Bool ~ Expr BOOL

But the equality isn't right, because Expr captures a Typeable dictionary that can see what type the term has.

This bug has been long un-fixed because I've been quite unsure what the right fix is. Happily I think we now know; see our POPL 2011 paper Generative Type Abstraction and Type-level Computation.

Of course, there is the small matter of implementing the ideas in the paper, which in turn is queued up behind a number of other type-system implementation tasks. So don't hold your breath. (The workaround is not to use newtype deriving for (B BOOL).)

The paper only deals with type functions, but your example shows that we must be equally careful with type classes. Thank you for that.

comment:2 Changed 7 years ago by igloo

Milestone: 7.2.1

comment:3 Changed 6 years ago by igloo

Milestone: 7.4.17.6.1
Priority: normallow

comment:4 Changed 5 years ago by igloo

Milestone: 7.6.17.6.2

comment:5 Changed 4 years ago by goldfire

difficulty: Unknown

See Roles for the concrete approach toward a solution. Expect a working implementation to be available within a week or two.

comment:6 Changed 4 years ago by eir@…

commit e8aa8ccba0c40884765281b21ff8f4411802dd41

Author: Richard Eisenberg <eir@cis.upenn.edu>
Date:   Fri Aug 2 15:47:03 2013 +0100

    Implement "roles" into GHC.
    
    Roles are a solution to the GeneralizedNewtypeDeriving type-safety
    problem.
    
    Roles were first described in the "Generative type abstraction" paper,
    by Stephanie Weirich, Dimitrios Vytiniotis, Simon PJ, and Steve Zdancewic.
    The implementation is a little different than that paper. For a quick
    primer, check out Note [Roles] in Coercion. Also see
    http://ghc.haskell.org/trac/ghc/wiki/Roles
    and
    http://ghc.haskell.org/trac/ghc/wiki/RolesImplementation
    For a more formal treatment, check out docs/core-spec/core-spec.pdf.
    
    This fixes Trac #1496, #4846, #7148.

 compiler/basicTypes/DataCon.lhs                   |   10 +-
 compiler/basicTypes/MkId.lhs                      |   14 +-
 compiler/cmm/SMRep.lhs                            |   42 +-
 compiler/coreSyn/CoreLint.lhs                     |  123 ++--
 compiler/coreSyn/CoreSubst.lhs                    |    8 +-
 compiler/coreSyn/CoreUtils.lhs                    |   16 +-
 compiler/coreSyn/ExternalCore.lhs                 |   29 +-
 compiler/coreSyn/MkExternalCore.lhs               |   24 +-
 compiler/coreSyn/PprExternalCore.lhs              |   60 +-
 compiler/coreSyn/TrieMap.lhs                      |   82 ++-
 compiler/deSugar/DsBinds.lhs                      |   59 +-
 compiler/deSugar/DsForeign.lhs                    |    2 +-
 compiler/deSugar/DsMeta.hs                        |  106 ++-
 compiler/ghci/ByteCodeAsm.lhs                     |   16 +-
 compiler/hsSyn/Convert.lhs                        |   19 +-
 compiler/hsSyn/HsTypes.lhs                        |   25 +-
 compiler/hsSyn/HsUtils.lhs                        |    2 +-
 compiler/iface/BinIface.hs                        |    1 +
 compiler/iface/BuildTyCl.lhs                      |   43 +-
 compiler/iface/IfaceSyn.lhs                       |  128 ++--
 compiler/iface/IfaceType.lhs                      |  343 ++++++---
 compiler/iface/MkIface.lhs                        |   19 +-
 compiler/iface/TcIface.lhs                        |   75 +-
 compiler/main/DynFlags.hs                         |    2 +
 compiler/parser/Lexer.x                           |   31 +-
 compiler/parser/Parser.y.pp                       |   26 +-
 compiler/parser/ParserCore.y                      |    7 +-
 compiler/parser/RdrHsSyn.lhs                      |    8 +-
 compiler/prelude/PrelNames.lhs                    |    4 +-
 compiler/prelude/PrelRules.lhs                    |    4 +-
 compiler/prelude/TysPrim.lhs                      |   62 +-
 compiler/prelude/TysWiredIn.lhs                   |    4 +
 compiler/rename/RnTypes.lhs                       |   43 +-
 compiler/simplCore/SimplUtils.lhs                 |    2 +-
 compiler/specialise/Rules.lhs                     |    7 +-
 compiler/specialise/SpecConstr.lhs                |    2 +-
 compiler/stranal/WwLib.lhs                        |    4 +-
 compiler/typecheck/TcDeriv.lhs                    |   16 +-
 compiler/typecheck/TcEvidence.lhs                 |    8 +-
 compiler/typecheck/TcForeign.lhs                  |   48 +-
 compiler/typecheck/TcGenGenerics.lhs              |    2 +-
 compiler/typecheck/TcHsType.lhs                   |  105 ++-
 compiler/typecheck/TcInstDcls.lhs                 |   13 +-
 compiler/typecheck/TcInteract.lhs                 |    3 +-
 compiler/typecheck/TcRnDriver.lhs                 |   12 +-
 compiler/typecheck/TcSplice.lhs                   |   42 +-
 compiler/typecheck/TcTyClsDecls.lhs               |  302 ++++++--
 compiler/typecheck/TcTyDecls.lhs                  |  293 +++++++-
 compiler/typecheck/TcType.lhs                     |    7 +-
 compiler/types/Class.lhs                          |    6 +-
 compiler/types/CoAxiom.lhs                        |   82 ++-
 compiler/types/Coercion.lhs                       |  802 +++++++++++++++------
 compiler/types/FamInstEnv.lhs                     |   78 +-
 compiler/types/OptCoercion.lhs                    |  199 +++--
 compiler/types/TyCon.lhs                          |  110 ++-
 compiler/types/Type.lhs                           |    9 +-
 compiler/types/TypeRep.lhs                        |    2 +-
 compiler/utils/Maybes.lhs                         |    5 +
 compiler/utils/UniqFM.lhs                         |    2 +-
 compiler/utils/Util.lhs                           |   10 +-
 compiler/vectorise/Vectorise/Generic/PAMethods.hs |    8 +-
 compiler/vectorise/Vectorise/Generic/PData.hs     |    1 +
 compiler/vectorise/Vectorise/Type/Env.hs          |    2 +-
 compiler/vectorise/Vectorise/Type/TyConDecl.hs    |    2 +
 compiler/vectorise/Vectorise/Utils/Base.hs        |    4 +-
 compiler/vectorise/Vectorise/Utils/PADict.hs      |    2 +-
 docs/core-spec/CoreLint.ott                       |  178 +++--
 docs/core-spec/CoreSyn.ott                        |   77 +-
 docs/core-spec/OpSem.ott                          |    2 +-
 docs/core-spec/README                             |    2 +-
 docs/core-spec/core-spec.mng                      |   54 +-
 docs/core-spec/core-spec.pdf                      |  Bin 349150 -> 359837 bytes
 docs/users_guide/glasgow_exts.xml                 |  211 +++++-
 73 files changed, 3091 insertions(+), 1060 deletions(-)

comment:7 Changed 4 years ago by goldfire

Resolution: fixed
Status: newclosed

comment:8 Changed 4 years ago by goldfire

Test Case: deriving/should_fail/T4846
Note: See TracTickets for help on using tickets.