types.nim 59 KB

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