Instantiate field types properly in stock-derived instances
Previously, the `deriving` machinery was very loosey-goosey about how it used the types of data constructor fields when generating code. It would usually just consult `dataConOrigArgTys`, which returns the _uninstantiated_ field types of each data constructor. Usually, you can get away with this, but issues #20375 and #20387 revealed circumstances where this approach fails. Instead, when generated code for a stock-derived instance `C (T arg_1 ... arg_n)`, one must take care to instantiate the field types of each data constructor with `arg_1 ... arg_n`. The particulars of how this is accomplished is described in the new `Note [Instantiating field types in stock deriving]` in `GHC.Tc.Deriv.Generate`. Some highlights: * `DerivInstTys` now has a new `dit_dc_inst_arg_env :: DataConEnv [Type]` field that caches the instantiated field types of each data constructor. Whenever we need to consult the field types somewhere in `GHC.Tc.Deriv.*` we avoid using `dataConOrigArgTys` and instead look it up in `dit_dc_inst_arg_env`. * Because `DerivInstTys` now stores the instantiated field types of each constructor, some of the details of the `GHC.Tc.Deriv.Generics.mkBindsRep` function were able to be simplified. In particular, we no longer need to apply a substitution to instantiate the field types in a `Rep(1)` instance, as that is already done for us by `DerivInstTys`. We still need a substitution to implement the "wrinkle" section of `Note [Generating a correctly typed Rep instance]`, but the code is nevertheless much simpler than before. * The `tyConInstArgTys` function has been removed in favor of the new `GHC.Core.DataCon.dataConInstUnivs` function, which is really the proper tool for the job. `dataConInstUnivs` is much like `tyConInstArgTys` except that it takes a data constructor, not a type constructor, as an argument, and it adds extra universal type variables from that data constructor at the end of the returned list if need be. `dataConInstUnivs` takes care to instantiate the kinds of the universal type variables at the end, thereby avoiding a bug in `tyConInstArgTys` discovered in #20387 (comment 377037). Fixes #20375. Fixes #20387.
Showing
- compiler/GHC/Core/DataCon.hs 56 additions, 0 deletionscompiler/GHC/Core/DataCon.hs
- compiler/GHC/Tc/Deriv.hs 15 additions, 17 deletionscompiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Deriv/Functor.hs 15 additions, 15 deletionscompiler/GHC/Tc/Deriv/Functor.hs
- compiler/GHC/Tc/Deriv/Generate.hs 169 additions, 43 deletionscompiler/GHC/Tc/Deriv/Generate.hs
- compiler/GHC/Tc/Deriv/Generics.hs 70 additions, 90 deletionscompiler/GHC/Tc/Deriv/Generics.hs
- compiler/GHC/Tc/Deriv/Infer.hs 32 additions, 41 deletionscompiler/GHC/Tc/Deriv/Infer.hs
- compiler/GHC/Tc/Deriv/Utils.hs 43 additions, 38 deletionscompiler/GHC/Tc/Deriv/Utils.hs
- testsuite/tests/deriving/should_compile/T20375.hs 40 additions, 0 deletionstestsuite/tests/deriving/should_compile/T20375.hs
- testsuite/tests/deriving/should_compile/T20387.hs 13 additions, 0 deletionstestsuite/tests/deriving/should_compile/T20387.hs
- testsuite/tests/deriving/should_compile/all.T 2 additions, 0 deletionstestsuite/tests/deriving/should_compile/all.T
- testsuite/tests/typecheck/should_fail/T15883b.stderr 16 additions, 5 deletionstestsuite/tests/typecheck/should_fail/T15883b.stderr
- testsuite/tests/typecheck/should_fail/T15883c.stderr 41 additions, 5 deletionstestsuite/tests/typecheck/should_fail/T15883c.stderr
- testsuite/tests/typecheck/should_fail/T15883d.stderr 19 additions, 6 deletionstestsuite/tests/typecheck/should_fail/T15883d.stderr
- testsuite/tests/typecheck/should_fail/T15883e.stderr 68 additions, 6 deletionstestsuite/tests/typecheck/should_fail/T15883e.stderr
Loading
Please register or sign in to comment