semcall.nim 20 KB

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