
#10996: family is treated as keyword in types even without TypeFamilies enabled -------------------------------------+------------------------------------- Reporter: oerjan | Owner: Type: bug | Status: new Priority: low | Milestone: Component: Compiler | Version: 7.10.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: GHC rejects | Test Case: type Test valid program | family = family Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): Indeed. In `Parser.y` we see: {{{ tyvarid :: { Located RdrName } : VARID { sL1 $1 $! mkUnqual tvName (getVARID $1) } | special_id { sL1 $1 $! mkUnqual tvName (unLoc $1) } | 'unsafe' { sL1 $1 $! mkUnqual tvName (fsLit "unsafe") } | 'safe' { sL1 $1 $! mkUnqual tvName (fsLit "safe") } | 'interruptible' { sL1 $1 $! mkUnqual tvName (fsLit "interruptible") } varid :: { Located RdrName } : VARID { sL1 $1 $! mkUnqual varName (getVARID $1) } | special_id { sL1 $1 $! mkUnqual varName (unLoc $1) } | 'unsafe' { sL1 $1 $! mkUnqual varName (fsLit "unsafe") } | 'safe' { sL1 $1 $! mkUnqual varName (fsLit "safe") } | 'interruptible' { sL1 $1 $! mkUnqual varName (fsLit "interruptible")} | 'forall' { sL1 $1 $! mkUnqual varName (fsLit "forall") } | 'family' { sL1 $1 $! mkUnqual varName (fsLit "family") } | 'role' { sL1 $1 $! mkUnqual varName (fsLit "role") } -- These special_ids are treated as keywords in various places, -- but as ordinary ids elsewhere. 'special_id' collects all these -- except 'unsafe', 'interruptible', 'forall', 'family', and 'role', -- whose treatment differs depending on context special_id :: { Located FastString } special_id : 'as' { sL1 $1 (fsLit "as") } | 'qualified' { sL1 $1 (fsLit "qualified") } | 'hiding' { sL1 $1 (fsLit "hiding") } | 'export' { sL1 $1 (fsLit "export") } | 'label' { sL1 $1 (fsLit "label") } | 'dynamic' { sL1 $1 (fsLit "dynamic") } | 'stdcall' { sL1 $1 (fsLit "stdcall") } | 'ccall' { sL1 $1 (fsLit "ccall") } | 'capi' { sL1 $1 (fsLit "capi") } | 'prim' { sL1 $1 (fsLit "prim") } | 'javascript' { sL1 $1 (fsLit "javascript") } | 'group' { sL1 $1 (fsLit "group") } }}} The idea of `special_id` is a good one, because it avoids stealing keywords. The comment claims that 'unsafe', 'safe', and 'interruptible' have treatment that varies by context; but that claim seems bogus. The ONLY uses of `special_id` is the code above, so adding those three to `special_id` and removing them from `varid` and `tyvarid` should be a useful simplification. Can someone try? 'forall' is different because in ''terms'' it is not a keyword, but in ''types'' it is. The lexer therefore only recognises it when specific flags are on. 'role' and 'family' are the warts. Can we put them in `special_id`? I think (but I am not certain) that the reason they are not there is to exclude them from `tyvarid`. Why do that? I think (but I am not sure) that the reason is to resolve the ambiguity in comment:1. If someone felt able to resolve that ambiguity some other way, it'd be great. Otherwise this really is a bug. This isn't really hard, I think; just needs someone to to think clearly for a while. Thanks Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10996#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler