types.nim 74 KB

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