semstmts.nim 74 KB

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