Admin message

Due to a large amount of spam we do not allow new users to create repositories, they are "external" users. If you are a new user and want to create a repository, for example for forking GHC, open a new issue on ghc/ghc using the "get-verified" issue template

Generic1 deriving should use more coercions
Consider ```hs newtype Foo a = Foo (Maybe [a]) deriving (Generic1) ``` This produces some rather unsatisfactory Core: ``` -- to1 worker Travv.$fGeneric1Foo1 :: forall a. Rep1 Foo a -> Maybe [a] Travv.$fGeneric1Foo1 = \ (@ a_a7RL) (ds_d9dZ :: Rep1 Foo a_a7RL) -> case ds_d9dZ `cast` <Co:103> of { Nothing -> GHC.Maybe.Nothing @ [a_a7RL]; Just a1_a9fD -> GHC.Maybe.Just @ [a_a7RL] (a1_a9fD `cast` <Co:5>) } -- from1 worker Travv.$fGeneric1Foo2 :: forall a. Foo a -> Maybe (Rec1 [] a) Travv.$fGeneric1Foo2 = \ (@ a_a7R6) (x_a7GJ :: Foo a_a7R6) -> case x_a7GJ `cast` <Co:2> of { Nothing -> GHC.Maybe.Nothing @ (Rec1 [] a_a7R6); Just a1_a9fD -> GHC.Maybe.Just @ (Rec1 [] a_a7R6) (a1_a9fD `cast` <Co:6>) } ``` Both of these functions could be implemented as safe coercions, but neither of them is! Similarly, if I define ```hs data Bar a = Bar (Maybe [a]) deriving Generic1 ``` I get a `to1` worker that looks like ``` Travv.$fGeneric1Bar_$cto1 :: forall a. Rep1 Bar a -> Bar a Travv.$fGeneric1Bar_$cto1 = \ (@ a_a7UA) (ds_d9ho :: Rep1 Bar a_a7UA) -> Travv.Bar @ a_a7UA (case ds_d9ho `cast` <Co:103> of { Nothing -> GHC.Maybe.Nothing @ [a_a7UA]; Just a1_a9iK -> GHC.Maybe.Just @ [a_a7UA] (a1_a9iK `cast` <Co:5>) }) ``` That `case` expression should really just be a cast. I think the basic trick is probably to inspect the role of the type argument of each type in a composition, using that to work out whether to coerce that step. <details><summary>Trac metadata</summary> | Trac field | Value | | ---------------------- | ------------ | | Version | 8.6.2 | | Type | Bug | | TypeOfFailure | OtherFailure | | Priority | normal | | Resolution | Unresolved | | Component | Compiler | | Test case | | | Differential revisions | | | BlockedBy | | | Related | | | Blocking | | | CC | RyanGlScott | | Operating system | | | Architecture | | </details> <!-- {"blocked_by":[],"summary":"Generic1 deriving should use more coercions","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.8.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":["Generics"],"differentials":[],"test_case":"","architecture":"","cc":["RyanGlScott"],"type":"Bug","description":"Consider\r\n\r\n{{{#!hs\r\nnewtype Foo a = Foo (Maybe [a]) deriving (Generic1)\r\n}}}\r\n\r\nThis produces some rather unsatisfactory Core:\r\n\r\n{{{\r\n-- to1 worker\r\nTravv.$fGeneric1Foo1 :: forall a. Rep1 Foo a -> Maybe [a]\r\nTravv.$fGeneric1Foo1\r\n = \\ (@ a_a7RL) (ds_d9dZ :: Rep1 Foo a_a7RL) ->\r\n case ds_d9dZ `cast` <Co:103> of {\r\n Nothing -> GHC.Maybe.Nothing @ [a_a7RL];\r\n Just a1_a9fD -> GHC.Maybe.Just @ [a_a7RL] (a1_a9fD `cast` <Co:5>)\r\n}\r\n\r\n-- from1 worker\r\nTravv.$fGeneric1Foo2 :: forall a. Foo a -> Maybe (Rec1 [] a)\r\nTravv.$fGeneric1Foo2\r\n = \\ (@ a_a7R6) (x_a7GJ :: Foo a_a7R6) ->\r\n case x_a7GJ `cast` <Co:2> of {\r\n Nothing -> GHC.Maybe.Nothing @ (Rec1 [] a_a7R6);\r\n Just a1_a9fD ->\r\n GHC.Maybe.Just @ (Rec1 [] a_a7R6) (a1_a9fD `cast` <Co:6>)\r\n }\r\n}}}\r\n\r\nBoth of these functions could be implemented as safe coercions, but neither of them is! Similarly, if I define\r\n\r\n{{{#!hs\r\ndata Bar a = Bar (Maybe [a]) deriving Generic1\r\n}}}\r\n\r\nI get a `to1` worker that looks like\r\n\r\n{{{\r\nTravv.$fGeneric1Bar_$cto1 :: forall a. Rep1 Bar a -> Bar a\r\nTravv.$fGeneric1Bar_$cto1\r\n = \\ (@ a_a7UA) (ds_d9ho :: Rep1 Bar a_a7UA) ->\r\n Travv.Bar\r\n @ a_a7UA\r\n (case ds_d9ho `cast` <Co:103> of {\r\n Nothing -> GHC.Maybe.Nothing @ [a_a7UA];\r\n Just a1_a9iK -> GHC.Maybe.Just @ [a_a7UA] (a1_a9iK `cast` <Co:5>)\r\n })\r\n}}}\r\n\r\nThat `case` expression should really just be a cast.\r\n\r\nI think the basic trick is probably to inspect the role of the type argument of each type in a composition, using that to work out whether to coerce that step.","type_of_failure":"OtherFailure","blocking":[]} -->
issue