types.nim 55 KB

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