Skip to content
Browse files

work on OverloadedStrings, but not yet working (implicit import gets …

…lost somewhere in toplevel compilation driver)
  • Loading branch information...
1 parent 3f09d19 commit 1cb861b3986f4c9b44042afd78134f5b96e78dd0 @atzedijkstra atzedijkstra committed Sep 28, 2012
View
36,052 EHC/configure
6,667 additions, 29,385 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
16 EHC/ehclib/base/Data/String.hs
@@ -1,5 +1,8 @@
{-# LANGUAGE Trustworthy #-}
-{-# LANGUAGE CPP, NoImplicitPrelude, FlexibleInstances #-}
+{-# LANGUAGE CPP, FlexibleInstances #-}
+#ifdef __GLASGOW_HASKELL__
+{-# LANGUAGE NoImplicitPrelude #-}
+#endif
-----------------------------------------------------------------------------
-- |
@@ -31,7 +34,7 @@ import GHC.Base
#endif
#ifdef __UHC__
-import UHC.Base
+-- import UHC.Base
#endif
import Data.List (lines, words, unlines, unwords)
@@ -41,12 +44,17 @@ import Data.List (lines, words, unlines, unwords)
class IsString a where
fromString :: String -> a
-instance IsString [Char] where
- fromString xs = xs
+instance IsString String where
+ fromString = id
#ifdef __UHC_TARGET_JS__
foreign import prim "primStringToPackedString" primStringToPackedString :: String -> PackedString
instance IsString PackedString where
fromString = primStringToPackedString
#endif
+
+#ifdef __UHC__
+default IsString [Char]
+#endif
+
View
19 EHC/src/ehc/Base/Builtin.chs
@@ -653,6 +653,17 @@ TBD: Needs cleaning up, correct partitioning in variants
%%]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Known/available runtime values: IsString
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%[99 export(hsnDataStringFromString)
+[hsnDataStringFromString]
+ = map
+ (mkRV hsnModDataString)
+ [ "fromString" ]
+%%]
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Known/available runtime values: main entry point
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -690,6 +701,10 @@ hsnModBuiltin = mkHNm "#Builtin"
hsnUHC = hsnFromString "UHC"
%%]
+%%[92
+hsnData = hsnFromString "Data"
+%%]
+
%%[99 export(hsnIsInPrelude)
hsnIsInPrelude :: HsName -> Bool
hsnIsInPrelude n
@@ -716,6 +731,10 @@ hsnModIntlShow = hsnPrefixQual hsnUHC (hsnFromString
hsnModPrelude = hsnFromString "Prelude"
%%]
+%%[99 export(hsnModDataString)
+hsnModDataString = hsnPrefixQual hsnData (hsnFromString "String")
+%%]
+
%%[99
hsnModIntlTypes = hsnPrefixQual hsnUHC (hsnFromString "Types")
hsnModIntlPtr = hsnPrefixQual hsnUHC (hsnFromString "Ptr")
View
12 EHC/src/ehc/EHC/CompilePhase/Module.chs
@@ -8,7 +8,7 @@ Module analysis
%%]
-- general imports
-%%[50 import(qualified Data.Map as Map)
+%%[50 import(qualified Data.Map as Map, qualified Data.Set as Set)
%%]
%%[50 import(qualified EH.Util.Rel as Rel)
%%]
@@ -25,6 +25,9 @@ Module analysis
%%[50 import(qualified {%{EH}HS.ModImpExp} as HSSemMod)
%%]
+%%[50 import({%{EH}Base.Debug})
+%%]
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Module analysis
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -38,7 +41,7 @@ cpCheckMods' modL@(Mod {modName = modNm} : _)
%%[[50
; when (ehcOptVerbosity (crsiOpts crsi) >= VerboseDebug)
(do { cpMsg modNm VerboseDebug "cpCheckMods'"
- ; lift $ putWidthPPLn 120 (pp (head modL) >-< ppModMp mm) -- debug
+ ; lift $ putWidthPPLn 120 (pp (head modL) >-< pp modL >-< ppModMp mm) -- debug
})
%%][99
%%]]
@@ -82,10 +85,11 @@ cpGetHsImports modNm
mbHsSemMod = ecuMbHSSemMod ecu
hsSemMod = panicJust "cpGetHsImports" mbHsSemMod
modNm' = HSSemMod.realModuleNm_Syn_AGItf hsSemMod
- upd = ecuStoreHSDeclImpS (HSSemMod.modImpNmS_Syn_AGItf hsSemMod)
+ upd = ecuStoreHSDeclImpS ( -- (\v -> tr "XX" (pp $ Set.toList v) v) $
+ HSSemMod.modImpNmS_Syn_AGItf hsSemMod)
; case mbHsSemMod of
Just _ | ecuIsTopMod ecu -> cpUpdCUWithKey modNm (\_ ecu -> (modNm', upd $ cuUpdKey modNm' ecu))
- | otherwise -> do cpUpdCU modNm upd ; return modNm
+ | otherwise -> do { cpUpdCU modNm upd ; return modNm }
_ -> return modNm
}
View
3 EHC/src/ehc/EHC/CompilePhase/Semantics.chs
@@ -112,7 +112,8 @@ cpFoldHs modNm
})
%%[[50
where mmi = panicJust "cpFoldHs.crsiModMp" $ Map.lookup modNm $ crsiModMp crsi
- inscps = Rel.toDomMap $ mmiInscps $ mmi
+ inscps = Rel.toDomMap -- $ (\v -> tr "XX" (pp v ) v)
+ $ mmiInscps mmi
exps = Rel.toRngMap $ Rel.restrictRng (\o -> let mq = hsnQualifier (ioccNm o) in isJust mq && fromJust mq /= modNm)
$ Rel.mapRng mentIdOcc $ mmiExps mmi
%%]]
View
3 EHC/src/ehc/EHC/CompileUnit.chs
@@ -292,7 +292,8 @@ emptyECU
%%[50 export(ecuImpNmS,ecuImpNmL)
ecuImpNmS :: EHCompileUnit -> Set.Set HsName
-ecuImpNmS ecu = Set.delete (ecuModNm ecu) $ Set.unions [ ecuHSDeclImpNmS ecu, ecuHIDeclImpNmS ecu, ecuHIUsedImpNmS ecu ]
+ecuImpNmS ecu = -- (\v -> tr "XX" (pp $ Set.toList v) v) $
+ Set.delete (ecuModNm ecu) $ Set.unions [ ecuHSDeclImpNmS ecu, ecuHIDeclImpNmS ecu, ecuHIUsedImpNmS ecu ]
ecuImpNmL :: EHCompileUnit -> [HsName]
ecuImpNmL = Set.toList . ecuImpNmS -- ecu = (nub $ ecuHSDeclImpNmL ecu ++ ecuHIDeclImpNmL ecu ++ ecuHIUsedImpNmL ecu) \\ [ecuModNm ecu]
View
3 EHC/src/ehc/HS/ModImpExp.cag
@@ -20,6 +20,9 @@
%%[50 hs import(qualified EH.Util.Rel as Rel,{%{EH}Module})
%%]
+%%[97 hs import({%{EH}Base.Debug} as Debug, EH.Util.Pretty)
+%%]
+
%%[(99 codegen) hs import ({%{EH}Base.Target})
%%]
%%[99 hs import(qualified {%{EH}Base.Pragma} as Pragma)
View
14 EHC/src/ehc/HS/Module.cag
@@ -66,13 +66,15 @@ SEM Module
%%[99 -50.Module.modImpL
SEM Module
| Module
- loc . modImpL = if hsnModPrelude `elem` map mimpSource @body.modImpL
+ loc . modImpL = -- (\v -> tr "XX" (pp v) v) $
+ @prelModImpL ++ @body.extraModImpL ++ @body.modImpL
+ . prelModImpL = if hsnModPrelude `elem` map mimpSource @body.modImpL
|| @realModuleNm == hsnModPrelude
|| hsnIsInPrelude @realModuleNm
|| not (ehcOptUseAssumePrelude @lhs.opts)
|| Set.member Pragma.Pragma_NoImplicitPrelude @fileHeaderPragmas
- then @body.modImpL
- else modImpPrelude : @body.modImpL
+ then []
+ else [modImpPrelude]
%%]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -84,7 +86,8 @@ ATTR AGItf Module [ | | modImpNmS: {Set.Set HsName} ]
SEM Module
| Module
- lhs . modImpNmS = Set.fromList $ map mimpSource @modImpL
+ lhs . modImpNmS = -- (\v -> tr "XX" (pp $ Set.toList v) v) $
+ Set.fromList $ map mimpSource @modImpL
%%]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -228,7 +231,8 @@ ATTR Module AGItf [ | | mod: Mod ]
SEM Module
| Module
- lhs . mod = Mod @lhs.moduleNm @name
+ lhs . mod = -- (\v -> tr "XX" (pp v) v) $
+ Mod @lhs.moduleNm @name
@exports.modExpsMb @modImpL
@body.modDefsRel @body.modHideDefsRel
(reverse @body.topInstanceNmL)
View
73 EHC/src/ehc/HS/NameAnalysis.cag
@@ -442,7 +442,9 @@ SEM Body
| Body
loc . idGam = let -- lookup a name whether it is in scope and check for equality of its qualifier
lkn :: (IdOcc -> Bool) -> HsName -> Maybe (HsName,[ModEnt])
- lkn isq n = case Map.lookup n @lhs.modInScope of
+ lkn isq n = case Map.lookup n
+ -- $ (\v -> tr "ZZ" (pp $ Map.toList v) v) $
+ @lhs.modInScope of
Just es | not (null es')
-> Just (n,es')
where es' = [ e | e <- es, isq (mentIdOcc e) ]
@@ -469,7 +471,7 @@ SEM Body
| otherwise = const []
-- map qualifier to a possible 'qualified as' alias
as :: HsName -> HsName
- as n = Map.findWithDefault n n @importdeclarations.modAsMp
+ as n = Map.findWithDefault n n @modAsMp
-- compute new gamma holding proper mapping for unqualified & qualified idents
mkg sel g
= foldr idDefOccGamUnion emptyGam
@@ -479,8 +481,11 @@ SEM Body
, (n,es) <- sel o
, let ns = [ ioccNm eo | e <- es, let eo = mentIdOcc e, ioccKind eo == ioccKind o ]
]
- gnew = mkg (lks False) @lhs.idGam
- in mkg (lks False) @declarations.idDefOccGam `idDefOccGamUnion` gnew
+ gnew = mkg (lks False)
+ -- $ (\v -> tr "YY" (pp v) v) $
+ @lhs.idGam
+ in -- (\v -> tr "XX" (pp v) v) $
+ mkg (lks False) @declarations.idDefOccGam `idDefOccGamUnion` gnew
%%]
%%[1
@@ -610,43 +615,53 @@ SEM ContextItem
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%[1 hs
-litNames :: Literal -> Bool -> Int -> ([HsName],IdAspect)
-litNames lit isPat sign
+-- | Get the names used by the literals
+-- Note: don't change the order in returned lists, only append new values, as position is assumed to be fixed
+litNames :: EHCOpts -> Literal -> Bool -> Int -> [([HsName],IdOccKind,IdAspect)]
+litNames opts lit isPat sign
= case lit of
%%[[5
- Literal_String r s -> ([hsnDataListAltCons,hsnDataListAltNil],if isPat then IdAsp_Val_Con else IdAsp_Val_Var)
+ Literal_String r s -> mk' (if isPat then IdAsp_Val_Con else IdAsp_Val_Var) [hsnDataListAltCons,hsnDataListAltNil]
+ ++ (if ehcOptOverloadedStrings opts then mk [hsnDataStringFromString] else [])
%%]]
%%[[97
Literal_Int _ _ _
- | sign < 0 -> ([hsnFromInteger,hsnNegate],IdAsp_Val_Var)
- | otherwise -> ([hsnFromInteger],IdAsp_Val_Var)
+ | sign < 0 -> mk [hsnFromInteger,hsnNegate]
+ | otherwise -> mk [hsnFromInteger]
Literal_Float _ _
- | sign < 0 -> ([hsnMkRatio,hsnFromRational,hsnNegate],IdAsp_Val_Var)
- | otherwise -> ([hsnMkRatio,hsnFromRational],IdAsp_Val_Var)
+ | sign < 0 -> mk [hsnMkRatio,hsnFromRational,hsnNegate]
+ | otherwise -> mk [hsnMkRatio,hsnFromRational]
%%]]
- _ -> ([],IdAsp_Val_Var)
+ _ -> []
+ where mk' a ns = [(ns,IdOcc_Val,a)]
+ mk = mk' IdAsp_Val_Var
%%]
%%[1.mkUseOccGam hs
-mkUseOccGam :: EHCOpts -> IdDefOccGam -> [HsName] -> IdOccKind -> IdAspect -> Range -> (HsName,[HsName],IdUseOccGam,[Err])
-mkUseOccGam _ _ [] _ _ _
+mkUseOccGam' :: EHCOpts -> IdDefOccGam -> [([HsName],IdOccKind,IdAspect)] -> Range -> (HsName,[HsName],IdUseOccGam,[Err])
+mkUseOccGam' _ _ [] _
= (hsnUnknown,[],emptyGam,[])
-mkUseOccGam _ idGam names@(fstName:_) kind asp rng
- = (fstName,names,gamUnions [ mkUse idGam n kind asp rng | n <- names ],[])
+mkUseOccGam' _ idGam names@((fstName:_):_) rng
+ = (fstName,names,gamUnions [ mkUse idGam n kind asp rng | (ns,kind,asp) <- names, n <- ns ],[])
where mkUse idGam name kind asp rng
= idUseOccGam
where idOccUse = IdOcc name kind
mbDef = gamLookup idOccUse idGam
idUseOccGam = gamSingleton idOccUse (IdUseOcc idOccUse asp rng (doccForUse mbDef))
%%]
-%%[50 -1.mkUseOccGam hs
+%%[1 hs
mkUseOccGam :: EHCOpts -> IdDefOccGam -> [HsName] -> IdOccKind -> IdAspect -> Range -> (HsName,[HsName],IdUseOccGam,[Err])
-mkUseOccGam _ _ [] _ _ _
+mkUseOccGam opts idGam names kind asp rng = mkUseOccGam' opts idGam [(names,kind,asp)] rng
+%%]
+
+%%[50 -1.mkUseOccGam hs
+mkUseOccGam' :: EHCOpts -> IdDefOccGam -> [([HsName],IdOccKind,IdAspect)] -> Range -> (HsName,[HsName],IdUseOccGam,[Err])
+mkUseOccGam' _ _ [] _
= (hsnUnknown,[],emptyGam,[])
-mkUseOccGam opts idGam names kind asp rng
- = (n, ns, gamUnions g, concat e)
- where (ns@(n:_),g,e) = unzip3 [ mkUse idGam n kind asp rng | n <- names ]
+mkUseOccGam' opts idGam names rng
+ = (if null ns then hsnUnknown else n, ns, gamUnions g, concat e)
+ where (ns@(~(n:_)),g,e) = unzip3 [ mkUse idGam n kind asp rng | (ns,kind,asp) <- names, n <- ns ]
mkUse idGam name kind asp rng
= (nmOfDef,idUseOccGam,errs)
where idOccUse = IdOcc name kind
@@ -680,10 +695,9 @@ ATTR AllNT [ | | idUseOccGam USE {`gamAddGam`} {emptyGam}: IdUseOccGam ]
%%[1
SEM Expression
| Literal
- loc . (litnames,litAsp)
- = litNames @literal.eh False 1
+ loc . litnames = litNames @lhs.opts @literal.eh False 1
. (litrefname,litrefnames,idUseOccGam,errIdUse)
- = mkUseOccGam @lhs.opts @lhs.idGam @litnames IdOcc_Val @litAsp @range
+ = mkUseOccGam' @lhs.opts @lhs.idGam @litnames @range
lhs . idUseOccGam = gamUnions [@idUseOccGam, @literal.idUseOccGam]
| Variable
loc . idAsp = IdAsp_Val_Var
@@ -730,7 +744,7 @@ SEM Expression
%%]
%%]
-%%[5
+%%[5555
SEM Literal
| String
loc . (_,refnames,idUseOccGam,errIdUse)
@@ -750,10 +764,9 @@ SEM Pattern
| Literal
loc . (eqrefname,_,idUseOccGamEq,errIdUseEq)
= mkUseOccGam @lhs.opts @lhs.idGam [hsnClassEqFldEq] IdOcc_Val IdAsp_Val_Var @range
- . (litnames,litAsp)
- = litNames @literal.eh True @sign
+ . litnames = litNames @lhs.opts @literal.eh True @sign
. (litrefname,litrefnames,idUseOccGam,errIdUse)
- = mkUseOccGam @lhs.opts @lhs.idGam @litnames IdOcc_Val @litAsp @range
+ = mkUseOccGam' @lhs.opts @lhs.idGam @litnames @range
%%[[9
. (eqclassrefname,_,idUseOccGamCls,errIdUseCls)
= mkUseOccGam @lhs.opts @lhs.idGam [hsnClassEq] IdOcc_Class IdAsp_Class_Class @range
@@ -1534,6 +1547,10 @@ SEM ImportDeclaration
lhs . modAsMp = maybe Map.empty (Map.singleton @name) @asname
| * - Import
lhs . modAsMp = Map.empty
+
+SEM Body
+ | Body
+ loc . modAsMp = Map.fromList [ (mimpSource e, mimpAs e) | e <- @extraModImpL ] `Map.union` @importdeclarations.modAsMp
%%]
View
18 EHC/src/ehc/HS/NameDef.cag
@@ -462,7 +462,6 @@ SEM Pattern
%%[9
SEM Declaration
| Instance
- -- loc . instancename= maybe (hsnUniqifyUID HsNameUniqifier_ClassDict @lUniq (mkHNm @name)) id @maybeinstancename -- maybe (hsnSuffix (mkHNm @lUniq) ("_instance_"++ show @name)) id @maybeinstancename
loc . instancename= maybe (hsnUniqifyUID HsNameUniqifier_ClassDict @lUniq (@type.conNm)) id @maybeinstancename -- maybe (hsnSuffix (mkHNm @lUniq) ("_instance_"++ show @name)) id @maybeinstancename
| Class
loc . instancename= hsnUniqifyUID HsNameUniqifier_Class @lUniq (mkHNm @typelefthandside.name) -- hsnSuffix (mkHNm @lUniq) ("_class_"++ show @typelefthandside.name)
@@ -503,3 +502,20 @@ SEM Expression
| * - Constructor
lhs . conNm = hsnUnknown
%%]
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Misc: extra module imports
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%[99
+ATTR Body [ | | extraModImpL: {[ModImp]} ]
+
+SEM Body
+ | Body
+ loc . extraModImpL= if ehcOptOverloadedStrings @lhs.opts
+ then [ModImp True hsnModDataString hsnModDataString False [] @range]
+ else []
+%%]
+
+-- ModEntSpec (hsnQualified hsnDataStringFromString) @range Nothing
+
View
4 EHC/src/ehc/HS/Parser.chs
@@ -615,8 +615,8 @@ pBody' opts addDecl
pDeclarationDefault :: HSParser Declaration
pDeclarationDefault
= (Declaration_Default . mkRange1) <$> pDEFAULT <*> pMb (tokMkQName <$> qtyconid)
- <*> ( (:[]) <$> pTypeBaseCon
- <|> pParens (pListSep pCOMMA pTypeBaseCon)
+ <*> ( (:[]) <$> pTypeBase
+ <|> pParens (pListSep pCOMMA pTypeBase)
)
%%]
View
1 EHC/src/ehc/HS/Pragmas.cag
@@ -32,6 +32,7 @@ SEM Module
| Module
loc . fileHeaderPragmas
= @fileheaderpragmas.gathPragmas
+ . opts = fst $ ehcOptUpdateWithPragmas @fileHeaderPragmas @lhs.opts
%%]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
View
10 EHC/src/ehc/HS/ToEH.cag
@@ -652,6 +652,14 @@ ehExpLitFloat r s sign litrefnames
)
%%]
+%%[99 hs
+ehExpLitString :: EHCOpts -> Range -> String -> [HsName] -> (EH.Expr,Maybe SrcConst)
+ehExpLitString opts r str litrefnames
+ | ehcOptOverloadedStrings opts = (ehExpVarApp r (litrefnames !! 2) [s], Nothing)
+ | otherwise = (s , Nothing)
+ where s = rngLift r EH.Expr_SConst str
+%%]
+
%%[1 hs
ehExpApp' :: (EH.Expr -> a -> EH.Expr) -> Range -> EH.Expr -> [a] -> EH.Expr
ehExpApp' app r f as
@@ -706,6 +714,8 @@ SEM Expression
Literal_Char r s -> rngLift r EH.Expr_CConst (head s)
%%[[5
Literal_String r s -> rngLift r EH.Expr_SConst s
+%%][99
+ Literal_String r s -> fst $ ehExpLitString @lhs.opts r s @litrefnames
%%]]
%%[[97
Literal_Float r s -> fst $ ehExpLitFloat r s 1 @litrefnames
View
3 EHC/text/ToolDocEHC.cltex
@@ -1106,6 +1106,9 @@ The following pragmas are supported.
\item @GenericDeriving@, @NoGenericDeriving@: turn on/off respectively generic deriving, default is on.
\item @BangPatterns@, @NoBangPatterns@: turn on/off respectively bang patterns, default is on.
\item @PolyKinds@, @NoPolyKinds@: turn on/off respectively polymorphic kind inference, default is off.
+\item @OverloadedStrings@, @NoOverloadedStrings@: turn on/off overloaded strings, default is off.
+ See also \href{http://www.haskell.org/ghc/docs/7.0.3/html/users_guide/type-class-extensions.html#overloaded-strings}{GHC doc}.
+ The (current) difference is that the module @Data.String@ is brought in scope, although qualified.
\item @ExtensibleRecords@: turn on special syntax for extensible records. Available for internal backwards compatibility, but otherwise useless as codegeneration and runtime currently does not support extensible records. It reserves the operators \verb|#| and \verb|:=| for record selection and update respectively.
\end{itemize}
\item \verb|{-# DERIVING class field generic-function #-}| pragma: see \lref{generic-deriving}{generic deriving}.

0 comments on commit 1cb861b

Please sign in to comment.
Something went wrong with that request. Please try again.