sigmatch.nim 112 KB

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