sem.nim 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894
  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 implements the semantic checking pass.
  10. import
  11. ast, options, astalgo, trees,
  12. wordrecg, ropes, msgs, idents, renderer, types, platform,
  13. magicsys, nversion, nimsets, semfold, modulepaths, importer,
  14. procfind, lookups, pragmas, semdata, semtypinst, sigmatch,
  15. transf, vmdef, vm, aliases, cgmeth, lambdalifting,
  16. evaltempl, patterns, parampatterns, sempass2, linter, semmacrosanity,
  17. lowerings, plugins/active, lineinfos, int128,
  18. isolation_check, typeallowed, modulegraphs, enumtostr, concepts, astmsgs,
  19. extccomp
  20. import std/[strtabs, math, tables, intsets, strutils]
  21. when not defined(leanCompiler):
  22. import spawn
  23. when defined(nimPreviewSlimSystem):
  24. import std/[
  25. formatfloat,
  26. assertions,
  27. ]
  28. # implementation
  29. proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}, expectedType: PType = nil): PNode
  30. proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}, expectedType: PType = nil): PNode
  31. proc semExprNoType(c: PContext, n: PNode): PNode
  32. proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
  33. proc semProcBody(c: PContext, n: PNode; expectedType: PType = nil): PNode
  34. proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode
  35. proc changeType(c: PContext; n: PNode, newType: PType, check: bool)
  36. proc semTypeNode(c: PContext, n: PNode, prev: PType): PType
  37. proc semStmt(c: PContext, n: PNode; flags: TExprFlags): PNode
  38. proc semOpAux(c: PContext, n: PNode)
  39. proc semParamList(c: PContext, n, genericParams: PNode, s: PSym)
  40. proc addParams(c: PContext, n: PNode, kind: TSymKind)
  41. proc maybeAddResult(c: PContext, s: PSym, n: PNode)
  42. proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
  43. proc activate(c: PContext, n: PNode)
  44. proc semQuoteAst(c: PContext, n: PNode): PNode
  45. proc finishMethod(c: PContext, s: PSym)
  46. proc evalAtCompileTime(c: PContext, n: PNode): PNode
  47. proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode
  48. proc semStaticExpr(c: PContext, n: PNode; expectedType: PType = nil): PNode
  49. proc semStaticType(c: PContext, childNode: PNode, prev: PType): PType
  50. proc semTypeOf(c: PContext; n: PNode): PNode
  51. proc computeRequiresInit(c: PContext, t: PType): bool
  52. proc defaultConstructionError(c: PContext, t: PType, info: TLineInfo)
  53. proc hasUnresolvedArgs(c: PContext, n: PNode): bool
  54. proc isArrayConstr(n: PNode): bool {.inline.} =
  55. result = n.kind == nkBracket and
  56. n.typ.skipTypes(abstractInst).kind == tyArray
  57. template semIdeForTemplateOrGenericCheck(conf, n, requiresCheck) =
  58. # we check quickly if the node is where the cursor is
  59. when defined(nimsuggest):
  60. if n.info.fileIndex == conf.m.trackPos.fileIndex and n.info.line == conf.m.trackPos.line:
  61. requiresCheck = true
  62. template semIdeForTemplateOrGeneric(c: PContext; n: PNode;
  63. requiresCheck: bool) =
  64. # use only for idetools support; this is pretty slow so generics and
  65. # templates perform some quick check whether the cursor is actually in
  66. # the generic or template.
  67. when defined(nimsuggest):
  68. if c.config.cmd == cmdIdeTools and requiresCheck:
  69. #if optIdeDebug in gGlobalOptions:
  70. # echo "passing to safeSemExpr: ", renderTree(n)
  71. discard safeSemExpr(c, n)
  72. proc fitNodePostMatch(c: PContext, formal: PType, arg: PNode): PNode =
  73. let x = arg.skipConv
  74. if (x.kind == nkCurly and formal.kind == tySet and formal.base.kind != tyGenericParam) or
  75. (x.kind in {nkPar, nkTupleConstr}) and formal.kind notin {tyUntyped, tyBuiltInTypeClass, tyAnything}:
  76. changeType(c, x, formal, check=true)
  77. result = arg
  78. result = skipHiddenSubConv(result, c.graph, c.idgen)
  79. proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode =
  80. if arg.typ.isNil:
  81. localError(c.config, arg.info, "expression has no type: " &
  82. renderTree(arg, {renderNoComments}))
  83. # error correction:
  84. result = copyTree(arg)
  85. result.typ = formal
  86. elif arg.kind in nkSymChoices and formal.skipTypes(abstractInst).kind == tyEnum:
  87. # Pick the right 'sym' from the sym choice by looking at 'formal' type:
  88. result = nil
  89. for ch in arg:
  90. if sameType(ch.typ, formal):
  91. return getConstExpr(c.module, ch, c.idgen, c.graph)
  92. typeMismatch(c.config, info, formal, arg.typ, arg)
  93. else:
  94. result = indexTypesMatch(c, formal, arg.typ, arg)
  95. if result == nil:
  96. typeMismatch(c.config, info, formal, arg.typ, arg)
  97. # error correction:
  98. result = copyTree(arg)
  99. result.typ = formal
  100. else:
  101. result = fitNodePostMatch(c, formal, result)
  102. proc fitNodeConsiderViewType(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode =
  103. let a = fitNode(c, formal, arg, info)
  104. if formal.kind in {tyVar, tyLent}:
  105. #classifyViewType(formal) != noView:
  106. result = newNodeIT(nkHiddenAddr, a.info, formal)
  107. result.add a
  108. formal.flags.incl tfVarIsPtr
  109. else:
  110. result = a
  111. proc inferWithMetatype(c: PContext, formal: PType,
  112. arg: PNode, coerceDistincts = false): PNode
  113. template commonTypeBegin*(): PType = PType(kind: tyUntyped)
  114. proc commonType*(c: PContext; x, y: PType): PType =
  115. # new type relation that is used for array constructors,
  116. # if expressions, etc.:
  117. if x == nil: return x
  118. if y == nil: return y
  119. var a = skipTypes(x, {tyGenericInst, tyAlias, tySink})
  120. var b = skipTypes(y, {tyGenericInst, tyAlias, tySink})
  121. result = x
  122. if a.kind in {tyUntyped, tyNil}: result = y
  123. elif b.kind in {tyUntyped, tyNil}: result = x
  124. elif a.kind == tyTyped: result = a
  125. elif b.kind == tyTyped: result = b
  126. elif a.kind == tyTypeDesc:
  127. # turn any concrete typedesc into the abstract typedesc type
  128. if a.len == 0: result = a
  129. else:
  130. result = newType(tyTypeDesc, c.idgen, a.owner)
  131. rawAddSon(result, newType(tyNone, c.idgen, a.owner))
  132. elif b.kind in {tyArray, tySet, tySequence} and
  133. a.kind == b.kind:
  134. # check for seq[empty] vs. seq[int]
  135. let idx = ord(b.kind == tyArray)
  136. if a[idx].kind == tyEmpty: return y
  137. elif a.kind == tyTuple and b.kind == tyTuple and a.len == b.len:
  138. var nt: PType = nil
  139. for i in 0..<a.len:
  140. let aEmpty = isEmptyContainer(a[i])
  141. let bEmpty = isEmptyContainer(b[i])
  142. if aEmpty != bEmpty:
  143. if nt.isNil:
  144. nt = copyType(a, c.idgen, a.owner)
  145. copyTypeProps(c.graph, c.idgen.module, nt, a)
  146. nt[i] = if aEmpty: b[i] else: a[i]
  147. if not nt.isNil: result = nt
  148. #elif b[idx].kind == tyEmpty: return x
  149. elif a.kind == tyRange and b.kind == tyRange:
  150. # consider: (range[0..3], range[0..4]) here. We should make that
  151. # range[0..4]. But then why is (range[0..4], 6) not range[0..6]?
  152. # But then why is (2,4) not range[2..4]? But I think this would break
  153. # too much code. So ... it's the same range or the base type. This means
  154. # typeof(if b: 0 else 1) == int and not range[0..1]. For now. In the long
  155. # run people expect ranges to work properly within a tuple.
  156. if not sameType(a, b):
  157. result = skipTypes(a, {tyRange}).skipIntLit(c.idgen)
  158. when false:
  159. if a.kind != tyRange and b.kind == tyRange:
  160. # XXX This really needs a better solution, but a proper fix now breaks
  161. # code.
  162. result = a #.skipIntLit
  163. elif a.kind == tyRange and b.kind != tyRange:
  164. result = b #.skipIntLit
  165. elif a.kind in IntegralTypes and a.n != nil:
  166. result = a #.skipIntLit
  167. elif a.kind == tyProc and b.kind == tyProc:
  168. if a.callConv == ccClosure and b.callConv != ccClosure:
  169. result = x
  170. elif compatibleEffects(a, b) != efCompat or
  171. (b.flags * {tfNoSideEffect, tfGcSafe}) < (a.flags * {tfNoSideEffect, tfGcSafe}):
  172. result = y
  173. else:
  174. var k = tyNone
  175. if a.kind in {tyRef, tyPtr}:
  176. k = a.kind
  177. if b.kind != a.kind: return x
  178. # bug #7601, array construction of ptr generic
  179. a = a.lastSon.skipTypes({tyGenericInst})
  180. b = b.lastSon.skipTypes({tyGenericInst})
  181. if a.kind == tyObject and b.kind == tyObject:
  182. result = commonSuperclass(a, b)
  183. # this will trigger an error later:
  184. if result.isNil or result == a: return x
  185. if result == b: return y
  186. # bug #7906, tyRef/tyPtr + tyGenericInst of ref/ptr object ->
  187. # ill-formed AST, no need for additional tyRef/tyPtr
  188. if k != tyNone and x.kind != tyGenericInst:
  189. let r = result
  190. result = newType(k, c.idgen, r.owner)
  191. result.addSonSkipIntLit(r, c.idgen)
  192. proc endsInNoReturn(n: PNode): bool =
  193. ## check if expr ends the block like raising or call of noreturn procs do
  194. result = false # assume it does return
  195. template checkBranch(branch) =
  196. if not endsInNoReturn(branch):
  197. # proved a branch returns
  198. return false
  199. var it = n
  200. # skip these beforehand, no special handling needed
  201. while it.kind in {nkStmtList, nkStmtListExpr} and it.len > 0:
  202. it = it.lastSon
  203. case it.kind
  204. of nkIfStmt:
  205. var hasElse = false
  206. for branch in it:
  207. checkBranch:
  208. if branch.len == 2:
  209. branch[1]
  210. elif branch.len == 1:
  211. hasElse = true
  212. branch[0]
  213. else:
  214. raiseAssert "Malformed `if` statement during endsInNoReturn"
  215. # none of the branches returned
  216. result = hasElse # Only truly a no-return when it's exhaustive
  217. of nkCaseStmt:
  218. for i in 1 ..< it.len:
  219. let branch = it[i]
  220. checkBranch:
  221. case branch.kind
  222. of nkOfBranch:
  223. branch[^1]
  224. of nkElifBranch:
  225. branch[1]
  226. of nkElse:
  227. branch[0]
  228. else:
  229. raiseAssert "Malformed `case` statement in endsInNoReturn"
  230. # none of the branches returned
  231. result = true
  232. of nkTryStmt:
  233. checkBranch(it[0])
  234. for i in 1 ..< it.len:
  235. let branch = it[i]
  236. checkBranch(branch[^1])
  237. # none of the branches returned
  238. result = true
  239. else:
  240. result = it.kind in nkLastBlockStmts or
  241. it.kind in nkCallKinds and it[0].kind == nkSym and sfNoReturn in it[0].sym.flags
  242. proc commonType*(c: PContext; x: PType, y: PNode): PType =
  243. # ignore exception raising branches in case/if expressions
  244. if endsInNoReturn(y): return x
  245. commonType(c, x, y.typ)
  246. proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym =
  247. result = newSym(kind, considerQuotedIdent(c, n), c.idgen, getCurrOwner(c), n.info)
  248. when defined(nimsuggest):
  249. suggestDecl(c, n, result)
  250. proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
  251. # like newSymS, but considers gensym'ed symbols
  252. if n.kind == nkSym:
  253. # and sfGenSym in n.sym.flags:
  254. result = n.sym
  255. if result.kind notin {kind, skTemp}:
  256. localError(c.config, n.info, "cannot use symbol of kind '$1' as a '$2'" %
  257. [result.kind.toHumanStr, kind.toHumanStr])
  258. when false:
  259. if sfGenSym in result.flags and result.kind notin {skTemplate, skMacro, skParam}:
  260. # declarative context, so produce a fresh gensym:
  261. result = copySym(result)
  262. result.ast = n.sym.ast
  263. put(c.p, n.sym, result)
  264. # when there is a nested proc inside a template, semtmpl
  265. # will assign a wrong owner during the first pass over the
  266. # template; we must fix it here: see #909
  267. result.owner = getCurrOwner(c)
  268. else:
  269. result = newSym(kind, considerQuotedIdent(c, n), c.idgen, getCurrOwner(c), n.info)
  270. #if kind in {skForVar, skLet, skVar} and result.owner.kind == skModule:
  271. # incl(result.flags, sfGlobal)
  272. when defined(nimsuggest):
  273. suggestDecl(c, n, result)
  274. proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
  275. allowed: TSymFlags): PSym
  276. # identifier with visibility
  277. proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode,
  278. allowed: TSymFlags): PSym
  279. proc typeAllowedCheck(c: PContext; info: TLineInfo; typ: PType; kind: TSymKind;
  280. flags: TTypeAllowedFlags = {}) =
  281. let t = typeAllowed(typ, kind, c, flags)
  282. if t != nil:
  283. var err: string
  284. if t == typ:
  285. err = "invalid type: '$1' for $2" % [typeToString(typ), toHumanStr(kind)]
  286. if kind in {skVar, skLet, skConst} and taIsTemplateOrMacro in flags:
  287. err &= ". Did you mean to call the $1 with '()'?" % [toHumanStr(typ.owner.kind)]
  288. else:
  289. err = "invalid type: '$1' in this context: '$2' for $3" % [typeToString(t),
  290. typeToString(typ), toHumanStr(kind)]
  291. localError(c.config, info, err)
  292. proc paramsTypeCheck(c: PContext, typ: PType) {.inline.} =
  293. typeAllowedCheck(c, typ.n.info, typ, skProc)
  294. proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym
  295. proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType = nil): PNode
  296. proc semWhen(c: PContext, n: PNode, semCheck: bool = true): PNode
  297. proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
  298. flags: TExprFlags = {}; expectedType: PType = nil): PNode
  299. proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
  300. flags: TExprFlags = {}; expectedType: PType = nil): PNode
  301. when false:
  302. proc createEvalContext(c: PContext, mode: TEvalMode): PEvalContext =
  303. result = newEvalContext(c.module, mode)
  304. result.getType = proc (n: PNode): PNode =
  305. result = tryExpr(c, n)
  306. if result == nil:
  307. result = newSymNode(errorSym(c, n))
  308. elif result.typ == nil:
  309. result = newSymNode(getSysSym"void")
  310. else:
  311. result.typ = makeTypeDesc(c, result.typ)
  312. result.handleIsOperator = proc (n: PNode): PNode =
  313. result = isOpImpl(c, n)
  314. proc hasCycle(n: PNode): bool =
  315. result = false
  316. incl n.flags, nfNone
  317. for i in 0..<n.safeLen:
  318. if nfNone in n[i].flags or hasCycle(n[i]):
  319. result = true
  320. break
  321. excl n.flags, nfNone
  322. proc fixupTypeAfterEval(c: PContext, evaluated, eOrig: PNode): PNode =
  323. # recompute the types as 'eval' isn't guaranteed to construct types nor
  324. # that the types are sound:
  325. when true:
  326. if eOrig.typ.kind in {tyUntyped, tyTyped, tyTypeDesc}:
  327. result = semExprWithType(c, evaluated)
  328. else:
  329. result = evaluated
  330. let expectedType = eOrig.typ.skipTypes({tyStatic})
  331. if hasCycle(result):
  332. result = localErrorNode(c, eOrig, "the resulting AST is cyclic and cannot be processed further")
  333. else:
  334. semmacrosanity.annotateType(result, expectedType, c.config)
  335. else:
  336. result = semExprWithType(c, evaluated)
  337. #result = fitNode(c, e.typ, result) inlined with special case:
  338. let arg = result
  339. result = indexTypesMatch(c, eOrig.typ, arg.typ, arg)
  340. if result == nil:
  341. result = arg
  342. # for 'tcnstseq' we support [] to become 'seq'
  343. if eOrig.typ.skipTypes(abstractInst).kind == tySequence and
  344. isArrayConstr(arg):
  345. arg.typ = eOrig.typ
  346. proc tryConstExpr(c: PContext, n: PNode; expectedType: PType = nil): PNode =
  347. var e = semExprWithType(c, n, expectedType = expectedType)
  348. if e == nil: return
  349. result = getConstExpr(c.module, e, c.idgen, c.graph)
  350. if result != nil: return
  351. let oldErrorCount = c.config.errorCounter
  352. let oldErrorMax = c.config.errorMax
  353. let oldErrorOutputs = c.config.m.errorOutputs
  354. c.config.m.errorOutputs = {}
  355. c.config.errorMax = high(int) # `setErrorMaxHighMaybe` not appropriate here
  356. when defined(nimsuggest):
  357. # Remove the error hook so nimsuggest doesn't report errors there
  358. let tempHook = c.graph.config.structuredErrorHook
  359. c.graph.config.structuredErrorHook = nil
  360. try:
  361. result = evalConstExpr(c.module, c.idgen, c.graph, e)
  362. if result == nil or result.kind == nkEmpty:
  363. result = nil
  364. else:
  365. result = fixupTypeAfterEval(c, result, e)
  366. except ERecoverableError:
  367. result = nil
  368. when defined(nimsuggest):
  369. # Restore the error hook
  370. c.graph.config.structuredErrorHook = tempHook
  371. c.config.errorCounter = oldErrorCount
  372. c.config.errorMax = oldErrorMax
  373. c.config.m.errorOutputs = oldErrorOutputs
  374. const
  375. errConstExprExpected = "constant expression expected"
  376. proc semConstExpr(c: PContext, n: PNode; expectedType: PType = nil): PNode =
  377. var e = semExprWithType(c, n, expectedType = expectedType)
  378. if e == nil:
  379. localError(c.config, n.info, errConstExprExpected)
  380. return n
  381. if e.kind in nkSymChoices and e[0].typ.skipTypes(abstractInst).kind == tyEnum:
  382. return e
  383. result = getConstExpr(c.module, e, c.idgen, c.graph)
  384. if result == nil:
  385. #if e.kind == nkEmpty: globalError(n.info, errConstExprExpected)
  386. result = evalConstExpr(c.module, c.idgen, c.graph, e)
  387. if result == nil or result.kind == nkEmpty:
  388. if e.info != n.info:
  389. pushInfoContext(c.config, n.info)
  390. localError(c.config, e.info, errConstExprExpected)
  391. popInfoContext(c.config)
  392. else:
  393. localError(c.config, e.info, errConstExprExpected)
  394. # error correction:
  395. result = e
  396. else:
  397. result = fixupTypeAfterEval(c, result, e)
  398. proc semExprFlagDispatched(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType = nil): PNode =
  399. if efNeedStatic in flags:
  400. if efPreferNilResult in flags:
  401. return tryConstExpr(c, n, expectedType)
  402. else:
  403. return semConstExpr(c, n, expectedType)
  404. else:
  405. result = semExprWithType(c, n, flags, expectedType)
  406. if efPreferStatic in flags:
  407. var evaluated = getConstExpr(c.module, result, c.idgen, c.graph)
  408. if evaluated != nil: return evaluated
  409. evaluated = evalAtCompileTime(c, result)
  410. if evaluated != nil: return evaluated
  411. proc semGenericStmt(c: PContext, n: PNode): PNode
  412. include hlo, seminst, semcall
  413. proc resetSemFlag(n: PNode) =
  414. if n != nil:
  415. excl n.flags, nfSem
  416. for i in 0..<n.safeLen:
  417. resetSemFlag(n[i])
  418. proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
  419. s: PSym, flags: TExprFlags; expectedType: PType = nil): PNode =
  420. ## Semantically check the output of a macro.
  421. ## This involves processes such as re-checking the macro output for type
  422. ## coherence, making sure that variables declared with 'let' aren't
  423. ## reassigned, and binding the unbound identifiers that the macro output
  424. ## contains.
  425. inc(c.config.evalTemplateCounter)
  426. if c.config.evalTemplateCounter > evalTemplateLimit:
  427. globalError(c.config, s.info, "template instantiation too nested")
  428. c.friendModules.add(s.owner.getModule)
  429. result = macroResult
  430. resetSemFlag result
  431. if s.typ[0] == nil:
  432. result = semStmt(c, result, flags)
  433. else:
  434. var retType = s.typ[0]
  435. if retType.kind == tyTypeDesc and tfUnresolved in retType.flags and
  436. retType.len == 1:
  437. # bug #11941: template fails(T: type X, v: auto): T
  438. # does not mean we expect a tyTypeDesc.
  439. retType = retType[0]
  440. case retType.kind
  441. of tyUntyped, tyAnything:
  442. # Not expecting a type here allows templates like in ``tmodulealias.in``.
  443. result = semExpr(c, result, flags, expectedType)
  444. of tyTyped:
  445. # More restrictive version.
  446. result = semExprWithType(c, result, flags, expectedType)
  447. of tyTypeDesc:
  448. if result.kind == nkStmtList: result.transitionSonsKind(nkStmtListType)
  449. var typ = semTypeNode(c, result, nil)
  450. if typ == nil:
  451. localError(c.config, result.info, "expression has no type: " &
  452. renderTree(result, {renderNoComments}))
  453. result = newSymNode(errorSym(c, result))
  454. else:
  455. result.typ = makeTypeDesc(c, typ)
  456. #result = symNodeFromType(c, typ, n.info)
  457. else:
  458. if s.ast[genericParamsPos] != nil and retType.isMetaType:
  459. # The return type may depend on the Macro arguments
  460. # e.g. template foo(T: typedesc): seq[T]
  461. # We will instantiate the return type here, because
  462. # we now know the supplied arguments
  463. var paramTypes = initIdTable()
  464. for param, value in genericParamsInMacroCall(s, call):
  465. var givenType = value.typ
  466. # the sym nodes used for the supplied generic arguments for
  467. # templates and macros leave type nil so regular sem can handle it
  468. # in this case, get the type directly from the sym
  469. if givenType == nil and value.kind == nkSym and value.sym.typ != nil:
  470. givenType = value.sym.typ
  471. idTablePut(paramTypes, param.typ, givenType)
  472. retType = generateTypeInstance(c, paramTypes,
  473. macroResult.info, retType)
  474. if retType.kind == tyVoid:
  475. result = semStmt(c, result, flags)
  476. else:
  477. result = semExpr(c, result, flags, expectedType)
  478. result = fitNode(c, retType, result, result.info)
  479. #globalError(s.info, errInvalidParamKindX, typeToString(s.typ[0]))
  480. dec(c.config.evalTemplateCounter)
  481. discard c.friendModules.pop()
  482. const
  483. errMissingGenericParamsForTemplate = "'$1' has unspecified generic parameters"
  484. errFloatToString = "cannot convert '$1' to '$2'"
  485. proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
  486. flags: TExprFlags = {}; expectedType: PType = nil): PNode =
  487. rememberExpansion(c, nOrig.info, sym)
  488. pushInfoContext(c.config, nOrig.info, sym.detailedInfo)
  489. let info = getCallLineInfo(n)
  490. markUsed(c, info, sym)
  491. onUse(info, sym)
  492. if sym == c.p.owner:
  493. globalError(c.config, info, "recursive dependency: '$1'" % sym.name.s)
  494. let genericParams = sym.ast[genericParamsPos].len
  495. let suppliedParams = max(n.safeLen - 1, 0)
  496. if suppliedParams < genericParams:
  497. globalError(c.config, info, errMissingGenericParamsForTemplate % n.renderTree)
  498. #if c.evalContext == nil:
  499. # c.evalContext = c.createEvalContext(emStatic)
  500. result = evalMacroCall(c.module, c.idgen, c.graph, c.templInstCounter, n, nOrig, sym)
  501. if efNoSemCheck notin flags:
  502. result = semAfterMacroCall(c, n, result, sym, flags, expectedType)
  503. if c.config.macrosToExpand.hasKey(sym.name.s):
  504. message(c.config, nOrig.info, hintExpandMacro, renderTree(result))
  505. result = wrapInComesFrom(nOrig.info, sym, result)
  506. popInfoContext(c.config)
  507. proc forceBool(c: PContext, n: PNode): PNode =
  508. result = fitNode(c, getSysType(c.graph, n.info, tyBool), n, n.info)
  509. if result == nil: result = n
  510. proc semConstBoolExpr(c: PContext, n: PNode): PNode =
  511. result = forceBool(c, semConstExpr(c, n, getSysType(c.graph, n.info, tyBool)))
  512. if result.kind != nkIntLit:
  513. localError(c.config, n.info, errConstExprExpected)
  514. proc semConceptBody(c: PContext, n: PNode): PNode
  515. include semtypes
  516. proc setGenericParamsMisc(c: PContext; n: PNode) =
  517. ## used by call defs (procs, templates, macros, ...) to analyse their generic
  518. ## params, and store the originals in miscPos for better error reporting.
  519. let orig = n[genericParamsPos]
  520. doAssert orig.kind in {nkEmpty, nkGenericParams}
  521. if n[genericParamsPos].kind == nkEmpty:
  522. n[genericParamsPos] = newNodeI(nkGenericParams, n.info)
  523. else:
  524. # we keep the original params around for better error messages, see
  525. # issue https://github.com/nim-lang/Nim/issues/1713
  526. n[genericParamsPos] = semGenericParamList(c, orig)
  527. if n[miscPos].kind == nkEmpty:
  528. n[miscPos] = newTree(nkBracket, c.graph.emptyNode, orig)
  529. else:
  530. n[miscPos][1] = orig
  531. proc caseBranchMatchesExpr(branch, matched: PNode): bool =
  532. result = false
  533. for i in 0 ..< branch.len-1:
  534. if branch[i].kind == nkRange:
  535. if overlap(branch[i], matched): return true
  536. elif exprStructuralEquivalent(branch[i], matched):
  537. return true
  538. proc pickCaseBranchIndex(caseExpr, matched: PNode): int =
  539. result = 0
  540. let endsWithElse = caseExpr[^1].kind == nkElse
  541. for i in 1..<caseExpr.len - endsWithElse.int:
  542. if caseExpr[i].caseBranchMatchesExpr(matched):
  543. return i
  544. if endsWithElse:
  545. return caseExpr.len - 1
  546. proc defaultFieldsForTheUninitialized(c: PContext, recNode: PNode, checkDefault: bool): seq[PNode]
  547. proc defaultNodeField(c: PContext, a: PNode, aTyp: PType, checkDefault: bool): PNode
  548. proc defaultNodeField(c: PContext, a: PNode, checkDefault: bool): PNode
  549. const defaultFieldsSkipTypes = {tyGenericInst, tyAlias, tySink}
  550. proc defaultFieldsForTuple(c: PContext, recNode: PNode, hasDefault: var bool, checkDefault: bool): seq[PNode] =
  551. result = @[]
  552. case recNode.kind
  553. of nkRecList:
  554. for field in recNode:
  555. result.add defaultFieldsForTuple(c, field, hasDefault, checkDefault)
  556. of nkSym:
  557. let field = recNode.sym
  558. let recType = recNode.typ.skipTypes(defaultFieldsSkipTypes)
  559. if field.ast != nil: #Try to use default value
  560. hasDefault = true
  561. result.add newTree(nkExprColonExpr, recNode, field.ast)
  562. else:
  563. if recType.kind in {tyObject, tyArray, tyTuple}:
  564. let asgnExpr = defaultNodeField(c, recNode, recNode.typ, checkDefault)
  565. if asgnExpr != nil:
  566. hasDefault = true
  567. asgnExpr.flags.incl nfSkipFieldChecking
  568. result.add newTree(nkExprColonExpr, recNode, asgnExpr)
  569. return
  570. let asgnType = newType(tyTypeDesc, c.idgen, recNode.typ.owner)
  571. rawAddSon(asgnType, recNode.typ)
  572. let asgnExpr = newTree(nkCall,
  573. newSymNode(getSysMagic(c.graph, recNode.info, "zeroDefault", mZeroDefault)),
  574. newNodeIT(nkType, recNode.info, asgnType)
  575. )
  576. asgnExpr.flags.incl nfSkipFieldChecking
  577. asgnExpr.typ = recNode.typ
  578. result.add newTree(nkExprColonExpr, recNode, asgnExpr)
  579. else:
  580. raiseAssert "unreachable"
  581. proc defaultFieldsForTheUninitialized(c: PContext, recNode: PNode, checkDefault: bool): seq[PNode] =
  582. result = @[]
  583. case recNode.kind
  584. of nkRecList:
  585. for field in recNode:
  586. result.add defaultFieldsForTheUninitialized(c, field, checkDefault)
  587. of nkRecCase:
  588. let discriminator = recNode[0]
  589. var selectedBranch: int
  590. var defaultValue = discriminator.sym.ast
  591. if defaultValue == nil:
  592. # None of the branches were explicitly selected by the user and no value
  593. # was given to the discrimator. We can assume that it will be initialized
  594. # to zero and this will select a particular branch as a result:
  595. if checkDefault: # don't add defaults when checking whether a case branch has default fields
  596. return
  597. defaultValue = newIntNode(nkIntLit#[c.graph]#, 0)
  598. defaultValue.typ = discriminator.typ
  599. selectedBranch = recNode.pickCaseBranchIndex defaultValue
  600. defaultValue.flags.incl nfSkipFieldChecking
  601. result.add newTree(nkExprColonExpr, discriminator, defaultValue)
  602. result.add defaultFieldsForTheUninitialized(c, recNode[selectedBranch][^1], checkDefault)
  603. of nkSym:
  604. let field = recNode.sym
  605. let recType = recNode.typ.skipTypes(defaultFieldsSkipTypes)
  606. if field.ast != nil: #Try to use default value
  607. result.add newTree(nkExprColonExpr, recNode, field.ast)
  608. elif recType.kind in {tyObject, tyArray, tyTuple}:
  609. let asgnExpr = defaultNodeField(c, recNode, recNode.typ, checkDefault)
  610. if asgnExpr != nil:
  611. asgnExpr.typ = recNode.typ
  612. asgnExpr.flags.incl nfSkipFieldChecking
  613. result.add newTree(nkExprColonExpr, recNode, asgnExpr)
  614. else:
  615. raiseAssert "unreachable"
  616. proc defaultNodeField(c: PContext, a: PNode, aTyp: PType, checkDefault: bool): PNode =
  617. let aTypSkip = aTyp.skipTypes(defaultFieldsSkipTypes)
  618. if aTypSkip.kind == tyObject:
  619. let child = defaultFieldsForTheUninitialized(c, aTypSkip.n, checkDefault)
  620. if child.len > 0:
  621. var asgnExpr = newTree(nkObjConstr, newNodeIT(nkType, a.info, aTyp))
  622. asgnExpr.typ = aTyp
  623. asgnExpr.sons.add child
  624. result = semExpr(c, asgnExpr)
  625. else:
  626. result = nil
  627. elif aTypSkip.kind == tyArray:
  628. let child = defaultNodeField(c, a, aTypSkip[1], checkDefault)
  629. if child != nil:
  630. let node = newNode(nkIntLit)
  631. node.intVal = toInt64(lengthOrd(c.graph.config, aTypSkip))
  632. result = semExpr(c, newTree(nkCall, newSymNode(getSysSym(c.graph, a.info, "arrayWith"), a.info),
  633. semExprWithType(c, child),
  634. node
  635. ))
  636. result.typ = aTyp
  637. else:
  638. result = nil
  639. elif aTypSkip.kind == tyTuple:
  640. var hasDefault = false
  641. if aTypSkip.n != nil:
  642. let children = defaultFieldsForTuple(c, aTypSkip.n, hasDefault, checkDefault)
  643. if hasDefault and children.len > 0:
  644. result = newNodeI(nkTupleConstr, a.info)
  645. result.typ = aTyp
  646. result.sons.add children
  647. result = semExpr(c, result)
  648. else:
  649. result = nil
  650. else:
  651. result = nil
  652. else:
  653. result = nil
  654. proc defaultNodeField(c: PContext, a: PNode, checkDefault: bool): PNode =
  655. result = defaultNodeField(c, a, a.typ, checkDefault)
  656. include semtempl, semgnrc, semstmts, semexprs
  657. proc addCodeForGenerics(c: PContext, n: PNode) =
  658. for i in c.lastGenericIdx..<c.generics.len:
  659. var prc = c.generics[i].inst.sym
  660. if prc.kind in {skProc, skFunc, skMethod, skConverter} and prc.magic == mNone:
  661. if prc.ast == nil or prc.ast[bodyPos] == nil:
  662. internalError(c.config, prc.info, "no code for " & prc.name.s)
  663. else:
  664. n.add prc.ast
  665. c.lastGenericIdx = c.generics.len
  666. proc preparePContext*(graph: ModuleGraph; module: PSym; idgen: IdGenerator): PContext =
  667. result = newContext(graph, module)
  668. result.idgen = idgen
  669. result.enforceVoidContext = newType(tyTyped, idgen, nil)
  670. result.voidType = newType(tyVoid, idgen, nil)
  671. if result.p != nil: internalError(graph.config, module.info, "sem.preparePContext")
  672. result.semConstExpr = semConstExpr
  673. result.semExpr = semExpr
  674. result.semExprWithType = semExprWithType
  675. result.semTryExpr = tryExpr
  676. result.semTryConstExpr = tryConstExpr
  677. result.computeRequiresInit = computeRequiresInit
  678. result.semOperand = semOperand
  679. result.semConstBoolExpr = semConstBoolExpr
  680. result.semOverloadedCall = semOverloadedCall
  681. result.semInferredLambda = semInferredLambda
  682. result.semGenerateInstance = generateInstance
  683. result.semTypeNode = semTypeNode
  684. result.instTypeBoundOp = sigmatch.instTypeBoundOp
  685. result.hasUnresolvedArgs = hasUnresolvedArgs
  686. result.templInstCounter = new int
  687. pushProcCon(result, module)
  688. pushOwner(result, result.module)
  689. result.moduleScope = openScope(result)
  690. result.moduleScope.addSym(module) # a module knows itself
  691. if sfSystemModule in module.flags:
  692. graph.systemModule = module
  693. result.topLevelScope = openScope(result)
  694. proc isImportSystemStmt(g: ModuleGraph; n: PNode): bool =
  695. if g.systemModule == nil: return false
  696. var n = n
  697. if n.kind == nkStmtList:
  698. for i in 0..<n.len-1:
  699. if n[i].kind notin {nkCommentStmt, nkEmpty}:
  700. n = n[i]
  701. break
  702. case n.kind
  703. of nkImportStmt:
  704. result = false
  705. for x in n:
  706. if x.kind == nkIdent:
  707. let f = checkModuleName(g.config, x, false)
  708. if f == g.systemModule.info.fileIndex:
  709. return true
  710. of nkImportExceptStmt, nkFromStmt:
  711. result = false
  712. if n[0].kind == nkIdent:
  713. let f = checkModuleName(g.config, n[0], false)
  714. if f == g.systemModule.info.fileIndex:
  715. return true
  716. else: result = false
  717. proc isEmptyTree(n: PNode): bool =
  718. case n.kind
  719. of nkStmtList:
  720. for it in n:
  721. if not isEmptyTree(it): return false
  722. result = true
  723. of nkEmpty, nkCommentStmt: result = true
  724. else: result = false
  725. proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode =
  726. if c.topStmts == 0 and not isImportSystemStmt(c.graph, n):
  727. if sfSystemModule notin c.module.flags and not isEmptyTree(n):
  728. assert c.graph.systemModule != nil
  729. c.moduleScope.addSym c.graph.systemModule # import the "System" identifier
  730. importAllSymbols(c, c.graph.systemModule)
  731. inc c.topStmts
  732. else:
  733. inc c.topStmts
  734. if sfNoForward in c.module.flags:
  735. result = semAllTypeSections(c, n)
  736. else:
  737. result = n
  738. result = semStmt(c, result, {})
  739. when false:
  740. # Code generators are lazy now and can deal with undeclared procs, so these
  741. # steps are not required anymore and actually harmful for the upcoming
  742. # destructor support.
  743. # BUGFIX: process newly generated generics here, not at the end!
  744. if c.lastGenericIdx < c.generics.len:
  745. var a = newNodeI(nkStmtList, n.info)
  746. addCodeForGenerics(c, a)
  747. if a.len > 0:
  748. # a generic has been added to `a`:
  749. if result.kind != nkEmpty: a.add result
  750. result = a
  751. result = hloStmt(c, result)
  752. if c.config.cmd == cmdInteractive and not isEmptyType(result.typ):
  753. result = buildEchoStmt(c, result)
  754. if c.config.cmd == cmdIdeTools:
  755. appendToModule(c.module, result)
  756. trackStmt(c, c.module, result, isTopLevel = true)
  757. proc recoverContext(c: PContext) =
  758. # clean up in case of a semantic error: We clean up the stacks, etc. This is
  759. # faster than wrapping every stack operation in a 'try finally' block and
  760. # requires far less code.
  761. c.currentScope = c.topLevelScope
  762. while getCurrOwner(c).kind != skModule: popOwner(c)
  763. while c.p != nil and c.p.owner.kind != skModule: c.p = c.p.next
  764. proc semWithPContext*(c: PContext, n: PNode): PNode =
  765. # no need for an expensive 'try' if we stop after the first error anyway:
  766. if c.config.errorMax <= 1:
  767. result = semStmtAndGenerateGenerics(c, n)
  768. else:
  769. let oldContextLen = msgs.getInfoContextLen(c.config)
  770. let oldInGenericInst = c.inGenericInst
  771. try:
  772. result = semStmtAndGenerateGenerics(c, n)
  773. except ERecoverableError, ESuggestDone:
  774. recoverContext(c)
  775. c.inGenericInst = oldInGenericInst
  776. msgs.setInfoContextLen(c.config, oldContextLen)
  777. if getCurrentException() of ESuggestDone:
  778. c.suggestionsMade = true
  779. result = nil
  780. else:
  781. result = newNodeI(nkEmpty, n.info)
  782. #if c.config.cmd == cmdIdeTools: findSuggest(c, n)
  783. storeRodNode(c, result)
  784. proc reportUnusedModules(c: PContext) =
  785. if c.config.cmd == cmdM: return
  786. for i in 0..high(c.unusedImports):
  787. if sfUsed notin c.unusedImports[i][0].flags:
  788. message(c.config, c.unusedImports[i][1], warnUnusedImportX, c.unusedImports[i][0].name.s)
  789. proc closePContext*(graph: ModuleGraph; c: PContext, n: PNode): PNode =
  790. if c.config.cmd == cmdIdeTools and not c.suggestionsMade:
  791. suggestSentinel(c)
  792. closeScope(c) # close module's scope
  793. rawCloseScope(c) # imported symbols; don't check for unused ones!
  794. reportUnusedModules(c)
  795. result = newNode(nkStmtList)
  796. if n != nil:
  797. internalError(c.config, n.info, "n is not nil") #result := n;
  798. addCodeForGenerics(c, result)
  799. if c.module.ast != nil:
  800. result.add(c.module.ast)
  801. popOwner(c)
  802. popProcCon(c)
  803. sealRodFile(c)