sigmatch.nim 99 KB

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