types.nim 71 KB

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