[project @ 2002-02-11 08:20:38 by chak]
[ghc-hetmet.git] / ghc / compiler / rename / ParseIface.y
index 0763ce4..cbeaeed 100644 (file)
@@ -1,4 +1,4 @@
-{-     Notes about the syntax of interface files
+{-     Notes about the syntax of interface files                 -*-haskell-*-
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 The header
 ~~~~~~~~~~
@@ -28,49 +28,50 @@ Import declarations
 
 
 {
-module ParseIface ( parseIface, IfaceStuff(..) ) where
+module ParseIface ( parseIface, parseType, parseRules, parseIdInfo ) where
 
 #include "HsVersions.h"
 
 import HsSyn           -- quite a bit of stuff
 import RdrHsSyn                -- oodles of synonyms
-import HsTypes         ( mkHsForAllTy, mkHsUsForAllTy, mkHsTupCon )
+import HsTypes         ( mkHsForAllTy, mkHsTupCon )
 import HsCore
-import Demand          ( mkStrictnessInfo )
 import Literal         ( Literal(..), mkMachInt, mkMachInt64, mkMachWord, mkMachWord64 )
-import BasicTypes      ( Fixity(..), FixityDirection(..), 
-                         NewOrData(..), Version, initialVersion, Boxity(..)
+import BasicTypes      ( Fixity(..), FixityDirection(..), StrictnessMark(..),
+                         NewOrData(..), Version, initialVersion, Boxity(..),
+                          Activation(..), IPName(..)
                        )
 import CostCentre       ( CostCentre(..), IsCafCC(..), IsDupdCC(..) )
-import CallConv         ( cCallConv )
-import HsPragmas       ( noDataPragmas, noClassPragmas )
-import Type            ( Kind, mkArrowKind, boxedTypeKind, openTypeKind )
-import IdInfo           ( exactArity, InlinePragInfo(..) )
-import PrimOp           ( CCall(..), CCallTarget(..) )
+import Type            ( Kind, mkArrowKind, liftedTypeKind, openTypeKind, usageTypeKind )
+import ForeignCall     ( ForeignCall(..), CCallConv(..), CCallSpec(..), CCallTarget(..) )
 import Lex             
 
-import RnMonad         ( ImportVersion, ParsedIface(..), WhatsImported(..),
-                         ExportItem, RdrAvailInfo, GenAvailInfo(..), 
-                          WhetherHasOrphans, IsBootInterface
-                       ) 
-import RdrName          ( RdrName, mkRdrUnqual, mkSysQual, mkSysUnqual )
+import RnMonad         ( ParsedIface(..), ExportItem, IfaceDeprecs ) 
+import HscTypes         ( WhetherHasOrphans, IsBootInterface, GenAvailInfo(..), 
+                          ImportVersion, WhatsImported(..),
+                          RdrAvailInfo )
+
+import RdrName          ( RdrName, mkRdrUnqual, mkIfaceOrig )
 import Name            ( OccName )
 import OccName          ( mkSysOccFS,
-                         tcName, varName, ipName, dataName, clsName, tvName, uvName,
+                         tcName, varName, dataName, clsName, tvName,
                          EncodedFS 
                        )
-import Module           ( ModuleName, PackageName, mkSysModuleFS, mkModule )                   
+import Module           ( ModuleName, PackageName, mkSysModuleNameFS )
 import SrcLoc          ( SrcLoc )
-import CmdLineOpts     ( opt_InPackage )
+import CmdLineOpts     ( opt_InPackage, opt_IgnoreIfacePragmas )
 import Outputable
-import List            ( insert )
 import Class            ( DefMeth (..) )
 
 import GlaExts
 import FastString      ( tailFS )
 }
 
-%name      parseIface
+%name      parseIface      iface
+%name      parseType       type
+%name      parseIdInfo     id_info
+%name      parseRules      rules_and_deprecs
+
 %tokentype  { Token }
 %monad     { P }{ thenP }{ returnP }
 %lexer      { lexer } { ITeof }
@@ -136,12 +137,11 @@ import FastString ( tailFS )
  '__sccC'       { ITsccAllCafs }
 
  '__u'         { ITusage }
- '__fuall'     { ITfuall }
 
  '__A'         { ITarity }
  '__P'         { ITspecialise }
  '__C'         { ITnocaf }
- '__U'         { ITunfold $$ }
+ '__U'         { ITunfold }
  '__S'         { ITstrict $$ }
  '__R'         { ITrules }
  '__M'         { ITcprinfo }
@@ -160,20 +160,21 @@ import FastString ( tailFS )
  '-'           { ITminus }
  '!'           { ITbang }
 
- '/\\'         { ITbiglam }                    -- GHC-extension symbols
-
  '{'           { ITocurly }                    -- special symbols
  '}'           { ITccurly }
  '{|'          { ITocurlybar }                         -- special symbols
  '|}'          { ITccurlybar }                         -- special symbols
  '['           { ITobrack }
  ']'           { ITcbrack }
+ '[:'          { ITopabrack }
+ ':]'          { ITcpabrack }
  '('           { IToparen }
  ')'           { ITcparen }
  '(#'          { IToubxparen }
  '#)'          { ITcubxparen }
  ';'           { ITsemi }
  ','           { ITcomma }
+ '.'           { ITdot }
 
  VARID         { ITvarid    $$ }               -- identifiers
  CONID         { ITconid    $$ }
@@ -184,7 +185,8 @@ import FastString   ( tailFS )
  QVARSYM       { ITqvarsym  $$ }
  QCONSYM       { ITqconsym  $$ }
 
- IPVARID       { ITipvarid  $$ }               -- GHC extension
+ IPDUPVARID    { ITdupipvarid   $$ }           -- GHC extension
+ IPSPLITVARID          { ITsplitipvarid $$ }           -- GHC extension
 
  PRAGMA                { ITpragma   $$ }
 
@@ -197,19 +199,6 @@ import FastString  ( tailFS )
  UNKNOWN       { ITunknown  $$ }
 %%
 
--- iface_stuff is the main production.
--- It recognises (a) a whole interface file
---              (b) a type (so that type sigs can be parsed lazily)
---              (c) the IdInfo part of a signature (same reason)
-
-iface_stuff :: { IfaceStuff }
-iface_stuff : iface            { PIface   $1 }
-           | type              { PType    $1 }
-           | id_info           { PIdInfo  $1 }
-           | '__R' rules       { PRules   $2 }
-           | '__D' deprecs     { PDeprecs $2 }
-
-
 iface          :: { ParsedIface }
 iface          : '__interface' package mod_name 
                        version sub_versions
@@ -219,21 +208,23 @@ iface             : '__interface' package mod_name
                  fix_decl_part
                  instance_decl_part
                  decls_part
-                 rules_and_deprecs
-                 { ParsedIface {
-                       pi_mod  = mkModule $3 $2,       -- Module itself
+                 rules_and_deprecs_part
+                 { let (rules,deprecs) = $14 () in
+                   ParsedIface {
+                       pi_mod  = $3,                   -- Module name
+                       pi_pkg = $2,                    -- Package name
                        pi_vers = $4,                   -- Module version
                        pi_orphan  = $6,
-                       pi_exports = $9,                -- Exports
+                       pi_exports = (fst $5, $9),      -- Exports
                        pi_usages  = $10,               -- Usages
-                       pi_fixity  = (fst $5,$11),      -- Fixies
+                       pi_fixity  = $11,               -- Fixies
                        pi_insts   = $12,               -- Local instances
                        pi_decls   = $13,               -- Decls
-                       pi_rules   = (snd $5,fst $14),  -- Rules 
-                       pi_deprecs = snd $14            -- Deprecations 
+                       pi_rules   = (snd $5,rules),    -- Rules 
+                       pi_deprecs = deprecs            -- Deprecations 
                   } }
 
--- Versions for fixities and rules (optional)
+-- Versions for exports and rules (optional)
 sub_versions :: { (Version,Version) }
        : '[' version version ']'               { ($2,$3) }
        | {- empty -}                           { (initialVersion, initialVersion) }
@@ -246,7 +237,7 @@ import_part :                                                 { [] }
            
 import_decl :: { ImportVersion OccName }
 import_decl : 'import' mod_name orphans is_boot whats_imported ';'
-                       { (mkSysModuleFS $2, $3, $4, $5) }
+                       { ({-mkSysModuleNameFS-} $2, $3, $4, $5) }
 
 orphans                    :: { WhetherHasOrphans }
 orphans                    :                                           { False }
@@ -259,7 +250,8 @@ is_boot                 :                                           { False }
 whats_imported      :: { WhatsImported OccName }
 whats_imported      :                                                  { NothingAtAll }
                    | '::' version                                      { Everything $2 }
-                    | '::' version version version name_version_pairs   { Specifically $2 $3 $4 $5 }
+                    | '::' version version version name_version_pairs   { Specifically $2 (Just $3) $5 $4 }
+                    | '::' version version name_version_pairs          { Specifically $2 Nothing $4 $3 }
 
 name_version_pairs  :: { [(OccName, Version)] }
 name_version_pairs  :                                                  { [] }
@@ -275,7 +267,7 @@ name_version_pair   :  var_occ version                              { ($1, $2) }
 exports_part   :: { [ExportItem] }
 exports_part   :                                       { [] }
                | '__export' mod_name entities ';'
-                       exports_part                    { (mkSysModuleFS $2, $3) : $5 }
+                       exports_part                    { ({-mkSysModuleNameFS-} $2, $3) : $5 }
 
 entities       :: { [RdrAvailInfo] }
 entities       :                                       { [] }
@@ -285,11 +277,8 @@ entity             :: { RdrAvailInfo }
 entity         :  var_occ                              { Avail $1 }
                |  tc_occ                               { AvailTC $1 [$1] }
                |  tc_occ '|' stuff_inside              { AvailTC $1 $3 }
-               |  tc_occ stuff_inside                  { AvailTC $1 (insert $1 $2) }
-               -- The 'insert' is important.  The stuff_inside is sorted, and
-               -- insert keeps it that way.  This is important when comparing 
-               -- against the new interface file, which has the stuff in sorted order
-               -- If they differ, we'll bump the module number when it's unnecessary
+               |  tc_occ stuff_inside                  { AvailTC $1 ($1:$2) }
+               -- Note that the "main name" comes at the beginning
 
 stuff_inside   :: { [OccName] }
 stuff_inside   :  '{' val_occs '}'                     { $2 }
@@ -335,10 +324,9 @@ csigs1             :                               { [] }
                | csig ';' csigs1               { $1 : $3 }
 
 csig           :: { RdrNameSig }
-csig           :  src_loc var_name '::' type           { mkClassOpSig NoDefMeth $2 $4 $1 }
-               |  src_loc var_name '=' '::' type       { mkClassOpSig (DefMeth (error "DefMeth") )
-                                                               $2 $5 $1 }
-               |  src_loc var_name ';' '::' type       { mkClassOpSig GenDefMeth  $2 $5 $1 }           
+csig           :  src_loc qvar_name '::' type          { ClassOpSig $2 NoDefMeth $4 $1 }
+               |  src_loc qvar_name ';' '::' type      { ClassOpSig $2 GenDefMeth $5 $1 }              
+               |  src_loc qvar_name '=' '::' type      { mkClassOpSigDM $2 $5 $1 }
 
 --------------------------------------------------------------------------
 
@@ -347,7 +335,7 @@ instance_decl_part : {- empty -}                   { [] }
                   | instance_decl_part inst_decl      { $2 : $1 }
 
 inst_decl      :: { RdrNameInstDecl }
-inst_decl      :  src_loc 'instance' type '=' var_name ';'
+inst_decl      :  src_loc 'instance' type '=' qvar_name ';'
                        { InstDecl $3
                                   EmptyMonoBinds       {- No bindings -}
                                   []                   {- No user pragmas -}
@@ -357,87 +345,117 @@ inst_decl        :  src_loc 'instance' type '=' var_name ';'
 
 --------------------------------------------------------------------------
 
-decls_part :: { [(Version, RdrNameHsDecl)] }
+decls_part :: { [(Version, RdrNameTyClDecl)] }
 decls_part 
        :  {- empty -}                          { [] }
        |  opt_version decl ';' decls_part              { ($1,$2):$4 }
 
-decl   :: { RdrNameHsDecl }
-decl    : src_loc var_name '::' type maybe_idinfo
-                        { SigD (IfaceSig $2 $4 ($5 $2) $1) }
-       | src_loc 'type' tc_name tv_bndrs '=' type                     
-                       { TyClD (TySynonym $3 $4 $6 $1) }
-       | src_loc 'data' opt_decl_context tc_name tv_bndrs constrs             
-                       { TyClD (mkTyData DataType $3 $4 $5 $6 (length $6) Nothing noDataPragmas $1) }
-       | src_loc 'newtype' opt_decl_context tc_name tv_bndrs newtype_constr
-                       { TyClD (mkTyData NewType $3 $4 $5 $6 1 Nothing noDataPragmas $1) }
-       | src_loc 'class' opt_decl_context tc_name tv_bndrs fds csigs
-                       { TyClD (mkClassDecl $3 $4 $5 $6 $7 EmptyMonoBinds 
-                                       noClassPragmas $1) }
+decl   :: { RdrNameTyClDecl }
+decl    : src_loc qvar_name '::' type maybe_idinfo
+                       { IfaceSig $2 $4 ($5 $2) $1 }
+       | src_loc 'type' qtc_name tv_bndrs '=' type                    
+                       { TySynonym $3 $4 $6 $1 }
+       | src_loc 'foreign' 'type' qtc_name                    
+                       { ForeignType $4 Nothing DNType $1 }
+       | src_loc 'data' opt_decl_context qtc_name tv_bndrs constrs            
+                       { mkTyData DataType $3 $4 $5 $6 (length $6) Nothing $1 }
+       | src_loc 'newtype' opt_decl_context qtc_name tv_bndrs newtype_constr
+                       { mkTyData NewType $3 $4 $5 $6 1 Nothing $1 }
+       | src_loc 'class' opt_decl_context qtc_name tv_bndrs fds csigs
+                       { mkClassDecl $3 $4 $5 $6 $7 Nothing $1 }
 
 maybe_idinfo  :: { RdrName -> [HsIdInfo RdrName] }
 maybe_idinfo  : {- empty -}    { \_ -> [] }
-             | pragma          { \x -> case $1 of
-                                    POk _ (PIdInfo id_info) -> id_info
-                                    PFailed err -> 
-                                       pprPanic "IdInfo parse failed" 
-                                           (vcat [ppr x, err])
+             | pragma          { \x -> if opt_IgnoreIfacePragmas then [] 
+                                       else case $1 of
+                                               Just (POk _ id_info) -> id_info
+                                               Just (PFailed err) -> pprPanic "IdInfo parse failed" 
+                                                                       (vcat [ppr x, err])
                                }
-
-pragma :: { ParseResult IfaceStuff }
-pragma : src_loc PRAGMA        { parseIface $2 PState{ bol = 0#, atbol = 1#,
-                                                       context = [],
-                                                       glasgow_exts = 1#,
-                                                       loc = $1 }
+    {-
+      If a signature decl is being loaded, and opt_IgnoreIfacePragmas is on,
+      we toss away unfolding information.
+
+      Also, if the signature is loaded from a module we're importing from source,
+      we do the same. This is to avoid situations when compiling a pair of mutually
+      recursive modules, peering at unfolding info in the interface file of the other, 
+      e.g., you compile A, it looks at B's interface file and may as a result change
+      its interface file. Hence, B is recompiled, maybe changing its interface file,
+      which will the unfolding info used in A to become invalid. Simple way out is to
+      just ignore unfolding info.
+
+      [Jan 99: I junked the second test above.  If we're importing from an hi-boot
+       file there isn't going to *be* any pragma info.  The above comment
+       dates from a time where we picked up a .hi file first if it existed.]
+    -}
+
+pragma :: { Maybe (ParseResult [HsIdInfo RdrName]) }
+pragma : src_loc PRAGMA        { let exts = ExtFlags {glasgowExtsEF = True,
+                                                      parrEF        = True}
+                                 in
+                                 Just (parseIdInfo $2 (mkPState $1 exts))
                                }
 
 -----------------------------------------------------------------------------
 
-rules_and_deprecs :: { ([RdrNameRuleDecl], [RdrNameDeprecation]) }
-rules_and_deprecs : {- empty -}        { ([], []) }
-                 | rules_and_deprecs rule_or_deprec
-                               { let
-                                    append2 (xs1,ys1) (xs2,ys2) =
-                                       (xs1 `app` xs2, ys1 `app` ys2)
-                                    xs `app` [] = xs -- performance paranoia
-                                    xs `app` ys = xs ++ ys
-                                 in append2 $1 $2
-                               }
-
-rule_or_deprec :: { ([RdrNameRuleDecl], [RdrNameDeprecation]) }
-rule_or_deprec : pragma        { case $1 of
-                            POk _ (PRules   rules)   -> (rules,[])
-                            POk _ (PDeprecs deprecs) -> ([],deprecs)
-                            PFailed err -> pprPanic "Rules/Deprecations parse failed" err
+-- This production is lifted so that it doesn't get eagerly parsed when we
+-- use happy --strict.
+rules_and_deprecs_part :: { () -> ([RdrNameRuleDecl], IfaceDeprecs) }
+rules_and_deprecs_part
+  : {- empty -}                { \_ -> ([], Nothing) }
+  | src_loc PRAGMA     { \_ -> let exts = ExtFlags {glasgowExtsEF = True,
+                                                    parrEF        = True}
+                               in case parseRules $2 (mkPState $1 exts) of
+                                       POk _ rds   -> rds
+                                       PFailed err -> pprPanic "Rules/Deprecations parse failed" err
                        }
 
+rules_and_deprecs :: { ([RdrNameRuleDecl], IfaceDeprecs) }
+rules_and_deprecs : rule_prag deprec_prag      { ($1, $2) }
+
+
 -----------------------------------------------------------------------------
 
+rule_prag :: { [RdrNameRuleDecl] }
+rule_prag : {- empty -}                        { [] }
+         | '__R' rules                 { $2 }
+
 rules     :: { [RdrNameRuleDecl] }
           : {- empty -}        { [] }
           | rule ';' rules     { $1:$3 }
 
 rule      :: { RdrNameRuleDecl }
-rule      : src_loc STRING rule_forall qvar_name 
-            core_args '=' core_expr    { IfaceRule $2 $3 $4 $5 $7 $1 } 
+rule      : src_loc STRING activation rule_forall qvar_name 
+            core_args '=' core_expr    { IfaceRule $2 $3 $4 $5 $6 $8 $1 } 
+
+activation :: { Activation }
+activation : {- empty -}                { AlwaysActive }
+           | '[' INTEGER ']'            { ActiveAfter (fromInteger $2) }
+           | '[' '~' INTEGER ']'        { ActiveBefore (fromInteger $3) }
 
 rule_forall    :: { [UfBinder RdrName] }
 rule_forall    : '__forall' '{' core_bndrs '}' { $3 }
                  
 -----------------------------------------------------------------------------
 
-deprecs        :: { [RdrNameDeprecation] }
-deprecs                : {- empty -}           { [] }
-               | deprec ';' deprecs    { $1 : $3 }
+deprec_prag    :: { IfaceDeprecs }
+deprec_prag    : {- empty -}           { Nothing }
+               | '__D' deprecs         { Just $2 } 
 
-deprec         :: { RdrNameDeprecation }
-deprec         : src_loc STRING                { Deprecation (IEModuleContents undefined) $2 $1 }
-               | src_loc deprec_name STRING    { Deprecation $2 $3 $1 }
+deprecs        :: { Either DeprecTxt [(RdrName,DeprecTxt)] }
+deprecs                : STRING                { Left $1 }
+               | deprec_list           { Right $1 }
 
--- SUP: TEMPORARY HACK
-deprec_name    :: { RdrNameIE }
-               : var_name              { IEVar      $1 }
-               | data_name             { IEThingAbs $1 }
+deprec_list    :: { [(RdrName,DeprecTxt)] }
+deprec_list    : deprec                        { [$1] }
+               | deprec ';' deprec_list        { $1 : $3 }
+
+deprec         :: { (RdrName,DeprecTxt) }
+deprec         : deprec_name STRING    { ($1, $2) }
+
+deprec_name    :: { RdrName }
+               : qvar_name             { $1 }
+               | qtc_name              { $1 }
 
 -----------------------------------------------------------------------------
 
@@ -463,14 +481,14 @@ constrs1  :  constr               { [$1] }
                |  constr '|' constrs1  { $1 : $3 }
 
 constr         :: { RdrNameConDecl }
-constr         :  src_loc ex_stuff data_name batypes           { mk_con_decl $3 $2 (VanillaCon $4) $1 }
-               |  src_loc ex_stuff data_name '{' fields1 '}'   { mk_con_decl $3 $2 (RecCon $5)     $1 }
+constr         :  src_loc ex_stuff qdata_name batypes          { mk_con_decl $3 $2 (VanillaCon $4) $1 }
+               |  src_loc ex_stuff qdata_name '{' fields1 '}'  { mk_con_decl $3 $2 (RecCon $5)     $1 }
                 -- We use "data_fs" so as to include ()
 
 newtype_constr :: { [RdrNameConDecl] {- Not allowed to be empty -} }
-newtype_constr : src_loc '=' ex_stuff data_name atype  { [mk_con_decl $4 $3 (VanillaCon [Unbanged $5]) $1] }
-               | src_loc '=' ex_stuff data_name '{' var_name '::' atype '}'
-                                                       { [mk_con_decl $4 $3 (RecCon [([$6], Unbanged $8)]) $1] }
+newtype_constr : src_loc '=' ex_stuff qdata_name atype { [mk_con_decl $4 $3 (VanillaCon [unbangedType $5]) $1] }
+               | src_loc '=' ex_stuff qdata_name '{' qvar_name '::' atype '}'
+                                                       { [mk_con_decl $4 $3 (RecCon [([$6], unbangedType $8)]) $1] }
 
 ex_stuff :: { ([HsTyVarBndr RdrName], RdrNameContext) }
 ex_stuff       :                                       { ([],[]) }
@@ -481,30 +499,27 @@ batypes           :                                       { [] }
                |  batype batypes                       { $1 : $2 }
 
 batype         :: { RdrNameBangType }
-batype         :  atype                                { Unbanged $1 }
-               |  '!' atype                            { Banged   $2 }
-               |  '!' '!' atype                        { Unpacked $3 }
+batype         :  tatype                               { unbangedType $1 }
+               |  '!' tatype                           { BangType MarkedStrict    $2 }
+               |  '!' '!' tatype                       { BangType MarkedUnboxed   $3 }
 
 fields1                :: { [([RdrName], RdrNameBangType)] }
 fields1                : field                                 { [$1] }
                | field ',' fields1                     { $1 : $3 }
 
 field          :: { ([RdrName], RdrNameBangType) }
-field          :  var_names1 '::' type         { ($1, Unbanged $3) }
-               |  var_names1 '::' '!' type     { ($1, Banged   $4) }
-               |  var_names1 '::' '!' '!' type { ($1, Unpacked $5) }
+field          :  qvar_names1 '::' ttype               { ($1, unbangedType $3) }
+               |  qvar_names1 '::' '!' ttype           { ($1, BangType MarkedStrict    $4) }
+               |  qvar_names1 '::' '!' '!' ttype       { ($1, BangType MarkedUnboxed   $5) }
+
 --------------------------------------------------------------------------
 
 type           :: { RdrNameHsType }
-type           : '__fuall'  fuall '=>' type    { mkHsUsForAllTy $2 $4 }
-                | '__forall' tv_bndrs 
+type           : '__forall' tv_bndrs 
                        opt_context '=>' type   { mkHsForAllTy (Just $2) $3 $5 }
                | btype '->' type               { HsFunTy $1 $3 }
                | btype                         { $1 }
 
-fuall          :: { [RdrName] }
-fuall          : '[' uv_bndrs ']'                      { $2 }
-
 opt_context    :: { RdrNameContext }
 opt_context    :                                       { [] }
                | context                               { $1 }
@@ -518,8 +533,8 @@ context_list1       : class                                 { [$1] }
                | class ',' context_list1               { $1 : $3 }
 
 class          :: { HsPred RdrName }
-class          :  qcls_name atypes                     { (HsPClass $1 $2) }
-               |  ipvar_name '::' type                 { (HsPIParam $1 $3) }
+class          :  qcls_name atypes                     { (HsClassP $1 $2) }
+               |  ipvar_name '::' type                 { (HsIParam $1 $3) }
 
 types0         :: { [RdrNameHsType]                    {- Zero or more -}  }   
 types0         :  {- empty -}                          { [ ] }
@@ -533,20 +548,17 @@ types2            :  type ',' type                        { [$1,$3] }
 btype          :: { RdrNameHsType }
 btype          :  atype                                { $1 }
                |  btype atype                          { HsAppTy $1 $2 }
-                |  '__u' usage atype                   { HsUsgTy $2 $3 }
-
-usage          :: { HsUsageAnn RdrName }
-usage          : '-'                                   { HsUsOnce }
-               | '!'                                   { HsUsMany }
-               | uv_name                               { HsUsVar $1 }
 
 atype          :: { RdrNameHsType }
 atype          :  qtc_name                             { HsTyVar $1 }
                |  tv_name                              { HsTyVar $1 }
+               |  '.'                                  { hsUsOnce }
+               |  '!'                                  { hsUsMany }
                |  '(' ')'                              { HsTupleTy (mkHsTupCon tcName Boxed   []) [] }
                |  '(' types2 ')'                       { HsTupleTy (mkHsTupCon tcName Boxed   $2) $2 }
                |  '(#' types0 '#)'                     { HsTupleTy (mkHsTupCon tcName Unboxed $2) $2 }
                |  '[' type ']'                         { HsListTy  $2 }
+               |  '[:' type ':]'                       { HsPArrTy $2 }
                |  '{' qcls_name atypes '}'             { mkHsDictTy $2 $3 }
                |  '{' ipvar_name '::' type '}'         { mkHsIParamTy $2 $4 }
                |  '(' type ')'                         { $2 }
@@ -554,21 +566,48 @@ atype             :  qtc_name                             { HsTyVar $1 }
 atypes         :: { [RdrNameHsType]    {-  Zero or more -} }
 atypes         :                                       { [] }
                |  atype atypes                         { $1 : $2 }
+--------------------------------------------------------------------------
+
+-- versions of type/btype/atype that cant begin with '!' (or '.')
+-- for use where the kind is definitely known NOT to be '$'
+
+ttype          :: { RdrNameHsType }
+ttype          : '__forall' tv_bndrs 
+                       opt_context '=>' type           { mkHsForAllTy (Just $2) $3 $5 }
+               | tbtype '->' type                      { HsFunTy $1 $3 }
+               | tbtype                                { $1 }
+
+tbtype         :: { RdrNameHsType }
+tbtype         :  tatype                               { $1 }
+               |  tbtype atype                         { HsAppTy $1 $2 }
+
+tatype         :: { RdrNameHsType }
+tatype         :  qtc_name                             { HsTyVar $1 }
+               |  tv_name                              { HsTyVar $1 }
+               |  '(' ')'                              { HsTupleTy (mkHsTupCon tcName Boxed   []) [] }
+               |  '(' types2 ')'                       { HsTupleTy (mkHsTupCon tcName Boxed   $2) $2 }
+               |  '(#' types0 '#)'                     { HsTupleTy (mkHsTupCon tcName Unboxed $2) $2 }
+               |  '[' type ']'                         { HsListTy  $2 }
+               |  '[:' type ':]'                       { HsPArrTy $2 }
+               |  '{' qcls_name atypes '}'             { mkHsDictTy $2 $3 }
+               |  '{' ipvar_name '::' type '}'         { mkHsIParamTy $2 $4 }
+               |  '(' type ')'                         { $2 }
 ---------------------------------------------------------------------
+
 package                :: { PackageName }
                :  STRING               { $1 }
-               | {- empty -}           { opt_InPackage }       -- Useful for .hi-boot files,
-                                                               -- which can omit the package Id
-                                                               -- Module loops are always within a package
+               | {- empty -}           { opt_InPackage }
+                               -- Useful for .hi-boot files,
+                               -- which can omit the package Id
+                               -- Module loops are always within a package
 
 mod_name       :: { ModuleName }
-               :  CONID                { mkSysModuleFS $1 }
+               :  CONID                { mkSysModuleNameFS $1 }
 
 
 ---------------------------------------------------
-var_fs         :: { EncodedFS }
+var_fs          :: { EncodedFS }
                : VARID                 { $1 }
-               | '!'                   { SLIT("!") }
                | 'as'                  { SLIT("as") }
                | 'qualified'           { SLIT("qualified") }
                | 'hiding'              { SLIT("hiding") }
@@ -582,10 +621,6 @@ var_fs             :: { EncodedFS }
                | 'ccall'               { SLIT("ccall") }
                | 'stdcall'             { SLIT("stdcall") }
 
-qvar_fs                :: { (EncodedFS, EncodedFS) }
-               :  QVARID               { $1 }
-               |  QVARSYM              { $1 }
-
 var_occ                :: { OccName }
                :  var_fs               { mkSysOccFS varName $1 }
 
@@ -594,10 +629,15 @@ var_name  :  var_occ              { mkRdrUnqual $1 }
 
 qvar_name      :: { RdrName }
 qvar_name      :  var_name             { $1 }
-               |  qvar_fs              { mkSysQual varName $1 }
+               |  QVARID               { mkIfaceOrig varName $1 }
+
+ipvar_name     :: { IPName RdrName }
+               : IPDUPVARID            { Dupable (mkRdrUnqual (mkSysOccFS varName $1)) }
+               | IPSPLITVARID          { Linear  (mkRdrUnqual (mkSysOccFS varName $1)) }
 
-ipvar_name     :: { RdrName }
-               :  IPVARID              { mkSysUnqual ipName (tailFS $1) }
+qvar_names1    :: { [RdrName] }
+qvar_names1    : qvar_name             { [$1] }
+               | qvar_name qvar_names1 { $1 : $2 }
 
 var_names      :: { [RdrName] }
 var_names      :                       { [] }
@@ -607,81 +647,41 @@ var_names1        :: { [RdrName] }
 var_names1     : var_name var_names    { $1 : $2 }
 
 ---------------------------------------------------
--- For some bizarre reason, 
---      (,,,)      is dealt with by the parser
---      Foo.(,,,)  is dealt with by the lexer
--- Sigh
-
-data_fs                :: { EncodedFS }
-               :  CONID                { $1 }
-               |  CONSYM               { $1 }
-
-qdata_fs       :: { (EncodedFS, EncodedFS) }
-                :  QCONID              { $1 }
-                |  QCONSYM             { $1 }
 
 data_occ       :: { OccName }
-               :  data_fs              { mkSysOccFS dataName $1 }
-
-data_name      :: { RdrName }
-                :  data_occ             { mkRdrUnqual $1 }
+               :  CONID                { mkSysOccFS dataName $1 }
 
 qdata_name     :: { RdrName }
-qdata_name     :  data_name            { $1 }
-               |  qdata_fs             { mkSysQual dataName $1 }
+               :  data_occ             { mkRdrUnqual $1 }
+               |  QCONID               { mkIfaceOrig dataName $1 }
                                
-qdata_names    :: { [RdrName] }
-qdata_names    :                               { [] }
-               | qdata_name qdata_names        { $1 : $2 }
-
 var_or_data_name :: { RdrName }
-                  : var_name                    { $1 }
-                  | data_name                   { $1 }
+                  : qvar_name          { $1 }
+                  | qdata_name         { $1 }
 
 ---------------------------------------------------
-tc_fs           :: { EncodedFS }
-                :  data_fs              { $1 }
-
 tc_occ         :: { OccName }
-               :  tc_fs                { mkSysOccFS tcName $1 }
-
-tc_name                :: { RdrName }
-                :  tc_occ              { mkRdrUnqual $1 }
+               :  CONID                { mkSysOccFS tcName $1 }
 
 qtc_name       :: { RdrName }
-                : tc_name              { $1 }
-               | qdata_fs              { mkSysQual tcName $1 }
+                : tc_occ               { mkRdrUnqual $1 }
+               | QCONID                { mkIfaceOrig tcName $1 }
 
 ---------------------------------------------------
-cls_name       :: { RdrName }
-               :  data_fs              { mkSysUnqual clsName $1 }
-
 qcls_name      :: { RdrName }
-               : cls_name              { $1 }
-               | qdata_fs              { mkSysQual clsName $1 }
-
----------------------------------------------------
-uv_name                :: { RdrName }
-               :  VARID                { mkSysUnqual uvName $1 }
-
-uv_bndr                :: { RdrName }
-               :  uv_name              { $1 }
-
-uv_bndrs       :: { [RdrName] }
-               :                       { [] }
-               | uv_bndr uv_bndrs      { $1 : $2 }
+               : CONID                 { mkRdrUnqual (mkSysOccFS clsName $1) }
+               | QCONID                { mkIfaceOrig clsName $1 }
 
 ---------------------------------------------------
 tv_name                :: { RdrName }
-               :  VARID                { mkSysUnqual tvName $1 }
-               |  VARSYM               { mkSysUnqual tvName $1 {- Allow t2 as a tyvar -} }
+               :  var_fs               { mkRdrUnqual (mkSysOccFS tvName $1) }
 
 tv_bndr                :: { HsTyVarBndr RdrName }
                :  tv_name '::' akind   { IfaceTyVar $1 $3 }
-               |  tv_name              { IfaceTyVar $1 boxedTypeKind }
+               |  tv_name              { IfaceTyVar $1 liftedTypeKind }
 
 tv_bndrs       :: { [HsTyVarBndr RdrName] }
-tv_bndrs       : tv_bndrs1             { $1 }
+               : tv_bndrs1             { $1 }
                | '[' tv_bndrs1 ']'     { $2 }  -- Backward compatibility
 
 tv_bndrs1      :: { [HsTyVarBndr RdrName] }
@@ -711,38 +711,27 @@ kind              :: { Kind }
 
 akind          :: { Kind }
                : VARSYM                { if $1 == SLIT("*") then
-                                               boxedTypeKind
+                                               liftedTypeKind
                                          else if $1 == SLIT("?") then
                                                openTypeKind
-                                         else panic "ParseInterface: akind"
+                                         else if $1 == SLIT("\36") then
+                                                usageTypeKind  -- dollar
+                                          else panic "ParseInterface: akind"
                                        }
                | '(' kind ')'  { $2 }
 
 --------------------------------------------------------------------------
 
 id_info                :: { [HsIdInfo RdrName] }
-               :                               { [] }
+               : id_info_item                  { [$1] }
                | id_info_item id_info          { $1 : $2 }
 
 id_info_item   :: { HsIdInfo RdrName }
-               : '__A' INTEGER                 { HsArity (exactArity (fromInteger $2)) }
-               | '__U' inline_prag core_expr   { HsUnfold $2 $3 }
-               | '__M'                         { HsCprInfo }
-               | '__S'                         { HsStrictness (mkStrictnessInfo $1) }
+               : '__A' INTEGER                 { HsArity (fromInteger $2) }
+               | '__U' activation core_expr    { HsUnfold $2 $3 }
+               | '__S'                         { HsStrictness $1 }
                | '__C'                         { HsNoCafRefs }
-               | '__P' qvar_name               { HsWorker $2 }
-
-inline_prag     :: { InlinePragInfo }
-                :  {- empty -}                  { NoInlinePragInfo }
-               | '[' from_prag phase ']'       { IMustNotBeINLINEd $2 $3 }
-
-from_prag      :: { Bool }
-               : {- empty -}                   { True }
-               | '!'                           { False }
-
-phase          :: { Maybe Int }
-               : {- empty -}                   { Nothing }
-               | INTEGER                       { Just (fromInteger $1) }
+               | '__P' qvar_name INTEGER       { HsWorker $2 (fromInteger $3) }
 
 -------------------------------------------------------
 core_expr      :: { UfExpr RdrName }
@@ -790,12 +779,13 @@ core_aexpr      : qvar_name                                       { UfVar $1 }
                            { let
                                  (is_dyn, is_casm, may_gc) = $2
 
-                                target | is_dyn    = DynamicTarget (error "CCall dyn target bogus unique")
+                                target | is_dyn    = DynamicTarget
+                                       | is_casm   = CasmTarget $3
                                        | otherwise = StaticTarget $3
 
-                                ccall = CCall target is_casm may_gc cCallConv
+                                ccall = CCallSpec target CCallConv may_gc
                             in
-                            UfCCall ccall $4
+                            UfFCall (CCall ccall) $4
                           }
 
 
@@ -878,7 +868,7 @@ core_val_bndr       : var_name '::' atype                           { UfValBinder $1 $3 }
 
 core_tv_bndr   :: { UfBinder RdrName }
 core_tv_bndr   :  '@' tv_name '::' akind               { UfTyBinder $2 $4 }
-               |  '@' tv_name                          { UfTyBinder $2 boxedTypeKind }
+               |  '@' tv_name                          { UfTyBinder $2 liftedTypeKind }
 
 ccall_string   :: { FAST_STRING }
                : STRING                                        { $1 }
@@ -924,11 +914,5 @@ checkVersion :: { () }
 happyError :: P a
 happyError buf PState{ loc = loc } = PFailed (ifaceParseErr buf loc)
 
-data IfaceStuff = PIface       ParsedIface
-               | PIdInfo       [HsIdInfo RdrName]
-               | PType         RdrNameHsType
-               | PRules        [RdrNameRuleDecl]
-               | PDeprecs      [RdrNameDeprecation]
-
 mk_con_decl name (ex_tvs, ex_ctxt) details loc = mkConDecl name ex_tvs ex_ctxt details loc
 }