sigmatch.nim 93 KB

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