Commit 30059bd8 authored by Simon Peyton Jones's avatar Simon Peyton Jones
Browse files

Fix Read for empty data types (again; Trac #7931)

parent 827cc509
...@@ -617,11 +617,12 @@ punc_RDR = dataQual_RDR lEX (fsLit "Punc") ...@@ -617,11 +617,12 @@ punc_RDR = dataQual_RDR lEX (fsLit "Punc")
ident_RDR = dataQual_RDR lEX (fsLit "Ident") ident_RDR = dataQual_RDR lEX (fsLit "Ident")
symbol_RDR = dataQual_RDR lEX (fsLit "Symbol") symbol_RDR = dataQual_RDR lEX (fsLit "Symbol")
step_RDR, alt_RDR, reset_RDR, prec_RDR :: RdrName step_RDR, alt_RDR, reset_RDR, prec_RDR, pfail_RDR :: RdrName
step_RDR = varQual_RDR rEAD_PREC (fsLit "step") step_RDR = varQual_RDR rEAD_PREC (fsLit "step")
alt_RDR = varQual_RDR rEAD_PREC (fsLit "+++") alt_RDR = varQual_RDR rEAD_PREC (fsLit "+++")
reset_RDR = varQual_RDR rEAD_PREC (fsLit "reset") reset_RDR = varQual_RDR rEAD_PREC (fsLit "reset")
prec_RDR = varQual_RDR rEAD_PREC (fsLit "prec") prec_RDR = varQual_RDR rEAD_PREC (fsLit "prec")
pfail_RDR = varQual_RDR rEAD_PREC (fsLit "pfail")
showList_RDR, showList___RDR, showsPrec_RDR, showString_RDR, showList_RDR, showList___RDR, showsPrec_RDR, showString_RDR,
showSpace_RDR, showParen_RDR :: RdrName showSpace_RDR, showParen_RDR :: RdrName
......
...@@ -881,7 +881,25 @@ The latter desugares to inline code for matching the Ident and the ...@@ -881,7 +881,25 @@ The latter desugares to inline code for matching the Ident and the
string, and this can be very voluminous. The former is much more string, and this can be very voluminous. The former is much more
compact. Cf Trac #7258, although that also concerned non-linearity in compact. Cf Trac #7258, although that also concerned non-linearity in
the occurrence analyser, a separate issue. the occurrence analyser, a separate issue.
Note [Read for empty data types]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
What should we get for this? (Trac #7931)
data Emp deriving( Read ) -- No data constructors
Here we want
read "[]" :: [Emp] to succeed, returning []
So we do NOT want
instance Read Emp where
readPrec = error "urk"
Rather we want
instance Read Emp where
readPred = pfail -- Same as choose []
Because 'pfail' allows the parser to backtrack, but 'error' doesn't.
These instances are also useful for Read (Either Int Emp), where
we want to be able to parse (Left 3) just fine.
\begin{code} \begin{code}
gen_Read_binds :: FixityEnv -> SrcSpan -> TyCon -> (LHsBinds RdrName, BagDerivStuff) gen_Read_binds :: FixityEnv -> SrcSpan -> TyCon -> (LHsBinds RdrName, BagDerivStuff)
...@@ -902,7 +920,7 @@ gen_Read_binds get_fixity loc tycon ...@@ -902,7 +920,7 @@ gen_Read_binds get_fixity loc tycon
read_prec = mkHsVarBind loc readPrec_RDR read_prec = mkHsVarBind loc readPrec_RDR
(nlHsApp (nlHsVar parens_RDR) read_cons) (nlHsApp (nlHsVar parens_RDR) read_cons)
read_cons | null data_cons = error_Expr "Derived Read on empty data type" -- Trac #7931 read_cons | null data_cons = nlHsVar pfail_RDR -- See Note [Read for empty data types]
| otherwise = foldr1 mk_alt (read_nullary_cons ++ read_non_nullary_cons) | otherwise = foldr1 mk_alt (read_nullary_cons ++ read_non_nullary_cons)
read_non_nullary_cons = map read_non_nullary_con non_nullary_cons read_non_nullary_cons = map read_non_nullary_con non_nullary_cons
......
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