types.nim 61 KB

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