types.nim 57 KB

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