sigmatch.nim 96 KB

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