semstmts.nim 86 KB

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