types.nim 52 KB

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