semcall.nim 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  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 semantic checking for calls.
  10. # included from sem.nim
  11. proc sameMethodDispatcher(a, b: PSym): bool =
  12. result = false
  13. if a.kind == skMethod and b.kind == skMethod:
  14. var aa = lastSon(a.ast)
  15. var bb = lastSon(b.ast)
  16. if aa.kind == nkSym and bb.kind == nkSym:
  17. if aa.sym == bb.sym:
  18. result = true
  19. else:
  20. discard
  21. # generics have no dispatcher yet, so we need to compare the method
  22. # names; however, the names are equal anyway because otherwise we
  23. # wouldn't even consider them to be overloaded. But even this does
  24. # not work reliably! See tmultim6 for an example:
  25. # method collide[T](a: TThing, b: TUnit[T]) is instantiated and not
  26. # method collide[T](a: TUnit[T], b: TThing)! This means we need to
  27. # *instantiate* every candidate! However, we don't keep more than 2-3
  28. # candidated around so we cannot implement that for now. So in order
  29. # to avoid subtle problems, the call remains ambiguous and needs to
  30. # be disambiguated by the programmer; this way the right generic is
  31. # instantiated.
  32. proc determineType(c: PContext, s: PSym)
  33. proc initCandidateSymbols(c: PContext, headSymbol: PNode,
  34. initialBinding: PNode,
  35. filter: TSymKinds,
  36. best, alt: var TCandidate,
  37. o: var TOverloadIter,
  38. diagnostics: bool): seq[tuple[s: PSym, scope: int]] =
  39. result = @[]
  40. var symx = initOverloadIter(o, c, headSymbol)
  41. while symx != nil:
  42. if symx.kind in filter:
  43. result.add((symx, o.lastOverloadScope))
  44. symx = nextOverloadIter(o, c, headSymbol)
  45. if result.len > 0:
  46. initCandidate(c, best, result[0].s, initialBinding,
  47. result[0].scope, diagnostics)
  48. initCandidate(c, alt, result[0].s, initialBinding,
  49. result[0].scope, diagnostics)
  50. best.state = csNoMatch
  51. proc pickBestCandidate(c: PContext, headSymbol: PNode,
  52. n, orig: PNode,
  53. initialBinding: PNode,
  54. filter: TSymKinds,
  55. best, alt: var TCandidate,
  56. errors: var CandidateErrors,
  57. diagnosticsFlag = false) =
  58. var o: TOverloadIter
  59. var sym = initOverloadIter(o, c, headSymbol)
  60. var scope = o.lastOverloadScope
  61. # Thanks to the lazy semchecking for operands, we need to check whether
  62. # 'initCandidate' modifies the symbol table (via semExpr).
  63. # This can occur in cases like 'init(a, 1, (var b = new(Type2); b))'
  64. let counterInitial = c.currentScope.symbols.counter
  65. var syms: seq[tuple[s: PSym, scope: int]]
  66. var nextSymIndex = 0
  67. while sym != nil:
  68. if sym.kind in filter:
  69. # Initialise 'best' and 'alt' with the first available symbol
  70. initCandidate(c, best, sym, initialBinding, scope, diagnosticsFlag)
  71. initCandidate(c, alt, sym, initialBinding, scope, diagnosticsFlag)
  72. best.state = csNoMatch
  73. break
  74. else:
  75. sym = nextOverloadIter(o, c, headSymbol)
  76. scope = o.lastOverloadScope
  77. var z: TCandidate
  78. while sym != nil:
  79. if sym.kind notin filter:
  80. sym = nextOverloadIter(o, c, headSymbol)
  81. scope = o.lastOverloadScope
  82. continue
  83. determineType(c, sym)
  84. initCandidate(c, z, sym, initialBinding, scope, diagnosticsFlag)
  85. if c.currentScope.symbols.counter == counterInitial or syms != nil:
  86. matches(c, n, orig, z)
  87. if z.state == csMatch:
  88. # little hack so that iterators are preferred over everything else:
  89. if sym.kind == skIterator: inc(z.exactMatches, 200)
  90. case best.state
  91. of csEmpty, csNoMatch: best = z
  92. of csMatch:
  93. var cmp = cmpCandidates(best, z)
  94. if cmp < 0: best = z # x is better than the best so far
  95. elif cmp == 0: alt = z # x is as good as the best so far
  96. elif errors != nil or z.diagnostics != nil:
  97. errors.safeAdd(CandidateError(
  98. sym: sym,
  99. unmatchedVarParam: int z.mutabilityProblem,
  100. diagnostics: z.diagnostics))
  101. else:
  102. # Symbol table has been modified. Restart and pre-calculate all syms
  103. # before any further candidate init and compare. SLOW, but rare case.
  104. syms = initCandidateSymbols(c, headSymbol, initialBinding, filter,
  105. best, alt, o, diagnosticsFlag)
  106. if syms == nil:
  107. sym = nextOverloadIter(o, c, headSymbol)
  108. scope = o.lastOverloadScope
  109. elif nextSymIndex < syms.len:
  110. # rare case: retrieve the next pre-calculated symbol
  111. sym = syms[nextSymIndex].s
  112. scope = syms[nextSymIndex].scope
  113. nextSymIndex += 1
  114. else:
  115. break
  116. proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
  117. (TPreferedDesc, string) =
  118. var prefer = preferName
  119. # to avoid confusing errors like:
  120. # got (SslPtr, SocketHandle)
  121. # but expected one of:
  122. # openssl.SSL_set_fd(ssl: SslPtr, fd: SocketHandle): cint
  123. # we do a pre-analysis. If all types produce the same string, we will add
  124. # module information.
  125. let proto = describeArgs(c, n, 1, preferName)
  126. for err in errors:
  127. var errProto = ""
  128. let n = err.sym.typ.n
  129. for i in countup(1, n.len - 1):
  130. var p = n.sons[i]
  131. if p.kind == nkSym:
  132. add(errProto, typeToString(p.sym.typ, preferName))
  133. if i != n.len-1: add(errProto, ", ")
  134. # else: ignore internal error as we're already in error handling mode
  135. if errProto == proto:
  136. prefer = preferModuleInfo
  137. break
  138. var candidates = ""
  139. for err in errors:
  140. if err.sym.kind in routineKinds and err.sym.ast != nil:
  141. add(candidates, renderTree(err.sym.ast,
  142. {renderNoBody, renderNoComments, renderNoPragmas}))
  143. else:
  144. add(candidates, err.sym.getProcHeader(prefer))
  145. add(candidates, "\n")
  146. if err.unmatchedVarParam != 0 and err.unmatchedVarParam < n.len:
  147. add(candidates, "for a 'var' type a variable needs to be passed, but '" &
  148. renderTree(n[err.unmatchedVarParam]) & "' is immutable\n")
  149. for diag in err.diagnostics:
  150. add(candidates, diag & "\n")
  151. result = (prefer, candidates)
  152. proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
  153. # Gives a detailed error message; this is separated from semOverloadedCall,
  154. # as semOverlodedCall is already pretty slow (and we need this information
  155. # only in case of an error).
  156. if errorOutputs == {}:
  157. # fail fast:
  158. globalError(n.info, errTypeMismatch, "")
  159. if errors.isNil or errors.len == 0:
  160. localError(n.info, errExprXCannotBeCalled, n[0].renderTree)
  161. return
  162. let (prefer, candidates) = presentFailedCandidates(c, n, errors)
  163. var result = msgKindToString(errTypeMismatch)
  164. add(result, describeArgs(c, n, 1, prefer))
  165. add(result, ')')
  166. if candidates != "":
  167. add(result, "\n" & msgKindToString(errButExpected) & "\n" & candidates)
  168. localError(n.info, errGenerated, result)
  169. proc bracketNotFoundError(c: PContext; n: PNode) =
  170. var errors: CandidateErrors = @[]
  171. var o: TOverloadIter
  172. let headSymbol = n[0]
  173. var symx = initOverloadIter(o, c, headSymbol)
  174. while symx != nil:
  175. if symx.kind in routineKinds:
  176. errors.add(CandidateError(sym: symx,
  177. unmatchedVarParam: 0,
  178. diagnostics: nil))
  179. symx = nextOverloadIter(o, c, headSymbol)
  180. if errors.len == 0:
  181. localError(n.info, "could not resolve: " & $n)
  182. else:
  183. notFoundError(c, n, errors)
  184. proc resolveOverloads(c: PContext, n, orig: PNode,
  185. filter: TSymKinds, flags: TExprFlags,
  186. errors: var CandidateErrors): TCandidate =
  187. var initialBinding: PNode
  188. var alt: TCandidate
  189. var f = n.sons[0]
  190. if f.kind == nkBracketExpr:
  191. # fill in the bindings:
  192. initialBinding = f
  193. f = f.sons[0]
  194. else:
  195. initialBinding = nil
  196. template pickBest(headSymbol) =
  197. pickBestCandidate(c, headSymbol, n, orig, initialBinding,
  198. filter, result, alt, errors, efExplain in flags)
  199. pickBest(f)
  200. let overloadsState = result.state
  201. if overloadsState != csMatch:
  202. if c.p != nil and c.p.selfSym != nil:
  203. # we need to enforce semchecking of selfSym again because it
  204. # might need auto-deref:
  205. var hiddenArg = newSymNode(c.p.selfSym)
  206. hiddenArg.typ = nil
  207. n.sons.insert(hiddenArg, 1)
  208. orig.sons.insert(hiddenArg, 1)
  209. pickBest(f)
  210. if result.state != csMatch:
  211. n.sons.delete(1)
  212. orig.sons.delete(1)
  213. excl n.flags, nfExprCall
  214. else: return
  215. if nfDotField in n.flags:
  216. internalAssert f.kind == nkIdent and n.sonsLen >= 2
  217. let calleeName = newStrNode(nkStrLit, f.ident.s).withInfo(n.info)
  218. # leave the op head symbol empty,
  219. # we are going to try multiple variants
  220. n.sons[0..1] = [nil, n[1], calleeName]
  221. orig.sons[0..1] = [nil, orig[1], calleeName]
  222. template tryOp(x) =
  223. let op = newIdentNode(getIdent(x), n.info)
  224. n.sons[0] = op
  225. orig.sons[0] = op
  226. pickBest(op)
  227. if nfExplicitCall in n.flags:
  228. tryOp ".()"
  229. if result.state in {csEmpty, csNoMatch}:
  230. tryOp "."
  231. elif nfDotSetter in n.flags and f.kind == nkIdent and n.len == 3:
  232. let calleeName = newStrNode(nkStrLit,
  233. f.ident.s[0..f.ident.s.len-2]).withInfo(n.info)
  234. let callOp = newIdentNode(getIdent".=", n.info)
  235. n.sons[0..1] = [callOp, n[1], calleeName]
  236. orig.sons[0..1] = [callOp, orig[1], calleeName]
  237. pickBest(callOp)
  238. if overloadsState == csEmpty and result.state == csEmpty:
  239. if nfDotField in n.flags and nfExplicitCall notin n.flags:
  240. localError(n.info, errUndeclaredField, considerQuotedIdent(f).s)
  241. else:
  242. localError(n.info, errUndeclaredRoutine, considerQuotedIdent(f).s)
  243. return
  244. elif result.state != csMatch:
  245. if nfExprCall in n.flags:
  246. localError(n.info, errExprXCannotBeCalled,
  247. renderTree(n, {renderNoComments}))
  248. else:
  249. if {nfDotField, nfDotSetter} * n.flags != {}:
  250. # clean up the inserted ops
  251. n.sons.delete(2)
  252. n.sons[0] = f
  253. return
  254. if alt.state == csMatch and cmpCandidates(result, alt) == 0 and
  255. not sameMethodDispatcher(result.calleeSym, alt.calleeSym):
  256. internalAssert result.state == csMatch
  257. #writeMatches(result)
  258. #writeMatches(alt)
  259. if errorOutputs == {}:
  260. # quick error message for performance of 'compiles' built-in:
  261. globalError(n.info, errGenerated, "ambiguous call")
  262. elif gErrorCounter == 0:
  263. # don't cascade errors
  264. var args = "("
  265. for i in countup(1, sonsLen(n) - 1):
  266. if i > 1: add(args, ", ")
  267. add(args, typeToString(n.sons[i].typ))
  268. add(args, ")")
  269. localError(n.info, errGenerated, msgKindToString(errAmbiguousCallXYZ) % [
  270. getProcHeader(result.calleeSym), getProcHeader(alt.calleeSym),
  271. args])
  272. proc instGenericConvertersArg*(c: PContext, a: PNode, x: TCandidate) =
  273. if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym:
  274. let s = a.sons[0].sym
  275. if s.ast != nil and s.ast[genericParamsPos].kind != nkEmpty:
  276. let finalCallee = generateInstance(c, s, x.bindings, a.info)
  277. a.sons[0].sym = finalCallee
  278. a.sons[0].typ = finalCallee.typ
  279. #a.typ = finalCallee.typ.sons[0]
  280. proc instGenericConvertersSons*(c: PContext, n: PNode, x: TCandidate) =
  281. assert n.kind in nkCallKinds
  282. if x.genericConverter:
  283. for i in 1 .. <n.len:
  284. instGenericConvertersArg(c, n.sons[i], x)
  285. proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode =
  286. var m: TCandidate
  287. initCandidate(c, m, f)
  288. result = paramTypesMatch(m, f, a, arg, nil)
  289. if m.genericConverter and result != nil:
  290. instGenericConvertersArg(c, result, m)
  291. proc inferWithMetatype(c: PContext, formal: PType,
  292. arg: PNode, coerceDistincts = false): PNode =
  293. var m: TCandidate
  294. initCandidate(c, m, formal)
  295. m.coerceDistincts = coerceDistincts
  296. result = paramTypesMatch(m, formal, arg.typ, arg, nil)
  297. if m.genericConverter and result != nil:
  298. instGenericConvertersArg(c, result, m)
  299. if result != nil:
  300. # This almost exactly replicates the steps taken by the compiler during
  301. # param matching. It performs an embarrassing amount of back-and-forth
  302. # type jugling, but it's the price to pay for consistency and correctness
  303. result.typ = generateTypeInstance(c, m.bindings, arg.info,
  304. formal.skipTypes({tyCompositeTypeClass}))
  305. else:
  306. typeMismatch(arg.info, formal, arg.typ)
  307. # error correction:
  308. result = copyTree(arg)
  309. result.typ = formal
  310. proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
  311. assert x.state == csMatch
  312. var finalCallee = x.calleeSym
  313. markUsed(n.sons[0].info, finalCallee, c.graph.usageSym)
  314. styleCheckUse(n.sons[0].info, finalCallee)
  315. assert finalCallee.ast != nil
  316. if x.hasFauxMatch:
  317. result = x.call
  318. result.sons[0] = newSymNode(finalCallee, result.sons[0].info)
  319. if containsGenericType(result.typ) or x.fauxMatch == tyUnknown:
  320. result.typ = newTypeS(x.fauxMatch, c)
  321. return
  322. let gp = finalCallee.ast.sons[genericParamsPos]
  323. if gp.kind != nkEmpty:
  324. if x.calleeSym.kind notin {skMacro, skTemplate}:
  325. if x.calleeSym.magic in {mArrGet, mArrPut}:
  326. finalCallee = x.calleeSym
  327. else:
  328. finalCallee = generateInstance(c, x.calleeSym, x.bindings, n.info)
  329. else:
  330. # For macros and templates, the resolved generic params
  331. # are added as normal params.
  332. for s in instantiateGenericParamList(c, gp, x.bindings):
  333. case s.kind
  334. of skConst:
  335. x.call.add s.ast
  336. of skType:
  337. x.call.add newSymNode(s, n.info)
  338. else:
  339. internalAssert false
  340. result = x.call
  341. instGenericConvertersSons(c, result, x)
  342. result.sons[0] = newSymNode(finalCallee, result.sons[0].info)
  343. result.typ = finalCallee.typ.sons[0]
  344. proc canDeref(n: PNode): bool {.inline.} =
  345. result = n.len >= 2 and (let t = n[1].typ;
  346. t != nil and t.skipTypes({tyGenericInst, tyAlias}).kind in {tyPtr, tyRef})
  347. proc tryDeref(n: PNode): PNode =
  348. result = newNodeI(nkHiddenDeref, n.info)
  349. result.typ = n.typ.skipTypes(abstractInst).sons[0]
  350. result.addSon(n)
  351. proc semOverloadedCall(c: PContext, n, nOrig: PNode,
  352. filter: TSymKinds, flags: TExprFlags): PNode =
  353. var errors: CandidateErrors = if efExplain in flags: @[]
  354. else: nil
  355. var r = resolveOverloads(c, n, nOrig, filter, flags, errors)
  356. if r.state == csMatch:
  357. # this may be triggered, when the explain pragma is used
  358. if errors.len > 0:
  359. let (_, candidates) = presentFailedCandidates(c, n, errors)
  360. message(n.info, hintUserRaw,
  361. "Non-matching candidates for " & renderTree(n) & "\n" &
  362. candidates)
  363. result = semResolvedCall(c, n, r)
  364. elif experimentalMode(c) and canDeref(n):
  365. # try to deref the first argument and then try overloading resolution again:
  366. #
  367. # XXX: why is this here?
  368. # it could be added to the long list of alternatives tried
  369. # inside `resolveOverloads` or it could be moved all the way
  370. # into sigmatch with hidden conversion produced there
  371. #
  372. n.sons[1] = n.sons[1].tryDeref
  373. var r = resolveOverloads(c, n, nOrig, filter, flags, errors)
  374. if r.state == csMatch: result = semResolvedCall(c, n, r)
  375. else:
  376. # get rid of the deref again for a better error message:
  377. n.sons[1] = n.sons[1].sons[0]
  378. #notFoundError(c, n, errors)
  379. if efExplain notin flags:
  380. # repeat the overload resolution,
  381. # this time enabling all the diagnostic output (this should fail again)
  382. discard semOverloadedCall(c, n, nOrig, filter, flags + {efExplain})
  383. else:
  384. notFoundError(c, n, errors)
  385. else:
  386. if efExplain notin flags:
  387. # repeat the overload resolution,
  388. # this time enabling all the diagnostic output (this should fail again)
  389. discard semOverloadedCall(c, n, nOrig, filter, flags + {efExplain})
  390. else:
  391. notFoundError(c, n, errors)
  392. proc explicitGenericInstError(n: PNode): PNode =
  393. localError(n.info, errCannotInstantiateX, renderTree(n))
  394. result = n
  395. proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode =
  396. var m: TCandidate
  397. # binding has to stay 'nil' for this to work!
  398. initCandidate(c, m, s, nil)
  399. for i in 1..sonsLen(n)-1:
  400. let formal = s.ast.sons[genericParamsPos].sons[i-1].typ
  401. let arg = n[i].typ
  402. let tm = typeRel(m, formal, arg)
  403. if tm in {isNone, isConvertible}: return nil
  404. var newInst = generateInstance(c, s, m.bindings, n.info)
  405. newInst.typ.flags.excl tfUnresolved
  406. markUsed(n.info, s, c.graph.usageSym)
  407. styleCheckUse(n.info, s)
  408. result = newSymNode(newInst, n.info)
  409. proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
  410. assert n.kind == nkBracketExpr
  411. for i in 1..sonsLen(n)-1:
  412. let e = semExpr(c, n.sons[i])
  413. n.sons[i].typ = e.typ.skipTypes({tyTypeDesc})
  414. var s = s
  415. var a = n.sons[0]
  416. if a.kind == nkSym:
  417. # common case; check the only candidate has the right
  418. # number of generic type parameters:
  419. if safeLen(s.ast.sons[genericParamsPos]) != n.len-1:
  420. let expected = safeLen(s.ast.sons[genericParamsPos])
  421. localError(n.info, errGenerated, "cannot instantiate: " & renderTree(n) &
  422. "; got " & $(n.len-1) & " type(s) but expected " & $expected)
  423. return n
  424. result = explicitGenericSym(c, n, s)
  425. if result == nil: result = explicitGenericInstError(n)
  426. elif a.kind in {nkClosedSymChoice, nkOpenSymChoice}:
  427. # choose the generic proc with the proper number of type parameters.
  428. # XXX I think this could be improved by reusing sigmatch.paramTypesMatch.
  429. # It's good enough for now.
  430. result = newNodeI(a.kind, n.info)
  431. for i in countup(0, len(a)-1):
  432. var candidate = a.sons[i].sym
  433. if candidate.kind in {skProc, skMethod, skConverter,
  434. skIterator}:
  435. # it suffices that the candidate has the proper number of generic
  436. # type parameters:
  437. if safeLen(candidate.ast.sons[genericParamsPos]) == n.len-1:
  438. let x = explicitGenericSym(c, n, candidate)
  439. if x != nil: result.add(x)
  440. # get rid of nkClosedSymChoice if not ambiguous:
  441. if result.len == 1 and a.kind == nkClosedSymChoice:
  442. result = result[0]
  443. elif result.len == 0: result = explicitGenericInstError(n)
  444. # candidateCount != 1: return explicitGenericInstError(n)
  445. else:
  446. result = explicitGenericInstError(n)
  447. proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym =
  448. # Searchs for the fn in the symbol table. If the parameter lists are suitable
  449. # for borrowing the sym in the symbol table is returned, else nil.
  450. # New approach: generate fn(x, y, z) where x, y, z have the proper types
  451. # and use the overloading resolution mechanism:
  452. var call = newNodeI(nkCall, fn.info)
  453. var hasDistinct = false
  454. call.add(newIdentNode(fn.name, fn.info))
  455. for i in 1.. <fn.typ.n.len:
  456. let param = fn.typ.n.sons[i]
  457. let t = skipTypes(param.typ, abstractVar-{tyTypeDesc, tyDistinct})
  458. if t.kind == tyDistinct or param.typ.kind == tyDistinct: hasDistinct = true
  459. var x: PType
  460. if param.typ.kind == tyVar:
  461. x = newTypeS(tyVar, c)
  462. x.addSonSkipIntLit t.baseOfDistinct
  463. else:
  464. x = t.baseOfDistinct
  465. call.add(newNodeIT(nkEmpty, fn.info, x))
  466. if hasDistinct:
  467. var resolved = semOverloadedCall(c, call, call, {fn.kind}, {})
  468. if resolved != nil:
  469. result = resolved.sons[0].sym
  470. if not compareTypes(result.typ.sons[0], fn.typ.sons[0], dcEqIgnoreDistinct):
  471. result = nil
  472. elif result.magic in {mArrPut, mArrGet}:
  473. # cannot borrow these magics for now
  474. result = nil