types.nim 64 KB

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