sigmatch.nim 105 KB

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