[Git][ghc/ghc][wip/T23145] Pmc: Treat `x ~ y @ty` the same as `x ~ y` (#23145)

Sebastian Graf (@sgraf812) gitlab at gitlab.haskell.org
Thu Apr 6 09:04:01 UTC 2023



Sebastian Graf pushed to branch wip/T23145 at Glasgow Haskell Compiler / GHC


Commits:
0b65d387 by Sebastian Graf at 2023-04-06T11:03:54+02:00
Pmc: Treat `x ~ y @ty` the same as `x ~ y` (#23145)

In #23145 we had a desugaring that matched on expressions `ds @Any`
and `ds @blah` (where `blah /= Any`). In both cases, we match on the
same value, but Long-distance information was unable to figure this
out.

The fix is rather simple: Upon reasoning about the Core constraint
`x ~ ds @Any`, drop any type arguments to see `x ~ ds`, then we will
equate that to the same as `ds @blah`.

This plays a bit fast-and-loose with types; on the other hand, the
situations in which can give the same value different types should
be exceedingly rare.

Fixes #23145.

- - - - -


3 changed files:

- compiler/GHC/HsToCore/Pmc/Solver.hs
- + testsuite/tests/pmcheck/should_compile/T23145.hs
- testsuite/tests/pmcheck/should_compile/all.T


Changes:

=====================================
compiler/GHC/HsToCore/Pmc/Solver.hs
=====================================
@@ -868,15 +868,23 @@ addCoreCt nabla x e = do
           -- Otherwise we alternate endlessly between [] and ""
           [] -> data_con_app x emptyInScopeSet nilDataCon []
           s' -> core_expr x (mkListExpr charTy (map mkCharExpr s'))
+
       | Just lit <- coreExprAsPmLit e
       = pm_lit x lit
+
       | Just (in_scope, _empty_floats@[], dc, _arg_tys, args)
             <- exprIsConApp_maybe in_scope_env e
       = data_con_app x in_scope dc args
-      -- See Note [Detecting pattern synonym applications in expressions]
-      | Var y <- e, Nothing <- isDataConId_maybe x
-      -- We don't consider DataCons flexible variables
+          -- See Note [Detecting pattern synonym applications in expressions]
+
+      | (Var y, args) <- collectArgs e
+          -- This catches the case of a variable constraints `x ~ y`
+      , all isTypeArg args
+          -- See Note [Identify VarInfo modulo type arguments]
+      , Nothing <- isDataConId_maybe x
+          -- We don't consider DataCons flexible variables
       = modifyT (\nabla -> addVarCt nabla x y)
+
       | otherwise
       -- Any other expression. Try to find other uses of a semantically
       -- equivalent expression and represent them by the same variable!
@@ -1059,10 +1067,41 @@ In the end, replacing dictionaries with an error value in the pattern-match
 checker was the most self-contained, although we might want to revisit once
 we implement a more robust approach to computing equality in the pattern-match
 checker (see #19272).
--}
 
-{- Note [The Pos/Neg invariant]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Note [Identify VarInfo modulo type arguments]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider (#23145)
+
+  f :: (forall a. Maybe a) -> Maybe b
+  f (Just x) = Just x
+  f Nothing  = Nothing
+
+this desugars to
+
+  f = \ @b (ds :: forall a. Maybe a) ->
+        case ds @b of {
+          Just x  -> Just @b x;
+          Nothing ->
+            case ds @Any of {
+              Just ipv -> patError ...
+              Nothing -> Nothing @b
+            }
+        }
+
+Note we match on `ds` twice with different type arguments applied, but since the
+type arguments are erased both matches must yield the same value. Hence we should
+not warn about `f` having an incomplete match.
+A good way to achieve that is discard the type arguments in the constraint `pm
+~ ds @b` (where `pm` is the match variable of the outermost Case) so that we
+get `pm ~ ds`, with the outcome of giving both match variables the same VarInfo
+as `ds`. Long distance information will sort out the rest and we the checker
+detects `f` as exhaustive.
+
+Note that the potential type confusion is harmless as the TyCon of `ds` and `pm`
+must be the same (if it exists).
+
+Note [The Pos/Neg invariant]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Invariant applying to each VarInfo: Whenever we have @C @tvs args@ in 'vi_pos',
 any entry in 'vi_neg' must be incomparable to C (return Nothing) according to
 'eqPmAltCons'. Those entries that are comparable either lead to a refutation


=====================================
testsuite/tests/pmcheck/should_compile/T23145.hs
=====================================
@@ -0,0 +1,12 @@
+{-# LANGUAGE Haskell2010 #-}
+{-# LANGUAGE RankNTypes #-}
+{-# OPTIONS_GHC -Wincomplete-patterns #-}
+module T23145 where
+
+data T a
+  = MkT1 a
+  | MkT2
+
+f :: (forall a. T a) -> T b
+f (MkT1 x) = MkT1 x
+f MkT2 = MkT2


=====================================
testsuite/tests/pmcheck/should_compile/all.T
=====================================
@@ -159,3 +159,4 @@ test('EmptyCase010', [],  compile, [overlapping_incomplete])
 test('T19271', [],  compile, [overlapping_incomplete])
 test('T21761', [],  compile, [overlapping_incomplete])
 test('T22964', [], compile, [overlapping_incomplete])
+test('T23145', [], compile, [overlapping_incomplete])



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0b65d3873b30f87bfe3b9452f8d7432a04baf1ce

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0b65d3873b30f87bfe3b9452f8d7432a04baf1ce
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20230406/de92f607/attachment-0001.html>


More information about the ghc-commits mailing list