sigmatch.nim 117 KB

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