Improve error messages for record updates that don't typecheck
We now typecheck record updates by desugaring the record update to a case expression (MR !7981 (merged)). However, this can mean some of the error messages aren't particularly clear about the source of the error.
Example 1
{-# LANGUAGE GADTs #-}
data E where
MkE :: Show e => { ex :: e } -> E
ex_upd r = r { ex = undefined }
* Could not deduce (Show e0)
from the context: Show e
bound by a pattern with constructor:
MkE :: forall e. Show e => e -> E,
in a case alternative
at testsuite\tests\typecheck\should_fail\T3323b.hs:11:12-31
The type variable `e0' is ambiguous
Potentially matching instances:
instance Show Ordering -- Defined in `GHC.Show'
instance Show a => Show (Maybe a) -- Defined in `GHC.Show'
...plus 25 others
...plus 12 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
* In a record update at field `ex',
with type constructor `E',
data constructor `MkE'
and existential variable `e'.
Example 2
{-# LANGUAGE TypeFamilies #-}
type family F a
data D a b =
MkD { fld1 :: a -> b
, fld2 :: F a -> F b }
d :: D z z
d = MkD { fld1 = id, fld2 = id }
foo _ = d { fld1 = id }
* Could not deduce (F z0 ~ F b)
from the context: F z ~ F b
bound by the inferred type for `foo':
forall {z} {b} {p}. (F z ~ F b) => p -> D b b
at testsuite\tests\typecheck\should_fail\T3323b.hs:15:1-23
NB: `F' is a non-injective type family
The type variable `z0' is ambiguous
* In the ambiguity check for the inferred type for `foo'
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
When checking the inferred type
foo :: forall {z} {b} {p}. (F z ~ F b) => p -> D b b
|
15 | foo _ = d { fld1 = id }
| ^^^^^^^^^^^^^^^^^^^^^^^
This error message doesn't even mention anything about a record update, which isn't great.
Ideas
One difficulty with reporting good error messages in this area is that we'd like to tag the generated code as having a certain origin, so that constraints emitted when typechecking the generated code would be tagged with "In the record update...". This would also allow better error messages, as CtOrigin
s are reported after constraint solving, so we can print the actual types that caused an issue, rather than using addErrCtxt
where we have to provide the full message then-and-there.