sem.nim 33 KB

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