semstmts.nim 112 KB

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