sigmatch.nim 96 KB

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