types.nim 53 KB

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