semstmts.nim 76 KB

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