[GHC] #15814: Orphan Instance Overlap Error Message

#15814: Orphan Instance Overlap Error Message -------------------------------------+------------------------------------- Reporter: parsonsmatt | Owner: (none) Type: feature | Status: new request | Priority: normal | Milestone: Component: Compiler | Version: 8.4.3 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- I'm working on moving some code around which unfortunately relies on orphan instances. This is the error I get: {{{ /home/matt/Projects/cardano-sl/wallet- new/src/Cardano/Wallet/API/V1/Types.hs:1794:27: error: • Overlapping instances for Arbitrary (NonEmpty PaymentDistribution) arising from a use of ‘arbitrary’ Matching instances: instance Arbitrary a => Arbitrary (NonEmpty a) -- Defined in ‘Pos.Util.Example’ instance [safe] Arbitrary a => Arbitrary (NonEmpty a) -- Defined in ‘quickcheck- instances-0.3.18:Test.QuickCheck.Instances.Semigroup’ • In the second argument of ‘(<*>)’, namely ‘arbitrary’ In the first argument of ‘(<*>)’, namely ‘Payment <$> arbitrary <*> arbitrary’ In the first argument of ‘(<*>)’, namely ‘Payment <$> arbitrary <*> arbitrary <*> arbitrary’ | 1794 | <*> arbitrary | ^^^^^^^^^ }}} The first instance is the one that I have defined. The second is defined in library code upstream -- great! I want to use that one instead. However, I don't have a clue which module import is providing that instance. It would be *fantastic* if there was an additional line that says which module imported the instance, or brought it into scope. Multiple modules might do this; in this case, reporting any of them would be fine. Eg: {{{ /home/matt/Projects/cardano-sl/wallet- new/src/Cardano/Wallet/API/V1/Types.hs:1794:27: error: • Overlapping instances for Arbitrary (NonEmpty PaymentDistribution) arising from a use of ‘arbitrary’ Matching instances: instance Arbitrary a => Arbitrary (NonEmpty a) -- Defined in ‘Pos.Util.Example’ -- and imported via | 186 | import Cardano.Wallet.API.V1.Swagger.Example | instance [safe] Arbitrary a => Arbitrary (NonEmpty a) -- Defined in ‘quickcheck- instances-0.3.18:Test.QuickCheck.Instances.Semigroup’ -- and imported via | ??? | this information would literally make my day | • In the second argument of ‘(<*>)’, namely ‘arbitrary’ In the first argument of ‘(<*>)’, namely ‘Payment <$> arbitrary <*> arbitrary’ In the first argument of ‘(<*>)’, namely ‘Payment <$> arbitrary <*> arbitrary <*> arbitrary’ | 1794 | <*> arbitrary | ^^^^^^^^^ }}} I'll have to binary search the import list to try and figure out which module is bringing the instance into scope otherwise. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15814 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15814: Orphan Instance Overlap Error Message -------------------------------------+------------------------------------- Reporter: parsonsmatt | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.4.3 Resolution: | Keywords: newcomer Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by RyanGlScott): * keywords: => newcomer Comment: Good idea. I don't think this would be that hard to do, given that we do something similar for other errors already. Here is an example of an ambiguous name occurrence error message (taken from the `tcfail037` test case): {{{ tcfail037.hs:7:11: error: Ambiguous occurrence ‘+’ It could refer to either ‘Prelude.+’, imported from ‘Prelude’ at tcfail037.hs:3:8-17 (and originally defined in ‘GHC.Num’) or ‘ShouldFail.+’, defined at tcfail037.hs:10:5 }}} That "and originally defined in ..." part is exactly what we need. The code for this error message can be found [http://git.haskell.org/ghc.git/blob/23956b2ada690c78a134fe6d149940c777c7efcc... here], in `ppr_defn_site`. We'd just need to incorporate similar logic to the function [http://git.haskell.org/ghc.git/blob/23956b2ada690c78a134fe6d149940c777c7efcc... here] which constructs error messages for overlapping instances. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15814#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15814: Orphan Instance Overlap Error Message -------------------------------------+------------------------------------- Reporter: parsonsmatt | Owner: (none) Type: feature request | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 8.4.3 Resolution: | Keywords: newcomer Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): D5377 Wiki Page: | -------------------------------------+------------------------------------- Changes (by dminuoso): * status: new => patch * differential: => D5377 Comment: I put up a differential to include the requested feature. The current limitation is that import provenance can only be displayed if either the instances were defined in orphan modules or in the same module you imported it from. That should be sufficient for most cases though. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15814#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15814: Orphan Instance Overlap Error Message -------------------------------------+------------------------------------- Reporter: parsonsmatt | Owner: (none) Type: feature request | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 8.4.3 Resolution: | Keywords: newcomer Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D5377 Wiki Page: | -------------------------------------+------------------------------------- Changes (by dminuoso): * differential: D5377 => Phab:D5377 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15814#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15814: Orphan Instance Overlap Error Message -------------------------------------+------------------------------------- Reporter: parsonsmatt | Owner: (none) Type: feature request | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 8.4.3 Resolution: | Keywords: newcomer Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D5377 Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): Thanks for working on this. Indeed, a careful `Note` to explain how it works, and some more type signatures on local definitions, would be helpful. I could not understand the code. I think your idea is something like this, supposing we are compiling module M, and are reporting an instance whose dictionary function is `$df`. * Given a `$df` we know the module D in which it is defined, via `nameModule`. * If that module D is * M itself, or * one of the module that M directly imports * an orphan module we can report how `$df` came to be in scope. * Those three cases are easy because we have that info to hand in the `TcGblEnv`. You code looks a bit complicated if I'm right, but maybe I'm missing something. I also wonder about doing the full job, when `$df` is in scope indirectly. After all, that's the situation in which the user is going to be most puzzled! What we want is to ask * For each `import B`, does `B` transitively import `D`? And that info is also conveniently available, in the `mi_deps` field of each `ModIface`. So it should be easy to do to full job, no exceptions. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15814#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15814: Orphan Instance Overlap Error Message -------------------------------------+------------------------------------- Reporter: parsonsmatt | Owner: (none) Type: feature request | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 8.4.3 Resolution: | Keywords: newcomer Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D5377 Wiki Page: | -------------------------------------+------------------------------------- Comment (by dminuoso): `- an orphan module we can report how $df came to be in scope.` You need a transitive closure of depended upon orphan modules and finally some `[ImportedBy]` for each such module. We cannot recover that information from TcGblEnv currently. My code already takes your suggested second approach, but it can't do a full job because the record `mi_deps :: Dependencies` has no field containing the full transitive closure of depended upon modules. It only contains that information for orphan modules. I hope the changes I pushed make my code a bit clearer. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15814#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15814: Orphan Instance Overlap Error Message -------------------------------------+------------------------------------- Reporter: parsonsmatt | Owner: (none) Type: feature request | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 8.4.3 Resolution: | Keywords: newcomer Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D5377 Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): I've added more comments to the diff. (`mi_deps` includes more than you think!) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15814#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC