types.nim 60 KB

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