2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[Inst]{The @Inst@ type: dictionaries or method instances}
7 #include "HsVersions.h"
10 Inst(..), -- Visible only to TcSimplify
12 InstOrigin(..), OverloadedLit(..),
13 SYN_IE(LIE), emptyLIE, unitLIE, plusLIE, consLIE, zonkLIE, plusLIEs,
15 SYN_IE(InstanceMapper),
17 newDicts, newDictsAtLoc, newMethod, newMethodWithGivenTy, newOverloadedLit,
19 instType, tyVarsOfInst, lookupInst, lookupSimpleInst,
26 instBindingRequired, instCanBeGeneralised,
32 IMPORT_1_3(Ratio(Rational))
34 import HsSyn ( HsLit(..), HsExpr(..), HsBinds, Fixity, MonoBinds(..),
35 InPat, OutPat, Stmt, DoOrListComp, Match, GRHSsAndBinds,
36 ArithSeqInfo, HsType, Fake )
37 import RnHsSyn ( SYN_IE(RenamedArithSeqInfo), SYN_IE(RenamedHsExpr) )
38 import TcHsSyn ( TcIdOcc(..), SYN_IE(TcExpr), SYN_IE(TcIdBndr),
39 SYN_IE(TcDictBinds), SYN_IE(TcMonoBinds),
40 mkHsTyApp, mkHsDictApp, tcIdTyVars )
43 import TcEnv ( tcLookupGlobalValueByKey, tcLookupTyConByKey )
44 import TcType ( SYN_IE(TcType), SYN_IE(TcRhoType), TcMaybe, SYN_IE(TcTyVarSet),
45 tcInstType, zonkTcType, tcSplitForAllTy, tcSplitRhoTy )
47 import Bag ( emptyBag, unitBag, unionBags, unionManyBags,
48 listToBag, consBag, Bag )
49 import Class ( classInstEnv,
50 SYN_IE(Class), GenClass, SYN_IE(ClassInstEnv), SYN_IE(ClassOp)
52 import ErrUtils ( addErrLoc, SYN_IE(Error) )
53 import Id ( GenId, idType, mkInstId, SYN_IE(Id) )
54 import PrelInfo ( isCcallishClass, isNoDictClass )
55 import MatchEnv ( lookupMEnv, insertMEnv )
56 import Name ( OccName(..), Name, mkLocalName,
57 mkSysLocalName, occNameString, getOccName )
59 import PprType ( GenClass, TyCon, GenType, GenTyVar, pprParendGenType )
61 import SpecEnv ( SpecEnv )
62 import SrcLoc ( SrcLoc, noSrcLoc )
63 import Type ( GenType, eqSimpleTy, instantiateTy,
64 isTyVarTy, mkDictTy, splitForAllTy, splitSigmaTy,
65 splitRhoTy, matchTy, tyVarsOfType, tyVarsOfTypes,
68 import TyVar ( unionTyVarSets, GenTyVar )
69 import TysPrim ( intPrimTy )
70 import TysWiredIn ( intDataCon, integerTy )
71 import Unique ( showUnique, fromRationalClassOpKey, rationalTyConKey,
72 fromIntClassOpKey, fromIntegerClassOpKey, Unique
74 import Util ( panic, zipEqual, zipWithEqual, assoc, assertPanic, pprTrace{-ToDo:rm-} )
75 #if __GLASGOW_HASKELL__ >= 202
80 %************************************************************************
82 \subsection[Inst-collections]{LIE: a collection of Insts}
84 %************************************************************************
87 type LIE s = Bag (Inst s)
90 unitLIE inst = unitBag inst
91 plusLIE lie1 lie2 = lie1 `unionBags` lie2
92 consLIE inst lie = inst `consBag` lie
93 plusLIEs lies = unionManyBags lies
95 zonkLIE :: LIE s -> NF_TcM s (LIE s)
96 zonkLIE lie = mapBagNF_Tc zonkInst lie
99 %************************************************************************
101 \subsection[Inst-types]{@Inst@ types}
103 %************************************************************************
105 An @Inst@ is either a dictionary, an instance of an overloaded
106 literal, or an instance of an overloaded value. We call the latter a
107 ``method'' even though it may not correspond to a class operation.
108 For example, we might have an instance of the @double@ function at
109 type Int, represented by
111 Method 34 doubleId [Int] origin
117 Class -- The type of the dict is (c t), where
118 (TcType s) -- c is the class and t the type;
125 (TcIdOcc s) -- The overloaded function
126 -- This function will be a global, local, or ClassOpId;
127 -- inside instance decls (only) it can also be an InstId!
128 -- The id needn't be completely polymorphic.
129 -- You'll probably find its name (for documentation purposes)
130 -- inside the InstOrigin
132 [TcType s] -- The types to which its polymorphic tyvars
133 -- should be instantiated.
134 -- These types must saturate the Id's foralls.
136 (TcRhoType s) -- Cached: (type-of-id applied to inst_tys)
137 -- If this type is (theta => tau) then the type of the Method
138 -- is tau, and the method can be built by saying
140 -- where dicts are constructed from theta
148 (TcType s) -- The type at which the literal is used
149 (InstOrigin s) -- Always a literal; but more convenient to carry this around
153 = OverloadedIntegral Integer -- The number
154 | OverloadedFractional Rational -- The number
156 getInstOrigin (Dict u clas ty origin loc) = origin
157 getInstOrigin (Method u clas ty rho origin loc) = origin
158 getInstOrigin (LitInst u lit ty origin loc) = origin
165 newDicts :: InstOrigin s
166 -> [(Class, TcType s)]
167 -> NF_TcM s (LIE s, [TcIdOcc s])
169 = tcGetSrcLoc `thenNF_Tc` \ loc ->
170 newDictsAtLoc orig loc theta `thenNF_Tc` \ (dicts, ids) ->
171 returnNF_Tc (listToBag dicts, ids)
173 tcGetUniques (length theta) `thenNF_Tc` \ new_uniqs ->
175 mk_dict u (clas, ty) = Dict u clas ty orig loc
176 dicts = zipWithEqual "newDicts" mk_dict new_uniqs theta
178 returnNF_Tc (listToBag dicts, map instToId dicts)
181 -- Local function, similar to newDicts,
182 -- but with slightly different interface
183 newDictsAtLoc :: InstOrigin s
185 -> [(Class, TcType s)]
186 -> NF_TcM s ([Inst s], [TcIdOcc s])
187 newDictsAtLoc orig loc theta =
188 tcGetUniques (length theta) `thenNF_Tc` \ new_uniqs ->
190 mk_dict u (clas, ty) = Dict u clas ty orig loc
191 dicts = zipWithEqual "newDictsAtLoc" mk_dict new_uniqs theta
193 returnNF_Tc (dicts, map instToId dicts)
195 newMethod :: InstOrigin s
198 -> NF_TcM s (LIE s, TcIdOcc s)
199 newMethod orig id tys
200 = -- Get the Id type and instantiate it at the specified types
202 RealId id -> let (tyvars, rho) = splitForAllTy (idType id)
204 (if length tyvars /= length tys then pprTrace "newMethod" (ppr PprDebug (idType id)) else \x->x) $
205 tcInstType (zip{-Equal "newMethod"-} tyvars tys) rho
206 TcId id -> tcSplitForAllTy (idType id) `thenNF_Tc` \ (tyvars, rho) ->
207 returnNF_Tc (instantiateTy (zipEqual "newMethod(2)" tyvars tys) rho)
208 ) `thenNF_Tc` \ rho_ty ->
209 -- Our friend does the rest
210 newMethodWithGivenTy orig id tys rho_ty
213 newMethodWithGivenTy orig id tys rho_ty
214 = tcGetSrcLoc `thenNF_Tc` \ loc ->
215 tcGetUnique `thenNF_Tc` \ new_uniq ->
217 meth_inst = Method new_uniq id tys rho_ty orig loc
219 returnNF_Tc (unitLIE meth_inst, instToId meth_inst)
221 newMethodAtLoc :: InstOrigin s -> SrcLoc -> Id -> [TcType s] -> NF_TcM s (Inst s, TcIdOcc s)
222 newMethodAtLoc orig loc real_id tys -- Local function, similar to newMethod but with
223 -- slightly different interface
224 = -- Get the Id type and instantiate it at the specified types
226 (tyvars,rho) = splitForAllTy (idType real_id)
228 tcInstType (zipEqual "newMethodAtLoc" tyvars tys) rho `thenNF_Tc` \ rho_ty ->
229 tcGetUnique `thenNF_Tc` \ new_uniq ->
231 meth_inst = Method new_uniq (RealId real_id) tys rho_ty orig loc
233 returnNF_Tc (meth_inst, instToId meth_inst)
235 newOverloadedLit :: InstOrigin s
238 -> NF_TcM s (LIE s, TcIdOcc s)
239 newOverloadedLit orig lit ty
240 = tcGetSrcLoc `thenNF_Tc` \ loc ->
241 tcGetUnique `thenNF_Tc` \ new_uniq ->
243 lit_inst = LitInst new_uniq lit ty orig loc
245 returnNF_Tc (unitLIE lit_inst, instToId lit_inst)
250 instToId :: Inst s -> TcIdOcc s
251 instToId (Dict u clas ty orig loc)
252 = TcId (mkInstId u (mkDictTy clas ty) (mkLocalName u str loc))
254 str = VarOcc (SLIT("d.") _APPEND_ (occNameString (getOccName clas)))
256 instToId (Method u id tys rho_ty orig loc)
257 = TcId (mkInstId u tau_ty (mkLocalName u occ loc))
260 (_, tau_ty) = splitRhoTy rho_ty
261 -- I hope we don't need tcSplitRhoTy...
262 -- NB The method Id has just the tau type
264 instToId (LitInst u list ty orig loc)
265 = TcId (mkInstId u ty (mkSysLocalName u SLIT("lit") loc))
269 instType :: Inst s -> TcType s
270 instType (Dict _ clas ty _ _) = mkDictTy clas ty
271 instType (LitInst _ _ ty _ _) = ty
272 instType (Method _ id tys ty _ _) = ty
278 Zonking makes sure that the instance types are fully zonked,
279 but doesn't do the same for the Id in a Method. There's no
280 need, and it's a lot of extra work.
283 zonkInst :: Inst s -> NF_TcM s (Inst s)
284 zonkInst (Dict u clas ty orig loc)
285 = zonkTcType ty `thenNF_Tc` \ new_ty ->
286 returnNF_Tc (Dict u clas new_ty orig loc)
288 zonkInst (Method u id tys rho orig loc) -- Doesn't zonk the id!
289 = mapNF_Tc zonkTcType tys `thenNF_Tc` \ new_tys ->
290 zonkTcType rho `thenNF_Tc` \ new_rho ->
291 returnNF_Tc (Method u id new_tys new_rho orig loc)
293 zonkInst (LitInst u lit ty orig loc)
294 = zonkTcType ty `thenNF_Tc` \ new_ty ->
295 returnNF_Tc (LitInst u lit new_ty orig loc)
300 tyVarsOfInst :: Inst s -> TcTyVarSet s
301 tyVarsOfInst (Dict _ _ ty _ _) = tyVarsOfType ty
302 tyVarsOfInst (Method _ id tys rho _ _) = tyVarsOfTypes tys `unionTyVarSets` tcIdTyVars id
303 -- The id might not be a RealId; in the case of
304 -- locally-overloaded class methods, for example
305 tyVarsOfInst (LitInst _ _ ty _ _) = tyVarsOfType ty
308 @matchesInst@ checks when two @Inst@s are instances of the same
309 thing at the same type, even if their uniques differ.
312 matchesInst :: Inst s -> Inst s -> Bool
314 matchesInst (Dict _ clas1 ty1 _ _) (Dict _ clas2 ty2 _ _)
315 = clas1 == clas2 && ty1 `eqSimpleTy` ty2
317 matchesInst (Method _ id1 tys1 _ _ _) (Method _ id2 tys2 _ _ _)
319 && and (zipWith eqSimpleTy tys1 tys2)
320 && length tys1 == length tys2
322 matchesInst (LitInst _ lit1 ty1 _ _) (LitInst _ lit2 ty2 _ _)
323 = lit1 `eq` lit2 && ty1 `eqSimpleTy` ty2
325 (OverloadedIntegral i1) `eq` (OverloadedIntegral i2) = i1 == i2
326 (OverloadedFractional f1) `eq` (OverloadedFractional f2) = f1 == f2
329 matchesInst other1 other2 = False
336 isDict :: Inst s -> Bool
337 isDict (Dict _ _ _ _ _) = True
340 isTyVarDict :: Inst s -> Bool
341 isTyVarDict (Dict _ _ ty _ _) = isTyVarTy ty
342 isTyVarDict other = False
345 Two predicates which deal with the case where class constraints don't
346 necessarily result in bindings. The first tells whether an @Inst@
347 must be witnessed by an actual binding; the second tells whether an
348 @Inst@ can be generalised over.
351 instBindingRequired :: Inst s -> Bool
352 instBindingRequired (Dict _ clas _ _ _) = not (isNoDictClass clas)
353 instBindingRequired other = True
355 instCanBeGeneralised :: Inst s -> Bool
356 instCanBeGeneralised (Dict _ clas _ _ _) = not (isCcallishClass clas)
357 instCanBeGeneralised other = True
363 ToDo: improve these pretty-printing things. The ``origin'' is really only
364 relevant in error messages.
367 instance Outputable (Inst s) where
368 ppr sty inst = pprQuote sty (\ sty -> ppr_inst sty (\ o l -> empty) inst)
370 pprInst sty inst = ppr_inst sty (\ o l -> pprOrigin o l sty) inst
372 ppr_inst sty ppr_orig (LitInst u lit ty orig loc)
373 = hang (ppr_orig orig loc)
375 OverloadedIntegral i -> integer i
376 OverloadedFractional f -> rational f,
381 ppr_inst sty ppr_orig (Dict u clas ty orig loc)
382 = hang (ppr_orig orig loc)
383 4 (pprQuote sty $ \ sty ->
384 hsep [ppr sty clas, pprParendGenType sty ty, show_uniq sty u])
386 ppr_inst sty ppr_orig (Method u id tys rho orig loc)
387 = hang (ppr_orig orig loc)
388 4 (hsep [ppr sty id, ptext SLIT("at"),
389 pprQuote sty $ \ sty -> interppSP sty tys,
392 show_uniq PprDebug u = ppr PprDebug u
393 show_uniq sty u = empty
396 Printing in error messages
399 noInstanceErr inst sty = hang (ptext SLIT("No instance for:")) 4 (ppr sty inst)
402 %************************************************************************
404 \subsection[InstEnv-types]{Type declarations}
406 %************************************************************************
409 type InstanceMapper = Class -> (ClassInstEnv, ClassOp -> SpecEnv)
412 A @ClassInstEnv@ lives inside a class, and identifies all the instances
413 of that class. The @Id@ inside a ClassInstEnv mapping is the dfun for
416 There is an important consistency constraint between the @MatchEnv@s
417 in and the dfun @Id@s inside them: the free type variables of the
418 @Type@ key in the @MatchEnv@ must be a subset of the universally-quantified
419 type variables of the dfun. Thus, the @ClassInstEnv@ for @Eq@ might
420 contain the following entry:
422 [a] ===> dfun_Eq_List :: forall a. Eq a => Eq [a]
424 The "a" in the pattern must be one of the forall'd variables in
430 TcDictBinds s) -- The new binding
434 lookupInst dict@(Dict _ clas ty orig loc)
435 = case lookupMEnv matchTy (get_inst_env clas orig) ty of
436 Nothing -> tcAddSrcLoc loc $
437 tcAddErrCtxt (pprOrigin orig loc) $
438 failTc (noInstanceErr dict)
442 (tyvars, rho) = splitForAllTy (idType dfun_id)
443 ty_args = map (assoc "lookupInst" tenv) tyvars
444 -- tenv should bind all the tyvars
446 tcInstType tenv rho `thenNF_Tc` \ dfun_rho ->
448 (theta, tau) = splitRhoTy dfun_rho
450 newDictsAtLoc orig loc theta `thenNF_Tc` \ (dicts, dict_ids) ->
452 rhs = mkHsDictApp (mkHsTyApp (HsVar (RealId dfun_id)) ty_args) dict_ids
454 returnTc (dicts, VarMonoBind (instToId dict) rhs)
459 lookupInst inst@(Method _ id tys rho orig loc)
460 = tcSplitRhoTy rho `thenNF_Tc` \ (theta, _) ->
461 newDictsAtLoc orig loc theta `thenNF_Tc` \ (dicts, dict_ids) ->
462 returnTc (dicts, VarMonoBind (instToId inst) (mkHsDictApp (mkHsTyApp (HsVar id) tys) dict_ids))
466 lookupInst inst@(LitInst u (OverloadedIntegral i) ty orig loc)
467 | i >= toInteger minInt && i <= toInteger maxInt
468 = -- It's overloaded but small enough to fit into an Int
469 tcLookupGlobalValueByKey fromIntClassOpKey `thenNF_Tc` \ from_int ->
470 newMethodAtLoc orig loc from_int [ty] `thenNF_Tc` \ (method_inst, method_id) ->
471 returnTc ([method_inst], VarMonoBind (instToId inst) (HsApp (HsVar method_id) int_lit))
474 = -- Alas, it is overloaded and a big literal!
475 tcLookupGlobalValueByKey fromIntegerClassOpKey `thenNF_Tc` \ from_integer ->
476 newMethodAtLoc orig loc from_integer [ty] `thenNF_Tc` \ (method_inst, method_id) ->
477 returnTc ([method_inst], VarMonoBind (instToId inst) (HsApp (HsVar method_id) (HsLitOut (HsInt i) integerTy)))
479 intprim_lit = HsLitOut (HsIntPrim i) intPrimTy
480 int_lit = HsApp (HsVar (RealId intDataCon)) intprim_lit
482 lookupInst inst@(LitInst u (OverloadedFractional f) ty orig loc)
483 = tcLookupGlobalValueByKey fromRationalClassOpKey `thenNF_Tc` \ from_rational ->
485 -- The type Rational isn't wired in so we have to conjure it up
486 tcLookupTyConByKey rationalTyConKey `thenNF_Tc` \ rational_tycon ->
488 rational_ty = mkSynTy rational_tycon []
489 rational_lit = HsLitOut (HsFrac f) rational_ty
491 newMethodAtLoc orig loc from_rational [ty] `thenNF_Tc` \ (method_inst, method_id) ->
492 returnTc ([method_inst], VarMonoBind (instToId inst) (HsApp (HsVar method_id) rational_lit))
495 There is a second, simpler interface, when you want an instance of a
496 class at a given nullary type constructor. It just returns the
497 appropriate dictionary if it exists. It is used only when resolving
498 ambiguous dictionaries.
501 lookupSimpleInst :: ClassInstEnv
503 -> Type -- Look up (c,t)
504 -> TcM s [(Class,Type)] -- Here are the needed (c,t)s
506 lookupSimpleInst class_inst_env clas ty
507 = case (lookupMEnv matchTy class_inst_env ty) of
508 Nothing -> failTc (noSimpleInst clas ty)
509 Just (dfun,tenv) -> returnTc [(c,instantiateTy tenv t) | (c,t) <- theta]
511 (_, theta, _) = splitSigmaTy (idType dfun)
513 noSimpleInst clas ty sty
514 = sep [ptext SLIT("No instance for class"), ppr sty clas,
515 ptext SLIT("at type"), ppr sty ty]
519 @mkInstSpecEnv@ is used to construct the @SpecEnv@ for a dfun.
520 It does it by filtering the class's @InstEnv@. All pretty shady stuff.
523 mkInstSpecEnv clas inst_ty inst_tvs inst_theta = panic "mkInstSpecEnv"
527 mkInstSpecEnv :: Class -- class
528 -> Type -- instance type
529 -> [TyVarTemplate] -- instance tyvars
530 -> ThetaType -- superclasses dicts
531 -> SpecEnv -- specenv for dfun of instance
533 mkInstSpecEnv clas inst_ty inst_tvs inst_theta
534 = mkSpecEnv (catMaybes (map maybe_spec_info matches))
536 matches = matchMEnv matchTy (classInstEnv clas) inst_ty
538 maybe_spec_info (_, match_info, MkInstTemplate dfun _ [])
539 = Just (SpecInfo (map (assocMaybe match_info) inst_tvs) (length inst_theta) dfun)
540 maybe_spec_info (_, match_info, _)
547 :: ClassInstEnv -- Incoming envt
548 -> Type -- The instance type: inst_ty
549 -> Id -- Dict fun id to apply. Free tyvars of inst_ty must
550 -- be the same as the forall'd tyvars of the dfun id.
552 ClassInstEnv -- Success
553 (Type, Id) -- Offending overlap
555 addClassInst inst_env inst_ty dfun_id = insertMEnv matchTy inst_env inst_ty dfun_id
560 %************************************************************************
562 \subsection[Inst-origin]{The @InstOrigin@ type}
564 %************************************************************************
566 The @InstOrigin@ type gives information about where a dictionary came from.
567 This is important for decent error message reporting because dictionaries
568 don't appear in the original source code. Doubtless this type will evolve...
572 = OccurrenceOf (TcIdOcc s) -- Occurrence of an overloaded identifier
573 | OccurrenceOfCon Id -- Occurrence of a data constructor
577 | DataDeclOrigin -- Typechecking a data declaration
579 | InstanceDeclOrigin -- Typechecking an instance decl
581 | LiteralOrigin HsLit -- Occurrence of a literal
583 | ArithSeqOrigin RenamedArithSeqInfo -- [x..], [x..y] etc
585 | SignatureOrigin -- A dict created from a type signature
587 | DoOrigin -- The monad for a do expression
589 | ClassDeclOrigin -- Manufactured during a class decl
592 -- | DerivingOrigin InstanceMapper
596 -- During "deriving" operations we have an ever changing
597 -- mapping of classes to instances, so we record it inside the
598 -- origin information. This is a bit of a hack, but it works
599 -- fine. (Simon is to blame [WDP].)
601 | InstanceSpecOrigin InstanceMapper
602 Class -- in a SPECIALIZE instance pragma
605 -- When specialising instances the instance info attached to
606 -- each class is not yet ready, so we record it inside the
607 -- origin information. This is a bit of a hack, but it works
608 -- fine. (Patrick is to blame [WDP].)
610 -- | DefaultDeclOrigin -- Related to a `default' declaration
612 | ValSpecOrigin Name -- in a SPECIALIZE pragma for a value
614 -- Argument or result of a ccall
615 -- Dictionaries with this origin aren't actually mentioned in the
616 -- translated term, and so need not be bound. Nor should they
617 -- be abstracted over.
619 | CCallOrigin String -- CCall label
620 (Maybe RenamedHsExpr) -- Nothing if it's the result
621 -- Just arg, for an argument
623 | LitLitOrigin String -- the litlit
625 | UnknownOrigin -- Help! I give up...
629 -- During deriving and instance specialisation operations
630 -- we can't get the instances of the class from inside the
631 -- class, because the latter ain't ready yet. Instead we
632 -- find a mapping from classes to envts inside the dict origin.
634 get_inst_env :: Class -> InstOrigin s -> ClassInstEnv
635 -- get_inst_env clas (DerivingOrigin inst_mapper _ _)
636 -- = fst (inst_mapper clas)
637 get_inst_env clas (InstanceSpecOrigin inst_mapper _ _)
638 = fst (inst_mapper clas)
639 get_inst_env clas other_orig = classInstEnv clas
642 pprOrigin :: InstOrigin s -> SrcLoc -> Error
644 pprOrigin orig locn sty
645 = hsep [text "arising from", pp_orig, text "at", ppr sty locn]
650 hsep [ptext SLIT("use of"), ppr sty id]
651 OccurrenceOfCon id ->
652 hsep [ptext SLIT("use of"), ppr sty id]
654 hsep [ptext SLIT("the literal"), ppr sty lit]
655 InstanceDeclOrigin ->
656 ptext SLIT("an instance declaration")
657 ArithSeqOrigin seq ->
658 hsep [ptext SLIT("the arithmetic sequence:"), ppr sty seq]
660 ptext SLIT("a type signature")
662 ptext SLIT("a do statement")
664 ptext SLIT("a class declaration")
665 InstanceSpecOrigin _ clas ty ->
666 hsep [text "a SPECIALIZE instance pragma; class",
667 ppr sty clas, text "type:", ppr sty ty]
668 ValSpecOrigin name ->
669 hsep [ptext SLIT("a SPECIALIZE user-pragma for"), ppr sty name]
670 CCallOrigin clabel Nothing{-ccall result-} ->
671 hsep [ptext SLIT("the result of the _ccall_ to"), text clabel]
672 CCallOrigin clabel (Just arg_expr) ->
673 hsep [ptext SLIT("an argument in the _ccall_ to"), text clabel <> comma, text "namely", ppr sty arg_expr]
675 hcat [ptext SLIT("the ``literal-literal''"), text s]
677 ptext SLIT("...oops -- I don't know where the overloading came from!")