Commit d978c5ed authored by eir@cis.upenn.edu's avatar eir@cis.upenn.edu
Browse files

Fix #11723 and #11724.

Test cases: typecheck/should_fail/T1172{3,4}
parent 5c0c751a
......@@ -29,7 +29,10 @@ module TcHsSyn (
zonkTopBndrs, zonkTyBndrsX, zonkTyBinders,
emptyZonkEnv, mkEmptyZonkEnv,
zonkTcTypeToType, zonkTcTypeToTypes, zonkTyVarOcc,
zonkCoToCo, zonkTcKindToKind
zonkCoToCo, zonkTcKindToKind,
-- * Validity checking
checkForRepresentationPolymorphism
) where
#include "HsVersions.h"
......@@ -45,6 +48,7 @@ import TysPrim
import TysWiredIn
import Type
import TyCoRep ( TyBinder(..) )
import TyCon
import Coercion
import ConLike
import DataCon
......@@ -1665,16 +1669,38 @@ ensureNotRepresentationPolymorphic
ensureNotRepresentationPolymorphic id ty
= whenNoErrs $ -- sometimes we end up zonking bogus definitions of type
-- forall a. a. See, for example, test ghci/scripts/T9140
unless (isEmptyVarSet (tyCoVarsOfType ki)) $
addErrAt (nameSrcSpan $ idName id) $
vcat [ text "The following variable has an unknown runtime representation:"
, text " Var name:" <+> ppr id
, text " Var type:" <+> ppr tidy_ty
, text " Type's kind:" <+> ppr tidy_ki
, text "Perhaps add a type or kind signature to fix the representation."
]
checkForRepresentationPolymorphism
(text "In the type of binder" <+> quotes (ppr id)) ty
checkForRepresentationPolymorphism :: SDoc -> Type -> TcM ()
checkForRepresentationPolymorphism extra ty
| Just (tc, tys) <- splitTyConApp_maybe ty
, isUnboxedTupleTyCon tc
= mapM_ (checkForRepresentationPolymorphism extra) (dropRuntimeRepArgs tys)
-- You might think that we can just check the RuntimeRep args themselves.
-- But this would fail in the case of nested unboxed tuples, for which
-- one of the RuntimeRep args would be UnboxedTupleRep. So we just check
-- the type args directly.
| runtime_rep `eqType` unboxedTupleRepDataConTy
= addErr (vcat [ text "The type" <+> quotes (ppr tidy_ty) <+>
text "is not an unboxed tuple,"
, text "and yet its kind suggests that it has the representation"
, text "of an unboxed tuple. This is not allowed." ] $$
extra)
| not (isEmptyVarSet (tyCoVarsOfType runtime_rep))
= addErr $
hang (text "A representation-polymorphic type is not allowed here:")
2 (vcat [ text "Type:" <+> ppr tidy_ty
, text "Kind:" <+> ppr tidy_ki ]) $$
extra
| otherwise
= return ()
where
ki = typeKind ty
ki = typeKind ty
runtime_rep = getRuntimeRepFromKind "check_type" ki
(tidy_env, tidy_ty) = tidyOpenType emptyTidyEnv ty
tidy_ki = tidyType tidy_env ki
tidy_ki = tidyType tidy_env (typeKind ty)
......@@ -37,6 +37,7 @@ import TyCon
-- others:
import HsSyn -- HsType
import TcRnMonad -- TcType, amongst others
import TcHsSyn ( checkForRepresentationPolymorphism )
import FunDeps
import FamInstEnv ( isDominatedBy, injectiveBranches,
InjectivityCheckResult(..) )
......@@ -444,6 +445,16 @@ forAllAllowed ArbitraryRank = True
forAllAllowed (LimitedRank forall_ok _) = forall_ok
forAllAllowed _ = False
-- The zonker issues errors if it zonks a representation-polymorphic binder
-- But sometimes it's nice to check a little more eagerly, trying to report
-- errors earlier.
representationPolymorphismForbidden :: UserTypeCtxt -> Bool
representationPolymorphismForbidden = go
where
go (ConArgCtxt _) = True -- A rep-polymorphic datacon won't be useful
go (PatSynCtxt _) = True -- Similar to previous case
go _ = False -- Other cases are caught by zonker
----------------------------------------
-- | Fail with error message if the type is unlifted
check_lifted :: Type -> TcM ()
......@@ -498,6 +509,8 @@ check_type _ _ _ (TyVarTy _) = return ()
check_type env ctxt rank (ForAllTy (Anon arg_ty) res_ty)
= do { check_type env ctxt arg_rank arg_ty
; when (representationPolymorphismForbidden ctxt) $
checkForRepresentationPolymorphism empty arg_ty
; check_type env ctxt res_rank res_ty }
where
(arg_rank, res_rank) = funArgResRank rank
......
......@@ -7638,7 +7638,7 @@ your program, we encourage you to turn on these flags, especially
.. index::
single: TYPE
single: runtime representation polymorphism
single: representation polymorphism
.. _runtime-rep:
......
T11473.hs:19:7: error:
The following variable has an unknown runtime representation:
Var name: x
Var type: a
Type's kind: TYPE r
Perhaps add a type or kind signature to fix the representation.
A representation-polymorphic type is not allowed here:
Type: a
Kind: TYPE r
In the type of binder ‘x’
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
module Example where
import Data.Typeable
import GHC.Exts
data Wat (a :: TYPE 'UnboxedTupleRep) = Wat a
T11723.hs:8:41: error:
• The type ‘a’ is not an unboxed tuple,
and yet its kind suggests that it has the representation
of an unboxed tuple. This is not allowed.
• In the definition of data constructor ‘Wat’
In the data type declaration for ‘Wat’
{-# LANGUAGE TypeInType #-}
module T11724 where
import GHC.Exts
data Foo (r :: RuntimeRep) (a :: TYPE r) = Foo a
T11724.hs:7:44: error:
• A representation-polymorphic type is not allowed here:
Type: a
Kind: TYPE r
• In the definition of data constructor ‘Foo’
In the data type declaration for ‘Foo’
......@@ -409,3 +409,5 @@ test('T11464', normal, compile_fail, [''])
test('T11563', normal, compile_fail, [''])
test('T11541', normal, compile_fail, [''])
test('T11313', normal, compile_fail, [''])
test('T11723', normal, compile_fail, [''])
test('T11724', normal, compile_fail, [''])
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment