Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
GHC
GHC
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,262
    • Issues 4,262
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
    • Iterations
  • Merge Requests 404
    • Merge Requests 404
  • Requirements
    • Requirements
    • List
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
  • Security & Compliance
    • Security & Compliance
    • Dependency List
    • License Compliance
  • Operations
    • Operations
    • Incidents
    • Environments
  • Analytics
    • Analytics
    • CI / CD
    • Code Review
    • Insights
    • Issue
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #15678

Closed
Open
Opened Sep 26, 2018 by Ryan Scott@RyanGlScottMaintainer

Provide the provenance of unification variables in error messages when possible

Consider the following code:

module Foo where

x :: Int
x = const 42 _

When compiles, this gives the following suggestion:

$ /opt/ghc/8.6.1/bin/ghc Bug.hs
[1 of 1] Compiling Foo              ( Bug.hs, Bug.o )

Bug.hs:4:14: error:
    • Found hole: _ :: b0
      Where: ‘b0’ is an ambiguous type variable
    • In the second argument of ‘const’, namely ‘_’
      In the expression: const 42 _
      In an equation for ‘x’: x = const 42 _
    • Relevant bindings include x :: Int (bound at Bug.hs:4:1)
      Valid hole fits include
        x :: Int (bound at Bug.hs:4:1)
        otherwise :: Bool
          (imported from ‘Prelude’ at Bug.hs:1:8-10
           (and originally defined in ‘GHC.Base’))
        False :: Bool
          (imported from ‘Prelude’ at Bug.hs:1:8-10
           (and originally defined in ‘GHC.Types’))
        True :: Bool
          (imported from ‘Prelude’ at Bug.hs:1:8-10
           (and originally defined in ‘GHC.Types’))
        lines :: String -> [String]
          (imported from ‘Prelude’ at Bug.hs:1:8-10
           (and originally defined in ‘base-4.12.0.0:Data.OldList’))
        unlines :: [String] -> String
          (imported from ‘Prelude’ at Bug.hs:1:8-10
           (and originally defined in ‘base-4.12.0.0:Data.OldList’))
        (Some hole fits suppressed; use -fmax-valid-hole-fits=N or -fno-max-valid-hole-fits)
  |
4 | x = const 42 _
  |              ^

One thing that's rather ugly about this is the use of the type b0. What exactly //is// b0 anyway? The only hint that the error message gives is that it's an ambiguous type variable. But that's not terribly helpful to figure out where b0 arises from. Ambiguous type variables like this one arise quite frequently when writing Haskell code, and it can often take some sleuthing to figure out why they pop up.

simonpj had one suggestion for making ambiguous type variables less confusing: report their provenance whenever possible. There is one notable example of a situation where it's simple to explain from where exactly in the source code a unification variable originates: function applications. In particular, the program above applies the function const 42 to _, which means that the type of const 42 is instantiated to be b0 -> Int. Let's report this! Something like:

    • Found hole: _ :: b0
      Where: ‘b0’ is an ambiguous type variable
             Arising from an application of
               (const 42 :: b0 -> Int)
             In the expression: const 42 _

This would go a long way to clearing up what GHC is thinking when it reports these ambiguous type variable errors. While we can't easily report the provenance of //every// ambiguous type variables, those arising from function applications are quite doable. We might be able to reuse the CtOrigin machinery (or take heavy inspiration from it) to accomplish this feat.

Trac metadata
Trac field Value
Version 8.6.1
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler (Type checker)
Test case
Differential revisions
BlockedBy
Related
Blocking
CC Tritlo
Operating system
Architecture
Assignee
Assign to
9.0.1
Milestone
9.0.1 (Past due)
Assign milestone
Time tracking
None
Due date
None
Reference: ghc/ghc#15678