types.nim 57 KB

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