types.nim 63 KB

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