86 | | * If the declaration of `T` mentions another type constructor `S` and we have `tyConCC S == NoCC`, we do not convert `T` and set its `tyConCC` field to `NoCC` as well. |
87 | | * If all type constructors `S` that are mentioned in `T`'s definiton have `tyConCC S == ConvCC S`, we do not convert `T` and set its `tyConCC` field to `ConvCC (T, isoT)` generating a suitable conversion constructor `isoT`. (NB: This implies that `T` does not mention any function arrows.) |
88 | | * If the declaration of `T` uses any features that we cannot (or for the moment, don't want to) convert, we do not convert `T` and set its `tyConCC` field to `NoCC`. |
89 | | * Otherwise, we generate a converted type declaration `T_CC` together a conversion constructor `isoT`, and set `tyConCC` to `ConvCC (T_CC, isoT)`. |
| 86 | 1. If the declaration of `T` mentions another algebraic type constructor `S` with `tyConCC S == NoCC`, we cannot convert `T` and set its `tyConCC` field to `NoCC` as well. |
| 87 | 2. If '''all''' algebraic type constructors `S` that are mentioned in `T`'s definiton have `tyConCC S == ConvCC S`, we do not convert `T` and set its `tyConCC` field to `ConvCC (T, isoT)` generating a suitable conversion constructor `isoT`. (NB: The condition implies that `T` does not mention any function arrows.) |
| 88 | 3. If the declaration of `T` uses any features that we cannot (or for the moment, don't want to) convert, we set its `tyConCC` field to `NoCC` - except if Case 2 applies. |
| 89 | 4. Otherwise, we generate a converted type declaration `T_CC` together a conversion constructor `isoT`, and set `tyConCC` to `ConvCC (T_CC, isoT)`. Conversion proceeds by converting all data constructors (including their workers and wrappers), and in particular, we need to convert all types in the constructor signatures by replacing all type constructors that have conversions by their converted variant. Data constructors get a new field `dcCC :: StatusCC DataCon`. |
| 90 | Moreover, we handle other forms of type constructors as follows: |
| 91 | * `FunTyCon`: It's `StatusCC` value was defined above. We handle any occurence of the function type constructor like that of an algabraic type constructor with the `StatusCC` value given above, but we may not want to explcitly store that value in a field of `FunTyCon`, as `(:->)` would then probably need to go into `TyWiredIn` in. |
| 92 | * `TupleTyCon`: The `StatusCC` value of a tuple constructor `T` is `ConvCC (T, isoT)`, where `isoT` is a suitable conversion function; i.e., we don't need converted tuple type constructors, but we need to define conversions for all supported tuple types somewhere. Unfortunately, there are many tuple types, and hence, many conversion functions. An alternative might be to special case tuples during conversion generation and just inline the needed case construct. |
| 93 | * `SynTyCon`: Closure conversion operates on `coreView`; hence, we will see no synonyms. (Well, we may see synonym families, but will treat them as not convertible for the moment.) |
| 94 | * `PrimTyCon`: We essentially ignore primitive types during conversion. We assume their converted and unconverted form are identical, which implies that they never inhibit conversion and that they need no conversion constructors. |
| 95 | * `CoercionTyCon` and `SuperKindTyCon`: They don't categorise values and are ignored during conversion. |
| 96 | |
| 97 | For example, when we process |
| 98 | {{{ |
| 99 | data Int = I# Int# |
| 100 | }}} |
| 101 | |
| 102 | |