types.nim 57 KB

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