semstmts.nim 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868
  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 does the semantic checking of statements
  10. # included from sem.nim
  11. var enforceVoidContext = PType(kind: tyStmt)
  12. proc semDiscard(c: PContext, n: PNode): PNode =
  13. result = n
  14. checkSonsLen(n, 1)
  15. if n.sons[0].kind != nkEmpty:
  16. n.sons[0] = semExprWithType(c, n.sons[0])
  17. if isEmptyType(n.sons[0].typ) or n.sons[0].typ.kind == tyNone:
  18. localError(n.info, errInvalidDiscard)
  19. proc semBreakOrContinue(c: PContext, n: PNode): PNode =
  20. result = n
  21. checkSonsLen(n, 1)
  22. if n.sons[0].kind != nkEmpty:
  23. if n.kind != nkContinueStmt:
  24. var s: PSym
  25. case n.sons[0].kind
  26. of nkIdent: s = lookUp(c, n.sons[0])
  27. of nkSym: s = n.sons[0].sym
  28. else: illFormedAst(n)
  29. s = getGenSym(c, s)
  30. if s.kind == skLabel and s.owner.id == c.p.owner.id:
  31. var x = newSymNode(s)
  32. x.info = n.info
  33. incl(s.flags, sfUsed)
  34. n.sons[0] = x
  35. suggestSym(x.info, s, c.graph.usageSym)
  36. styleCheckUse(x.info, s)
  37. else:
  38. localError(n.info, errInvalidControlFlowX, s.name.s)
  39. else:
  40. localError(n.info, errGenerated, "'continue' cannot have a label")
  41. elif (c.p.nestedLoopCounter <= 0) and (c.p.nestedBlockCounter <= 0):
  42. localError(n.info, errInvalidControlFlowX,
  43. renderTree(n, {renderNoComments}))
  44. proc semAsm(con: PContext, n: PNode): PNode =
  45. checkSonsLen(n, 2)
  46. var marker = pragmaAsm(con, n.sons[0])
  47. if marker == '\0': marker = '`' # default marker
  48. result = semAsmOrEmit(con, n, marker)
  49. proc semWhile(c: PContext, n: PNode): PNode =
  50. result = n
  51. checkSonsLen(n, 2)
  52. openScope(c)
  53. n.sons[0] = forceBool(c, semExprWithType(c, n.sons[0]))
  54. inc(c.p.nestedLoopCounter)
  55. n.sons[1] = semStmt(c, n.sons[1])
  56. dec(c.p.nestedLoopCounter)
  57. closeScope(c)
  58. if n.sons[1].typ == enforceVoidContext:
  59. result.typ = enforceVoidContext
  60. proc toCover(t: PType): BiggestInt =
  61. var t2 = skipTypes(t, abstractVarRange-{tyTypeDesc})
  62. if t2.kind == tyEnum and enumHasHoles(t2):
  63. result = sonsLen(t2.n)
  64. else:
  65. result = lengthOrd(skipTypes(t, abstractVar-{tyTypeDesc}))
  66. when false:
  67. proc performProcvarCheck(c: PContext, info: TLineInfo, s: PSym) =
  68. ## Checks that the given symbol is a proper procedure variable, meaning
  69. ## that it
  70. var smoduleId = getModule(s).id
  71. if sfProcvar notin s.flags and s.typ.callConv == ccDefault and
  72. smoduleId != c.module.id:
  73. block outer:
  74. for module in c.friendModules:
  75. if smoduleId == module.id:
  76. break outer
  77. localError(info, errXCannotBePassedToProcVar, s.name.s)
  78. template semProcvarCheck(c: PContext, n: PNode) =
  79. when false:
  80. var n = n.skipConv
  81. if n.kind in nkSymChoices:
  82. for x in n:
  83. if x.sym.kind in {skProc, skMethod, skConverter, skIterator}:
  84. performProcvarCheck(c, n.info, x.sym)
  85. elif n.kind == nkSym and n.sym.kind in {skProc, skMethod, skConverter,
  86. skIterator}:
  87. performProcvarCheck(c, n.info, n.sym)
  88. proc semProc(c: PContext, n: PNode): PNode
  89. include semdestruct
  90. proc semDestructorCheck(c: PContext, n: PNode, flags: TExprFlags) {.inline.} =
  91. if not newDestructors:
  92. if efAllowDestructor notin flags and
  93. n.kind in nkCallKinds+{nkObjConstr,nkBracket}:
  94. if instantiateDestructor(c, n.typ) != nil:
  95. localError(n.info, warnDestructor)
  96. # This still breaks too many things:
  97. when false:
  98. if efDetermineType notin flags and n.typ.kind == tyTypeDesc and
  99. c.p.owner.kind notin {skTemplate, skMacro}:
  100. localError(n.info, errGenerated, "value expected, but got a type")
  101. proc semExprBranch(c: PContext, n: PNode): PNode =
  102. result = semExpr(c, n)
  103. if result.typ != nil:
  104. # XXX tyGenericInst here?
  105. semProcvarCheck(c, result)
  106. if result.typ.kind == tyVar: result = newDeref(result)
  107. semDestructorCheck(c, result, {})
  108. proc semExprBranchScope(c: PContext, n: PNode): PNode =
  109. openScope(c)
  110. result = semExprBranch(c, n)
  111. closeScope(c)
  112. const
  113. skipForDiscardable = {nkIfStmt, nkIfExpr, nkCaseStmt, nkOfBranch,
  114. nkElse, nkStmtListExpr, nkTryStmt, nkFinally, nkExceptBranch,
  115. nkElifBranch, nkElifExpr, nkElseExpr, nkBlockStmt, nkBlockExpr}
  116. proc implicitlyDiscardable(n: PNode): bool =
  117. var n = n
  118. while n.kind in skipForDiscardable: n = n.lastSon
  119. result = isCallExpr(n) and n.sons[0].kind == nkSym and
  120. sfDiscardable in n.sons[0].sym.flags
  121. proc fixNilType(n: PNode) =
  122. if isAtom(n):
  123. if n.kind != nkNilLit and n.typ != nil:
  124. localError(n.info, errDiscardValueX, n.typ.typeToString)
  125. elif n.kind in {nkStmtList, nkStmtListExpr}:
  126. n.kind = nkStmtList
  127. for it in n: fixNilType(it)
  128. n.typ = nil
  129. proc discardCheck(c: PContext, result: PNode) =
  130. if c.matchedConcept != nil: return
  131. if result.typ != nil and result.typ.kind notin {tyStmt, tyVoid}:
  132. if result.kind == nkNilLit:
  133. result.typ = nil
  134. message(result.info, warnNilStatement)
  135. elif implicitlyDiscardable(result):
  136. var n = result
  137. result.typ = nil
  138. while n.kind in skipForDiscardable:
  139. n = n.lastSon
  140. n.typ = nil
  141. elif result.typ.kind != tyError and gCmd != cmdInteractive:
  142. if result.typ.kind == tyNil:
  143. fixNilType(result)
  144. message(result.info, warnNilStatement)
  145. else:
  146. var n = result
  147. while n.kind in skipForDiscardable: n = n.lastSon
  148. var s = "expression '" & $n & "' is of type '" &
  149. result.typ.typeToString & "' and has to be discarded"
  150. if result.typ.kind == tyProc:
  151. s.add "; for a function call use ()"
  152. localError(n.info, s)
  153. proc semIf(c: PContext, n: PNode): PNode =
  154. result = n
  155. var typ = commonTypeBegin
  156. var hasElse = false
  157. for i in countup(0, sonsLen(n) - 1):
  158. var it = n.sons[i]
  159. if it.len == 2:
  160. when newScopeForIf: openScope(c)
  161. it.sons[0] = forceBool(c, semExprWithType(c, it.sons[0]))
  162. when not newScopeForIf: openScope(c)
  163. it.sons[1] = semExprBranch(c, it.sons[1])
  164. typ = commonType(typ, it.sons[1].typ)
  165. closeScope(c)
  166. elif it.len == 1:
  167. hasElse = true
  168. it.sons[0] = semExprBranchScope(c, it.sons[0])
  169. typ = commonType(typ, it.sons[0].typ)
  170. else: illFormedAst(it)
  171. if isEmptyType(typ) or typ.kind == tyNil or not hasElse:
  172. for it in n: discardCheck(c, it.lastSon)
  173. result.kind = nkIfStmt
  174. # propagate any enforced VoidContext:
  175. if typ == enforceVoidContext: result.typ = enforceVoidContext
  176. else:
  177. for it in n:
  178. let j = it.len-1
  179. it.sons[j] = fitNode(c, typ, it.sons[j], it.sons[j].info)
  180. result.kind = nkIfExpr
  181. result.typ = typ
  182. proc semCase(c: PContext, n: PNode): PNode =
  183. result = n
  184. checkMinSonsLen(n, 2)
  185. openScope(c)
  186. n.sons[0] = semExprWithType(c, n.sons[0])
  187. var chckCovered = false
  188. var covered: BiggestInt = 0
  189. var typ = commonTypeBegin
  190. var hasElse = false
  191. let caseTyp = skipTypes(n.sons[0].typ, abstractVarRange-{tyTypeDesc})
  192. case caseTyp.kind
  193. of tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool:
  194. chckCovered = true
  195. of tyFloat..tyFloat128, tyString, tyError:
  196. discard
  197. else:
  198. localError(n.info, errSelectorMustBeOfCertainTypes)
  199. return
  200. for i in countup(1, sonsLen(n) - 1):
  201. var x = n.sons[i]
  202. when defined(nimsuggest):
  203. if gIdeCmd == ideSug and exactEquals(gTrackPos, x.info) and caseTyp.kind == tyEnum:
  204. suggestEnum(c, x, caseTyp)
  205. case x.kind
  206. of nkOfBranch:
  207. checkMinSonsLen(x, 2)
  208. semCaseBranch(c, n, x, i, covered)
  209. var last = sonsLen(x)-1
  210. x.sons[last] = semExprBranchScope(c, x.sons[last])
  211. typ = commonType(typ, x.sons[last].typ)
  212. of nkElifBranch:
  213. chckCovered = false
  214. checkSonsLen(x, 2)
  215. when newScopeForIf: openScope(c)
  216. x.sons[0] = forceBool(c, semExprWithType(c, x.sons[0]))
  217. when not newScopeForIf: openScope(c)
  218. x.sons[1] = semExprBranch(c, x.sons[1])
  219. typ = commonType(typ, x.sons[1].typ)
  220. closeScope(c)
  221. of nkElse:
  222. chckCovered = false
  223. checkSonsLen(x, 1)
  224. x.sons[0] = semExprBranchScope(c, x.sons[0])
  225. typ = commonType(typ, x.sons[0].typ)
  226. hasElse = true
  227. else:
  228. illFormedAst(x)
  229. if chckCovered:
  230. if covered == toCover(n.sons[0].typ):
  231. hasElse = true
  232. else:
  233. localError(n.info, errNotAllCasesCovered)
  234. closeScope(c)
  235. if isEmptyType(typ) or typ.kind == tyNil or not hasElse:
  236. for i in 1..n.len-1: discardCheck(c, n.sons[i].lastSon)
  237. # propagate any enforced VoidContext:
  238. if typ == enforceVoidContext:
  239. result.typ = enforceVoidContext
  240. else:
  241. for i in 1..n.len-1:
  242. var it = n.sons[i]
  243. let j = it.len-1
  244. it.sons[j] = fitNode(c, typ, it.sons[j], it.sons[j].info)
  245. result.typ = typ
  246. proc semTry(c: PContext, n: PNode): PNode =
  247. result = n
  248. inc c.p.inTryStmt
  249. checkMinSonsLen(n, 2)
  250. var typ = commonTypeBegin
  251. n.sons[0] = semExprBranchScope(c, n.sons[0])
  252. typ = commonType(typ, n.sons[0].typ)
  253. var check = initIntSet()
  254. var last = sonsLen(n) - 1
  255. for i in countup(1, last):
  256. var a = n.sons[i]
  257. checkMinSonsLen(a, 1)
  258. var length = sonsLen(a)
  259. openScope(c)
  260. if a.kind == nkExceptBranch:
  261. # so that ``except [a, b, c]`` is supported:
  262. if length == 2 and a.sons[0].kind == nkBracket:
  263. a.sons[0..0] = a.sons[0].sons
  264. length = a.sonsLen
  265. # Iterate through each exception type in the except branch.
  266. for j in countup(0, length-2):
  267. var typeNode = a.sons[j] # e.g. `Exception`
  268. var symbolNode: PNode = nil # e.g. `foobar`
  269. # Handle the case where the `Exception as foobar` syntax is used.
  270. if typeNode.isInfixAs():
  271. typeNode = a.sons[j].sons[1]
  272. symbolNode = a.sons[j].sons[2]
  273. # Resolve the type ident into a PType.
  274. var typ = semTypeNode(c, typeNode, nil).toObject()
  275. if typ.kind != tyObject:
  276. localError(a.sons[j].info, errExprCannotBeRaised)
  277. let newTypeNode = newNodeI(nkType, typeNode.info)
  278. newTypeNode.typ = typ
  279. if symbolNode.isNil:
  280. a.sons[j] = newTypeNode
  281. else:
  282. a.sons[j].sons[1] = newTypeNode
  283. # Add the exception ident to the symbol table.
  284. let symbol = newSymG(skLet, symbolNode, c)
  285. symbol.typ = typ.toRef()
  286. addDecl(c, symbol)
  287. # Overwrite symbol in AST with the symbol in the symbol table.
  288. let symNode = newNodeI(nkSym, typeNode.info)
  289. symNode.sym = symbol
  290. a.sons[j].sons[2] = symNode
  291. if containsOrIncl(check, typ.id):
  292. localError(a.sons[j].info, errExceptionAlreadyHandled)
  293. elif a.kind != nkFinally:
  294. illFormedAst(n)
  295. # last child of an nkExcept/nkFinally branch is a statement:
  296. a.sons[length-1] = semExprBranchScope(c, a.sons[length-1])
  297. if a.kind != nkFinally: typ = commonType(typ, a.sons[length-1].typ)
  298. else: dec last
  299. closeScope(c)
  300. dec c.p.inTryStmt
  301. if isEmptyType(typ) or typ.kind == tyNil:
  302. discardCheck(c, n.sons[0])
  303. for i in 1..n.len-1: discardCheck(c, n.sons[i].lastSon)
  304. if typ == enforceVoidContext:
  305. result.typ = enforceVoidContext
  306. else:
  307. if n.lastSon.kind == nkFinally: discardCheck(c, n.lastSon.lastSon)
  308. n.sons[0] = fitNode(c, typ, n.sons[0], n.sons[0].info)
  309. for i in 1..last:
  310. var it = n.sons[i]
  311. let j = it.len-1
  312. it.sons[j] = fitNode(c, typ, it.sons[j], it.sons[j].info)
  313. result.typ = typ
  314. proc fitRemoveHiddenConv(c: PContext, typ: PType, n: PNode): PNode =
  315. result = fitNode(c, typ, n, n.info)
  316. if result.kind in {nkHiddenStdConv, nkHiddenSubConv}:
  317. let r1 = result.sons[1]
  318. if r1.kind in {nkCharLit..nkUInt64Lit} and typ.skipTypes(abstractRange).kind in {tyFloat..tyFloat128}:
  319. result = newFloatNode(nkFloatLit, BiggestFloat r1.intVal)
  320. result.info = n.info
  321. result.typ = typ
  322. else:
  323. changeType(r1, typ, check=true)
  324. result = r1
  325. elif not sameType(result.typ, typ):
  326. changeType(result, typ, check=false)
  327. proc findShadowedVar(c: PContext, v: PSym): PSym =
  328. for scope in walkScopes(c.currentScope.parent):
  329. if scope == c.topLevelScope: break
  330. let shadowed = strTableGet(scope.symbols, v.name)
  331. if shadowed != nil and shadowed.kind in skLocalVars:
  332. return shadowed
  333. proc identWithin(n: PNode, s: PIdent): bool =
  334. for i in 0 .. n.safeLen-1:
  335. if identWithin(n.sons[i], s): return true
  336. result = n.kind == nkSym and n.sym.name.id == s.id
  337. proc semIdentDef(c: PContext, n: PNode, kind: TSymKind): PSym =
  338. if isTopLevel(c):
  339. result = semIdentWithPragma(c, kind, n, {sfExported})
  340. incl(result.flags, sfGlobal)
  341. #if kind in {skVar, skLet}:
  342. # echo "global variable here ", n.info, " ", result.name.s
  343. else:
  344. result = semIdentWithPragma(c, kind, n, {})
  345. if result.owner.kind == skModule:
  346. incl(result.flags, sfGlobal)
  347. suggestSym(n.info, result, c.graph.usageSym)
  348. styleCheckDef(result)
  349. proc checkNilable(v: PSym) =
  350. if {sfGlobal, sfImportC} * v.flags == {sfGlobal} and
  351. {tfNotNil, tfNeedsInit} * v.typ.flags != {}:
  352. if v.ast.isNil:
  353. message(v.info, warnProveInit, v.name.s)
  354. elif tfNotNil in v.typ.flags and tfNotNil notin v.ast.typ.flags:
  355. message(v.info, warnProveInit, v.name.s)
  356. include semasgn
  357. proc addToVarSection(c: PContext; result: var PNode; orig, identDefs: PNode) =
  358. # consider this:
  359. # var
  360. # x = 0
  361. # withOverloadedAssignment = foo()
  362. # y = use(withOverloadedAssignment)
  363. # We need to split this into a statement list with multiple 'var' sections
  364. # in order for this transformation to be correct.
  365. let L = identDefs.len
  366. let value = identDefs[L-1]
  367. if value.typ != nil and tfHasAsgn in value.typ.flags and not newDestructors:
  368. # the spec says we need to rewrite 'var x = T()' to 'var x: T; x = T()':
  369. identDefs.sons[L-1] = emptyNode
  370. if result.kind != nkStmtList:
  371. let oldResult = result
  372. oldResult.add identDefs
  373. result = newNodeI(nkStmtList, result.info)
  374. result.add oldResult
  375. else:
  376. let o = copyNode(orig)
  377. o.add identDefs
  378. result.add o
  379. for i in 0 .. L-3:
  380. result.add overloadedAsgn(c, identDefs[i], value)
  381. elif result.kind == nkStmtList:
  382. let o = copyNode(orig)
  383. o.add identDefs
  384. result.add o
  385. else:
  386. result.add identDefs
  387. proc addDefer(c: PContext; result: var PNode; s: PSym) =
  388. let deferDestructorCall = createDestructorCall(c, s)
  389. if deferDestructorCall != nil:
  390. if result.kind != nkStmtList:
  391. let oldResult = result
  392. result = newNodeI(nkStmtList, result.info)
  393. result.add oldResult
  394. result.add deferDestructorCall
  395. proc isDiscardUnderscore(v: PSym): bool =
  396. if v.name.s == "_":
  397. v.flags.incl(sfGenSym)
  398. result = true
  399. proc semUsing(c: PContext; n: PNode): PNode =
  400. result = ast.emptyNode
  401. if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "using")
  402. for i in countup(0, sonsLen(n)-1):
  403. var a = n.sons[i]
  404. if gCmd == cmdIdeTools: suggestStmt(c, a)
  405. if a.kind == nkCommentStmt: continue
  406. if a.kind notin {nkIdentDefs, nkVarTuple, nkConstDef}: illFormedAst(a)
  407. checkMinSonsLen(a, 3)
  408. var length = sonsLen(a)
  409. if a.sons[length-2].kind != nkEmpty:
  410. let typ = semTypeNode(c, a.sons[length-2], nil)
  411. for j in countup(0, length-3):
  412. let v = semIdentDef(c, a.sons[j], skParam)
  413. v.typ = typ
  414. strTableIncl(c.signatures, v)
  415. else:
  416. localError(a.info, "'using' section must have a type")
  417. var def: PNode
  418. if a.sons[length-1].kind != nkEmpty:
  419. localError(a.info, "'using' sections cannot contain assignments")
  420. proc hasEmpty(typ: PType): bool =
  421. if typ.kind in {tySequence, tyArray, tySet}:
  422. result = typ.lastSon.kind == tyEmpty
  423. elif typ.kind == tyTuple:
  424. for s in typ.sons:
  425. result = result or hasEmpty(s)
  426. proc makeDeref(n: PNode): PNode =
  427. var t = skipTypes(n.typ, {tyGenericInst, tyAlias})
  428. if t.kind in tyUserTypeClasses and t.isResolvedUserTypeClass:
  429. t = t.lastSon
  430. result = n
  431. if t.kind == tyVar:
  432. result = newNodeIT(nkHiddenDeref, n.info, t.sons[0])
  433. addSon(result, n)
  434. t = skipTypes(t.sons[0], {tyGenericInst, tyAlias})
  435. while t.kind in {tyPtr, tyRef}:
  436. var a = result
  437. let baseTyp = t.lastSon
  438. result = newNodeIT(nkHiddenDeref, n.info, baseTyp)
  439. addSon(result, a)
  440. t = skipTypes(baseTyp, {tyGenericInst, tyAlias})
  441. proc fillPartialObject(c: PContext; n: PNode; typ: PType) =
  442. if n.len == 2:
  443. let x = semExprWithType(c, n[0])
  444. let y = considerQuotedIdent(n[1])
  445. let obj = x.typ.skipTypes(abstractPtrs)
  446. if obj.kind == tyObject and tfPartial in obj.flags:
  447. let field = newSym(skField, getIdent(y.s), obj.sym, n[1].info)
  448. field.typ = skipIntLit(typ)
  449. field.position = sonsLen(obj.n)
  450. addSon(obj.n, newSymNode(field))
  451. n.sons[0] = makeDeref x
  452. n.sons[1] = newSymNode(field)
  453. n.typ = field.typ
  454. else:
  455. localError(n.info, "implicit object field construction " &
  456. "requires a .partial object, but got " & typeToString(obj))
  457. else:
  458. localError(n.info, "nkDotNode requires 2 children")
  459. proc setVarType(v: PSym, typ: PType) =
  460. if v.typ != nil and not sameTypeOrNil(v.typ, typ):
  461. localError(v.info, "inconsistent typing for reintroduced symbol '" &
  462. v.name.s & "': previous type was: " & typeToString(v.typ) &
  463. "; new type is: " & typeToString(typ))
  464. v.typ = typ
  465. proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
  466. var b: PNode
  467. result = copyNode(n)
  468. var hasCompileTime = false
  469. for i in countup(0, sonsLen(n)-1):
  470. var a = n.sons[i]
  471. if gCmd == cmdIdeTools: suggestStmt(c, a)
  472. if a.kind == nkCommentStmt: continue
  473. if a.kind notin {nkIdentDefs, nkVarTuple, nkConstDef}: illFormedAst(a)
  474. checkMinSonsLen(a, 3)
  475. var length = sonsLen(a)
  476. var typ: PType
  477. if a.sons[length-2].kind != nkEmpty:
  478. typ = semTypeNode(c, a.sons[length-2], nil)
  479. else:
  480. typ = nil
  481. var def: PNode = ast.emptyNode
  482. if a.sons[length-1].kind != nkEmpty:
  483. def = semExprWithType(c, a.sons[length-1], {efAllowDestructor})
  484. if def.typ.kind == tyTypeDesc and c.p.owner.kind != skMacro:
  485. # prevent the all too common 'var x = int' bug:
  486. localError(def.info, "'typedesc' metatype is not valid here; typed '=' instead of ':'?")
  487. def.typ = errorType(c)
  488. if typ != nil:
  489. if typ.isMetaType:
  490. def = inferWithMetatype(c, typ, def)
  491. typ = def.typ
  492. else:
  493. # BUGFIX: ``fitNode`` is needed here!
  494. # check type compatibility between def.typ and typ
  495. def = fitNode(c, typ, def, def.info)
  496. #changeType(def.skipConv, typ, check=true)
  497. else:
  498. typ = skipIntLit(def.typ)
  499. if typ.kind in tyUserTypeClasses and typ.isResolvedUserTypeClass:
  500. typ = typ.lastSon
  501. if hasEmpty(typ):
  502. localError(def.info, errCannotInferTypeOfTheLiteral,
  503. ($typ.kind).substr(2).toLowerAscii)
  504. elif typ.kind == tyProc and tfUnresolved in typ.flags:
  505. localError(def.info, errProcHasNoConcreteType, def.renderTree)
  506. else:
  507. if symkind == skLet: localError(a.info, errLetNeedsInit)
  508. # this can only happen for errornous var statements:
  509. if typ == nil: continue
  510. typeAllowedCheck(a.info, typ, symkind)
  511. liftTypeBoundOps(c, typ, a.info)
  512. var tup = skipTypes(typ, {tyGenericInst, tyAlias})
  513. if a.kind == nkVarTuple:
  514. if tup.kind != tyTuple:
  515. localError(a.info, errXExpected, "tuple")
  516. elif length-2 != sonsLen(tup):
  517. localError(a.info, errWrongNumberOfVariables)
  518. else:
  519. b = newNodeI(nkVarTuple, a.info)
  520. newSons(b, length)
  521. b.sons[length-2] = a.sons[length-2] # keep type desc for doc generator
  522. b.sons[length-1] = def
  523. addToVarSection(c, result, n, b)
  524. elif tup.kind == tyTuple and def.kind == nkPar and
  525. a.kind == nkIdentDefs and a.len > 3:
  526. message(a.info, warnEachIdentIsTuple)
  527. for j in countup(0, length-3):
  528. if a[j].kind == nkDotExpr:
  529. fillPartialObject(c, a[j],
  530. if a.kind != nkVarTuple: typ else: tup.sons[j])
  531. addToVarSection(c, result, n, a)
  532. continue
  533. var v = semIdentDef(c, a.sons[j], symkind)
  534. if sfGenSym notin v.flags and not isDiscardUnderscore(v):
  535. addInterfaceDecl(c, v)
  536. when oKeepVariableNames:
  537. if c.inUnrolledContext > 0: v.flags.incl(sfShadowed)
  538. else:
  539. let shadowed = findShadowedVar(c, v)
  540. if shadowed != nil:
  541. shadowed.flags.incl(sfShadowed)
  542. if shadowed.kind == skResult and sfGenSym notin v.flags:
  543. message(a.info, warnResultShadowed)
  544. # a shadowed variable is an error unless it appears on the right
  545. # side of the '=':
  546. if warnShadowIdent in gNotes and not identWithin(def, v.name):
  547. message(a.info, warnShadowIdent, v.name.s)
  548. if a.kind != nkVarTuple:
  549. if def.kind != nkEmpty:
  550. # this is needed for the evaluation pass and for the guard checking:
  551. v.ast = def
  552. if sfThread in v.flags: localError(def.info, errThreadvarCannotInit)
  553. setVarType(v, typ)
  554. b = newNodeI(nkIdentDefs, a.info)
  555. if importantComments():
  556. # keep documentation information:
  557. b.comment = a.comment
  558. addSon(b, newSymNode(v))
  559. addSon(b, a.sons[length-2]) # keep type desc for doc generator
  560. addSon(b, copyTree(def))
  561. addToVarSection(c, result, n, b)
  562. else:
  563. if def.kind == nkPar: v.ast = def[j]
  564. setVarType(v, tup.sons[j])
  565. b.sons[j] = newSymNode(v)
  566. if not newDestructors: addDefer(c, result, v)
  567. checkNilable(v)
  568. if sfCompileTime in v.flags: hasCompileTime = true
  569. if hasCompileTime: vm.setupCompileTimeVar(c.module, c.cache, result)
  570. proc semConst(c: PContext, n: PNode): PNode =
  571. result = copyNode(n)
  572. for i in countup(0, sonsLen(n) - 1):
  573. var a = n.sons[i]
  574. if gCmd == cmdIdeTools: suggestStmt(c, a)
  575. if a.kind == nkCommentStmt: continue
  576. if (a.kind != nkConstDef): illFormedAst(a)
  577. checkSonsLen(a, 3)
  578. var v = semIdentDef(c, a.sons[0], skConst)
  579. var typ: PType = nil
  580. if a.sons[1].kind != nkEmpty: typ = semTypeNode(c, a.sons[1], nil)
  581. var def = semConstExpr(c, a.sons[2])
  582. if def == nil:
  583. localError(a.sons[2].info, errConstExprExpected)
  584. continue
  585. # check type compatibility between def.typ and typ:
  586. if typ != nil:
  587. def = fitRemoveHiddenConv(c, typ, def)
  588. else:
  589. typ = def.typ
  590. if typ == nil:
  591. localError(a.sons[2].info, errConstExprExpected)
  592. continue
  593. if typeAllowed(typ, skConst) != nil and def.kind != nkNilLit:
  594. localError(a.info, "invalid type for const: " & typeToString(typ))
  595. continue
  596. setVarType(v, typ)
  597. v.ast = def # no need to copy
  598. if sfGenSym notin v.flags: addInterfaceDecl(c, v)
  599. var b = newNodeI(nkConstDef, a.info)
  600. if importantComments(): b.comment = a.comment
  601. addSon(b, newSymNode(v))
  602. addSon(b, a.sons[1])
  603. addSon(b, copyTree(def))
  604. addSon(result, b)
  605. include semfields
  606. proc addForVarDecl(c: PContext, v: PSym) =
  607. if warnShadowIdent in gNotes:
  608. let shadowed = findShadowedVar(c, v)
  609. if shadowed != nil:
  610. # XXX should we do this here?
  611. #shadowed.flags.incl(sfShadowed)
  612. message(v.info, warnShadowIdent, v.name.s)
  613. addDecl(c, v)
  614. proc symForVar(c: PContext, n: PNode): PSym =
  615. let m = if n.kind == nkPragmaExpr: n.sons[0] else: n
  616. result = newSymG(skForVar, m, c)
  617. styleCheckDef(result)
  618. proc semForVars(c: PContext, n: PNode): PNode =
  619. result = n
  620. var length = sonsLen(n)
  621. let iterBase = n.sons[length-2].typ
  622. var iter = skipTypes(iterBase, {tyGenericInst, tyAlias})
  623. # length == 3 means that there is one for loop variable
  624. # and thus no tuple unpacking:
  625. if iter.kind != tyTuple or length == 3:
  626. if length == 3:
  627. var v = symForVar(c, n.sons[0])
  628. if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal)
  629. # BUGFIX: don't use `iter` here as that would strip away
  630. # the ``tyGenericInst``! See ``tests/compile/tgeneric.nim``
  631. # for an example:
  632. v.typ = iterBase
  633. n.sons[0] = newSymNode(v)
  634. if sfGenSym notin v.flags: addForVarDecl(c, v)
  635. else:
  636. localError(n.info, errWrongNumberOfVariables)
  637. elif length-2 != sonsLen(iter):
  638. localError(n.info, errWrongNumberOfVariables)
  639. else:
  640. for i in countup(0, length - 3):
  641. var v = symForVar(c, n.sons[i])
  642. if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal)
  643. v.typ = iter.sons[i]
  644. n.sons[i] = newSymNode(v)
  645. if sfGenSym notin v.flags and not isDiscardUnderscore(v):
  646. addForVarDecl(c, v)
  647. inc(c.p.nestedLoopCounter)
  648. n.sons[length-1] = semStmt(c, n.sons[length-1])
  649. dec(c.p.nestedLoopCounter)
  650. proc implicitIterator(c: PContext, it: string, arg: PNode): PNode =
  651. result = newNodeI(nkCall, arg.info)
  652. result.add(newIdentNode(it.getIdent, arg.info))
  653. if arg.typ != nil and arg.typ.kind == tyVar:
  654. result.add newDeref(arg)
  655. else:
  656. result.add arg
  657. result = semExprNoDeref(c, result, {efWantIterator})
  658. proc semFor(c: PContext, n: PNode): PNode =
  659. result = n
  660. checkMinSonsLen(n, 3)
  661. var length = sonsLen(n)
  662. openScope(c)
  663. n.sons[length-2] = semExprNoDeref(c, n.sons[length-2], {efWantIterator})
  664. var call = n.sons[length-2]
  665. let isCallExpr = call.kind in nkCallKinds
  666. if isCallExpr and call[0].kind == nkSym and
  667. call[0].sym.magic in {mFields, mFieldPairs, mOmpParFor}:
  668. if call.sons[0].sym.magic == mOmpParFor:
  669. result = semForVars(c, n)
  670. result.kind = nkParForStmt
  671. else:
  672. result = semForFields(c, n, call.sons[0].sym.magic)
  673. elif isCallExpr and call.sons[0].typ.callConv == ccClosure and
  674. tfIterator in call.sons[0].typ.flags:
  675. # first class iterator:
  676. result = semForVars(c, n)
  677. elif not isCallExpr or call.sons[0].kind != nkSym or
  678. call.sons[0].sym.kind != skIterator:
  679. if length == 3:
  680. n.sons[length-2] = implicitIterator(c, "items", n.sons[length-2])
  681. elif length == 4:
  682. n.sons[length-2] = implicitIterator(c, "pairs", n.sons[length-2])
  683. else:
  684. localError(n.sons[length-2].info, errIteratorExpected)
  685. result = semForVars(c, n)
  686. else:
  687. result = semForVars(c, n)
  688. # propagate any enforced VoidContext:
  689. if n.sons[length-1].typ == enforceVoidContext:
  690. result.typ = enforceVoidContext
  691. closeScope(c)
  692. proc semRaise(c: PContext, n: PNode): PNode =
  693. result = n
  694. checkSonsLen(n, 1)
  695. if n.sons[0].kind != nkEmpty:
  696. n.sons[0] = semExprWithType(c, n.sons[0])
  697. var typ = n.sons[0].typ
  698. if typ.kind != tyRef or typ.lastSon.kind != tyObject:
  699. localError(n.info, errExprCannotBeRaised)
  700. proc addGenericParamListToScope(c: PContext, n: PNode) =
  701. if n.kind != nkGenericParams: illFormedAst(n)
  702. for i in countup(0, sonsLen(n)-1):
  703. var a = n.sons[i]
  704. if a.kind == nkSym: addDecl(c, a.sym)
  705. else: illFormedAst(a)
  706. proc typeSectionLeftSidePass(c: PContext, n: PNode) =
  707. # process the symbols on the left side for the whole type section, before
  708. # we even look at the type definitions on the right
  709. for i in countup(0, sonsLen(n) - 1):
  710. var a = n.sons[i]
  711. when defined(nimsuggest):
  712. if gCmd == cmdIdeTools:
  713. inc c.inTypeContext
  714. suggestStmt(c, a)
  715. dec c.inTypeContext
  716. if a.kind == nkCommentStmt: continue
  717. if a.kind != nkTypeDef: illFormedAst(a)
  718. checkSonsLen(a, 3)
  719. let name = a.sons[0]
  720. var s: PSym
  721. if name.kind == nkDotExpr:
  722. s = qualifiedLookUp(c, name, {checkUndeclared, checkModule})
  723. if s.kind != skType or
  724. s.typ.skipTypes(abstractPtrs).kind != tyObject or
  725. tfPartial notin s.typ.skipTypes(abstractPtrs).flags:
  726. localError(name.info, "only .partial objects can be extended")
  727. else:
  728. s = semIdentDef(c, name, skType)
  729. s.typ = newTypeS(tyForward, c)
  730. s.typ.sym = s # process pragmas:
  731. if name.kind == nkPragmaExpr:
  732. pragma(c, s, name.sons[1], typePragmas)
  733. # add it here, so that recursive types are possible:
  734. if sfGenSym notin s.flags: addInterfaceDecl(c, s)
  735. a.sons[0] = newSymNode(s)
  736. proc checkCovariantParamsUsages(genericType: PType) =
  737. var body = genericType{-1}
  738. proc traverseSubTypes(t: PType): bool =
  739. template error(msg) = localError(genericType.sym.info, msg)
  740. result = false
  741. template subresult(r) =
  742. let sub = r
  743. result = result or sub
  744. case t.kind
  745. of tyGenericParam:
  746. t.flags.incl tfWeakCovariant
  747. return true
  748. of tyObject:
  749. for field in t.n:
  750. subresult traverseSubTypes(field.typ)
  751. of tyArray:
  752. return traverseSubTypes(t[1])
  753. of tyProc:
  754. for subType in t.sons:
  755. if subType != nil:
  756. subresult traverseSubTypes(subType)
  757. if result:
  758. error("non-invariant type param used in a proc type: " & $t)
  759. of tySequence:
  760. return traverseSubTypes(t[0])
  761. of tyGenericInvocation:
  762. let targetBody = t[0]
  763. for i in 1 .. <t.len:
  764. let param = t[i]
  765. if param.kind == tyGenericParam:
  766. if tfCovariant in param.flags:
  767. let formalFlags = targetBody[i-1].flags
  768. if tfCovariant notin formalFlags:
  769. error("covariant param '" & param.sym.name.s &
  770. "' used in a non-covariant position")
  771. elif tfWeakCovariant in formalFlags:
  772. param.flags.incl tfWeakCovariant
  773. result = true
  774. elif tfContravariant in param.flags:
  775. let formalParam = targetBody[i-1].sym
  776. if tfContravariant notin formalParam.typ.flags:
  777. error("contravariant param '" & param.sym.name.s &
  778. "' used in a non-contravariant position")
  779. result = true
  780. else:
  781. subresult traverseSubTypes(param)
  782. of tyAnd, tyOr, tyNot, tyStatic, tyBuiltInTypeClass, tyCompositeTypeClass:
  783. error("non-invariant type parameters cannot be used with types such '" & $t & "'")
  784. of tyUserTypeClass, tyUserTypeClassInst:
  785. error("non-invariant type parameters are not supported in concepts")
  786. of tyTuple:
  787. for fieldType in t.sons:
  788. subresult traverseSubTypes(fieldType)
  789. of tyPtr, tyRef, tyVar:
  790. if t.base.kind == tyGenericParam: return true
  791. return traverseSubTypes(t.base)
  792. of tyDistinct, tyAlias:
  793. return traverseSubTypes(t.lastSon)
  794. of tyGenericInst:
  795. internalAssert false
  796. else:
  797. discard
  798. discard traverseSubTypes(body)
  799. proc typeSectionRightSidePass(c: PContext, n: PNode) =
  800. for i in countup(0, sonsLen(n) - 1):
  801. var a = n.sons[i]
  802. if a.kind == nkCommentStmt: continue
  803. if (a.kind != nkTypeDef): illFormedAst(a)
  804. checkSonsLen(a, 3)
  805. let name = a.sons[0]
  806. if (name.kind != nkSym): illFormedAst(a)
  807. var s = name.sym
  808. if s.magic == mNone and a.sons[2].kind == nkEmpty:
  809. localError(a.info, errImplOfXexpected, s.name.s)
  810. if s.magic != mNone: processMagicType(c, s)
  811. if a.sons[1].kind != nkEmpty:
  812. # We have a generic type declaration here. In generic types,
  813. # symbol lookup needs to be done here.
  814. openScope(c)
  815. pushOwner(c, s)
  816. if s.magic == mNone: s.typ.kind = tyGenericBody
  817. # XXX for generic type aliases this is not correct! We need the
  818. # underlying Id really:
  819. #
  820. # type
  821. # TGObj[T] = object
  822. # TAlias[T] = TGObj[T]
  823. #
  824. s.typ.n = semGenericParamList(c, a.sons[1], s.typ)
  825. a.sons[1] = s.typ.n
  826. s.typ.size = -1 # could not be computed properly
  827. # we fill it out later. For magic generics like 'seq', it won't be filled
  828. # so we use tyNone instead of nil to not crash for strange conversions
  829. # like: mydata.seq
  830. rawAddSon(s.typ, newTypeS(tyNone, c))
  831. s.ast = a
  832. inc c.inGenericContext
  833. var body = semTypeNode(c, a.sons[2], nil)
  834. dec c.inGenericContext
  835. if body != nil:
  836. body.sym = s
  837. body.size = -1 # could not be computed properly
  838. s.typ.sons[sonsLen(s.typ) - 1] = body
  839. if tfCovariant in s.typ.flags:
  840. checkCovariantParamsUsages(s.typ)
  841. # XXX: This is a temporary limitation:
  842. # The codegen currently produces various failures with
  843. # generic imported types that have fields, but we need
  844. # the fields specified in order to detect weak covariance.
  845. # The proper solution is to teach the codegen how to handle
  846. # such types, because this would offer various interesting
  847. # possibilities such as instantiating C++ generic types with
  848. # garbage collected Nim types.
  849. if sfImportc in s.flags:
  850. var body = s.typ.lastSon
  851. if body.kind == tyObject:
  852. # erases all declared fields
  853. body.n.sons = nil
  854. popOwner(c)
  855. closeScope(c)
  856. elif a.sons[2].kind != nkEmpty:
  857. # process the type's body:
  858. pushOwner(c, s)
  859. var t = semTypeNode(c, a.sons[2], s.typ)
  860. if s.typ == nil:
  861. s.typ = t
  862. elif t != s.typ and (s.typ == nil or s.typ.kind != tyAlias):
  863. # this can happen for e.g. tcan_alias_specialised_generic:
  864. assignType(s.typ, t)
  865. #debug s.typ
  866. s.ast = a
  867. popOwner(c)
  868. let aa = a.sons[2]
  869. if aa.kind in {nkRefTy, nkPtrTy} and aa.len == 1 and
  870. aa.sons[0].kind == nkObjectTy:
  871. # give anonymous object a dummy symbol:
  872. var st = s.typ
  873. if st.kind == tyGenericBody: st = st.lastSon
  874. internalAssert st.kind in {tyPtr, tyRef}
  875. internalAssert st.lastSon.sym == nil
  876. incl st.flags, tfRefsAnonObj
  877. let obj = newSym(skType, getIdent(s.name.s & ":ObjectType"),
  878. getCurrOwner(c), s.info)
  879. obj.typ = st.lastSon
  880. st.lastSon.sym = obj
  881. proc checkForMetaFields(n: PNode) =
  882. template checkMeta(t) =
  883. if t != nil and t.isMetaType and tfGenericTypeParam notin t.flags:
  884. localError(n.info, errTIsNotAConcreteType, t.typeToString)
  885. if n.isNil: return
  886. case n.kind
  887. of nkRecList, nkRecCase:
  888. for s in n: checkForMetaFields(s)
  889. of nkOfBranch, nkElse:
  890. checkForMetaFields(n.lastSon)
  891. of nkSym:
  892. let t = n.sym.typ
  893. case t.kind
  894. of tySequence, tySet, tyArray, tyOpenArray, tyVar, tyPtr, tyRef,
  895. tyProc, tyGenericInvocation, tyGenericInst, tyAlias:
  896. let start = ord(t.kind in {tyGenericInvocation, tyGenericInst})
  897. for i in start .. <t.sons.len:
  898. checkMeta(t.sons[i])
  899. else:
  900. checkMeta(t)
  901. else:
  902. internalAssert false
  903. proc typeSectionFinalPass(c: PContext, n: PNode) =
  904. for i in countup(0, sonsLen(n) - 1):
  905. var a = n.sons[i]
  906. if a.kind == nkCommentStmt: continue
  907. if a.sons[0].kind != nkSym: illFormedAst(a)
  908. var s = a.sons[0].sym
  909. # compute the type's size and check for illegal recursions:
  910. if a.sons[1].kind == nkEmpty:
  911. var x = a[2]
  912. while x.kind in {nkStmtList, nkStmtListExpr} and x.len > 0:
  913. x = x.lastSon
  914. if x.kind notin {nkObjectTy, nkDistinctTy, nkEnumTy, nkEmpty} and
  915. s.typ.kind notin {tyObject, tyEnum}:
  916. # type aliases are hard:
  917. var t = semTypeNode(c, x, nil)
  918. assert t != nil
  919. if s.typ != nil and s.typ.kind != tyAlias:
  920. if t.kind in {tyProc, tyGenericInst} and not t.isMetaType:
  921. assignType(s.typ, t)
  922. s.typ.id = t.id
  923. elif t.kind in {tyObject, tyEnum, tyDistinct}:
  924. assert s.typ != nil
  925. assignType(s.typ, t)
  926. s.typ.id = t.id # same id
  927. checkConstructedType(s.info, s.typ)
  928. if s.typ.kind in {tyObject, tyTuple} and not s.typ.n.isNil:
  929. checkForMetaFields(s.typ.n)
  930. proc semAllTypeSections(c: PContext; n: PNode): PNode =
  931. proc gatherStmts(c: PContext; n: PNode; result: PNode) {.nimcall.} =
  932. case n.kind
  933. of nkIncludeStmt:
  934. for i in 0..<n.len:
  935. var f = checkModuleName(n.sons[i])
  936. if f != InvalidFileIDX:
  937. if containsOrIncl(c.includedFiles, f):
  938. localError(n.info, errRecursiveDependencyX, f.toFilename)
  939. else:
  940. let code = gIncludeFile(c.graph, c.module, f, c.cache)
  941. gatherStmts c, code, result
  942. excl(c.includedFiles, f)
  943. of nkStmtList:
  944. for i in 0 ..< n.len:
  945. gatherStmts(c, n.sons[i], result)
  946. of nkTypeSection:
  947. incl n.flags, nfSem
  948. typeSectionLeftSidePass(c, n)
  949. result.add n
  950. else:
  951. result.add n
  952. result = newNodeI(nkStmtList, n.info)
  953. gatherStmts(c, n, result)
  954. template rec(name) =
  955. for i in 0 ..< result.len:
  956. if result[i].kind == nkTypeSection:
  957. name(c, result[i])
  958. rec typeSectionRightSidePass
  959. rec typeSectionFinalPass
  960. when false:
  961. # too beautiful to delete:
  962. template rec(name; setbit=false) =
  963. proc `name rec`(c: PContext; n: PNode) {.nimcall.} =
  964. if n.kind == nkTypeSection:
  965. when setbit: incl n.flags, nfSem
  966. name(c, n)
  967. elif n.kind == nkStmtList:
  968. for i in 0 ..< n.len:
  969. `name rec`(c, n.sons[i])
  970. `name rec`(c, n)
  971. rec typeSectionLeftSidePass, true
  972. rec typeSectionRightSidePass
  973. rec typeSectionFinalPass
  974. proc semTypeSection(c: PContext, n: PNode): PNode =
  975. ## Processes a type section. This must be done in separate passes, in order
  976. ## to allow the type definitions in the section to reference each other
  977. ## without regard for the order of their definitions.
  978. if sfNoForward notin c.module.flags or nfSem notin n.flags:
  979. typeSectionLeftSidePass(c, n)
  980. typeSectionRightSidePass(c, n)
  981. typeSectionFinalPass(c, n)
  982. result = n
  983. proc semParamList(c: PContext, n, genericParams: PNode, s: PSym) =
  984. s.typ = semProcTypeNode(c, n, genericParams, nil, s.kind)
  985. if s.kind notin {skMacro, skTemplate}:
  986. if s.typ.sons[0] != nil and s.typ.sons[0].kind == tyStmt:
  987. localError(n.info, errGenerated, "invalid return type: 'stmt'")
  988. proc addParams(c: PContext, n: PNode, kind: TSymKind) =
  989. for i in countup(1, sonsLen(n)-1):
  990. if n.sons[i].kind == nkSym: addParamOrResult(c, n.sons[i].sym, kind)
  991. else: illFormedAst(n)
  992. proc semBorrow(c: PContext, n: PNode, s: PSym) =
  993. # search for the correct alias:
  994. var b = searchForBorrowProc(c, c.currentScope.parent, s)
  995. if b != nil:
  996. # store the alias:
  997. n.sons[bodyPos] = newSymNode(b)
  998. else:
  999. localError(n.info, errNoSymbolToBorrowFromFound)
  1000. proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind) =
  1001. if t != nil:
  1002. var s = newSym(skResult, getIdent"result", getCurrOwner(c), info)
  1003. s.typ = t
  1004. incl(s.flags, sfUsed)
  1005. addParamOrResult(c, s, owner)
  1006. c.p.resultSym = s
  1007. proc addResultNode(c: PContext, n: PNode) =
  1008. if c.p.resultSym != nil: addSon(n, newSymNode(c.p.resultSym))
  1009. proc copyExcept(n: PNode, i: int): PNode =
  1010. result = copyNode(n)
  1011. for j in 0.. <n.len:
  1012. if j != i: result.add(n.sons[j])
  1013. proc lookupMacro(c: PContext, n: PNode): PSym =
  1014. if n.kind == nkSym:
  1015. result = n.sym
  1016. if result.kind notin {skMacro, skTemplate}: result = nil
  1017. else:
  1018. result = searchInScopes(c, considerQuotedIdent(n), {skMacro, skTemplate})
  1019. proc semProcAnnotation(c: PContext, prc: PNode;
  1020. validPragmas: TSpecialWords): PNode =
  1021. var n = prc.sons[pragmasPos]
  1022. if n == nil or n.kind == nkEmpty: return
  1023. for i in countup(0, <n.len):
  1024. var it = n.sons[i]
  1025. var key = if it.kind == nkExprColonExpr: it.sons[0] else: it
  1026. let m = lookupMacro(c, key)
  1027. if m == nil:
  1028. if key.kind == nkIdent and key.ident.id == ord(wDelegator):
  1029. if considerQuotedIdent(prc.sons[namePos]).s == "()":
  1030. prc.sons[namePos] = newIdentNode(c.cache.idDelegator, prc.info)
  1031. prc.sons[pragmasPos] = copyExcept(n, i)
  1032. else:
  1033. localError(prc.info, errOnlyACallOpCanBeDelegator)
  1034. continue
  1035. # we transform ``proc p {.m, rest.}`` into ``m(do: proc p {.rest.})`` and
  1036. # let the semantic checker deal with it:
  1037. var x = newNodeI(nkCall, n.info)
  1038. x.add(newSymNode(m))
  1039. prc.sons[pragmasPos] = copyExcept(n, i)
  1040. if prc[pragmasPos].kind != nkEmpty and prc[pragmasPos].len == 0:
  1041. prc.sons[pragmasPos] = emptyNode
  1042. if it.kind == nkExprColonExpr:
  1043. # pass pragma argument to the macro too:
  1044. x.add(it.sons[1])
  1045. x.add(prc)
  1046. # recursion assures that this works for multiple macro annotations too:
  1047. result = semExpr(c, x)
  1048. # since a proc annotation can set pragmas, we process these here again.
  1049. # This is required for SqueakNim-like export pragmas.
  1050. if result.kind in procDefs and result[namePos].kind == nkSym and
  1051. result[pragmasPos].kind != nkEmpty:
  1052. pragma(c, result[namePos].sym, result[pragmasPos], validPragmas)
  1053. return
  1054. proc setGenericParamsMisc(c: PContext; n: PNode): PNode =
  1055. let orig = n.sons[genericParamsPos]
  1056. # we keep the original params around for better error messages, see
  1057. # issue https://github.com/nim-lang/Nim/issues/1713
  1058. result = semGenericParamList(c, orig)
  1059. if n.sons[miscPos].kind == nkEmpty:
  1060. n.sons[miscPos] = newTree(nkBracket, ast.emptyNode, orig)
  1061. else:
  1062. n.sons[miscPos].sons[1] = orig
  1063. n.sons[genericParamsPos] = result
  1064. proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
  1065. # XXX semProcAux should be good enough for this now, we will eventually
  1066. # remove semLambda
  1067. result = semProcAnnotation(c, n, lambdaPragmas)
  1068. if result != nil: return result
  1069. result = n
  1070. checkSonsLen(n, bodyPos + 1)
  1071. var s: PSym
  1072. if n[namePos].kind != nkSym:
  1073. s = newSym(skProc, c.cache.idAnon, getCurrOwner(c), n.info)
  1074. s.ast = n
  1075. n.sons[namePos] = newSymNode(s)
  1076. else:
  1077. s = n[namePos].sym
  1078. pushOwner(c, s)
  1079. openScope(c)
  1080. var gp: PNode
  1081. if n.sons[genericParamsPos].kind != nkEmpty:
  1082. gp = setGenericParamsMisc(c, n)
  1083. else:
  1084. gp = newNodeI(nkGenericParams, n.info)
  1085. if n.sons[paramsPos].kind != nkEmpty:
  1086. #if n.kind == nkDo and not experimentalMode(c):
  1087. # localError(n.sons[paramsPos].info,
  1088. # "use the {.experimental.} pragma to enable 'do' with parameters")
  1089. semParamList(c, n.sons[paramsPos], gp, s)
  1090. # paramsTypeCheck(c, s.typ)
  1091. if sonsLen(gp) > 0 and n.sons[genericParamsPos].kind == nkEmpty:
  1092. # we have a list of implicit type parameters:
  1093. n.sons[genericParamsPos] = gp
  1094. else:
  1095. s.typ = newProcType(c, n.info)
  1096. if n.sons[pragmasPos].kind != nkEmpty:
  1097. pragma(c, s, n.sons[pragmasPos], lambdaPragmas)
  1098. s.options = gOptions
  1099. if n.sons[bodyPos].kind != nkEmpty:
  1100. if sfImportc in s.flags:
  1101. localError(n.sons[bodyPos].info, errImplOfXNotAllowed, s.name.s)
  1102. #if efDetermineType notin flags:
  1103. # XXX not good enough; see tnamedparamanonproc.nim
  1104. if gp.len == 0 or (gp.len == 1 and tfRetType in gp[0].typ.flags):
  1105. pushProcCon(c, s)
  1106. addResult(c, s.typ.sons[0], n.info, skProc)
  1107. addResultNode(c, n)
  1108. let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
  1109. n.sons[bodyPos] = transformBody(c.module, semBody, s)
  1110. popProcCon(c)
  1111. elif efOperand notin flags:
  1112. localError(n.info, errGenericLambdaNotAllowed)
  1113. sideEffectsCheck(c, s)
  1114. else:
  1115. localError(n.info, errImplOfXexpected, s.name.s)
  1116. closeScope(c) # close scope for parameters
  1117. popOwner(c)
  1118. result.typ = s.typ
  1119. proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode =
  1120. var n = n
  1121. let original = n.sons[namePos].sym
  1122. let s = original #copySym(original, false)
  1123. #incl(s.flags, sfFromGeneric)
  1124. #s.owner = original
  1125. n = replaceTypesInBody(c, pt, n, original)
  1126. result = n
  1127. s.ast = result
  1128. n.sons[namePos].sym = s
  1129. n.sons[genericParamsPos] = emptyNode
  1130. # for LL we need to avoid wrong aliasing
  1131. let params = copyTree n.typ.n
  1132. n.sons[paramsPos] = params
  1133. s.typ = n.typ
  1134. for i in 1..<params.len:
  1135. if params[i].typ.kind in {tyTypeDesc, tyGenericParam,
  1136. tyFromExpr}+tyTypeClasses:
  1137. localError(params[i].info, "cannot infer type of parameter: " &
  1138. params[i].sym.name.s)
  1139. #params[i].sym.owner = s
  1140. openScope(c)
  1141. pushOwner(c, s)
  1142. addParams(c, params, skProc)
  1143. pushProcCon(c, s)
  1144. addResult(c, n.typ.sons[0], n.info, skProc)
  1145. addResultNode(c, n)
  1146. let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
  1147. n.sons[bodyPos] = transformBody(c.module, semBody, s)
  1148. popProcCon(c)
  1149. popOwner(c)
  1150. closeScope(c)
  1151. # alternative variant (not quite working):
  1152. # var prc = arg[0].sym
  1153. # let inferred = c.semGenerateInstance(c, prc, m.bindings, arg.info)
  1154. # result = inferred.ast
  1155. # result.kind = arg.kind
  1156. proc activate(c: PContext, n: PNode) =
  1157. # XXX: This proc is part of my plan for getting rid of
  1158. # forward declarations. stay tuned.
  1159. when false:
  1160. # well for now it breaks code ...
  1161. case n.kind
  1162. of nkLambdaKinds:
  1163. discard semLambda(c, n, {})
  1164. of nkCallKinds:
  1165. for i in 1 .. <n.len: activate(c, n[i])
  1166. else:
  1167. discard
  1168. proc maybeAddResult(c: PContext, s: PSym, n: PNode) =
  1169. if s.typ.sons[0] != nil and not
  1170. (s.kind == skIterator and s.typ.callConv != ccClosure):
  1171. addResult(c, s.typ.sons[0], n.info, s.kind)
  1172. addResultNode(c, n)
  1173. proc semOverride(c: PContext, s: PSym, n: PNode) =
  1174. case s.name.s.normalize
  1175. of "destroy", "=destroy":
  1176. if newDestructors:
  1177. let t = s.typ
  1178. var noError = false
  1179. if t.len == 2 and t.sons[0] == nil and t.sons[1].kind == tyVar:
  1180. var obj = t.sons[1].sons[0]
  1181. while true:
  1182. incl(obj.flags, tfHasAsgn)
  1183. if obj.kind == tyGenericBody: obj = obj.lastSon
  1184. elif obj.kind == tyGenericInvocation: obj = obj.sons[0]
  1185. else: break
  1186. if obj.kind in {tyObject, tyDistinct}:
  1187. if obj.destructor.isNil:
  1188. obj.destructor = s
  1189. else:
  1190. localError(n.info, errGenerated,
  1191. "cannot bind another '" & s.name.s & "' to: " & typeToString(obj))
  1192. noError = true
  1193. if not noError and sfSystemModule notin s.owner.flags:
  1194. localError(n.info, errGenerated,
  1195. "signature for '" & s.name.s & "' must be proc[T: object](x: var T)")
  1196. else:
  1197. doDestructorStuff(c, s, n)
  1198. if not experimentalMode(c):
  1199. localError n.info, "use the {.experimental.} pragma to enable destructors"
  1200. incl(s.flags, sfUsed)
  1201. of "deepcopy", "=deepcopy":
  1202. if s.typ.len == 2 and
  1203. s.typ.sons[1].skipTypes(abstractInst).kind in {tyRef, tyPtr} and
  1204. sameType(s.typ.sons[1], s.typ.sons[0]):
  1205. # Note: we store the deepCopy in the base of the pointer to mitigate
  1206. # the problem that pointers are structural types:
  1207. var t = s.typ.sons[1].skipTypes(abstractInst).lastSon.skipTypes(abstractInst)
  1208. while true:
  1209. if t.kind == tyGenericBody: t = t.lastSon
  1210. elif t.kind == tyGenericInvocation: t = t.sons[0]
  1211. else: break
  1212. if t.kind in {tyObject, tyDistinct, tyEnum}:
  1213. if t.deepCopy.isNil: t.deepCopy = s
  1214. else:
  1215. localError(n.info, errGenerated,
  1216. "cannot bind another 'deepCopy' to: " & typeToString(t))
  1217. else:
  1218. localError(n.info, errGenerated,
  1219. "cannot bind 'deepCopy' to: " & typeToString(t))
  1220. else:
  1221. localError(n.info, errGenerated,
  1222. "signature for 'deepCopy' must be proc[T: ptr|ref](x: T): T")
  1223. incl(s.flags, sfUsed)
  1224. of "=", "=sink":
  1225. if s.magic == mAsgn: return
  1226. incl(s.flags, sfUsed)
  1227. let t = s.typ
  1228. if t.len == 3 and t.sons[0] == nil and t.sons[1].kind == tyVar:
  1229. var obj = t.sons[1].sons[0]
  1230. while true:
  1231. incl(obj.flags, tfHasAsgn)
  1232. if obj.kind == tyGenericBody: obj = obj.lastSon
  1233. elif obj.kind == tyGenericInvocation: obj = obj.sons[0]
  1234. else: break
  1235. var objB = t.sons[2]
  1236. while true:
  1237. if objB.kind == tyGenericBody: objB = objB.lastSon
  1238. elif objB.kind in {tyGenericInvocation, tyGenericInst}:
  1239. objB = objB.sons[0]
  1240. else: break
  1241. if obj.kind in {tyObject, tyDistinct} and sameType(obj, objB):
  1242. let opr = if s.name.s == "=": addr(obj.assignment) else: addr(obj.sink)
  1243. if opr[].isNil:
  1244. opr[] = s
  1245. else:
  1246. localError(n.info, errGenerated,
  1247. "cannot bind another '" & s.name.s & "' to: " & typeToString(obj))
  1248. return
  1249. if sfSystemModule notin s.owner.flags:
  1250. localError(n.info, errGenerated,
  1251. "signature for '" & s.name.s & "' must be proc[T: object](x: var T; y: T)")
  1252. else:
  1253. if sfOverriden in s.flags:
  1254. localError(n.info, errGenerated,
  1255. "'destroy' or 'deepCopy' expected for 'override'")
  1256. proc cursorInProcAux(n: PNode): bool =
  1257. if inCheckpoint(n.info) != cpNone: return true
  1258. for i in 0..<n.safeLen:
  1259. if cursorInProcAux(n[i]): return true
  1260. proc cursorInProc(n: PNode): bool =
  1261. if n.info.fileIndex == gTrackPos.fileIndex:
  1262. result = cursorInProcAux(n)
  1263. type
  1264. TProcCompilationSteps = enum
  1265. stepRegisterSymbol,
  1266. stepDetermineType,
  1267. proc hasObjParam(s: PSym): bool =
  1268. var t = s.typ
  1269. for col in countup(1, sonsLen(t)-1):
  1270. if skipTypes(t.sons[col], skipPtrs).kind == tyObject:
  1271. return true
  1272. proc finishMethod(c: PContext, s: PSym) =
  1273. if hasObjParam(s):
  1274. methodDef(c.graph, s, false)
  1275. proc semMethodPrototype(c: PContext; s: PSym; n: PNode) =
  1276. if isGenericRoutine(s):
  1277. let tt = s.typ
  1278. var foundObj = false
  1279. # we start at 1 for now so that tparsecombnum continues to compile.
  1280. # XXX Revisit this problem later.
  1281. for col in countup(1, sonsLen(tt)-1):
  1282. let t = tt.sons[col]
  1283. if t != nil and t.kind == tyGenericInvocation:
  1284. var x = skipTypes(t.sons[0], {tyVar, tyPtr, tyRef, tyGenericInst,
  1285. tyGenericInvocation, tyGenericBody,
  1286. tyAlias})
  1287. if x.kind == tyObject and t.len-1 == n.sons[genericParamsPos].len:
  1288. foundObj = true
  1289. x.methods.safeAdd((col,s))
  1290. if not foundObj:
  1291. message(n.info, warnDeprecated, "generic method not attachable to object type")
  1292. else:
  1293. # why check for the body? bug #2400 has none. Checking for sfForward makes
  1294. # no sense either.
  1295. # and result.sons[bodyPos].kind != nkEmpty:
  1296. if hasObjParam(s):
  1297. methodDef(c.graph, s, fromCache=false)
  1298. else:
  1299. localError(n.info, errXNeedsParamObjectType, "method")
  1300. proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
  1301. validPragmas: TSpecialWords,
  1302. phase = stepRegisterSymbol): PNode =
  1303. result = semProcAnnotation(c, n, validPragmas)
  1304. if result != nil: return result
  1305. result = n
  1306. checkSonsLen(n, bodyPos + 1)
  1307. var s: PSym
  1308. var typeIsDetermined = false
  1309. var isAnon = false
  1310. if n[namePos].kind != nkSym:
  1311. assert phase == stepRegisterSymbol
  1312. if n[namePos].kind == nkEmpty:
  1313. s = newSym(kind, c.cache.idAnon, getCurrOwner(c), n.info)
  1314. incl(s.flags, sfUsed)
  1315. isAnon = true
  1316. else:
  1317. s = semIdentDef(c, n.sons[0], kind)
  1318. n.sons[namePos] = newSymNode(s)
  1319. s.ast = n
  1320. #s.scope = c.currentScope
  1321. when false:
  1322. # disable for now
  1323. if sfNoForward in c.module.flags and
  1324. sfSystemModule notin c.module.flags:
  1325. addInterfaceOverloadableSymAt(c, c.currentScope, s)
  1326. s.flags.incl sfForward
  1327. return
  1328. else:
  1329. s = n[namePos].sym
  1330. s.owner = getCurrOwner(c)
  1331. typeIsDetermined = s.typ == nil
  1332. s.ast = n
  1333. #s.scope = c.currentScope
  1334. # before compiling the proc body, set as current the scope
  1335. # where the proc was declared
  1336. let oldScope = c.currentScope
  1337. #c.currentScope = s.scope
  1338. pushOwner(c, s)
  1339. openScope(c)
  1340. var gp: PNode
  1341. if n.sons[genericParamsPos].kind != nkEmpty:
  1342. gp = setGenericParamsMisc(c, n)
  1343. else:
  1344. gp = newNodeI(nkGenericParams, n.info)
  1345. # process parameters:
  1346. if n.sons[paramsPos].kind != nkEmpty:
  1347. semParamList(c, n.sons[paramsPos], gp, s)
  1348. if sonsLen(gp) > 0:
  1349. if n.sons[genericParamsPos].kind == nkEmpty:
  1350. # we have a list of implicit type parameters:
  1351. n.sons[genericParamsPos] = gp
  1352. # check for semantics again:
  1353. # semParamList(c, n.sons[ParamsPos], nil, s)
  1354. else:
  1355. s.typ = newProcType(c, n.info)
  1356. if tfTriggersCompileTime in s.typ.flags: incl(s.flags, sfCompileTime)
  1357. if n.sons[patternPos].kind != nkEmpty:
  1358. n.sons[patternPos] = semPattern(c, n.sons[patternPos])
  1359. if s.kind == skIterator:
  1360. s.typ.flags.incl(tfIterator)
  1361. var proto = searchForProc(c, oldScope, s)
  1362. if proto == nil or isAnon:
  1363. if s.kind == skIterator:
  1364. if s.typ.callConv != ccClosure:
  1365. s.typ.callConv = if isAnon: ccClosure else: ccInline
  1366. else:
  1367. s.typ.callConv = lastOptionEntry(c).defaultCC
  1368. # add it here, so that recursive procs are possible:
  1369. if sfGenSym in s.flags: discard
  1370. elif kind in OverloadableSyms:
  1371. if not typeIsDetermined:
  1372. addInterfaceOverloadableSymAt(c, oldScope, s)
  1373. else:
  1374. if not typeIsDetermined:
  1375. addInterfaceDeclAt(c, oldScope, s)
  1376. if n.sons[pragmasPos].kind != nkEmpty:
  1377. pragma(c, s, n.sons[pragmasPos], validPragmas)
  1378. else:
  1379. implicitPragmas(c, s, n, validPragmas)
  1380. else:
  1381. if n.sons[pragmasPos].kind != nkEmpty:
  1382. pragma(c, s, n.sons[pragmasPos], validPragmas)
  1383. # To ease macro generation that produce forwarded .async procs we now
  1384. # allow a bit redudancy in the pragma declarations. The rule is
  1385. # a prototype's pragma list must be a superset of the current pragma
  1386. # list.
  1387. # XXX This needs more checks eventually, for example that external
  1388. # linking names do agree:
  1389. if proto.typ.callConv != s.typ.callConv or proto.typ.flags < s.typ.flags:
  1390. localError(n.sons[pragmasPos].info, errPragmaOnlyInHeaderOfProcX,
  1391. "'" & proto.name.s & "' from " & $proto.info)
  1392. if sfForward notin proto.flags:
  1393. wrongRedefinition(n.info, proto.name.s)
  1394. excl(proto.flags, sfForward)
  1395. closeScope(c) # close scope with wrong parameter symbols
  1396. openScope(c) # open scope for old (correct) parameter symbols
  1397. if proto.ast.sons[genericParamsPos].kind != nkEmpty:
  1398. addGenericParamListToScope(c, proto.ast.sons[genericParamsPos])
  1399. addParams(c, proto.typ.n, proto.kind)
  1400. proto.info = s.info # more accurate line information
  1401. s.typ = proto.typ
  1402. s = proto
  1403. n.sons[genericParamsPos] = proto.ast.sons[genericParamsPos]
  1404. n.sons[paramsPos] = proto.ast.sons[paramsPos]
  1405. n.sons[pragmasPos] = proto.ast.sons[pragmasPos]
  1406. if n.sons[namePos].kind != nkSym: internalError(n.info, "semProcAux")
  1407. n.sons[namePos].sym = proto
  1408. if importantComments() and not isNil(proto.ast.comment):
  1409. n.comment = proto.ast.comment
  1410. proto.ast = n # needed for code generation
  1411. popOwner(c)
  1412. pushOwner(c, s)
  1413. s.options = gOptions
  1414. if sfOverriden in s.flags or s.name.s[0] == '=': semOverride(c, s, n)
  1415. if s.name.s[0] in {'.', '('}:
  1416. if s.name.s in [".", ".()", ".=", "()"] and not experimentalMode(c):
  1417. message(n.info, warnDeprecated, "overloaded '.' and '()' operators are now .experimental; " & s.name.s)
  1418. if n.sons[bodyPos].kind != nkEmpty:
  1419. # for DLL generation it is annoying to check for sfImportc!
  1420. if sfBorrow in s.flags:
  1421. localError(n.sons[bodyPos].info, errImplOfXNotAllowed, s.name.s)
  1422. let usePseudoGenerics = kind in {skMacro, skTemplate}
  1423. # Macros and Templates can have generic parameters, but they are
  1424. # only used for overload resolution (there is no instantiation of
  1425. # the symbol, so we must process the body now)
  1426. if not usePseudoGenerics and gIdeCmd in {ideSug, ideCon} and not
  1427. cursorInProc(n.sons[bodyPos]):
  1428. discard "speed up nimsuggest"
  1429. if s.kind == skMethod: semMethodPrototype(c, s, n)
  1430. else:
  1431. pushProcCon(c, s)
  1432. if n.sons[genericParamsPos].kind == nkEmpty or usePseudoGenerics:
  1433. if not usePseudoGenerics: paramsTypeCheck(c, s.typ)
  1434. c.p.wasForwarded = proto != nil
  1435. maybeAddResult(c, s, n)
  1436. if s.kind == skMethod: semMethodPrototype(c, s, n)
  1437. if lfDynamicLib notin s.loc.flags:
  1438. # no semantic checking for importc:
  1439. let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
  1440. # unfortunately we cannot skip this step when in 'system.compiles'
  1441. # context as it may even be evaluated in 'system.compiles':
  1442. n.sons[bodyPos] = transformBody(c.module, semBody, s)
  1443. else:
  1444. if s.typ.sons[0] != nil and kind != skIterator:
  1445. addDecl(c, newSym(skUnknown, getIdent"result", nil, n.info))
  1446. openScope(c)
  1447. n.sons[bodyPos] = semGenericStmt(c, n.sons[bodyPos])
  1448. closeScope(c)
  1449. fixupInstantiatedSymbols(c, s)
  1450. if s.kind == skMethod: semMethodPrototype(c, s, n)
  1451. if sfImportc in s.flags:
  1452. # so we just ignore the body after semantic checking for importc:
  1453. n.sons[bodyPos] = ast.emptyNode
  1454. popProcCon(c)
  1455. else:
  1456. if s.kind == skMethod: semMethodPrototype(c, s, n)
  1457. if proto != nil: localError(n.info, errImplOfXexpected, proto.name.s)
  1458. if {sfImportc, sfBorrow} * s.flags == {} and s.magic == mNone:
  1459. incl(s.flags, sfForward)
  1460. elif sfBorrow in s.flags: semBorrow(c, n, s)
  1461. sideEffectsCheck(c, s)
  1462. closeScope(c) # close scope for parameters
  1463. # c.currentScope = oldScope
  1464. popOwner(c)
  1465. if n.sons[patternPos].kind != nkEmpty:
  1466. c.patterns.add(s)
  1467. if isAnon:
  1468. n.kind = nkLambda
  1469. result.typ = s.typ
  1470. if isTopLevel(c) and s.kind != skIterator and
  1471. s.typ.callConv == ccClosure:
  1472. localError(s.info, "'.closure' calling convention for top level routines is invalid")
  1473. proc determineType(c: PContext, s: PSym) =
  1474. if s.typ != nil: return
  1475. #if s.magic != mNone: return
  1476. #if s.ast.isNil: return
  1477. discard semProcAux(c, s.ast, s.kind, {}, stepDetermineType)
  1478. proc semIterator(c: PContext, n: PNode): PNode =
  1479. # gensym'ed iterator?
  1480. let isAnon = n[namePos].kind == nkEmpty
  1481. if n[namePos].kind == nkSym:
  1482. # gensym'ed iterators might need to become closure iterators:
  1483. n[namePos].sym.owner = getCurrOwner(c)
  1484. n[namePos].sym.kind = skIterator
  1485. result = semProcAux(c, n, skIterator, iteratorPragmas)
  1486. var s = result.sons[namePos].sym
  1487. var t = s.typ
  1488. if t.sons[0] == nil and s.typ.callConv != ccClosure:
  1489. localError(n.info, errXNeedsReturnType, "iterator")
  1490. if isAnon and s.typ.callConv == ccInline:
  1491. localError(n.info, "inline iterators are not first-class / cannot be assigned to variables")
  1492. # iterators are either 'inline' or 'closure'; for backwards compatibility,
  1493. # we require first class iterators to be marked with 'closure' explicitly
  1494. # -- at least for 0.9.2.
  1495. if s.typ.callConv == ccClosure:
  1496. incl(s.typ.flags, tfCapturesEnv)
  1497. else:
  1498. s.typ.callConv = ccInline
  1499. when false:
  1500. if s.typ.callConv != ccInline:
  1501. s.typ.callConv = ccClosure
  1502. # and they always at least use the 'env' for the state field:
  1503. incl(s.typ.flags, tfCapturesEnv)
  1504. if n.sons[bodyPos].kind == nkEmpty and s.magic == mNone:
  1505. localError(n.info, errImplOfXexpected, s.name.s)
  1506. proc semProc(c: PContext, n: PNode): PNode =
  1507. result = semProcAux(c, n, skProc, procPragmas)
  1508. proc semFunc(c: PContext, n: PNode): PNode =
  1509. result = semProcAux(c, n, skFunc, procPragmas)
  1510. proc semMethod(c: PContext, n: PNode): PNode =
  1511. if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "method")
  1512. result = semProcAux(c, n, skMethod, methodPragmas)
  1513. # macros can transform converters to nothing:
  1514. if namePos >= result.safeLen: return result
  1515. var s = result.sons[namePos].sym
  1516. # we need to fix the 'auto' return type for the dispatcher here (see tautonotgeneric
  1517. # test case):
  1518. let disp = getDispatcher(s)
  1519. # auto return type?
  1520. if disp != nil and disp.typ.sons[0] != nil and disp.typ.sons[0].kind == tyExpr:
  1521. let ret = s.typ.sons[0]
  1522. disp.typ.sons[0] = ret
  1523. if disp.ast[resultPos].kind == nkSym:
  1524. if isEmptyType(ret): disp.ast.sons[resultPos] = emptyNode
  1525. else: disp.ast[resultPos].sym.typ = ret
  1526. proc semConverterDef(c: PContext, n: PNode): PNode =
  1527. if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "converter")
  1528. checkSonsLen(n, bodyPos + 1)
  1529. result = semProcAux(c, n, skConverter, converterPragmas)
  1530. # macros can transform converters to nothing:
  1531. if namePos >= result.safeLen: return result
  1532. var s = result.sons[namePos].sym
  1533. var t = s.typ
  1534. if t.sons[0] == nil: localError(n.info, errXNeedsReturnType, "converter")
  1535. if sonsLen(t) != 2: localError(n.info, errXRequiresOneArgument, "converter")
  1536. addConverter(c, s)
  1537. proc semMacroDef(c: PContext, n: PNode): PNode =
  1538. checkSonsLen(n, bodyPos + 1)
  1539. result = semProcAux(c, n, skMacro, macroPragmas)
  1540. # macros can transform macros to nothing:
  1541. if namePos >= result.safeLen: return result
  1542. var s = result.sons[namePos].sym
  1543. var t = s.typ
  1544. var allUntyped = true
  1545. for i in 1 .. t.n.len-1:
  1546. let param = t.n.sons[i].sym
  1547. if param.typ.kind != tyExpr: allUntyped = false
  1548. if allUntyped: incl(s.flags, sfAllUntyped)
  1549. if t.sons[0] == nil: localError(n.info, errXNeedsReturnType, "macro")
  1550. if n.sons[bodyPos].kind == nkEmpty:
  1551. localError(n.info, errImplOfXexpected, s.name.s)
  1552. proc evalInclude(c: PContext, n: PNode): PNode =
  1553. result = newNodeI(nkStmtList, n.info)
  1554. addSon(result, n)
  1555. for i in countup(0, sonsLen(n) - 1):
  1556. var f = checkModuleName(n.sons[i])
  1557. if f != InvalidFileIDX:
  1558. if containsOrIncl(c.includedFiles, f):
  1559. localError(n.info, errRecursiveDependencyX, f.toFilename)
  1560. else:
  1561. addSon(result, semStmt(c, gIncludeFile(c.graph, c.module, f, c.cache)))
  1562. excl(c.includedFiles, f)
  1563. proc setLine(n: PNode, info: TLineInfo) =
  1564. for i in 0 .. <safeLen(n): setLine(n.sons[i], info)
  1565. n.info = info
  1566. proc semPragmaBlock(c: PContext, n: PNode): PNode =
  1567. let pragmaList = n.sons[0]
  1568. pragma(c, nil, pragmaList, exprPragmas)
  1569. result = semExpr(c, n.sons[1])
  1570. n.sons[1] = result
  1571. for i in 0 .. <pragmaList.len:
  1572. case whichPragma(pragmaList.sons[i])
  1573. of wLine: setLine(result, pragmaList.sons[i].info)
  1574. of wLocks, wGcSafe:
  1575. result = n
  1576. result.typ = n.sons[1].typ
  1577. of wNoRewrite:
  1578. incl(result.flags, nfNoRewrite)
  1579. else: discard
  1580. proc semStaticStmt(c: PContext, n: PNode): PNode =
  1581. #echo "semStaticStmt"
  1582. #writeStackTrace()
  1583. let a = semStmt(c, n.sons[0])
  1584. n.sons[0] = a
  1585. evalStaticStmt(c.module, c.cache, a, c.p.owner)
  1586. result = newNodeI(nkDiscardStmt, n.info, 1)
  1587. result.sons[0] = emptyNode
  1588. when false:
  1589. result = evalStaticStmt(c.module, a, c.p.owner)
  1590. if result.isNil:
  1591. LocalError(n.info, errCannotInterpretNodeX, renderTree(n))
  1592. result = emptyNode
  1593. elif result.kind == nkEmpty:
  1594. result = newNodeI(nkDiscardStmt, n.info, 1)
  1595. result.sons[0] = emptyNode
  1596. proc usesResult(n: PNode): bool =
  1597. # nkStmtList(expr) properly propagates the void context,
  1598. # so we don't need to process that all over again:
  1599. if n.kind notin {nkStmtList, nkStmtListExpr,
  1600. nkMacroDef, nkTemplateDef} + procDefs:
  1601. if isAtom(n):
  1602. result = n.kind == nkSym and n.sym.kind == skResult
  1603. elif n.kind == nkReturnStmt:
  1604. result = true
  1605. else:
  1606. for c in n:
  1607. if usesResult(c): return true
  1608. proc inferConceptStaticParam(c: PContext, inferred, n: PNode) =
  1609. var typ = inferred.typ
  1610. let res = semConstExpr(c, n)
  1611. if not sameType(res.typ, typ.base):
  1612. localError(n.info,
  1613. "cannot infer the concept parameter '%s', due to a type mismatch. " &
  1614. "attempt to equate '%s' and '%s'.",
  1615. [inferred.renderTree, $res.typ, $typ.base])
  1616. typ.n = res
  1617. proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
  1618. # these must be last statements in a block:
  1619. const
  1620. LastBlockStmts = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt}
  1621. result = n
  1622. result.kind = nkStmtList
  1623. var length = sonsLen(n)
  1624. var voidContext = false
  1625. var last = length-1
  1626. # by not allowing for nkCommentStmt etc. we ensure nkStmtListExpr actually
  1627. # really *ends* in the expression that produces the type: The compiler now
  1628. # relies on this fact and it's too much effort to change that. And arguably
  1629. # 'R(); #comment' shouldn't produce R's type anyway.
  1630. #while last > 0 and n.sons[last].kind in {nkPragma, nkCommentStmt,
  1631. # nkNilLit, nkEmpty}:
  1632. # dec last
  1633. for i in countup(0, length - 1):
  1634. let k = n.sons[i].kind
  1635. case k
  1636. of nkFinally, nkExceptBranch:
  1637. # stand-alone finally and except blocks are
  1638. # transformed into regular try blocks:
  1639. #
  1640. # var f = fopen("somefile") | var f = fopen("somefile")
  1641. # finally: fclose(f) | try:
  1642. # ... | ...
  1643. # | finally:
  1644. # | fclose(f)
  1645. var deferPart: PNode
  1646. if k == nkDefer:
  1647. deferPart = newNodeI(nkFinally, n.sons[i].info)
  1648. deferPart.add n.sons[i].sons[0]
  1649. elif k == nkFinally:
  1650. message(n.info, warnDeprecated,
  1651. "use 'defer'; standalone 'finally'")
  1652. deferPart = n.sons[i]
  1653. else:
  1654. message(n.info, warnDeprecated,
  1655. "use an explicit 'try'; standalone 'except'")
  1656. deferPart = n.sons[i]
  1657. var tryStmt = newNodeI(nkTryStmt, n.sons[i].info)
  1658. var body = newNodeI(nkStmtList, n.sons[i].info)
  1659. if i < n.sonsLen - 1:
  1660. body.sons = n.sons[(i+1)..n.len-1]
  1661. tryStmt.addSon(body)
  1662. tryStmt.addSon(deferPart)
  1663. n.sons[i] = semTry(c, tryStmt)
  1664. n.sons.setLen(i+1)
  1665. n.typ = n.sons[i].typ
  1666. return
  1667. else:
  1668. var expr = semExpr(c, n.sons[i], flags)
  1669. n.sons[i] = expr
  1670. if c.matchedConcept != nil and expr.typ != nil and
  1671. (nfFromTemplate notin n.flags or i != last):
  1672. case expr.typ.kind
  1673. of tyBool:
  1674. if expr.kind == nkInfix and
  1675. expr[0].kind == nkSym and
  1676. expr[0].sym.name.s == "==":
  1677. if expr[1].typ.isUnresolvedStatic:
  1678. inferConceptStaticParam(c, expr[1], expr[2])
  1679. continue
  1680. elif expr[2].typ.isUnresolvedStatic:
  1681. inferConceptStaticParam(c, expr[2], expr[1])
  1682. continue
  1683. let verdict = semConstExpr(c, n[i])
  1684. if verdict.intVal == 0:
  1685. localError(result.info, "concept predicate failed")
  1686. of tyUnknown: continue
  1687. else: discard
  1688. if n.sons[i].typ == enforceVoidContext: #or usesResult(n.sons[i]):
  1689. voidContext = true
  1690. n.typ = enforceVoidContext
  1691. if i == last and (length == 1 or efWantValue in flags):
  1692. n.typ = n.sons[i].typ
  1693. if not isEmptyType(n.typ): n.kind = nkStmtListExpr
  1694. elif i != last or voidContext:
  1695. discardCheck(c, n.sons[i])
  1696. else:
  1697. n.typ = n.sons[i].typ
  1698. if not isEmptyType(n.typ): n.kind = nkStmtListExpr
  1699. case n.sons[i].kind
  1700. of LastBlockStmts:
  1701. for j in countup(i + 1, length - 1):
  1702. case n.sons[j].kind
  1703. of nkPragma, nkCommentStmt, nkNilLit, nkEmpty, nkBlockExpr,
  1704. nkBlockStmt, nkState: discard
  1705. else: localError(n.sons[j].info, errStmtInvalidAfterReturn)
  1706. else: discard
  1707. if result.len == 1 and
  1708. # concept bodies should be preserved as a stmt list:
  1709. c.matchedConcept == nil and
  1710. # also, don't make life complicated for macros.
  1711. # they will always expect a proper stmtlist:
  1712. nfBlockArg notin n.flags and
  1713. result.sons[0].kind != nkDefer:
  1714. result = result.sons[0]
  1715. when defined(nimfix):
  1716. if result.kind == nkCommentStmt and not result.comment.isNil and
  1717. not (result.comment[0] == '#' and result.comment[1] == '#'):
  1718. # it is an old-style comment statement: we replace it with 'discard ""':
  1719. prettybase.replaceComment(result.info)
  1720. when false:
  1721. # a statement list (s; e) has the type 'e':
  1722. if result.kind == nkStmtList and result.len > 0:
  1723. var lastStmt = lastSon(result)
  1724. if lastStmt.kind != nkNilLit and not implicitlyDiscardable(lastStmt):
  1725. result.typ = lastStmt.typ
  1726. #localError(lastStmt.info, errGenerated,
  1727. # "Last expression must be explicitly returned if it " &
  1728. # "is discardable or discarded")
  1729. proc semStmt(c: PContext, n: PNode): PNode =
  1730. # now: simply an alias:
  1731. result = semExprNoType(c, n)