packages feed

ghc-tcplugin-api 0.16.0.0 → 0.16.1.0

raw patch · 3 files changed

+32/−19 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

changelog.md view
@@ -1,5 +1,12 @@ 
-# Version 0.16.0.0 (2025-06-10)
+# Version 0.16.1.0 (2025-07-18)
+
+- Correctness fix for the `GHC.TcPlugin.API.TyConSubst` module: ensure that
+  the `TyConSubst` does not mistake representational Given equalities for
+  nominal equalities. For the time being, the `splitTyConApp_upTo` functionality
+  only works at nominal role.
+
+# Version 0.16.0.0 (2025-07-18)
 
 - Re-export `tyConDataCons`, `tyConSingleDataCon_maybe`,
   `tyConSingleDataCon`, `dataConTyCon`, `isNewTyCon` and `isNewDataCon`
ghc-tcplugin-api.cabal view
@@ -1,6 +1,6 @@ cabal-version:  3.0
 name:           ghc-tcplugin-api
-version:        0.16.0.0
+version:        0.16.1.0
 synopsis:       An API for type-checker plugins.
 license:        BSD-3-Clause
 build-type:     Simple
src/GHC/TcPlugin/API/TyConSubst.hs view
@@ -11,7 +11,7 @@ Module: GHC.TcPlugin.API.TyConSubst
 
 This module provides functionality for recognising whether a type is a
-'TyConApp' while taking into account Given constraints.
+'TyConApp' while taking into account Given nominal equalities.
 
 In particular, this allows dealing with flattening variables on older GHC versions
 (9.0 and below). For example, instead of @[W] m + n ~ n + m@, older GHCs might
@@ -23,10 +23,15 @@ 
   - Use 'mkTyConSubst' to create a 'TyConSubst' from Givens.
   - Use 'splitTyConApp_upTo' to compute whether a type is a 'TyConApp', taking
-    into account the Givens (in the form of the 'TyConSubst').
+    into account Given constraints (in the form of the 'TyConSubst').
 
-Note that 'splitTyConApp_upTo' will also look through type synonyms.
+Notes:
 
+  - 'splitTyConApp_upTo' will also look through type synonyms,
+  - 'splitTyConApp_upTo' only takes into account nominal equalities.
+    Please open a ticket if you have a need for rewriting modulo representational
+    equalities.
+
 -}
 module GHC.TcPlugin.API.TyConSubst (
     TyConSubst -- opaque
@@ -69,7 +74,7 @@   <https://hackage.haskell.org/package/union-find>?
 -------------------------------------------------------------------------------}
 
--- | Substitution for recognizing 'TyCon' applications modulo equalities
+-- | Substitution for recognizing 'TyCon' applications modulo nominal equalities.
 data TyConSubst = TyConSubst {
       tyConSubstMap :: Map TcTyVar (NonEmpty (TyCon, [Type]))
     , tyConSubstCanon :: Map TcTyVar TcTyVar
@@ -164,7 +169,7 @@   Classification
 -------------------------------------------------------------------------------}
 
--- | Classified canonical equality constraints
+-- | Classified canonical nominal equality constraints.
 --
 -- The first step in the construction of the 'TyConSubst' is to classify the
 -- available canonical equalities as one of three categories, defined below.
@@ -221,7 +226,7 @@       classifiedReconsider = [(var, (var', args))]
     }
 
--- | Classify a set of given constraints
+-- | Classify a set of Given constraints.
 --
 -- See 'Classified' for details.
 classify :: [Ct] -> Classified
@@ -231,7 +236,7 @@     go acc []     = acc
     go acc (c:cs) =
         case isCanonicalVarEq c of
-          Just (var, splitAppTys -> (fn, args))
+          Just (var, splitAppTys -> (fn, args), NomEq)
             | Just tyCon <- tyConAppTyCon_maybe fn ->
                 go (productive var (tyCon, args) <> acc) cs
             | Just var' <- getTyVar_maybe fn, null args ->
@@ -245,7 +250,7 @@   Processing
 -------------------------------------------------------------------------------}
 
--- | Construct 'TyCon' substitution from classified equality constraints
+-- | Construct 'TyCon' substitution from classified nominal equality constraints.
 --
 -- The difficult part in constructing this substitution are the equalities of
 -- the form @var1 ~ var2 args@, which we ear-marked as "to reconsider" during
@@ -352,33 +357,34 @@   Canonical equalities
 -------------------------------------------------------------------------------}
 
-isCanonicalVarEq :: Ct -> Maybe (TcTyVar, Type)
+isCanonicalVarEq :: Ct -> Maybe (TcTyVar, Type, EqRel)
 isCanonicalVarEq = \case
 #if __GLASGOW_HASKELL__ < 902
-    CTyEqCan { cc_tyvar, cc_rhs } ->
-      Just (cc_tyvar, cc_rhs)
+    CTyEqCan { cc_tyvar, cc_rhs, cc_eq_rel } ->
+      Just (cc_tyvar, cc_rhs, cc_eq_rel)
     CFunEqCan { cc_fsk, cc_fun, cc_tyargs } ->
-      Just (cc_fsk, mkTyConApp cc_fun cc_tyargs)
+      Just (cc_fsk, mkTyConApp cc_fun cc_tyargs, NomEq)
     _otherwise    -> Nothing
 #elif __GLASGOW_HASKELL__ < 907
-    CEqCan { cc_lhs, cc_rhs }
+    CEqCan { cc_lhs, cc_rhs, cc_eq_rel }
       | TyVarLHS var <- cc_lhs
-      -> Just (var, cc_rhs)
+      -> Just (var, cc_rhs, cc_eq_rel)
       | TyFamLHS tyCon args <- cc_lhs
       , Just var            <- getTyVar_maybe cc_rhs
-      -> Just (var, mkTyConApp tyCon args)
+      -> Just (var, mkTyConApp tyCon args, NomEq)
     _otherwise
       -> Nothing
 #else
     CEqCan eqCt
       | TyVarLHS var <- lhs
-      -> Just (var, rhs)
+      -> Just (var, rhs, rel)
       | TyFamLHS tyCon args <- lhs
       , Just var            <- getTyVar_maybe rhs
-      -> Just (var, mkTyConApp tyCon args)
+      -> Just (var, mkTyConApp tyCon args, rel)
       where
         lhs = eq_lhs eqCt
         rhs = eq_rhs eqCt
+        rel = eq_eq_rel eqCt
     _otherwise
       -> Nothing
 #endif