The newtype-deriving mechanism generates a HsSyn case expression looking
like this
case (d `cast` co) of { ... }
That is, the case expression scrutinises a dictionary. This is
otherwise never seen in HsSyn, and it made the desugarer
(Check.get_unused_cons) crash in tcTyConAppTyCon.
It would really be better to generate Core in TcInstDecls (the newtype
deriving part) but I'm not going to do that today. Instead, I made
Check.get_unused_cons a bit more robust.
Audrey tried to fix this over the weekend, but her fix was, alas, utterly
bogus, which caused mysterious failures later. I completely undid this
change.
Anyway it should work now!
get_unused_cons :: [Pat Id] -> [DataCon]
get_unused_cons used_cons = unused_cons
where
get_unused_cons :: [Pat Id] -> [DataCon]
get_unused_cons used_cons = unused_cons
where
- (ConPatOut { pat_ty = ty }) = head used_cons
- ty_con = tcTyConAppTyCon ty -- Newtype observable
- all_cons = tyConDataCons ty_con
- used_cons_as_id = map (\ (ConPatOut{ pat_con = L _ d}) -> d) used_cons
- unused_cons = uniqSetToList
- (mkUniqSet all_cons `minusUniqSet` mkUniqSet used_cons_as_id)
+ (ConPatOut { pat_con = l_con, pat_ty = ty }) = head used_cons
+ ty_con = dataConTyCon (unLoc l_con) -- Newtype observable
+ all_cons = tyConDataCons ty_con
+ used_cons_as_id = map (\ (ConPatOut{ pat_con = L _ d}) -> d) used_cons
+ unused_cons = uniqSetToList
+ (mkUniqSet all_cons `minusUniqSet` mkUniqSet used_cons_as_id)
all_vars :: [Pat Id] -> Bool
all_vars [] = True
all_vars :: [Pat Id] -> Bool
all_vars [] = True
-- f {| a+b |} ... = ...
-- f {| x+y |} ... = ...
-- Then at this point we'll have an InstInfo for each
-- f {| a+b |} ... = ...
-- f {| x+y |} ... = ...
-- Then at this point we'll have an InstInfo for each
+ --
+ -- The class should be unary, which is why simpleInstInfoTyCon should be ok
let
tc_inst_infos :: [(TyCon, InstInfo)]
tc_inst_infos = [(simpleInstInfoTyCon i, i) | i <- inst_infos]
let
tc_inst_infos :: [(TyCon, InstInfo)]
tc_inst_infos = [(simpleInstInfoTyCon i, i) | i <- inst_infos]
the_rhs = mkHsConApp cls_data_con cls_inst_tys $
map HsVar (sc_dict_ids ++ op_ids)
the_rhs = mkHsConApp cls_data_con cls_inst_tys $
map HsVar (sc_dict_ids ++ op_ids)
+ -- Warning: this HsCase scrutinises a value with a PredTy, which is
+ -- never otherwise seen in Haskell source code. It'd be
+ -- nicer to generate Core directly!
; return (HsCase (noLoc coerced_rep_dict) $
MatchGroup [the_match] (mkFunTy inst_head_ty inst_head_ty)) }
where
; return (HsCase (noLoc coerced_rep_dict) $
MatchGroup [the_match] (mkFunTy inst_head_ty inst_head_ty)) }
where
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
\section[TcType]{Types used in the typechecker}
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
\section[TcType]{Types used in the typechecker}
-----------------------
tcTyConAppTyCon :: Type -> TyCon
-----------------------
tcTyConAppTyCon :: Type -> TyCon
-tcTyConAppTyCon ty = fst (tcSplitTyConApp ty)
+tcTyConAppTyCon ty = case tcSplitTyConApp_maybe ty of
+ Just (tc, _) -> tc
+ Nothing -> pprPanic "tcTyConAppTyCon" (pprType ty)
tcTyConAppArgs :: Type -> [Type]
tcTyConAppArgs :: Type -> [Type]
-tcTyConAppArgs ty = snd (tcSplitTyConApp ty)
+tcTyConAppArgs ty = case tcSplitTyConApp_maybe ty of
+ Just (_, args) -> args
+ Nothing -> pprPanic "tcTyConAppArgs" (pprType ty)
tcSplitTyConApp :: Type -> (TyCon, [Type])
tcSplitTyConApp ty = case tcSplitTyConApp_maybe ty of
tcSplitTyConApp :: Type -> (TyCon, [Type])
tcSplitTyConApp ty = case tcSplitTyConApp_maybe ty of
tcSplitTyConApp_maybe ty | Just ty' <- tcView ty = tcSplitTyConApp_maybe ty'
tcSplitTyConApp_maybe (TyConApp tc tys) = Just (tc, tys)
tcSplitTyConApp_maybe (FunTy arg res) = Just (funTyCon, [arg,res])
tcSplitTyConApp_maybe ty | Just ty' <- tcView ty = tcSplitTyConApp_maybe ty'
tcSplitTyConApp_maybe (TyConApp tc tys) = Just (tc, tys)
tcSplitTyConApp_maybe (FunTy arg res) = Just (funTyCon, [arg,res])
-tcSplitTyConApp_maybe (AppTy arg res) = Just (funTyCon, [arg,res])
-- Newtypes are opaque, so they may be split
-- However, predicates are not treated
-- as tycon applications by the type checker
-- Newtypes are opaque, so they may be split
-- However, predicates are not treated
-- as tycon applications by the type checker
-
--- XXX - 2006-09-24: This case is hard-coded in (rendering predicates opaque as well)
--- to make the newly reworked newtype-deriving work on the trivial case:
--- newtype T = T () deriving (Eq, Ord)
--- Please remove this if the newtype-deriving scheme no longer produces a PredTy.
-tcSplitTyConApp_maybe (PredTy (ClassP _ [ty'])) = tcSplitTyConApp_maybe ty'
-
tcSplitTyConApp_maybe other = Nothing
-----------------------
tcSplitTyConApp_maybe other = Nothing
-----------------------