Changes between Version 47 and Version 48 of Records/OverloadedRecordFields/Implementation


Ignore:
Timestamp:
Aug 21, 2013 1:44:50 PM (8 months ago)
Author:
adamgundry
Comment:

new instance generation story

Legend:

Unmodified
Added
Removed
Modified
  • Records/OverloadedRecordFields/Implementation

    v47 v48  
    3535{{{ 
    3636data FieldLbl a = FieldLabel { 
    37       flOccName   :: OccName,           -- ^ Label of the field 
    38       flSelector  :: a,                 -- ^ Record selector function 
    39       flInstances :: Maybe (FldInsts a) -- ^ Instances for overloading 
     37      flOccName   :: OccName,   -- ^ Label of the field 
     38      flSelector  :: a,         -- ^ Record selector function 
     39      flInstances :: FldInsts a -- ^ Instances for overloading 
    4040    } 
    4141 
     
    4848}}} 
    4949 
    50 Every field has a label (`OccName`) and selector. If it is defined in a module with `-XOverloadedRecordFields` enabled, it also has names for the instances.  
     50Every field has a label (`OccName`), selector, and names for the typeclass and family instances (currently stored together in the `FldInsts` record, but this could change). 
    5151 
    5252The `AvailTC Name [Name] [FieldLabel]` constructor of `AvailInfo` represents a type and its pieces that are in scope. Record fields are now stored in a separate list (the third argument). The `IEThingWith name [name] [OccName]` constructor of `IE`, which represents a thing that can be imported or exported, stores only the `OccName`s. 
     
    5555 
    5656{{{ 
    57 x |->  GRE $sel_x_T (FldParent T x (Just (FldInsts $dfHasTx $dfUpdTx TFCo:R:GetResultTx TFCo:R:SetResultTx))) LocalDef 
     57x |->  GRE $sel_x_T (FldParent T x (FldInsts $dfHasTx $dfUpdTx TFCo:R:GetResultTx TFCo:R:SetResultTx)) LocalDef 
    5858}}} 
    5959 
     
    100100== Automatic instance generation == 
    101101 
    102 Typeclass and family instances are generated, provided the extension is enabled, by `makeLocalRecFldInsts` and `makeImportedRecFldInsts` in `TcInstDecls`. These functions correspond to the two places in which instances are generated: 
    103  
    104 * `tcInstDecls1` generates instances for fields from datatypes in the current group (at the same time as derived instances, from '''deriving''' clauses, are generated) 
    105  
    106 * `tcRnImports` in `TcRnDriver` generates instances for overladed record fields ''that are in scope''. (This is different from the usual visible-everywhere story for instances.) We know which overloaded fields are in scope by looking at the `GlobalRdrEnv` 
    107  
    108 The typeclass instances must be subsequently typechecked (by `tcInstDecls2`). Such instances are "private" in that they are available when typechecking the current module (in `tcg_inst_env`) but not exported to other modules (via `tcg_insts`). On the other hand, the underlying dfun ids, axioms and family instances are exported from the module as usual. 
     102Typeclass and family instances are generated by `addLocalRecFldInsts` in `TcInstDecls`, regardless of whether or not the extension is enabled. This is called by `tcInstDecls1` to generate instances for fields from datatypes in the current group (at the same time as derived instances, from '''deriving''' clauses, are generated). The typeclass instances must be subsequently typechecked (by `tcInstDecls2`). Such instances are "private" in that they are available when typechecking the current module (in `tcg_inst_env`) but not exported to other modules (via `tcg_insts`). On the other hand, the underlying dfun ids and axioms are exported from the module as usual. 
    109103 
    110104'''AMG''' This means that typeclass instances are not visible in GHCi, because it tracks only `tcg_insts` (via the `InteractiveContext`). What to do here? Perhaps a new field in `TcGblEnv` could record the private instances? 
    111105 
    112 For each imported field, there are two possible cases: 
    113  
    114 1. If the module containing the field was compiled with `-XOverloadedRecordFields`, it will have the necessary dfuns already, so we can just look them up and add appropriate class instances to `tcg_inst_env`. Moreover, the family instances will have been imported. 
    115 2. Otherwise, all the instances must be generated, as if the field were locally defined. 
    116  
    117 '''AMG''' Modules in `base` that are compiled before `GHC.Records` cannot have the instances created. This is the motivation for restricting dfun and family instance generation to modules with the extension enabled. It occurs to me that we could have a separate extension for generating the instances (`-XOverloadedRecordFieldInstances`, perhaps) that could be enabled by default (except for `base`). This would reduce the number of fields for which `-XOverloadedRecordFields` modules would have to generate instances on the fly. On the other hand, it would increase the amount of stuff in interface files. 
     106Moreover, `tcRnImports` calls `addImportedRecFldInsts` to add instances for overloaded record fields ''that are in scope'' from other modules. (This is different from the usual visible-everywhere story for instances.) We know which overloaded fields are in scope by looking at the `GlobalRdrEnv`. Since the dfuns and axioms are available, it is easy to turn them into appropriate `ClsInst`s and `FamInst`s.  
     107 
     108'''AMG''' This is the general idea, but there are some bugs left to iron out: 
     109 
     110* `tcIfaceGlobal` gives "not found" errors when compiling `TyCon.hs` for the stage 2 compiler. I think this might be something to do with the cycle with `Class.hs`. 
     111* `addPrivateTyFamInsts` leads to fingerprinting errors, presumably because exporting an axiom without its family instance is not handled correctly. 
     112* When the extension is disabled, the instances are still generated and typechecked, and they must be in scope (via `addPrivateClsInsts`/`addPrivateTyFamInsts`) while they are being typechecked. This means `tcInstDecls1` and `2` need some refactoring. 
    118113 
    119114 
     
    273268== To do == 
    274269 
    275 * Put `(r ~ SetResult r f (GetResult r f))` in superclasses of `Upd`, not `Has`.  And Note to explain what it is doing 
    276 * Add Note to explain why `GetR` and `SetR` are not associated types (NB: it’d be possible for associated types to have type parameters that are an *instance of* the class header.  Feature request!) 
    277 * With fundep in class, I think we don’t need it in the instance.  Check this. 
    278 * Generate dfuns unconditionally; *use* them when `OverloadedFields` is on.  Make sure `GHC.Records` is compiled before any base module that has a record field.  (Maybe move `TypeLits.Symbol` to an earlier module eg `GHC.Base`.) 
    279 * Add axioms to `tcg_type_env` but not `tcg_fam_inst_env` 
    280 * Always mangle selector names (for simplicity) 
     270* It'd be possible for associated types to have type parameters that are an *instance of* the class header.  Feature request! 
     271* With fundep in class, we don't need it in the instance. 
     272* Always mangle selector names (for simplicity)? 
    281273  * Sort out impedance mismatch with boot files, if easy or enough people care 
    282274  * Check import/export behaviour