semstmts.nim 92 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465
  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. const
  12. errNoSymbolToBorrowFromFound = "no symbol to borrow from found"
  13. errDiscardValueX = "value of type '$1' has to be used (or discarded)"
  14. errInvalidDiscard = "statement returns no value that can be discarded"
  15. errInvalidControlFlowX = "invalid control flow: $1"
  16. errSelectorMustBeOfCertainTypes = "selector must be of an ordinal type, float or string"
  17. errExprCannotBeRaised = "only a 'ref object' can be raised"
  18. errBreakOnlyInLoop = "'break' only allowed in loop construct"
  19. errExceptionAlreadyHandled = "exception already handled"
  20. errYieldNotAllowedHere = "'yield' only allowed in an iterator"
  21. errYieldNotAllowedInTryStmt = "'yield' cannot be used within 'try' in a non-inlined iterator"
  22. errInvalidNumberOfYieldExpr = "invalid number of 'yield' expressions"
  23. errCannotReturnExpr = "current routine cannot return an expression"
  24. errGenericLambdaNotAllowed = "A nested proc can have generic parameters only when " &
  25. "it is used as an operand to another routine and the types " &
  26. "of the generic paramers can be inferred from the expected signature."
  27. errCannotInferTypeOfTheLiteral = "cannot infer the type of the $1"
  28. errCannotInferReturnType = "cannot infer the return type of '$1'"
  29. errCannotInferStaticParam = "cannot infer the value of the static param '$1'"
  30. errProcHasNoConcreteType = "'$1' doesn't have a concrete type, due to unspecified generic parameters."
  31. errLetNeedsInit = "'let' symbol requires an initialization"
  32. errThreadvarCannotInit = "a thread var cannot be initialized explicitly; this would only run for the main thread"
  33. errImplOfXexpected = "implementation of '$1' expected"
  34. errRecursiveDependencyX = "recursive dependency: '$1'"
  35. errRecursiveDependencyIteratorX = "recursion is not supported in iterators: '$1'"
  36. errPragmaOnlyInHeaderOfProcX = "pragmas are only allowed in the header of a proc; redefinition of $1"
  37. errCannotAssignToGlobal = "cannot assign local to global variable"
  38. proc implicitlyDiscardable(n: PNode): bool
  39. proc hasEmpty(typ: PType): bool =
  40. if typ.kind in {tySequence, tyArray, tySet}:
  41. result = typ.lastSon.kind == tyEmpty
  42. elif typ.kind == tyTuple:
  43. for s in typ.sons:
  44. result = result or hasEmpty(s)
  45. proc semDiscard(c: PContext, n: PNode): PNode =
  46. result = n
  47. checkSonsLen(n, 1, c.config)
  48. if n[0].kind != nkEmpty:
  49. n[0] = semExprWithType(c, n[0])
  50. let sonType = n[0].typ
  51. let sonKind = n[0].kind
  52. if isEmptyType(sonType) or hasEmpty(sonType) or
  53. sonType.kind in {tyNone, tyTypeDesc} or
  54. sonKind == nkTypeOfExpr:
  55. localError(c.config, n.info, errInvalidDiscard)
  56. if sonType.kind == tyProc and sonKind notin nkCallKinds:
  57. # tyProc is disallowed to prevent ``discard foo`` to be valid, when ``discard foo()`` is meant.
  58. localError(c.config, n.info, "illegal discard proc, did you mean: " & $n[0] & "()")
  59. proc semBreakOrContinue(c: PContext, n: PNode): PNode =
  60. result = n
  61. checkSonsLen(n, 1, c.config)
  62. if n[0].kind != nkEmpty:
  63. if n.kind != nkContinueStmt:
  64. var s: PSym
  65. case n[0].kind
  66. of nkIdent: s = lookUp(c, n[0])
  67. of nkSym: s = n[0].sym
  68. else: illFormedAst(n, c.config)
  69. s = getGenSym(c, s)
  70. if s.kind == skLabel and s.owner.id == c.p.owner.id:
  71. var x = newSymNode(s)
  72. x.info = n.info
  73. incl(s.flags, sfUsed)
  74. n[0] = x
  75. suggestSym(c.graph, x.info, s, c.graph.usageSym)
  76. onUse(x.info, s)
  77. else:
  78. localError(c.config, n.info, errInvalidControlFlowX % s.name.s)
  79. else:
  80. localError(c.config, n.info, errGenerated, "'continue' cannot have a label")
  81. elif (c.p.nestedLoopCounter <= 0) and ((c.p.nestedBlockCounter <= 0) or n.kind == nkContinueStmt):
  82. localError(c.config, n.info, errInvalidControlFlowX %
  83. renderTree(n, {renderNoComments}))
  84. proc semAsm(c: PContext, n: PNode): PNode =
  85. checkSonsLen(n, 2, c.config)
  86. var marker = pragmaAsm(c, n[0])
  87. if marker == '\0': marker = '`' # default marker
  88. result = semAsmOrEmit(c, n, marker)
  89. proc semWhile(c: PContext, n: PNode; flags: TExprFlags): PNode =
  90. result = n
  91. checkSonsLen(n, 2, c.config)
  92. openScope(c)
  93. n[0] = forceBool(c, semExprWithType(c, n[0], expectedType = getSysType(c.graph, n.info, tyBool)))
  94. inc(c.p.nestedLoopCounter)
  95. n[1] = semStmt(c, n[1], flags)
  96. dec(c.p.nestedLoopCounter)
  97. closeScope(c)
  98. if n[1].typ == c.enforceVoidContext:
  99. result.typ = c.enforceVoidContext
  100. elif efInTypeof in flags:
  101. result.typ = n[1].typ
  102. elif implicitlyDiscardable(n[1]):
  103. result[1].typ = c.enforceVoidContext
  104. proc semProc(c: PContext, n: PNode): PNode
  105. proc semExprBranch(c: PContext, n: PNode; flags: TExprFlags = {}; expectedType: PType = nil): PNode =
  106. result = semExpr(c, n, flags, expectedType)
  107. if result.typ != nil:
  108. # XXX tyGenericInst here?
  109. if result.typ.kind in {tyVar, tyLent}: result = newDeref(result)
  110. proc semExprBranchScope(c: PContext, n: PNode; expectedType: PType = nil): PNode =
  111. openScope(c)
  112. result = semExprBranch(c, n, expectedType = expectedType)
  113. closeScope(c)
  114. const
  115. skipForDiscardable = {nkIfStmt, nkIfExpr, nkCaseStmt, nkOfBranch,
  116. nkElse, nkStmtListExpr, nkTryStmt, nkFinally, nkExceptBranch,
  117. nkElifBranch, nkElifExpr, nkElseExpr, nkBlockStmt, nkBlockExpr,
  118. nkHiddenStdConv, nkHiddenDeref}
  119. proc implicitlyDiscardable(n: PNode): bool =
  120. var n = n
  121. while n.kind in skipForDiscardable: n = n.lastSon
  122. result = n.kind in nkLastBlockStmts or
  123. (isCallExpr(n) and n[0].kind == nkSym and
  124. sfDiscardable in n[0].sym.flags)
  125. proc fixNilType(c: PContext; n: PNode) =
  126. if isAtom(n):
  127. if n.kind != nkNilLit and n.typ != nil:
  128. localError(c.config, n.info, errDiscardValueX % n.typ.typeToString)
  129. elif n.kind in {nkStmtList, nkStmtListExpr}:
  130. n.transitionSonsKind(nkStmtList)
  131. for it in n: fixNilType(c, it)
  132. n.typ = nil
  133. proc discardCheck(c: PContext, result: PNode, flags: TExprFlags) =
  134. if c.matchedConcept != nil or efInTypeof in flags: return
  135. if result.typ != nil and result.typ.kind notin {tyTyped, tyVoid}:
  136. if implicitlyDiscardable(result):
  137. var n = newNodeI(nkDiscardStmt, result.info, 1)
  138. n[0] = result
  139. elif result.typ.kind != tyError and c.config.cmd != cmdInteractive:
  140. if result.typ.kind == tyNone:
  141. localError(c.config, result.info, "expression has no type: " &
  142. renderTree(result, {renderNoComments}))
  143. var n = result
  144. while n.kind in skipForDiscardable:
  145. if n.kind == nkTryStmt: n = n[0]
  146. else: n = n.lastSon
  147. var s = "expression '" & $n & "' is of type '" &
  148. result.typ.typeToString & "' and has to be used (or discarded)"
  149. if result.info.line != n.info.line or
  150. result.info.fileIndex != n.info.fileIndex:
  151. s.add "; start of expression here: " & c.config$result.info
  152. if result.typ.kind == tyProc:
  153. s.add "; for a function call use ()"
  154. localError(c.config, n.info, s)
  155. proc semIf(c: PContext, n: PNode; flags: TExprFlags; expectedType: PType = nil): PNode =
  156. result = n
  157. var typ = commonTypeBegin
  158. var expectedType = expectedType
  159. var hasElse = false
  160. for i in 0..<n.len:
  161. var it = n[i]
  162. if it.len == 2:
  163. openScope(c)
  164. it[0] = forceBool(c, semExprWithType(c, it[0], expectedType = getSysType(c.graph, n.info, tyBool)))
  165. it[1] = semExprBranch(c, it[1], flags, expectedType)
  166. typ = commonType(c, typ, it[1])
  167. if not endsInNoReturn(it[1]):
  168. expectedType = typ
  169. closeScope(c)
  170. elif it.len == 1:
  171. hasElse = true
  172. it[0] = semExprBranchScope(c, it[0], expectedType)
  173. typ = commonType(c, typ, it[0])
  174. if not endsInNoReturn(it[0]):
  175. expectedType = typ
  176. else: illFormedAst(it, c.config)
  177. if isEmptyType(typ) or typ.kind in {tyNil, tyUntyped} or
  178. (not hasElse and efInTypeof notin flags):
  179. for it in n: discardCheck(c, it.lastSon, flags)
  180. result.transitionSonsKind(nkIfStmt)
  181. # propagate any enforced VoidContext:
  182. if typ == c.enforceVoidContext: result.typ = c.enforceVoidContext
  183. else:
  184. for it in n:
  185. let j = it.len-1
  186. if not endsInNoReturn(it[j]):
  187. it[j] = fitNode(c, typ, it[j], it[j].info)
  188. result.transitionSonsKind(nkIfExpr)
  189. result.typ = typ
  190. proc semTry(c: PContext, n: PNode; flags: TExprFlags; expectedType: PType = nil): PNode =
  191. var check = initIntSet()
  192. template semExceptBranchType(typeNode: PNode): bool =
  193. # returns true if exception type is imported type
  194. let typ = semTypeNode(c, typeNode, nil).toObject()
  195. var isImported = false
  196. if isImportedException(typ, c.config):
  197. isImported = true
  198. elif not isException(typ):
  199. localError(c.config, typeNode.info, errExprCannotBeRaised)
  200. elif not isDefectOrCatchableError(typ):
  201. message(c.config, a.info, warnBareExcept, "catch a more precise Exception deriving from CatchableError or Defect.")
  202. if containsOrIncl(check, typ.id):
  203. localError(c.config, typeNode.info, errExceptionAlreadyHandled)
  204. typeNode = newNodeIT(nkType, typeNode.info, typ)
  205. isImported
  206. result = n
  207. checkMinSonsLen(n, 2, c.config)
  208. var typ = commonTypeBegin
  209. var expectedType = expectedType
  210. n[0] = semExprBranchScope(c, n[0], expectedType)
  211. if not endsInNoReturn(n[0]):
  212. typ = commonType(c, typ, n[0].typ)
  213. expectedType = typ
  214. var last = n.len - 1
  215. var catchAllExcepts = 0
  216. for i in 1..last:
  217. let a = n[i]
  218. checkMinSonsLen(a, 1, c.config)
  219. openScope(c)
  220. if a.kind == nkExceptBranch:
  221. if a.len == 2 and a[0].kind == nkBracket:
  222. # rewrite ``except [a, b, c]: body`` -> ```except a, b, c: body```
  223. a.sons[0..0] = a[0].sons
  224. if a.len == 2 and a[0].isInfixAs():
  225. # support ``except Exception as ex: body``
  226. let isImported = semExceptBranchType(a[0][1])
  227. let symbol = newSymG(skLet, a[0][2], c)
  228. symbol.typ = if isImported: a[0][1].typ
  229. else: a[0][1].typ.toRef(c.idgen)
  230. addDecl(c, symbol)
  231. # Overwrite symbol in AST with the symbol in the symbol table.
  232. a[0][2] = newSymNode(symbol, a[0][2].info)
  233. elif a.len == 1:
  234. # count number of ``except: body`` blocks
  235. inc catchAllExcepts
  236. message(c.config, a.info, warnBareExcept,
  237. "The bare except clause is deprecated; use `except CatchableError:` instead")
  238. else:
  239. # support ``except KeyError, ValueError, ... : body``
  240. if catchAllExcepts > 0:
  241. # if ``except: body`` already encountered,
  242. # cannot be followed by a ``except KeyError, ... : body`` block
  243. inc catchAllExcepts
  244. var isNative, isImported: bool
  245. for j in 0..<a.len-1:
  246. let tmp = semExceptBranchType(a[j])
  247. if tmp: isImported = true
  248. else: isNative = true
  249. if isNative and isImported:
  250. localError(c.config, a[0].info, "Mix of imported and native exception types is not allowed in one except branch")
  251. elif a.kind == nkFinally:
  252. if i != n.len-1:
  253. localError(c.config, a.info, "Only one finally is allowed after all other branches")
  254. else:
  255. illFormedAst(n, c.config)
  256. if catchAllExcepts > 1:
  257. # if number of ``except: body`` blocks is greater than 1
  258. # or more specific exception follows a general except block, it is invalid
  259. localError(c.config, a.info, "Only one general except clause is allowed after more specific exceptions")
  260. # last child of an nkExcept/nkFinally branch is a statement:
  261. if a.kind != nkFinally:
  262. a[^1] = semExprBranchScope(c, a[^1], expectedType)
  263. typ = commonType(c, typ, a[^1])
  264. if not endsInNoReturn(a[^1]):
  265. expectedType = typ
  266. else:
  267. a[^1] = semExprBranchScope(c, a[^1])
  268. dec last
  269. closeScope(c)
  270. if isEmptyType(typ) or typ.kind in {tyNil, tyUntyped}:
  271. discardCheck(c, n[0], flags)
  272. for i in 1..<n.len: discardCheck(c, n[i].lastSon, flags)
  273. if typ == c.enforceVoidContext:
  274. result.typ = c.enforceVoidContext
  275. else:
  276. if n.lastSon.kind == nkFinally: discardCheck(c, n.lastSon.lastSon, flags)
  277. if not endsInNoReturn(n[0]):
  278. n[0] = fitNode(c, typ, n[0], n[0].info)
  279. for i in 1..last:
  280. var it = n[i]
  281. let j = it.len-1
  282. if not endsInNoReturn(it[j]):
  283. it[j] = fitNode(c, typ, it[j], it[j].info)
  284. result.typ = typ
  285. proc fitRemoveHiddenConv(c: PContext, typ: PType, n: PNode): PNode =
  286. result = fitNode(c, typ, n, n.info)
  287. if result.kind in {nkHiddenStdConv, nkHiddenSubConv}:
  288. let r1 = result[1]
  289. if r1.kind in {nkCharLit..nkUInt64Lit} and typ.skipTypes(abstractRange).kind in {tyFloat..tyFloat128}:
  290. result = newFloatNode(nkFloatLit, BiggestFloat r1.intVal)
  291. result.info = n.info
  292. result.typ = typ
  293. if not floatRangeCheck(result.floatVal, typ):
  294. localError(c.config, n.info, errFloatToString % [$result.floatVal, typeToString(typ)])
  295. else:
  296. changeType(c, r1, typ, check=true)
  297. result = r1
  298. elif not sameType(result.typ, typ):
  299. changeType(c, result, typ, check=false)
  300. proc findShadowedVar(c: PContext, v: PSym): PSym =
  301. for scope in localScopesFrom(c, c.currentScope.parent):
  302. let shadowed = strTableGet(scope.symbols, v.name)
  303. if shadowed != nil and shadowed.kind in skLocalVars:
  304. return shadowed
  305. proc identWithin(n: PNode, s: PIdent): bool =
  306. for i in 0..n.safeLen-1:
  307. if identWithin(n[i], s): return true
  308. result = n.kind == nkSym and n.sym.name.id == s.id
  309. proc semIdentDef(c: PContext, n: PNode, kind: TSymKind, reportToNimsuggest = true): PSym =
  310. if isTopLevel(c):
  311. result = semIdentWithPragma(c, kind, n, {sfExported})
  312. incl(result.flags, sfGlobal)
  313. #if kind in {skVar, skLet}:
  314. # echo "global variable here ", n.info, " ", result.name.s
  315. else:
  316. result = semIdentWithPragma(c, kind, n, {})
  317. if result.owner.kind == skModule:
  318. incl(result.flags, sfGlobal)
  319. result.options = c.config.options
  320. proc getLineInfo(n: PNode): TLineInfo =
  321. case n.kind
  322. of nkPostfix:
  323. if len(n) > 1:
  324. return getLineInfo(n[1])
  325. of nkAccQuoted, nkPragmaExpr:
  326. if len(n) > 0:
  327. return getLineInfo(n[0])
  328. else:
  329. discard
  330. result = n.info
  331. let info = getLineInfo(n)
  332. if reportToNimsuggest:
  333. suggestSym(c.graph, info, result, c.graph.usageSym)
  334. proc checkNilable(c: PContext; v: PSym) =
  335. if {sfGlobal, sfImportc} * v.flags == {sfGlobal} and v.typ.requiresInit:
  336. if v.astdef.isNil:
  337. message(c.config, v.info, warnProveInit, v.name.s)
  338. elif tfNotNil in v.typ.flags and not v.astdef.typ.isNil and tfNotNil notin v.astdef.typ.flags:
  339. message(c.config, v.info, warnProveInit, v.name.s)
  340. #include liftdestructors
  341. proc addToVarSection(c: PContext; result: PNode; orig, identDefs: PNode) =
  342. let value = identDefs[^1]
  343. if result.kind == nkStmtList:
  344. let o = copyNode(orig)
  345. o.add identDefs
  346. result.add o
  347. else:
  348. result.add identDefs
  349. proc isDiscardUnderscore(v: PSym): bool =
  350. if v.name.id == ord(wUnderscore):
  351. v.flags.incl(sfGenSym)
  352. result = true
  353. proc semUsing(c: PContext; n: PNode): PNode =
  354. result = c.graph.emptyNode
  355. if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "using")
  356. for i in 0..<n.len:
  357. var a = n[i]
  358. if c.config.cmd == cmdIdeTools: suggestStmt(c, a)
  359. if a.kind == nkCommentStmt: continue
  360. if a.kind notin {nkIdentDefs, nkVarTuple, nkConstDef}: illFormedAst(a, c.config)
  361. checkMinSonsLen(a, 3, c.config)
  362. if a[^2].kind != nkEmpty:
  363. let typ = semTypeNode(c, a[^2], nil)
  364. for j in 0..<a.len-2:
  365. let v = semIdentDef(c, a[j], skParam)
  366. styleCheckDef(c, v)
  367. onDef(a[j].info, v)
  368. v.typ = typ
  369. strTableIncl(c.signatures, v)
  370. else:
  371. localError(c.config, a.info, "'using' section must have a type")
  372. var def: PNode
  373. if a[^1].kind != nkEmpty:
  374. localError(c.config, a.info, "'using' sections cannot contain assignments")
  375. proc hasUnresolvedParams(n: PNode; flags: TExprFlags): bool =
  376. result = tfUnresolved in n.typ.flags
  377. when false:
  378. case n.kind
  379. of nkSym:
  380. result = isGenericRoutineStrict(n.sym)
  381. of nkSymChoices:
  382. for ch in n:
  383. if hasUnresolvedParams(ch, flags):
  384. return true
  385. result = false
  386. else:
  387. result = false
  388. if efOperand in flags:
  389. if tfUnresolved notin n.typ.flags:
  390. result = false
  391. proc makeDeref(n: PNode): PNode =
  392. var t = n.typ
  393. if t.kind in tyUserTypeClasses and t.isResolvedUserTypeClass:
  394. t = t.lastSon
  395. t = skipTypes(t, {tyGenericInst, tyAlias, tySink, tyOwned})
  396. result = n
  397. if t.kind in {tyVar, tyLent}:
  398. result = newNodeIT(nkHiddenDeref, n.info, t[0])
  399. result.add n
  400. t = skipTypes(t[0], {tyGenericInst, tyAlias, tySink, tyOwned})
  401. while t.kind in {tyPtr, tyRef}:
  402. var a = result
  403. let baseTyp = t.lastSon
  404. result = newNodeIT(nkHiddenDeref, n.info, baseTyp)
  405. result.add a
  406. t = skipTypes(baseTyp, {tyGenericInst, tyAlias, tySink, tyOwned})
  407. proc fillPartialObject(c: PContext; n: PNode; typ: PType) =
  408. if n.len == 2:
  409. let x = semExprWithType(c, n[0])
  410. let y = considerQuotedIdent(c, n[1])
  411. let obj = x.typ.skipTypes(abstractPtrs)
  412. if obj.kind == tyObject and tfPartial in obj.flags:
  413. let field = newSym(skField, getIdent(c.cache, y.s), nextSymId c.idgen, obj.sym, n[1].info)
  414. field.typ = skipIntLit(typ, c.idgen)
  415. field.position = obj.n.len
  416. obj.n.add newSymNode(field)
  417. n[0] = makeDeref x
  418. n[1] = newSymNode(field)
  419. n.typ = field.typ
  420. else:
  421. localError(c.config, n.info, "implicit object field construction " &
  422. "requires a .partial object, but got " & typeToString(obj))
  423. else:
  424. localError(c.config, n.info, "nkDotNode requires 2 children")
  425. proc setVarType(c: PContext; v: PSym, typ: PType) =
  426. if v.typ != nil and not sameTypeOrNil(v.typ, typ):
  427. localError(c.config, v.info, "inconsistent typing for reintroduced symbol '" &
  428. v.name.s & "': previous type was: " & typeToString(v.typ, preferDesc) &
  429. "; new type is: " & typeToString(typ, preferDesc))
  430. v.typ = typ
  431. proc semLowerLetVarCustomPragma(c: PContext, a: PNode, n: PNode): PNode =
  432. var b = a[0]
  433. if b.kind == nkPragmaExpr:
  434. if b[1].len != 1:
  435. # we could in future support pragmas w args e.g.: `var foo {.bar:"goo".} = expr`
  436. return nil
  437. let nodePragma = b[1][0]
  438. # see: `singlePragma`
  439. var amb = false
  440. var sym: PSym = nil
  441. case nodePragma.kind
  442. of nkIdent, nkAccQuoted:
  443. let ident = considerQuotedIdent(c, nodePragma)
  444. var userPragma = strTableGet(c.userPragmas, ident)
  445. if userPragma != nil: return nil
  446. let w = nodePragma.whichPragma
  447. if n.kind == nkVarSection and w in varPragmas or
  448. n.kind == nkLetSection and w in letPragmas or
  449. n.kind == nkConstSection and w in constPragmas:
  450. return nil
  451. sym = searchInScopes(c, ident, amb)
  452. # XXX what if amb is true?
  453. # CHECKME: should that test also apply to `nkSym` case?
  454. if sym == nil or sfCustomPragma in sym.flags: return nil
  455. of nkSym:
  456. sym = nodePragma.sym
  457. else:
  458. return nil
  459. # skip if not in scope; skip `template myAttr() {.pragma.}`
  460. let lhs = b[0]
  461. let clash = strTableGet(c.currentScope.symbols, lhs.ident)
  462. if clash != nil:
  463. # refs https://github.com/nim-lang/Nim/issues/8275
  464. wrongRedefinition(c, lhs.info, lhs.ident.s, clash.info)
  465. result = newTree(nkCall)
  466. result.add nodePragma
  467. result.add lhs
  468. if a[1].kind != nkEmpty:
  469. result.add a[1]
  470. else:
  471. result.add newNodeIT(nkNilLit, a.info, c.graph.sysTypes[tyNil])
  472. result.add a[2]
  473. result.info = a.info
  474. let ret = newNodeI(nkStmtList, a.info)
  475. ret.add result
  476. result = semExprNoType(c, ret)
  477. proc errorSymChoiceUseQualifier(c: PContext; n: PNode) =
  478. assert n.kind in nkSymChoices
  479. var err = "ambiguous identifier: '" & $n[0] & "'"
  480. var i = 0
  481. for child in n:
  482. let candidate = child.sym
  483. if i == 0: err.add " -- use one of the following:\n"
  484. else: err.add "\n"
  485. err.add " " & candidate.owner.name.s & "." & candidate.name.s
  486. inc i
  487. localError(c.config, n.info, errGenerated, err)
  488. template isLocalVarSym(n: PNode): bool =
  489. n.kind == nkSym and
  490. n.sym.kind in {skVar, skLet} and not
  491. ({sfGlobal, sfPure} * n.sym.flags != {} or
  492. sfCompileTime in n.sym.flags)
  493. proc usesLocalVar(n: PNode): bool =
  494. for z in 1 ..< n.len:
  495. if n[z].isLocalVarSym:
  496. return true
  497. elif n[z].kind in nkCallKinds:
  498. if usesLocalVar(n[z]):
  499. return true
  500. proc globalVarInitCheck(c: PContext, n: PNode) =
  501. if n.isLocalVarSym or n.kind in nkCallKinds and usesLocalVar(n):
  502. localError(c.config, n.info, errCannotAssignToGlobal)
  503. proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
  504. if n.len == 1:
  505. result = semLowerLetVarCustomPragma(c, n[0], n)
  506. if result != nil: return result
  507. var b: PNode
  508. result = copyNode(n)
  509. for i in 0..<n.len:
  510. var a = n[i]
  511. if c.config.cmd == cmdIdeTools: suggestStmt(c, a)
  512. if a.kind == nkCommentStmt: continue
  513. if a.kind notin {nkIdentDefs, nkVarTuple}: illFormedAst(a, c.config)
  514. checkMinSonsLen(a, 3, c.config)
  515. var hasUserSpecifiedType = false
  516. var typ: PType = nil
  517. if a[^2].kind != nkEmpty:
  518. typ = semTypeNode(c, a[^2], nil)
  519. hasUserSpecifiedType = true
  520. var typFlags: TTypeAllowedFlags
  521. var def: PNode = c.graph.emptyNode
  522. if a[^1].kind != nkEmpty:
  523. def = semExprWithType(c, a[^1], {}, typ)
  524. if def.kind in nkSymChoices and def[0].typ.skipTypes(abstractInst).kind == tyEnum:
  525. errorSymChoiceUseQualifier(c, def)
  526. elif def.kind == nkSym and def.sym.kind in {skTemplate, skMacro}:
  527. typFlags.incl taIsTemplateOrMacro
  528. elif def.typ.kind == tyTypeDesc and c.p.owner.kind != skMacro:
  529. typFlags.incl taProcContextIsNotMacro
  530. if typ != nil:
  531. if typ.isMetaType:
  532. def = inferWithMetatype(c, typ, def)
  533. typ = def.typ
  534. else:
  535. # BUGFIX: ``fitNode`` is needed here!
  536. # check type compatibility between def.typ and typ
  537. def = fitNodeConsiderViewType(c, typ, def, def.info)
  538. #changeType(def.skipConv, typ, check=true)
  539. else:
  540. typ = def.typ.skipTypes({tyStatic, tySink}).skipIntLit(c.idgen)
  541. if typ.kind in tyUserTypeClasses and typ.isResolvedUserTypeClass:
  542. typ = typ.lastSon
  543. if hasEmpty(typ):
  544. localError(c.config, def.info, errCannotInferTypeOfTheLiteral % typ.kind.toHumanStr)
  545. elif typ.kind == tyProc and def.kind == nkSym and isGenericRoutine(def.sym.ast):
  546. # tfUnresolved in typ.flags:
  547. localError(c.config, def.info, errProcHasNoConcreteType % def.renderTree)
  548. when false:
  549. # XXX This typing rule is neither documented nor complete enough to
  550. # justify it. Instead use the newer 'unowned x' until we figured out
  551. # a more general solution.
  552. if symkind == skVar and typ.kind == tyOwned and def.kind notin nkCallKinds:
  553. # special type inference rule: 'var it = ownedPointer' is turned
  554. # into an unowned pointer.
  555. typ = typ.lastSon
  556. # this can only happen for errornous var statements:
  557. if typ == nil: continue
  558. if c.matchedConcept != nil:
  559. typFlags.incl taConcept
  560. typeAllowedCheck(c, a.info, typ, symkind, typFlags)
  561. var tup = skipTypes(typ, {tyGenericInst, tyAlias, tySink})
  562. if a.kind == nkVarTuple:
  563. if tup.kind != tyTuple:
  564. localError(c.config, a.info, errXExpected, "tuple")
  565. elif a.len-2 != tup.len:
  566. localError(c.config, a.info, errWrongNumberOfVariables)
  567. b = newNodeI(nkVarTuple, a.info)
  568. newSons(b, a.len)
  569. # keep type desc for doc generator
  570. # NOTE: at the moment this is always ast.emptyNode, see parser.nim
  571. b[^2] = a[^2]
  572. b[^1] = def
  573. addToVarSection(c, result, n, b)
  574. elif tup.kind == tyTuple and def.kind in {nkPar, nkTupleConstr} and
  575. a.kind == nkIdentDefs and a.len > 3:
  576. message(c.config, a.info, warnEachIdentIsTuple)
  577. for j in 0..<a.len-2:
  578. if a[j].kind == nkDotExpr:
  579. fillPartialObject(c, a[j],
  580. if a.kind != nkVarTuple: typ else: tup[j])
  581. addToVarSection(c, result, n, a)
  582. continue
  583. var v = semIdentDef(c, a[j], symkind, false)
  584. when defined(nimsuggest):
  585. v.hasUserSpecifiedType = hasUserSpecifiedType
  586. styleCheckDef(c, v)
  587. onDef(a[j].info, v)
  588. if sfGenSym notin v.flags:
  589. if not isDiscardUnderscore(v): addInterfaceDecl(c, v)
  590. else:
  591. if v.owner == nil: v.owner = c.p.owner
  592. when oKeepVariableNames:
  593. if c.inUnrolledContext > 0: v.flags.incl(sfShadowed)
  594. else:
  595. let shadowed = findShadowedVar(c, v)
  596. if shadowed != nil:
  597. shadowed.flags.incl(sfShadowed)
  598. if shadowed.kind == skResult and sfGenSym notin v.flags:
  599. message(c.config, a.info, warnResultShadowed)
  600. if a.kind != nkVarTuple:
  601. if def.kind != nkEmpty:
  602. if sfThread in v.flags: localError(c.config, def.info, errThreadvarCannotInit)
  603. setVarType(c, v, typ)
  604. b = newNodeI(nkIdentDefs, a.info)
  605. if importantComments(c.config):
  606. # keep documentation information:
  607. b.comment = a.comment
  608. b.add newSymNode(v)
  609. # keep type desc for doc generator
  610. b.add a[^2]
  611. b.add copyTree(def)
  612. addToVarSection(c, result, n, b)
  613. # this is needed for the evaluation pass, guard checking
  614. # and custom pragmas:
  615. var ast = newNodeI(nkIdentDefs, a.info)
  616. if a[j].kind == nkPragmaExpr:
  617. var p = newNodeI(nkPragmaExpr, a.info)
  618. p.add newSymNode(v)
  619. p.add a[j][1].copyTree
  620. ast.add p
  621. else:
  622. ast.add newSymNode(v)
  623. ast.add a[^2].copyTree
  624. ast.add def
  625. v.ast = ast
  626. else:
  627. if def.kind in {nkPar, nkTupleConstr}: v.ast = def[j]
  628. # bug #7663, for 'nim check' this can be a non-tuple:
  629. if tup.kind == tyTuple: setVarType(c, v, tup[j])
  630. else: v.typ = tup
  631. b[j] = newSymNode(v)
  632. if def.kind == nkEmpty:
  633. let actualType = v.typ.skipTypes({tyGenericInst, tyAlias,
  634. tyUserTypeClassInst})
  635. if actualType.kind in {tyObject, tyDistinct} and
  636. actualType.requiresInit:
  637. defaultConstructionError(c, v.typ, v.info)
  638. else:
  639. checkNilable(c, v)
  640. # allow let to not be initialised if imported from C:
  641. if v.kind == skLet and sfImportc notin v.flags:
  642. localError(c.config, a.info, errLetNeedsInit)
  643. if sfCompileTime in v.flags:
  644. if a.kind != nkVarTuple:
  645. var x = newNodeI(result.kind, v.info)
  646. x.add result[i]
  647. vm.setupCompileTimeVar(c.module, c.idgen, c.graph, x)
  648. else:
  649. localError(c.config, a.info, "cannot destructure to compile time variable")
  650. if v.flags * {sfGlobal, sfThread} == {sfGlobal}:
  651. message(c.config, v.info, hintGlobalVar)
  652. if {sfGlobal, sfPure} <= v.flags:
  653. globalVarInitCheck(c, def)
  654. suggestSym(c.graph, v.info, v, c.graph.usageSym)
  655. proc semConst(c: PContext, n: PNode): PNode =
  656. result = copyNode(n)
  657. inc c.inStaticContext
  658. for i in 0..<n.len:
  659. var a = n[i]
  660. if c.config.cmd == cmdIdeTools: suggestStmt(c, a)
  661. if a.kind == nkCommentStmt: continue
  662. if a.kind notin {nkConstDef, nkVarTuple}: illFormedAst(a, c.config)
  663. checkMinSonsLen(a, 3, c.config)
  664. var hasUserSpecifiedType = false
  665. var typ: PType = nil
  666. if a[^2].kind != nkEmpty:
  667. typ = semTypeNode(c, a[^2], nil)
  668. hasUserSpecifiedType = true
  669. var typFlags: TTypeAllowedFlags
  670. # don't evaluate here since the type compatibility check below may add a converter
  671. var def = semExprWithType(c, a[^1], {}, typ)
  672. if def.kind == nkSym and def.sym.kind in {skTemplate, skMacro}:
  673. typFlags.incl taIsTemplateOrMacro
  674. elif def.typ.kind == tyTypeDesc and c.p.owner.kind != skMacro:
  675. typFlags.incl taProcContextIsNotMacro
  676. # check type compatibility between def.typ and typ:
  677. if typ != nil:
  678. if typ.isMetaType:
  679. def = inferWithMetatype(c, typ, def)
  680. typ = def.typ
  681. else:
  682. def = fitRemoveHiddenConv(c, typ, def)
  683. else:
  684. typ = def.typ
  685. # evaluate the node
  686. def = semConstExpr(c, def)
  687. if def == nil:
  688. localError(c.config, a[^1].info, errConstExprExpected)
  689. continue
  690. if def.kind != nkNilLit:
  691. if c.matchedConcept != nil:
  692. typFlags.incl taConcept
  693. typeAllowedCheck(c, a.info, typ, skConst, typFlags)
  694. var b: PNode
  695. if a.kind == nkVarTuple:
  696. if typ.kind != tyTuple:
  697. localError(c.config, a.info, errXExpected, "tuple")
  698. elif a.len-2 != typ.len:
  699. localError(c.config, a.info, errWrongNumberOfVariables)
  700. b = newNodeI(nkVarTuple, a.info)
  701. newSons(b, a.len)
  702. b[^2] = a[^2]
  703. b[^1] = def
  704. for j in 0..<a.len-2:
  705. var v = semIdentDef(c, a[j], skConst)
  706. when defined(nimsuggest):
  707. v.hasUserSpecifiedType = hasUserSpecifiedType
  708. if sfGenSym notin v.flags: addInterfaceDecl(c, v)
  709. elif v.owner == nil: v.owner = getCurrOwner(c)
  710. styleCheckDef(c, v)
  711. onDef(a[j].info, v)
  712. if a.kind != nkVarTuple:
  713. setVarType(c, v, typ)
  714. v.ast = def # no need to copy
  715. b = newNodeI(nkConstDef, a.info)
  716. if importantComments(c.config): b.comment = a.comment
  717. b.add newSymNode(v)
  718. b.add a[1]
  719. b.add copyTree(def)
  720. else:
  721. setVarType(c, v, typ[j])
  722. v.ast = if def[j].kind != nkExprColonExpr: def[j]
  723. else: def[j][1]
  724. b[j] = newSymNode(v)
  725. result.add b
  726. dec c.inStaticContext
  727. include semfields
  728. proc symForVar(c: PContext, n: PNode): PSym =
  729. let m = if n.kind == nkPragmaExpr: n[0] else: n
  730. result = newSymG(skForVar, m, c)
  731. styleCheckDef(c, result)
  732. onDef(n.info, result)
  733. if n.kind == nkPragmaExpr:
  734. pragma(c, result, n[1], forVarPragmas)
  735. proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode =
  736. result = n
  737. let iterBase = n[^2].typ
  738. var iter = skipTypes(iterBase, {tyGenericInst, tyAlias, tySink, tyOwned})
  739. var iterAfterVarLent = iter.skipTypes({tyGenericInst, tyAlias, tyLent, tyVar})
  740. # n.len == 3 means that there is one for loop variable
  741. # and thus no tuple unpacking:
  742. if iterAfterVarLent.kind == tyEmpty:
  743. localError(c.config, n[^2].info, "cannot infer element type of $1" %
  744. renderTree(n[^2], {renderNoComments}))
  745. if iterAfterVarLent.kind != tyTuple or n.len == 3:
  746. if n.len == 3:
  747. if n[0].kind == nkVarTuple:
  748. if n[0].len-1 != iterAfterVarLent.len:
  749. return localErrorNode(c, n, n[0].info, errWrongNumberOfVariables)
  750. for i in 0..<n[0].len-1:
  751. var v = symForVar(c, n[0][i])
  752. if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal)
  753. case iter.kind
  754. of tyVar, tyLent:
  755. v.typ = newTypeS(iter.kind, c)
  756. v.typ.add iterAfterVarLent[i]
  757. if tfVarIsPtr in iter.flags:
  758. v.typ.flags.incl tfVarIsPtr
  759. else:
  760. v.typ = iter[i]
  761. n[0][i] = newSymNode(v)
  762. if sfGenSym notin v.flags and not isDiscardUnderscore(v): addDecl(c, v)
  763. elif v.owner == nil: v.owner = getCurrOwner(c)
  764. else:
  765. var v = symForVar(c, n[0])
  766. if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal)
  767. # BUGFIX: don't use `iter` here as that would strip away
  768. # the ``tyGenericInst``! See ``tests/compile/tgeneric.nim``
  769. # for an example:
  770. v.typ = iterBase
  771. n[0] = newSymNode(v)
  772. if sfGenSym notin v.flags and not isDiscardUnderscore(v): addDecl(c, v)
  773. elif v.owner == nil: v.owner = getCurrOwner(c)
  774. else:
  775. localError(c.config, n.info, errWrongNumberOfVariables)
  776. elif n.len-2 != iterAfterVarLent.len:
  777. localError(c.config, n.info, errWrongNumberOfVariables)
  778. else:
  779. for i in 0..<n.len - 2:
  780. if n[i].kind == nkVarTuple:
  781. var mutable = false
  782. var isLent = false
  783. case iter[i].kind
  784. of tyVar:
  785. mutable = true
  786. iter[i] = iter[i].skipTypes({tyVar})
  787. of tyLent:
  788. isLent = true
  789. iter[i] = iter[i].skipTypes({tyLent})
  790. else: discard
  791. if n[i].len-1 != iter[i].len:
  792. localError(c.config, n[i].info, errWrongNumberOfVariables)
  793. for j in 0..<n[i].len-1:
  794. var v = symForVar(c, n[i][j])
  795. if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal)
  796. if mutable:
  797. v.typ = newTypeS(tyVar, c)
  798. v.typ.add iter[i][j]
  799. elif isLent:
  800. v.typ = newTypeS(tyLent, c)
  801. v.typ.add iter[i][j]
  802. else:
  803. v.typ = iter[i][j]
  804. n[i][j] = newSymNode(v)
  805. if not isDiscardUnderscore(v): addDecl(c, v)
  806. elif v.owner == nil: v.owner = getCurrOwner(c)
  807. else:
  808. var v = symForVar(c, n[i])
  809. if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal)
  810. case iter.kind
  811. of tyVar, tyLent:
  812. v.typ = newTypeS(iter.kind, c)
  813. v.typ.add iterAfterVarLent[i]
  814. if tfVarIsPtr in iter.flags:
  815. v.typ.flags.incl tfVarIsPtr
  816. else:
  817. v.typ = iter[i]
  818. n[i] = newSymNode(v)
  819. if sfGenSym notin v.flags:
  820. if not isDiscardUnderscore(v): addDecl(c, v)
  821. elif v.owner == nil: v.owner = getCurrOwner(c)
  822. inc(c.p.nestedLoopCounter)
  823. openScope(c)
  824. n[^1] = semExprBranch(c, n[^1], flags)
  825. if efInTypeof notin flags:
  826. discardCheck(c, n[^1], flags)
  827. closeScope(c)
  828. dec(c.p.nestedLoopCounter)
  829. proc implicitIterator(c: PContext, it: string, arg: PNode): PNode =
  830. result = newNodeI(nkCall, arg.info)
  831. result.add(newIdentNode(getIdent(c.cache, it), arg.info))
  832. if arg.typ != nil and arg.typ.kind in {tyVar, tyLent}:
  833. result.add newDeref(arg)
  834. else:
  835. result.add arg
  836. result = semExprNoDeref(c, result, {efWantIterator})
  837. proc isTrivalStmtExpr(n: PNode): bool =
  838. for i in 0..<n.len-1:
  839. if n[i].kind notin {nkEmpty, nkCommentStmt}:
  840. return false
  841. result = true
  842. proc handleStmtMacro(c: PContext; n, selector: PNode; magicType: string;
  843. flags: TExprFlags): PNode =
  844. if selector.kind in nkCallKinds:
  845. # we transform
  846. # n := for a, b, c in m(x, y, z): Y
  847. # to
  848. # m(n)
  849. let maType = magicsys.getCompilerProc(c.graph, magicType)
  850. if maType == nil: return
  851. let headSymbol = selector[0]
  852. var o: TOverloadIter
  853. var match: PSym = nil
  854. var symx = initOverloadIter(o, c, headSymbol)
  855. while symx != nil:
  856. if symx.kind in {skTemplate, skMacro}:
  857. if symx.typ.len == 2 and symx.typ[1] == maType.typ:
  858. if match == nil:
  859. match = symx
  860. else:
  861. localError(c.config, n.info, errAmbiguousCallXYZ % [
  862. getProcHeader(c.config, match),
  863. getProcHeader(c.config, symx), $selector])
  864. symx = nextOverloadIter(o, c, headSymbol)
  865. if match == nil: return
  866. var callExpr = newNodeI(nkCall, n.info)
  867. callExpr.add newSymNode(match)
  868. callExpr.add n
  869. case match.kind
  870. of skMacro: result = semMacroExpr(c, callExpr, callExpr, match, flags)
  871. of skTemplate: result = semTemplateExpr(c, callExpr, match, flags)
  872. else: result = nil
  873. proc handleForLoopMacro(c: PContext; n: PNode; flags: TExprFlags): PNode =
  874. result = handleStmtMacro(c, n, n[^2], "ForLoopStmt", flags)
  875. proc handleCaseStmtMacro(c: PContext; n: PNode; flags: TExprFlags): PNode =
  876. # n[0] has been sem'checked and has a type. We use this to resolve
  877. # '`case`(n[0])' but then we pass 'n' to the `case` macro. This seems to
  878. # be the best solution.
  879. var toResolve = newNodeI(nkCall, n.info)
  880. toResolve.add newIdentNode(getIdent(c.cache, "case"), n.info)
  881. toResolve.add n[0]
  882. var errors: CandidateErrors
  883. var r = resolveOverloads(c, toResolve, toResolve, {skTemplate, skMacro}, {efNoDiagnostics},
  884. errors, false)
  885. if r.state == csMatch:
  886. var match = r.calleeSym
  887. markUsed(c, n[0].info, match)
  888. onUse(n[0].info, match)
  889. # but pass 'n' to the `case` macro, not 'n[0]':
  890. r.call[1] = n
  891. let toExpand = semResolvedCall(c, r, r.call, {})
  892. case match.kind
  893. of skMacro: result = semMacroExpr(c, toExpand, toExpand, match, flags)
  894. of skTemplate: result = semTemplateExpr(c, toExpand, match, flags)
  895. else: result = errorNode(c, n[0])
  896. elif r.state == csNoMatch:
  897. result = errorNode(c, n[0])
  898. if result.kind == nkEmpty:
  899. localError(c.config, n[0].info, errSelectorMustBeOfCertainTypes)
  900. # this would be the perfectly consistent solution with 'for loop macros',
  901. # but it kinda sucks for pattern matching as the matcher is not attached to
  902. # a type then:
  903. when false:
  904. result = handleStmtMacro(c, n, n[0], "CaseStmt")
  905. proc semFor(c: PContext, n: PNode; flags: TExprFlags): PNode =
  906. checkMinSonsLen(n, 3, c.config)
  907. result = handleForLoopMacro(c, n, flags)
  908. if result != nil: return result
  909. openScope(c)
  910. result = n
  911. n[^2] = semExprNoDeref(c, n[^2], {efWantIterator})
  912. var call = n[^2]
  913. if call.kind == nkStmtListExpr and (isTrivalStmtExpr(call) or (call.lastSon.kind in nkCallKinds and call.lastSon[0].sym.kind == skIterator)):
  914. call = call.lastSon
  915. n[^2] = call
  916. let isCallExpr = call.kind in nkCallKinds
  917. if isCallExpr and call[0].kind == nkSym and
  918. call[0].sym.magic in {mFields, mFieldPairs, mOmpParFor}:
  919. if call[0].sym.magic == mOmpParFor:
  920. result = semForVars(c, n, flags)
  921. result.transitionSonsKind(nkParForStmt)
  922. else:
  923. result = semForFields(c, n, call[0].sym.magic)
  924. elif isCallExpr and isClosureIterator(call[0].typ.skipTypes(abstractInst)):
  925. # first class iterator:
  926. result = semForVars(c, n, flags)
  927. elif not isCallExpr or call[0].kind != nkSym or
  928. call[0].sym.kind != skIterator:
  929. if n.len == 3:
  930. n[^2] = implicitIterator(c, "items", n[^2])
  931. elif n.len == 4:
  932. n[^2] = implicitIterator(c, "pairs", n[^2])
  933. else:
  934. localError(c.config, n[^2].info, "iterator within for loop context expected")
  935. result = semForVars(c, n, flags)
  936. else:
  937. result = semForVars(c, n, flags)
  938. # propagate any enforced VoidContext:
  939. if n[^1].typ == c.enforceVoidContext:
  940. result.typ = c.enforceVoidContext
  941. elif efInTypeof in flags:
  942. result.typ = result.lastSon.typ
  943. closeScope(c)
  944. proc semCase(c: PContext, n: PNode; flags: TExprFlags; expectedType: PType = nil): PNode =
  945. result = n
  946. checkMinSonsLen(n, 2, c.config)
  947. openScope(c)
  948. pushCaseContext(c, n)
  949. n[0] = semExprWithType(c, n[0])
  950. var chckCovered = false
  951. var covered: Int128 = toInt128(0)
  952. var typ = commonTypeBegin
  953. var expectedType = expectedType
  954. var hasElse = false
  955. let caseTyp = skipTypes(n[0].typ, abstractVar-{tyTypeDesc})
  956. const shouldChckCovered = {tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt64, tyBool}
  957. case caseTyp.kind
  958. of shouldChckCovered:
  959. chckCovered = true
  960. of tyRange:
  961. if skipTypes(caseTyp[0], abstractInst).kind in shouldChckCovered:
  962. chckCovered = true
  963. of tyFloat..tyFloat128, tyString, tyError:
  964. discard
  965. else:
  966. popCaseContext(c)
  967. closeScope(c)
  968. return handleCaseStmtMacro(c, n, flags)
  969. for i in 1..<n.len:
  970. setCaseContextIdx(c, i)
  971. var x = n[i]
  972. when defined(nimsuggest):
  973. if c.config.ideCmd == ideSug and exactEquals(c.config.m.trackPos, x.info) and caseTyp.kind == tyEnum:
  974. suggestEnum(c, x, caseTyp)
  975. case x.kind
  976. of nkOfBranch:
  977. checkMinSonsLen(x, 2, c.config)
  978. semCaseBranch(c, n, x, i, covered)
  979. var last = x.len-1
  980. x[last] = semExprBranchScope(c, x[last], expectedType)
  981. typ = commonType(c, typ, x[last])
  982. if not endsInNoReturn(x[last]):
  983. expectedType = typ
  984. of nkElifBranch:
  985. chckCovered = false
  986. checkSonsLen(x, 2, c.config)
  987. openScope(c)
  988. x[0] = forceBool(c, semExprWithType(c, x[0], expectedType = getSysType(c.graph, n.info, tyBool)))
  989. x[1] = semExprBranch(c, x[1], expectedType = expectedType)
  990. typ = commonType(c, typ, x[1])
  991. if not endsInNoReturn(x[1]):
  992. expectedType = typ
  993. closeScope(c)
  994. of nkElse:
  995. checkSonsLen(x, 1, c.config)
  996. x[0] = semExprBranchScope(c, x[0], expectedType)
  997. typ = commonType(c, typ, x[0])
  998. if not endsInNoReturn(x[0]):
  999. expectedType = typ
  1000. if (chckCovered and covered == toCover(c, n[0].typ)) or hasElse:
  1001. message(c.config, x.info, warnUnreachableElse)
  1002. hasElse = true
  1003. chckCovered = false
  1004. else:
  1005. illFormedAst(x, c.config)
  1006. if chckCovered:
  1007. if covered == toCover(c, n[0].typ):
  1008. hasElse = true
  1009. elif n[0].typ.skipTypes(abstractRange).kind in {tyEnum, tyChar}:
  1010. localError(c.config, n.info, "not all cases are covered; missing: $1" %
  1011. formatMissingEnums(c, n))
  1012. else:
  1013. localError(c.config, n.info, "not all cases are covered")
  1014. popCaseContext(c)
  1015. closeScope(c)
  1016. if isEmptyType(typ) or typ.kind in {tyNil, tyUntyped} or
  1017. (not hasElse and efInTypeof notin flags):
  1018. for i in 1..<n.len: discardCheck(c, n[i].lastSon, flags)
  1019. # propagate any enforced VoidContext:
  1020. if typ == c.enforceVoidContext:
  1021. result.typ = c.enforceVoidContext
  1022. else:
  1023. for i in 1..<n.len:
  1024. var it = n[i]
  1025. let j = it.len-1
  1026. if not endsInNoReturn(it[j]):
  1027. it[j] = fitNode(c, typ, it[j], it[j].info)
  1028. result.typ = typ
  1029. proc semRaise(c: PContext, n: PNode): PNode =
  1030. result = n
  1031. checkSonsLen(n, 1, c.config)
  1032. if n[0].kind != nkEmpty:
  1033. n[0] = semExprWithType(c, n[0])
  1034. var typ = n[0].typ
  1035. if not isImportedException(typ, c.config):
  1036. typ = typ.skipTypes({tyAlias, tyGenericInst, tyOwned})
  1037. if typ.kind != tyRef:
  1038. localError(c.config, n.info, errExprCannotBeRaised)
  1039. if typ.len > 0 and not isException(typ.lastSon):
  1040. localError(c.config, n.info, "raised object of type $1 does not inherit from Exception" % typeToString(typ))
  1041. proc addGenericParamListToScope(c: PContext, n: PNode) =
  1042. if n.kind != nkGenericParams: illFormedAst(n, c.config)
  1043. for i in 0..<n.len:
  1044. var a = n[i]
  1045. if a.kind == nkSym: addDecl(c, a.sym)
  1046. else: illFormedAst(a, c.config)
  1047. proc typeSectionTypeName(c: PContext; n: PNode): PNode =
  1048. if n.kind == nkPragmaExpr:
  1049. if n.len == 0: illFormedAst(n, c.config)
  1050. result = n[0]
  1051. else:
  1052. result = n
  1053. if result.kind != nkSym: illFormedAst(n, c.config)
  1054. proc typeDefLeftSidePass(c: PContext, typeSection: PNode, i: int) =
  1055. let typeDef = typeSection[i]
  1056. checkSonsLen(typeDef, 3, c.config)
  1057. var name = typeDef[0]
  1058. var s: PSym
  1059. if name.kind == nkDotExpr and typeDef[2].kind == nkObjectTy:
  1060. let pkgName = considerQuotedIdent(c, name[0])
  1061. let typName = considerQuotedIdent(c, name[1])
  1062. let pkg = c.graph.packageSyms.strTableGet(pkgName)
  1063. if pkg.isNil or pkg.kind != skPackage:
  1064. localError(c.config, name.info, "unknown package name: " & pkgName.s)
  1065. else:
  1066. let typsym = c.graph.packageTypes.strTableGet(typName)
  1067. if typsym.isNil:
  1068. s = semIdentDef(c, name[1], skType)
  1069. onDef(name[1].info, s)
  1070. s.typ = newTypeS(tyObject, c)
  1071. s.typ.sym = s
  1072. s.flags.incl sfForward
  1073. c.graph.packageTypes.strTableAdd s
  1074. addInterfaceDecl(c, s)
  1075. elif typsym.kind == skType and sfForward in typsym.flags:
  1076. s = typsym
  1077. addInterfaceDecl(c, s)
  1078. # PRTEMP no onDef here?
  1079. else:
  1080. localError(c.config, name.info, typsym.name.s & " is not a type that can be forwarded")
  1081. s = typsym
  1082. else:
  1083. s = semIdentDef(c, name, skType)
  1084. onDef(name.info, s)
  1085. s.typ = newTypeS(tyForward, c)
  1086. s.typ.sym = s # process pragmas:
  1087. if name.kind == nkPragmaExpr:
  1088. let rewritten = applyTypeSectionPragmas(c, name[1], typeDef)
  1089. if rewritten != nil:
  1090. typeSection[i] = rewritten
  1091. typeDefLeftSidePass(c, typeSection, i)
  1092. return
  1093. pragma(c, s, name[1], typePragmas)
  1094. if sfForward in s.flags:
  1095. # check if the symbol already exists:
  1096. let pkg = c.module.owner
  1097. if not isTopLevel(c) or pkg.isNil:
  1098. localError(c.config, name.info, "only top level types in a package can be 'package'")
  1099. else:
  1100. let typsym = c.graph.packageTypes.strTableGet(s.name)
  1101. if typsym != nil:
  1102. if sfForward notin typsym.flags or sfNoForward notin typsym.flags:
  1103. typeCompleted(typsym)
  1104. typsym.info = s.info
  1105. else:
  1106. localError(c.config, name.info, "cannot complete type '" & s.name.s & "' twice; " &
  1107. "previous type completion was here: " & c.config$typsym.info)
  1108. s = typsym
  1109. # add it here, so that recursive types are possible:
  1110. if sfGenSym notin s.flags: addInterfaceDecl(c, s)
  1111. elif s.owner == nil: s.owner = getCurrOwner(c)
  1112. if name.kind == nkPragmaExpr:
  1113. typeDef[0][0] = newSymNode(s)
  1114. else:
  1115. typeDef[0] = newSymNode(s)
  1116. proc typeSectionLeftSidePass(c: PContext, n: PNode) =
  1117. # process the symbols on the left side for the whole type section, before
  1118. # we even look at the type definitions on the right
  1119. for i in 0..<n.len:
  1120. var a = n[i]
  1121. when defined(nimsuggest):
  1122. if c.config.cmd == cmdIdeTools:
  1123. inc c.inTypeContext
  1124. suggestStmt(c, a)
  1125. dec c.inTypeContext
  1126. if a.kind == nkCommentStmt: continue
  1127. if a.kind != nkTypeDef: illFormedAst(a, c.config)
  1128. typeDefLeftSidePass(c, n, i)
  1129. proc checkCovariantParamsUsages(c: PContext; genericType: PType) =
  1130. var body = genericType[^1]
  1131. proc traverseSubTypes(c: PContext; t: PType): bool =
  1132. template error(msg) = localError(c.config, genericType.sym.info, msg)
  1133. result = false
  1134. template subresult(r) =
  1135. let sub = r
  1136. result = result or sub
  1137. case t.kind
  1138. of tyGenericParam:
  1139. t.flags.incl tfWeakCovariant
  1140. return true
  1141. of tyObject:
  1142. for field in t.n:
  1143. subresult traverseSubTypes(c, field.typ)
  1144. of tyArray:
  1145. return traverseSubTypes(c, t[1])
  1146. of tyProc:
  1147. for subType in t.sons:
  1148. if subType != nil:
  1149. subresult traverseSubTypes(c, subType)
  1150. if result:
  1151. error("non-invariant type param used in a proc type: " & $t)
  1152. of tySequence:
  1153. return traverseSubTypes(c, t[0])
  1154. of tyGenericInvocation:
  1155. let targetBody = t[0]
  1156. for i in 1..<t.len:
  1157. let param = t[i]
  1158. if param.kind == tyGenericParam:
  1159. if tfCovariant in param.flags:
  1160. let formalFlags = targetBody[i-1].flags
  1161. if tfCovariant notin formalFlags:
  1162. error("covariant param '" & param.sym.name.s &
  1163. "' used in a non-covariant position")
  1164. elif tfWeakCovariant in formalFlags:
  1165. param.flags.incl tfWeakCovariant
  1166. result = true
  1167. elif tfContravariant in param.flags:
  1168. let formalParam = targetBody[i-1].sym
  1169. if tfContravariant notin formalParam.typ.flags:
  1170. error("contravariant param '" & param.sym.name.s &
  1171. "' used in a non-contravariant position")
  1172. result = true
  1173. else:
  1174. subresult traverseSubTypes(c, param)
  1175. of tyAnd, tyOr, tyNot, tyStatic, tyBuiltInTypeClass, tyCompositeTypeClass:
  1176. error("non-invariant type parameters cannot be used with types such '" & $t & "'")
  1177. of tyUserTypeClass, tyUserTypeClassInst:
  1178. error("non-invariant type parameters are not supported in concepts")
  1179. of tyTuple:
  1180. for fieldType in t.sons:
  1181. subresult traverseSubTypes(c, fieldType)
  1182. of tyPtr, tyRef, tyVar, tyLent:
  1183. if t.base.kind == tyGenericParam: return true
  1184. return traverseSubTypes(c, t.base)
  1185. of tyDistinct, tyAlias, tySink, tyOwned:
  1186. return traverseSubTypes(c, t.lastSon)
  1187. of tyGenericInst:
  1188. internalAssert c.config, false
  1189. else:
  1190. discard
  1191. discard traverseSubTypes(c, body)
  1192. proc typeSectionRightSidePass(c: PContext, n: PNode) =
  1193. for i in 0..<n.len:
  1194. var a = n[i]
  1195. if a.kind == nkCommentStmt: continue
  1196. if a.kind != nkTypeDef: illFormedAst(a, c.config)
  1197. checkSonsLen(a, 3, c.config)
  1198. let name = typeSectionTypeName(c, a[0])
  1199. var s = name.sym
  1200. if s.magic == mNone and a[2].kind == nkEmpty:
  1201. localError(c.config, a.info, errImplOfXexpected % s.name.s)
  1202. if s.magic != mNone: processMagicType(c, s)
  1203. let oldFlags = s.typ.flags
  1204. if a[1].kind != nkEmpty:
  1205. # We have a generic type declaration here. In generic types,
  1206. # symbol lookup needs to be done here.
  1207. openScope(c)
  1208. pushOwner(c, s)
  1209. if s.magic == mNone: s.typ.kind = tyGenericBody
  1210. # XXX for generic type aliases this is not correct! We need the
  1211. # underlying Id really:
  1212. #
  1213. # type
  1214. # TGObj[T] = object
  1215. # TAlias[T] = TGObj[T]
  1216. #
  1217. s.typ.n = semGenericParamList(c, a[1], s.typ)
  1218. a[1] = s.typ.n
  1219. s.typ.size = -1 # could not be computed properly
  1220. # we fill it out later. For magic generics like 'seq', it won't be filled
  1221. # so we use tyNone instead of nil to not crash for strange conversions
  1222. # like: mydata.seq
  1223. rawAddSon(s.typ, newTypeS(tyNone, c))
  1224. s.ast = a
  1225. inc c.inGenericContext
  1226. var body = semTypeNode(c, a[2], nil)
  1227. dec c.inGenericContext
  1228. if body != nil:
  1229. body.sym = s
  1230. body.size = -1 # could not be computed properly
  1231. if body.kind == tyObject:
  1232. # add flags applied to generic type to object (nominal) type
  1233. incl(body.flags, oldFlags)
  1234. # {.inheritable, final.} is already disallowed, but
  1235. # object might have been assumed to be final
  1236. if tfInheritable in oldFlags and tfFinal in body.flags:
  1237. excl(body.flags, tfFinal)
  1238. s.typ[^1] = body
  1239. if tfCovariant in s.typ.flags:
  1240. checkCovariantParamsUsages(c, s.typ)
  1241. # XXX: This is a temporary limitation:
  1242. # The codegen currently produces various failures with
  1243. # generic imported types that have fields, but we need
  1244. # the fields specified in order to detect weak covariance.
  1245. # The proper solution is to teach the codegen how to handle
  1246. # such types, because this would offer various interesting
  1247. # possibilities such as instantiating C++ generic types with
  1248. # garbage collected Nim types.
  1249. if sfImportc in s.flags:
  1250. var body = s.typ.lastSon
  1251. if body.kind == tyObject:
  1252. # erases all declared fields
  1253. body.n.sons = @[]
  1254. popOwner(c)
  1255. closeScope(c)
  1256. elif a[2].kind != nkEmpty:
  1257. # process the type's body:
  1258. pushOwner(c, s)
  1259. var t = semTypeNode(c, a[2], s.typ)
  1260. if s.typ == nil:
  1261. s.typ = t
  1262. elif t != s.typ and (s.typ == nil or s.typ.kind != tyAlias):
  1263. # this can happen for e.g. tcan_alias_specialised_generic:
  1264. assignType(s.typ, t)
  1265. #debug s.typ
  1266. s.ast = a
  1267. popOwner(c)
  1268. # If the right hand side expression was a macro call we replace it with
  1269. # its evaluated result here so that we don't execute it once again in the
  1270. # final pass
  1271. if a[2].kind in nkCallKinds:
  1272. incl a[2].flags, nfSem # bug #10548
  1273. if sfExportc in s.flags and s.typ.kind == tyAlias:
  1274. localError(c.config, name.info, "{.exportc.} not allowed for type aliases")
  1275. if tfBorrowDot in s.typ.flags and s.typ.skipTypes({tyGenericBody}).kind != tyDistinct:
  1276. excl s.typ.flags, tfBorrowDot
  1277. localError(c.config, name.info, "only a 'distinct' type can borrow `.`")
  1278. let aa = a[2]
  1279. if aa.kind in {nkRefTy, nkPtrTy} and aa.len == 1 and
  1280. aa[0].kind == nkObjectTy:
  1281. # give anonymous object a dummy symbol:
  1282. var st = s.typ
  1283. if st.kind == tyGenericBody: st = st.lastSon
  1284. internalAssert c.config, st.kind in {tyPtr, tyRef}
  1285. internalAssert c.config, st.lastSon.sym == nil
  1286. incl st.flags, tfRefsAnonObj
  1287. let objTy = st.lastSon
  1288. # add flags for `ref object` etc to underlying `object`
  1289. incl(objTy.flags, oldFlags)
  1290. # {.inheritable, final.} is already disallowed, but
  1291. # object might have been assumed to be final
  1292. if tfInheritable in oldFlags and tfFinal in objTy.flags:
  1293. excl(objTy.flags, tfFinal)
  1294. let obj = newSym(skType, getIdent(c.cache, s.name.s & ":ObjectType"),
  1295. nextSymId c.idgen, getCurrOwner(c), s.info)
  1296. obj.flags.incl sfGeneratedType
  1297. let symNode = newSymNode(obj)
  1298. obj.ast = a.shallowCopy
  1299. case a[0].kind
  1300. of nkSym: obj.ast[0] = symNode
  1301. of nkPragmaExpr:
  1302. obj.ast[0] = a[0].shallowCopy
  1303. obj.ast[0][0] = symNode
  1304. obj.ast[0][1] = a[0][1]
  1305. else: assert(false)
  1306. obj.ast[1] = a[1]
  1307. obj.ast[2] = a[2][0]
  1308. if sfPure in s.flags:
  1309. obj.flags.incl sfPure
  1310. obj.typ = objTy
  1311. objTy.sym = obj
  1312. proc checkForMetaFields(c: PContext; n: PNode) =
  1313. proc checkMeta(c: PContext; n: PNode; t: PType) =
  1314. if t != nil and t.isMetaType and tfGenericTypeParam notin t.flags:
  1315. if t.kind == tyBuiltInTypeClass and t.len == 1 and t[0].kind == tyProc:
  1316. localError(c.config, n.info, ("'$1' is not a concrete type; " &
  1317. "for a callback without parameters use 'proc()'") % t.typeToString)
  1318. else:
  1319. localError(c.config, n.info, errTIsNotAConcreteType % t.typeToString)
  1320. if n.isNil: return
  1321. case n.kind
  1322. of nkRecList, nkRecCase:
  1323. for s in n: checkForMetaFields(c, s)
  1324. of nkOfBranch, nkElse:
  1325. checkForMetaFields(c, n.lastSon)
  1326. of nkSym:
  1327. let t = n.sym.typ
  1328. case t.kind
  1329. of tySequence, tySet, tyArray, tyOpenArray, tyVar, tyLent, tyPtr, tyRef,
  1330. tyProc, tyGenericInvocation, tyGenericInst, tyAlias, tySink, tyOwned:
  1331. let start = ord(t.kind in {tyGenericInvocation, tyGenericInst})
  1332. for i in start..<t.len:
  1333. checkMeta(c, n, t[i])
  1334. else:
  1335. checkMeta(c, n, t)
  1336. else:
  1337. internalAssert c.config, false
  1338. proc typeSectionFinalPass(c: PContext, n: PNode) =
  1339. for i in 0..<n.len:
  1340. var a = n[i]
  1341. if a.kind == nkCommentStmt: continue
  1342. let name = typeSectionTypeName(c, a[0])
  1343. var s = name.sym
  1344. # check the style here after the pragmas have been processed:
  1345. styleCheckDef(c, s)
  1346. # compute the type's size and check for illegal recursions:
  1347. if a[1].kind == nkEmpty:
  1348. var x = a[2]
  1349. if x.kind in nkCallKinds and nfSem in x.flags:
  1350. discard "already semchecked, see line marked with bug #10548"
  1351. else:
  1352. while x.kind in {nkStmtList, nkStmtListExpr} and x.len > 0:
  1353. x = x.lastSon
  1354. # we need the 'safeSkipTypes' here because illegally recursive types
  1355. # can enter at this point, see bug #13763
  1356. if x.kind notin {nkObjectTy, nkDistinctTy, nkEnumTy, nkEmpty} and
  1357. s.typ.safeSkipTypes(abstractPtrs).kind notin {tyObject, tyEnum}:
  1358. # type aliases are hard:
  1359. var t = semTypeNode(c, x, nil)
  1360. assert t != nil
  1361. if s.typ != nil and s.typ.kind notin {tyAlias, tySink}:
  1362. if t.kind in {tyProc, tyGenericInst} and not t.isMetaType:
  1363. assignType(s.typ, t)
  1364. s.typ.itemId = t.itemId
  1365. elif t.kind in {tyObject, tyEnum, tyDistinct}:
  1366. assert s.typ != nil
  1367. assignType(s.typ, t)
  1368. s.typ.itemId = t.itemId # same id
  1369. checkConstructedType(c.config, s.info, s.typ)
  1370. if s.typ.kind in {tyObject, tyTuple} and not s.typ.n.isNil:
  1371. checkForMetaFields(c, s.typ.n)
  1372. # fix bug #5170, bug #17162, bug #15526: ensure locally scoped types get a unique name:
  1373. if s.typ.kind in {tyEnum, tyRef, tyObject} and not isTopLevel(c):
  1374. incl(s.flags, sfGenSym)
  1375. #instAllTypeBoundOp(c, n.info)
  1376. proc semAllTypeSections(c: PContext; n: PNode): PNode =
  1377. proc gatherStmts(c: PContext; n: PNode; result: PNode) {.nimcall.} =
  1378. case n.kind
  1379. of nkIncludeStmt:
  1380. for i in 0..<n.len:
  1381. var f = checkModuleName(c.config, n[i])
  1382. if f != InvalidFileIdx:
  1383. if containsOrIncl(c.includedFiles, f.int):
  1384. localError(c.config, n.info, errRecursiveDependencyX % toMsgFilename(c.config, f))
  1385. else:
  1386. let code = c.graph.includeFileCallback(c.graph, c.module, f)
  1387. gatherStmts c, code, result
  1388. excl(c.includedFiles, f.int)
  1389. of nkStmtList:
  1390. for i in 0..<n.len:
  1391. gatherStmts(c, n[i], result)
  1392. of nkTypeSection:
  1393. incl n.flags, nfSem
  1394. typeSectionLeftSidePass(c, n)
  1395. result.add n
  1396. else:
  1397. result.add n
  1398. result = newNodeI(nkStmtList, n.info)
  1399. gatherStmts(c, n, result)
  1400. template rec(name) =
  1401. for i in 0..<result.len:
  1402. if result[i].kind == nkTypeSection:
  1403. name(c, result[i])
  1404. rec typeSectionRightSidePass
  1405. rec typeSectionFinalPass
  1406. when false:
  1407. # too beautiful to delete:
  1408. template rec(name; setbit=false) =
  1409. proc `name rec`(c: PContext; n: PNode) {.nimcall.} =
  1410. if n.kind == nkTypeSection:
  1411. when setbit: incl n.flags, nfSem
  1412. name(c, n)
  1413. elif n.kind == nkStmtList:
  1414. for i in 0..<n.len:
  1415. `name rec`(c, n[i])
  1416. `name rec`(c, n)
  1417. rec typeSectionLeftSidePass, true
  1418. rec typeSectionRightSidePass
  1419. rec typeSectionFinalPass
  1420. proc semTypeSection(c: PContext, n: PNode): PNode =
  1421. ## Processes a type section. This must be done in separate passes, in order
  1422. ## to allow the type definitions in the section to reference each other
  1423. ## without regard for the order of their definitions.
  1424. if sfNoForward notin c.module.flags or nfSem notin n.flags:
  1425. inc c.inTypeContext
  1426. typeSectionLeftSidePass(c, n)
  1427. typeSectionRightSidePass(c, n)
  1428. typeSectionFinalPass(c, n)
  1429. dec c.inTypeContext
  1430. result = n
  1431. proc semParamList(c: PContext, n, genericParams: PNode, s: PSym) =
  1432. s.typ = semProcTypeNode(c, n, genericParams, nil, s.kind)
  1433. proc addParams(c: PContext, n: PNode, kind: TSymKind) =
  1434. for i in 1..<n.len:
  1435. if n[i].kind == nkSym: addParamOrResult(c, n[i].sym, kind)
  1436. else: illFormedAst(n, c.config)
  1437. proc semBorrow(c: PContext, n: PNode, s: PSym) =
  1438. # search for the correct alias:
  1439. var b = searchForBorrowProc(c, c.currentScope.parent, s)
  1440. if b != nil:
  1441. # store the alias:
  1442. n[bodyPos] = newSymNode(b)
  1443. # Carry over the original symbol magic, this is necessary in order to ensure
  1444. # the semantic pass is correct
  1445. s.magic = b.magic
  1446. if b.typ != nil and b.typ.len > 0:
  1447. s.typ.n[0] = b.typ.n[0]
  1448. s.typ.flags = b.typ.flags
  1449. else:
  1450. localError(c.config, n.info, errNoSymbolToBorrowFromFound)
  1451. proc swapResult(n: PNode, sRes: PSym, dNode: PNode) =
  1452. ## Swap nodes that are (skResult) symbols to d(estination)Node.
  1453. for i in 0..<n.safeLen:
  1454. if n[i].kind == nkSym and n[i].sym == sRes:
  1455. n[i] = dNode
  1456. swapResult(n[i], sRes, dNode)
  1457. proc addResult(c: PContext, n: PNode, t: PType, owner: TSymKind) =
  1458. template genResSym(s) =
  1459. var s = newSym(skResult, getIdent(c.cache, "result"), nextSymId c.idgen,
  1460. getCurrOwner(c), n.info)
  1461. s.typ = t
  1462. incl(s.flags, sfUsed)
  1463. if owner == skMacro or t != nil:
  1464. if n.len > resultPos and n[resultPos] != nil:
  1465. if n[resultPos].sym.kind != skResult:
  1466. localError(c.config, n.info, "incorrect result proc symbol")
  1467. if n[resultPos].sym.owner != getCurrOwner(c):
  1468. # re-write result with new ownership, and re-write the proc accordingly
  1469. let sResSym = n[resultPos].sym
  1470. genResSym(s)
  1471. n[resultPos] = newSymNode(s)
  1472. swapResult(n, sResSym, n[resultPos])
  1473. c.p.resultSym = n[resultPos].sym
  1474. else:
  1475. genResSym(s)
  1476. c.p.resultSym = s
  1477. n.add newSymNode(c.p.resultSym)
  1478. addParamOrResult(c, c.p.resultSym, owner)
  1479. proc copyExcept(n: PNode, i: int): PNode =
  1480. result = copyNode(n)
  1481. for j in 0..<n.len:
  1482. if j != i: result.add(n[j])
  1483. proc semProcAnnotation(c: PContext, prc: PNode;
  1484. validPragmas: TSpecialWords): PNode =
  1485. var n = prc[pragmasPos]
  1486. if n == nil or n.kind == nkEmpty: return
  1487. for i in 0..<n.len:
  1488. let it = n[i]
  1489. let key = if it.kind in nkPragmaCallKinds and it.len >= 1: it[0] else: it
  1490. if whichPragma(it) != wInvalid:
  1491. # Not a custom pragma
  1492. continue
  1493. else:
  1494. let ident = considerQuotedIdent(c, key)
  1495. if strTableGet(c.userPragmas, ident) != nil:
  1496. continue # User defined pragma
  1497. else:
  1498. var amb = false
  1499. let sym = searchInScopes(c, ident, amb)
  1500. if sym != nil and sfCustomPragma in sym.flags:
  1501. continue # User custom pragma
  1502. # we transform ``proc p {.m, rest.}`` into ``m(do: proc p {.rest.})`` and
  1503. # let the semantic checker deal with it:
  1504. var x = newNodeI(nkCall, key.info)
  1505. x.add(key)
  1506. if it.kind in nkPragmaCallKinds and it.len > 1:
  1507. # pass pragma arguments to the macro too:
  1508. for i in 1..<it.len:
  1509. x.add(it[i])
  1510. # Drop the pragma from the list, this prevents getting caught in endless
  1511. # recursion when the nkCall is semanticized
  1512. prc[pragmasPos] = copyExcept(n, i)
  1513. if prc[pragmasPos].kind != nkEmpty and prc[pragmasPos].len == 0:
  1514. prc[pragmasPos] = c.graph.emptyNode
  1515. x.add(prc)
  1516. # recursion assures that this works for multiple macro annotations too:
  1517. var r = semOverloadedCall(c, x, x, {skMacro, skTemplate}, {efNoUndeclared})
  1518. if r == nil:
  1519. # Restore the old list of pragmas since we couldn't process this
  1520. prc[pragmasPos] = n
  1521. # No matching macro was found but there's always the possibility this may
  1522. # be a .pragma. template instead
  1523. continue
  1524. doAssert r[0].kind == nkSym
  1525. let m = r[0].sym
  1526. case m.kind
  1527. of skMacro: result = semMacroExpr(c, r, r, m, {})
  1528. of skTemplate: result = semTemplateExpr(c, r, m, {})
  1529. else:
  1530. prc[pragmasPos] = n
  1531. continue
  1532. doAssert result != nil
  1533. # since a proc annotation can set pragmas, we process these here again.
  1534. # This is required for SqueakNim-like export pragmas.
  1535. if result.kind in procDefs and result[namePos].kind == nkSym and
  1536. result[pragmasPos].kind != nkEmpty:
  1537. pragma(c, result[namePos].sym, result[pragmasPos], validPragmas)
  1538. return
  1539. proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode {.nosinks.} =
  1540. ## used for resolving 'auto' in lambdas based on their callsite
  1541. var n = n
  1542. let original = n[namePos].sym
  1543. let s = original #copySym(original, false)
  1544. #incl(s.flags, sfFromGeneric)
  1545. #s.owner = original
  1546. n = replaceTypesInBody(c, pt, n, original)
  1547. result = n
  1548. s.ast = result
  1549. n[namePos].sym = s
  1550. n[genericParamsPos] = c.graph.emptyNode
  1551. # for LL we need to avoid wrong aliasing
  1552. let params = copyTree n.typ.n
  1553. n[paramsPos] = params
  1554. s.typ = n.typ
  1555. for i in 1..<params.len:
  1556. if params[i].typ.kind in {tyTypeDesc, tyGenericParam,
  1557. tyFromExpr}+tyTypeClasses:
  1558. localError(c.config, params[i].info, "cannot infer type of parameter: " &
  1559. params[i].sym.name.s)
  1560. #params[i].sym.owner = s
  1561. openScope(c)
  1562. pushOwner(c, s)
  1563. addParams(c, params, skProc)
  1564. pushProcCon(c, s)
  1565. addResult(c, n, n.typ[0], skProc)
  1566. s.ast[bodyPos] = hloBody(c, semProcBody(c, n[bodyPos], n.typ[0]))
  1567. trackProc(c, s, s.ast[bodyPos])
  1568. popProcCon(c)
  1569. popOwner(c)
  1570. closeScope(c)
  1571. if optOwnedRefs in c.config.globalOptions and result.typ != nil:
  1572. result.typ = makeVarType(c, result.typ, tyOwned)
  1573. # alternative variant (not quite working):
  1574. # var prc = arg[0].sym
  1575. # let inferred = c.semGenerateInstance(c, prc, m.bindings, arg.info)
  1576. # result = inferred.ast
  1577. # result.kind = arg.kind
  1578. proc activate(c: PContext, n: PNode) =
  1579. # XXX: This proc is part of my plan for getting rid of
  1580. # forward declarations. stay tuned.
  1581. when false:
  1582. # well for now it breaks code ...
  1583. case n.kind
  1584. of nkLambdaKinds:
  1585. discard semLambda(c, n, {})
  1586. of nkCallKinds:
  1587. for i in 1..<n.len: activate(c, n[i])
  1588. else:
  1589. discard
  1590. proc maybeAddResult(c: PContext, s: PSym, n: PNode) =
  1591. if s.kind == skMacro:
  1592. let resultType = sysTypeFromName(c.graph, n.info, "NimNode")
  1593. addResult(c, n, resultType, s.kind)
  1594. elif s.typ[0] != nil and not isInlineIterator(s.typ):
  1595. addResult(c, n, s.typ[0], s.kind)
  1596. proc canonType(c: PContext, t: PType): PType =
  1597. if t.kind == tySequence:
  1598. result = c.graph.sysTypes[tySequence]
  1599. else:
  1600. result = t
  1601. proc prevDestructor(c: PContext; prevOp: PSym; obj: PType; info: TLineInfo) =
  1602. var msg = "cannot bind another '" & prevOp.name.s & "' to: " & typeToString(obj)
  1603. if sfOverriden notin prevOp.flags:
  1604. msg.add "; previous declaration was constructed here implicitly: " & (c.config $ prevOp.info)
  1605. else:
  1606. msg.add "; previous declaration was here: " & (c.config $ prevOp.info)
  1607. localError(c.config, info, errGenerated, msg)
  1608. proc whereToBindTypeHook(c: PContext; t: PType): PType =
  1609. result = t
  1610. while true:
  1611. if result.kind in {tyGenericBody, tyGenericInst}: result = result.lastSon
  1612. elif result.kind == tyGenericInvocation: result = result[0]
  1613. else: break
  1614. if result.kind in {tyObject, tyDistinct, tySequence, tyString}:
  1615. result = canonType(c, result)
  1616. proc bindTypeHook(c: PContext; s: PSym; n: PNode; op: TTypeAttachedOp) =
  1617. let t = s.typ
  1618. var noError = false
  1619. let cond = if op == attachedDestructor:
  1620. t.len == 2 and t[0] == nil and t[1].kind == tyVar
  1621. elif op == attachedTrace:
  1622. t.len == 3 and t[0] == nil and t[1].kind == tyVar and t[2].kind == tyPointer
  1623. else:
  1624. t.len >= 2 and t[0] == nil
  1625. if cond:
  1626. var obj = t[1].skipTypes({tyVar})
  1627. while true:
  1628. incl(obj.flags, tfHasAsgn)
  1629. if obj.kind in {tyGenericBody, tyGenericInst}: obj = obj.lastSon
  1630. elif obj.kind == tyGenericInvocation: obj = obj[0]
  1631. else: break
  1632. if obj.kind in {tyObject, tyDistinct, tySequence, tyString}:
  1633. obj = canonType(c, obj)
  1634. let ao = getAttachedOp(c.graph, obj, op)
  1635. if ao == s:
  1636. discard "forward declared destructor"
  1637. elif ao.isNil and tfCheckedForDestructor notin obj.flags:
  1638. setAttachedOp(c.graph, c.module.position, obj, op, s)
  1639. else:
  1640. prevDestructor(c, ao, obj, n.info)
  1641. noError = true
  1642. if obj.owner.getModule != s.getModule:
  1643. localError(c.config, n.info, errGenerated,
  1644. "type bound operation `" & s.name.s & "` can be defined only in the same module with its type (" & obj.typeToString() & ")")
  1645. if not noError and sfSystemModule notin s.owner.flags:
  1646. if op == attachedTrace:
  1647. localError(c.config, n.info, errGenerated,
  1648. "signature for '=trace' must be proc[T: object](x: var T; env: pointer)")
  1649. else:
  1650. localError(c.config, n.info, errGenerated,
  1651. "signature for '" & s.name.s & "' must be proc[T: object](x: var T)")
  1652. incl(s.flags, sfUsed)
  1653. incl(s.flags, sfOverriden)
  1654. proc semOverride(c: PContext, s: PSym, n: PNode) =
  1655. let name = s.name.s.normalize
  1656. case name
  1657. of "=destroy":
  1658. bindTypeHook(c, s, n, attachedDestructor)
  1659. if s.ast != nil:
  1660. if s.ast[pragmasPos].kind == nkEmpty:
  1661. s.ast[pragmasPos] = newNodeI(nkPragma, s.info)
  1662. s.ast[pragmasPos].add newTree(nkExprColonExpr,
  1663. newIdentNode(c.cache.getIdent("raises"), s.info), newNodeI(nkBracket, s.info))
  1664. of "deepcopy", "=deepcopy":
  1665. if s.typ.len == 2 and
  1666. s.typ[1].skipTypes(abstractInst).kind in {tyRef, tyPtr} and
  1667. sameType(s.typ[1], s.typ[0]):
  1668. # Note: we store the deepCopy in the base of the pointer to mitigate
  1669. # the problem that pointers are structural types:
  1670. var t = s.typ[1].skipTypes(abstractInst).lastSon.skipTypes(abstractInst)
  1671. while true:
  1672. if t.kind == tyGenericBody: t = t.lastSon
  1673. elif t.kind == tyGenericInvocation: t = t[0]
  1674. else: break
  1675. if t.kind in {tyObject, tyDistinct, tyEnum, tySequence, tyString}:
  1676. if getAttachedOp(c.graph, t, attachedDeepCopy).isNil:
  1677. setAttachedOp(c.graph, c.module.position, t, attachedDeepCopy, s)
  1678. else:
  1679. localError(c.config, n.info, errGenerated,
  1680. "cannot bind another 'deepCopy' to: " & typeToString(t))
  1681. else:
  1682. localError(c.config, n.info, errGenerated,
  1683. "cannot bind 'deepCopy' to: " & typeToString(t))
  1684. if t.owner.getModule != s.getModule:
  1685. localError(c.config, n.info, errGenerated,
  1686. "type bound operation `" & name & "` can be defined only in the same module with its type (" & t.typeToString() & ")")
  1687. else:
  1688. localError(c.config, n.info, errGenerated,
  1689. "signature for 'deepCopy' must be proc[T: ptr|ref](x: T): T")
  1690. incl(s.flags, sfUsed)
  1691. incl(s.flags, sfOverriden)
  1692. of "=", "=copy", "=sink":
  1693. if s.magic == mAsgn: return
  1694. incl(s.flags, sfUsed)
  1695. incl(s.flags, sfOverriden)
  1696. let t = s.typ
  1697. if t.len == 3 and t[0] == nil and t[1].kind == tyVar:
  1698. var obj = t[1][0]
  1699. while true:
  1700. incl(obj.flags, tfHasAsgn)
  1701. if obj.kind == tyGenericBody: obj = obj.lastSon
  1702. elif obj.kind == tyGenericInvocation: obj = obj[0]
  1703. else: break
  1704. var objB = t[2]
  1705. while true:
  1706. if objB.kind == tyGenericBody: objB = objB.lastSon
  1707. elif objB.kind in {tyGenericInvocation, tyGenericInst}:
  1708. objB = objB[0]
  1709. else: break
  1710. if obj.kind in {tyObject, tyDistinct, tySequence, tyString} and sameType(obj, objB):
  1711. # attach these ops to the canonical tySequence
  1712. obj = canonType(c, obj)
  1713. #echo "ATTACHING TO ", obj.id, " ", s.name.s, " ", cast[int](obj)
  1714. let k = if name == "=" or name == "=copy": attachedAsgn else: attachedSink
  1715. let ao = getAttachedOp(c.graph, obj, k)
  1716. if ao == s:
  1717. discard "forward declared op"
  1718. elif ao.isNil and tfCheckedForDestructor notin obj.flags:
  1719. setAttachedOp(c.graph, c.module.position, obj, k, s)
  1720. else:
  1721. prevDestructor(c, ao, obj, n.info)
  1722. if obj.owner.getModule != s.getModule:
  1723. localError(c.config, n.info, errGenerated,
  1724. "type bound operation `" & name & "` can be defined only in the same module with its type (" & obj.typeToString() & ")")
  1725. return
  1726. if sfSystemModule notin s.owner.flags:
  1727. localError(c.config, n.info, errGenerated,
  1728. "signature for '" & s.name.s & "' must be proc[T: object](x: var T; y: T)")
  1729. of "=trace":
  1730. if s.magic != mTrace:
  1731. bindTypeHook(c, s, n, attachedTrace)
  1732. else:
  1733. if sfOverriden in s.flags:
  1734. localError(c.config, n.info, errGenerated,
  1735. "'destroy' or 'deepCopy' expected for 'override'")
  1736. proc cursorInProcAux(conf: ConfigRef; n: PNode): bool =
  1737. if inCheckpoint(n.info, conf.m.trackPos) != cpNone: return true
  1738. for i in 0..<n.safeLen:
  1739. if cursorInProcAux(conf, n[i]): return true
  1740. proc cursorInProc(conf: ConfigRef; n: PNode): bool =
  1741. if n.info.fileIndex == conf.m.trackPos.fileIndex:
  1742. result = cursorInProcAux(conf, n)
  1743. proc hasObjParam(s: PSym): bool =
  1744. var t = s.typ
  1745. for col in 1..<t.len:
  1746. if skipTypes(t[col], skipPtrs).kind == tyObject:
  1747. return true
  1748. proc finishMethod(c: PContext, s: PSym) =
  1749. if hasObjParam(s):
  1750. methodDef(c.graph, c.idgen, s)
  1751. proc semMethodPrototype(c: PContext; s: PSym; n: PNode) =
  1752. if s.isGenericRoutine:
  1753. let tt = s.typ
  1754. var foundObj = false
  1755. # we start at 1 for now so that tparsecombnum continues to compile.
  1756. # XXX Revisit this problem later.
  1757. for col in 1..<tt.len:
  1758. let t = tt[col]
  1759. if t != nil and t.kind == tyGenericInvocation:
  1760. var x = skipTypes(t[0], {tyVar, tyLent, tyPtr, tyRef, tyGenericInst,
  1761. tyGenericInvocation, tyGenericBody,
  1762. tyAlias, tySink, tyOwned})
  1763. if x.kind == tyObject and t.len-1 == n[genericParamsPos].len:
  1764. foundObj = true
  1765. addMethodToGeneric(c.graph, c.module.position, x, col, s)
  1766. message(c.config, n.info, warnDeprecated, "generic methods are deprecated")
  1767. #if not foundObj:
  1768. # message(c.config, n.info, warnDeprecated, "generic method not attachable to object type is deprecated")
  1769. else:
  1770. # why check for the body? bug #2400 has none. Checking for sfForward makes
  1771. # no sense either.
  1772. # and result[bodyPos].kind != nkEmpty:
  1773. if hasObjParam(s):
  1774. methodDef(c.graph, c.idgen, s)
  1775. else:
  1776. localError(c.config, n.info, "'method' needs a parameter that has an object type")
  1777. proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
  1778. validPragmas: TSpecialWords, flags: TExprFlags = {}): PNode =
  1779. result = semProcAnnotation(c, n, validPragmas)
  1780. if result != nil: return result
  1781. result = n
  1782. checkMinSonsLen(n, bodyPos + 1, c.config)
  1783. let isAnon = n[namePos].kind == nkEmpty
  1784. var s: PSym
  1785. case n[namePos].kind
  1786. of nkEmpty:
  1787. s = newSym(kind, c.cache.idAnon, nextSymId c.idgen, c.getCurrOwner, n.info)
  1788. s.flags.incl sfUsed
  1789. n[namePos] = newSymNode(s)
  1790. of nkSym:
  1791. s = n[namePos].sym
  1792. s.owner = c.getCurrOwner
  1793. else:
  1794. s = semIdentDef(c, n[namePos], kind)
  1795. n[namePos] = newSymNode(s)
  1796. when false:
  1797. # disable for now
  1798. if sfNoForward in c.module.flags and
  1799. sfSystemModule notin c.module.flags:
  1800. addInterfaceOverloadableSymAt(c, c.currentScope, s)
  1801. s.flags.incl sfForward
  1802. return
  1803. assert s.kind in skProcKinds
  1804. s.ast = n
  1805. s.options = c.config.options
  1806. #s.scope = c.currentScope
  1807. # before compiling the proc params & body, set as current the scope
  1808. # where the proc was declared
  1809. let declarationScope = c.currentScope
  1810. pushOwner(c, s)
  1811. openScope(c)
  1812. # process parameters:
  1813. # generic parameters, parameters, and also the implicit generic parameters
  1814. # within are analysed. This is often the entirety of their semantic analysis
  1815. # but later we will have to do a check for forward declarations, which can by
  1816. # way of pragmas, default params, and so on invalidate this parsing.
  1817. # Nonetheless, we need to carry out this analysis to perform the search for a
  1818. # potential forward declaration.
  1819. setGenericParamsMisc(c, n)
  1820. if n[paramsPos].kind != nkEmpty:
  1821. semParamList(c, n[paramsPos], n[genericParamsPos], s)
  1822. else:
  1823. s.typ = newProcType(c, n.info)
  1824. if n[genericParamsPos].safeLen == 0:
  1825. # if there exist no explicit or implicit generic parameters, then this is
  1826. # at most a nullary generic (generic with no type params). Regardless of
  1827. # whether it's a nullary generic or non-generic, we restore the original.
  1828. # In the case of `nkEmpty` it's non-generic and an empty `nkGeneircParams`
  1829. # is a nullary generic.
  1830. #
  1831. # Remarks about nullary generics vs non-generics:
  1832. # The difference between a non-generic and nullary generic is minor in
  1833. # most cases but there are subtle and significant differences as well.
  1834. # Due to instantiation that generic procs go through, a static echo in the
  1835. # body of a nullary generic will not be executed immediately, as it's
  1836. # instantiated and not immediately evaluated.
  1837. n[genericParamsPos] = n[miscPos][1]
  1838. n[miscPos] = c.graph.emptyNode
  1839. if tfTriggersCompileTime in s.typ.flags: incl(s.flags, sfCompileTime)
  1840. if n[patternPos].kind != nkEmpty:
  1841. n[patternPos] = semPattern(c, n[patternPos], s)
  1842. if s.kind == skIterator:
  1843. s.typ.flags.incl(tfIterator)
  1844. elif s.kind == skFunc:
  1845. incl(s.flags, sfNoSideEffect)
  1846. incl(s.typ.flags, tfNoSideEffect)
  1847. var (proto, comesFromShadowScope) =
  1848. if isAnon: (nil, false)
  1849. else: searchForProc(c, declarationScope, s)
  1850. if proto == nil and sfForward in s.flags and n[bodyPos].kind != nkEmpty:
  1851. ## In cases such as a macro generating a proc with a gensymmed name we
  1852. ## know `searchForProc` will not find it and sfForward will be set. In
  1853. ## such scenarios the sym is shared between forward declaration and we
  1854. ## can treat the `s` as the proto.
  1855. ## To differentiate between that happening and a macro just returning a
  1856. ## forward declaration that has been typed before we check if the body
  1857. ## is not empty. This has the sideeffect of allowing multiple forward
  1858. ## declarations if they share the same sym.
  1859. ## See the "doubly-typed forward decls" case in tmacros_issues.nim
  1860. proto = s
  1861. let hasProto = proto != nil
  1862. # set the default calling conventions
  1863. case s.kind
  1864. of skIterator:
  1865. if s.typ.callConv != ccClosure:
  1866. s.typ.callConv = if isAnon: ccClosure else: ccInline
  1867. of skMacro, skTemplate:
  1868. # we don't bother setting calling conventions for macros and templates
  1869. discard
  1870. else:
  1871. # NB: procs with a forward decl have theirs determined by the forward decl
  1872. if not hasProto:
  1873. # in this case we're either a forward declaration or we're an impl without
  1874. # a forward decl. We set the calling convention or will be set during
  1875. # pragma analysis further down.
  1876. s.typ.callConv = lastOptionEntry(c).defaultCC
  1877. if not hasProto and sfGenSym notin s.flags: #and not isAnon:
  1878. if s.kind in OverloadableSyms:
  1879. addInterfaceOverloadableSymAt(c, declarationScope, s)
  1880. else:
  1881. addInterfaceDeclAt(c, declarationScope, s)
  1882. pragmaCallable(c, s, n, validPragmas)
  1883. if not hasProto:
  1884. implicitPragmas(c, s, n.info, validPragmas)
  1885. if n[pragmasPos].kind != nkEmpty and sfBorrow notin s.flags:
  1886. setEffectsForProcType(c.graph, s.typ, n[pragmasPos], s)
  1887. s.typ.flags.incl tfEffectSystemWorkaround
  1888. # To ease macro generation that produce forwarded .async procs we now
  1889. # allow a bit redundancy in the pragma declarations. The rule is
  1890. # a prototype's pragma list must be a superset of the current pragma
  1891. # list.
  1892. # XXX This needs more checks eventually, for example that external
  1893. # linking names do agree:
  1894. if hasProto and (
  1895. # calling convention mismatch
  1896. tfExplicitCallConv in s.typ.flags and proto.typ.callConv != s.typ.callConv or
  1897. # implementation has additional pragmas
  1898. proto.typ.flags < s.typ.flags):
  1899. localError(c.config, n[pragmasPos].info, errPragmaOnlyInHeaderOfProcX %
  1900. ("'" & proto.name.s & "' from " & c.config$proto.info &
  1901. " '" & s.name.s & "' from " & c.config$s.info))
  1902. styleCheckDef(c, s)
  1903. if hasProto:
  1904. onDefResolveForward(n[namePos].info, proto)
  1905. else:
  1906. onDef(n[namePos].info, s)
  1907. if hasProto:
  1908. if sfForward notin proto.flags and proto.magic == mNone:
  1909. wrongRedefinition(c, n.info, proto.name.s, proto.info)
  1910. if not comesFromShadowScope:
  1911. excl(proto.flags, sfForward)
  1912. incl(proto.flags, sfWasForwarded)
  1913. suggestSym(c.graph, s.info, proto, c.graph.usageSym)
  1914. closeScope(c) # close scope with wrong parameter symbols
  1915. openScope(c) # open scope for old (correct) parameter symbols
  1916. if proto.ast[genericParamsPos].isGenericParams:
  1917. addGenericParamListToScope(c, proto.ast[genericParamsPos])
  1918. addParams(c, proto.typ.n, proto.kind)
  1919. proto.info = s.info # more accurate line information
  1920. proto.options = s.options
  1921. s = proto
  1922. n[genericParamsPos] = proto.ast[genericParamsPos]
  1923. n[paramsPos] = proto.ast[paramsPos]
  1924. n[pragmasPos] = proto.ast[pragmasPos]
  1925. if n[namePos].kind != nkSym: internalError(c.config, n.info, "semProcAux")
  1926. n[namePos].sym = proto
  1927. if importantComments(c.config) and proto.ast.comment.len > 0:
  1928. n.comment = proto.ast.comment
  1929. proto.ast = n # needed for code generation
  1930. popOwner(c)
  1931. pushOwner(c, s)
  1932. if not isAnon:
  1933. if sfOverriden in s.flags or s.name.s[0] == '=': semOverride(c, s, n)
  1934. elif s.name.s[0] in {'.', '('}:
  1935. if s.name.s in [".", ".()", ".="] and {Feature.destructor, dotOperators} * c.features == {}:
  1936. localError(c.config, n.info, "the overloaded " & s.name.s &
  1937. " operator has to be enabled with {.experimental: \"dotOperators\".}")
  1938. elif s.name.s == "()" and callOperator notin c.features:
  1939. localError(c.config, n.info, "the overloaded " & s.name.s &
  1940. " operator has to be enabled with {.experimental: \"callOperator\".}")
  1941. if n[bodyPos].kind != nkEmpty and sfError notin s.flags:
  1942. # for DLL generation we allow sfImportc to have a body, for use in VM
  1943. if sfBorrow in s.flags:
  1944. localError(c.config, n[bodyPos].info, errImplOfXNotAllowed % s.name.s)
  1945. if c.config.ideCmd in {ideSug, ideCon} and s.kind notin {skMacro, skTemplate} and not
  1946. cursorInProc(c.config, n[bodyPos]):
  1947. # speed up nimsuggest
  1948. if s.kind == skMethod: semMethodPrototype(c, s, n)
  1949. elif isAnon:
  1950. let gp = n[genericParamsPos]
  1951. if gp.kind == nkEmpty or (gp.len == 1 and tfRetType in gp[0].typ.flags):
  1952. # absolutely no generics (empty) or a single generic return type are
  1953. # allowed, everything else, including a nullary generic is an error.
  1954. pushProcCon(c, s)
  1955. addResult(c, n, s.typ[0], skProc)
  1956. s.ast[bodyPos] = hloBody(c, semProcBody(c, n[bodyPos], s.typ[0]))
  1957. trackProc(c, s, s.ast[bodyPos])
  1958. popProcCon(c)
  1959. elif efOperand notin flags:
  1960. localError(c.config, n.info, errGenericLambdaNotAllowed)
  1961. else:
  1962. pushProcCon(c, s)
  1963. if n[genericParamsPos].kind == nkEmpty or s.kind in {skMacro, skTemplate}:
  1964. # Macros and Templates can have generic parameters, but they are only
  1965. # used for overload resolution (there is no instantiation of the symbol)
  1966. if s.kind notin {skMacro, skTemplate} and s.magic == mNone: paramsTypeCheck(c, s.typ)
  1967. maybeAddResult(c, s, n)
  1968. let resultType =
  1969. if s.kind == skMacro:
  1970. sysTypeFromName(c.graph, n.info, "NimNode")
  1971. elif not isInlineIterator(s.typ):
  1972. s.typ[0]
  1973. else:
  1974. nil
  1975. # semantic checking also needed with importc in case used in VM
  1976. s.ast[bodyPos] = hloBody(c, semProcBody(c, n[bodyPos], resultType))
  1977. # unfortunately we cannot skip this step when in 'system.compiles'
  1978. # context as it may even be evaluated in 'system.compiles':
  1979. trackProc(c, s, s.ast[bodyPos])
  1980. else:
  1981. if (s.typ[0] != nil and s.kind != skIterator):
  1982. addDecl(c, newSym(skUnknown, getIdent(c.cache, "result"), nextSymId c.idgen, s, n.info))
  1983. openScope(c)
  1984. n[bodyPos] = semGenericStmt(c, n[bodyPos])
  1985. closeScope(c)
  1986. if s.magic == mNone:
  1987. fixupInstantiatedSymbols(c, s)
  1988. if s.kind == skMethod: semMethodPrototype(c, s, n)
  1989. popProcCon(c)
  1990. else:
  1991. if s.kind == skMethod: semMethodPrototype(c, s, n)
  1992. if hasProto: localError(c.config, n.info, errImplOfXexpected % proto.name.s)
  1993. if {sfImportc, sfBorrow, sfError} * s.flags == {} and s.magic == mNone:
  1994. # this is a forward declaration and we're building the prototype
  1995. if s.kind in {skProc, skFunc} and s.typ[0] != nil and s.typ[0].kind == tyAnything:
  1996. localError(c.config, n[paramsPos][0].info, "return type 'auto' cannot be used in forward declarations")
  1997. incl(s.flags, sfForward)
  1998. incl(s.flags, sfWasForwarded)
  1999. elif sfBorrow in s.flags: semBorrow(c, n, s)
  2000. sideEffectsCheck(c, s)
  2001. closeScope(c) # close scope for parameters
  2002. # c.currentScope = oldScope
  2003. popOwner(c)
  2004. if n[patternPos].kind != nkEmpty:
  2005. c.patterns.add(s)
  2006. if isAnon:
  2007. n.transitionSonsKind(nkLambda)
  2008. result.typ = s.typ
  2009. if optOwnedRefs in c.config.globalOptions:
  2010. result.typ = makeVarType(c, result.typ, tyOwned)
  2011. elif isTopLevel(c) and s.kind != skIterator and s.typ.callConv == ccClosure:
  2012. localError(c.config, s.info, "'.closure' calling convention for top level routines is invalid")
  2013. proc determineType(c: PContext, s: PSym) =
  2014. if s.typ != nil: return
  2015. #if s.magic != mNone: return
  2016. #if s.ast.isNil: return
  2017. discard semProcAux(c, s.ast, s.kind, {})
  2018. proc semIterator(c: PContext, n: PNode): PNode =
  2019. # gensym'ed iterator?
  2020. if n[namePos].kind == nkSym:
  2021. # gensym'ed iterators might need to become closure iterators:
  2022. n[namePos].sym.owner = getCurrOwner(c)
  2023. n[namePos].sym.transitionRoutineSymKind(skIterator)
  2024. result = semProcAux(c, n, skIterator, iteratorPragmas)
  2025. # bug #7093: if after a macro transformation we don't have an
  2026. # nkIteratorDef aynmore, return. The iterator then might have been
  2027. # sem'checked already. (Or not, if the macro skips it.)
  2028. if result.kind != n.kind: return
  2029. var s = result[namePos].sym
  2030. var t = s.typ
  2031. if t[0] == nil and s.typ.callConv != ccClosure:
  2032. localError(c.config, n.info, "iterator needs a return type")
  2033. # iterators are either 'inline' or 'closure'; for backwards compatibility,
  2034. # we require first class iterators to be marked with 'closure' explicitly
  2035. # -- at least for 0.9.2.
  2036. if s.typ.callConv == ccClosure:
  2037. incl(s.typ.flags, tfCapturesEnv)
  2038. else:
  2039. s.typ.callConv = ccInline
  2040. if n[bodyPos].kind == nkEmpty and s.magic == mNone and c.inConceptDecl == 0:
  2041. localError(c.config, n.info, errImplOfXexpected % s.name.s)
  2042. if optOwnedRefs in c.config.globalOptions and result.typ != nil:
  2043. result.typ = makeVarType(c, result.typ, tyOwned)
  2044. result.typ.callConv = ccClosure
  2045. proc semProc(c: PContext, n: PNode): PNode =
  2046. result = semProcAux(c, n, skProc, procPragmas)
  2047. proc semFunc(c: PContext, n: PNode): PNode =
  2048. let validPragmas = if n[namePos].kind != nkEmpty: procPragmas
  2049. else: lambdaPragmas
  2050. result = semProcAux(c, n, skFunc, validPragmas)
  2051. proc semMethod(c: PContext, n: PNode): PNode =
  2052. if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "method")
  2053. result = semProcAux(c, n, skMethod, methodPragmas)
  2054. # macros can transform converters to nothing:
  2055. if namePos >= result.safeLen: return result
  2056. # bug #7093: if after a macro transformation we don't have an
  2057. # nkIteratorDef aynmore, return. The iterator then might have been
  2058. # sem'checked already. (Or not, if the macro skips it.)
  2059. if result.kind != nkMethodDef: return
  2060. var s = result[namePos].sym
  2061. # we need to fix the 'auto' return type for the dispatcher here (see tautonotgeneric
  2062. # test case):
  2063. let disp = getDispatcher(s)
  2064. # auto return type?
  2065. if disp != nil and disp.typ[0] != nil and disp.typ[0].kind == tyUntyped:
  2066. let ret = s.typ[0]
  2067. disp.typ[0] = ret
  2068. if disp.ast[resultPos].kind == nkSym:
  2069. if isEmptyType(ret): disp.ast[resultPos] = c.graph.emptyNode
  2070. else: disp.ast[resultPos].sym.typ = ret
  2071. proc semConverterDef(c: PContext, n: PNode): PNode =
  2072. if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "converter")
  2073. result = semProcAux(c, n, skConverter, converterPragmas)
  2074. # macros can transform converters to nothing:
  2075. if namePos >= result.safeLen: return result
  2076. # bug #7093: if after a macro transformation we don't have an
  2077. # nkIteratorDef aynmore, return. The iterator then might have been
  2078. # sem'checked already. (Or not, if the macro skips it.)
  2079. if result.kind != nkConverterDef: return
  2080. var s = result[namePos].sym
  2081. var t = s.typ
  2082. if t[0] == nil: localError(c.config, n.info, errXNeedsReturnType % "converter")
  2083. if t.len != 2: localError(c.config, n.info, "a converter takes exactly one argument")
  2084. addConverterDef(c, LazySym(sym: s))
  2085. proc semMacroDef(c: PContext, n: PNode): PNode =
  2086. result = semProcAux(c, n, skMacro, macroPragmas)
  2087. # macros can transform macros to nothing:
  2088. if namePos >= result.safeLen: return result
  2089. # bug #7093: if after a macro transformation we don't have an
  2090. # nkIteratorDef aynmore, return. The iterator then might have been
  2091. # sem'checked already. (Or not, if the macro skips it.)
  2092. if result.kind != nkMacroDef: return
  2093. var s = result[namePos].sym
  2094. var t = s.typ
  2095. var allUntyped = true
  2096. for i in 1..<t.n.len:
  2097. let param = t.n[i].sym
  2098. if param.typ.kind != tyUntyped: allUntyped = false
  2099. if allUntyped: incl(s.flags, sfAllUntyped)
  2100. if n[bodyPos].kind == nkEmpty:
  2101. localError(c.config, n.info, errImplOfXexpected % s.name.s)
  2102. proc incMod(c: PContext, n: PNode, it: PNode, includeStmtResult: PNode) =
  2103. var f = checkModuleName(c.config, it)
  2104. if f != InvalidFileIdx:
  2105. addIncludeFileDep(c, f)
  2106. onProcessing(c.graph, f, "include", c.module)
  2107. if containsOrIncl(c.includedFiles, f.int):
  2108. localError(c.config, n.info, errRecursiveDependencyX % toMsgFilename(c.config, f))
  2109. else:
  2110. includeStmtResult.add semStmt(c, c.graph.includeFileCallback(c.graph, c.module, f), {})
  2111. excl(c.includedFiles, f.int)
  2112. proc evalInclude(c: PContext, n: PNode): PNode =
  2113. result = newNodeI(nkStmtList, n.info)
  2114. result.add n
  2115. for i in 0..<n.len:
  2116. var imp: PNode
  2117. let it = n[i]
  2118. if it.kind == nkInfix and it.len == 3 and it[0].ident.s != "/":
  2119. localError(c.config, it.info, "Cannot use '" & it[0].ident.s & "' in 'include'.")
  2120. if it.kind == nkInfix and it.len == 3 and it[2].kind == nkBracket:
  2121. let sep = it[0]
  2122. let dir = it[1]
  2123. imp = newNodeI(nkInfix, it.info)
  2124. imp.add sep
  2125. imp.add dir
  2126. imp.add sep # dummy entry, replaced in the loop
  2127. for x in it[2]:
  2128. imp[2] = x
  2129. incMod(c, n, imp, result)
  2130. else:
  2131. incMod(c, n, it, result)
  2132. proc setLine(n: PNode, info: TLineInfo) =
  2133. if n != nil:
  2134. for i in 0..<n.safeLen: setLine(n[i], info)
  2135. n.info = info
  2136. proc semPragmaBlock(c: PContext, n: PNode; expectedType: PType = nil): PNode =
  2137. checkSonsLen(n, 2, c.config)
  2138. let pragmaList = n[0]
  2139. pragma(c, nil, pragmaList, exprPragmas, isStatement = true)
  2140. var inUncheckedAssignSection = 0
  2141. for p in pragmaList:
  2142. if whichPragma(p) == wCast:
  2143. case whichPragma(p[1])
  2144. of wGcSafe, wNoSideEffect, wTags, wRaises:
  2145. discard "handled in sempass2"
  2146. of wUncheckedAssign:
  2147. inUncheckedAssignSection = 1
  2148. else:
  2149. localError(c.config, p.info, "invalid pragma block: " & $p)
  2150. inc c.inUncheckedAssignSection, inUncheckedAssignSection
  2151. n[1] = semExpr(c, n[1], expectedType = expectedType)
  2152. dec c.inUncheckedAssignSection, inUncheckedAssignSection
  2153. result = n
  2154. result.typ = n[1].typ
  2155. for i in 0..<pragmaList.len:
  2156. case whichPragma(pragmaList[i])
  2157. of wLine: setLine(result, pragmaList[i].info)
  2158. of wNoRewrite: incl(result.flags, nfNoRewrite)
  2159. else: discard
  2160. proc semStaticStmt(c: PContext, n: PNode): PNode =
  2161. #echo "semStaticStmt"
  2162. #writeStackTrace()
  2163. inc c.inStaticContext
  2164. openScope(c)
  2165. let a = semStmt(c, n[0], {})
  2166. closeScope(c)
  2167. dec c.inStaticContext
  2168. n[0] = a
  2169. evalStaticStmt(c.module, c.idgen, c.graph, a, c.p.owner)
  2170. when false:
  2171. # for incremental replays, keep the AST as required for replays:
  2172. result = n
  2173. else:
  2174. result = newNodeI(nkDiscardStmt, n.info, 1)
  2175. result[0] = c.graph.emptyNode
  2176. proc usesResult(n: PNode): bool =
  2177. # nkStmtList(expr) properly propagates the void context,
  2178. # so we don't need to process that all over again:
  2179. if n.kind notin {nkStmtList, nkStmtListExpr,
  2180. nkMacroDef, nkTemplateDef} + procDefs:
  2181. if isAtom(n):
  2182. result = n.kind == nkSym and n.sym.kind == skResult
  2183. elif n.kind == nkReturnStmt:
  2184. result = true
  2185. else:
  2186. for c in n:
  2187. if usesResult(c): return true
  2188. proc inferConceptStaticParam(c: PContext, inferred, n: PNode) =
  2189. var typ = inferred.typ
  2190. let res = semConstExpr(c, n)
  2191. if not sameType(res.typ, typ.base):
  2192. localError(c.config, n.info,
  2193. "cannot infer the concept parameter '%s', due to a type mismatch. " &
  2194. "attempt to equate '%s' and '%s'." % [inferred.renderTree, $res.typ, $typ.base])
  2195. typ.n = res
  2196. proc semStmtList(c: PContext, n: PNode, flags: TExprFlags, expectedType: PType = nil): PNode =
  2197. result = n
  2198. result.transitionSonsKind(nkStmtList)
  2199. var voidContext = false
  2200. var last = n.len-1
  2201. # by not allowing for nkCommentStmt etc. we ensure nkStmtListExpr actually
  2202. # really *ends* in the expression that produces the type: The compiler now
  2203. # relies on this fact and it's too much effort to change that. And arguably
  2204. # 'R(); #comment' shouldn't produce R's type anyway.
  2205. #while last > 0 and n[last].kind in {nkPragma, nkCommentStmt,
  2206. # nkNilLit, nkEmpty}:
  2207. # dec last
  2208. for i in 0..<n.len:
  2209. var x = semExpr(c, n[i], flags, if i == n.len - 1: expectedType else: nil)
  2210. n[i] = x
  2211. if c.matchedConcept != nil and x.typ != nil and
  2212. (nfFromTemplate notin n.flags or i != last):
  2213. case x.typ.kind
  2214. of tyBool:
  2215. if x.kind == nkInfix and
  2216. x[0].kind == nkSym and
  2217. x[0].sym.name.s == "==":
  2218. if x[1].typ.isUnresolvedStatic:
  2219. inferConceptStaticParam(c, x[1], x[2])
  2220. continue
  2221. elif x[2].typ.isUnresolvedStatic:
  2222. inferConceptStaticParam(c, x[2], x[1])
  2223. continue
  2224. let verdict = semConstExpr(c, n[i])
  2225. if verdict == nil or verdict.kind != nkIntLit or verdict.intVal == 0:
  2226. localError(c.config, result.info, "concept predicate failed")
  2227. of tyUnknown: continue
  2228. else: discard
  2229. if n[i].typ == c.enforceVoidContext: #or usesResult(n[i]):
  2230. voidContext = true
  2231. n.typ = c.enforceVoidContext
  2232. if i == last and (n.len == 1 or ({efWantValue, efInTypeof} * flags != {})):
  2233. n.typ = n[i].typ
  2234. if not isEmptyType(n.typ): n.transitionSonsKind(nkStmtListExpr)
  2235. elif i != last or voidContext:
  2236. discardCheck(c, n[i], flags)
  2237. else:
  2238. n.typ = n[i].typ
  2239. if not isEmptyType(n.typ): n.transitionSonsKind(nkStmtListExpr)
  2240. var m = n[i]
  2241. while m.kind in {nkStmtListExpr, nkStmtList} and m.len > 0: # from templates
  2242. m = m.lastSon
  2243. if endsInNoReturn(m):
  2244. for j in i + 1..<n.len:
  2245. case n[j].kind
  2246. of nkPragma, nkCommentStmt, nkNilLit, nkEmpty, nkState: discard
  2247. else: message(c.config, n[j].info, warnUnreachableCode)
  2248. else: discard
  2249. if result.len == 1 and
  2250. # concept bodies should be preserved as a stmt list:
  2251. c.matchedConcept == nil and
  2252. # also, don't make life complicated for macros.
  2253. # they will always expect a proper stmtlist:
  2254. nfBlockArg notin n.flags and
  2255. result[0].kind != nkDefer:
  2256. result = result[0]
  2257. when defined(nimfix):
  2258. if result.kind == nkCommentStmt and not result.comment.isNil and
  2259. not (result.comment[0] == '#' and result.comment[1] == '#'):
  2260. # it is an old-style comment statement: we replace it with 'discard ""':
  2261. prettybase.replaceComment(result.info)
  2262. proc semStmt(c: PContext, n: PNode; flags: TExprFlags): PNode =
  2263. if efInTypeof notin flags:
  2264. result = semExprNoType(c, n)
  2265. else:
  2266. result = semExpr(c, n, flags)