sigmatch.nim 101 KB

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