Forked from
Glasgow Haskell Compiler / GHC
Source project has a limited visibility.
-
GHC used to reject programs of this form: ``` newtype Age = MkAge Int deriving Eq via Const Int a ``` That's because an earlier implementation of `DerivingVia` would generate the following instance: ``` instance Eq Age where (==) = coerce @(Const Int a -> Const Int a -> Bool) @(Age -> Age -> Bool) (==) ``` Note that the `a` in `Const Int a` is not bound anywhere, which causes all sorts of issues. I figured that no one would ever want to write code like this anyway, so I simply banned "floating" `via` type variables like `a`, checking for their presence in the aptly named `reportFloatingViaTvs` function. `reportFloatingViaTvs` ended up being implemented in a subtly incorrect way, as #15831 demonstrates. Following counsel with the sage of gold fire, I decided to abandon `reportFloatingViaTvs` entirely and opt for a different approach that would _accept_ the instance above. This is because GHC now generates this instance instead: ``` instance forall a. Eq Age where (==) = coerce @(Const Int a -> Const Int a -> Bool) @(Age -> Age -> Bool) (==) ``` Notice that we now explicitly quantify the `a` in `instance forall a. Eq Age`, so everything is peachy scoping-wise. See `Note [Floating `via` type variables]` in `TcDeriv` for the full scoop. A pleasant benefit of this refactoring is that it made it much easier to catch the problem observed in #16181, so this patch fixes that issue too. Fixes #15831. Fixes #16181.
GHC used to reject programs of this form: ``` newtype Age = MkAge Int deriving Eq via Const Int a ``` That's because an earlier implementation of `DerivingVia` would generate the following instance: ``` instance Eq Age where (==) = coerce @(Const Int a -> Const Int a -> Bool) @(Age -> Age -> Bool) (==) ``` Note that the `a` in `Const Int a` is not bound anywhere, which causes all sorts of issues. I figured that no one would ever want to write code like this anyway, so I simply banned "floating" `via` type variables like `a`, checking for their presence in the aptly named `reportFloatingViaTvs` function. `reportFloatingViaTvs` ended up being implemented in a subtly incorrect way, as #15831 demonstrates. Following counsel with the sage of gold fire, I decided to abandon `reportFloatingViaTvs` entirely and opt for a different approach that would _accept_ the instance above. This is because GHC now generates this instance instead: ``` instance forall a. Eq Age where (==) = coerce @(Const Int a -> Const Int a -> Bool) @(Age -> Age -> Bool) (==) ``` Notice that we now explicitly quantify the `a` in `instance forall a. Eq Age`, so everything is peachy scoping-wise. See `Note [Floating `via` type variables]` in `TcDeriv` for the full scoop. A pleasant benefit of this refactoring is that it made it much easier to catch the problem observed in #16181, so this patch fixes that issue too. Fixes #15831. Fixes #16181.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.