sigmatch.nim 98 KB

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