X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcHsSyn.lhs;h=b9a2188ec532471d2086fc01acb3ced1b984be8f;hb=06f6f35dadc461336675e6d2b8a2192b1f518a1b;hp=075ae7153966348869ccf4bfe6e06e9fccb5d504;hpb=6a05ec5ef5373f61b7f9f5bdc344483417fa801b;p=ghc-hetmet.git diff --git a/compiler/typecheck/TcHsSyn.lhs b/compiler/typecheck/TcHsSyn.lhs index 075ae71..b9a2188 100644 --- a/compiler/typecheck/TcHsSyn.lhs +++ b/compiler/typecheck/TcHsSyn.lhs @@ -194,6 +194,13 @@ zonkIdBndr env id zonkIdBndrs :: ZonkEnv -> [TcId] -> TcM [Id] zonkIdBndrs env ids = mappM (zonkIdBndr env) ids +zonkDictBndrs :: ZonkEnv -> [Var] -> TcM [Var] +-- "Dictionary" binders can be coercion variables or dictionary variables +zonkDictBndrs env ids = mappM (zonkDictBndr env) ids + +zonkDictBndr env var | isTyVar var = return var + | otherwise = zonkIdBndr env var + zonkTopBndrs :: [TcId] -> TcM [Id] zonkTopBndrs ids = zonkIdBndrs emptyZonkEnv ids \end{code} @@ -287,7 +294,7 @@ zonk_bind env bind@(FunBind { fun_id = var, fun_matches = ms, fun_co_fn = co_fn zonk_bind env (AbsBinds { abs_tvs = tyvars, abs_dicts = dicts, abs_exports = exports, abs_binds = val_binds }) = ASSERT( all isImmutableTyVar tyvars ) - zonkIdBndrs env dicts `thenM` \ new_dicts -> + zonkDictBndrs env dicts `thenM` \ new_dicts -> fixM (\ ~(new_val_binds, _) -> let env1 = extendZonkEnv env new_dicts @@ -536,7 +543,8 @@ zonk_cmd_top env (HsCmdTop cmd stack_tys ty ids) ------------------------------------------------------------------------- zonkCoFn :: ZonkEnv -> HsWrapper -> TcM (ZonkEnv, HsWrapper) -zonkCoFn env WpHole = return (env, WpHole) +zonkCoFn env WpHole = return (env, WpHole) +zonkCoFn env WpInline = return (env, WpInline) zonkCoFn env (WpCompose c1 c2) = do { (env1, c1') <- zonkCoFn env c1 ; (env2, c2') <- zonkCoFn env1 c2 ; return (env2, WpCompose c1' c2') } @@ -900,56 +908,76 @@ zonkTypeZapping ty -- mutable tyvar to a fresh immutable one. So the mutable store -- plays the role of an environment. If we come across a mutable -- type variable that isn't so bound, it must be completely free. - zonk_unbound_tyvar tv = do { writeMetaTyVar tv ty; return ty } - where - ty = mkArbitraryType tv - - --- When the type checker finds a type variable with no binding, --- which means it can be instantiated with an arbitrary type, it --- usually instantiates it to Void. Eg. --- --- length [] --- ===> --- length Void (Nil Void) --- --- But in really obscure programs, the type variable might have --- a kind other than *, so we need to invent a suitably-kinded type. --- --- This commit uses --- Void for kind * --- List for kind *->* --- Tuple for kind *->...*->* --- --- which deals with most cases. (Previously, it only dealt with --- kind *.) --- --- In the other cases, it just makes up a TyCon with a suitable --- kind. If this gets into an interface file, anyone reading that --- file won't understand it. This is fixable (by making the client --- of the interface file make up a TyCon too) but it is tiresome and --- never happens, so I am leaving it - -mkArbitraryType :: TcTyVar -> Type --- Make up an arbitrary type whose kind is the same as the tyvar. --- We'll use this to instantiate the (unbound) tyvar. -mkArbitraryType tv - | liftedTypeKind `isSubKind` kind = anyPrimTy -- The vastly common case - | otherwise = mkTyConApp tycon [] - where - kind = tyVarKind tv - (args,res) = splitKindFunTys kind + zonk_unbound_tyvar tv = do { ty <- mkArbitraryType warn tv + ; writeMetaTyVar tv ty + ; return ty } + where + warn span msg = setSrcSpan span (addWarnTc msg) + + +{- Note [Strangely-kinded void TyCons] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + See Trac #959 for more examples + +When the type checker finds a type variable with no binding, which +means it can be instantiated with an arbitrary type, it usually +instantiates it to Void. Eg. - tycon | eqKind kind (tyConKind anyPrimTyCon1) -- *->* - = anyPrimTyCon1 -- No tuples this size + length [] +===> + length Void (Nil Void) - | all isLiftedTypeKind args && isLiftedTypeKind res - = tupleTyCon Boxed (length args) -- *-> ... ->*->* - -- Horrible hack to make less use of mkAnyPrimTyCon +But in really obscure programs, the type variable might have a kind +other than *, so we need to invent a suitably-kinded type. - | otherwise - = mkAnyPrimTyCon (getUnique tv) kind +This commit uses + Void for kind * + List for kind *->* + Tuple for kind *->...*->* + +which deals with most cases. (Previously, it only dealt with +kind *.) + +In the other cases, it just makes up a TyCon with a suitable kind. If +this gets into an interface file, anyone reading that file won't +understand it. This is fixable (by making the client of the interface +file make up a TyCon too) but it is tiresome and never happens, so I +am leaving it. + +Meanwhile I have now fixed GHC to emit a civilized warning. + -} + +mkArbitraryType :: (SrcSpan -> SDoc -> TcRnIf g l a) -- How to complain + -> TcTyVar + -> TcRnIf g l Type -- Used by desugarer too +-- Make up an arbitrary type whose kind is the same as the tyvar. +-- We'll use this to instantiate the (unbound) tyvar. +-- +-- Also used by the desugarer; hence the (tiresome) parameter +-- to use when generating a warning +mkArbitraryType warn tv + | liftedTypeKind `isSubKind` kind -- The vastly common case + = return anyPrimTy + | eqKind kind (tyConKind anyPrimTyCon1) -- *->* + = return (mkTyConApp anyPrimTyCon1 []) -- No tuples this size + | all isLiftedTypeKind args -- *-> ... ->*->* + , isLiftedTypeKind res -- Horrible hack to make less use + = return (mkTyConApp tup_tc []) -- of mkAnyPrimTyCon + | otherwise + = do { warn (getSrcSpan tv) msg + ; return (mkTyConApp (mkAnyPrimTyCon (getUnique tv) kind) []) } -- Same name as the tyvar, apart from making it start with a colon (sigh) -- I dread to think what will happen if this gets out into an -- interface file. Catastrophe likely. Major sigh. + where + kind = tyVarKind tv + (args,res) = splitKindFunTys kind + tup_tc = tupleTyCon Boxed (length args) + + msg = vcat [ hang (ptext SLIT("Inventing strangely-kinded Any TyCon")) + 2 (ptext SLIT("of kind") <+> quotes (ppr kind)) + , nest 2 (ptext SLIT("from an instantiation of type variable") <+> quotes (ppr tv)) + , ptext SLIT("This warning can be suppressed by a type signature fixing") <+> quotes (ppr tv) + , nest 2 (ptext SLIT("but is harmless without -O (and usually harmless anyway).")) + , ptext SLIT("See http://hackage.haskell.org/trac/ghc/ticket/959 for details") ] \end{code}