semstmts.nim 95 KB

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