types.nim 62 KB

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