semstmts.nim 84 KB

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