sigmatch.nim 94 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693
  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 implements the signature matching for resolving
  10. ## the call to overloaded procs, generic procs and operators.
  11. import
  12. intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst,
  13. magicsys, condsyms, idents, lexer, options, parampatterns, strutils, trees,
  14. linter, lineinfos, lowerings, modulegraphs
  15. when (defined(booting) or defined(nimsuggest)) and not defined(leanCompiler):
  16. import docgen
  17. type
  18. TCandidateState* = enum
  19. csEmpty, csMatch, csNoMatch
  20. CandidateError* = object
  21. sym*: PSym
  22. unmatchedVarParam*, firstMismatch*: int
  23. diagnostics*: seq[string]
  24. enabled*: bool
  25. CandidateErrors* = seq[CandidateError]
  26. MatchQuality = enum # todo: spec this; order is important
  27. noMatch,
  28. convMatch,
  29. intConvMatch,
  30. subtypeMatch,
  31. genericMatch,
  32. exactMatch
  33. TCandidate* = object
  34. matchQual: MatchQuality
  35. c*: PContext
  36. state*: TCandidateState
  37. callee*: PType # may not be nil!
  38. calleeSym*: PSym # may be nil
  39. calleeScope*: int # scope depth:
  40. # is this a top-level symbol or a nested proc?
  41. call*: PNode # modified call
  42. bindings*: TIdTable # maps types to types
  43. magic*: TMagic # magic of operation
  44. baseTypeMatch: bool # needed for conversions from T to openarray[T]
  45. # for example
  46. fauxMatch*: TTypeKind # the match was successful only due to the use
  47. # of error or wildcard (unknown) types.
  48. # this is used to prevent instantiations.
  49. genericConverter*: bool # true if a generic converter needs to
  50. # be instantiated
  51. coerceDistincts*: bool # this is an explicit coercion that can strip away
  52. # a distrinct type
  53. typedescMatched*: bool
  54. isNoCall*: bool # misused for generic type instantiations C[T]
  55. mutabilityProblem*: uint8 # tyVar mismatch
  56. inferredTypes: seq[PType] # inferred types during the current signature
  57. # matching. they will be reset if the matching
  58. # is not successful. may replace the bindings
  59. # table in the future.
  60. diagnostics*: seq[string] # \
  61. # when diagnosticsEnabled, the matching process
  62. # will collect extra diagnostics that will be
  63. # displayed to the user.
  64. # triggered when overload resolution fails
  65. # or when the explain pragma is used. may be
  66. # triggered with an idetools command in the
  67. # future.
  68. inheritancePenalty: int # to prefer closest father object type
  69. firstMismatch*: int # position of the first type mismatch for
  70. # better error messages
  71. diagnosticsEnabled*: bool
  72. TTypeRelFlag* = enum
  73. trDontBind
  74. trNoCovariance
  75. TTypeRelFlags* = set[TTypeRelFlag]
  76. TTypeRelation* = enum # order is important!
  77. isNone, isConvertible,
  78. isIntConv,
  79. isSubtype,
  80. isSubrange, # subrange of the wanted type; no type conversion
  81. # but apart from that counts as ``isSubtype``
  82. isBothMetaConvertible # generic proc parameter was matched against
  83. # generic type, e.g., map(mySeq, x=>x+1),
  84. # maybe recoverable by rerun if the parameter is
  85. # the proc's return value
  86. isInferred, # generic proc was matched against a concrete type
  87. isInferredConvertible, # same as above, but requiring proc CC conversion
  88. isGeneric,
  89. isFromIntLit, # conversion *from* int literal; proven safe
  90. isEqual
  91. const
  92. isNilConversion = isConvertible # maybe 'isIntConv' fits better?
  93. proc markUsed*(conf: ConfigRef; info: TLineInfo, s: PSym; usageSym: var PSym)
  94. template hasFauxMatch*(c: TCandidate): bool = c.fauxMatch != tyNone
  95. proc initCandidateAux(ctx: PContext,
  96. c: var TCandidate, callee: PType) {.inline.} =
  97. c.matchQual = exactMatch
  98. c.c = ctx
  99. c.state = csEmpty
  100. c.callee = callee
  101. c.call = nil
  102. c.baseTypeMatch = false
  103. c.genericConverter = false
  104. c.inheritancePenalty = 0
  105. proc initCandidate*(ctx: PContext, c: var TCandidate, callee: PType) =
  106. initCandidateAux(ctx, c, callee)
  107. c.calleeSym = nil
  108. initIdTable(c.bindings)
  109. proc put(c: var TCandidate, key, val: PType) {.inline.} =
  110. when false:
  111. let old = PType(idTableGet(c.bindings, key))
  112. if old != nil:
  113. echo "Putting ", typeToString(key), " ", typeToString(val), " and old is ", typeToString(old)
  114. if typeToString(old) == "seq[string]":
  115. writeStackTrace()
  116. if c.c.module.name.s == "temp3":
  117. echo "binding ", key, " -> ", val
  118. idTablePut(c.bindings, key, val.skipIntLit)
  119. proc initCandidate*(ctx: PContext, c: var TCandidate, callee: PSym,
  120. binding: PNode, calleeScope = -1,
  121. diagnosticsEnabled = false) =
  122. initCandidateAux(ctx, c, callee.typ)
  123. c.calleeSym = callee
  124. if callee.kind in skProcKinds and calleeScope == -1:
  125. if callee.originatingModule == ctx.module:
  126. c.calleeScope = 2
  127. var owner = callee
  128. while true:
  129. owner = owner.skipGenericOwner
  130. if owner.kind == skModule: break
  131. inc c.calleeScope
  132. else:
  133. c.calleeScope = 1
  134. else:
  135. c.calleeScope = calleeScope
  136. c.diagnostics = @[] # if diagnosticsEnabled: @[] else: nil
  137. c.diagnosticsEnabled = diagnosticsEnabled
  138. c.magic = c.calleeSym.magic
  139. initIdTable(c.bindings)
  140. if binding != nil and callee.kind in routineKinds:
  141. var typeParams = callee.ast[genericParamsPos]
  142. for i in 1..min(sonsLen(typeParams), sonsLen(binding)-1):
  143. var formalTypeParam = typeParams.sons[i-1].typ
  144. var bound = binding[i].typ
  145. if bound != nil:
  146. if formalTypeParam.kind == tyTypeDesc:
  147. if bound.kind != tyTypeDesc:
  148. bound = makeTypeDesc(ctx, bound)
  149. else:
  150. bound = bound.skipTypes({tyTypeDesc})
  151. put(c, formalTypeParam, bound)
  152. proc newCandidate*(ctx: PContext, callee: PSym,
  153. binding: PNode, calleeScope = -1): TCandidate =
  154. initCandidate(ctx, result, callee, binding, calleeScope)
  155. proc newCandidate*(ctx: PContext, callee: PType): TCandidate =
  156. initCandidate(ctx, result, callee)
  157. proc copyCandidate(a: var TCandidate, b: TCandidate) =
  158. a.c = b.c
  159. a.matchQual = b.matchQual
  160. a.state = b.state
  161. a.callee = b.callee
  162. a.calleeSym = b.calleeSym
  163. a.call = copyTree(b.call)
  164. a.baseTypeMatch = b.baseTypeMatch
  165. copyIdTable(a.bindings, b.bindings)
  166. proc sumGeneric(t: PType): int =
  167. # count the "genericness" so that Foo[Foo[T]] has the value 3
  168. # and Foo[T] has the value 2 so that we know Foo[Foo[T]] is more
  169. # specific than Foo[T].
  170. var t = t
  171. var isvar = 1
  172. while true:
  173. case t.kind
  174. of tyGenericInst, tyArray, tyRef, tyPtr, tyDistinct, tyUncheckedArray,
  175. tyOpenArray, tyVarargs, tySet, tyRange, tySequence, tyGenericBody,
  176. tyLent, tyOwned:
  177. t = t.lastSon
  178. inc result
  179. of tyOr:
  180. var maxBranch = 0
  181. for branch in t.sons:
  182. let branchSum = sumGeneric(branch)
  183. if branchSum > maxBranch: maxBranch = branchSum
  184. inc result, maxBranch
  185. break
  186. of tyVar:
  187. t = t.sons[0]
  188. inc result
  189. inc isvar
  190. of tyTypeDesc:
  191. t = t.lastSon
  192. if t.kind == tyEmpty: break
  193. inc result
  194. of tyGenericInvocation, tyTuple, tyProc, tyAnd:
  195. result += ord(t.kind in {tyGenericInvocation, tyAnd})
  196. for i in 0 ..< t.len:
  197. if t.sons[i] != nil:
  198. result += sumGeneric(t.sons[i])
  199. break
  200. of tyStatic:
  201. return sumGeneric(t.sons[0]) + 1
  202. of tyGenericParam, tyUntyped, tyTyped: break
  203. of tyAlias, tySink: t = t.lastSon
  204. of tyBool, tyChar, tyEnum, tyObject, tyPointer,
  205. tyString, tyCString, tyInt..tyInt64, tyFloat..tyFloat128,
  206. tyUInt..tyUInt64, tyCompositeTypeClass:
  207. return isvar
  208. else:
  209. return 0
  210. #var ggDebug: bool
  211. proc complexDisambiguation(a, b: PType): int =
  212. # 'a' matches better if *every* argument matches better or equal than 'b'.
  213. var winner = 0
  214. for i in 1 ..< min(a.len, b.len):
  215. let x = a.sons[i].sumGeneric
  216. let y = b.sons[i].sumGeneric
  217. #if ggDebug:
  218. #echo "came herA ", typeToString(a.sons[i]), " ", x
  219. #echo "came herB ", typeToString(b.sons[i]), " ", y
  220. if x != y:
  221. if winner == 0:
  222. if x > y: winner = 1
  223. else: winner = -1
  224. elif x > y:
  225. if winner != 1:
  226. # contradiction
  227. return 0
  228. else:
  229. if winner != -1:
  230. return 0
  231. result = winner
  232. when false:
  233. var x, y: int
  234. for i in 1 ..< a.len: x += a.sons[i].sumGeneric
  235. for i in 1 ..< b.len: y += b.sons[i].sumGeneric
  236. result = x - y
  237. proc writeMatches*(c: TCandidate) =
  238. echo "Candidate '", c.calleeSym.name.s, "' at ", c.c.config $ c.calleeSym.info
  239. echo " match quality: ", c.matchQual
  240. echo " inheritance: ", c.inheritancePenalty
  241. proc cmpCandidates*(a, b: TCandidate): int =
  242. proc isIter(a: TCandidate): int {.inline.} =
  243. result = ord(a.calleeSym != nil and a.calleeSym.kind == skIterator)
  244. # prefer iterators over anything else...
  245. result = isIter(a) - isIter(b)
  246. if result != 0: return
  247. if a.matchQual == b.matchQual:
  248. # the other way round because of other semantics:
  249. result = b.inheritancePenalty - a.inheritancePenalty
  250. if result != 0: return
  251. # prefer more specialized generic over more general generic:
  252. result = complexDisambiguation(a.callee, b.callee)
  253. if result != 0: return
  254. # only as a last resort, consider scoping:
  255. result = a.calleeScope - b.calleeScope
  256. elif a.matchQual > b.matchQual:
  257. result = 1
  258. else:
  259. result = -1
  260. proc argTypeToString(arg: PNode; prefer: TPreferedDesc): string =
  261. if arg.kind in nkSymChoices:
  262. result = typeToString(arg[0].typ, prefer)
  263. for i in 1 ..< arg.len:
  264. result.add(" | ")
  265. result.add typeToString(arg[i].typ, prefer)
  266. elif arg.typ == nil:
  267. result = "void"
  268. else:
  269. result = arg.typ.typeToString(prefer)
  270. proc describeArgs*(c: PContext, n: PNode, startIdx = 1;
  271. prefer: TPreferedDesc = preferName): string =
  272. result = ""
  273. for i in startIdx ..< n.len:
  274. var arg = n.sons[i]
  275. if n.sons[i].kind == nkExprEqExpr:
  276. add(result, renderTree(n.sons[i].sons[0]))
  277. add(result, ": ")
  278. if arg.typ.isNil and arg.kind notin {nkStmtList, nkDo}:
  279. # XXX we really need to 'tryExpr' here!
  280. arg = c.semOperand(c, n.sons[i].sons[1])
  281. n.sons[i].typ = arg.typ
  282. n.sons[i].sons[1] = arg
  283. else:
  284. if arg.typ.isNil and arg.kind notin {nkStmtList, nkDo, nkElse,
  285. nkOfBranch, nkElifBranch,
  286. nkExceptBranch}:
  287. arg = c.semOperand(c, n.sons[i])
  288. n.sons[i] = arg
  289. if arg.typ != nil and arg.typ.kind == tyError: return
  290. add(result, argTypeToString(arg, prefer))
  291. if i != sonsLen(n) - 1: add(result, ", ")
  292. proc typeRel*(c: var TCandidate, f, aOrig: PType,
  293. flags: TTypeRelFlags = {}): TTypeRelation
  294. proc concreteType(c: TCandidate, t: PType; f: PType = nil): PType =
  295. case t.kind
  296. of tyNil:
  297. result = nil # what should it be?
  298. of tyTypeDesc:
  299. if c.isNoCall: result = t
  300. else: result = nil
  301. of tySequence, tySet:
  302. if t.sons[0].kind == tyEmpty: result = nil
  303. else: result = t
  304. of tyGenericParam, tyAnything:
  305. result = t
  306. while true:
  307. result = PType(idTableGet(c.bindings, t))
  308. if result == nil:
  309. break # it's ok, no match
  310. # example code that triggers it:
  311. # proc sort[T](cmp: proc(a, b: T): int = cmp)
  312. if result.kind != tyGenericParam: break
  313. of tyGenericInvocation:
  314. result = t
  315. doAssert(false, "cannot resolve type: " & typeToString(t))
  316. of tyOwned:
  317. # bug #11257: the comparison system.`==`[T: proc](x, y: T) works
  318. # better without the 'owned' type:
  319. if f != nil and f.len > 0 and f.sons[0].skipTypes({tyBuiltInTypeClass}).kind == tyProc:
  320. result = t.lastSon
  321. else:
  322. result = t
  323. else:
  324. result = t # Note: empty is valid here
  325. proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
  326. if a.kind == f.kind:
  327. result = isEqual
  328. else:
  329. let ab = skipTypes(a, {tyRange})
  330. let k = ab.kind
  331. if k == f.kind: result = isSubrange
  332. elif k == tyInt and f.kind in {tyRange, tyInt8..tyInt64,
  333. tyUInt..tyUInt64} and
  334. isIntLit(ab) and ab.n.intVal >= firstOrd(nil, f) and
  335. ab.n.intVal <= lastOrd(nil, f):
  336. # passing 'nil' to firstOrd/lastOrd here as type checking rules should
  337. # not depent on the target integer size configurations!
  338. # integer literal in the proper range; we want ``i16 + 4`` to stay an
  339. # ``int16`` operation so we declare the ``4`` pseudo-equal to int16
  340. result = isFromIntLit
  341. elif f.kind == tyInt and k in {tyInt8..tyInt32}:
  342. result = isIntConv
  343. elif f.kind == tyUInt and k in {tyUInt8..tyUInt32}:
  344. result = isIntConv
  345. elif k >= min and k <= max:
  346. result = isConvertible
  347. elif a.kind == tyRange and
  348. # Make sure the conversion happens between types w/ same signedness
  349. (f.kind in {tyInt..tyInt64} and a[0].kind in {tyInt..tyInt64} or
  350. f.kind in {tyUInt8..tyUInt32} and a[0].kind in {tyUInt8..tyInt32}) and
  351. a.n[0].intVal >= firstOrd(nil, f) and a.n[1].intVal <= lastOrd(nil, f):
  352. # passing 'nil' to firstOrd/lastOrd here as type checking rules should
  353. # not depent on the target integer size configurations!
  354. result = isConvertible
  355. else: result = isNone
  356. proc isConvertibleToRange(f, a: PType): bool =
  357. # be less picky for tyRange, as that it is used for array indexing:
  358. if f.kind in {tyInt..tyInt64, tyUInt..tyUInt64} and
  359. a.kind in {tyInt..tyInt64, tyUInt..tyUInt64}:
  360. case f.kind
  361. of tyInt, tyInt64: result = true
  362. of tyInt8: result = a.kind in {tyInt8, tyInt}
  363. of tyInt16: result = a.kind in {tyInt8, tyInt16, tyInt}
  364. of tyInt32: result = a.kind in {tyInt8, tyInt16, tyInt32, tyInt}
  365. of tyUInt, tyUInt64: result = true
  366. of tyUInt8: result = a.kind in {tyUInt8, tyUInt}
  367. of tyUInt16: result = a.kind in {tyUInt8, tyUInt16, tyUInt}
  368. of tyUInt32: result = a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt}
  369. else: result = false
  370. elif f.kind in {tyFloat..tyFloat128} and
  371. a.kind in {tyFloat..tyFloat128}:
  372. result = true
  373. proc handleFloatRange(f, a: PType): TTypeRelation =
  374. if a.kind == f.kind:
  375. result = isEqual
  376. else:
  377. let ab = skipTypes(a, {tyRange})
  378. var k = ab.kind
  379. if k == f.kind: result = isSubrange
  380. elif isFloatLit(ab): result = isFromIntLit
  381. elif isIntLit(ab): result = isConvertible
  382. elif k >= tyFloat and k <= tyFloat128:
  383. # conversion to "float32" is not as good:
  384. if f.kind == tyFloat32: result = isConvertible
  385. else: result = isIntConv
  386. else: result = isNone
  387. proc genericParamPut(c: var TCandidate; last, fGenericOrigin: PType) =
  388. if fGenericOrigin != nil and last.kind == tyGenericInst and
  389. last.len-1 == fGenericOrigin.len:
  390. for i in 1 ..< sonsLen(fGenericOrigin):
  391. let x = PType(idTableGet(c.bindings, fGenericOrigin.sons[i]))
  392. if x == nil:
  393. put(c, fGenericOrigin.sons[i], last.sons[i])
  394. proc isObjectSubtype(c: var TCandidate; a, f, fGenericOrigin: PType): int =
  395. var t = a
  396. assert t.kind == tyObject
  397. var depth = 0
  398. var last = a
  399. while t != nil and not sameObjectTypes(f, t):
  400. assert t.kind == tyObject
  401. t = t.sons[0]
  402. if t == nil: break
  403. last = t
  404. t = skipTypes(t, skipPtrs)
  405. inc depth
  406. if t != nil:
  407. genericParamPut(c, last, fGenericOrigin)
  408. result = depth
  409. else:
  410. result = -1
  411. type
  412. SkippedPtr = enum skippedNone, skippedRef, skippedPtr
  413. proc skipToObject(t: PType; skipped: var SkippedPtr): PType =
  414. var r = t
  415. # we're allowed to skip one level of ptr/ref:
  416. var ptrs = 0
  417. while r != nil:
  418. case r.kind
  419. of tyGenericInvocation:
  420. r = r.sons[0]
  421. of tyRef:
  422. inc ptrs
  423. skipped = skippedRef
  424. r = r.lastSon
  425. of tyPtr:
  426. inc ptrs
  427. skipped = skippedPtr
  428. r = r.lastSon
  429. of tyGenericBody, tyGenericInst, tyAlias, tySink, tyOwned:
  430. r = r.lastSon
  431. else:
  432. break
  433. if r.kind == tyObject and ptrs <= 1: result = r
  434. proc isGenericSubtype(c: var TCandidate; a, f: PType, d: var int, fGenericOrigin: PType): bool =
  435. assert f.kind in {tyGenericInst, tyGenericInvocation, tyGenericBody}
  436. var askip = skippedNone
  437. var fskip = skippedNone
  438. var t = a.skipToObject(askip)
  439. let r = f.skipToObject(fskip)
  440. if r == nil: return false
  441. var depth = 0
  442. var last = a
  443. # XXX sameObjectType can return false here. Need to investigate
  444. # why that is but sameObjectType does way too much work here anyway.
  445. while t != nil and r.sym != t.sym and askip == fskip:
  446. t = t.sons[0]
  447. if t == nil: break
  448. last = t
  449. t = t.skipToObject(askip)
  450. inc depth
  451. if t != nil and askip == fskip:
  452. genericParamPut(c, last, fGenericOrigin)
  453. d = depth
  454. result = true
  455. proc minRel(a, b: TTypeRelation): TTypeRelation =
  456. if a <= b: result = a
  457. else: result = b
  458. proc recordRel(c: var TCandidate, f, a: PType): TTypeRelation =
  459. result = isNone
  460. if sameType(f, a):
  461. result = isEqual
  462. elif sonsLen(a) == sonsLen(f):
  463. result = isEqual
  464. let firstField = if f.kind == tyTuple: 0
  465. else: 1
  466. for i in firstField ..< sonsLen(f):
  467. var m = typeRel(c, f.sons[i], a.sons[i])
  468. if m < isSubtype: return isNone
  469. result = minRel(result, m)
  470. if f.n != nil and a.n != nil:
  471. for i in 0 ..< sonsLen(f.n):
  472. # check field names:
  473. if f.n.sons[i].kind != nkSym: return isNone
  474. elif a.n.sons[i].kind != nkSym: return isNone
  475. else:
  476. var x = f.n.sons[i].sym
  477. var y = a.n.sons[i].sym
  478. if f.kind == tyObject and typeRel(c, x.typ, y.typ) < isSubtype:
  479. return isNone
  480. if x.name.id != y.name.id: return isNone
  481. proc allowsNil(f: PType): TTypeRelation {.inline.} =
  482. result = if tfNotNil notin f.flags: isSubtype else: isNone
  483. proc allowsNilDeprecated(c: TCandidate, f: PType): TTypeRelation =
  484. if optNilSeqs in c.c.config.options:
  485. result = allowsNil(f)
  486. else:
  487. result = isNone
  488. proc inconsistentVarTypes(f, a: PType): bool {.inline.} =
  489. result = f.kind != a.kind and (f.kind in {tyVar, tyLent} or a.kind in {tyVar, tyLent})
  490. proc procParamTypeRel(c: var TCandidate, f, a: PType): TTypeRelation =
  491. ## For example we have:
  492. ## .. code-block:: nim
  493. ## proc myMap[T,S](sIn: seq[T], f: proc(x: T): S): seq[S] = ...
  494. ## proc innerProc[Q,W](q: Q): W = ...
  495. ## And we want to match: myMap(@[1,2,3], innerProc)
  496. ## This proc (procParamTypeRel) will do the following steps in
  497. ## three different calls:
  498. ## - matches f=T to a=Q. Since f is metatype, we resolve it
  499. ## to int (which is already known at this point). So in this case
  500. ## Q=int mapping will be saved to c.bindings.
  501. ## - matches f=S to a=W. Both of these metatypes are unknown, so we
  502. ## return with isBothMetaConvertible to ask for rerun.
  503. ## - matches f=S to a=W. At this point the return type of innerProc
  504. ## is known (we get it from c.bindings). We can use that value
  505. ## to match with f, and save back to c.bindings.
  506. var
  507. f = f
  508. a = a
  509. if a.isMetaType:
  510. let aResolved = PType(idTableGet(c.bindings, a))
  511. if aResolved != nil:
  512. a = aResolved
  513. if a.isMetaType:
  514. if f.isMetaType:
  515. # We are matching a generic proc (as proc param)
  516. # to another generic type appearing in the proc
  517. # signature. There is a change that the target
  518. # type is already fully-determined, so we are
  519. # going to try resolve it
  520. if c.call != nil:
  521. f = generateTypeInstance(c.c, c.bindings, c.call.info, f)
  522. else:
  523. f = nil
  524. if f == nil or f.isMetaType:
  525. # no luck resolving the type, so the inference fails
  526. return isBothMetaConvertible
  527. # Note that this typeRel call will save a's resolved type into c.bindings
  528. let reverseRel = typeRel(c, a, f)
  529. if reverseRel >= isGeneric:
  530. result = isInferred
  531. #inc c.genericMatches
  532. else:
  533. # Note that this typeRel call will save f's resolved type into c.bindings
  534. # if f is metatype.
  535. result = typeRel(c, f, a)
  536. if result <= isSubtype or inconsistentVarTypes(f, a):
  537. result = isNone
  538. #if result == isEqual:
  539. # inc c.exactMatches
  540. proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation =
  541. case a.kind
  542. of tyProc:
  543. if sonsLen(f) != sonsLen(a): return
  544. result = isEqual # start with maximum; also correct for no
  545. # params at all
  546. template checkParam(f, a) =
  547. result = minRel(result, procParamTypeRel(c, f, a))
  548. if result == isNone: return
  549. # Note: We have to do unification for the parameters before the
  550. # return type!
  551. for i in 1 ..< f.sonsLen:
  552. checkParam(f.sons[i], a.sons[i])
  553. if f.sons[0] != nil:
  554. if a.sons[0] != nil:
  555. checkParam(f.sons[0], a.sons[0])
  556. else:
  557. return isNone
  558. elif a.sons[0] != nil:
  559. return isNone
  560. if tfNoSideEffect in f.flags and tfNoSideEffect notin a.flags:
  561. return isNone
  562. elif tfThread in f.flags and a.flags * {tfThread, tfNoSideEffect} == {} and
  563. optThreadAnalysis in c.c.config.globalOptions:
  564. # noSideEffect implies ``tfThread``!
  565. return isNone
  566. elif f.flags * {tfIterator} != a.flags * {tfIterator}:
  567. return isNone
  568. elif f.callConv != a.callConv:
  569. # valid to pass a 'nimcall' thingie to 'closure':
  570. if f.callConv == ccClosure and a.callConv == ccDefault:
  571. result = if result == isInferred: isInferredConvertible
  572. elif result == isBothMetaConvertible: isBothMetaConvertible
  573. else: isConvertible
  574. else:
  575. return isNone
  576. when useEffectSystem:
  577. if compatibleEffects(f, a) != efCompat: return isNone
  578. of tyNil:
  579. result = f.allowsNil
  580. else: discard
  581. proc typeRangeRel(f, a: PType): TTypeRelation {.noinline.} =
  582. template checkRange[T](a0, a1, f0, f1: T): TTypeRelation =
  583. if a0 == f0 and a1 == f1:
  584. isEqual
  585. elif a0 >= f0 and a1 <= f1:
  586. isConvertible
  587. elif a0 <= f1 and f0 <= a1:
  588. # X..Y and C..D overlap iff (X <= D and C <= Y)
  589. isConvertible
  590. else:
  591. isNone
  592. if f.isOrdinalType:
  593. checkRange(firstOrd(nil, a), lastOrd(nil, a), firstOrd(nil, f), lastOrd(nil, f))
  594. else:
  595. checkRange(firstFloat(a), lastFloat(a), firstFloat(f), lastFloat(f))
  596. proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
  597. var
  598. c = m.c
  599. typeClass = ff.skipTypes({tyUserTypeClassInst})
  600. body = typeClass.n[3]
  601. matchedConceptContext: TMatchedConcept
  602. prevMatchedConcept = c.matchedConcept
  603. prevCandidateType = typeClass[0][0]
  604. if prevMatchedConcept != nil:
  605. matchedConceptContext.prev = prevMatchedConcept
  606. matchedConceptContext.depth = prevMatchedConcept.depth + 1
  607. if prevMatchedConcept.depth > 4:
  608. localError(m.c.graph.config, body.info, $body & " too nested for type matching")
  609. return nil
  610. openScope(c)
  611. matchedConceptContext.candidateType = a
  612. typeClass[0].sons[0] = a
  613. c.matchedConcept = addr(matchedConceptContext)
  614. defer:
  615. c.matchedConcept = prevMatchedConcept
  616. typeClass[0].sons[0] = prevCandidateType
  617. closeScope(c)
  618. var typeParams: seq[(PSym, PType)]
  619. if ff.kind == tyUserTypeClassInst:
  620. for i in 1 ..< (ff.len - 1):
  621. var
  622. typeParamName = ff.base.sons[i-1].sym.name
  623. typ = ff.sons[i]
  624. param: PSym
  625. alreadyBound = PType(idTableGet(m.bindings, typ))
  626. if alreadyBound != nil: typ = alreadyBound
  627. template paramSym(kind): untyped =
  628. newSym(kind, typeParamName, typeClass.sym, typeClass.sym.info, {})
  629. block addTypeParam:
  630. for prev in typeParams:
  631. if prev[1].id == typ.id:
  632. param = paramSym prev[0].kind
  633. param.typ = prev[0].typ
  634. break addTypeParam
  635. case typ.kind
  636. of tyStatic:
  637. param = paramSym skConst
  638. param.typ = typ.exactReplica
  639. if typ.n == nil:
  640. param.typ.flags.incl tfInferrableStatic
  641. else:
  642. param.ast = typ.n
  643. of tyUnknown:
  644. param = paramSym skVar
  645. param.typ = typ.exactReplica
  646. else:
  647. param = paramSym skType
  648. param.typ = if typ.isMetaType:
  649. c.newTypeWithSons(tyInferred, @[typ])
  650. else:
  651. makeTypeDesc(c, typ)
  652. typeParams.add((param, typ))
  653. addDecl(c, param)
  654. var
  655. oldWriteHook: type(m.c.config.writelnHook)
  656. diagnostics: seq[string]
  657. errorPrefix: string
  658. flags: TExprFlags = {}
  659. collectDiagnostics = m.diagnosticsEnabled or
  660. sfExplain in typeClass.sym.flags
  661. if collectDiagnostics:
  662. oldWriteHook = m.c.config.writelnHook
  663. # XXX: we can't write to m.diagnostics directly, because
  664. # Nim doesn't support capturing var params in closures
  665. diagnostics = @[]
  666. flags = {efExplain}
  667. m.c.config.writelnHook = proc (s: string) =
  668. if errorPrefix.len == 0: errorPrefix = typeClass.sym.name.s & ":"
  669. let msg = s.replace("Error:", errorPrefix)
  670. if oldWriteHook != nil: oldWriteHook msg
  671. diagnostics.add msg
  672. var checkedBody = c.semTryExpr(c, body.copyTree, flags)
  673. if collectDiagnostics:
  674. m.c.config.writelnHook = oldWriteHook
  675. for msg in diagnostics:
  676. m.diagnostics.add msg
  677. m.diagnosticsEnabled = true
  678. if checkedBody == nil: return nil
  679. # The inferrable type params have been identified during the semTryExpr above.
  680. # We need to put them in the current sigmatch's binding table in order for them
  681. # to be resolvable while matching the rest of the parameters
  682. for p in typeParams:
  683. put(m, p[1], p[0].typ)
  684. if ff.kind == tyUserTypeClassInst:
  685. result = generateTypeInstance(c, m.bindings, typeClass.sym.info, ff)
  686. else:
  687. result = copyType(ff, ff.owner, true)
  688. result.n = checkedBody
  689. proc shouldSkipDistinct(m: TCandidate; rules: PNode, callIdent: PIdent): bool =
  690. # XXX This is bad as 'considerQuotedIdent' can produce an error!
  691. if rules.kind == nkWith:
  692. for r in rules:
  693. if considerQuotedIdent(m.c, r) == callIdent: return true
  694. return false
  695. else:
  696. for r in rules:
  697. if considerQuotedIdent(m.c, r) == callIdent: return false
  698. return true
  699. proc maybeSkipDistinct(m: TCandidate; t: PType, callee: PSym): PType =
  700. if t != nil and t.kind == tyDistinct and t.n != nil and
  701. shouldSkipDistinct(m, t.n, callee.name):
  702. result = t.base
  703. else:
  704. result = t
  705. proc tryResolvingStaticExpr(c: var TCandidate, n: PNode,
  706. allowUnresolved = false): PNode =
  707. # Consider this example:
  708. # type Value[N: static[int]] = object
  709. # proc foo[N](a: Value[N], r: range[0..(N-1)])
  710. # Here, N-1 will be initially nkStaticExpr that can be evaluated only after
  711. # N is bound to a concrete value during the matching of the first param.
  712. # This proc is used to evaluate such static expressions.
  713. let instantiated = replaceTypesInBody(c.c, c.bindings, n, nil,
  714. allowMetaTypes = allowUnresolved)
  715. result = c.c.semExpr(c.c, instantiated)
  716. proc inferStaticParam*(c: var TCandidate, lhs: PNode, rhs: BiggestInt): bool =
  717. # This is a simple integer arithimetic equation solver,
  718. # capable of deriving the value of a static parameter in
  719. # expressions such as (N + 5) / 2 = rhs
  720. #
  721. # Preconditions:
  722. #
  723. # * The input of this proc must be semantized
  724. # - all templates should be expanded
  725. # - aby constant folding possible should already be performed
  726. #
  727. # * There must be exactly one unresolved static parameter
  728. #
  729. # Result:
  730. #
  731. # The proc will return true if the static types was successfully
  732. # inferred. The result will be bound to the original static type
  733. # in the TCandidate.
  734. #
  735. if lhs.kind in nkCallKinds and lhs[0].kind == nkSym:
  736. case lhs[0].sym.magic
  737. of mUnaryLt:
  738. return inferStaticParam(c, lhs[1], rhs + 1)
  739. of mAddI, mAddU, mInc, mSucc:
  740. if lhs[1].kind == nkIntLit:
  741. return inferStaticParam(c, lhs[2], rhs - lhs[1].intVal)
  742. elif lhs[2].kind == nkIntLit:
  743. return inferStaticParam(c, lhs[1], rhs - lhs[2].intVal)
  744. of mDec, mSubI, mSubU, mPred:
  745. if lhs[1].kind == nkIntLit:
  746. return inferStaticParam(c, lhs[2], lhs[1].intVal - rhs)
  747. elif lhs[2].kind == nkIntLit:
  748. return inferStaticParam(c, lhs[1], rhs + lhs[2].intVal)
  749. of mMulI, mMulU:
  750. if lhs[1].kind == nkIntLit:
  751. if rhs mod lhs[1].intVal == 0:
  752. return inferStaticParam(c, lhs[2], rhs div lhs[1].intVal)
  753. elif lhs[2].kind == nkIntLit:
  754. if rhs mod lhs[2].intVal == 0:
  755. return inferStaticParam(c, lhs[1], rhs div lhs[2].intVal)
  756. of mDivI, mDivU:
  757. if lhs[1].kind == nkIntLit:
  758. if lhs[1].intVal mod rhs == 0:
  759. return inferStaticParam(c, lhs[2], lhs[1].intVal div rhs)
  760. elif lhs[2].kind == nkIntLit:
  761. return inferStaticParam(c, lhs[1], lhs[2].intVal * rhs)
  762. of mShlI:
  763. if lhs[2].kind == nkIntLit:
  764. return inferStaticParam(c, lhs[1], rhs shr lhs[2].intVal)
  765. of mShrI:
  766. if lhs[2].kind == nkIntLit:
  767. return inferStaticParam(c, lhs[1], rhs shl lhs[2].intVal)
  768. of mAshrI:
  769. if lhs[2].kind == nkIntLit:
  770. return inferStaticParam(c, lhs[1], ashr(rhs, lhs[2].intVal))
  771. of mUnaryMinusI:
  772. return inferStaticParam(c, lhs[1], -rhs)
  773. of mUnaryPlusI, mToInt, mToBiggestInt:
  774. return inferStaticParam(c, lhs[1], rhs)
  775. else: discard
  776. elif lhs.kind == nkSym and lhs.typ.kind == tyStatic and lhs.typ.n == nil:
  777. var inferred = newTypeWithSons(c.c, tyStatic, lhs.typ.sons)
  778. inferred.n = newIntNode(nkIntLit, rhs)
  779. put(c, lhs.typ, inferred)
  780. if c.c.matchedConcept != nil:
  781. # inside concepts, binding is currently done with
  782. # direct mutation of the involved types:
  783. lhs.typ.n = inferred.n
  784. return true
  785. return false
  786. proc failureToInferStaticParam(conf: ConfigRef; n: PNode) =
  787. let staticParam = n.findUnresolvedStatic
  788. let name = if staticParam != nil: staticParam.sym.name.s
  789. else: "unknown"
  790. localError(conf, n.info, "cannot infer the value of the static param '" & name & "'")
  791. proc inferStaticsInRange(c: var TCandidate,
  792. inferred, concrete: PType): TTypeRelation =
  793. let lowerBound = tryResolvingStaticExpr(c, inferred.n[0],
  794. allowUnresolved = true)
  795. let upperBound = tryResolvingStaticExpr(c, inferred.n[1],
  796. allowUnresolved = true)
  797. template doInferStatic(e: PNode, r: BiggestInt) =
  798. var exp = e
  799. var rhs = r
  800. if inferStaticParam(c, exp, rhs):
  801. return isGeneric
  802. else:
  803. failureToInferStaticParam(c.c.config, exp)
  804. if lowerBound.kind == nkIntLit:
  805. if upperBound.kind == nkIntLit:
  806. if lengthOrd(c.c.config, concrete) == upperBound.intVal - lowerBound.intVal + 1:
  807. return isGeneric
  808. else:
  809. return isNone
  810. doInferStatic(upperBound, lengthOrd(c.c.config, concrete) + lowerBound.intVal - 1)
  811. elif upperBound.kind == nkIntLit:
  812. doInferStatic(lowerBound, upperBound.intVal + 1 - lengthOrd(c.c.config, concrete))
  813. template subtypeCheck() =
  814. if result <= isSubrange and f.lastSon.skipTypes(abstractInst).kind in {
  815. tyRef, tyPtr, tyVar, tyLent, tyOwned}:
  816. result = isNone
  817. proc isCovariantPtr(c: var TCandidate, f, a: PType): bool =
  818. # this proc is always called for a pair of matching types
  819. assert f.kind == a.kind
  820. template baseTypesCheck(lhs, rhs: PType): bool =
  821. lhs.kind notin {tyPtr, tyRef, tyVar, tyLent, tyOwned} and
  822. typeRel(c, lhs, rhs, {trNoCovariance}) == isSubtype
  823. case f.kind
  824. of tyRef, tyPtr, tyOwned:
  825. return baseTypesCheck(f.base, a.base)
  826. of tyGenericInst:
  827. let body = f.base
  828. return body == a.base and
  829. a.sonsLen == 3 and
  830. tfWeakCovariant notin body.sons[0].flags and
  831. baseTypesCheck(f.sons[1], a.sons[1])
  832. else:
  833. return false
  834. when false:
  835. proc maxNumericType(prev, candidate: PType): PType =
  836. let c = candidate.skipTypes({tyRange})
  837. template greater(s) =
  838. if c.kind in s: result = c
  839. case prev.kind
  840. of tyInt: greater({tyInt64})
  841. of tyInt8: greater({tyInt, tyInt16, tyInt32, tyInt64})
  842. of tyInt16: greater({tyInt, tyInt32, tyInt64})
  843. of tyInt32: greater({tyInt64})
  844. of tyUInt: greater({tyUInt64})
  845. of tyUInt8: greater({tyUInt, tyUInt16, tyUInt32, tyUInt64})
  846. of tyUInt16: greater({tyUInt, tyUInt32, tyUInt64})
  847. of tyUInt32: greater({tyUInt64})
  848. of tyFloat32: greater({tyFloat64, tyFloat128})
  849. of tyFloat64: greater({tyFloat128})
  850. else: discard
  851. template skipOwned(a) =
  852. if a.kind == tyOwned: a = a.skipTypes({tyOwned, tyGenericInst})
  853. proc typeRel(c: var TCandidate, f, aOrig: PType,
  854. flags: TTypeRelFlags = {}): TTypeRelation =
  855. # typeRel can be used to establish various relationships between types:
  856. #
  857. # 1) When used with concrete types, it will check for type equivalence
  858. # or a subtype relationship.
  859. #
  860. # 2) When used with a concrete type against a type class (such as generic
  861. # signature of a proc), it will check whether the concrete type is a member
  862. # of the designated type class.
  863. #
  864. # 3) When used with two type classes, it will check whether the types
  865. # matching the first type class are a strict subset of the types matching
  866. # the other. This allows us to compare the signatures of generic procs in
  867. # order to give preferrence to the most specific one:
  868. #
  869. # seq[seq[any]] is a strict subset of seq[any] and hence more specific.
  870. result = isNone
  871. assert(f != nil)
  872. if f.kind == tyUntyped:
  873. if aOrig != nil: put(c, f, aOrig)
  874. return isGeneric
  875. assert(aOrig != nil)
  876. var
  877. useTypeLoweringRuleInTypeClass = c.c.matchedConcept != nil and
  878. not c.isNoCall and
  879. f.kind != tyTypeDesc and
  880. tfExplicit notin aOrig.flags and
  881. tfConceptMatchedTypeSym notin aOrig.flags
  882. aOrig = if useTypeLoweringRuleInTypeClass:
  883. aOrig.skipTypes({tyTypeDesc})
  884. else:
  885. aOrig
  886. if aOrig.kind == tyInferred:
  887. let prev = aOrig.previouslyInferred
  888. if prev != nil:
  889. return typeRel(c, f, prev)
  890. else:
  891. var candidate = f
  892. case f.kind
  893. of tyGenericParam:
  894. var prev = PType(idTableGet(c.bindings, f))
  895. if prev != nil: candidate = prev
  896. of tyFromExpr:
  897. let computedType = tryResolvingStaticExpr(c, f.n).typ
  898. case computedType.kind
  899. of tyTypeDesc:
  900. candidate = computedType.base
  901. of tyStatic:
  902. candidate = computedType
  903. else:
  904. # XXX What is this non-sense? Error reporting in signature matching?
  905. discard "localError(f.n.info, errTypeExpected)"
  906. else:
  907. discard
  908. result = typeRel(c, aOrig.base, candidate)
  909. if result != isNone:
  910. c.inferredTypes.add aOrig
  911. aOrig.sons.add candidate
  912. result = isEqual
  913. return
  914. template doBind: bool = trDontBind notin flags
  915. # var, sink and static arguments match regular modifier-free types
  916. var a = maybeSkipDistinct(c, aOrig.skipTypes({tyStatic, tyVar, tyLent, tySink}), c.calleeSym)
  917. # XXX: Theoretically, maybeSkipDistinct could be called before we even
  918. # start the param matching process. This could be done in `prepareOperand`
  919. # for example, but unfortunately `prepareOperand` is not called in certain
  920. # situation when nkDotExpr are rotated to nkDotCalls
  921. if aOrig.kind in {tyAlias, tySink}:
  922. return typeRel(c, f, lastSon(aOrig))
  923. if a.kind == tyGenericInst and
  924. skipTypes(f, {tyVar, tyLent, tySink}).kind notin {
  925. tyGenericBody, tyGenericInvocation,
  926. tyGenericInst, tyGenericParam} + tyTypeClasses:
  927. return typeRel(c, f, lastSon(a))
  928. if a.isResolvedUserTypeClass:
  929. return typeRel(c, f, a.lastSon)
  930. template bindingRet(res) =
  931. if doBind:
  932. let bound = aOrig.skipTypes({tyRange}).skipIntLit
  933. put(c, f, bound)
  934. return res
  935. template considerPreviousT(body: untyped) =
  936. var prev = PType(idTableGet(c.bindings, f))
  937. if prev == nil: body
  938. else: return typeRel(c, prev, a)
  939. case a.kind
  940. of tyOr:
  941. # XXX: deal with the current dual meaning of tyGenericParam
  942. c.typedescMatched = true
  943. # seq[int|string] vs seq[number]
  944. # both int and string must match against number
  945. # but ensure that '[T: A|A]' matches as good as '[T: A]' (bug #2219):
  946. result = isGeneric
  947. for branch in a.sons:
  948. let x = typeRel(c, f, branch, flags + {trDontBind})
  949. if x == isNone: return isNone
  950. if x < result: result = x
  951. return
  952. of tyAnd:
  953. # XXX: deal with the current dual meaning of tyGenericParam
  954. c.typedescMatched = true
  955. # seq[Sortable and Iterable] vs seq[Sortable]
  956. # only one match is enough
  957. for branch in a.sons:
  958. let x = typeRel(c, f, branch, flags + {trDontBind})
  959. if x != isNone:
  960. return if x >= isGeneric: isGeneric else: x
  961. return isNone
  962. of tyNot:
  963. case f.kind
  964. of tyNot:
  965. # seq[!int] vs seq[!number]
  966. # seq[float] matches the first, but not the second
  967. # we must turn the problem around:
  968. # is number a subset of int?
  969. return typeRel(c, a.lastSon, f.lastSon)
  970. else:
  971. # negative type classes are essentially infinite,
  972. # so only the `any` type class is their superset
  973. return if f.kind == tyAnything: isGeneric
  974. else: isNone
  975. of tyAnything:
  976. if f.kind == tyAnything: return isGeneric
  977. else: return isNone
  978. of tyUserTypeClass, tyUserTypeClassInst:
  979. if c.c.matchedConcept != nil and c.c.matchedConcept.depth <= 4:
  980. # consider this: 'var g: Node' *within* a concept where 'Node'
  981. # is a concept too (tgraph)
  982. inc c.c.matchedConcept.depth
  983. let x = typeRel(c, a, f, flags + {trDontBind})
  984. if x >= isGeneric:
  985. return isGeneric
  986. else: discard
  987. case f.kind
  988. of tyEnum:
  989. if a.kind == f.kind and sameEnumTypes(f, a): result = isEqual
  990. elif sameEnumTypes(f, skipTypes(a, {tyRange})): result = isSubtype
  991. of tyBool, tyChar:
  992. if a.kind == f.kind: result = isEqual
  993. elif skipTypes(a, {tyRange}).kind == f.kind: result = isSubtype
  994. of tyRange:
  995. if a.kind == f.kind:
  996. if f.base.kind == tyNone: return isGeneric
  997. result = typeRel(c, base(f), base(a))
  998. # bugfix: accept integer conversions here
  999. #if result < isGeneric: result = isNone
  1000. if result notin {isNone, isGeneric}:
  1001. # resolve any late-bound static expressions
  1002. # that may appear in the range:
  1003. for i in 0..1:
  1004. if f.n[i].kind == nkStaticExpr:
  1005. f.n.sons[i] = tryResolvingStaticExpr(c, f.n[i])
  1006. result = typeRangeRel(f, a)
  1007. else:
  1008. if skipTypes(f, {tyRange}).kind == a.kind:
  1009. result = isIntConv
  1010. elif isConvertibleToRange(skipTypes(f, {tyRange}), a):
  1011. result = isConvertible # a convertible to f
  1012. of tyInt: result = handleRange(f, a, tyInt8, tyInt32)
  1013. of tyInt8: result = handleRange(f, a, tyInt8, tyInt8)
  1014. of tyInt16: result = handleRange(f, a, tyInt8, tyInt16)
  1015. of tyInt32: result = handleRange(f, a, tyInt8, tyInt32)
  1016. of tyInt64: result = handleRange(f, a, tyInt, tyInt64)
  1017. of tyUInt: result = handleRange(f, a, tyUInt8, tyUInt32)
  1018. of tyUInt8: result = handleRange(f, a, tyUInt8, tyUInt8)
  1019. of tyUInt16: result = handleRange(f, a, tyUInt8, tyUInt16)
  1020. of tyUInt32: result = handleRange(f, a, tyUInt8, tyUInt32)
  1021. of tyUInt64: result = handleRange(f, a, tyUInt, tyUInt64)
  1022. of tyFloat: result = handleFloatRange(f, a)
  1023. of tyFloat32: result = handleFloatRange(f, a)
  1024. of tyFloat64: result = handleFloatRange(f, a)
  1025. of tyFloat128: result = handleFloatRange(f, a)
  1026. of tyVar, tyLent:
  1027. if aOrig.kind == f.kind: result = typeRel(c, f.base, aOrig.base)
  1028. else: result = typeRel(c, f.base, aOrig, flags + {trNoCovariance})
  1029. subtypeCheck()
  1030. of tyArray:
  1031. case a.kind
  1032. of tyArray:
  1033. var fRange = f.sons[0]
  1034. var aRange = a.sons[0]
  1035. if fRange.kind == tyGenericParam:
  1036. var prev = PType(idTableGet(c.bindings, fRange))
  1037. if prev == nil:
  1038. put(c, fRange, a.sons[0])
  1039. fRange = a
  1040. else:
  1041. fRange = prev
  1042. let ff = f.sons[1].skipTypes({tyTypeDesc})
  1043. # This typeDesc rule is wrong, see bug #7331
  1044. let aa = a.sons[1] #.skipTypes({tyTypeDesc})
  1045. if f.sons[0].kind != tyGenericParam and aa.kind == tyEmpty:
  1046. result = isGeneric
  1047. else:
  1048. result = typeRel(c, ff, aa)
  1049. if result < isGeneric:
  1050. if nimEnableCovariance and
  1051. trNoCovariance notin flags and
  1052. ff.kind == aa.kind and
  1053. isCovariantPtr(c, ff, aa):
  1054. result = isSubtype
  1055. else:
  1056. return isNone
  1057. if fRange.rangeHasUnresolvedStatic:
  1058. return inferStaticsInRange(c, fRange, a)
  1059. elif c.c.matchedConcept != nil and aRange.rangeHasUnresolvedStatic:
  1060. return inferStaticsInRange(c, aRange, f)
  1061. else:
  1062. if lengthOrd(c.c.config, fRange) != lengthOrd(c.c.config, aRange):
  1063. result = isNone
  1064. else: discard
  1065. of tyUncheckedArray:
  1066. if a.kind == tyUncheckedArray:
  1067. result = typeRel(c, base(f), base(a))
  1068. if result < isGeneric: result = isNone
  1069. else: discard
  1070. of tyOpenArray, tyVarargs:
  1071. # varargs[expr] is special too but handled earlier. So we only need to
  1072. # handle varargs[stmt] which is the same as varargs[typed]:
  1073. if f.kind == tyVarargs:
  1074. if tfVarargs in a.flags:
  1075. return typeRel(c, f.base, a.lastSon)
  1076. if f.sons[0].kind == tyTyped: return
  1077. template matchArrayOrSeq(aBase: PType) =
  1078. let ff = f.base
  1079. let aa = aBase
  1080. let baseRel = typeRel(c, ff, aa)
  1081. if baseRel >= isGeneric:
  1082. result = isConvertible
  1083. elif nimEnableCovariance and
  1084. trNoCovariance notin flags and
  1085. ff.kind == aa.kind and
  1086. isCovariantPtr(c, ff, aa):
  1087. result = isConvertible
  1088. case a.kind
  1089. of tyOpenArray, tyVarargs:
  1090. result = typeRel(c, base(f), base(a))
  1091. if result < isGeneric: result = isNone
  1092. of tyArray:
  1093. if (f.sons[0].kind != tyGenericParam) and (a.sons[1].kind == tyEmpty):
  1094. return isSubtype
  1095. matchArrayOrSeq(a.sons[1])
  1096. of tySequence:
  1097. if (f.sons[0].kind != tyGenericParam) and (a.sons[0].kind == tyEmpty):
  1098. return isConvertible
  1099. matchArrayOrSeq(a.sons[0])
  1100. of tyString:
  1101. if f.kind == tyOpenArray:
  1102. if f.sons[0].kind == tyChar:
  1103. result = isConvertible
  1104. elif f.sons[0].kind == tyGenericParam and a.len > 0 and
  1105. typeRel(c, base(f), base(a)) >= isGeneric:
  1106. result = isConvertible
  1107. else: discard
  1108. of tySequence:
  1109. case a.kind
  1110. of tySequence:
  1111. if (f.sons[0].kind != tyGenericParam) and (a.sons[0].kind == tyEmpty):
  1112. result = isSubtype
  1113. else:
  1114. let ff = f.sons[0]
  1115. let aa = a.sons[0]
  1116. result = typeRel(c, ff, aa)
  1117. if result < isGeneric:
  1118. if nimEnableCovariance and
  1119. trNoCovariance notin flags and
  1120. ff.kind == aa.kind and
  1121. isCovariantPtr(c, ff, aa):
  1122. result = isSubtype
  1123. else:
  1124. result = isNone
  1125. elif tfNotNil in f.flags and tfNotNil notin a.flags:
  1126. result = isNilConversion
  1127. of tyNil: result = allowsNilDeprecated(c, f)
  1128. else: discard
  1129. of tyOrdinal:
  1130. if isOrdinalType(a):
  1131. var x = if a.kind == tyOrdinal: a.sons[0] else: a
  1132. if f.sons[0].kind == tyNone:
  1133. result = isGeneric
  1134. else:
  1135. result = typeRel(c, f.sons[0], x)
  1136. if result < isGeneric: result = isNone
  1137. elif a.kind == tyGenericParam:
  1138. result = isGeneric
  1139. of tyForward:
  1140. #internalError("forward type in typeRel()")
  1141. result = isNone
  1142. of tyNil:
  1143. skipOwned(a)
  1144. if a.kind == f.kind: result = isEqual
  1145. of tyTuple:
  1146. if a.kind == tyTuple: result = recordRel(c, f, a)
  1147. of tyObject:
  1148. if a.kind == tyObject:
  1149. if sameObjectTypes(f, a):
  1150. result = isEqual
  1151. # elif tfHasMeta in f.flags: result = recordRel(c, f, a)
  1152. else:
  1153. var depth = isObjectSubtype(c, a, f, nil)
  1154. if depth > 0:
  1155. inc(c.inheritancePenalty, depth)
  1156. result = isSubtype
  1157. of tyDistinct:
  1158. if a.kind == tyDistinct:
  1159. if sameDistinctTypes(f, a): result = isEqual
  1160. #elif f.base.kind == tyAnything: result = isGeneric # issue 4435
  1161. elif c.coerceDistincts: result = typeRel(c, f.base, a)
  1162. elif a.kind == tyNil and f.base.kind in NilableTypes:
  1163. result = f.allowsNil # XXX remove this typing rule, it is not in the spec
  1164. elif c.coerceDistincts: result = typeRel(c, f.base, a)
  1165. of tySet:
  1166. if a.kind == tySet:
  1167. if f.sons[0].kind != tyGenericParam and a.sons[0].kind == tyEmpty:
  1168. result = isSubtype
  1169. else:
  1170. result = typeRel(c, f.sons[0], a.sons[0])
  1171. if result <= isConvertible:
  1172. result = isNone # BUGFIX!
  1173. of tyPtr, tyRef:
  1174. skipOwned(a)
  1175. if a.kind == f.kind:
  1176. # ptr[R, T] can be passed to ptr[T], but not the other way round:
  1177. if a.len < f.len: return isNone
  1178. for i in 0..f.len-2:
  1179. if typeRel(c, f.sons[i], a.sons[i]) == isNone: return isNone
  1180. result = typeRel(c, f.lastSon, a.lastSon, flags + {trNoCovariance})
  1181. subtypeCheck()
  1182. if result <= isIntConv: result = isNone
  1183. elif tfNotNil in f.flags and tfNotNil notin a.flags:
  1184. result = isNilConversion
  1185. elif a.kind == tyNil: result = f.allowsNil
  1186. else: discard
  1187. of tyProc:
  1188. skipOwned(a)
  1189. result = procTypeRel(c, f, a)
  1190. if result != isNone and tfNotNil in f.flags and tfNotNil notin a.flags:
  1191. result = isNilConversion
  1192. of tyOwned:
  1193. case a.kind
  1194. of tyOwned:
  1195. result = typeRel(c, lastSon(f), lastSon(a))
  1196. of tyNil: result = f.allowsNil
  1197. else: discard
  1198. of tyPointer:
  1199. skipOwned(a)
  1200. case a.kind
  1201. of tyPointer:
  1202. if tfNotNil in f.flags and tfNotNil notin a.flags:
  1203. result = isNilConversion
  1204. else:
  1205. result = isEqual
  1206. of tyNil: result = f.allowsNil
  1207. of tyProc:
  1208. if a.callConv != ccClosure: result = isConvertible
  1209. of tyPtr:
  1210. # 'pointer' is NOT compatible to regionized pointers
  1211. # so 'dealloc(regionPtr)' fails:
  1212. if a.len == 1: result = isConvertible
  1213. of tyCString: result = isConvertible
  1214. else: discard
  1215. of tyString:
  1216. case a.kind
  1217. of tyString:
  1218. if tfNotNil in f.flags and tfNotNil notin a.flags:
  1219. result = isNilConversion
  1220. else:
  1221. result = isEqual
  1222. of tyNil: result = allowsNilDeprecated(c, f)
  1223. else: discard
  1224. of tyCString:
  1225. # conversion from string to cstring is automatic:
  1226. case a.kind
  1227. of tyCString:
  1228. if tfNotNil in f.flags and tfNotNil notin a.flags:
  1229. result = isNilConversion
  1230. else:
  1231. result = isEqual
  1232. of tyNil: result = f.allowsNil
  1233. of tyString: result = isConvertible
  1234. of tyPtr:
  1235. # ptr[Tag, char] is not convertible to 'cstring' for now:
  1236. if a.len == 1:
  1237. let pointsTo = a.sons[0].skipTypes(abstractInst)
  1238. if pointsTo.kind == tyChar: result = isConvertible
  1239. elif pointsTo.kind == tyUncheckedArray and pointsTo.sons[0].kind == tyChar:
  1240. result = isConvertible
  1241. elif pointsTo.kind == tyArray and firstOrd(nil, pointsTo.sons[0]) == 0 and
  1242. skipTypes(pointsTo.sons[0], {tyRange}).kind in {tyInt..tyInt64} and
  1243. pointsTo.sons[1].kind == tyChar:
  1244. result = isConvertible
  1245. else: discard
  1246. of tyEmpty, tyVoid:
  1247. if a.kind == f.kind: result = isEqual
  1248. of tyAlias, tySink:
  1249. result = typeRel(c, lastSon(f), a)
  1250. of tyGenericInst:
  1251. var prev = PType(idTableGet(c.bindings, f))
  1252. let origF = f
  1253. var f = if prev == nil: f else: prev
  1254. let roota = a.skipGenericAlias
  1255. let rootf = f.skipGenericAlias
  1256. var m = c
  1257. if a.kind == tyGenericInst:
  1258. if roota.base == rootf.base:
  1259. let nextFlags = flags + {trNoCovariance}
  1260. var hasCovariance = false
  1261. # YYYY
  1262. result = isEqual
  1263. for i in 1 .. rootf.sonsLen-2:
  1264. let ff = rootf.sons[i]
  1265. let aa = roota.sons[i]
  1266. let res = typeRel(c, ff, aa, nextFlags)
  1267. if res != isEqual: result = isGeneric
  1268. if res notin {isEqual, isGeneric}:
  1269. if trNoCovariance notin flags and ff.kind == aa.kind:
  1270. let paramFlags = rootf.base.sons[i-1].flags
  1271. hasCovariance =
  1272. if tfCovariant in paramFlags:
  1273. if tfWeakCovariant in paramFlags:
  1274. isCovariantPtr(c, ff, aa)
  1275. else:
  1276. ff.kind notin {tyRef, tyPtr} and res == isSubtype
  1277. else:
  1278. tfContravariant in paramFlags and
  1279. typeRel(c, aa, ff) == isSubtype
  1280. if hasCovariance:
  1281. continue
  1282. return isNone
  1283. if prev == nil: put(c, f, a)
  1284. else:
  1285. let fKind = rootf.lastSon.kind
  1286. if fKind in {tyAnd, tyOr}:
  1287. result = typeRel(c, lastSon(f), a)
  1288. if result != isNone: put(c, f, a)
  1289. return
  1290. var aAsObject = roota.lastSon
  1291. if fKind in {tyRef, tyPtr}:
  1292. if aAsObject.kind == tyObject:
  1293. # bug #7600, tyObject cannot be passed
  1294. # as argument to tyRef/tyPtr
  1295. return isNone
  1296. elif aAsObject.kind == fKind:
  1297. aAsObject = aAsObject.base
  1298. if aAsObject.kind == tyObject:
  1299. let baseType = aAsObject.base
  1300. if baseType != nil:
  1301. c.inheritancePenalty += 1
  1302. let ret = typeRel(c, f, baseType)
  1303. return if ret == isEqual: isSubtype else: ret
  1304. result = isNone
  1305. else:
  1306. assert lastSon(origF) != nil
  1307. result = typeRel(c, lastSon(origF), a)
  1308. if result != isNone and a.kind != tyNil:
  1309. put(c, f, a)
  1310. of tyGenericBody:
  1311. considerPreviousT:
  1312. if a == f or a.kind == tyGenericInst and a.sons[0] == f:
  1313. bindingRet isGeneric
  1314. let ff = lastSon(f)
  1315. if ff != nil:
  1316. result = typeRel(c, ff, a)
  1317. of tyGenericInvocation:
  1318. var x = a.skipGenericAlias
  1319. # XXX: This is very hacky. It should be moved back into liftTypeParam
  1320. if x.kind in {tyGenericInst, tyArray} and
  1321. c.calleeSym != nil and
  1322. c.calleeSym.kind in {skProc, skFunc} and c.call != nil:
  1323. let inst = prepareMetatypeForSigmatch(c.c, c.bindings, c.call.info, f)
  1324. #echo "inferred ", typeToString(inst), " for ", f
  1325. return typeRel(c, inst, a)
  1326. var depth = 0
  1327. if x.kind == tyGenericInvocation or f.sons[0].kind != tyGenericBody:
  1328. #InternalError("typeRel: tyGenericInvocation -> tyGenericInvocation")
  1329. # simply no match for now:
  1330. discard
  1331. elif x.kind == tyGenericInst and f.sons[0] == x.sons[0] and
  1332. sonsLen(x) - 1 == sonsLen(f):
  1333. for i in 1 ..< sonsLen(f):
  1334. if x.sons[i].kind == tyGenericParam:
  1335. internalError(c.c.graph.config, "wrong instantiated type!")
  1336. elif typeRel(c, f.sons[i], x.sons[i]) <= isSubtype:
  1337. # Workaround for regression #4589
  1338. if f.sons[i].kind != tyTypeDesc: return
  1339. result = isGeneric
  1340. elif x.kind == tyGenericInst and isGenericSubType(c, x, f, depth, f) and
  1341. (sonsLen(x) - 1 == sonsLen(f)):
  1342. # do not recurse here in order to not K bind twice for this code:
  1343. #
  1344. # type
  1345. # BaseFruit[T] = object of RootObj
  1346. # Banana[T] = object of BaseFruit[uint32] # Concrete type here, not T!
  1347. # proc setColor[K](self: var BaseFruit[K])
  1348. # var x: Banana[float64]
  1349. # x.setColor()
  1350. c.inheritancePenalty += depth
  1351. result = isGeneric
  1352. else:
  1353. let genericBody = f.sons[0]
  1354. var askip = skippedNone
  1355. var fskip = skippedNone
  1356. let aobj = x.skipToObject(askip)
  1357. let fobj = genericBody.lastSon.skipToObject(fskip)
  1358. var depth = -1
  1359. if fobj != nil and aobj != nil and askip == fskip:
  1360. depth = isObjectSubtype(c, aobj, fobj, f)
  1361. result = typeRel(c, genericBody, x)
  1362. if result != isNone:
  1363. # see tests/generics/tgeneric3.nim for an example that triggers this
  1364. # piece of code:
  1365. #
  1366. # proc internalFind[T,D](n: PNode[T,D], key: T): ref TItem[T,D]
  1367. # proc internalPut[T,D](ANode: ref TNode[T,D], Akey: T, Avalue: D,
  1368. # Oldvalue: var D): ref TNode[T,D]
  1369. # var root = internalPut[int, int](nil, 312, 312, oldvalue)
  1370. # var it1 = internalFind(root, 312) # cannot instantiate: 'D'
  1371. #
  1372. # we steal the generic parameters from the tyGenericBody:
  1373. for i in 1 ..< sonsLen(f):
  1374. let x = PType(idTableGet(c.bindings, genericBody.sons[i-1]))
  1375. if x == nil:
  1376. discard "maybe fine (for eg. a==tyNil)"
  1377. elif x.kind in {tyGenericInvocation, tyGenericParam}:
  1378. internalError(c.c.graph.config, "wrong instantiated type!")
  1379. else:
  1380. let key = f.sons[i]
  1381. let old = PType(idTableGet(c.bindings, key))
  1382. if old == nil:
  1383. put(c, key, x)
  1384. elif typeRel(c, old, x, flags + {trDontBind}) == isNone:
  1385. return isNone
  1386. if result == isNone:
  1387. # Here object inheriting from generic/specialized generic object
  1388. # crossing path with metatypes/aliases, so we need to separate them
  1389. # by checking sym.id
  1390. let genericSubtype = isGenericSubType(c, x, f, depth, f)
  1391. if not (genericSubtype and aobj.sym.id != fobj.sym.id) and aOrig.kind != tyGenericBody:
  1392. depth = -1
  1393. if depth >= 0:
  1394. c.inheritancePenalty += depth
  1395. # bug #4863: We still need to bind generic alias crap, so
  1396. # we cannot return immediately:
  1397. result = if depth == 0: isGeneric else: isSubtype
  1398. of tyAnd:
  1399. considerPreviousT:
  1400. result = isEqual
  1401. for branch in f.sons:
  1402. let x = typeRel(c, branch, aOrig)
  1403. if x < isSubtype: return isNone
  1404. # 'and' implies minimum matching result:
  1405. if x < result: result = x
  1406. if result > isGeneric: result = isGeneric
  1407. bindingRet result
  1408. of tyOr:
  1409. considerPreviousT:
  1410. result = isNone
  1411. let oldInheritancePenalty = c.inheritancePenalty
  1412. var maxInheritance = 0
  1413. for branch in f.sons:
  1414. c.inheritancePenalty = 0
  1415. let x = typeRel(c, branch, aOrig)
  1416. maxInheritance = max(maxInheritance, c.inheritancePenalty)
  1417. # 'or' implies maximum matching result:
  1418. if x > result: result = x
  1419. if result >= isSubtype:
  1420. if result > isGeneric: result = isGeneric
  1421. bindingRet result
  1422. else:
  1423. result = isNone
  1424. c.inheritancePenalty = oldInheritancePenalty + maxInheritance
  1425. of tyNot:
  1426. considerPreviousT:
  1427. for branch in f.sons:
  1428. if typeRel(c, branch, aOrig) != isNone:
  1429. return isNone
  1430. bindingRet isGeneric
  1431. of tyAnything:
  1432. considerPreviousT:
  1433. var concrete = concreteType(c, a)
  1434. if concrete != nil and doBind:
  1435. put(c, f, concrete)
  1436. return isGeneric
  1437. of tyBuiltInTypeClass:
  1438. considerPreviousT:
  1439. let targetKind = f.sons[0].kind
  1440. let effectiveArgType = a.skipTypes({tyRange, tyGenericInst,
  1441. tyBuiltInTypeClass, tyAlias, tySink, tyOwned})
  1442. let typeClassMatches = targetKind == effectiveArgType.kind and
  1443. not effectiveArgType.isEmptyContainer
  1444. if typeClassMatches or
  1445. (targetKind in {tyProc, tyPointer} and effectiveArgType.kind == tyNil):
  1446. put(c, f, a)
  1447. return isGeneric
  1448. else:
  1449. return isNone
  1450. of tyUserTypeClassInst, tyUserTypeClass:
  1451. if f.isResolvedUserTypeClass:
  1452. result = typeRel(c, f.lastSon, a)
  1453. else:
  1454. considerPreviousT:
  1455. if aOrig == f: return isEqual
  1456. var matched = matchUserTypeClass(c, f, aOrig)
  1457. if matched != nil:
  1458. bindConcreteTypeToUserTypeClass(matched, a)
  1459. if doBind: put(c, f, matched)
  1460. result = isGeneric
  1461. else:
  1462. result = isNone
  1463. of tyCompositeTypeClass:
  1464. considerPreviousT:
  1465. let roota = a.skipGenericAlias
  1466. let rootf = f.lastSon.skipGenericAlias
  1467. if a.kind == tyGenericInst and roota.base == rootf.base:
  1468. for i in 1 .. rootf.sonsLen-2:
  1469. let ff = rootf.sons[i]
  1470. let aa = roota.sons[i]
  1471. result = typeRel(c, ff, aa)
  1472. if result == isNone: return
  1473. if ff.kind == tyRange and result != isEqual: return isNone
  1474. else:
  1475. result = typeRel(c, rootf.lastSon, a)
  1476. if result != isNone:
  1477. put(c, f, a)
  1478. result = isGeneric
  1479. of tyGenericParam:
  1480. var x = PType(idTableGet(c.bindings, f))
  1481. if x == nil:
  1482. if c.callee.kind == tyGenericBody and
  1483. f.kind == tyGenericParam and not c.typedescMatched:
  1484. # XXX: The fact that generic types currently use tyGenericParam for
  1485. # their parameters is really a misnomer. tyGenericParam means "match
  1486. # any value" and what we need is "match any type", which can be encoded
  1487. # by a tyTypeDesc params. Unfortunately, this requires more substantial
  1488. # changes in semtypinst and elsewhere.
  1489. if tfWildcard in a.flags:
  1490. result = isGeneric
  1491. elif a.kind == tyTypeDesc:
  1492. if f.sonsLen == 0:
  1493. result = isGeneric
  1494. else:
  1495. internalAssert c.c.graph.config, a.len > 0
  1496. c.typedescMatched = true
  1497. var aa = a
  1498. while aa.kind in {tyTypeDesc, tyGenericParam} and aa.len > 0:
  1499. aa = lastSon(aa)
  1500. if aa.kind == tyGenericParam:
  1501. return isGeneric
  1502. result = typeRel(c, f.base, aa)
  1503. if result > isGeneric: result = isGeneric
  1504. elif c.isNoCall:
  1505. if doBind:
  1506. let concrete = concreteType(c, a, f)
  1507. if concrete == nil: return isNone
  1508. put(c, f, concrete)
  1509. result = isGeneric
  1510. else:
  1511. result = isNone
  1512. else:
  1513. # check if 'T' has a constraint as in 'proc p[T: Constraint](x: T)'
  1514. if f.sonsLen > 0 and f.sons[0].kind != tyNone:
  1515. let oldInheritancePenalty = c.inheritancePenalty
  1516. result = typeRel(c, f.sons[0], a, flags + {trDontBind})
  1517. if doBind and result notin {isNone, isGeneric}:
  1518. let concrete = concreteType(c, a, f)
  1519. if concrete == nil: return isNone
  1520. put(c, f, concrete)
  1521. # bug #6526
  1522. if result in {isEqual, isSubtype}:
  1523. # 'T: Class' is a *better* match than just 'T'
  1524. # but 'T: Subclass' is even better:
  1525. c.inheritancePenalty = oldInheritancePenalty - c.inheritancePenalty -
  1526. 100 * ord(result == isEqual)
  1527. result = isGeneric
  1528. else:
  1529. result = isGeneric
  1530. if result == isGeneric:
  1531. var concrete = a
  1532. if tfWildcard in a.flags:
  1533. a.sym.kind = skType
  1534. a.flags.excl tfWildcard
  1535. else:
  1536. concrete = concreteType(c, a, f)
  1537. if concrete == nil:
  1538. return isNone
  1539. if doBind:
  1540. put(c, f, concrete)
  1541. elif result > isGeneric:
  1542. result = isGeneric
  1543. elif a.kind == tyEmpty:
  1544. result = isGeneric
  1545. elif x.kind == tyGenericParam:
  1546. result = isGeneric
  1547. else:
  1548. result = typeRel(c, x, a) # check if it fits
  1549. if result > isGeneric: result = isGeneric
  1550. of tyStatic:
  1551. let prev = PType(idTableGet(c.bindings, f))
  1552. if prev == nil:
  1553. if aOrig.kind == tyStatic:
  1554. if f.base.kind != tyNone:
  1555. result = typeRel(c, f.base, a)
  1556. if result != isNone and f.n != nil:
  1557. if not exprStructuralEquivalent(f.n, aOrig.n):
  1558. result = isNone
  1559. else:
  1560. result = isGeneric
  1561. if result != isNone: put(c, f, aOrig)
  1562. elif aOrig.n != nil and aOrig.n.typ != nil:
  1563. result = if f.base.kind != tyNone: typeRel(c, f.lastSon, aOrig.n.typ)
  1564. else: isGeneric
  1565. if result != isNone:
  1566. var boundType = newTypeWithSons(c.c, tyStatic, @[aOrig.n.typ])
  1567. boundType.n = aOrig.n
  1568. put(c, f, boundType)
  1569. else:
  1570. result = isNone
  1571. elif prev.kind == tyStatic:
  1572. if aOrig.kind == tyStatic:
  1573. result = typeRel(c, prev.lastSon, a)
  1574. if result != isNone and prev.n != nil:
  1575. if not exprStructuralEquivalent(prev.n, aOrig.n):
  1576. result = isNone
  1577. else: result = isNone
  1578. else:
  1579. # XXX endless recursion?
  1580. #result = typeRel(c, prev, aOrig)
  1581. result = isNone
  1582. of tyInferred:
  1583. let prev = f.previouslyInferred
  1584. if prev != nil:
  1585. result = typeRel(c, prev, a)
  1586. else:
  1587. result = typeRel(c, f.base, a)
  1588. if result != isNone:
  1589. c.inferredTypes.add f
  1590. f.sons.add a
  1591. of tyTypeDesc:
  1592. var prev = PType(idTableGet(c.bindings, f))
  1593. if prev == nil:
  1594. # proc foo(T: typedesc, x: T)
  1595. # when `f` is an unresolved typedesc, `a` could be any
  1596. # type, so we should not perform this check earlier
  1597. if a.kind != tyTypeDesc:
  1598. if a.kind == tyGenericParam and tfWildcard in a.flags:
  1599. # TODO: prevent `a` from matching as a wildcard again
  1600. result = isGeneric
  1601. else:
  1602. result = isNone
  1603. elif f.base.kind == tyNone:
  1604. result = isGeneric
  1605. else:
  1606. result = typeRel(c, f.base, a.base)
  1607. if result != isNone:
  1608. put(c, f, a)
  1609. else:
  1610. if tfUnresolved in f.flags:
  1611. result = typeRel(c, prev.base, a)
  1612. elif a.kind == tyTypeDesc:
  1613. result = typeRel(c, prev.base, a.base)
  1614. else:
  1615. result = isNone
  1616. of tyTyped:
  1617. if aOrig != nil:
  1618. put(c, f, aOrig)
  1619. result = isGeneric
  1620. of tyProxy:
  1621. result = isEqual
  1622. of tyFromExpr:
  1623. # fix the expression, so it contains the already instantiated types
  1624. if f.n == nil or f.n.kind == nkEmpty: return isGeneric
  1625. let reevaluated = tryResolvingStaticExpr(c, f.n)
  1626. case reevaluated.typ.kind
  1627. of tyTypeDesc:
  1628. result = typeRel(c, a, reevaluated.typ.base)
  1629. of tyStatic:
  1630. result = typeRel(c, a, reevaluated.typ.base)
  1631. if result != isNone and reevaluated.typ.n != nil:
  1632. if not exprStructuralEquivalent(aOrig.n, reevaluated.typ.n):
  1633. result = isNone
  1634. else:
  1635. localError(c.c.graph.config, f.n.info, "type expected")
  1636. result = isNone
  1637. of tyNone:
  1638. if a.kind == tyNone: result = isEqual
  1639. else:
  1640. internalError c.c.graph.config, " unknown type kind " & $f.kind
  1641. when false:
  1642. var nowDebug = false
  1643. var dbgCount = 0
  1644. proc typeRel(c: var TCandidate, f, aOrig: PType,
  1645. flags: TTypeRelFlags = {}): TTypeRelation =
  1646. if nowDebug:
  1647. echo f, " <- ", aOrig
  1648. inc dbgCount
  1649. if dbgCount == 2:
  1650. writeStackTrace()
  1651. result = typeRelImpl(c, f, aOrig, flags)
  1652. if nowDebug:
  1653. echo f, " <- ", aOrig, " res ", result
  1654. template setQuality(q) =
  1655. if q < m.matchQual: m.matchQual = q
  1656. proc cmpTypes*(c: PContext, f, a: PType): TTypeRelation =
  1657. var m: TCandidate
  1658. initCandidate(c, m, f)
  1659. result = typeRel(m, f, a)
  1660. proc getInstantiatedType(c: PContext, arg: PNode, m: TCandidate,
  1661. f: PType): PType =
  1662. result = PType(idTableGet(m.bindings, f))
  1663. if result == nil:
  1664. result = generateTypeInstance(c, m.bindings, arg, f)
  1665. if result == nil:
  1666. internalError(c.graph.config, arg.info, "getInstantiatedType")
  1667. result = errorType(c)
  1668. proc implicitConv(kind: TNodeKind, f: PType, arg: PNode, m: TCandidate,
  1669. c: PContext): PNode =
  1670. result = newNodeI(kind, arg.info)
  1671. if containsGenericType(f):
  1672. if not m.hasFauxMatch:
  1673. result.typ = getInstantiatedType(c, arg, m, f)
  1674. else:
  1675. result.typ = errorType(c)
  1676. else:
  1677. result.typ = f
  1678. if result.typ == nil: internalError(c.graph.config, arg.info, "implicitConv")
  1679. addSon(result, c.graph.emptyNode)
  1680. addSon(result, arg)
  1681. proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
  1682. arg: PNode): PNode =
  1683. result = nil
  1684. for i in 0 ..< len(c.converters):
  1685. var src = c.converters[i].typ.sons[1]
  1686. var dest = c.converters[i].typ.sons[0]
  1687. # for generic type converters we need to check 'src <- a' before
  1688. # 'f <- dest' in order to not break the unification:
  1689. # see tests/tgenericconverter:
  1690. let srca = typeRel(m, src, a)
  1691. if srca notin {isEqual, isGeneric, isSubtype}: continue
  1692. # What's done below matches the logic in ``matchesAux``
  1693. let constraint = c.converters[i].typ.n[1].sym.constraint
  1694. if not constraint.isNil and not matchNodeKinds(constraint, arg):
  1695. continue
  1696. if src.kind in {tyVar, tyLent} and not arg.isLValue:
  1697. continue
  1698. let destIsGeneric = containsGenericType(dest)
  1699. if destIsGeneric:
  1700. dest = generateTypeInstance(c, m.bindings, arg, dest)
  1701. let fdest = typeRel(m, f, dest)
  1702. if fdest in {isEqual, isGeneric} and not (dest.kind == tyLent and f.kind == tyVar):
  1703. markUsed(c.config, arg.info, c.converters[i], c.graph.usageSym)
  1704. var s = newSymNode(c.converters[i])
  1705. s.typ = c.converters[i].typ
  1706. s.info = arg.info
  1707. result = newNodeIT(nkHiddenCallConv, arg.info, dest)
  1708. addSon(result, s)
  1709. # We build the call expression by ourselves in order to avoid passing this
  1710. # expression trough the semantic check phase once again so let's make sure
  1711. # it is correct
  1712. var param: PNode = nil
  1713. if srca == isSubtype:
  1714. param = implicitConv(nkHiddenSubConv, src, copyTree(arg), m, c)
  1715. elif src.kind == tyVar:
  1716. # Analyse the converter return type
  1717. param = newNodeIT(nkHiddenAddr, arg.info, s.typ[1])
  1718. param.addSon(copyTree(arg))
  1719. else:
  1720. param = copyTree(arg)
  1721. addSon(result, param)
  1722. if dest.kind in {tyVar, tyLent}:
  1723. dest.flags.incl tfVarIsPtr
  1724. result = newDeref(result)
  1725. setQuality(convMatch)
  1726. if not m.genericConverter:
  1727. m.genericConverter = srca == isGeneric or destIsGeneric
  1728. return result
  1729. proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType,
  1730. arg: PNode): PNode =
  1731. # arg.typ can be nil in 'suggest':
  1732. if isNil(arg.typ): return nil
  1733. # sem'checking for 'echo' needs to be re-entrant:
  1734. # XXX we will revisit this issue after 0.10.2 is released
  1735. if f == arg.typ and arg.kind == nkHiddenStdConv: return arg
  1736. var call = newNodeI(nkCall, arg.info)
  1737. call.add(f.n.copyTree)
  1738. call.add(arg.copyTree)
  1739. result = c.semExpr(c, call)
  1740. if result != nil:
  1741. if result.typ == nil: return nil
  1742. # resulting type must be consistent with the other arguments:
  1743. var r = typeRel(m, f.sons[0], result.typ)
  1744. if r < isGeneric: return nil
  1745. if result.kind == nkCall: result.kind = nkHiddenCallConv
  1746. setQuality(convMatch)
  1747. if r == isGeneric:
  1748. result.typ = getInstantiatedType(c, arg, m, base(f))
  1749. m.baseTypeMatch = true
  1750. proc incMatches(m: var TCandidate; r: TTypeRelation) =
  1751. let q =
  1752. case r
  1753. of isConvertible, isIntConv, isInferredConvertible:
  1754. convMatch
  1755. of isSubtype, isSubrange:
  1756. subtypeMatch
  1757. of isGeneric, isInferred, isBothMetaConvertible:
  1758. genericMatch
  1759. of isFromIntLit:
  1760. subtypeMatch
  1761. of isEqual:
  1762. exactMatch
  1763. of isNone:
  1764. noMatch
  1765. setQuality(q)
  1766. template matchesVoidProc(t: PType): bool =
  1767. (t.kind == tyProc and t.len == 1 and t.sons[0] == nil) or
  1768. (t.kind == tyBuiltInTypeClass and t.sons[0].kind == tyProc)
  1769. proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
  1770. argSemantized, argOrig: PNode): PNode =
  1771. var
  1772. fMaybeStatic = f.skipTypes({tyDistinct})
  1773. arg = argSemantized
  1774. a = a
  1775. c = m.c
  1776. if tfHasStatic in fMaybeStatic.flags:
  1777. # XXX: When implicit statics are the default
  1778. # this will be done earlier - we just have to
  1779. # make sure that static types enter here
  1780. # Zahary: weaken tyGenericParam and call it tyGenericPlaceholder
  1781. # and finally start using tyTypedesc for generic types properly.
  1782. # Araq: This would only shift the problems around, in 'proc p[T](x: T)'
  1783. # the T is NOT a typedesc.
  1784. if a.kind == tyGenericParam and tfWildcard in a.flags:
  1785. a.assignType(f)
  1786. # put(m.bindings, f, a)
  1787. return argSemantized
  1788. if a.kind == tyStatic:
  1789. if m.callee.kind == tyGenericBody and
  1790. a.n == nil and
  1791. tfGenericTypeParam notin a.flags:
  1792. return newNodeIT(nkType, argOrig.info, makeTypeFromExpr(c, arg))
  1793. else:
  1794. var evaluated = c.semTryConstExpr(c, arg)
  1795. if evaluated != nil:
  1796. # Don't build the type in-place because `evaluated` and `arg` may point
  1797. # to the same object and we'd end up creating recursive types (#9255)
  1798. let typ = newTypeS(tyStatic, c)
  1799. typ.sons = @[evaluated.typ]
  1800. typ.n = evaluated
  1801. arg.typ = typ
  1802. a = typ
  1803. else:
  1804. if m.callee.kind == tyGenericBody:
  1805. if f.kind == tyStatic and typeRel(m, f.base, a) != isNone:
  1806. result = makeStaticExpr(m.c, arg)
  1807. result.typ.flags.incl tfUnresolved
  1808. result.typ.n = arg
  1809. return
  1810. let oldInheritancePenalty = m.inheritancePenalty
  1811. var r = typeRel(m, f, a)
  1812. # This special typing rule for macros and templates is not documented
  1813. # anywhere and breaks symmetry. It's hard to get rid of though, my
  1814. # custom seqs example fails to compile without this:
  1815. if r != isNone and m.calleeSym != nil and
  1816. m.calleeSym.kind in {skMacro, skTemplate}:
  1817. # XXX: duplicating this is ugly, but we cannot (!) move this
  1818. # directly into typeRel using return-like templates
  1819. incMatches(m, r)
  1820. if f.kind == tyTyped:
  1821. return arg
  1822. elif f.kind == tyTypeDesc:
  1823. return arg
  1824. elif f.kind == tyStatic and arg.typ.n != nil:
  1825. return arg.typ.n
  1826. else:
  1827. return argSemantized # argOrig
  1828. # If r == isBothMetaConvertible then we rerun typeRel.
  1829. # bothMetaCounter is for safety to avoid any infinite loop,
  1830. # I don't have any example when it is needed.
  1831. # lastBindingsLenth is used to check whether m.bindings remains the same,
  1832. # because in that case there is no point in continuing.
  1833. var bothMetaCounter = 0
  1834. var lastBindingsLength = -1
  1835. while r == isBothMetaConvertible and
  1836. lastBindingsLength != m.bindings.counter and
  1837. bothMetaCounter < 100:
  1838. lastBindingsLength = m.bindings.counter
  1839. inc(bothMetaCounter)
  1840. if arg.kind in {nkProcDef, nkFuncDef, nkIteratorDef} + nkLambdaKinds:
  1841. result = c.semInferredLambda(c, m.bindings, arg)
  1842. elif arg.kind != nkSym:
  1843. return nil
  1844. else:
  1845. let inferred = c.semGenerateInstance(c, arg.sym, m.bindings, arg.info)
  1846. result = newSymNode(inferred, arg.info)
  1847. setQuality(convMatch)
  1848. arg = result
  1849. r = typeRel(m, f, arg.typ)
  1850. case r
  1851. of isConvertible:
  1852. setQuality(convMatch)
  1853. result = implicitConv(nkHiddenStdConv, f, arg, m, c)
  1854. of isIntConv:
  1855. # I'm too lazy to introduce another ``*matches`` field, so we conflate
  1856. # ``isIntConv`` and ``isIntLit`` here:
  1857. setQuality(intConvMatch)
  1858. result = implicitConv(nkHiddenStdConv, f, arg, m, c)
  1859. of isSubtype:
  1860. setQuality(subtypeMatch)
  1861. if f.kind == tyTypeDesc:
  1862. result = arg
  1863. else:
  1864. result = implicitConv(nkHiddenSubConv, f, arg, m, c)
  1865. of isSubrange:
  1866. setQuality(subtypeMatch)
  1867. if f.kind == tyVar:
  1868. result = arg
  1869. else:
  1870. result = implicitConv(nkHiddenStdConv, f, arg, m, c)
  1871. of isInferred, isInferredConvertible:
  1872. if arg.kind in {nkProcDef, nkFuncDef, nkIteratorDef} + nkLambdaKinds:
  1873. result = c.semInferredLambda(c, m.bindings, arg)
  1874. elif arg.kind != nkSym:
  1875. return nil
  1876. else:
  1877. let inferred = c.semGenerateInstance(c, arg.sym, m.bindings, arg.info)
  1878. result = newSymNode(inferred, arg.info)
  1879. if r == isInferredConvertible:
  1880. setQuality(convMatch)
  1881. result = implicitConv(nkHiddenStdConv, f, result, m, c)
  1882. else:
  1883. setQuality(genericMatch)
  1884. of isGeneric:
  1885. setQuality(genericMatch)
  1886. if arg.typ == nil:
  1887. result = arg
  1888. elif skipTypes(arg.typ, abstractVar-{tyTypeDesc}).kind == tyTuple or
  1889. m.inheritancePenalty > oldInheritancePenalty:
  1890. result = implicitConv(nkHiddenSubConv, f, arg, m, c)
  1891. elif arg.typ.isEmptyContainer:
  1892. result = arg.copyTree
  1893. result.typ = getInstantiatedType(c, arg, m, f)
  1894. else:
  1895. result = arg
  1896. of isBothMetaConvertible:
  1897. # This is the result for the 101th time.
  1898. result = nil
  1899. of isFromIntLit:
  1900. # too lazy to introduce another ``*matches`` field, so we conflate
  1901. # ``isIntConv`` and ``isIntLit`` here:
  1902. setQuality(subtypeMatch)
  1903. result = implicitConv(nkHiddenStdConv, f, arg, m, c)
  1904. of isEqual:
  1905. setQuality(exactMatch)
  1906. result = arg
  1907. if skipTypes(f, abstractVar-{tyTypeDesc}).kind == tyTuple or
  1908. (arg.typ != nil and skipTypes(arg.typ, abstractVar-{tyTypeDesc}).kind == tyTuple):
  1909. result = implicitConv(nkHiddenSubConv, f, arg, m, c)
  1910. of isNone:
  1911. # do not do this in ``typeRel`` as it then can't infer T in ``ref T``:
  1912. if a.kind in {tyProxy, tyUnknown}:
  1913. setQuality(genericMatch)
  1914. m.fauxMatch = a.kind
  1915. return arg
  1916. elif a.kind == tyVoid and f.matchesVoidProc and argOrig.kind == nkStmtList:
  1917. # lift do blocks without params to lambdas
  1918. let p = c.graph
  1919. let lifted = c.semExpr(c, newProcNode(nkDo, argOrig.info, body = argOrig,
  1920. params = p.emptyNode, name = p.emptyNode, pattern = p.emptyNode,
  1921. genericParams = p.emptyNode, pragmas = p.emptyNode, exceptions = p.emptyNode), {})
  1922. if f.kind == tyBuiltInTypeClass:
  1923. put(m, f, lifted.typ)
  1924. setQuality(convMatch)
  1925. return implicitConv(nkHiddenStdConv, f, lifted, m, c)
  1926. result = userConvMatch(c, m, f, a, arg)
  1927. # check for a base type match, which supports varargs[T] without []
  1928. # constructor in a call:
  1929. if result == nil and f.kind == tyVarargs:
  1930. if f.n != nil:
  1931. # Forward to the varargs converter
  1932. result = localConvMatch(c, m, f, a, arg)
  1933. else:
  1934. r = typeRel(m, base(f), a)
  1935. case r
  1936. of isGeneric:
  1937. setQuality(convMatch)
  1938. result = copyTree(arg)
  1939. result.typ = getInstantiatedType(c, arg, m, base(f))
  1940. m.baseTypeMatch = true
  1941. of isFromIntLit:
  1942. setQuality(subtypeMatch)
  1943. result = implicitConv(nkHiddenStdConv, f[0], arg, m, c)
  1944. m.baseTypeMatch = true
  1945. of isEqual:
  1946. setQuality(convMatch)
  1947. result = copyTree(arg)
  1948. m.baseTypeMatch = true
  1949. of isSubtype: # bug #4799, varargs accepting subtype relation object
  1950. setQuality(subtypeMatch)
  1951. if base(f).kind == tyTypeDesc:
  1952. result = arg
  1953. else:
  1954. result = implicitConv(nkHiddenSubConv, base(f), arg, m, c)
  1955. m.baseTypeMatch = true
  1956. else:
  1957. result = userConvMatch(c, m, base(f), a, arg)
  1958. if result != nil: m.baseTypeMatch = true
  1959. proc paramTypesMatch*(m: var TCandidate, f, a: PType,
  1960. arg, argOrig: PNode): PNode =
  1961. if arg == nil or arg.kind notin nkSymChoices:
  1962. result = paramTypesMatchAux(m, f, a, arg, argOrig)
  1963. else:
  1964. # CAUTION: The order depends on the used hashing scheme. Thus it is
  1965. # incorrect to simply use the first fitting match. However, to implement
  1966. # this correctly is inefficient. We have to copy `m` here to be able to
  1967. # roll back the side effects of the unification algorithm.
  1968. let c = m.c
  1969. var x, y, z: TCandidate
  1970. initCandidate(c, x, m.callee)
  1971. initCandidate(c, y, m.callee)
  1972. initCandidate(c, z, m.callee)
  1973. x.calleeSym = m.calleeSym
  1974. y.calleeSym = m.calleeSym
  1975. z.calleeSym = m.calleeSym
  1976. var best = -1
  1977. for i in 0 ..< arg.len:
  1978. if arg.sons[i].sym.kind in {skProc, skFunc, skMethod, skConverter,
  1979. skIterator, skMacro, skTemplate}:
  1980. copyCandidate(z, m)
  1981. z.callee = arg.sons[i].typ
  1982. if tfUnresolved in z.callee.flags: continue
  1983. z.calleeSym = arg.sons[i].sym
  1984. #if arg.sons[i].sym.name.s == "cmp":
  1985. # ggDebug = true
  1986. # echo "CALLLEEEEEEEE A ", typeToString(z.callee)
  1987. # XXX this is still all wrong: (T, T) should be 2 generic matches
  1988. # and (int, int) 2 exact matches, etc. Essentially you cannot call
  1989. # typeRel here and expect things to work!
  1990. let r = typeRel(z, f, arg.sons[i].typ)
  1991. incMatches(z, r)
  1992. #if arg.sons[i].sym.name.s == "cmp": # and arg.info.line == 606:
  1993. # echo "M ", r, " ", arg.info, " ", typeToString(arg.sons[i].sym.typ)
  1994. # writeMatches(z)
  1995. if r != isNone:
  1996. z.state = csMatch
  1997. case x.state
  1998. of csEmpty, csNoMatch:
  1999. x = z
  2000. best = i
  2001. of csMatch:
  2002. let cmp = cmpCandidates(x, z)
  2003. if cmp < 0:
  2004. best = i
  2005. x = z
  2006. elif cmp == 0:
  2007. y = z # z is as good as x
  2008. if x.state == csEmpty:
  2009. result = nil
  2010. elif y.state == csMatch and cmpCandidates(x, y) == 0:
  2011. if x.state != csMatch:
  2012. internalError(m.c.graph.config, arg.info, "x.state is not csMatch")
  2013. # ambiguous: more than one symbol fits!
  2014. # See tsymchoice_for_expr as an example. 'f.kind == tyUntyped' should match
  2015. # anyway:
  2016. if f.kind in {tyUntyped, tyTyped}: result = arg
  2017. else: result = nil
  2018. else:
  2019. # only one valid interpretation found:
  2020. markUsed(m.c.config, arg.info, arg.sons[best].sym, m.c.graph.usageSym)
  2021. onUse(arg.info, arg.sons[best].sym)
  2022. result = paramTypesMatchAux(m, f, arg.sons[best].typ, arg.sons[best],
  2023. argOrig)
  2024. when false:
  2025. if m.calleeSym != nil and m.calleeSym.name.s == "[]":
  2026. echo m.c.config $ arg.info, " for ", m.calleeSym.name.s, " ", m.c.config $ m.calleeSym.info
  2027. writeMatches(m)
  2028. proc setSon(father: PNode, at: int, son: PNode) =
  2029. let oldLen = father.len
  2030. if oldLen <= at:
  2031. setLen(father.sons, at + 1)
  2032. father.sons[at] = son
  2033. # insert potential 'void' parameters:
  2034. #for i in oldLen ..< at:
  2035. # father.sons[i] = newNodeIT(nkEmpty, son.info, getSysType(tyVoid))
  2036. # we are allowed to modify the calling node in the 'prepare*' procs:
  2037. proc prepareOperand(c: PContext; formal: PType; a: PNode): PNode =
  2038. if formal.kind == tyUntyped and formal.len != 1:
  2039. # {tyTypeDesc, tyUntyped, tyTyped, tyProxy}:
  2040. # a.typ == nil is valid
  2041. result = a
  2042. elif a.typ.isNil:
  2043. # XXX This is unsound! 'formal' can differ from overloaded routine to
  2044. # overloaded routine!
  2045. let flags = {efDetermineType, efAllowStmt}
  2046. #if formal.kind == tyIter: {efDetermineType, efWantIterator}
  2047. #else: {efDetermineType, efAllowStmt}
  2048. #elif formal.kind == tyTyped: {efDetermineType, efWantStmt}
  2049. #else: {efDetermineType}
  2050. result = c.semOperand(c, a, flags)
  2051. else:
  2052. result = a
  2053. considerGenSyms(c, result)
  2054. proc prepareOperand(c: PContext; a: PNode): PNode =
  2055. if a.typ.isNil:
  2056. result = c.semOperand(c, a, {efDetermineType})
  2057. else:
  2058. result = a
  2059. considerGenSyms(c, result)
  2060. proc prepareNamedParam(a: PNode; c: PContext) =
  2061. if a.sons[0].kind != nkIdent:
  2062. var info = a.sons[0].info
  2063. a.sons[0] = newIdentNode(considerQuotedIdent(c, a.sons[0]), info)
  2064. proc arrayConstr(c: PContext, n: PNode): PType =
  2065. result = newTypeS(tyArray, c)
  2066. rawAddSon(result, makeRangeType(c, 0, 0, n.info))
  2067. addSonSkipIntLit(result, skipTypes(n.typ,
  2068. {tyGenericInst, tyVar, tyLent, tyOrdinal}))
  2069. proc arrayConstr(c: PContext, info: TLineInfo): PType =
  2070. result = newTypeS(tyArray, c)
  2071. rawAddSon(result, makeRangeType(c, 0, -1, info))
  2072. rawAddSon(result, newTypeS(tyEmpty, c)) # needs an empty basetype!
  2073. proc incrIndexType(t: PType) =
  2074. assert t.kind == tyArray
  2075. inc t.sons[0].n.sons[1].intVal
  2076. template isVarargsUntyped(x): untyped =
  2077. x.kind == tyVarargs and x.sons[0].kind == tyUntyped
  2078. proc matchesAux(c: PContext, n, nOrig: PNode,
  2079. m: var TCandidate, marker: var IntSet) =
  2080. template checkConstraint(n: untyped) {.dirty.} =
  2081. if not formal.constraint.isNil:
  2082. if matchNodeKinds(formal.constraint, n):
  2083. discard "do nothing"
  2084. else:
  2085. m.state = csNoMatch
  2086. return
  2087. if formal.typ.kind == tyVar:
  2088. let argConverter = if arg.kind == nkHiddenDeref: arg[0] else: arg
  2089. if argConverter.kind == nkHiddenCallConv:
  2090. if argConverter.typ.kind != tyVar:
  2091. m.state = csNoMatch
  2092. m.mutabilityProblem = uint8(f-1)
  2093. return
  2094. elif not n.isLValue:
  2095. m.state = csNoMatch
  2096. m.mutabilityProblem = uint8(f-1)
  2097. return
  2098. var
  2099. # iterates over formal parameters
  2100. f = if m.callee.kind != tyGenericBody: 1
  2101. else: 0
  2102. # iterates over the actual given arguments
  2103. a = 1
  2104. arg: PNode # current prepared argument
  2105. m.state = csMatch # until proven otherwise
  2106. m.call = newNodeI(n.kind, n.info)
  2107. m.call.typ = base(m.callee) # may be nil
  2108. var formalLen = m.callee.n.len
  2109. addSon(m.call, copyTree(n.sons[0]))
  2110. var container: PNode = nil # constructed container
  2111. var formal: PSym = if formalLen > 1: m.callee.n.sons[1].sym else: nil
  2112. while a < n.len:
  2113. if a >= formalLen-1 and f < formalLen and m.callee.n[f].typ.isVarargsUntyped:
  2114. formal = m.callee.n.sons[f].sym
  2115. incl(marker, formal.position)
  2116. if n.sons[a].kind == nkHiddenStdConv:
  2117. doAssert n.sons[a].sons[0].kind == nkEmpty and
  2118. n.sons[a].sons[1].kind in {nkBracket, nkArgList}
  2119. # Steal the container and pass it along
  2120. setSon(m.call, formal.position + 1, n.sons[a].sons[1])
  2121. else:
  2122. if container.isNil:
  2123. container = newNodeIT(nkArgList, n.sons[a].info, arrayConstr(c, n.info))
  2124. setSon(m.call, formal.position + 1, container)
  2125. else:
  2126. incrIndexType(container.typ)
  2127. addSon(container, n.sons[a])
  2128. elif n.sons[a].kind == nkExprEqExpr:
  2129. # named param
  2130. # check if m.callee has such a param:
  2131. prepareNamedParam(n.sons[a], c)
  2132. if n.sons[a].sons[0].kind != nkIdent:
  2133. localError(c.config, n.sons[a].info, "named parameter has to be an identifier")
  2134. m.state = csNoMatch
  2135. m.firstMismatch = -a
  2136. return
  2137. formal = getSymFromList(m.callee.n, n.sons[a].sons[0].ident, 1)
  2138. if formal == nil:
  2139. # no error message!
  2140. m.state = csNoMatch
  2141. m.firstMismatch = -a
  2142. return
  2143. if containsOrIncl(marker, formal.position):
  2144. # already in namedParams, so no match
  2145. # we used to produce 'errCannotBindXTwice' here but see
  2146. # bug #3836 of why that is not sound (other overload with
  2147. # different parameter names could match later on):
  2148. when false: localError(n.sons[a].info, errCannotBindXTwice, formal.name.s)
  2149. m.state = csNoMatch
  2150. return
  2151. m.baseTypeMatch = false
  2152. m.typedescMatched = false
  2153. n.sons[a].sons[1] = prepareOperand(c, formal.typ, n.sons[a].sons[1])
  2154. n.sons[a].typ = n.sons[a].sons[1].typ
  2155. arg = paramTypesMatch(m, formal.typ, n.sons[a].typ,
  2156. n.sons[a].sons[1], n.sons[a].sons[1])
  2157. if arg == nil:
  2158. m.state = csNoMatch
  2159. m.firstMismatch = a
  2160. return
  2161. checkConstraint(n.sons[a].sons[1])
  2162. if m.baseTypeMatch:
  2163. #assert(container == nil)
  2164. container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg))
  2165. addSon(container, arg)
  2166. setSon(m.call, formal.position + 1, container)
  2167. if f != formalLen - 1: container = nil
  2168. else:
  2169. setSon(m.call, formal.position + 1, arg)
  2170. inc f
  2171. else:
  2172. # unnamed param
  2173. if f >= formalLen:
  2174. # too many arguments?
  2175. if tfVarargs in m.callee.flags:
  2176. # is ok... but don't increment any counters...
  2177. # we have no formal here to snoop at:
  2178. n.sons[a] = prepareOperand(c, n.sons[a])
  2179. if skipTypes(n.sons[a].typ, abstractVar-{tyTypeDesc}).kind==tyString:
  2180. addSon(m.call, implicitConv(nkHiddenStdConv,
  2181. getSysType(c.graph, n.sons[a].info, tyCString),
  2182. copyTree(n.sons[a]), m, c))
  2183. else:
  2184. addSon(m.call, copyTree(n.sons[a]))
  2185. elif formal != nil and formal.typ.kind == tyVarargs:
  2186. # beware of the side-effects in 'prepareOperand'! So only do it for
  2187. # varargs matching. See tests/metatype/tstatic_overloading.
  2188. m.baseTypeMatch = false
  2189. m.typedescMatched = false
  2190. incl(marker, formal.position)
  2191. n.sons[a] = prepareOperand(c, formal.typ, n.sons[a])
  2192. arg = paramTypesMatch(m, formal.typ, n.sons[a].typ,
  2193. n.sons[a], nOrig.sons[a])
  2194. if arg != nil and m.baseTypeMatch and container != nil:
  2195. addSon(container, arg)
  2196. incrIndexType(container.typ)
  2197. checkConstraint(n.sons[a])
  2198. else:
  2199. m.state = csNoMatch
  2200. return
  2201. else:
  2202. m.state = csNoMatch
  2203. return
  2204. else:
  2205. if m.callee.n.sons[f].kind != nkSym:
  2206. internalError(c.config, n.sons[a].info, "matches")
  2207. return
  2208. formal = m.callee.n.sons[f].sym
  2209. if containsOrIncl(marker, formal.position) and container.isNil:
  2210. # already in namedParams: (see above remark)
  2211. when false: localError(n.sons[a].info, errCannotBindXTwice, formal.name.s)
  2212. m.state = csNoMatch
  2213. return
  2214. if formal.typ.isVarargsUntyped:
  2215. if container.isNil:
  2216. container = newNodeIT(nkArgList, n.sons[a].info, arrayConstr(c, n.info))
  2217. setSon(m.call, formal.position + 1, container)
  2218. else:
  2219. incrIndexType(container.typ)
  2220. addSon(container, n.sons[a])
  2221. else:
  2222. m.baseTypeMatch = false
  2223. m.typedescMatched = false
  2224. n.sons[a] = prepareOperand(c, formal.typ, n.sons[a])
  2225. arg = paramTypesMatch(m, formal.typ, n.sons[a].typ,
  2226. n.sons[a], nOrig.sons[a])
  2227. if arg == nil:
  2228. m.state = csNoMatch
  2229. m.firstMismatch = f
  2230. return
  2231. if m.baseTypeMatch:
  2232. assert formal.typ.kind == tyVarargs
  2233. #assert(container == nil)
  2234. if container.isNil:
  2235. container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg))
  2236. container.typ.flags.incl tfVarargs
  2237. else:
  2238. incrIndexType(container.typ)
  2239. addSon(container, arg)
  2240. setSon(m.call, formal.position + 1,
  2241. implicitConv(nkHiddenStdConv, formal.typ, container, m, c))
  2242. #if f != formalLen - 1: container = nil
  2243. # pick the formal from the end, so that 'x, y, varargs, z' works:
  2244. f = max(f, formalLen - n.len + a + 1)
  2245. elif formal.typ.kind != tyVarargs or container == nil:
  2246. setSon(m.call, formal.position + 1, arg)
  2247. inc(f)
  2248. container = nil
  2249. else:
  2250. # we end up here if the argument can be converted into the varargs
  2251. # formal (eg. seq[T] -> varargs[T]) but we have already instantiated
  2252. # a container
  2253. assert arg.kind == nkHiddenStdConv
  2254. localError(c.config, n.sons[a].info, "cannot convert $1 to $2" % [
  2255. typeToString(n.sons[a].typ), typeToString(formal.typ) ])
  2256. m.state = csNoMatch
  2257. return
  2258. checkConstraint(n.sons[a])
  2259. inc(a)
  2260. proc semFinishOperands*(c: PContext, n: PNode) =
  2261. # this needs to be called to ensure that after overloading resolution every
  2262. # argument has been sem'checked:
  2263. for i in 1 ..< n.len:
  2264. n.sons[i] = prepareOperand(c, n.sons[i])
  2265. proc partialMatch*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
  2266. # for 'suggest' support:
  2267. var marker = initIntSet()
  2268. matchesAux(c, n, nOrig, m, marker)
  2269. proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
  2270. if m.magic in {mArrGet, mArrPut}:
  2271. m.state = csMatch
  2272. m.call = n
  2273. m.matchQual = genericMatch
  2274. # Note the following doesn't work as it would produce ambiguities.
  2275. # Instead we patch system.nim, see bug #8049.
  2276. when false:
  2277. m.matchQual = genericMatch
  2278. return
  2279. var marker = initIntSet()
  2280. matchesAux(c, n, nOrig, m, marker)
  2281. if m.state == csNoMatch: return
  2282. # check that every formal parameter got a value:
  2283. var f = 1
  2284. while f < sonsLen(m.callee.n):
  2285. var formal = m.callee.n.sons[f].sym
  2286. if not containsOrIncl(marker, formal.position):
  2287. if formal.ast == nil:
  2288. if formal.typ.kind == tyVarargs:
  2289. # For consistency with what happens in `matchesAux` select the
  2290. # container node kind accordingly
  2291. let cnKind = if formal.typ.isVarargsUntyped: nkArgList else: nkBracket
  2292. var container = newNodeIT(cnKind, n.info, arrayConstr(c, n.info))
  2293. setSon(m.call, formal.position + 1,
  2294. implicitConv(nkHiddenStdConv, formal.typ, container, m, c))
  2295. else:
  2296. # no default value
  2297. m.state = csNoMatch
  2298. m.firstMismatch = f
  2299. break
  2300. else:
  2301. if formal.ast.kind == nkEmpty:
  2302. # The default param value is set to empty in `instantiateProcType`
  2303. # when the type of the default expression doesn't match the type
  2304. # of the instantiated proc param:
  2305. localError(c.config, m.call.info,
  2306. ("The default parameter '$1' has incompatible type " &
  2307. "with the explicitly requested proc instantiation") %
  2308. formal.name.s)
  2309. if nfDefaultRefsParam in formal.ast.flags:
  2310. m.call.flags.incl nfDefaultRefsParam
  2311. var def = copyTree(formal.ast)
  2312. if def.kind == nkNilLit:
  2313. def = implicitConv(nkHiddenStdConv, formal.typ, def, m, c)
  2314. if {tfImplicitTypeParam, tfGenericTypeParam} * formal.typ.flags != {}:
  2315. put(m, formal.typ, def.typ)
  2316. def.flags.incl nfDefaultParam
  2317. setSon(m.call, formal.position + 1, def)
  2318. inc(f)
  2319. # forget all inferred types if the overload matching failed
  2320. if m.state == csNoMatch:
  2321. for t in m.inferredTypes:
  2322. if t.sonsLen > 1: t.sons.setLen 1
  2323. proc argtypeMatches*(c: PContext, f, a: PType, fromHlo = false): bool =
  2324. var m: TCandidate
  2325. initCandidate(c, m, f)
  2326. let res = paramTypesMatch(m, f, a, c.graph.emptyNode, nil)
  2327. #instantiateGenericConverters(c, res, m)
  2328. # XXX this is used by patterns.nim too; I think it's better to not
  2329. # instantiate generic converters for that
  2330. if not fromHlo:
  2331. res != nil
  2332. else:
  2333. # pattern templates do not allow for conversions except from int literal
  2334. res != nil and m.matchQual >= intConvMatch
  2335. proc instTypeBoundOp*(c: PContext; dc: PSym; t: PType; info: TLineInfo;
  2336. op: TTypeAttachedOp; col: int): PSym {.procvar.} =
  2337. var m: TCandidate
  2338. initCandidate(c, m, dc.typ)
  2339. if col >= dc.typ.len:
  2340. localError(c.config, info, "cannot instantiate: '" & dc.name.s & "'")
  2341. return nil
  2342. var f = dc.typ.sons[col]
  2343. if op == attachedDeepCopy:
  2344. if f.kind in {tyRef, tyPtr}: f = f.lastSon
  2345. else:
  2346. if f.kind == tyVar: f = f.lastSon
  2347. #if c.config.selectedGC == gcDestructors and f.kind == tySequence:
  2348. # use the canonical type to access the =sink and =destroy etc.
  2349. # f = c.graph.sysTypes[tySequence]
  2350. #echo "YUP_---------Formal ", typeToString(f, preferDesc), " real ", typeToString(t, preferDesc), " ", f.id, " ", t.id
  2351. if typeRel(m, f, t) == isNone:
  2352. localError(c.config, info, "cannot instantiate: '" & dc.name.s & "'")
  2353. else:
  2354. result = c.semGenerateInstance(c, dc, m.bindings, info)
  2355. if op == attachedDeepCopy:
  2356. assert sfFromGeneric in result.flags
  2357. include suggest
  2358. when not declared(tests):
  2359. template tests(s: untyped) = discard
  2360. tests:
  2361. var dummyOwner = newSym(skModule, getIdent("test_module"), nil, UnknownLineInfo())
  2362. proc `|` (t1, t2: PType): PType =
  2363. result = newType(tyOr, dummyOwner)
  2364. result.rawAddSon(t1)
  2365. result.rawAddSon(t2)
  2366. proc `&` (t1, t2: PType): PType =
  2367. result = newType(tyAnd, dummyOwner)
  2368. result.rawAddSon(t1)
  2369. result.rawAddSon(t2)
  2370. proc `!` (t: PType): PType =
  2371. result = newType(tyNot, dummyOwner)
  2372. result.rawAddSon(t)
  2373. proc seq(t: PType): PType =
  2374. result = newType(tySequence, dummyOwner)
  2375. result.rawAddSon(t)
  2376. proc array(x: int, t: PType): PType =
  2377. result = newType(tyArray, dummyOwner)
  2378. var n = newNodeI(nkRange, UnknownLineInfo())
  2379. addSon(n, newIntNode(nkIntLit, 0))
  2380. addSon(n, newIntNode(nkIntLit, x))
  2381. let range = newType(tyRange, dummyOwner)
  2382. result.rawAddSon(range)
  2383. result.rawAddSon(t)
  2384. suite "type classes":
  2385. let
  2386. int = newType(tyInt, dummyOwner)
  2387. float = newType(tyFloat, dummyOwner)
  2388. string = newType(tyString, dummyOwner)
  2389. ordinal = newType(tyOrdinal, dummyOwner)
  2390. any = newType(tyAnything, dummyOwner)
  2391. number = int | float
  2392. var TFoo = newType(tyObject, dummyOwner)
  2393. TFoo.sym = newSym(skType, getIdent"TFoo", dummyOwner, UnknownLineInfo())
  2394. var T1 = newType(tyGenericParam, dummyOwner)
  2395. T1.sym = newSym(skType, getIdent"T1", dummyOwner, UnknownLineInfo())
  2396. T1.sym.position = 0
  2397. var T2 = newType(tyGenericParam, dummyOwner)
  2398. T2.sym = newSym(skType, getIdent"T2", dummyOwner, UnknownLineInfo())
  2399. T2.sym.position = 1
  2400. setup:
  2401. var c: TCandidate
  2402. initCandidate(nil, c, nil)
  2403. template yes(x, y) =
  2404. test astToStr(x) & " is " & astToStr(y):
  2405. check typeRel(c, y, x) == isGeneric
  2406. template no(x, y) =
  2407. test astToStr(x) & " is not " & astToStr(y):
  2408. check typeRel(c, y, x) == isNone
  2409. yes seq(any), array(10, int) | seq(any)
  2410. # Sure, seq[any] is directly included
  2411. yes seq(int), seq(any)
  2412. yes seq(int), seq(number)
  2413. # Sure, the int sequence is certainly
  2414. # part of the number sequences (and all sequences)
  2415. no seq(any), seq(float)
  2416. # Nope, seq[any] includes types that are not seq[float] (e.g. seq[int])
  2417. yes seq(int|string), seq(any)
  2418. # Sure
  2419. yes seq(int&string), seq(any)
  2420. # Again
  2421. yes seq(int&string), seq(int)
  2422. # A bit more complicated
  2423. # seq[int&string] is not a real type, but it's analogous to
  2424. # seq[Sortable and Iterable], which is certainly a subset of seq[Sortable]
  2425. no seq(int|string), seq(int|float)
  2426. # Nope, seq[string] is not included in not included in
  2427. # the seq[int|float] set
  2428. no seq(!(int|string)), seq(string)
  2429. # A sequence that is neither seq[int] or seq[string]
  2430. # is obviously not seq[string]
  2431. no seq(!int), seq(number)
  2432. # Now your head should start to hurt a bit
  2433. # A sequence that is not seq[int] is not necessarily a number sequence
  2434. # it could well be seq[string] for example
  2435. yes seq(!(int|string)), seq(!string)
  2436. # all sequnece types besides seq[int] and seq[string]
  2437. # are subset of all sequence types that are not seq[string]
  2438. no seq(!(int|string)), seq(!(string|TFoo))
  2439. # Nope, seq[TFoo] is included in the first set, but not in the second
  2440. no seq(!string), seq(!number)
  2441. # Nope, seq[int] in included in the first set, but not in the second
  2442. yes seq(!number), seq(any)
  2443. yes seq(!int), seq(any)
  2444. no seq(any), seq(!any)
  2445. no seq(!int), seq(!any)
  2446. yes int, ordinal
  2447. no string, ordinal