sigmatch.nim 99 KB

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