sigmatch.nim 105 KB

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