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