sigmatch.nim 116 KB

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