diff options
author | Ryan Scott <ryan.gl.scott@gmail.com> | 2018-03-21 08:59:28 -0400 |
---|---|---|
committer | Ryan Scott <ryan.gl.scott@gmail.com> | 2018-03-21 08:59:29 -0400 |
commit | 49ac3f0f2a13f66fea31a258fa98b0de39bfbf10 (patch) | |
tree | bb93d071e6c8f5b0f5c1bec55b3fa567056b4f8d /compiler/types/TyCoRep.hs | |
parent | abaf43d9d88d6fdf7345b936a571d17cfe1fa140 (diff) | |
download | haskell-49ac3f0f2a13f66fea31a258fa98b0de39bfbf10.tar.gz |
Fix #14869 by being more mindful of Type vs. Constraint
Summary:
Before, we were using `isLiftedTypeKind` in `reifyType`
before checking if a type was `Constraint`. But as it turns out,
`isLiftedTypeKind` treats `Constraint` the same as `Type`, so every
occurrence of `Constraint` would be reified as `Type`! To make things
worse, the documentation for `isLiftedTypeKind` stated that it
treats `Constraint` //differently// from `Type`, which simply isn't
true.
This revises the documentation for `isLiftedTypeKind` to reflect
reality, and defers the `isLiftedTypeKind` check in `reifyType` so
that it does not accidentally swallow `Constraint`.
Test Plan: make test TEST=T14869
Reviewers: goldfire, bgamari
Reviewed By: goldfire
Subscribers: rwbarton, thomie, carter
GHC Trac Issues: #14869
Differential Revision: https://phabricator.haskell.org/D4474
Diffstat (limited to 'compiler/types/TyCoRep.hs')
-rw-r--r-- | compiler/types/TyCoRep.hs | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/compiler/types/TyCoRep.hs b/compiler/types/TyCoRep.hs index cc425991ae..1082b5036d 100644 --- a/compiler/types/TyCoRep.hs +++ b/compiler/types/TyCoRep.hs @@ -39,6 +39,7 @@ module TyCoRep ( mkTyConTy, mkTyVarTy, mkTyVarTys, mkFunTy, mkFunTys, mkForAllTy, mkForAllTys, mkPiTy, mkPiTys, + isTYPE, tcIsTYPE, isLiftedTypeKind, isUnliftedTypeKind, isCoercionType, isRuntimeRepTy, isRuntimeRepVar, sameVis, @@ -145,7 +146,7 @@ import {-# SOURCE #-} Type( isPredTy, isCoercionTy, mkAppTy, mkCastTy , tyCoVarsOfTypeWellScoped , tyCoVarsOfTypesWellScoped , toposortTyVars - , coreView ) + , coreView, tcView ) -- Transitively pulls in a LOT of stuff, better to break the loop import {-# SOURCE #-} Coercion @@ -706,22 +707,45 @@ mkTyConTy tycon = TyConApp tycon [] Some basic functions, put here to break loops eg with the pretty printer -} -is_TYPE :: ( Type -- the single argument to TYPE; not a synonym - -> Bool ) -- what to return - -> Kind -> Bool -is_TYPE f ki | Just ki' <- coreView ki = is_TYPE f ki' -is_TYPE f (TyConApp tc [arg]) +-- | If a type is @'TYPE' r@ for some @r@, run the predicate argument on @r@. +-- Otherwise, return 'False'. +-- +-- This function does not distinguish between 'Constraint' and 'Type'. For a +-- version which does distinguish between the two, see 'tcIsTYPE'. +isTYPE :: ( Type -- the single argument to TYPE; not a synonym + -> Bool ) -- what to return + -> Kind -> Bool +isTYPE f ki | Just ki' <- coreView ki = isTYPE f ki' +isTYPE f (TyConApp tc [arg]) | tc `hasKey` tYPETyConKey = go arg where go ty | Just ty' <- coreView ty = go ty' go ty = f ty -is_TYPE _ _ = False +isTYPE _ _ = False + +-- | If a type is @'TYPE' r@ for some @r@, run the predicate argument on @r@. +-- Otherwise, return 'False'. +-- +-- This function distinguishes between 'Constraint' and 'Type' (and will return +-- 'False' for 'Constraint'). For a version which does not distinguish between +-- the two, see 'isTYPE'. +tcIsTYPE :: ( Type -- the single argument to TYPE; not a synonym + -> Bool ) -- what to return + -> Kind -> Bool +tcIsTYPE f ki | Just ki' <- tcView ki = tcIsTYPE f ki' +tcIsTYPE f (TyConApp tc [arg]) + | tc `hasKey` tYPETyConKey + = go arg + where + go ty | Just ty' <- tcView ty = go ty' + go ty = f ty +tcIsTYPE _ _ = False --- | This version considers Constraint to be distinct from *. Returns True --- if the argument is equivalent to Type and False otherwise. +-- | This version considers Constraint to be the same as *. Returns True +-- if the argument is equivalent to Type/Constraint and False otherwise. isLiftedTypeKind :: Kind -> Bool -isLiftedTypeKind = is_TYPE is_lifted +isLiftedTypeKind = isTYPE is_lifted where is_lifted (TyConApp lifted_rep []) = lifted_rep `hasKey` liftedRepDataConKey is_lifted _ = False @@ -730,7 +754,7 @@ isLiftedTypeKind = is_TYPE is_lifted -- Note that this returns False for levity-polymorphic kinds, which may -- be specialized to a kind that classifies unlifted types. isUnliftedTypeKind :: Kind -> Bool -isUnliftedTypeKind = is_TYPE is_unlifted +isUnliftedTypeKind = isTYPE is_unlifted where is_unlifted (TyConApp rr _args) = not (rr `hasKey` liftedRepDataConKey) is_unlifted _ = False |