sigmatch.nim 96 KB

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