sigmatch.nim 105 KB

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