sigmatch.nim 106 KB

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