types.nim 63 KB

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