sigmatch.nim 98 KB

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