types.nim 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2013 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. # this module contains routines for accessing and iterating over types
  10. import
  11. intsets, ast, astalgo, trees, msgs, strutils, platform, renderer
  12. proc firstOrd*(t: PType): BiggestInt
  13. proc lastOrd*(t: PType): BiggestInt
  14. proc lengthOrd*(t: PType): BiggestInt
  15. type
  16. TPreferedDesc* = enum
  17. preferName, preferDesc, preferExported, preferModuleInfo, preferGenericArg
  18. proc typeToString*(typ: PType; prefer: TPreferedDesc = preferName): string
  19. template `$`*(typ: PType): string = typeToString(typ)
  20. proc base*(t: PType): PType =
  21. result = t.sons[0]
  22. # ------------------- type iterator: ----------------------------------------
  23. type
  24. TTypeIter* = proc (t: PType, closure: RootRef): bool {.nimcall.} # true if iteration should stop
  25. TTypeMutator* = proc (t: PType, closure: RootRef): PType {.nimcall.} # copy t and mutate it
  26. TTypePredicate* = proc (t: PType): bool {.nimcall.}
  27. proc iterOverType*(t: PType, iter: TTypeIter, closure: RootRef): bool
  28. # Returns result of `iter`.
  29. proc mutateType*(t: PType, iter: TTypeMutator, closure: RootRef): PType
  30. # Returns result of `iter`.
  31. type
  32. TParamsEquality* = enum # they are equal, but their
  33. # identifiers or their return
  34. # type differ (i.e. they cannot be
  35. # overloaded)
  36. # this used to provide better error messages
  37. paramsNotEqual, # parameters are not equal
  38. paramsEqual, # parameters are equal
  39. paramsIncompatible
  40. proc equalParams*(a, b: PNode): TParamsEquality
  41. # returns whether the parameter lists of the procs a, b are exactly the same
  42. proc isOrdinalType*(t: PType): bool
  43. proc enumHasHoles*(t: PType): bool
  44. const
  45. # TODO: Remove tyTypeDesc from each abstractX and (where necessary)
  46. # replace with typedescX
  47. abstractPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyDistinct, tyOrdinal,
  48. tyTypeDesc, tyAlias, tyInferred}
  49. abstractVar* = {tyVar, tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc,
  50. tyAlias, tyInferred}
  51. abstractRange* = {tyGenericInst, tyRange, tyDistinct, tyOrdinal, tyTypeDesc,
  52. tyAlias, tyInferred}
  53. abstractVarRange* = {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal,
  54. tyTypeDesc, tyAlias, tyInferred}
  55. abstractInst* = {tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc, tyAlias,
  56. tyInferred}
  57. skipPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyTypeDesc, tyAlias,
  58. tyInferred}
  59. # typedescX is used if we're sure tyTypeDesc should be included (or skipped)
  60. typedescPtrs* = abstractPtrs + {tyTypeDesc}
  61. typedescInst* = abstractInst + {tyTypeDesc}
  62. proc containsObject*(t: PType): bool
  63. proc containsGarbageCollectedRef*(typ: PType): bool
  64. proc containsHiddenPointer*(typ: PType): bool
  65. proc canFormAcycle*(typ: PType): bool
  66. proc isCompatibleToCString*(a: PType): bool
  67. proc getOrdValue*(n: PNode): BiggestInt
  68. proc computeSize*(typ: PType): BiggestInt
  69. proc getSize*(typ: PType): BiggestInt
  70. proc isPureObject*(typ: PType): bool
  71. proc invalidGenericInst*(f: PType): bool
  72. # for debugging
  73. type
  74. TTypeFieldResult* = enum
  75. frNone, # type has no object type field
  76. frHeader, # type has an object type field only in the header
  77. frEmbedded # type has an object type field somewhere embedded
  78. proc analyseObjectWithTypeField*(t: PType): TTypeFieldResult
  79. # this does a complex analysis whether a call to ``objectInit`` needs to be
  80. # made or intializing of the type field suffices or if there is no type field
  81. # at all in this type.
  82. proc invalidGenericInst(f: PType): bool =
  83. result = f.kind == tyGenericInst and lastSon(f) == nil
  84. proc isPureObject(typ: PType): bool =
  85. var t = typ
  86. while t.kind == tyObject and t.sons[0] != nil:
  87. t = t.sons[0].skipTypes(skipPtrs)
  88. result = t.sym != nil and sfPure in t.sym.flags
  89. proc getOrdValue(n: PNode): BiggestInt =
  90. case n.kind
  91. of nkCharLit..nkUInt64Lit: result = n.intVal
  92. of nkNilLit: result = 0
  93. of nkHiddenStdConv: result = getOrdValue(n.sons[1])
  94. else:
  95. localError(n.info, errOrdinalTypeExpected)
  96. result = 0
  97. proc isIntLit*(t: PType): bool {.inline.} =
  98. result = t.kind == tyInt and t.n != nil and t.n.kind == nkIntLit
  99. proc isFloatLit*(t: PType): bool {.inline.} =
  100. result = t.kind == tyFloat and t.n != nil and t.n.kind == nkFloatLit
  101. proc isCompatibleToCString(a: PType): bool =
  102. if a.kind == tyArray:
  103. if (firstOrd(a.sons[0]) == 0) and
  104. (skipTypes(a.sons[0], {tyRange, tyGenericInst, tyAlias}).kind in
  105. {tyInt..tyInt64, tyUInt..tyUInt64}) and
  106. (a.sons[1].kind == tyChar):
  107. result = true
  108. proc getProcHeader*(sym: PSym; prefer: TPreferedDesc = preferName): string =
  109. result = sym.owner.name.s & '.' & sym.name.s & '('
  110. var n = sym.typ.n
  111. for i in countup(1, sonsLen(n) - 1):
  112. var p = n.sons[i]
  113. if p.kind == nkSym:
  114. add(result, p.sym.name.s)
  115. add(result, ": ")
  116. add(result, typeToString(p.sym.typ, prefer))
  117. if i != sonsLen(n)-1: add(result, ", ")
  118. else:
  119. internalError("getProcHeader")
  120. add(result, ')')
  121. if n.sons[0].typ != nil:
  122. result.add(": " & typeToString(n.sons[0].typ, prefer))
  123. result.add "[declared in "
  124. result.add($sym.info)
  125. result.add "]"
  126. proc elemType*(t: PType): PType =
  127. assert(t != nil)
  128. case t.kind
  129. of tyGenericInst, tyDistinct, tyAlias: result = elemType(lastSon(t))
  130. of tyArray: result = t.sons[1]
  131. else: result = t.lastSon
  132. assert(result != nil)
  133. proc isOrdinalType(t: PType): bool =
  134. assert(t != nil)
  135. const
  136. # caution: uint, uint64 are no ordinal types!
  137. baseKinds = {tyChar,tyInt..tyInt64,tyUInt8..tyUInt32,tyBool,tyEnum}
  138. parentKinds = {tyRange, tyOrdinal, tyGenericInst, tyAlias, tyDistinct}
  139. t.kind in baseKinds or (t.kind in parentKinds and isOrdinalType(t.sons[0]))
  140. proc enumHasHoles(t: PType): bool =
  141. var b = t
  142. while b.kind in {tyRange, tyGenericInst, tyAlias}: b = b.sons[0]
  143. result = b.kind == tyEnum and tfEnumHasHoles in b.flags
  144. proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter,
  145. closure: RootRef): bool
  146. proc iterOverNode(marker: var IntSet, n: PNode, iter: TTypeIter,
  147. closure: RootRef): bool =
  148. if n != nil:
  149. case n.kind
  150. of nkNone..nkNilLit:
  151. # a leaf
  152. result = iterOverTypeAux(marker, n.typ, iter, closure)
  153. else:
  154. for i in countup(0, sonsLen(n) - 1):
  155. result = iterOverNode(marker, n.sons[i], iter, closure)
  156. if result: return
  157. proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter,
  158. closure: RootRef): bool =
  159. result = false
  160. if t == nil: return
  161. result = iter(t, closure)
  162. if result: return
  163. if not containsOrIncl(marker, t.id):
  164. case t.kind
  165. of tyGenericInst, tyGenericBody, tyAlias, tyInferred:
  166. result = iterOverTypeAux(marker, lastSon(t), iter, closure)
  167. else:
  168. for i in countup(0, sonsLen(t) - 1):
  169. result = iterOverTypeAux(marker, t.sons[i], iter, closure)
  170. if result: return
  171. if t.n != nil: result = iterOverNode(marker, t.n, iter, closure)
  172. proc iterOverType(t: PType, iter: TTypeIter, closure: RootRef): bool =
  173. var marker = initIntSet()
  174. result = iterOverTypeAux(marker, t, iter, closure)
  175. proc searchTypeForAux(t: PType, predicate: TTypePredicate,
  176. marker: var IntSet): bool
  177. proc searchTypeNodeForAux(n: PNode, p: TTypePredicate,
  178. marker: var IntSet): bool =
  179. result = false
  180. case n.kind
  181. of nkRecList:
  182. for i in countup(0, sonsLen(n) - 1):
  183. result = searchTypeNodeForAux(n.sons[i], p, marker)
  184. if result: return
  185. of nkRecCase:
  186. assert(n.sons[0].kind == nkSym)
  187. result = searchTypeNodeForAux(n.sons[0], p, marker)
  188. if result: return
  189. for i in countup(1, sonsLen(n) - 1):
  190. case n.sons[i].kind
  191. of nkOfBranch, nkElse:
  192. result = searchTypeNodeForAux(lastSon(n.sons[i]), p, marker)
  193. if result: return
  194. else: internalError("searchTypeNodeForAux(record case branch)")
  195. of nkSym:
  196. result = searchTypeForAux(n.sym.typ, p, marker)
  197. else: internalError(n.info, "searchTypeNodeForAux()")
  198. proc searchTypeForAux(t: PType, predicate: TTypePredicate,
  199. marker: var IntSet): bool =
  200. # iterates over VALUE types!
  201. result = false
  202. if t == nil: return
  203. if containsOrIncl(marker, t.id): return
  204. result = predicate(t)
  205. if result: return
  206. case t.kind
  207. of tyObject:
  208. if t.sons[0] != nil:
  209. result = searchTypeForAux(t.sons[0].skipTypes(skipPtrs), predicate, marker)
  210. if not result: result = searchTypeNodeForAux(t.n, predicate, marker)
  211. of tyGenericInst, tyDistinct, tyAlias:
  212. result = searchTypeForAux(lastSon(t), predicate, marker)
  213. of tyArray, tySet, tyTuple:
  214. for i in countup(0, sonsLen(t) - 1):
  215. result = searchTypeForAux(t.sons[i], predicate, marker)
  216. if result: return
  217. else:
  218. discard
  219. proc searchTypeFor(t: PType, predicate: TTypePredicate): bool =
  220. var marker = initIntSet()
  221. result = searchTypeForAux(t, predicate, marker)
  222. proc isObjectPredicate(t: PType): bool =
  223. result = t.kind == tyObject
  224. proc containsObject(t: PType): bool =
  225. result = searchTypeFor(t, isObjectPredicate)
  226. proc isObjectWithTypeFieldPredicate(t: PType): bool =
  227. result = t.kind == tyObject and t.sons[0] == nil and
  228. not (t.sym != nil and {sfPure, sfInfixCall} * t.sym.flags != {}) and
  229. tfFinal notin t.flags
  230. proc analyseObjectWithTypeFieldAux(t: PType,
  231. marker: var IntSet): TTypeFieldResult =
  232. var res: TTypeFieldResult
  233. result = frNone
  234. if t == nil: return
  235. case t.kind
  236. of tyObject:
  237. if (t.n != nil):
  238. if searchTypeNodeForAux(t.n, isObjectWithTypeFieldPredicate, marker):
  239. return frEmbedded
  240. for i in countup(0, sonsLen(t) - 1):
  241. var x = t.sons[i]
  242. if x != nil: x = x.skipTypes(skipPtrs)
  243. res = analyseObjectWithTypeFieldAux(x, marker)
  244. if res == frEmbedded:
  245. return frEmbedded
  246. if res == frHeader: result = frHeader
  247. if result == frNone:
  248. if isObjectWithTypeFieldPredicate(t): result = frHeader
  249. of tyGenericInst, tyDistinct, tyAlias:
  250. result = analyseObjectWithTypeFieldAux(lastSon(t), marker)
  251. of tyArray, tyTuple:
  252. for i in countup(0, sonsLen(t) - 1):
  253. res = analyseObjectWithTypeFieldAux(t.sons[i], marker)
  254. if res != frNone:
  255. return frEmbedded
  256. else:
  257. discard
  258. proc analyseObjectWithTypeField(t: PType): TTypeFieldResult =
  259. var marker = initIntSet()
  260. result = analyseObjectWithTypeFieldAux(t, marker)
  261. proc isGCRef(t: PType): bool =
  262. result = t.kind in GcTypeKinds or
  263. (t.kind == tyProc and t.callConv == ccClosure)
  264. proc containsGarbageCollectedRef(typ: PType): bool =
  265. # returns true if typ contains a reference, sequence or string (all the
  266. # things that are garbage-collected)
  267. result = searchTypeFor(typ, isGCRef)
  268. proc isTyRef(t: PType): bool =
  269. result = t.kind == tyRef or (t.kind == tyProc and t.callConv == ccClosure)
  270. proc containsTyRef*(typ: PType): bool =
  271. # returns true if typ contains a 'ref'
  272. result = searchTypeFor(typ, isTyRef)
  273. proc isHiddenPointer(t: PType): bool =
  274. result = t.kind in {tyString, tySequence}
  275. proc containsHiddenPointer(typ: PType): bool =
  276. # returns true if typ contains a string, table or sequence (all the things
  277. # that need to be copied deeply)
  278. result = searchTypeFor(typ, isHiddenPointer)
  279. proc canFormAcycleAux(marker: var IntSet, typ: PType, startId: int): bool
  280. proc canFormAcycleNode(marker: var IntSet, n: PNode, startId: int): bool =
  281. result = false
  282. if n != nil:
  283. result = canFormAcycleAux(marker, n.typ, startId)
  284. if not result:
  285. case n.kind
  286. of nkNone..nkNilLit:
  287. discard
  288. else:
  289. for i in countup(0, sonsLen(n) - 1):
  290. result = canFormAcycleNode(marker, n.sons[i], startId)
  291. if result: return
  292. proc canFormAcycleAux(marker: var IntSet, typ: PType, startId: int): bool =
  293. result = false
  294. if typ == nil: return
  295. if tfAcyclic in typ.flags: return
  296. var t = skipTypes(typ, abstractInst-{tyTypeDesc})
  297. if tfAcyclic in t.flags: return
  298. case t.kind
  299. of tyTuple, tyObject, tyRef, tySequence, tyArray, tyOpenArray, tyVarargs:
  300. if not containsOrIncl(marker, t.id):
  301. for i in countup(0, sonsLen(t) - 1):
  302. result = canFormAcycleAux(marker, t.sons[i], startId)
  303. if result: return
  304. if t.n != nil: result = canFormAcycleNode(marker, t.n, startId)
  305. else:
  306. result = t.id == startId
  307. # Inheritance can introduce cyclic types, however this is not relevant
  308. # as the type that is passed to 'new' is statically known!
  309. # er but we use it also for the write barrier ...
  310. if t.kind == tyObject and tfFinal notin t.flags:
  311. # damn inheritance may introduce cycles:
  312. result = true
  313. of tyProc: result = typ.callConv == ccClosure
  314. else: discard
  315. proc canFormAcycle(typ: PType): bool =
  316. var marker = initIntSet()
  317. result = canFormAcycleAux(marker, typ, typ.id)
  318. proc mutateTypeAux(marker: var IntSet, t: PType, iter: TTypeMutator,
  319. closure: RootRef): PType
  320. proc mutateNode(marker: var IntSet, n: PNode, iter: TTypeMutator,
  321. closure: RootRef): PNode =
  322. result = nil
  323. if n != nil:
  324. result = copyNode(n)
  325. result.typ = mutateTypeAux(marker, n.typ, iter, closure)
  326. case n.kind
  327. of nkNone..nkNilLit:
  328. # a leaf
  329. discard
  330. else:
  331. for i in countup(0, sonsLen(n) - 1):
  332. addSon(result, mutateNode(marker, n.sons[i], iter, closure))
  333. proc mutateTypeAux(marker: var IntSet, t: PType, iter: TTypeMutator,
  334. closure: RootRef): PType =
  335. result = nil
  336. if t == nil: return
  337. result = iter(t, closure)
  338. if not containsOrIncl(marker, t.id):
  339. for i in countup(0, sonsLen(t) - 1):
  340. result.sons[i] = mutateTypeAux(marker, result.sons[i], iter, closure)
  341. if t.n != nil: result.n = mutateNode(marker, t.n, iter, closure)
  342. assert(result != nil)
  343. proc mutateType(t: PType, iter: TTypeMutator, closure: RootRef): PType =
  344. var marker = initIntSet()
  345. result = mutateTypeAux(marker, t, iter, closure)
  346. proc valueToString(a: PNode): string =
  347. case a.kind
  348. of nkCharLit..nkUInt64Lit: result = $a.intVal
  349. of nkFloatLit..nkFloat128Lit: result = $a.floatVal
  350. of nkStrLit..nkTripleStrLit: result = a.strVal
  351. else: result = "<invalid value>"
  352. proc rangeToStr(n: PNode): string =
  353. assert(n.kind == nkRange)
  354. result = valueToString(n.sons[0]) & ".." & valueToString(n.sons[1])
  355. const
  356. typeToStr: array[TTypeKind, string] = ["None", "bool", "Char", "empty",
  357. "Alias", "nil", "untyped", "typed", "typeDesc",
  358. "GenericInvocation", "GenericBody", "GenericInst", "GenericParam",
  359. "distinct $1", "enum", "ordinal[$1]", "array[$1, $2]", "object", "tuple",
  360. "set[$1]", "range[$1]", "ptr ", "ref ", "var ", "seq[$1]", "proc",
  361. "pointer", "OpenArray[$1]", "string", "CString", "Forward",
  362. "int", "int8", "int16", "int32", "int64",
  363. "float", "float32", "float64", "float128",
  364. "uint", "uint8", "uint16", "uint32", "uint64",
  365. "unused0", "unused1",
  366. "unused2", "varargs[$1]", "unused", "Error Type",
  367. "BuiltInTypeClass", "UserTypeClass",
  368. "UserTypeClassInst", "CompositeTypeClass", "inferred",
  369. "and", "or", "not", "any", "static", "TypeFromExpr", "FieldAccessor",
  370. "void"]
  371. const preferToResolveSymbols = {preferName, preferModuleInfo, preferGenericArg}
  372. template bindConcreteTypeToUserTypeClass*(tc, concrete: PType) =
  373. tc.sons.safeAdd concrete
  374. tc.flags.incl tfResolved
  375. # TODO: It would be a good idea to kill the special state of a resolved
  376. # concept by switching to tyAlias within the instantiated procs.
  377. # Currently, tyAlias is always skipped with lastSon, which means that
  378. # we can store information about the matched concept in another position.
  379. # Then builtInFieldAccess can be modified to properly read the derived
  380. # consts and types stored within the concept.
  381. template isResolvedUserTypeClass*(t: PType): bool =
  382. tfResolved in t.flags
  383. proc addTypeFlags(name: var string, typ: PType) {.inline.} =
  384. if tfNotNil in typ.flags: name.add(" not nil")
  385. proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
  386. var t = typ
  387. result = ""
  388. if t == nil: return
  389. if prefer in preferToResolveSymbols and t.sym != nil and
  390. sfAnon notin t.sym.flags:
  391. if t.kind == tyInt and isIntLit(t):
  392. result = t.sym.name.s & " literal(" & $t.n.intVal & ")"
  393. elif prefer == preferName or t.sym.owner.isNil:
  394. result = t.sym.name.s
  395. if t.kind == tyGenericParam and t.sons != nil and t.sonsLen > 0:
  396. result.add ": "
  397. var first = true
  398. for son in t.sons:
  399. if not first: result.add " or "
  400. result.add son.typeToString
  401. first = false
  402. else:
  403. result = t.sym.owner.name.s & '.' & t.sym.name.s
  404. result.addTypeFlags(t)
  405. return
  406. case t.kind
  407. of tyInt:
  408. if not isIntLit(t) or prefer == preferExported:
  409. result = typeToStr[t.kind]
  410. else:
  411. if prefer == preferGenericArg:
  412. result = $t.n.intVal
  413. else:
  414. result = "int literal(" & $t.n.intVal & ")"
  415. of tyGenericBody, tyGenericInst, tyGenericInvocation:
  416. result = typeToString(t.sons[0]) & '['
  417. for i in countup(1, sonsLen(t)-1-ord(t.kind != tyGenericInvocation)):
  418. if i > 1: add(result, ", ")
  419. add(result, typeToString(t.sons[i], preferGenericArg))
  420. add(result, ']')
  421. of tyTypeDesc:
  422. if t.sons[0].kind == tyNone: result = "typedesc"
  423. else: result = "type " & typeToString(t.sons[0])
  424. of tyStatic:
  425. internalAssert t.len > 0
  426. if prefer == preferGenericArg and t.n != nil:
  427. result = t.n.renderTree
  428. else:
  429. result = "static[" & typeToString(t.sons[0]) & "]"
  430. if t.n != nil: result.add "(" & renderTree(t.n) & ")"
  431. of tyUserTypeClass:
  432. internalAssert t.sym != nil and t.sym.owner != nil
  433. if t.isResolvedUserTypeClass: return typeToString(t.lastSon)
  434. return t.sym.owner.name.s
  435. of tyBuiltInTypeClass:
  436. result = case t.base.kind:
  437. of tyVar: "var"
  438. of tyRef: "ref"
  439. of tyPtr: "ptr"
  440. of tySequence: "seq"
  441. of tyArray: "array"
  442. of tySet: "set"
  443. of tyRange: "range"
  444. of tyDistinct: "distinct"
  445. of tyProc: "proc"
  446. of tyObject: "object"
  447. of tyTuple: "tuple"
  448. of tyOpenArray: "openarray"
  449. else: typeToStr[t.base.kind]
  450. of tyInferred:
  451. let concrete = t.previouslyInferred
  452. if concrete != nil: result = typeToString(concrete)
  453. else: result = "inferred[" & typeToString(t.base) & "]"
  454. of tyUserTypeClassInst:
  455. let body = t.base
  456. result = body.sym.name.s & "["
  457. for i in countup(1, sonsLen(t) - 2):
  458. if i > 1: add(result, ", ")
  459. add(result, typeToString(t.sons[i]))
  460. result.add "]"
  461. of tyAnd:
  462. result = typeToString(t.sons[0]) & " and " & typeToString(t.sons[1])
  463. of tyOr:
  464. result = typeToString(t.sons[0]) & " or " & typeToString(t.sons[1])
  465. of tyNot:
  466. result = "not " & typeToString(t.sons[0])
  467. of tyExpr:
  468. internalAssert t.len == 0
  469. result = "untyped"
  470. of tyFromExpr, tyFieldAccessor:
  471. result = renderTree(t.n)
  472. of tyArray:
  473. if t.sons[0].kind == tyRange:
  474. result = "array[" & rangeToStr(t.sons[0].n) & ", " &
  475. typeToString(t.sons[1]) & ']'
  476. else:
  477. result = "array[" & typeToString(t.sons[0]) & ", " &
  478. typeToString(t.sons[1]) & ']'
  479. of tySequence:
  480. result = "seq[" & typeToString(t.sons[0]) & ']'
  481. of tyOrdinal:
  482. result = "ordinal[" & typeToString(t.sons[0]) & ']'
  483. of tySet:
  484. result = "set[" & typeToString(t.sons[0]) & ']'
  485. of tyOpenArray:
  486. result = "openarray[" & typeToString(t.sons[0]) & ']'
  487. of tyDistinct:
  488. result = "distinct " & typeToString(t.sons[0],
  489. if prefer == preferModuleInfo: preferModuleInfo else: preferName)
  490. of tyTuple:
  491. # we iterate over t.sons here, because t.n may be nil
  492. if t.n != nil:
  493. result = "tuple["
  494. assert(sonsLen(t.n) == sonsLen(t))
  495. for i in countup(0, sonsLen(t.n) - 1):
  496. assert(t.n.sons[i].kind == nkSym)
  497. add(result, t.n.sons[i].sym.name.s & ": " & typeToString(t.sons[i]))
  498. if i < sonsLen(t.n) - 1: add(result, ", ")
  499. add(result, ']')
  500. elif sonsLen(t) == 0:
  501. result = "tuple[]"
  502. else:
  503. result = "("
  504. for i in countup(0, sonsLen(t) - 1):
  505. add(result, typeToString(t.sons[i]))
  506. if i < sonsLen(t) - 1: add(result, ", ")
  507. add(result, ')')
  508. of tyPtr, tyRef, tyVar:
  509. result = typeToStr[t.kind]
  510. if t.len >= 2:
  511. setLen(result, result.len-1)
  512. result.add '['
  513. for i in countup(0, sonsLen(t) - 1):
  514. add(result, typeToString(t.sons[i]))
  515. if i < sonsLen(t) - 1: add(result, ", ")
  516. result.add ']'
  517. else:
  518. result.add typeToString(t.sons[0])
  519. of tyRange:
  520. result = "range "
  521. if t.n != nil and t.n.kind == nkRange:
  522. result.add rangeToStr(t.n)
  523. if prefer != preferExported:
  524. result.add("(" & typeToString(t.sons[0]) & ")")
  525. of tyProc:
  526. result = if tfIterator in t.flags: "iterator " else: "proc "
  527. if tfUnresolved in t.flags: result.add "[*missing parameters*]"
  528. result.add "("
  529. for i in countup(1, sonsLen(t) - 1):
  530. if t.n != nil and i < t.n.len and t.n[i].kind == nkSym:
  531. add(result, t.n[i].sym.name.s)
  532. add(result, ": ")
  533. add(result, typeToString(t.sons[i]))
  534. if i < sonsLen(t) - 1: add(result, ", ")
  535. add(result, ')')
  536. if t.sons[0] != nil: add(result, ": " & typeToString(t.sons[0]))
  537. var prag = if t.callConv == ccDefault: "" else: CallingConvToStr[t.callConv]
  538. if tfNoSideEffect in t.flags:
  539. addSep(prag)
  540. add(prag, "noSideEffect")
  541. if tfThread in t.flags:
  542. addSep(prag)
  543. add(prag, "gcsafe")
  544. if t.lockLevel.ord != UnspecifiedLockLevel.ord:
  545. addSep(prag)
  546. add(prag, "locks: " & $t.lockLevel)
  547. if len(prag) != 0: add(result, "{." & prag & ".}")
  548. of tyVarargs:
  549. result = typeToStr[t.kind] % typeToString(t.sons[0])
  550. else:
  551. result = typeToStr[t.kind]
  552. result.addTypeFlags(t)
  553. proc firstOrd(t: PType): BiggestInt =
  554. case t.kind
  555. of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyProxy:
  556. result = 0
  557. of tySet, tyVar: result = firstOrd(t.sons[0])
  558. of tyArray: result = firstOrd(t.sons[0])
  559. of tyRange:
  560. assert(t.n != nil) # range directly given:
  561. assert(t.n.kind == nkRange)
  562. result = getOrdValue(t.n.sons[0])
  563. of tyInt:
  564. if platform.intSize == 4: result = - (2147483646) - 2
  565. else: result = 0x8000000000000000'i64
  566. of tyInt8: result = - 128
  567. of tyInt16: result = - 32768
  568. of tyInt32: result = - 2147483646 - 2
  569. of tyInt64: result = 0x8000000000000000'i64
  570. of tyUInt..tyUInt64: result = 0
  571. of tyEnum:
  572. # if basetype <> nil then return firstOrd of basetype
  573. if sonsLen(t) > 0 and t.sons[0] != nil:
  574. result = firstOrd(t.sons[0])
  575. else:
  576. assert(t.n.sons[0].kind == nkSym)
  577. result = t.n.sons[0].sym.position
  578. of tyGenericInst, tyDistinct, tyTypeDesc, tyFieldAccessor, tyAlias:
  579. result = firstOrd(lastSon(t))
  580. of tyOrdinal:
  581. if t.len > 0: result = firstOrd(lastSon(t))
  582. else: internalError("invalid kind for first(" & $t.kind & ')')
  583. else:
  584. internalError("invalid kind for first(" & $t.kind & ')')
  585. result = 0
  586. proc lastOrd(t: PType): BiggestInt =
  587. case t.kind
  588. of tyBool: result = 1
  589. of tyChar: result = 255
  590. of tySet, tyVar: result = lastOrd(t.sons[0])
  591. of tyArray: result = lastOrd(t.sons[0])
  592. of tyRange:
  593. assert(t.n != nil) # range directly given:
  594. assert(t.n.kind == nkRange)
  595. result = getOrdValue(t.n.sons[1])
  596. of tyInt:
  597. if platform.intSize == 4: result = 0x7FFFFFFF
  598. else: result = 0x7FFFFFFFFFFFFFFF'i64
  599. of tyInt8: result = 0x0000007F
  600. of tyInt16: result = 0x00007FFF
  601. of tyInt32: result = 0x7FFFFFFF
  602. of tyInt64: result = 0x7FFFFFFFFFFFFFFF'i64
  603. of tyUInt:
  604. if platform.intSize == 4: result = 0xFFFFFFFF
  605. else: result = 0x7FFFFFFFFFFFFFFF'i64
  606. of tyUInt8: result = 0xFF
  607. of tyUInt16: result = 0xFFFF
  608. of tyUInt32: result = 0xFFFFFFFF
  609. of tyUInt64: result = 0x7FFFFFFFFFFFFFFF'i64
  610. of tyEnum:
  611. assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
  612. result = t.n.sons[sonsLen(t.n) - 1].sym.position
  613. of tyGenericInst, tyDistinct, tyTypeDesc, tyFieldAccessor, tyAlias:
  614. result = lastOrd(lastSon(t))
  615. of tyProxy: result = 0
  616. of tyOrdinal:
  617. if t.len > 0: result = lastOrd(lastSon(t))
  618. else: internalError("invalid kind for last(" & $t.kind & ')')
  619. else:
  620. internalError("invalid kind for last(" & $t.kind & ')')
  621. result = 0
  622. proc lengthOrd(t: PType): BiggestInt =
  623. case t.kind
  624. of tyInt64, tyInt32, tyInt: result = lastOrd(t)
  625. of tyDistinct: result = lengthOrd(t.sons[0])
  626. else:
  627. let last = lastOrd t
  628. let first = firstOrd t
  629. # XXX use a better overflow check here:
  630. if last == high(BiggestInt) and first <= 0:
  631. result = last
  632. else:
  633. result = lastOrd(t) - firstOrd(t) + 1
  634. # -------------- type equality -----------------------------------------------
  635. type
  636. TDistinctCompare* = enum ## how distinct types are to be compared
  637. dcEq, ## a and b should be the same type
  638. dcEqIgnoreDistinct, ## compare symmetrically: (distinct a) == b, a == b
  639. ## or a == (distinct b)
  640. dcEqOrDistinctOf ## a equals b or a is distinct of b
  641. TTypeCmpFlag* = enum
  642. IgnoreTupleFields ## NOTE: Only set this flag for backends!
  643. IgnoreCC
  644. ExactTypeDescValues
  645. ExactGenericParams
  646. ExactConstraints
  647. ExactGcSafety
  648. AllowCommonBase
  649. TTypeCmpFlags* = set[TTypeCmpFlag]
  650. TSameTypeClosure = object {.pure.}
  651. cmp: TDistinctCompare
  652. recCheck: int
  653. flags: TTypeCmpFlags
  654. s: seq[tuple[a,b: int]] # seq for a set as it's hopefully faster
  655. # (few elements expected)
  656. proc initSameTypeClosure: TSameTypeClosure =
  657. # we do the initialization lazily for performance (avoids memory allocations)
  658. discard
  659. proc containsOrIncl(c: var TSameTypeClosure, a, b: PType): bool =
  660. result = not isNil(c.s) and c.s.contains((a.id, b.id))
  661. if not result:
  662. if isNil(c.s): c.s = @[]
  663. c.s.add((a.id, b.id))
  664. proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool
  665. proc sameTypeOrNilAux(a, b: PType, c: var TSameTypeClosure): bool =
  666. if a == b:
  667. result = true
  668. else:
  669. if a == nil or b == nil: result = false
  670. else: result = sameTypeAux(a, b, c)
  671. proc sameType*(a, b: PType, flags: TTypeCmpFlags = {}): bool =
  672. var c = initSameTypeClosure()
  673. c.flags = flags
  674. result = sameTypeAux(a, b, c)
  675. proc sameTypeOrNil*(a, b: PType, flags: TTypeCmpFlags = {}): bool =
  676. if a == b:
  677. result = true
  678. else:
  679. if a == nil or b == nil: result = false
  680. else: result = sameType(a, b, flags)
  681. proc equalParam(a, b: PSym): TParamsEquality =
  682. if sameTypeOrNil(a.typ, b.typ, {ExactTypeDescValues}) and
  683. exprStructuralEquivalent(a.constraint, b.constraint):
  684. if a.ast == b.ast:
  685. result = paramsEqual
  686. elif a.ast != nil and b.ast != nil:
  687. if exprStructuralEquivalent(a.ast, b.ast): result = paramsEqual
  688. else: result = paramsIncompatible
  689. elif a.ast != nil:
  690. result = paramsEqual
  691. elif b.ast != nil:
  692. result = paramsIncompatible
  693. else:
  694. result = paramsNotEqual
  695. proc sameConstraints(a, b: PNode): bool =
  696. if isNil(a) and isNil(b): return true
  697. internalAssert a.len == b.len
  698. for i in 1 .. <a.len:
  699. if not exprStructuralEquivalent(a[i].sym.constraint,
  700. b[i].sym.constraint):
  701. return false
  702. return true
  703. proc equalParams(a, b: PNode): TParamsEquality =
  704. result = paramsEqual
  705. var length = sonsLen(a)
  706. if length != sonsLen(b):
  707. result = paramsNotEqual
  708. else:
  709. for i in countup(1, length - 1):
  710. var m = a.sons[i].sym
  711. var n = b.sons[i].sym
  712. assert((m.kind == skParam) and (n.kind == skParam))
  713. case equalParam(m, n)
  714. of paramsNotEqual:
  715. return paramsNotEqual
  716. of paramsEqual:
  717. discard
  718. of paramsIncompatible:
  719. result = paramsIncompatible
  720. if (m.name.id != n.name.id):
  721. # BUGFIX
  722. return paramsNotEqual # paramsIncompatible;
  723. # continue traversal! If not equal, we can return immediately; else
  724. # it stays incompatible
  725. if not sameTypeOrNil(a.sons[0].typ, b.sons[0].typ, {ExactTypeDescValues}):
  726. if (a.sons[0].typ == nil) or (b.sons[0].typ == nil):
  727. result = paramsNotEqual # one proc has a result, the other not is OK
  728. else:
  729. result = paramsIncompatible # overloading by different
  730. # result types does not work
  731. proc sameTuple(a, b: PType, c: var TSameTypeClosure): bool =
  732. # two tuples are equivalent iff the names, types and positions are the same;
  733. # however, both types may not have any field names (t.n may be nil) which
  734. # complicates the matter a bit.
  735. if sonsLen(a) == sonsLen(b):
  736. result = true
  737. for i in countup(0, sonsLen(a) - 1):
  738. var x = a.sons[i]
  739. var y = b.sons[i]
  740. if IgnoreTupleFields in c.flags:
  741. x = skipTypes(x, {tyRange, tyGenericInst, tyAlias})
  742. y = skipTypes(y, {tyRange, tyGenericInst, tyAlias})
  743. result = sameTypeAux(x, y, c)
  744. if not result: return
  745. if a.n != nil and b.n != nil and IgnoreTupleFields notin c.flags:
  746. for i in countup(0, sonsLen(a.n) - 1):
  747. # check field names:
  748. if a.n.sons[i].kind == nkSym and b.n.sons[i].kind == nkSym:
  749. var x = a.n.sons[i].sym
  750. var y = b.n.sons[i].sym
  751. result = x.name.id == y.name.id
  752. if not result: break
  753. else: internalError(a.n.info, "sameTuple")
  754. elif a.n != b.n and (a.n == nil or b.n == nil) and IgnoreTupleFields notin c.flags:
  755. result = false
  756. template ifFastObjectTypeCheckFailed(a, b: PType, body: untyped) =
  757. if tfFromGeneric notin a.flags + b.flags:
  758. # fast case: id comparison suffices:
  759. result = a.id == b.id
  760. else:
  761. # expensive structural equality test; however due to the way generic and
  762. # objects work, if one of the types does **not** contain tfFromGeneric,
  763. # they cannot be equal. The check ``a.sym.id == b.sym.id`` checks
  764. # for the same origin and is essential because we don't want "pure"
  765. # structural type equivalence:
  766. #
  767. # type
  768. # TA[T] = object
  769. # TB[T] = object
  770. # --> TA[int] != TB[int]
  771. if tfFromGeneric in a.flags * b.flags and a.sym.id == b.sym.id:
  772. # ok, we need the expensive structural check
  773. body
  774. proc sameObjectTypes*(a, b: PType): bool =
  775. # specialized for efficiency (sigmatch uses it)
  776. ifFastObjectTypeCheckFailed(a, b):
  777. var c = initSameTypeClosure()
  778. result = sameTypeAux(a, b, c)
  779. proc sameDistinctTypes*(a, b: PType): bool {.inline.} =
  780. result = sameObjectTypes(a, b)
  781. proc sameEnumTypes*(a, b: PType): bool {.inline.} =
  782. result = a.id == b.id
  783. proc sameObjectTree(a, b: PNode, c: var TSameTypeClosure): bool =
  784. if a == b:
  785. result = true
  786. elif a != nil and b != nil and a.kind == b.kind:
  787. var x = a.typ
  788. var y = b.typ
  789. if IgnoreTupleFields in c.flags:
  790. if x != nil: x = skipTypes(x, {tyRange, tyGenericInst, tyAlias})
  791. if y != nil: y = skipTypes(y, {tyRange, tyGenericInst, tyAlias})
  792. if sameTypeOrNilAux(x, y, c):
  793. case a.kind
  794. of nkSym:
  795. # same symbol as string is enough:
  796. result = a.sym.name.id == b.sym.name.id
  797. of nkIdent: result = a.ident.id == b.ident.id
  798. of nkCharLit..nkInt64Lit: result = a.intVal == b.intVal
  799. of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
  800. of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
  801. of nkEmpty, nkNilLit, nkType: result = true
  802. else:
  803. if sonsLen(a) == sonsLen(b):
  804. for i in countup(0, sonsLen(a) - 1):
  805. if not sameObjectTree(a.sons[i], b.sons[i], c): return
  806. result = true
  807. proc sameObjectStructures(a, b: PType, c: var TSameTypeClosure): bool =
  808. # check base types:
  809. if sonsLen(a) != sonsLen(b): return
  810. for i in countup(0, sonsLen(a) - 1):
  811. if not sameTypeOrNilAux(a.sons[i], b.sons[i], c): return
  812. if not sameObjectTree(a.n, b.n, c): return
  813. result = true
  814. proc sameChildrenAux(a, b: PType, c: var TSameTypeClosure): bool =
  815. if sonsLen(a) != sonsLen(b): return false
  816. result = true
  817. for i in countup(0, sonsLen(a) - 1):
  818. result = sameTypeOrNilAux(a.sons[i], b.sons[i], c)
  819. if not result: return
  820. proc isGenericAlias*(t: PType): bool =
  821. return t.kind == tyGenericInst and t.lastSon.kind == tyGenericInst
  822. proc skipGenericAlias*(t: PType): PType =
  823. return if t.isGenericAlias: t.lastSon else: t
  824. proc sameFlags*(a, b: PType): bool {.inline.} =
  825. result = eqTypeFlags*a.flags == eqTypeFlags*b.flags
  826. proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
  827. template cycleCheck() =
  828. # believe it or not, the direct check for ``containsOrIncl(c, a, b)``
  829. # increases bootstrapping time from 2.4s to 3.3s on my laptop! So we cheat
  830. # again: Since the recursion check is only to not get caught in an endless
  831. # recursion, we use a counter and only if it's value is over some
  832. # threshold we perform the expensive exact cycle check:
  833. if c.recCheck < 3:
  834. inc c.recCheck
  835. else:
  836. if containsOrIncl(c, a, b): return true
  837. if x == y: return true
  838. var a = skipTypes(x, {tyGenericInst, tyAlias})
  839. var b = skipTypes(y, {tyGenericInst, tyAlias})
  840. assert(a != nil)
  841. assert(b != nil)
  842. if a.kind != b.kind:
  843. case c.cmp
  844. of dcEq: return false
  845. of dcEqIgnoreDistinct:
  846. while a.kind == tyDistinct: a = a.sons[0]
  847. while b.kind == tyDistinct: b = b.sons[0]
  848. if a.kind != b.kind: return false
  849. of dcEqOrDistinctOf:
  850. while a.kind == tyDistinct: a = a.sons[0]
  851. if a.kind != b.kind: return false
  852. # this is required by tunique_type but makes no sense really:
  853. if x.kind == tyGenericInst and IgnoreTupleFields notin c.flags:
  854. let
  855. lhs = x.skipGenericAlias
  856. rhs = y.skipGenericAlias
  857. if rhs.kind != tyGenericInst or lhs.base != rhs.base:
  858. return false
  859. for i in 1 .. lhs.len - 2:
  860. let ff = rhs.sons[i]
  861. let aa = lhs.sons[i]
  862. if not sameTypeAux(ff, aa, c): return false
  863. return true
  864. case a.kind
  865. of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
  866. tyInt..tyUInt64, tyStmt, tyExpr, tyVoid:
  867. result = sameFlags(a, b)
  868. of tyStatic, tyFromExpr:
  869. result = exprStructuralEquivalent(a.n, b.n) and sameFlags(a, b)
  870. if result and a.len == b.len and a.len == 1:
  871. cycleCheck()
  872. result = sameTypeAux(a.sons[0], b.sons[0], c)
  873. of tyObject:
  874. ifFastObjectTypeCheckFailed(a, b):
  875. cycleCheck()
  876. result = sameObjectStructures(a, b, c) and sameFlags(a, b)
  877. of tyDistinct:
  878. cycleCheck()
  879. if c.cmp == dcEq:
  880. if sameFlags(a, b):
  881. ifFastObjectTypeCheckFailed(a, b):
  882. result = sameTypeAux(a.sons[0], b.sons[0], c)
  883. else:
  884. result = sameTypeAux(a.sons[0], b.sons[0], c) and sameFlags(a, b)
  885. of tyEnum, tyForward:
  886. # XXX generic enums do not make much sense, but require structural checking
  887. result = a.id == b.id and sameFlags(a, b)
  888. of tyError:
  889. result = b.kind == tyError
  890. of tyTuple:
  891. cycleCheck()
  892. result = sameTuple(a, b, c) and sameFlags(a, b)
  893. of tyTypeDesc:
  894. if c.cmp == dcEqIgnoreDistinct: result = false
  895. elif ExactTypeDescValues in c.flags:
  896. cycleCheck()
  897. result = sameChildrenAux(x, y, c) and sameFlags(a, b)
  898. else:
  899. result = sameFlags(a, b)
  900. of tyGenericParam:
  901. result = sameChildrenAux(a, b, c) and sameFlags(a, b)
  902. if result and ExactGenericParams in c.flags:
  903. result = a.sym.position == b.sym.position
  904. of tyGenericInvocation, tyGenericBody, tySequence,
  905. tyOpenArray, tySet, tyRef, tyPtr, tyVar,
  906. tyArray, tyProc, tyVarargs, tyOrdinal, tyTypeClasses, tyFieldAccessor:
  907. cycleCheck()
  908. if a.kind == tyUserTypeClass and a.n != nil: return a.n == b.n
  909. result = sameChildrenAux(a, b, c) and sameFlags(a, b)
  910. if result and ExactGcSafety in c.flags:
  911. result = a.flags * {tfThread} == b.flags * {tfThread}
  912. if result and a.kind == tyProc:
  913. result = ((IgnoreCC in c.flags) or a.callConv == b.callConv) and
  914. ((ExactConstraints notin c.flags) or sameConstraints(a.n, b.n))
  915. of tyRange:
  916. cycleCheck()
  917. result = sameTypeOrNilAux(a.sons[0], b.sons[0], c) and
  918. sameValue(a.n.sons[0], b.n.sons[0]) and
  919. sameValue(a.n.sons[1], b.n.sons[1])
  920. of tyGenericInst, tyAlias, tyInferred:
  921. cycleCheck()
  922. result = sameTypeAux(a.lastSon, b.lastSon, c)
  923. of tyNone: result = false
  924. of tyUnused, tyUnused0, tyUnused1, tyUnused2: internalError("sameFlags")
  925. proc sameBackendType*(x, y: PType): bool =
  926. var c = initSameTypeClosure()
  927. c.flags.incl IgnoreTupleFields
  928. result = sameTypeAux(x, y, c)
  929. proc compareTypes*(x, y: PType,
  930. cmp: TDistinctCompare = dcEq,
  931. flags: TTypeCmpFlags = {}): bool =
  932. ## compares two type for equality (modulo type distinction)
  933. var c = initSameTypeClosure()
  934. c.cmp = cmp
  935. c.flags = flags
  936. if x == y: result = true
  937. elif x.isNil or y.isNil: result = false
  938. else: result = sameTypeAux(x, y, c)
  939. proc inheritanceDiff*(a, b: PType): int =
  940. # | returns: 0 iff `a` == `b`
  941. # | returns: -x iff `a` is the x'th direct superclass of `b`
  942. # | returns: +x iff `a` is the x'th direct subclass of `b`
  943. # | returns: `maxint` iff `a` and `b` are not compatible at all
  944. if a == b or a.kind == tyError or b.kind == tyError: return 0
  945. assert a.kind == tyObject
  946. assert b.kind == tyObject
  947. var x = a
  948. result = 0
  949. while x != nil:
  950. x = skipTypes(x, skipPtrs)
  951. if sameObjectTypes(x, b): return
  952. x = x.sons[0]
  953. dec(result)
  954. var y = b
  955. result = 0
  956. while y != nil:
  957. y = skipTypes(y, skipPtrs)
  958. if sameObjectTypes(y, a): return
  959. y = y.sons[0]
  960. inc(result)
  961. result = high(int)
  962. proc commonSuperclass*(a, b: PType): PType =
  963. # quick check: are they the same?
  964. if sameObjectTypes(a, b): return a
  965. # simple algorithm: we store all ancestors of 'a' in a ID-set and walk 'b'
  966. # up until the ID is found:
  967. assert a.kind == tyObject
  968. assert b.kind == tyObject
  969. var x = a
  970. var ancestors = initIntSet()
  971. while x != nil:
  972. x = skipTypes(x, skipPtrs)
  973. ancestors.incl(x.id)
  974. x = x.sons[0]
  975. var y = b
  976. while y != nil:
  977. y = skipTypes(y, skipPtrs)
  978. if ancestors.contains(y.id): return y
  979. y = y.sons[0]
  980. type
  981. TTypeAllowedFlag = enum
  982. taField,
  983. taHeap
  984. TTypeAllowedFlags = set[TTypeAllowedFlag]
  985. proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
  986. flags: TTypeAllowedFlags = {}): PType
  987. proc typeAllowedNode(marker: var IntSet, n: PNode, kind: TSymKind,
  988. flags: TTypeAllowedFlags = {}): PType =
  989. if n != nil:
  990. result = typeAllowedAux(marker, n.typ, kind, flags)
  991. #if not result: debug(n.typ)
  992. if result == nil:
  993. case n.kind
  994. of nkNone..nkNilLit:
  995. discard
  996. else:
  997. if n.kind == nkRecCase and kind in {skProc, skConst}:
  998. return n[0].typ
  999. for i in countup(0, sonsLen(n) - 1):
  1000. let it = n.sons[i]
  1001. result = typeAllowedNode(marker, it, kind, flags)
  1002. if result != nil: break
  1003. proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]],
  1004. last: TTypeKind): bool =
  1005. var a = a
  1006. for k, i in pattern.items:
  1007. if a.kind != k: return false
  1008. if i >= a.sonsLen or a.sons[i] == nil: return false
  1009. a = a.sons[i]
  1010. result = a.kind == last
  1011. proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
  1012. flags: TTypeAllowedFlags = {}): PType =
  1013. assert(kind in {skVar, skLet, skConst, skProc, skParam, skResult})
  1014. # if we have already checked the type, return true, because we stop the
  1015. # evaluation if something is wrong:
  1016. result = nil
  1017. if typ == nil: return
  1018. if containsOrIncl(marker, typ.id): return
  1019. var t = skipTypes(typ, abstractInst-{tyTypeDesc})
  1020. case t.kind
  1021. of tyVar:
  1022. if kind in {skProc, skConst}: return t
  1023. var t2 = skipTypes(t.sons[0], abstractInst-{tyTypeDesc})
  1024. case t2.kind
  1025. of tyVar:
  1026. if taHeap notin flags: result = t2 # ``var var`` is illegal on the heap
  1027. of tyOpenArray:
  1028. if kind != skParam: result = t
  1029. else: result = typeAllowedAux(marker, t2, kind, flags)
  1030. else:
  1031. if kind notin {skParam, skResult}: result = t
  1032. else: result = typeAllowedAux(marker, t2, kind, flags)
  1033. of tyProc:
  1034. if kind == skConst and t.callConv == ccClosure: return t
  1035. for i in countup(1, sonsLen(t) - 1):
  1036. result = typeAllowedAux(marker, t.sons[i], skParam, flags)
  1037. if result != nil: break
  1038. if result.isNil and t.sons[0] != nil:
  1039. result = typeAllowedAux(marker, t.sons[0], skResult, flags)
  1040. of tyTypeDesc:
  1041. # XXX: This is still a horrible idea...
  1042. result = nil
  1043. of tyExpr, tyStmt, tyStatic:
  1044. if kind notin {skParam, skResult}: result = t
  1045. of tyVoid:
  1046. if taField notin flags: result = t
  1047. of tyTypeClasses:
  1048. if not (tfGenericTypeParam in t.flags or taField notin flags): result = t
  1049. of tyGenericBody, tyGenericParam, tyGenericInvocation,
  1050. tyNone, tyForward, tyFromExpr, tyFieldAccessor:
  1051. result = t
  1052. of tyNil:
  1053. if kind != skConst: result = t
  1054. of tyString, tyBool, tyChar, tyEnum, tyInt..tyUInt64, tyCString, tyPointer:
  1055. result = nil
  1056. of tyOrdinal:
  1057. if kind != skParam: result = t
  1058. of tyGenericInst, tyDistinct, tyAlias, tyInferred:
  1059. result = typeAllowedAux(marker, lastSon(t), kind, flags)
  1060. of tyRange:
  1061. if skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind notin
  1062. {tyChar, tyEnum, tyInt..tyFloat128, tyUInt8..tyUInt32}: result = t
  1063. of tyOpenArray, tyVarargs:
  1064. if kind != skParam: result = t
  1065. else: result = typeAllowedAux(marker, t.sons[0], skVar, flags)
  1066. of tySequence:
  1067. if t.sons[0].kind != tyEmpty:
  1068. result = typeAllowedAux(marker, t.sons[0], skVar, flags+{taHeap})
  1069. of tyArray:
  1070. if t.sons[1].kind != tyEmpty:
  1071. result = typeAllowedAux(marker, t.sons[1], skVar, flags)
  1072. of tyRef:
  1073. if kind == skConst: result = t
  1074. else: result = typeAllowedAux(marker, t.lastSon, skVar, flags+{taHeap})
  1075. of tyPtr:
  1076. result = typeAllowedAux(marker, t.lastSon, skVar, flags+{taHeap})
  1077. of tySet:
  1078. for i in countup(0, sonsLen(t) - 1):
  1079. result = typeAllowedAux(marker, t.sons[i], kind, flags)
  1080. if result != nil: break
  1081. of tyObject, tyTuple:
  1082. if kind in {skProc, skConst} and
  1083. t.kind == tyObject and t.sons[0] != nil: return t
  1084. let flags = flags+{taField}
  1085. for i in countup(0, sonsLen(t) - 1):
  1086. result = typeAllowedAux(marker, t.sons[i], kind, flags)
  1087. if result != nil: break
  1088. if result.isNil and t.n != nil:
  1089. result = typeAllowedNode(marker, t.n, kind, flags)
  1090. of tyProxy, tyEmpty:
  1091. # for now same as error node; we say it's a valid type as it should
  1092. # prevent cascading errors:
  1093. result = nil
  1094. of tyUnused, tyUnused0, tyUnused1, tyUnused2: internalError("typeAllowedAux")
  1095. proc typeAllowed*(t: PType, kind: TSymKind): PType =
  1096. # returns 'nil' on success and otherwise the part of the type that is
  1097. # wrong!
  1098. var marker = initIntSet()
  1099. result = typeAllowedAux(marker, t, kind, {})
  1100. proc align(address, alignment: BiggestInt): BiggestInt =
  1101. result = (address + (alignment - 1)) and not (alignment - 1)
  1102. const
  1103. szNonConcreteType* = -3
  1104. szIllegalRecursion* = -2
  1105. szUnknownSize* = -1
  1106. proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt
  1107. proc computeRecSizeAux(n: PNode, a, currOffset: var BiggestInt): BiggestInt =
  1108. var maxAlign, maxSize, b, res: BiggestInt
  1109. case n.kind
  1110. of nkRecCase:
  1111. assert(n.sons[0].kind == nkSym)
  1112. result = computeRecSizeAux(n.sons[0], a, currOffset)
  1113. maxSize = 0
  1114. maxAlign = 1
  1115. for i in countup(1, sonsLen(n) - 1):
  1116. case n.sons[i].kind
  1117. of nkOfBranch, nkElse:
  1118. res = computeRecSizeAux(lastSon(n.sons[i]), b, currOffset)
  1119. if res < 0: return res
  1120. maxSize = max(maxSize, res)
  1121. maxAlign = max(maxAlign, b)
  1122. else: internalError("computeRecSizeAux(record case branch)")
  1123. currOffset = align(currOffset, maxAlign) + maxSize
  1124. result = align(result, maxAlign) + maxSize
  1125. a = maxAlign
  1126. of nkRecList:
  1127. result = 0
  1128. maxAlign = 1
  1129. for i in countup(0, sonsLen(n) - 1):
  1130. res = computeRecSizeAux(n.sons[i], b, currOffset)
  1131. if res < 0: return res
  1132. currOffset = align(currOffset, b) + res
  1133. result = align(result, b) + res
  1134. if b > maxAlign: maxAlign = b
  1135. a = maxAlign
  1136. of nkSym:
  1137. result = computeSizeAux(n.sym.typ, a)
  1138. n.sym.offset = int(currOffset)
  1139. else:
  1140. a = 1
  1141. result = szNonConcreteType
  1142. proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt =
  1143. var res, maxAlign, length, currOffset: BiggestInt
  1144. if typ.size == szIllegalRecursion:
  1145. # we are already computing the size of the type
  1146. # --> illegal recursion in type
  1147. return szIllegalRecursion
  1148. if typ.size >= 0:
  1149. # size already computed
  1150. result = typ.size
  1151. a = typ.align
  1152. return
  1153. typ.size = szIllegalRecursion # mark as being computed
  1154. case typ.kind
  1155. of tyInt, tyUInt:
  1156. result = intSize
  1157. a = result
  1158. of tyInt8, tyUInt8, tyBool, tyChar:
  1159. result = 1
  1160. a = result
  1161. of tyInt16, tyUInt16:
  1162. result = 2
  1163. a = result
  1164. of tyInt32, tyUInt32, tyFloat32:
  1165. result = 4
  1166. a = result
  1167. of tyInt64, tyUInt64, tyFloat64:
  1168. result = 8
  1169. a = result
  1170. of tyFloat128:
  1171. result = 16
  1172. a = result
  1173. of tyFloat:
  1174. result = floatSize
  1175. a = result
  1176. of tyProc:
  1177. if typ.callConv == ccClosure: result = 2 * ptrSize
  1178. else: result = ptrSize
  1179. a = ptrSize
  1180. of tyNil, tyCString, tyString, tySequence, tyPtr, tyRef, tyVar, tyOpenArray:
  1181. let base = typ.lastSon
  1182. if base == typ or (base.kind == tyTuple and base.size==szIllegalRecursion):
  1183. result = szIllegalRecursion
  1184. else: result = ptrSize
  1185. a = result
  1186. of tyArray:
  1187. let elemSize = computeSizeAux(typ.sons[1], a)
  1188. if elemSize < 0: return elemSize
  1189. result = lengthOrd(typ.sons[0]) * elemSize
  1190. of tyEnum:
  1191. if firstOrd(typ) < 0:
  1192. result = 4 # use signed int32
  1193. else:
  1194. length = lastOrd(typ) # BUGFIX: use lastOrd!
  1195. if length + 1 < `shl`(1, 8): result = 1
  1196. elif length + 1 < `shl`(1, 16): result = 2
  1197. elif length + 1 < `shl`(BiggestInt(1), 32): result = 4
  1198. else: result = 8
  1199. a = result
  1200. of tySet:
  1201. if typ.sons[0].kind == tyGenericParam:
  1202. result = szUnknownSize
  1203. else:
  1204. length = lengthOrd(typ.sons[0])
  1205. if length <= 8: result = 1
  1206. elif length <= 16: result = 2
  1207. elif length <= 32: result = 4
  1208. elif length <= 64: result = 8
  1209. elif align(length, 8) mod 8 == 0: result = align(length, 8) div 8
  1210. else: result = align(length, 8) div 8 + 1
  1211. a = result
  1212. of tyRange:
  1213. result = computeSizeAux(typ.sons[0], a)
  1214. of tyTuple:
  1215. result = 0
  1216. maxAlign = 1
  1217. for i in countup(0, sonsLen(typ) - 1):
  1218. res = computeSizeAux(typ.sons[i], a)
  1219. if res < 0: return res
  1220. maxAlign = max(maxAlign, a)
  1221. result = align(result, a) + res
  1222. result = align(result, maxAlign)
  1223. a = maxAlign
  1224. of tyObject:
  1225. if typ.sons[0] != nil:
  1226. result = computeSizeAux(typ.sons[0].skipTypes(skipPtrs), a)
  1227. if result < 0: return
  1228. maxAlign = a
  1229. elif isObjectWithTypeFieldPredicate(typ):
  1230. result = intSize
  1231. maxAlign = result
  1232. else:
  1233. result = 0
  1234. maxAlign = 1
  1235. currOffset = result
  1236. result = computeRecSizeAux(typ.n, a, currOffset)
  1237. if result < 0: return
  1238. if a < maxAlign: a = maxAlign
  1239. result = align(result, a)
  1240. of tyInferred:
  1241. if typ.len > 1:
  1242. result = computeSizeAux(typ.lastSon, a)
  1243. of tyGenericInst, tyDistinct, tyGenericBody, tyAlias:
  1244. result = computeSizeAux(lastSon(typ), a)
  1245. of tyTypeClasses:
  1246. result = if typ.isResolvedUserTypeClass: computeSizeAux(typ.lastSon, a)
  1247. else: szUnknownSize
  1248. of tyTypeDesc:
  1249. result = computeSizeAux(typ.base, a)
  1250. of tyForward: return szIllegalRecursion
  1251. of tyStatic:
  1252. result = if typ.n != nil: computeSizeAux(typ.lastSon, a)
  1253. else: szUnknownSize
  1254. else:
  1255. #internalError("computeSizeAux()")
  1256. result = szUnknownSize
  1257. typ.size = result
  1258. typ.align = int16(a)
  1259. proc computeSize(typ: PType): BiggestInt =
  1260. var a: BiggestInt = 1
  1261. result = computeSizeAux(typ, a)
  1262. proc getReturnType*(s: PSym): PType =
  1263. # Obtains the return type of a iterator/proc/macro/template
  1264. assert s.kind in skProcKinds
  1265. result = s.typ.sons[0]
  1266. proc getSize(typ: PType): BiggestInt =
  1267. result = computeSize(typ)
  1268. if result < 0: internalError("getSize: " & $typ.kind)
  1269. proc containsGenericTypeIter(t: PType, closure: RootRef): bool =
  1270. case t.kind
  1271. of tyStatic:
  1272. return t.n == nil
  1273. of tyTypeDesc:
  1274. if t.base.kind == tyNone: return true
  1275. if containsGenericTypeIter(t.base, closure): return true
  1276. return false
  1277. of GenericTypes + tyTypeClasses + {tyFromExpr}:
  1278. return true
  1279. else:
  1280. return false
  1281. proc containsGenericType*(t: PType): bool =
  1282. result = iterOverType(t, containsGenericTypeIter, nil)
  1283. proc baseOfDistinct*(t: PType): PType =
  1284. if t.kind == tyDistinct:
  1285. result = t.sons[0]
  1286. else:
  1287. result = copyType(t, t.owner, false)
  1288. var parent: PType = nil
  1289. var it = result
  1290. while it.kind in {tyPtr, tyRef}:
  1291. parent = it
  1292. it = it.lastSon
  1293. if it.kind == tyDistinct:
  1294. internalAssert parent != nil
  1295. parent.sons[0] = it.sons[0]
  1296. proc safeInheritanceDiff*(a, b: PType): int =
  1297. # same as inheritanceDiff but checks for tyError:
  1298. if a.kind == tyError or b.kind == tyError:
  1299. result = -1
  1300. else:
  1301. result = inheritanceDiff(a.skipTypes(skipPtrs), b.skipTypes(skipPtrs))
  1302. proc compatibleEffectsAux(se, re: PNode): bool =
  1303. if re.isNil: return false
  1304. for r in items(re):
  1305. block search:
  1306. for s in items(se):
  1307. if safeInheritanceDiff(r.typ, s.typ) <= 0:
  1308. break search
  1309. return false
  1310. result = true
  1311. type
  1312. EffectsCompat* = enum
  1313. efCompat
  1314. efRaisesDiffer
  1315. efRaisesUnknown
  1316. efTagsDiffer
  1317. efTagsUnknown
  1318. efLockLevelsDiffer
  1319. proc compatibleEffects*(formal, actual: PType): EffectsCompat =
  1320. # for proc type compatibility checking:
  1321. assert formal.kind == tyProc and actual.kind == tyProc
  1322. internalAssert formal.n.sons[0].kind == nkEffectList
  1323. internalAssert actual.n.sons[0].kind == nkEffectList
  1324. var spec = formal.n.sons[0]
  1325. if spec.len != 0:
  1326. var real = actual.n.sons[0]
  1327. let se = spec.sons[exceptionEffects]
  1328. # if 'se.kind == nkArgList' it is no formal type really, but a
  1329. # computed effect and as such no spec:
  1330. # 'r.msgHandler = if isNil(msgHandler): defaultMsgHandler else: msgHandler'
  1331. if not isNil(se) and se.kind != nkArgList:
  1332. # spec requires some exception or tag, but we don't know anything:
  1333. if real.len == 0: return efRaisesUnknown
  1334. let res = compatibleEffectsAux(se, real.sons[exceptionEffects])
  1335. if not res: return efRaisesDiffer
  1336. let st = spec.sons[tagEffects]
  1337. if not isNil(st) and st.kind != nkArgList:
  1338. # spec requires some exception or tag, but we don't know anything:
  1339. if real.len == 0: return efTagsUnknown
  1340. let res = compatibleEffectsAux(st, real.sons[tagEffects])
  1341. if not res: return efTagsDiffer
  1342. if formal.lockLevel.ord < 0 or
  1343. actual.lockLevel.ord <= formal.lockLevel.ord:
  1344. result = efCompat
  1345. else:
  1346. result = efLockLevelsDiffer
  1347. proc isCompileTimeOnly*(t: PType): bool {.inline.} =
  1348. result = t.kind in {tyTypeDesc, tyStatic}
  1349. proc containsCompileTimeOnly*(t: PType): bool =
  1350. if isCompileTimeOnly(t): return true
  1351. if t.sons != nil:
  1352. for i in 0 .. <t.sonsLen:
  1353. if t.sons[i] != nil and isCompileTimeOnly(t.sons[i]):
  1354. return true
  1355. return false
  1356. type
  1357. OrdinalType* = enum
  1358. NoneLike, IntLike, FloatLike
  1359. proc classify*(t: PType): OrdinalType =
  1360. ## for convenient type checking:
  1361. if t == nil:
  1362. result = NoneLike
  1363. else:
  1364. case skipTypes(t, abstractVarRange).kind
  1365. of tyFloat..tyFloat128: result = FloatLike
  1366. of tyInt..tyInt64, tyUInt..tyUInt64, tyBool, tyChar, tyEnum:
  1367. result = IntLike
  1368. else: result = NoneLike
  1369. proc skipConv*(n: PNode): PNode =
  1370. result = n
  1371. case n.kind
  1372. of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
  1373. # only skip the conversion if it doesn't lose too important information
  1374. # (see bug #1334)
  1375. if n.sons[0].typ.classify == n.typ.classify:
  1376. result = n.sons[0]
  1377. of nkHiddenStdConv, nkHiddenSubConv, nkConv:
  1378. if n.sons[1].typ.classify == n.typ.classify:
  1379. result = n.sons[1]
  1380. else: discard
  1381. proc skipHidden*(n: PNode): PNode =
  1382. result = n
  1383. while true:
  1384. case result.kind
  1385. of nkHiddenStdConv, nkHiddenSubConv:
  1386. if result.sons[1].typ.classify == result.typ.classify:
  1387. result = result.sons[1]
  1388. else: break
  1389. of nkHiddenDeref, nkHiddenAddr:
  1390. result = result.sons[0]
  1391. else: break
  1392. proc skipConvTakeType*(n: PNode): PNode =
  1393. result = n.skipConv
  1394. result.typ = n.typ
  1395. proc isEmptyContainer*(t: PType): bool =
  1396. case t.kind
  1397. of tyExpr, tyNil: result = true
  1398. of tyArray: result = t.sons[1].kind == tyEmpty
  1399. of tySet, tySequence, tyOpenArray, tyVarargs:
  1400. result = t.sons[0].kind == tyEmpty
  1401. of tyGenericInst, tyAlias: result = isEmptyContainer(t.lastSon)
  1402. else: result = false
  1403. proc takeType*(formal, arg: PType): PType =
  1404. # param: openArray[string] = []
  1405. # [] is an array constructor of length 0 of type string!
  1406. if arg.kind == tyNil:
  1407. # and not (formal.kind == tyProc and formal.callConv == ccClosure):
  1408. result = formal
  1409. elif formal.kind in {tyOpenArray, tyVarargs, tySequence} and
  1410. arg.isEmptyContainer:
  1411. let a = copyType(arg.skipTypes({tyGenericInst, tyAlias}), arg.owner, keepId=false)
  1412. a.sons[ord(arg.kind == tyArray)] = formal.sons[0]
  1413. result = a
  1414. elif formal.kind in {tyTuple, tySet} and arg.kind == formal.kind:
  1415. result = formal
  1416. else:
  1417. result = arg
  1418. proc skipHiddenSubConv*(n: PNode): PNode =
  1419. if n.kind == nkHiddenSubConv:
  1420. # param: openArray[string] = []
  1421. # [] is an array constructor of length 0 of type string!
  1422. let formal = n.typ
  1423. result = n.sons[1]
  1424. let arg = result.typ
  1425. let dest = takeType(formal, arg)
  1426. if dest == arg and formal.kind != tyExpr:
  1427. #echo n.info, " came here for ", formal.typeToString
  1428. result = n
  1429. else:
  1430. result = copyTree(result)
  1431. result.typ = dest
  1432. else:
  1433. result = n
  1434. proc typeMismatch*(info: TLineInfo, formal, actual: PType) =
  1435. if formal.kind != tyError and actual.kind != tyError:
  1436. let named = typeToString(formal)
  1437. let desc = typeToString(formal, preferDesc)
  1438. let x = if named == desc: named else: named & " = " & desc
  1439. var msg = msgKindToString(errTypeMismatch) &
  1440. typeToString(actual) & ") " &
  1441. msgKindToString(errButExpectedX) % [x]
  1442. if formal.kind == tyProc and actual.kind == tyProc:
  1443. case compatibleEffects(formal, actual)
  1444. of efCompat: discard
  1445. of efRaisesDiffer:
  1446. msg.add "\n.raise effects differ"
  1447. of efRaisesUnknown:
  1448. msg.add "\n.raise effect is 'can raise any'"
  1449. of efTagsDiffer:
  1450. msg.add "\n.tag effects differ"
  1451. of efTagsUnknown:
  1452. msg.add "\n.tag effect is 'any tag allowed'"
  1453. of efLockLevelsDiffer:
  1454. msg.add "\nlock levels differ"
  1455. localError(info, errGenerated, msg)