Skip to content

GitLab

  • Menu
Projects Groups Snippets
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,869
    • Issues 4,869
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 456
    • Merge requests 456
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #21655
Closed
Open
Created May 26, 2022 by sheaf@sheafMaintainer

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 CtOrigins 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.

Edited May 26, 2022 by sheaf
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking