[GHC] #14932: DeriveAnyClass produces unjustifiably untouchable unification variables
#14932: DeriveAnyClass produces unjustifiably untouchable unification variables -------------------------------------+------------------------------------- Reporter: RyanGlScott | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.4.1 (Type checker) | Keywords: deriving | Operating System: Unknown/Multiple Architecture: | Type of failure: GHC rejects Unknown/Multiple | valid program Test Case: | Blocked By: Blocking: | Related Tickets: #13272 Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- The following code (courtesy of kosmikus) should typecheck, but does not: {{{#!hs {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} module Zero where import GHC.Exts class Zero a where zero :: a default zero :: (Code a ~ '[xs], All Zero xs) => a zero = undefined type family All c xs :: Constraint where All c '[] = () All c (x : xs) = (c x, All c xs) type family Code (a :: *) :: [[*]] type instance Code B1 = '[ '[ ] ] data B1 = B1 deriving Zero }}} This produces the following error: {{{ GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /nfs/nfs7/home/rgscott/.ghci [1 of 1] Compiling Zero ( Bug.hs, interpreted ) Bug.hs:23:11: error: • Couldn't match type ‘xs0’ with ‘'[]’ arising from the 'deriving' clause of a data type declaration ‘xs0’ is untouchable inside the constraints: All Zero xs0 bound by the deriving clause for ‘Zero B1’ at Bug.hs:23:11-14 • When deriving the instance for (Zero B1) | 23 | deriving Zero | ^^^^ }}} This error is baffling, however, because `xs0` should be a unification variable that readily unifies with `'[]`! As evidence, this typechecks: {{{ instance Zero B1 }}} But the equivalent `deriving` clause does not. I know what is going on here after some sleuthing: `DeriveAnyClass` (specifically, `inferConstraintsDAC`) is producing unification variables whose TcLevel is always bumped to three. However, in the program above, we will not form an implication constraints around those unification variables, since `zero` has no locally quantified type variables or given constraints. Thus, `simplifyDeriv` will try to simplify unification variables with TcLevel 3 at the top level, which results in them being untouchable. Blegh. This was partially noticed in #13272, when we were failing to bump unification variables that //did// appear inside implication constraints. However, we overlooked this one corner case, which kosmikus happened to stumble upon in a `generics-sop` [https://stackoverflow.com/a/49335338/1482749 example]. Patch incoming. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14932> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#14932: DeriveAnyClass produces unjustifiably untouchable unification variables -------------------------------------+------------------------------------- Reporter: RyanGlScott | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler (Type | Version: 8.4.1 checker) | Resolution: | Keywords: deriving Operating System: Unknown/Multiple | Architecture: Type of failure: GHC rejects | Unknown/Multiple valid program | Test Case: Blocked By: | Blocking: Related Tickets: #13272 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by RyanGlScott): Well, I do have a patch. But I also recently noticed the existence of #14933, which shares many similar characteristics with this issue, and now I'm wondering if perhaps I should clean up GHC's approach to `DeriveAnyClass` further to nail both bugs at once. Let me see how far I get... -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14932#comment:1> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#14932: DeriveAnyClass produces unjustifiably untouchable unification variables -------------------------------------+------------------------------------- Reporter: RyanGlScott | Owner: (none) Type: bug | Status: patch Priority: normal | Milestone: Component: Compiler (Type | Version: 8.4.1 checker) | Resolution: | Keywords: deriving Operating System: Unknown/Multiple | Architecture: Type of failure: GHC rejects | Unknown/Multiple valid program | Test Case: Blocked By: | Blocking: Related Tickets: #13272, #14933 | Differential Rev(s): Phab:D4507 Wiki Page: | -------------------------------------+------------------------------------- Changes (by RyanGlScott): * status: new => patch * differential: => Phab:D4507 * related: #13272 => #13272, #14933 -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14932#comment:2> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#14932: DeriveAnyClass produces unjustifiably untouchable unification variables -------------------------------------+------------------------------------- Reporter: RyanGlScott | Owner: (none) Type: bug | Status: patch Priority: normal | Milestone: Component: Compiler (Type | Version: 8.4.1 checker) | Resolution: | Keywords: deriving Operating System: Unknown/Multiple | Architecture: Type of failure: GHC rejects | Unknown/Multiple valid program | Test Case: Blocked By: | Blocking: Related Tickets: #13272, #14933 | Differential Rev(s): Phab:D4507 Wiki Page: | -------------------------------------+------------------------------------- Comment (by Ben Gamari <ben@…>): In [changeset:"9893042604cda5260cb0f7b674ed5c34b419e403/ghc" 9893042/ghc]: {{{ #!CommitTicketReference repository="ghc" revision="9893042604cda5260cb0f7b674ed5c34b419e403" Fix two pernicious bugs in DeriveAnyClass The way GHC was handling `DeriveAnyClass` was subtly wrong in two notable ways: * In `inferConstraintsDAC`, we were //always// bumping the `TcLevel` of newly created unification variables, under the assumption that we would always place those unification variables inside an implication constraint. But #14932 showed precisely the scenario where we had `DeriveAnyClass` //without// any of the generated constraints being used inside an implication, which made GHC incorrectly believe the unification variables were untouchable. * Even worse, we were using the generated unification variables from `inferConstraintsDAC` in every single iteration of `simplifyDeriv`. In #14933, however, we have a scenario where we fill in a unification variable with a skolem in one iteration, discard it, proceed on to another iteration, use the same unification variable (still filled in with the old skolem), and try to unify it with a //new// skolem! This results in an utter disaster. The root of both these problems is `inferConstraintsDAC`. This patch fixes the issue by no longer generating unification variables directly in `inferConstraintsDAC`. Instead, we store the original variables from a generic default type signature in `to_metas`, a new field of `ThetaOrigin`, and in each iteration of `simplifyDeriv`, we generate fresh meta tyvars (avoiding the second issue). Moreover, this allows us to more carefully fine-tune the `TcLevel` under which we create these meta tyvars, fixing the first issue. Test Plan: make test TEST="T14932 T14933" Reviewers: simonpj, bgamari Reviewed By: simonpj Subscribers: rwbarton, thomie, carter GHC Trac Issues: #14932, #14933 Differential Revision: https://phabricator.haskell.org/D4507 }}} -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14932#comment:3> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#14932: DeriveAnyClass produces unjustifiably untouchable unification variables -------------------------------------+------------------------------------- Reporter: RyanGlScott | Owner: (none) Type: bug | Status: patch Priority: normal | Milestone: 8.6.1 Component: Compiler (Type | Version: 8.4.1 checker) | Resolution: | Keywords: deriving Operating System: Unknown/Multiple | Architecture: Type of failure: GHC rejects | Unknown/Multiple valid program | Test Case: Blocked By: | Blocking: Related Tickets: #13272, #14933 | Differential Rev(s): Phab:D4507 Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * milestone: => 8.6.1 Comment: RyanGlScott, do you think this is `ghc-8.4` material? -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14932#comment:4> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#14932: DeriveAnyClass produces unjustifiably untouchable unification variables -------------------------------------+------------------------------------- Reporter: RyanGlScott | Owner: (none) Type: bug | Status: patch Priority: normal | Milestone: 8.6.1 Component: Compiler (Type | Version: 8.4.1 checker) | Resolution: | Keywords: deriving Operating System: Unknown/Multiple | Architecture: Type of failure: GHC rejects | Unknown/Multiple valid program | Test Case: Blocked By: | Blocking: Related Tickets: #13272, #14933 | Differential Rev(s): Phab:D4507 Wiki Page: | -------------------------------------+------------------------------------- Comment (by RyanGlScott): I'm biased, but I think so. I'm amazed `DeriveAnyClass` was working correctly at all before this patch! (Plus, the patch looks larger than it really is—at its core, it's quite small.) -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14932#comment:5> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#14932: DeriveAnyClass produces unjustifiably untouchable unification variables -------------------------------------+------------------------------------- Reporter: RyanGlScott | Owner: (none) Type: bug | Status: patch Priority: normal | Milestone: 8.6.1 Component: Compiler (Type | Version: 8.4.1 checker) | Resolution: | Keywords: deriving Operating System: Unknown/Multiple | Architecture: Type of failure: GHC rejects | Unknown/Multiple valid program | Test Case: Blocked By: | Blocking: Related Tickets: #13272, #14933 | Differential Rev(s): Phab:D4507 Wiki Page: | -------------------------------------+------------------------------------- Comment (by Simon Peyton Jones <simonpj@…>): In [changeset:"71d50db1f511d7aee32e6b429cdb912fcf6071b0/ghc" 71d50db/ghc]: {{{ #!CommitTicketReference repository="ghc" revision="71d50db1f511d7aee32e6b429cdb912fcf6071b0" Minor refactor and commments Minor refactor and comments, following Ryan's excellent DeriveAnyClass bug (Trac #14932) }}} -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14932#comment:6> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#14932: DeriveAnyClass produces unjustifiably untouchable unification variables -------------------------------------+------------------------------------- Reporter: RyanGlScott | Owner: (none) Type: bug | Status: merge Priority: normal | Milestone: 8.4.2 Component: Compiler (Type | Version: 8.4.1 checker) | Resolution: | Keywords: deriving Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: GHC rejects | Test Case: valid program | deriving/should_compile/T14932 Blocked By: | Blocking: Related Tickets: #13272, #14933 | Differential Rev(s): Phab:D4507 Wiki Page: | -------------------------------------+------------------------------------- Changes (by RyanGlScott): * status: patch => merge * testcase: => deriving/should_compile/T14932 * milestone: 8.6.1 => 8.4.2 -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14932#comment:7> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#14932: DeriveAnyClass produces unjustifiably untouchable unification variables -------------------------------------+------------------------------------- Reporter: RyanGlScott | Owner: (none) Type: bug | Status: closed Priority: normal | Milestone: 8.4.2 Component: Compiler (Type | Version: 8.4.1 checker) | Resolution: fixed | Keywords: deriving Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: GHC rejects | Test Case: valid program | deriving/should_compile/T14932 Blocked By: | Blocking: Related Tickets: #13272, #14933 | Differential Rev(s): Phab:D4507 Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * status: merge => closed * resolution: => fixed Comment: Merged to `ghc-8.4` with d8dbe2936c923471a13e214113b0e43222e95592. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14932#comment:8> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
participants (1)
-
GHC