[Git][ghc/ghc][wip/T21623] Add isCovertGadtDataCon, fixing build
Simon Peyton Jones (@simonpj)
gitlab at gitlab.haskell.org
Fri Oct 14 22:29:52 UTC 2022
Simon Peyton Jones pushed to branch wip/T21623 at Glasgow Haskell Compiler / GHC
Commits:
292f4f89 by Simon Peyton Jones at 2022-10-14T23:29:02+01:00
Add isCovertGadtDataCon, fixing build
- - - - -
2 changed files:
- compiler/GHC/Core/DataCon.hs
- compiler/GHC/Tc/Errors/Ppr.hs
Changes:
=====================================
compiler/GHC/Core/DataCon.hs
=====================================
@@ -55,7 +55,7 @@ module GHC.Core.DataCon (
-- ** Predicates on DataCons
isNullarySrcDataCon, isNullaryRepDataCon,
isTupleDataCon, isBoxedTupleDataCon, isUnboxedTupleDataCon,
- isUnboxedSumDataCon,
+ isUnboxedSumDataCon, isCovertGadtDataCon,
isVanillaDataCon, isNewDataCon, isTypeDataCon,
classDataCon, dataConCannotMatch,
dataConUserTyVarsNeedWrapper, checkDataConTyVars,
@@ -422,7 +422,7 @@ data DataCon
-- syntax, provided its type looks like the above.
-- The declaration format is held in the TyCon (algTcGadtSyntax)
- -- Universally-quantified type vars [a,b,c]
+ -- dcUnivTyVars: Universally-quantified type vars [a,b,c]
-- INVARIANT: length matches arity of the dcRepTyCon
-- INVARIANT: result type of data con worker is exactly (T a b c)
-- COROLLARY: The dcUnivTyVars are always in one-to-one correspondence with
@@ -875,8 +875,7 @@ data StrictnessMark = MarkedStrict | NotMarkedStrict
-- | An 'EqSpec' is a tyvar/type pair representing an equality made in
-- rejigging a GADT constructor
-data EqSpec = EqSpec TyVar
- Type
+data EqSpec = EqSpec TyVar Type
-- | Make a non-dependent 'EqSpec'
mkEqSpec :: TyVar -> Type -> EqSpec
@@ -1711,6 +1710,53 @@ isNewDataCon dc = isNewTyCon (dataConTyCon dc)
isTypeDataCon :: DataCon -> Bool
isTypeDataCon dc = isTcClsNameSpace (nameNameSpace (getName dc))
+isCovertGadtDataCon :: DataCon -> Bool
+-- See Note [isCovertGadtDataCon]
+isCovertGadtDataCon (MkData { dcUnivTyVars = univ_tvs
+ , dcEqSpec = eq_spec
+ , dcRepTyCon = rep_tc })
+ = not (null eq_spec) -- There are some constraints
+ && not (any is_visible_spec eq_spec) -- But none of them are visible
+ where
+ visible_univ_tvs :: [TyVar] -- Visible arguments in result type
+ visible_univ_tvs
+ = [ univ_tv | (univ_tv, tcb) <- univ_tvs `zip` tyConBinders rep_tc
+ , isVisibleTyConBinder tcb ]
+
+ is_visible_spec :: EqSpec -> Bool
+ is_visible_spec (EqSpec univ_tv _) = univ_tv `elem` visible_univ_tvs
+
+{- Note [isCovertGadtDataCon]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+(isCovertGadtDataCon K) returns True if K is a GADT data constructor, but
+does not /look/ like it. Consider (#21447)
+ type T :: TYPE r -> Type
+ data T a where { MkT :: b -> T b }
+Here MkT doesn't look GADT-like, but it is. If we make the kind applications
+explicit we'd see:
+ data T a where { MkT :: b -> T @LiftedRep b }
+
+The test for covert-ness is bit tricky, because we want to see if
+ - dcEqSpec is non-empty
+ - none of the universal type variables that it constrains is
+ a required argument of the TyCon
+
+In the example above, the DataCon for MkT will have
+ dcUnivTyVars: [(r::RuntimeRep), (b :: TYPE r)]
+ dcEqSpec: [ (r, LiftedRep) ]
+So `r` is constrained by dcEqSpec, but `b` is not, so the user-visible
+declaration MkT :: b -> T b
+looks entirely non-GADT-ish.
+
+But remember:
+* The visibility or otherwise is a property of the /TyCon/ binders
+* The dcUnivTyVars may or may not be the same as the TyCon binders
+* So we have to zip them together.
+* For a data family the TyCon in question is the /representation/ TyCon
+ hence dcRepTyCon
+-}
+
+
-- | Should this DataCon be allowed in a type even without -XDataKinds?
-- Currently, only Lifted & Unlifted
specialPromotedDc :: DataCon -> Bool
=====================================
compiler/GHC/Tc/Errors/Ppr.hs
=====================================
@@ -1018,7 +1018,8 @@ instance Diagnostic TcRnMessage where
ppr con <+> dcolon <+> ppr (dataConDisplayType True con))
IsGADT ->
(text "A newtype must not be a GADT",
- ppr con <+> dcolon <+> pprWithExplicitKindsWhen sneaky_eq_spec (ppr $ dataConDisplayType show_linear_types con))
+ ppr con <+> dcolon <+> pprWithExplicitKindsWhen sneaky_eq_spec
+ (ppr $ dataConDisplayType show_linear_types con))
HasConstructorContext ->
(text "A newtype constructor must not have a context in its type",
ppr con <+> dcolon <+> ppr (dataConDisplayType show_linear_types con))
@@ -1028,12 +1029,9 @@ instance Diagnostic TcRnMessage where
HasStrictnessAnnotation ->
(text "A newtype constructor must not have a strictness annotation", empty)
- -- Is there an EqSpec involving an invisible binder? If so, print the
- -- error message with explicit kinds.
- invisible_binders = filter isInvisibleTyConBinder (tyConBinders $ dataConTyCon con)
- sneaky_eq_spec
- = any (\eq -> any (( == eqSpecTyVar eq) . binderVar) invisible_binders)
- $ dataConEqSpec con
+ -- Is the data con a "covert" GADT? See Note [isCovertGadtDataCon]
+ -- in GHC.Core.DataCon
+ sneaky_eq_spec = isCovertGadtDataCon con
diagnosticReason = \case
TcRnUnknownMessage m
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/292f4f89f310cb1ff6723e0b7952c7f069abee41
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/292f4f89f310cb1ff6723e0b7952c7f069abee41
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/20221014/3ccb3beb/attachment-0001.html>
More information about the ghc-commits
mailing list