sigmatch.nim 118 KB

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