types.nim 52 KB

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