semexprs.nim 105 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818
  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 for expressions
  10. # included from sem.nim
  11. const
  12. errExprXHasNoType = "expression '$1' has no type (or is ambiguous)"
  13. errXExpectsTypeOrValue = "'$1' expects a type or value"
  14. errVarForOutParamNeededX = "for a 'var' type a variable needs to be passed; but '$1' is immutable"
  15. errXStackEscape = "address of '$1' may not escape its stack frame"
  16. errExprHasNoAddress = "expression has no address"
  17. errCannotInterpretNodeX = "cannot evaluate '$1'"
  18. errNamedExprExpected = "named expression expected"
  19. errNamedExprNotAllowed = "named expression not allowed here"
  20. errFieldInitTwice = "field initialized twice: '$1'"
  21. errUndeclaredFieldX = "undeclared field: '$1'"
  22. proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
  23. flags: TExprFlags = {}): PNode =
  24. let info = getCallLineInfo(n)
  25. markUsed(c, info, s)
  26. onUse(info, s)
  27. # Note: This is n.info on purpose. It prevents template from creating an info
  28. # context when called from an another template
  29. pushInfoContext(c.config, n.info, s.detailedInfo)
  30. result = evalTemplate(n, s, getCurrOwner(c), c.config, c.cache, efFromHlo in flags)
  31. if efNoSemCheck notin flags: result = semAfterMacroCall(c, n, result, s, flags)
  32. popInfoContext(c.config)
  33. # XXX: A more elaborate line info rewrite might be needed
  34. result.info = info
  35. proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
  36. template rejectEmptyNode(n: PNode) =
  37. # No matter what a nkEmpty node is not what we want here
  38. if n.kind == nkEmpty: illFormedAst(n, c.config)
  39. proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
  40. rejectEmptyNode(n)
  41. # same as 'semExprWithType' but doesn't check for proc vars
  42. result = semExpr(c, n, flags + {efOperand})
  43. if result.typ != nil:
  44. # XXX tyGenericInst here?
  45. if result.typ.kind == tyProc and tfUnresolved in result.typ.flags:
  46. localError(c.config, n.info, errProcHasNoConcreteType % n.renderTree)
  47. if result.typ.kind in {tyVar, tyLent}: result = newDeref(result)
  48. elif {efWantStmt, efAllowStmt} * flags != {}:
  49. result.typ = newTypeS(tyVoid, c)
  50. else:
  51. localError(c.config, n.info, errExprXHasNoType %
  52. renderTree(result, {renderNoComments}))
  53. result.typ = errorType(c)
  54. proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
  55. rejectEmptyNode(n)
  56. result = semExpr(c, n, flags+{efWantValue})
  57. if result.kind == nkEmpty:
  58. # do not produce another redundant error message:
  59. result = errorNode(c, n)
  60. if result.typ == nil or result.typ == c.enforceVoidContext:
  61. localError(c.config, n.info, errExprXHasNoType %
  62. renderTree(result, {renderNoComments}))
  63. result.typ = errorType(c)
  64. else:
  65. if result.typ.kind in {tyVar, tyLent}: result = newDeref(result)
  66. proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
  67. rejectEmptyNode(n)
  68. result = semExpr(c, n, flags+{efWantValue})
  69. if result.kind == nkEmpty:
  70. # do not produce another redundant error message:
  71. result = errorNode(c, n)
  72. if result.typ == nil:
  73. localError(c.config, n.info, errExprXHasNoType %
  74. renderTree(result, {renderNoComments}))
  75. result.typ = errorType(c)
  76. proc semSymGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
  77. result = symChoice(c, n, s, scClosed)
  78. proc inlineConst(c: PContext, n: PNode, s: PSym): PNode {.inline.} =
  79. result = copyTree(s.ast)
  80. if result.isNil:
  81. localError(c.config, n.info, "constant of type '" & typeToString(s.typ) & "' has no value")
  82. result = newSymNode(s)
  83. else:
  84. result.typ = s.typ
  85. result.info = n.info
  86. type
  87. TConvStatus = enum
  88. convOK,
  89. convNotNeedeed,
  90. convNotLegal,
  91. convNotInRange
  92. proc checkConversionBetweenObjects(castDest, src: PType; pointers: int): TConvStatus =
  93. let diff = inheritanceDiff(castDest, src)
  94. return if diff == high(int) or (pointers > 1 and diff != 0):
  95. convNotLegal
  96. else:
  97. convOK
  98. const
  99. IntegralTypes = {tyBool, tyEnum, tyChar, tyInt..tyUInt64}
  100. proc checkConvertible(c: PContext, targetTyp: PType, src: PNode): TConvStatus =
  101. let srcTyp = src.typ.skipTypes({tyStatic})
  102. result = convOK
  103. if sameType(targetTyp, srcTyp) and targetTyp.sym == srcTyp.sym:
  104. # don't annoy conversions that may be needed on another processor:
  105. if targetTyp.kind notin IntegralTypes+{tyRange}:
  106. result = convNotNeedeed
  107. return
  108. var d = skipTypes(targetTyp, abstractVar)
  109. var s = srcTyp
  110. if s.kind in tyUserTypeClasses and s.isResolvedUserTypeClass:
  111. s = s.lastSon
  112. s = skipTypes(s, abstractVar-{tyTypeDesc, tyOwned})
  113. if s.kind == tyOwned and d.kind != tyOwned:
  114. s = s.lastSon
  115. var pointers = 0
  116. while (d != nil) and (d.kind in {tyPtr, tyRef, tyOwned}):
  117. if s.kind == tyOwned and d.kind != tyOwned:
  118. s = s.lastSon
  119. elif d.kind != s.kind:
  120. break
  121. else:
  122. d = d.lastSon
  123. s = s.lastSon
  124. inc pointers
  125. let targetBaseTyp = skipTypes(targetTyp, abstractVarRange)
  126. let srcBaseTyp = skipTypes(srcTyp, abstractVarRange-{tyTypeDesc})
  127. if d == nil:
  128. result = convNotLegal
  129. elif d.skipTypes(abstractInst).kind == tyObject and s.skipTypes(abstractInst).kind == tyObject:
  130. result = checkConversionBetweenObjects(d.skipTypes(abstractInst), s.skipTypes(abstractInst), pointers)
  131. elif (targetBaseTyp.kind in IntegralTypes) and
  132. (srcBaseTyp.kind in IntegralTypes):
  133. if targetTyp.isOrdinalType:
  134. if src.kind in nkCharLit..nkUInt64Lit and
  135. src.getInt notin firstOrd(c.config, targetTyp)..lastOrd(c.config, targetTyp):
  136. result = convNotInRange
  137. elif src.kind in nkFloatLit..nkFloat64Lit and
  138. (classify(src.floatVal) in {fcNan, fcNegInf, fcInf} or
  139. src.floatVal.int64 notin firstOrd(c.config, targetTyp)..lastOrd(c.config, targetTyp)):
  140. result = convNotInRange
  141. elif targetBaseTyp.kind in tyFloat..tyFloat64:
  142. if src.kind in nkFloatLit..nkFloat64Lit and
  143. not floatRangeCheck(src.floatVal, targetTyp):
  144. result = convNotInRange
  145. elif src.kind in nkCharLit..nkUInt64Lit and
  146. not floatRangeCheck(src.intVal.float, targetTyp):
  147. result = convNotInRange
  148. else:
  149. # we use d, s here to speed up that operation a bit:
  150. case cmpTypes(c, d, s)
  151. of isNone, isGeneric:
  152. if not compareTypes(targetTyp.skipTypes(abstractVar), srcTyp.skipTypes({tyOwned}), dcEqIgnoreDistinct):
  153. result = convNotLegal
  154. else:
  155. discard
  156. proc isCastable(conf: ConfigRef; dst, src: PType): bool =
  157. ## Checks whether the source type can be cast to the destination type.
  158. ## Casting is very unrestrictive; casts are allowed as long as
  159. ## castDest.size >= src.size, and typeAllowed(dst, skParam)
  160. #const
  161. # castableTypeKinds = {tyInt, tyPtr, tyRef, tyCstring, tyString,
  162. # tySequence, tyPointer, tyNil, tyOpenArray,
  163. # tyProc, tySet, tyEnum, tyBool, tyChar}
  164. let src = src.skipTypes(tyUserTypeClasses)
  165. if skipTypes(dst, abstractInst-{tyOpenArray}).kind == tyOpenArray:
  166. return false
  167. if skipTypes(src, abstractInst-{tyTypeDesc}).kind == tyTypeDesc:
  168. return false
  169. var dstSize, srcSize: BiggestInt
  170. dstSize = computeSize(conf, dst)
  171. srcSize = computeSize(conf, src)
  172. if dstSize == -3 or srcSize == -3: # szUnknownSize
  173. # The Nim compiler can't detect if it's legal or not.
  174. # Just assume the programmer knows what he is doing.
  175. return true
  176. if dstSize < 0:
  177. result = false
  178. elif srcSize < 0:
  179. result = false
  180. elif typeAllowed(dst, skParam) != nil:
  181. result = false
  182. elif dst.kind == tyProc and dst.callConv == ccClosure:
  183. result = src.kind == tyProc and src.callConv == ccClosure
  184. else:
  185. result = (dstSize >= srcSize) or
  186. (skipTypes(dst, abstractInst).kind in IntegralTypes) or
  187. (skipTypes(src, abstractInst-{tyTypeDesc}).kind in IntegralTypes)
  188. if result and src.kind == tyNil:
  189. result = dst.size <= conf.target.ptrSize
  190. proc isSymChoice(n: PNode): bool {.inline.} =
  191. result = n.kind in nkSymChoices
  192. proc maybeLiftType(t: var PType, c: PContext, info: TLineInfo) =
  193. # XXX: liftParamType started to perform addDecl
  194. # we could do that instead in semTypeNode by snooping for added
  195. # gnrc. params, then it won't be necessary to open a new scope here
  196. openScope(c)
  197. var lifted = liftParamType(c, skType, newNodeI(nkArgList, info),
  198. t, ":anon", info)
  199. closeScope(c)
  200. if lifted != nil: t = lifted
  201. proc isOwnedSym(c: PContext; n: PNode): bool =
  202. let s = qualifiedLookUp(c, n, {})
  203. result = s != nil and sfSystemModule in s.owner.flags and s.name.s == "owned"
  204. proc semConv(c: PContext, n: PNode): PNode =
  205. if len(n) != 2:
  206. localError(c.config, n.info, "a type conversion takes exactly one argument")
  207. return n
  208. result = newNodeI(nkConv, n.info)
  209. var targetType = semTypeNode(c, n.sons[0], nil)
  210. if targetType.kind == tyTypeDesc:
  211. internalAssert c.config, targetType.len > 0
  212. if targetType.base.kind == tyNone:
  213. return semTypeOf(c, n)
  214. else:
  215. targetType = targetType.base
  216. elif targetType.kind == tyStatic:
  217. var evaluated = semStaticExpr(c, n[1])
  218. if evaluated.kind == nkType or evaluated.typ.kind == tyTypeDesc:
  219. result = n
  220. result.typ = c.makeTypeDesc semStaticType(c, evaluated, nil)
  221. return
  222. elif targetType.base.kind == tyNone:
  223. return evaluated
  224. else:
  225. targetType = targetType.base
  226. maybeLiftType(targetType, c, n[0].info)
  227. if targetType.kind in {tySink, tyLent} or isOwnedSym(c, n[0]):
  228. let baseType = semTypeNode(c, n.sons[1], nil).skipTypes({tyTypeDesc})
  229. let t = newTypeS(targetType.kind, c)
  230. if targetType.kind == tyOwned:
  231. t.flags.incl tfHasOwned
  232. t.rawAddSonNoPropagationOfTypeFlags baseType
  233. result = newNodeI(nkType, n.info)
  234. result.typ = makeTypeDesc(c, t)
  235. return
  236. result.addSon copyTree(n.sons[0])
  237. # special case to make MyObject(x = 3) produce a nicer error message:
  238. if n[1].kind == nkExprEqExpr and
  239. targetType.skipTypes(abstractPtrs).kind == tyObject:
  240. localError(c.config, n.info, "object construction uses ':', not '='")
  241. var op = semExprWithType(c, n.sons[1])
  242. if targetType.isMetaType:
  243. let final = inferWithMetatype(c, targetType, op, true)
  244. result.addSon final
  245. result.typ = final.typ
  246. return
  247. result.typ = targetType
  248. # XXX op is overwritten later on, this is likely added too early
  249. # here or needs to be overwritten too then.
  250. addSon(result, op)
  251. if not isSymChoice(op):
  252. let status = checkConvertible(c, result.typ, op)
  253. case status
  254. of convOK:
  255. # handle SomeProcType(SomeGenericProc)
  256. if op.kind == nkSym and op.sym.isGenericRoutine:
  257. result.sons[1] = fitNode(c, result.typ, result.sons[1], result.info)
  258. elif op.kind in {nkPar, nkTupleConstr} and targetType.kind == tyTuple:
  259. op = fitNode(c, targetType, op, result.info)
  260. of convNotNeedeed:
  261. message(c.config, n.info, hintConvFromXtoItselfNotNeeded, result.typ.typeToString)
  262. of convNotLegal:
  263. result = fitNode(c, result.typ, result.sons[1], result.info)
  264. if result == nil:
  265. localError(c.config, n.info, "illegal conversion from '$1' to '$2'" %
  266. [op.typ.typeToString, result.typ.typeToString])
  267. of convNotInRange:
  268. let value =
  269. if op.kind in {nkCharLit..nkUInt64Lit}: $op.getInt else: $op.getFloat
  270. localError(c.config, n.info, errGenerated, value & " can't be converted to " &
  271. result.typ.typeToString)
  272. else:
  273. for i in 0 ..< len(op):
  274. let it = op.sons[i]
  275. let status = checkConvertible(c, result.typ, it)
  276. if status in {convOK, convNotNeedeed}:
  277. markUsed(c, n.info, it.sym)
  278. onUse(n.info, it.sym)
  279. markIndirect(c, it.sym)
  280. return it
  281. errorUseQualifier(c, n.info, op.sons[0].sym)
  282. proc semCast(c: PContext, n: PNode): PNode =
  283. ## Semantically analyze a casting ("cast[type](param)")
  284. checkSonsLen(n, 2, c.config)
  285. let targetType = semTypeNode(c, n.sons[0], nil)
  286. let castedExpr = semExprWithType(c, n.sons[1])
  287. if tfHasMeta in targetType.flags:
  288. localError(c.config, n.sons[0].info, "cannot cast to a non concrete type: '$1'" % $targetType)
  289. if not isCastable(c.config, targetType, castedExpr.typ):
  290. let tar = $targetType
  291. let alt = typeToString(targetType, preferDesc)
  292. let msg = if tar != alt: tar & "=" & alt else: tar
  293. localError(c.config, n.info, "expression cannot be cast to " & msg)
  294. result = newNodeI(nkCast, n.info)
  295. result.typ = targetType
  296. addSon(result, copyTree(n.sons[0]))
  297. addSon(result, castedExpr)
  298. proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
  299. const
  300. opToStr: array[mLow..mHigh, string] = ["low", "high"]
  301. if len(n) != 2:
  302. localError(c.config, n.info, errXExpectsTypeOrValue % opToStr[m])
  303. else:
  304. n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType})
  305. var typ = skipTypes(n.sons[1].typ, abstractVarRange + {tyTypeDesc, tyUserTypeClassInst})
  306. case typ.kind
  307. of tySequence, tyString, tyCString, tyOpenArray, tyVarargs:
  308. n.typ = getSysType(c.graph, n.info, tyInt)
  309. of tyArray:
  310. n.typ = typ.sons[0] # indextype
  311. of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt..tyUInt64, tyFloat..tyFloat64:
  312. n.typ = n.sons[1].typ.skipTypes({tyTypeDesc})
  313. of tyGenericParam:
  314. # prepare this for resolving in semtypinst:
  315. # we must use copyTree here in order to avoid creating a cycle
  316. # that could easily turn into an infinite recursion in semtypinst
  317. n.typ = makeTypeFromExpr(c, n.copyTree)
  318. else:
  319. localError(c.config, n.info, "invalid argument for: " & opToStr[m])
  320. result = n
  321. proc fixupStaticType(c: PContext, n: PNode) =
  322. # This proc can be applied to evaluated expressions to assign
  323. # them a static type.
  324. #
  325. # XXX: with implicit static, this should not be necessary,
  326. # because the output type of operations such as `semConstExpr`
  327. # should be a static type (as well as the type of any other
  328. # expression that can be implicitly evaluated). For now, we
  329. # apply this measure only in code that is enlightened to work
  330. # with static types.
  331. if n.typ.kind != tyStatic:
  332. n.typ = newTypeWithSons(getCurrOwner(c), tyStatic, @[n.typ])
  333. n.typ.n = n # XXX: cycles like the one here look dangerous.
  334. # Consider using `n.copyTree`
  335. proc isOpImpl(c: PContext, n: PNode, flags: TExprFlags): PNode =
  336. internalAssert c.config,
  337. n.len == 3 and
  338. n[1].typ != nil and
  339. n[2].kind in {nkStrLit..nkTripleStrLit, nkType}
  340. var
  341. res = false
  342. t1 = n[1].typ
  343. t2 = n[2].typ
  344. if t1.kind == tyTypeDesc and t2.kind != tyTypeDesc:
  345. t1 = t1.base
  346. if n[2].kind in {nkStrLit..nkTripleStrLit}:
  347. case n[2].strVal.normalize
  348. of "closure":
  349. let t = skipTypes(t1, abstractRange)
  350. res = t.kind == tyProc and
  351. t.callConv == ccClosure and
  352. tfIterator notin t.flags
  353. of "iterator":
  354. let t = skipTypes(t1, abstractRange)
  355. res = t.kind == tyProc and
  356. t.callConv == ccClosure and
  357. tfIterator in t.flags
  358. else:
  359. res = false
  360. else:
  361. maybeLiftType(t2, c, n.info)
  362. var m: TCandidate
  363. initCandidate(c, m, t2)
  364. if efExplain in flags:
  365. m.diagnostics = @[]
  366. m.diagnosticsEnabled = true
  367. res = typeRel(m, t2, t1) >= isSubtype # isNone
  368. result = newIntNode(nkIntLit, ord(res))
  369. result.typ = n.typ
  370. proc semIs(c: PContext, n: PNode, flags: TExprFlags): PNode =
  371. if len(n) != 3:
  372. localError(c.config, n.info, "'is' operator takes 2 arguments")
  373. let boolType = getSysType(c.graph, n.info, tyBool)
  374. result = n
  375. n.typ = boolType
  376. var liftLhs = true
  377. n.sons[1] = semExprWithType(c, n[1], {efDetermineType, efWantIterator})
  378. if n[2].kind notin {nkStrLit..nkTripleStrLit}:
  379. let t2 = semTypeNode(c, n[2], nil)
  380. n.sons[2] = newNodeIT(nkType, n[2].info, t2)
  381. if t2.kind == tyStatic:
  382. let evaluated = tryConstExpr(c, n[1])
  383. if evaluated != nil:
  384. c.fixupStaticType(evaluated)
  385. n[1] = evaluated
  386. else:
  387. result = newIntNode(nkIntLit, 0)
  388. result.typ = boolType
  389. return
  390. elif t2.kind == tyTypeDesc and
  391. (t2.base.kind == tyNone or tfExplicit in t2.flags):
  392. # When the right-hand side is an explicit type, we must
  393. # not allow regular values to be matched against the type:
  394. liftLhs = false
  395. else:
  396. n.sons[2] = semExpr(c, n[2])
  397. var lhsType = n[1].typ
  398. if lhsType.kind != tyTypeDesc:
  399. if liftLhs:
  400. n[1] = makeTypeSymNode(c, lhsType, n[1].info)
  401. lhsType = n[1].typ
  402. else:
  403. if lhsType.base.kind == tyNone or
  404. (c.inGenericContext > 0 and lhsType.base.containsGenericType):
  405. # BUGFIX: don't evaluate this too early: ``T is void``
  406. return
  407. result = isOpImpl(c, n, flags)
  408. proc semOpAux(c: PContext, n: PNode) =
  409. const flags = {efDetermineType}
  410. for i in 1 ..< n.len:
  411. var a = n.sons[i]
  412. if a.kind == nkExprEqExpr and len(a) == 2:
  413. let info = a.sons[0].info
  414. a.sons[0] = newIdentNode(considerQuotedIdent(c, a.sons[0], a), info)
  415. a.sons[1] = semExprWithType(c, a.sons[1], flags)
  416. a.typ = a.sons[1].typ
  417. else:
  418. n.sons[i] = semExprWithType(c, a, flags)
  419. proc overloadedCallOpr(c: PContext, n: PNode): PNode =
  420. # quick check if there is *any* () operator overloaded:
  421. var par = getIdent(c.cache, "()")
  422. if searchInScopes(c, par) == nil:
  423. result = nil
  424. else:
  425. result = newNodeI(nkCall, n.info)
  426. addSon(result, newIdentNode(par, n.info))
  427. for i in 0 ..< len(n): addSon(result, n.sons[i])
  428. result = semExpr(c, result)
  429. proc changeType(c: PContext; n: PNode, newType: PType, check: bool) =
  430. case n.kind
  431. of nkCurly, nkBracket:
  432. for i in 0 ..< len(n):
  433. changeType(c, n.sons[i], elemType(newType), check)
  434. of nkPar, nkTupleConstr:
  435. let tup = newType.skipTypes({tyGenericInst, tyAlias, tySink, tyDistinct})
  436. if tup.kind != tyTuple:
  437. if tup.kind == tyObject: return
  438. globalError(c.config, n.info, "no tuple type for constructor")
  439. elif len(n) > 0 and n.sons[0].kind == nkExprColonExpr:
  440. # named tuple?
  441. for i in 0 ..< len(n):
  442. var m = n.sons[i].sons[0]
  443. if m.kind != nkSym:
  444. globalError(c.config, m.info, "invalid tuple constructor")
  445. return
  446. if tup.n != nil:
  447. var f = getSymFromList(tup.n, m.sym.name)
  448. if f == nil:
  449. globalError(c.config, m.info, "unknown identifier: " & m.sym.name.s)
  450. return
  451. changeType(c, n.sons[i].sons[1], f.typ, check)
  452. else:
  453. changeType(c, n.sons[i].sons[1], tup.sons[i], check)
  454. else:
  455. for i in 0 ..< len(n):
  456. changeType(c, n.sons[i], tup.sons[i], check)
  457. when false:
  458. var m = n.sons[i]
  459. var a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i])
  460. addSon(a, newSymNode(newType.n.sons[i].sym))
  461. addSon(a, m)
  462. changeType(m, tup.sons[i], check)
  463. of nkCharLit..nkUInt64Lit:
  464. if check and n.kind != nkUInt64Lit and not sameType(n.typ, newType):
  465. let value = n.intVal
  466. if value < firstOrd(c.config, newType) or value > lastOrd(c.config, newType):
  467. localError(c.config, n.info, "cannot convert " & $value &
  468. " to " & typeToString(newType))
  469. of nkFloatLit..nkFloat64Lit:
  470. if check and not floatRangeCheck(n.floatVal, newType):
  471. localError(c.config, n.info, errFloatToString % [$n.floatVal, typeToString(newType)])
  472. else: discard
  473. n.typ = newType
  474. proc arrayConstrType(c: PContext, n: PNode): PType =
  475. var typ = newTypeS(tyArray, c)
  476. rawAddSon(typ, nil) # index type
  477. if len(n) == 0:
  478. rawAddSon(typ, newTypeS(tyEmpty, c)) # needs an empty basetype!
  479. else:
  480. var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink})
  481. addSonSkipIntLit(typ, t)
  482. typ.sons[0] = makeRangeType(c, 0, len(n) - 1, n.info)
  483. result = typ
  484. proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
  485. result = newNodeI(nkBracket, n.info)
  486. result.typ = newTypeS(tyArray, c)
  487. rawAddSon(result.typ, nil) # index type
  488. var
  489. firstIndex, lastIndex: Int128
  490. indexType = getSysType(c.graph, n.info, tyInt)
  491. lastValidIndex = lastOrd(c.config, indexType)
  492. if len(n) == 0:
  493. rawAddSon(result.typ, newTypeS(tyEmpty, c)) # needs an empty basetype!
  494. lastIndex = toInt128(-1)
  495. else:
  496. var x = n.sons[0]
  497. if x.kind == nkExprColonExpr and len(x) == 2:
  498. var idx = semConstExpr(c, x.sons[0])
  499. if not isOrdinalType(idx.typ):
  500. localError(c.config, idx.info, "expected ordinal value for array " &
  501. "index, got '$1'" % renderTree(idx))
  502. else:
  503. firstIndex = getOrdValue(idx)
  504. lastIndex = firstIndex
  505. indexType = idx.typ
  506. lastValidIndex = lastOrd(c.config, indexType)
  507. x = x.sons[1]
  508. let yy = semExprWithType(c, x)
  509. var typ = yy.typ
  510. addSon(result, yy)
  511. #var typ = skipTypes(result.sons[0].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal})
  512. for i in 1 ..< len(n):
  513. if lastIndex == lastValidIndex:
  514. let validIndex = makeRangeType(c, toInt64(firstIndex), toInt64(lastValidIndex), n.info,
  515. indexType)
  516. localError(c.config, n.info, "size of array exceeds range of index " &
  517. "type '$1' by $2 elements" % [typeToString(validIndex), $(n.len-i)])
  518. x = n.sons[i]
  519. if x.kind == nkExprColonExpr and len(x) == 2:
  520. var idx = semConstExpr(c, x.sons[0])
  521. idx = fitNode(c, indexType, idx, x.info)
  522. if lastIndex+1 != getOrdValue(idx):
  523. localError(c.config, x.info, "invalid order in array constructor")
  524. x = x.sons[1]
  525. let xx = semExprWithType(c, x, flags*{efAllowDestructor})
  526. result.add xx
  527. typ = commonType(typ, xx.typ)
  528. #n.sons[i] = semExprWithType(c, x, flags*{efAllowDestructor})
  529. #addSon(result, fitNode(c, typ, n.sons[i]))
  530. inc(lastIndex)
  531. addSonSkipIntLit(result.typ, typ)
  532. for i in 0 ..< result.len:
  533. result.sons[i] = fitNode(c, typ, result.sons[i], result.sons[i].info)
  534. result.typ.sons[0] = makeRangeType(c, toInt64(firstIndex), toInt64(lastIndex), n.info,
  535. indexType)
  536. proc fixAbstractType(c: PContext, n: PNode) =
  537. for i in 1 ..< n.len:
  538. let it = n.sons[i]
  539. # do not get rid of nkHiddenSubConv for OpenArrays, the codegen needs it:
  540. if it.kind == nkHiddenSubConv and
  541. skipTypes(it.typ, abstractVar).kind notin {tyOpenArray, tyVarargs}:
  542. if skipTypes(it.sons[1].typ, abstractVar).kind in
  543. {tyNil, tyTuple, tySet} or it[1].isArrayConstr:
  544. var s = skipTypes(it.typ, abstractVar)
  545. if s.kind != tyUntyped:
  546. changeType(c, it.sons[1], s, check=true)
  547. n.sons[i] = it.sons[1]
  548. proc isAssignable(c: PContext, n: PNode; isUnsafeAddr=false): TAssignableResult =
  549. result = parampatterns.isAssignable(c.p.owner, n, isUnsafeAddr)
  550. proc isUnresolvedSym(s: PSym): bool =
  551. return s.kind == skGenericParam or
  552. tfInferrableStatic in s.typ.flags or
  553. (s.kind == skParam and s.typ.isMetaType) or
  554. (s.kind == skType and
  555. s.typ.flags * {tfGenericTypeParam, tfImplicitTypeParam} != {})
  556. proc hasUnresolvedArgs(c: PContext, n: PNode): bool =
  557. # Checks whether an expression depends on generic parameters that
  558. # don't have bound values yet. E.g. this could happen in situations
  559. # such as:
  560. # type Slot[T] = array[T.size, byte]
  561. # proc foo[T](x: default(T))
  562. #
  563. # Both static parameter and type parameters can be unresolved.
  564. case n.kind
  565. of nkSym:
  566. return isUnresolvedSym(n.sym)
  567. of nkIdent, nkAccQuoted:
  568. let ident = considerQuotedIdent(c, n)
  569. let sym = searchInScopes(c, ident)
  570. if sym != nil:
  571. return isUnresolvedSym(sym)
  572. else:
  573. return false
  574. else:
  575. for i in 0..<n.safeLen:
  576. if hasUnresolvedArgs(c, n.sons[i]): return true
  577. return false
  578. proc newHiddenAddrTaken(c: PContext, n: PNode): PNode =
  579. if n.kind == nkHiddenDeref and not (c.config.cmd == cmdCompileToCpp or
  580. sfCompileToCpp in c.module.flags):
  581. checkSonsLen(n, 1, c.config)
  582. result = n.sons[0]
  583. else:
  584. result = newNodeIT(nkHiddenAddr, n.info, makeVarType(c, n.typ))
  585. addSon(result, n)
  586. if isAssignable(c, n) notin {arLValue, arLocalLValue}:
  587. localError(c.config, n.info, errVarForOutParamNeededX % renderNotLValue(n))
  588. proc analyseIfAddressTaken(c: PContext, n: PNode): PNode =
  589. result = n
  590. case n.kind
  591. of nkSym:
  592. # n.sym.typ can be nil in 'check' mode ...
  593. if n.sym.typ != nil and
  594. skipTypes(n.sym.typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
  595. incl(n.sym.flags, sfAddrTaken)
  596. result = newHiddenAddrTaken(c, n)
  597. of nkDotExpr:
  598. checkSonsLen(n, 2, c.config)
  599. if n.sons[1].kind != nkSym:
  600. internalError(c.config, n.info, "analyseIfAddressTaken")
  601. return
  602. if skipTypes(n.sons[1].sym.typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
  603. incl(n.sons[1].sym.flags, sfAddrTaken)
  604. result = newHiddenAddrTaken(c, n)
  605. of nkBracketExpr:
  606. checkMinSonsLen(n, 1, c.config)
  607. if skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
  608. if n.sons[0].kind == nkSym: incl(n.sons[0].sym.flags, sfAddrTaken)
  609. result = newHiddenAddrTaken(c, n)
  610. else:
  611. result = newHiddenAddrTaken(c, n)
  612. proc analyseIfAddressTakenInCall(c: PContext, n: PNode) =
  613. checkMinSonsLen(n, 1, c.config)
  614. const
  615. FakeVarParams = {mNew, mNewFinalize, mInc, ast.mDec, mIncl, mExcl,
  616. mSetLengthStr, mSetLengthSeq, mAppendStrCh, mAppendStrStr, mSwap,
  617. mAppendSeqElem, mNewSeq, mReset, mShallowCopy, mDeepCopy, mMove,
  618. mWasMoved}
  619. # get the real type of the callee
  620. # it may be a proc var with a generic alias type, so we skip over them
  621. var t = n.sons[0].typ.skipTypes({tyGenericInst, tyAlias, tySink})
  622. if n.sons[0].kind == nkSym and n.sons[0].sym.magic in FakeVarParams:
  623. # BUGFIX: check for L-Value still needs to be done for the arguments!
  624. # note sometimes this is eval'ed twice so we check for nkHiddenAddr here:
  625. for i in 1 ..< len(n):
  626. if i < len(t) and t.sons[i] != nil and
  627. skipTypes(t.sons[i], abstractInst-{tyTypeDesc}).kind == tyVar:
  628. let it = n[i]
  629. if isAssignable(c, it) notin {arLValue, arLocalLValue}:
  630. if it.kind != nkHiddenAddr:
  631. localError(c.config, it.info, errVarForOutParamNeededX % $it)
  632. # bug #5113: disallow newSeq(result) where result is a 'var T':
  633. if n[0].sym.magic in {mNew, mNewFinalize, mNewSeq}:
  634. var arg = n[1] #.skipAddr
  635. if arg.kind == nkHiddenDeref: arg = arg[0]
  636. if arg.kind == nkSym and arg.sym.kind == skResult and
  637. arg.typ.skipTypes(abstractInst).kind in {tyVar, tyLent}:
  638. localError(c.config, n.info, errXStackEscape % renderTree(n[1], {renderNoComments}))
  639. return
  640. for i in 1 ..< len(n):
  641. let n = if n.kind == nkHiddenDeref: n[0] else: n
  642. if n.sons[i].kind == nkHiddenCallConv:
  643. # we need to recurse explicitly here as converters can create nested
  644. # calls and then they wouldn't be analysed otherwise
  645. analyseIfAddressTakenInCall(c, n.sons[i])
  646. if i < len(t) and
  647. skipTypes(t.sons[i], abstractInst-{tyTypeDesc}).kind == tyVar:
  648. if n.sons[i].kind != nkHiddenAddr:
  649. n.sons[i] = analyseIfAddressTaken(c, n.sons[i])
  650. include semmagic
  651. proc evalAtCompileTime(c: PContext, n: PNode): PNode =
  652. result = n
  653. if n.kind notin nkCallKinds or n.sons[0].kind != nkSym: return
  654. var callee = n.sons[0].sym
  655. # workaround for bug #537 (overly aggressive inlining leading to
  656. # wrong NimNode semantics):
  657. if n.typ != nil and tfTriggersCompileTime in n.typ.flags: return
  658. # constant folding that is necessary for correctness of semantic pass:
  659. if callee.magic != mNone and callee.magic in ctfeWhitelist and n.typ != nil:
  660. var call = newNodeIT(nkCall, n.info, n.typ)
  661. call.add(n.sons[0])
  662. var allConst = true
  663. for i in 1 ..< n.len:
  664. var a = getConstExpr(c.module, n.sons[i], c.graph)
  665. if a == nil:
  666. allConst = false
  667. a = n.sons[i]
  668. if a.kind == nkHiddenStdConv: a = a.sons[1]
  669. call.add(a)
  670. if allConst:
  671. result = semfold.getConstExpr(c.module, call, c.graph)
  672. if result.isNil: result = n
  673. else: return result
  674. block maybeLabelAsStatic:
  675. # XXX: temporary work-around needed for tlateboundstatic.
  676. # This is certainly not correct, but it will get the job
  677. # done until we have a more robust infrastructure for
  678. # implicit statics.
  679. if n.len > 1:
  680. for i in 1 ..< n.len:
  681. # see bug #2113, it's possible that n[i].typ for errornous code:
  682. if n[i].typ.isNil or n[i].typ.kind != tyStatic or
  683. tfUnresolved notin n[i].typ.flags:
  684. break maybeLabelAsStatic
  685. n.typ = newTypeWithSons(c, tyStatic, @[n.typ])
  686. n.typ.flags.incl tfUnresolved
  687. # optimization pass: not necessary for correctness of the semantic pass
  688. if callee.kind == skConst or
  689. {sfNoSideEffect, sfCompileTime} * callee.flags != {} and
  690. {sfForward, sfImportc} * callee.flags == {} and n.typ != nil:
  691. if callee.kind != skConst and
  692. sfCompileTime notin callee.flags and
  693. optImplicitStatic notin c.config.options: return
  694. if callee.magic notin ctfeWhitelist: return
  695. if callee.kind notin {skProc, skFunc, skConverter, skConst} or callee.isGenericRoutine:
  696. return
  697. if n.typ != nil and typeAllowed(n.typ, skConst) != nil: return
  698. var call = newNodeIT(nkCall, n.info, n.typ)
  699. call.add(n.sons[0])
  700. for i in 1 ..< n.len:
  701. let a = getConstExpr(c.module, n.sons[i], c.graph)
  702. if a == nil: return n
  703. call.add(a)
  704. #echo "NOW evaluating at compile time: ", call.renderTree
  705. if c.inStaticContext == 0 or sfNoSideEffect in callee.flags:
  706. if sfCompileTime in callee.flags:
  707. result = evalStaticExpr(c.module, c.graph, call, c.p.owner)
  708. if result.isNil:
  709. localError(c.config, n.info, errCannotInterpretNodeX % renderTree(call))
  710. else: result = fixupTypeAfterEval(c, result, n)
  711. else:
  712. result = evalConstExpr(c.module, c.graph, call)
  713. if result.isNil: result = n
  714. else: result = fixupTypeAfterEval(c, result, n)
  715. else:
  716. result = n
  717. #if result != n:
  718. # echo "SUCCESS evaluated at compile time: ", call.renderTree
  719. proc semStaticExpr(c: PContext, n: PNode): PNode =
  720. inc c.inStaticContext
  721. openScope(c)
  722. let a = semExprWithType(c, n)
  723. closeScope(c)
  724. dec c.inStaticContext
  725. if a.findUnresolvedStatic != nil: return a
  726. result = evalStaticExpr(c.module, c.graph, a, c.p.owner)
  727. if result.isNil:
  728. localError(c.config, n.info, errCannotInterpretNodeX % renderTree(n))
  729. result = c.graph.emptyNode
  730. else:
  731. result = fixupTypeAfterEval(c, result, a)
  732. proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode,
  733. flags: TExprFlags): PNode =
  734. if flags*{efInTypeof, efWantIterator} != {}:
  735. # consider: 'for x in pReturningArray()' --> we don't want the restriction
  736. # to 'skIterator' anymore; skIterator is preferred in sigmatch already
  737. # for typeof support.
  738. # for ``type(countup(1,3))``, see ``tests/ttoseq``.
  739. result = semOverloadedCall(c, n, nOrig,
  740. {skProc, skFunc, skMethod, skConverter, skMacro, skTemplate, skIterator}, flags)
  741. else:
  742. result = semOverloadedCall(c, n, nOrig,
  743. {skProc, skFunc, skMethod, skConverter, skMacro, skTemplate}, flags)
  744. if result != nil:
  745. if result.sons[0].kind != nkSym:
  746. internalError(c.config, "semOverloadedCallAnalyseEffects")
  747. return
  748. let callee = result.sons[0].sym
  749. case callee.kind
  750. of skMacro, skTemplate: discard
  751. else:
  752. if callee.kind == skIterator and callee.id == c.p.owner.id:
  753. localError(c.config, n.info, errRecursiveDependencyIteratorX % callee.name.s)
  754. # error correction, prevents endless for loop elimination in transf.
  755. # See bug #2051:
  756. result.sons[0] = newSymNode(errorSym(c, n))
  757. proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode
  758. proc resolveIndirectCall(c: PContext; n, nOrig: PNode;
  759. t: PType): TCandidate =
  760. initCandidate(c, result, t)
  761. matches(c, n, nOrig, result)
  762. if result.state != csMatch:
  763. # try to deref the first argument:
  764. if implicitDeref in c.features and canDeref(n):
  765. n.sons[1] = n.sons[1].tryDeref
  766. initCandidate(c, result, t)
  767. matches(c, n, nOrig, result)
  768. proc bracketedMacro(n: PNode): PSym =
  769. if n.len >= 1 and n[0].kind == nkSym:
  770. result = n[0].sym
  771. if result.kind notin {skMacro, skTemplate}:
  772. result = nil
  773. proc setGenericParams(c: PContext, n: PNode) =
  774. for i in 1 ..< n.len:
  775. n[i].typ = semTypeNode(c, n[i], nil)
  776. proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags): PNode =
  777. result = n
  778. let callee = result.sons[0].sym
  779. case callee.kind
  780. of skMacro: result = semMacroExpr(c, result, orig, callee, flags)
  781. of skTemplate: result = semTemplateExpr(c, result, callee, flags)
  782. else:
  783. semFinishOperands(c, result)
  784. activate(c, result)
  785. fixAbstractType(c, result)
  786. analyseIfAddressTakenInCall(c, result)
  787. if callee.magic != mNone:
  788. result = magicsAfterOverloadResolution(c, result, flags)
  789. when false:
  790. if result.typ != nil and
  791. not (result.typ.kind == tySequence and result.typ.sons[0].kind == tyEmpty):
  792. liftTypeBoundOps(c, result.typ, n.info)
  793. #result = patchResolvedTypeBoundOp(c, result)
  794. if c.matchedConcept == nil:
  795. result = evalAtCompileTime(c, result)
  796. proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
  797. result = nil
  798. checkMinSonsLen(n, 1, c.config)
  799. var prc = n.sons[0]
  800. if n.sons[0].kind == nkDotExpr:
  801. checkSonsLen(n.sons[0], 2, c.config)
  802. let n0 = semFieldAccess(c, n.sons[0])
  803. if n0.kind == nkDotCall:
  804. # it is a static call!
  805. result = n0
  806. result.kind = nkCall
  807. result.flags.incl nfExplicitCall
  808. for i in 1 ..< len(n): addSon(result, n.sons[i])
  809. return semExpr(c, result, flags)
  810. else:
  811. n.sons[0] = n0
  812. else:
  813. n.sons[0] = semExpr(c, n.sons[0], {efInCall})
  814. let t = n.sons[0].typ
  815. if t != nil and t.kind in {tyVar, tyLent}:
  816. n.sons[0] = newDeref(n.sons[0])
  817. elif n.sons[0].kind == nkBracketExpr:
  818. let s = bracketedMacro(n.sons[0])
  819. if s != nil:
  820. setGenericParams(c, n[0])
  821. return semDirectOp(c, n, flags)
  822. let nOrig = n.copyTree
  823. semOpAux(c, n)
  824. var t: PType = nil
  825. if n.sons[0].typ != nil:
  826. t = skipTypes(n.sons[0].typ, abstractInst+{tyOwned}-{tyTypeDesc, tyDistinct})
  827. if t != nil and t.kind == tyProc:
  828. # This is a proc variable, apply normal overload resolution
  829. let m = resolveIndirectCall(c, n, nOrig, t)
  830. if m.state != csMatch:
  831. if c.config.m.errorOutputs == {}:
  832. # speed up error generation:
  833. globalError(c.config, n.info, "type mismatch")
  834. return c.graph.emptyNode
  835. else:
  836. var hasErrorType = false
  837. var msg = "type mismatch: got <"
  838. for i in 1 ..< len(n):
  839. if i > 1: add(msg, ", ")
  840. let nt = n.sons[i].typ
  841. add(msg, typeToString(nt))
  842. if nt.kind == tyError:
  843. hasErrorType = true
  844. break
  845. if not hasErrorType:
  846. add(msg, ">\nbut expected one of: \n" &
  847. typeToString(n.sons[0].typ))
  848. localError(c.config, n.info, msg)
  849. return errorNode(c, n)
  850. result = nil
  851. else:
  852. result = m.call
  853. instGenericConvertersSons(c, result, m)
  854. elif t != nil and t.kind == tyTypeDesc:
  855. if n.len == 1: return semObjConstr(c, n, flags)
  856. return semConv(c, n)
  857. else:
  858. result = overloadedCallOpr(c, n)
  859. # Now that nkSym does not imply an iteration over the proc/iterator space,
  860. # the old ``prc`` (which is likely an nkIdent) has to be restored:
  861. if result == nil:
  862. # XXX: hmm, what kind of symbols will end up here?
  863. # do we really need to try the overload resolution?
  864. n.sons[0] = prc
  865. nOrig.sons[0] = prc
  866. n.flags.incl nfExprCall
  867. result = semOverloadedCallAnalyseEffects(c, n, nOrig, flags)
  868. if result == nil: return errorNode(c, n)
  869. elif result.kind notin nkCallKinds:
  870. # the semExpr() in overloadedCallOpr can even break this condition!
  871. # See bug #904 of how to trigger it:
  872. return result
  873. #result = afterCallActions(c, result, nOrig, flags)
  874. if result.sons[0].kind == nkSym:
  875. result = afterCallActions(c, result, nOrig, flags)
  876. else:
  877. fixAbstractType(c, result)
  878. analyseIfAddressTakenInCall(c, result)
  879. proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
  880. # this seems to be a hotspot in the compiler!
  881. let nOrig = n.copyTree
  882. #semLazyOpAux(c, n)
  883. result = semOverloadedCallAnalyseEffects(c, n, nOrig, flags)
  884. if result != nil: result = afterCallActions(c, result, nOrig, flags)
  885. else: result = errorNode(c, n)
  886. proc buildEchoStmt(c: PContext, n: PNode): PNode =
  887. # we MUST not check 'n' for semantics again here! But for now we give up:
  888. result = newNodeI(nkCall, n.info)
  889. var e = strTableGet(c.graph.systemModule.tab, getIdent(c.cache, "echo"))
  890. if e != nil:
  891. add(result, newSymNode(e))
  892. else:
  893. localError(c.config, n.info, "system needs: echo")
  894. add(result, errorNode(c, n))
  895. add(result, n)
  896. result = semExpr(c, result)
  897. proc semExprNoType(c: PContext, n: PNode): PNode =
  898. let isPush = hintExtendedContext in c.config.notes
  899. if isPush: pushInfoContext(c.config, n.info)
  900. result = semExpr(c, n, {efWantStmt})
  901. discardCheck(c, result, {})
  902. if isPush: popInfoContext(c.config)
  903. proc isTypeExpr(n: PNode): bool =
  904. case n.kind
  905. of nkType, nkTypeOfExpr: result = true
  906. of nkSym: result = n.sym.kind == skType
  907. else: result = false
  908. proc createSetType(c: PContext; baseType: PType): PType =
  909. assert baseType != nil
  910. result = newTypeS(tySet, c)
  911. rawAddSon(result, baseType)
  912. proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent,
  913. check: var PNode): PSym =
  914. # transform in a node that contains the runtime check for the
  915. # field, if it is in a case-part...
  916. result = nil
  917. case r.kind
  918. of nkRecList:
  919. for i in 0 ..< len(r):
  920. result = lookupInRecordAndBuildCheck(c, n, r.sons[i], field, check)
  921. if result != nil: return
  922. of nkRecCase:
  923. checkMinSonsLen(r, 2, c.config)
  924. if (r.sons[0].kind != nkSym): illFormedAst(r, c.config)
  925. result = lookupInRecordAndBuildCheck(c, n, r.sons[0], field, check)
  926. if result != nil: return
  927. let setType = createSetType(c, r.sons[0].typ)
  928. var s = newNodeIT(nkCurly, r.info, setType)
  929. for i in 1 ..< len(r):
  930. var it = r.sons[i]
  931. case it.kind
  932. of nkOfBranch:
  933. result = lookupInRecordAndBuildCheck(c, n, lastSon(it), field, check)
  934. if result == nil:
  935. for j in 0..len(it)-2: addSon(s, copyTree(it.sons[j]))
  936. else:
  937. if check == nil:
  938. check = newNodeI(nkCheckedFieldExpr, n.info)
  939. addSon(check, c.graph.emptyNode) # make space for access node
  940. s = newNodeIT(nkCurly, n.info, setType)
  941. for j in 0 .. len(it) - 2: addSon(s, copyTree(it.sons[j]))
  942. var inExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool))
  943. addSon(inExpr, newSymNode(c.graph.opContains, n.info))
  944. addSon(inExpr, s)
  945. addSon(inExpr, copyTree(r.sons[0]))
  946. addSon(check, inExpr)
  947. #addSon(check, semExpr(c, inExpr))
  948. return
  949. of nkElse:
  950. result = lookupInRecordAndBuildCheck(c, n, lastSon(it), field, check)
  951. if result != nil:
  952. if check == nil:
  953. check = newNodeI(nkCheckedFieldExpr, n.info)
  954. addSon(check, c.graph.emptyNode) # make space for access node
  955. var inExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool))
  956. addSon(inExpr, newSymNode(c.graph.opContains, n.info))
  957. addSon(inExpr, s)
  958. addSon(inExpr, copyTree(r.sons[0]))
  959. var notExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool))
  960. addSon(notExpr, newSymNode(c.graph.opNot, n.info))
  961. addSon(notExpr, inExpr)
  962. addSon(check, notExpr)
  963. return
  964. else: illFormedAst(it, c.config)
  965. of nkSym:
  966. if r.sym.name.id == field.id: result = r.sym
  967. else: illFormedAst(n, c.config)
  968. const
  969. tyTypeParamsHolders = {tyGenericInst, tyCompositeTypeClass}
  970. tyDotOpTransparent = {tyVar, tyLent, tyPtr, tyRef, tyOwned, tyAlias, tySink}
  971. proc readTypeParameter(c: PContext, typ: PType,
  972. paramName: PIdent, info: TLineInfo): PNode =
  973. # Note: This function will return emptyNode when attempting to read
  974. # a static type parameter that is not yet resolved (e.g. this may
  975. # happen in proc signatures such as `proc(x: T): array[T.sizeParam, U]`
  976. if typ.kind in {tyUserTypeClass, tyUserTypeClassInst}:
  977. for statement in typ.n:
  978. case statement.kind
  979. of nkTypeSection:
  980. for def in statement:
  981. if def[0].sym.name.id == paramName.id:
  982. # XXX: Instead of lifting the section type to a typedesc
  983. # here, we could try doing it earlier in semTypeSection.
  984. # This seems semantically correct and then we'll be able
  985. # to return the section symbol directly here
  986. let foundType = makeTypeDesc(c, def[2].typ)
  987. return newSymNode(copySym(def[0].sym).linkTo(foundType), info)
  988. of nkConstSection:
  989. for def in statement:
  990. if def[0].sym.name.id == paramName.id:
  991. return def[2]
  992. else:
  993. discard
  994. if typ.kind != tyUserTypeClass:
  995. let ty = if typ.kind == tyCompositeTypeClass: typ.sons[1].skipGenericAlias
  996. else: typ.skipGenericAlias
  997. let tbody = ty.sons[0]
  998. for s in 0 .. tbody.len-2:
  999. let tParam = tbody.sons[s]
  1000. if tParam.sym.name.id == paramName.id:
  1001. let rawTyp = ty.sons[s + 1]
  1002. if rawTyp.kind == tyStatic:
  1003. if rawTyp.n != nil:
  1004. return rawTyp.n
  1005. else:
  1006. return c.graph.emptyNode
  1007. else:
  1008. let foundTyp = makeTypeDesc(c, rawTyp)
  1009. return newSymNode(copySym(tParam.sym).linkTo(foundTyp), info)
  1010. return nil
  1011. proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
  1012. let s = getGenSym(c, sym)
  1013. case s.kind
  1014. of skConst:
  1015. markUsed(c, n.info, s)
  1016. onUse(n.info, s)
  1017. let typ = skipTypes(s.typ, abstractInst-{tyTypeDesc})
  1018. case typ.kind
  1019. of tyNil, tyChar, tyInt..tyInt64, tyFloat..tyFloat128,
  1020. tyTuple, tySet, tyUInt..tyUInt64:
  1021. if s.magic == mNone: result = inlineConst(c, n, s)
  1022. else: result = newSymNode(s, n.info)
  1023. of tyArray, tySequence:
  1024. # Consider::
  1025. # const x = []
  1026. # proc p(a: openarray[int])
  1027. # proc q(a: openarray[char])
  1028. # p(x)
  1029. # q(x)
  1030. #
  1031. # It is clear that ``[]`` means two totally different things. Thus, we
  1032. # copy `x`'s AST into each context, so that the type fixup phase can
  1033. # deal with two different ``[]``.
  1034. if s.ast.len == 0: result = inlineConst(c, n, s)
  1035. else: result = newSymNode(s, n.info)
  1036. of tyStatic:
  1037. if typ.n != nil:
  1038. result = typ.n
  1039. result.typ = typ.base
  1040. else:
  1041. result = newSymNode(s, n.info)
  1042. else:
  1043. result = newSymNode(s, n.info)
  1044. of skMacro:
  1045. if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0 or
  1046. (n.kind notin nkCallKinds and s.requiredParams > 0):
  1047. markUsed(c, n.info, s)
  1048. onUse(n.info, s)
  1049. result = symChoice(c, n, s, scClosed)
  1050. else:
  1051. result = semMacroExpr(c, n, n, s, flags)
  1052. of skTemplate:
  1053. if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0 or
  1054. (n.kind notin nkCallKinds and s.requiredParams > 0) or
  1055. sfCustomPragma in sym.flags:
  1056. let info = getCallLineInfo(n)
  1057. markUsed(c, info, s)
  1058. onUse(info, s)
  1059. result = symChoice(c, n, s, scClosed)
  1060. else:
  1061. result = semTemplateExpr(c, n, s, flags)
  1062. of skParam:
  1063. markUsed(c, n.info, s)
  1064. onUse(n.info, s)
  1065. if s.typ != nil and s.typ.kind == tyStatic and s.typ.n != nil:
  1066. # XXX see the hack in sigmatch.nim ...
  1067. return s.typ.n
  1068. elif sfGenSym in s.flags:
  1069. # the owner should have been set by now by addParamOrResult
  1070. internalAssert c.config, s.owner != nil
  1071. if c.p.wasForwarded:
  1072. # gensym'ed parameters that nevertheless have been forward declared
  1073. # need a special fixup:
  1074. let realParam = c.p.owner.typ.n[s.position+1]
  1075. internalAssert c.config, realParam.kind == nkSym and realParam.sym.kind == skParam
  1076. return newSymNode(c.p.owner.typ.n[s.position+1].sym, n.info)
  1077. elif c.p.owner.kind == skMacro:
  1078. # gensym'ed macro parameters need a similar hack (see bug #1944):
  1079. var u = searchInScopes(c, s.name)
  1080. internalAssert c.config, u != nil and u.kind == skParam and u.owner == s.owner
  1081. return newSymNode(u, n.info)
  1082. result = newSymNode(s, n.info)
  1083. of skVar, skLet, skResult, skForVar:
  1084. if s.magic == mNimvm:
  1085. localError(c.config, n.info, "illegal context for 'nimvm' magic")
  1086. markUsed(c, n.info, s)
  1087. onUse(n.info, s)
  1088. result = newSymNode(s, n.info)
  1089. # We cannot check for access to outer vars for example because it's still
  1090. # not sure the symbol really ends up being used:
  1091. # var len = 0 # but won't be called
  1092. # genericThatUsesLen(x) # marked as taking a closure?
  1093. of skGenericParam:
  1094. onUse(n.info, s)
  1095. if s.typ.kind == tyStatic:
  1096. result = newSymNode(s, n.info)
  1097. result.typ = s.typ
  1098. elif s.ast != nil:
  1099. result = semExpr(c, s.ast)
  1100. else:
  1101. n.typ = s.typ
  1102. return n
  1103. of skType:
  1104. markUsed(c, n.info, s)
  1105. onUse(n.info, s)
  1106. if s.typ.kind == tyStatic and s.typ.base.kind != tyNone and s.typ.n != nil:
  1107. return s.typ.n
  1108. result = newSymNode(s, n.info)
  1109. result.typ = makeTypeDesc(c, s.typ)
  1110. of skField:
  1111. var p = c.p
  1112. while p != nil and p.selfSym == nil:
  1113. p = p.next
  1114. if p != nil and p.selfSym != nil:
  1115. var ty = skipTypes(p.selfSym.typ, {tyGenericInst, tyVar, tyLent, tyPtr, tyRef,
  1116. tyAlias, tySink, tyOwned})
  1117. while tfBorrowDot in ty.flags: ty = ty.skipTypes({tyDistinct})
  1118. var check: PNode = nil
  1119. if ty.kind == tyObject:
  1120. while true:
  1121. check = nil
  1122. let f = lookupInRecordAndBuildCheck(c, n, ty.n, s.name, check)
  1123. if f != nil and fieldVisible(c, f):
  1124. # is the access to a public field or in the same module or in a friend?
  1125. doAssert f == s
  1126. markUsed(c, n.info, f)
  1127. onUse(n.info, f)
  1128. result = newNodeIT(nkDotExpr, n.info, f.typ)
  1129. result.add makeDeref(newSymNode(p.selfSym))
  1130. result.add newSymNode(f) # we now have the correct field
  1131. if check != nil:
  1132. check.sons[0] = result
  1133. check.typ = result.typ
  1134. result = check
  1135. return result
  1136. if ty.sons[0] == nil: break
  1137. ty = skipTypes(ty.sons[0], skipPtrs)
  1138. # old code, not sure if it's live code:
  1139. markUsed(c, n.info, s)
  1140. onUse(n.info, s)
  1141. result = newSymNode(s, n.info)
  1142. else:
  1143. let info = getCallLineInfo(n)
  1144. #if efInCall notin flags:
  1145. markUsed(c, info, s)
  1146. onUse(info, s)
  1147. result = newSymNode(s, info)
  1148. proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
  1149. ## returns nil if it's not a built-in field access
  1150. checkSonsLen(n, 2, c.config)
  1151. # tests/bind/tbindoverload.nim wants an early exit here, but seems to
  1152. # work without now. template/tsymchoicefield doesn't like an early exit
  1153. # here at all!
  1154. #if isSymChoice(n.sons[1]): return
  1155. when defined(nimsuggest):
  1156. if c.config.cmd == cmdIdeTools:
  1157. suggestExpr(c, n)
  1158. if exactEquals(c.config.m.trackPos, n[1].info): suggestExprNoCheck(c, n)
  1159. var s = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared, checkModule})
  1160. if s != nil:
  1161. if s.kind in OverloadableSyms:
  1162. result = symChoice(c, n, s, scClosed)
  1163. if result.kind == nkSym: result = semSym(c, n, s, flags)
  1164. else:
  1165. markUsed(c, n.sons[1].info, s)
  1166. result = semSym(c, n, s, flags)
  1167. onUse(n.sons[1].info, s)
  1168. return
  1169. n.sons[0] = semExprWithType(c, n.sons[0], flags+{efDetermineType})
  1170. #restoreOldStyleType(n.sons[0])
  1171. var i = considerQuotedIdent(c, n.sons[1], n)
  1172. var ty = n.sons[0].typ
  1173. var f: PSym = nil
  1174. result = nil
  1175. template tryReadingGenericParam(t: PType) =
  1176. case t.kind
  1177. of tyTypeParamsHolders:
  1178. result = readTypeParameter(c, t, i, n.info)
  1179. if result == c.graph.emptyNode:
  1180. result = n
  1181. n.typ = makeTypeFromExpr(c, n.copyTree)
  1182. return
  1183. of tyUserTypeClasses:
  1184. if t.isResolvedUserTypeClass:
  1185. return readTypeParameter(c, t, i, n.info)
  1186. else:
  1187. n.typ = makeTypeFromExpr(c, copyTree(n))
  1188. return n
  1189. of tyGenericParam, tyAnything:
  1190. n.typ = makeTypeFromExpr(c, copyTree(n))
  1191. return n
  1192. else:
  1193. discard
  1194. var argIsType = false
  1195. if ty.kind == tyTypeDesc:
  1196. if ty.base.kind == tyNone:
  1197. # This is a still unresolved typedesc parameter.
  1198. # If this is a regular proc, then all bets are off and we must return
  1199. # tyFromExpr, but when this happen in a macro this is not a built-in
  1200. # field access and we leave the compiler to compile a normal call:
  1201. if getCurrOwner(c).kind != skMacro:
  1202. n.typ = makeTypeFromExpr(c, n.copyTree)
  1203. return n
  1204. else:
  1205. return nil
  1206. else:
  1207. ty = ty.base
  1208. argIsType = true
  1209. else:
  1210. argIsType = isTypeExpr(n.sons[0])
  1211. if argIsType:
  1212. ty = ty.skipTypes(tyDotOpTransparent)
  1213. case ty.kind
  1214. of tyEnum:
  1215. # look up if the identifier belongs to the enum:
  1216. while ty != nil:
  1217. f = getSymFromList(ty.n, i)
  1218. if f != nil: break
  1219. ty = ty.sons[0] # enum inheritance
  1220. if f != nil:
  1221. result = newSymNode(f)
  1222. result.info = n.info
  1223. result.typ = ty
  1224. markUsed(c, n.info, f)
  1225. onUse(n.info, f)
  1226. return
  1227. of tyObject, tyTuple:
  1228. if ty.n != nil and ty.n.kind == nkRecList:
  1229. let field = lookupInRecord(ty.n, i)
  1230. if field != nil:
  1231. n.typ = makeTypeDesc(c, field.typ)
  1232. return n
  1233. else:
  1234. tryReadingGenericParam(ty)
  1235. return
  1236. # XXX: This is probably not relevant any more
  1237. # reset to prevent 'nil' bug: see "tests/reject/tenumitems.nim":
  1238. ty = n.sons[0].typ
  1239. return nil
  1240. if ty.kind in tyUserTypeClasses and ty.isResolvedUserTypeClass:
  1241. ty = ty.lastSon
  1242. ty = skipTypes(ty, {tyGenericInst, tyVar, tyLent, tyPtr, tyRef, tyOwned, tyAlias, tySink})
  1243. while tfBorrowDot in ty.flags: ty = ty.skipTypes({tyDistinct})
  1244. var check: PNode = nil
  1245. if ty.kind == tyObject:
  1246. while true:
  1247. check = nil
  1248. f = lookupInRecordAndBuildCheck(c, n, ty.n, i, check)
  1249. if f != nil: break
  1250. if ty.sons[0] == nil: break
  1251. ty = skipTypes(ty.sons[0], skipPtrs)
  1252. if f != nil:
  1253. let visibilityCheckNeeded =
  1254. if n[1].kind == nkSym and n[1].sym == f:
  1255. false # field lookup was done already, likely by hygienic template or bindSym
  1256. else: true
  1257. if not visibilityCheckNeeded or fieldVisible(c, f):
  1258. # is the access to a public field or in the same module or in a friend?
  1259. markUsed(c, n.sons[1].info, f)
  1260. onUse(n.sons[1].info, f)
  1261. n.sons[0] = makeDeref(n.sons[0])
  1262. n.sons[1] = newSymNode(f) # we now have the correct field
  1263. n.typ = f.typ
  1264. if check == nil:
  1265. result = n
  1266. else:
  1267. check.sons[0] = n
  1268. check.typ = n.typ
  1269. result = check
  1270. elif ty.kind == tyTuple and ty.n != nil:
  1271. f = getSymFromList(ty.n, i)
  1272. if f != nil:
  1273. markUsed(c, n.sons[1].info, f)
  1274. onUse(n.sons[1].info, f)
  1275. n.sons[0] = makeDeref(n.sons[0])
  1276. n.sons[1] = newSymNode(f)
  1277. n.typ = f.typ
  1278. result = n
  1279. # we didn't find any field, let's look for a generic param
  1280. if result == nil:
  1281. let t = n.sons[0].typ.skipTypes(tyDotOpTransparent)
  1282. tryReadingGenericParam(t)
  1283. proc dotTransformation(c: PContext, n: PNode): PNode =
  1284. if isSymChoice(n.sons[1]):
  1285. result = newNodeI(nkDotCall, n.info)
  1286. addSon(result, n.sons[1])
  1287. addSon(result, copyTree(n[0]))
  1288. else:
  1289. var i = considerQuotedIdent(c, n.sons[1], n)
  1290. result = newNodeI(nkDotCall, n.info)
  1291. result.flags.incl nfDotField
  1292. addSon(result, newIdentNode(i, n[1].info))
  1293. addSon(result, copyTree(n[0]))
  1294. proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
  1295. # this is difficult, because the '.' is used in many different contexts
  1296. # in Nim. We first allow types in the semantic checking.
  1297. result = builtinFieldAccess(c, n, flags)
  1298. if result == nil:
  1299. result = dotTransformation(c, n)
  1300. proc buildOverloadedSubscripts(n: PNode, ident: PIdent): PNode =
  1301. result = newNodeI(nkCall, n.info)
  1302. result.add(newIdentNode(ident, n.info))
  1303. for i in 0 .. n.len-1: result.add(n[i])
  1304. proc semDeref(c: PContext, n: PNode): PNode =
  1305. checkSonsLen(n, 1, c.config)
  1306. n.sons[0] = semExprWithType(c, n.sons[0])
  1307. result = n
  1308. var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyLent, tyAlias, tySink, tyOwned})
  1309. case t.kind
  1310. of tyRef, tyPtr: n.typ = t.lastSon
  1311. else: result = nil
  1312. #GlobalError(n.sons[0].info, errCircumNeedsPointer)
  1313. proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
  1314. ## returns nil if not a built-in subscript operator; also called for the
  1315. ## checking of assignments
  1316. if len(n) == 1:
  1317. let x = semDeref(c, n)
  1318. if x == nil: return nil
  1319. result = newNodeIT(nkDerefExpr, x.info, x.typ)
  1320. result.add(x[0])
  1321. return
  1322. checkMinSonsLen(n, 2, c.config)
  1323. # make sure we don't evaluate generic macros/templates
  1324. n.sons[0] = semExprWithType(c, n.sons[0],
  1325. {efNoEvaluateGeneric})
  1326. var arr = skipTypes(n.sons[0].typ, {tyGenericInst, tyUserTypeClassInst, tyOwned,
  1327. tyVar, tyLent, tyPtr, tyRef, tyAlias, tySink})
  1328. if arr.kind == tyStatic:
  1329. if arr.base.kind == tyNone:
  1330. result = n
  1331. result.typ = semStaticType(c, n[1], nil)
  1332. return
  1333. elif arr.n != nil:
  1334. return semSubscript(c, arr.n, flags)
  1335. else:
  1336. arr = arr.base
  1337. case arr.kind
  1338. of tyArray, tyOpenArray, tyVarargs, tySequence, tyString, tyCString,
  1339. tyUncheckedArray:
  1340. if n.len != 2: return nil
  1341. n.sons[0] = makeDeref(n.sons[0])
  1342. for i in 1 ..< len(n):
  1343. n.sons[i] = semExprWithType(c, n.sons[i],
  1344. flags*{efInTypeof, efDetermineType})
  1345. # Arrays index type is dictated by the range's type
  1346. if arr.kind == tyArray:
  1347. var indexType = arr.sons[0]
  1348. var arg = indexTypesMatch(c, indexType, n.sons[1].typ, n.sons[1])
  1349. if arg != nil:
  1350. n.sons[1] = arg
  1351. result = n
  1352. result.typ = elemType(arr)
  1353. # Other types have a bit more of leeway
  1354. elif n.sons[1].typ.skipTypes(abstractRange-{tyDistinct}).kind in
  1355. {tyInt..tyInt64, tyUInt..tyUInt64}:
  1356. result = n
  1357. result.typ = elemType(arr)
  1358. of tyTypeDesc:
  1359. # The result so far is a tyTypeDesc bound
  1360. # a tyGenericBody. The line below will substitute
  1361. # it with the instantiated type.
  1362. result = n
  1363. result.typ = makeTypeDesc(c, semTypeNode(c, n, nil))
  1364. #result = symNodeFromType(c, semTypeNode(c, n, nil), n.info)
  1365. of tyTuple:
  1366. if n.len != 2: return nil
  1367. n.sons[0] = makeDeref(n.sons[0])
  1368. # [] operator for tuples requires constant expression:
  1369. n.sons[1] = semConstExpr(c, n.sons[1])
  1370. if skipTypes(n.sons[1].typ, {tyGenericInst, tyRange, tyOrdinal, tyAlias, tySink}).kind in
  1371. {tyInt..tyInt64}:
  1372. let idx = getOrdValue(n.sons[1])
  1373. if idx >= 0 and idx < len(arr): n.typ = arr.sons[toInt(idx)]
  1374. else: localError(c.config, n.info, "invalid index value for tuple subscript")
  1375. result = n
  1376. else:
  1377. result = nil
  1378. else:
  1379. let s = if n.sons[0].kind == nkSym: n.sons[0].sym
  1380. elif n[0].kind in nkSymChoices: n.sons[0][0].sym
  1381. else: nil
  1382. if s != nil:
  1383. case s.kind
  1384. of skProc, skFunc, skMethod, skConverter, skIterator:
  1385. # type parameters: partial generic specialization
  1386. n.sons[0] = semSymGenericInstantiation(c, n.sons[0], s)
  1387. result = explicitGenericInstantiation(c, n, s)
  1388. if result == n:
  1389. n.sons[0] = copyTree(result)
  1390. else:
  1391. n.sons[0] = result
  1392. of skMacro, skTemplate:
  1393. if efInCall in flags:
  1394. # We are processing macroOrTmpl[] in macroOrTmpl[](...) call.
  1395. # Return as is, so it can be transformed into complete macro or
  1396. # template call in semIndirectOp caller.
  1397. result = n
  1398. else:
  1399. # We are processing macroOrTmpl[] not in call. Transform it to the
  1400. # macro or template call with generic arguments here.
  1401. n.kind = nkCall
  1402. case s.kind
  1403. of skMacro: result = semMacroExpr(c, n, n, s, flags)
  1404. of skTemplate: result = semTemplateExpr(c, n, s, flags)
  1405. else: discard
  1406. of skType:
  1407. result = symNodeFromType(c, semTypeNode(c, n, nil), n.info)
  1408. else:
  1409. discard
  1410. proc semArrayAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
  1411. result = semSubscript(c, n, flags)
  1412. if result == nil:
  1413. # overloaded [] operator:
  1414. result = semExpr(c, buildOverloadedSubscripts(n, getIdent(c.cache, "[]")))
  1415. proc propertyWriteAccess(c: PContext, n, nOrig, a: PNode): PNode =
  1416. var id = considerQuotedIdent(c, a[1], a)
  1417. var setterId = newIdentNode(getIdent(c.cache, id.s & '='), n.info)
  1418. # a[0] is already checked for semantics, that does ``builtinFieldAccess``
  1419. # this is ugly. XXX Semantic checking should use the ``nfSem`` flag for
  1420. # nodes?
  1421. let aOrig = nOrig[0]
  1422. result = newNode(nkCall, n.info, sons = @[setterId, a[0],
  1423. semExprWithType(c, n[1])])
  1424. result.flags.incl nfDotSetter
  1425. let orig = newNode(nkCall, n.info, sons = @[setterId, aOrig[0], nOrig[1]])
  1426. result = semOverloadedCallAnalyseEffects(c, result, orig, {})
  1427. if result != nil:
  1428. result = afterCallActions(c, result, nOrig, {})
  1429. #fixAbstractType(c, result)
  1430. #analyseIfAddressTakenInCall(c, result)
  1431. proc takeImplicitAddr(c: PContext, n: PNode; isLent: bool): PNode =
  1432. # See RFC #7373, calls returning 'var T' are assumed to
  1433. # return a view into the first argument (if there is one):
  1434. let root = exprRoot(n)
  1435. if root != nil and root.owner == c.p.owner:
  1436. if root.kind in {skLet, skVar, skTemp} and sfGlobal notin root.flags:
  1437. localError(c.config, n.info, "'$1' escapes its stack frame; context: '$2'; see $3/var_t_return.html" % [
  1438. root.name.s, renderTree(n, {renderNoComments}), explanationsBaseUrl])
  1439. elif root.kind == skParam and root.position != 0:
  1440. localError(c.config, n.info, "'$1' is not the first parameter; context: '$2'; see $3/var_t_return.html" % [
  1441. root.name.s, renderTree(n, {renderNoComments}), explanationsBaseUrl])
  1442. case n.kind
  1443. of nkHiddenAddr, nkAddr: return n
  1444. of nkHiddenDeref, nkDerefExpr: return n.sons[0]
  1445. of nkBracketExpr:
  1446. if len(n) == 1: return n.sons[0]
  1447. else: discard
  1448. let valid = isAssignable(c, n, isLent)
  1449. if valid != arLValue:
  1450. if valid == arLocalLValue:
  1451. localError(c.config, n.info, errXStackEscape % renderTree(n, {renderNoComments}))
  1452. else:
  1453. localError(c.config, n.info, errExprHasNoAddress)
  1454. result = newNodeIT(nkHiddenAddr, n.info, makePtrType(c, n.typ))
  1455. result.add(n)
  1456. proc asgnToResultVar(c: PContext, n, le, ri: PNode) {.inline.} =
  1457. if le.kind == nkHiddenDeref:
  1458. var x = le.sons[0]
  1459. if x.typ.kind in {tyVar, tyLent} and x.kind == nkSym and x.sym.kind == skResult:
  1460. n.sons[0] = x # 'result[]' --> 'result'
  1461. n.sons[1] = takeImplicitAddr(c, ri, x.typ.kind == tyLent)
  1462. x.typ.flags.incl tfVarIsPtr
  1463. #echo x.info, " setting it for this type ", typeToString(x.typ), " ", n.info
  1464. proc borrowCheck(c: PContext, n, le, ri: PNode) =
  1465. const
  1466. PathKinds0 = {nkDotExpr, nkCheckedFieldExpr,
  1467. nkBracketExpr, nkAddr, nkHiddenAddr,
  1468. nkObjDownConv, nkObjUpConv}
  1469. PathKinds1 = {nkHiddenStdConv, nkHiddenSubConv}
  1470. proc getRoot(n: PNode; followDeref: bool): PNode =
  1471. result = n
  1472. while true:
  1473. case result.kind
  1474. of nkDerefExpr, nkHiddenDeref:
  1475. if followDeref: result = result[0]
  1476. else: break
  1477. of PathKinds0:
  1478. result = result[0]
  1479. of PathKinds1:
  1480. result = result[1]
  1481. else: break
  1482. proc scopedLifetime(c: PContext; ri: PNode): bool {.inline.} =
  1483. let n = getRoot(ri, followDeref = false)
  1484. result = (ri.kind in nkCallKinds+{nkObjConstr}) or
  1485. (n.kind == nkSym and n.sym.owner == c.p.owner)
  1486. proc escapes(c: PContext; le: PNode): bool {.inline.} =
  1487. # param[].foo[] = self definitely escapes, we don't need to
  1488. # care about pointer derefs:
  1489. let n = getRoot(le, followDeref = true)
  1490. result = n.kind == nkSym and n.sym.kind == skParam
  1491. # Special typing rule: do not allow to pass 'owned T' to 'T' in 'result = x':
  1492. const absInst = abstractInst - {tyOwned}
  1493. if ri.typ != nil and ri.typ.skipTypes(absInst).kind == tyOwned and
  1494. le.typ != nil and le.typ.skipTypes(absInst).kind != tyOwned and
  1495. scopedLifetime(c, ri):
  1496. if le.kind == nkSym and le.sym.kind == skResult:
  1497. localError(c.config, n.info, "cannot return an owned pointer as an unowned pointer; " &
  1498. "use 'owned(" & typeToString(le.typ) & ")' as the return type")
  1499. elif escapes(c, le):
  1500. localError(c.config, n.info,
  1501. "assignment produces a dangling ref: the unowned ref lives longer than the owned ref")
  1502. template resultTypeIsInferrable(typ: PType): untyped =
  1503. typ.isMetaType and typ.kind != tyTypeDesc
  1504. proc goodLineInfo(arg: PNode): TLineInfo =
  1505. if arg.kind == nkStmtListExpr and arg.len > 0:
  1506. goodLineInfo(arg[^1])
  1507. else:
  1508. arg.info
  1509. proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
  1510. checkSonsLen(n, 2, c.config)
  1511. var a = n.sons[0]
  1512. case a.kind
  1513. of nkDotExpr:
  1514. # r.f = x
  1515. # --> `f=` (r, x)
  1516. let nOrig = n.copyTree
  1517. a = builtinFieldAccess(c, a, {efLValue})
  1518. if a == nil:
  1519. a = propertyWriteAccess(c, n, nOrig, n[0])
  1520. if a != nil: return a
  1521. # we try without the '='; proc that return 'var' or macros are still
  1522. # possible:
  1523. a = dotTransformation(c, n[0])
  1524. if a.kind == nkDotCall:
  1525. a.kind = nkCall
  1526. a = semExprWithType(c, a, {efLValue})
  1527. of nkBracketExpr:
  1528. # a[i] = x
  1529. # --> `[]=`(a, i, x)
  1530. a = semSubscript(c, a, {efLValue})
  1531. if a == nil:
  1532. result = buildOverloadedSubscripts(n.sons[0], getIdent(c.cache, "[]="))
  1533. add(result, n[1])
  1534. if mode == noOverloadedSubscript:
  1535. bracketNotFoundError(c, result)
  1536. return n
  1537. else:
  1538. result = semExprNoType(c, result)
  1539. return result
  1540. of nkCurlyExpr:
  1541. # a{i} = x --> `{}=`(a, i, x)
  1542. result = buildOverloadedSubscripts(n.sons[0], getIdent(c.cache, "{}="))
  1543. add(result, n[1])
  1544. return semExprNoType(c, result)
  1545. of nkPar, nkTupleConstr:
  1546. if a.len >= 2:
  1547. # unfortunately we need to rewrite ``(x, y) = foo()`` already here so
  1548. # that overloading of the assignment operator still works. Usually we
  1549. # prefer to do these rewritings in transf.nim:
  1550. return semStmt(c, lowerTupleUnpackingForAsgn(c.graph, n, c.p.owner), {})
  1551. else:
  1552. a = semExprWithType(c, a, {efLValue})
  1553. else:
  1554. a = semExprWithType(c, a, {efLValue})
  1555. n.sons[0] = a
  1556. # a = b # both are vars, means: a[] = b[]
  1557. # a = b # b no 'var T' means: a = addr(b)
  1558. var le = a.typ
  1559. if le == nil:
  1560. localError(c.config, a.info, "expression has no type")
  1561. elif (skipTypes(le, {tyGenericInst, tyAlias, tySink}).kind != tyVar and
  1562. isAssignable(c, a) == arNone) or
  1563. skipTypes(le, abstractVar).kind in {tyOpenArray, tyVarargs}:
  1564. # Direct assignment to a discriminant is allowed!
  1565. localError(c.config, a.info, errXCannotBeAssignedTo %
  1566. renderTree(a, {renderNoComments}))
  1567. else:
  1568. let
  1569. lhs = n.sons[0]
  1570. lhsIsResult = lhs.kind == nkSym and lhs.sym.kind == skResult
  1571. var
  1572. rhs = semExprWithType(c, n.sons[1],
  1573. if lhsIsResult: {efAllowDestructor} else: {})
  1574. if lhsIsResult:
  1575. n.typ = c.enforceVoidContext
  1576. if c.p.owner.kind != skMacro and resultTypeIsInferrable(lhs.sym.typ):
  1577. var rhsTyp = rhs.typ
  1578. if rhsTyp.kind in tyUserTypeClasses and rhsTyp.isResolvedUserTypeClass:
  1579. rhsTyp = rhsTyp.lastSon
  1580. if cmpTypes(c, lhs.typ, rhsTyp) in {isGeneric, isEqual}:
  1581. internalAssert c.config, c.p.resultSym != nil
  1582. # Make sure the type is valid for the result variable
  1583. typeAllowedCheck(c.config, n.info, rhsTyp, skResult)
  1584. lhs.typ = rhsTyp
  1585. c.p.resultSym.typ = rhsTyp
  1586. c.p.owner.typ.sons[0] = rhsTyp
  1587. else:
  1588. typeMismatch(c.config, n.info, lhs.typ, rhsTyp)
  1589. borrowCheck(c, n, lhs, rhs)
  1590. n.sons[1] = fitNode(c, le, rhs, goodLineInfo(n[1]))
  1591. when false: liftTypeBoundOps(c, lhs.typ, lhs.info)
  1592. fixAbstractType(c, n)
  1593. asgnToResultVar(c, n, n.sons[0], n.sons[1])
  1594. result = n
  1595. proc semReturn(c: PContext, n: PNode): PNode =
  1596. result = n
  1597. checkSonsLen(n, 1, c.config)
  1598. if c.p.owner.kind in {skConverter, skMethod, skProc, skFunc, skMacro} or
  1599. isClosureIterator(c.p.owner):
  1600. if n.sons[0].kind != nkEmpty:
  1601. # transform ``return expr`` to ``result = expr; return``
  1602. if c.p.resultSym != nil:
  1603. var a = newNodeI(nkAsgn, n.sons[0].info)
  1604. addSon(a, newSymNode(c.p.resultSym))
  1605. addSon(a, n.sons[0])
  1606. n.sons[0] = semAsgn(c, a)
  1607. # optimize away ``result = result``:
  1608. if n[0][1].kind == nkSym and n[0][1].sym == c.p.resultSym:
  1609. n.sons[0] = c.graph.emptyNode
  1610. else:
  1611. localError(c.config, n.info, errNoReturnTypeDeclared)
  1612. else:
  1613. localError(c.config, n.info, "'return' not allowed here")
  1614. proc semProcBody(c: PContext, n: PNode): PNode =
  1615. openScope(c)
  1616. result = semExpr(c, n)
  1617. if c.p.resultSym != nil and not isEmptyType(result.typ):
  1618. if result.kind == nkNilLit:
  1619. # or ImplicitlyDiscardable(result):
  1620. # new semantic: 'result = x' triggers the void context
  1621. result.typ = nil
  1622. elif result.kind == nkStmtListExpr and result.typ.kind == tyNil:
  1623. # to keep backwards compatibility bodies like:
  1624. # nil
  1625. # # comment
  1626. # are not expressions:
  1627. fixNilType(c, result)
  1628. else:
  1629. var a = newNodeI(nkAsgn, n.info, 2)
  1630. a.sons[0] = newSymNode(c.p.resultSym)
  1631. a.sons[1] = result
  1632. result = semAsgn(c, a)
  1633. else:
  1634. discardCheck(c, result, {})
  1635. if c.p.owner.kind notin {skMacro, skTemplate} and
  1636. c.p.resultSym != nil and c.p.resultSym.typ.isMetaType:
  1637. if isEmptyType(result.typ):
  1638. # we inferred a 'void' return type:
  1639. c.p.resultSym.typ = errorType(c)
  1640. c.p.owner.typ.sons[0] = nil
  1641. else:
  1642. localError(c.config, c.p.resultSym.info, errCannotInferReturnType %
  1643. c.p.owner.name.s)
  1644. if isInlineIterator(c.p.owner) and c.p.owner.typ.sons[0] != nil and
  1645. c.p.owner.typ.sons[0].kind == tyUntyped:
  1646. localError(c.config, c.p.owner.info, errCannotInferReturnType %
  1647. c.p.owner.name.s)
  1648. closeScope(c)
  1649. proc semYieldVarResult(c: PContext, n: PNode, restype: PType) =
  1650. var t = skipTypes(restype, {tyGenericInst, tyAlias, tySink})
  1651. case t.kind
  1652. of tyVar, tyLent:
  1653. t.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
  1654. if n.sons[0].kind in {nkHiddenStdConv, nkHiddenSubConv}:
  1655. n.sons[0] = n.sons[0].sons[1]
  1656. n.sons[0] = takeImplicitAddr(c, n.sons[0], t.kind == tyLent)
  1657. of tyTuple:
  1658. for i in 0..<t.len:
  1659. let e = skipTypes(t.sons[i], {tyGenericInst, tyAlias, tySink})
  1660. if e.kind in {tyVar, tyLent}:
  1661. e.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
  1662. if n.sons[0].kind in {nkPar, nkTupleConstr}:
  1663. n.sons[0].sons[i] = takeImplicitAddr(c, n.sons[0].sons[i], e.kind == tyLent)
  1664. elif n.sons[0].kind in {nkHiddenStdConv, nkHiddenSubConv} and
  1665. n.sons[0].sons[1].kind in {nkPar, nkTupleConstr}:
  1666. var a = n.sons[0].sons[1]
  1667. a.sons[i] = takeImplicitAddr(c, a.sons[i], e.kind == tyLent)
  1668. else:
  1669. localError(c.config, n.sons[0].info, errXExpected, "tuple constructor")
  1670. else: discard
  1671. proc semYield(c: PContext, n: PNode): PNode =
  1672. result = n
  1673. checkSonsLen(n, 1, c.config)
  1674. if c.p.owner == nil or c.p.owner.kind != skIterator:
  1675. localError(c.config, n.info, errYieldNotAllowedHere)
  1676. elif n.sons[0].kind != nkEmpty:
  1677. n.sons[0] = semExprWithType(c, n.sons[0]) # check for type compatibility:
  1678. var iterType = c.p.owner.typ
  1679. let restype = iterType.sons[0]
  1680. if restype != nil:
  1681. if restype.kind != tyUntyped:
  1682. n.sons[0] = fitNode(c, restype, n.sons[0], n.info)
  1683. if n.sons[0].typ == nil: internalError(c.config, n.info, "semYield")
  1684. if resultTypeIsInferrable(restype):
  1685. let inferred = n.sons[0].typ
  1686. iterType.sons[0] = inferred
  1687. if c.p.resultSym != nil:
  1688. c.p.resultSym.typ = inferred
  1689. semYieldVarResult(c, n, restype)
  1690. else:
  1691. localError(c.config, n.info, errCannotReturnExpr)
  1692. elif c.p.owner.typ.sons[0] != nil:
  1693. localError(c.config, n.info, errGenerated, "yield statement must yield a value")
  1694. proc lookUpForDefined(c: PContext, i: PIdent, onlyCurrentScope: bool): PSym =
  1695. if onlyCurrentScope:
  1696. result = localSearchInScope(c, i)
  1697. else:
  1698. result = searchInScopes(c, i) # no need for stub loading
  1699. proc lookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym =
  1700. case n.kind
  1701. of nkIdent:
  1702. result = lookUpForDefined(c, n.ident, onlyCurrentScope)
  1703. of nkDotExpr:
  1704. result = nil
  1705. if onlyCurrentScope: return
  1706. checkSonsLen(n, 2, c.config)
  1707. var m = lookUpForDefined(c, n.sons[0], onlyCurrentScope)
  1708. if m != nil and m.kind == skModule:
  1709. let ident = considerQuotedIdent(c, n[1], n)
  1710. if m == c.module:
  1711. result = strTableGet(c.topLevelScope.symbols, ident)
  1712. else:
  1713. result = strTableGet(m.tab, ident)
  1714. of nkAccQuoted:
  1715. result = lookUpForDefined(c, considerQuotedIdent(c, n), onlyCurrentScope)
  1716. of nkSym:
  1717. result = n.sym
  1718. of nkOpenSymChoice, nkClosedSymChoice:
  1719. result = n.sons[0].sym
  1720. else:
  1721. localError(c.config, n.info, "identifier expected, but got: " & renderTree(n))
  1722. result = nil
  1723. proc semDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PNode =
  1724. checkSonsLen(n, 2, c.config)
  1725. # we replace this node by a 'true' or 'false' node:
  1726. result = newIntNode(nkIntLit, 0)
  1727. if not onlyCurrentScope and considerQuotedIdent(c, n[0], n).s == "defined":
  1728. let d = considerQuotedIdent(c, n[1], n)
  1729. result.intVal = ord isDefined(c.config, d.s)
  1730. elif lookUpForDefined(c, n.sons[1], onlyCurrentScope) != nil:
  1731. result.intVal = 1
  1732. result.info = n.info
  1733. result.typ = getSysType(c.graph, n.info, tyBool)
  1734. proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym =
  1735. ## The argument to the proc should be nkCall(...) or similar
  1736. ## Returns the macro/template symbol
  1737. if isCallExpr(n):
  1738. var expandedSym = qualifiedLookUp(c, n[0], {checkUndeclared})
  1739. if expandedSym == nil:
  1740. errorUndeclaredIdentifier(c, n.info, n[0].renderTree)
  1741. return errorSym(c, n[0])
  1742. if expandedSym.kind notin {skMacro, skTemplate}:
  1743. localError(c.config, n.info, "'$1' is not a macro or template" % expandedSym.name.s)
  1744. return errorSym(c, n[0])
  1745. result = expandedSym
  1746. else:
  1747. localError(c.config, n.info, "'$1' is not a macro or template" % n.renderTree)
  1748. result = errorSym(c, n)
  1749. proc expectString(c: PContext, n: PNode): string =
  1750. var n = semConstExpr(c, n)
  1751. if n.kind in nkStrKinds:
  1752. return n.strVal
  1753. else:
  1754. localError(c.config, n.info, errStringLiteralExpected)
  1755. proc newAnonSym(c: PContext; kind: TSymKind, info: TLineInfo): PSym =
  1756. result = newSym(kind, c.cache.idAnon, getCurrOwner(c), info)
  1757. proc semExpandToAst(c: PContext, n: PNode): PNode =
  1758. let macroCall = n[1]
  1759. when false:
  1760. let expandedSym = expectMacroOrTemplateCall(c, macroCall)
  1761. if expandedSym.kind == skError: return n
  1762. macroCall.sons[0] = newSymNode(expandedSym, macroCall.info)
  1763. markUsed(c, n.info, expandedSym)
  1764. onUse(n.info, expandedSym)
  1765. if isCallExpr(macroCall):
  1766. for i in 1 ..< macroCall.len:
  1767. #if macroCall.sons[0].typ.sons[i].kind != tyUntyped:
  1768. macroCall.sons[i] = semExprWithType(c, macroCall[i], {})
  1769. # performing overloading resolution here produces too serious regressions:
  1770. let headSymbol = macroCall[0]
  1771. var cands = 0
  1772. var cand: PSym = nil
  1773. var o: TOverloadIter
  1774. var symx = initOverloadIter(o, c, headSymbol)
  1775. while symx != nil:
  1776. if symx.kind in {skTemplate, skMacro} and symx.typ.len == macroCall.len:
  1777. cand = symx
  1778. inc cands
  1779. symx = nextOverloadIter(o, c, headSymbol)
  1780. if cands == 0:
  1781. localError(c.config, n.info, "expected a template that takes " & $(macroCall.len-1) & " arguments")
  1782. elif cands >= 2:
  1783. localError(c.config, n.info, "ambiguous symbol in 'getAst' context: " & $macroCall)
  1784. else:
  1785. let info = macroCall.sons[0].info
  1786. macroCall.sons[0] = newSymNode(cand, info)
  1787. markUsed(c, info, cand)
  1788. onUse(info, cand)
  1789. # we just perform overloading resolution here:
  1790. #n.sons[1] = semOverloadedCall(c, macroCall, macroCall, {skTemplate, skMacro})
  1791. else:
  1792. localError(c.config, n.info, "getAst takes a call, but got " & n.renderTree)
  1793. # Preserve the magic symbol in order to be handled in evals.nim
  1794. internalAssert c.config, n.sons[0].sym.magic == mExpandToAst
  1795. #n.typ = getSysSym("NimNode").typ # expandedSym.getReturnType
  1796. if n.kind == nkStmtList and n.len == 1: result = n[0]
  1797. else: result = n
  1798. result.typ = sysTypeFromName(c.graph, n.info, "NimNode")
  1799. proc semExpandToAst(c: PContext, n: PNode, magicSym: PSym,
  1800. flags: TExprFlags = {}): PNode =
  1801. if len(n) == 2:
  1802. n.sons[0] = newSymNode(magicSym, n.info)
  1803. result = semExpandToAst(c, n)
  1804. else:
  1805. result = semDirectOp(c, n, flags)
  1806. proc processQuotations(c: PContext; n: var PNode, op: string,
  1807. quotes: var seq[PNode],
  1808. ids: var seq[PNode]) =
  1809. template returnQuote(q) =
  1810. quotes.add q
  1811. n = newIdentNode(getIdent(c.cache, $quotes.len), n.info)
  1812. ids.add n
  1813. return
  1814. if n.kind == nkPrefix:
  1815. checkSonsLen(n, 2, c.config)
  1816. if n[0].kind == nkIdent:
  1817. var examinedOp = n[0].ident.s
  1818. if examinedOp == op:
  1819. returnQuote n[1]
  1820. elif examinedOp.startsWith(op):
  1821. n.sons[0] = newIdentNode(getIdent(c.cache, examinedOp.substr(op.len)), n.info)
  1822. elif n.kind == nkAccQuoted and op == "``":
  1823. returnQuote n[0]
  1824. elif n.kind == nkIdent:
  1825. if n.ident.s == "result":
  1826. n = ids[0]
  1827. for i in 0 ..< n.safeLen:
  1828. processQuotations(c, n.sons[i], op, quotes, ids)
  1829. proc semQuoteAst(c: PContext, n: PNode): PNode =
  1830. if n.len != 2 and n.len != 3:
  1831. localError(c.config, n.info, "'quote' expects 1 or 2 arguments")
  1832. return n
  1833. # We transform the do block into a template with a param for
  1834. # each interpolation. We'll pass this template to getAst.
  1835. var
  1836. quotedBlock = n[^1]
  1837. op = if n.len == 3: expectString(c, n[1]) else: "``"
  1838. quotes = newSeq[PNode](2)
  1839. # the quotes will be added to a nkCall statement
  1840. # leave some room for the callee symbol and the result symbol
  1841. ids = newSeq[PNode](1)
  1842. # this will store the generated param names
  1843. # leave some room for the result symbol
  1844. if quotedBlock.kind != nkStmtList:
  1845. localError(c.config, n.info, errXExpected, "block")
  1846. # This adds a default first field to pass the result symbol
  1847. ids[0] = newAnonSym(c, skParam, n.info).newSymNode
  1848. processQuotations(c, quotedBlock, op, quotes, ids)
  1849. var dummyTemplate = newProcNode(
  1850. nkTemplateDef, quotedBlock.info, body = quotedBlock,
  1851. params = c.graph.emptyNode,
  1852. name = newAnonSym(c, skTemplate, n.info).newSymNode,
  1853. pattern = c.graph.emptyNode, genericParams = c.graph.emptyNode,
  1854. pragmas = c.graph.emptyNode, exceptions = c.graph.emptyNode)
  1855. if ids.len > 0:
  1856. dummyTemplate.sons[paramsPos] = newNodeI(nkFormalParams, n.info)
  1857. dummyTemplate[paramsPos].add getSysSym(c.graph, n.info, "untyped").newSymNode # return type
  1858. ids.add getSysSym(c.graph, n.info, "untyped").newSymNode # params type
  1859. ids.add c.graph.emptyNode # no default value
  1860. dummyTemplate[paramsPos].add newNode(nkIdentDefs, n.info, ids)
  1861. var tmpl = semTemplateDef(c, dummyTemplate)
  1862. quotes[0] = tmpl[namePos]
  1863. # This adds a call to newIdentNode("result") as the first argument to the template call
  1864. let identNodeSym = getCompilerProc(c.graph, "newIdentNode")
  1865. # so that new Nim compilers can compile old macros.nim versions, we check for 'nil'
  1866. # here and provide the old fallback solution:
  1867. let identNode = if identNodeSym == nil:
  1868. newIdentNode(getIdent(c.cache, "newIdentNode"), n.info)
  1869. else:
  1870. identNodeSym.newSymNode
  1871. quotes[1] = newNode(nkCall, n.info, @[identNode, newStrNode(nkStrLit, "result")])
  1872. result = newNode(nkCall, n.info, @[
  1873. createMagic(c.graph, "getAst", mExpandToAst).newSymNode,
  1874. newNode(nkCall, n.info, quotes)])
  1875. result = semExpandToAst(c, result)
  1876. proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
  1877. # watch out, hacks ahead:
  1878. when defined(nimsuggest):
  1879. # Remove the error hook so nimsuggest doesn't report errors there
  1880. let tempHook = c.graph.config.structuredErrorHook
  1881. c.graph.config.structuredErrorHook = nil
  1882. let oldErrorCount = c.config.errorCounter
  1883. let oldErrorMax = c.config.errorMax
  1884. let oldCompilesId = c.compilesContextId
  1885. # if this is a nested 'when compiles', do not increase the ID so that
  1886. # generic instantiations can still be cached for this level.
  1887. if c.compilesContextId == 0:
  1888. inc c.compilesContextIdGenerator
  1889. c.compilesContextId = c.compilesContextIdGenerator
  1890. # do not halt after first error:
  1891. c.config.errorMax = high(int)
  1892. # open a scope for temporary symbol inclusions:
  1893. let oldScope = c.currentScope
  1894. openScope(c)
  1895. let oldOwnerLen = len(c.graph.owners)
  1896. let oldGenerics = c.generics
  1897. let oldErrorOutputs = c.config.m.errorOutputs
  1898. if efExplain notin flags: c.config.m.errorOutputs = {}
  1899. let oldContextLen = msgs.getInfoContextLen(c.config)
  1900. let oldInGenericContext = c.inGenericContext
  1901. let oldInUnrolledContext = c.inUnrolledContext
  1902. let oldInGenericInst = c.inGenericInst
  1903. let oldInStaticContext = c.inStaticContext
  1904. let oldProcCon = c.p
  1905. c.generics = @[]
  1906. var err: string
  1907. try:
  1908. result = semExpr(c, n, flags)
  1909. if c.config.errorCounter != oldErrorCount: result = nil
  1910. except ERecoverableError:
  1911. discard
  1912. # undo symbol table changes (as far as it's possible):
  1913. c.compilesContextId = oldCompilesId
  1914. c.generics = oldGenerics
  1915. c.inGenericContext = oldInGenericContext
  1916. c.inUnrolledContext = oldInUnrolledContext
  1917. c.inGenericInst = oldInGenericInst
  1918. c.inStaticContext = oldInStaticContext
  1919. c.p = oldProcCon
  1920. msgs.setInfoContextLen(c.config, oldContextLen)
  1921. setLen(c.graph.owners, oldOwnerLen)
  1922. c.currentScope = oldScope
  1923. c.config.m.errorOutputs = oldErrorOutputs
  1924. c.config.errorCounter = oldErrorCount
  1925. c.config.errorMax = oldErrorMax
  1926. when defined(nimsuggest):
  1927. # Restore the error hook
  1928. c.graph.config.structuredErrorHook = tempHook
  1929. proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode =
  1930. # we replace this node by a 'true' or 'false' node:
  1931. if len(n) != 2: return semDirectOp(c, n, flags)
  1932. result = newIntNode(nkIntLit, ord(tryExpr(c, n[1], flags) != nil))
  1933. result.info = n.info
  1934. result.typ = getSysType(c.graph, n.info, tyBool)
  1935. proc semShallowCopy(c: PContext, n: PNode, flags: TExprFlags): PNode =
  1936. if len(n) == 3:
  1937. # XXX ugh this is really a hack: shallowCopy() can be overloaded only
  1938. # with procs that take not 2 parameters:
  1939. result = newNodeI(nkFastAsgn, n.info)
  1940. result.add(n[1])
  1941. result.add(n[2])
  1942. result = semAsgn(c, result)
  1943. else:
  1944. result = semDirectOp(c, n, flags)
  1945. proc createFlowVar(c: PContext; t: PType; info: TLineInfo): PType =
  1946. result = newType(tyGenericInvocation, c.module)
  1947. addSonSkipIntLit(result, magicsys.getCompilerProc(c.graph, "FlowVar").typ)
  1948. addSonSkipIntLit(result, t)
  1949. result = instGenericContainer(c, info, result, allowMetaTypes = false)
  1950. proc instantiateCreateFlowVarCall(c: PContext; t: PType;
  1951. info: TLineInfo): PSym =
  1952. let sym = magicsys.getCompilerProc(c.graph, "nimCreateFlowVar")
  1953. if sym == nil:
  1954. localError(c.config, info, "system needs: nimCreateFlowVar")
  1955. var bindings: TIdTable
  1956. initIdTable(bindings)
  1957. bindings.idTablePut(sym.ast[genericParamsPos].sons[0].typ, t)
  1958. result = c.semGenerateInstance(c, sym, bindings, info)
  1959. # since it's an instantiation, we unmark it as a compilerproc. Otherwise
  1960. # codegen would fail:
  1961. if sfCompilerProc in result.flags:
  1962. result.flags = result.flags - {sfCompilerProc, sfExportc, sfImportc}
  1963. result.loc.r = nil
  1964. proc setMs(n: PNode, s: PSym): PNode =
  1965. result = n
  1966. n.sons[0] = newSymNode(s)
  1967. n.sons[0].info = n.info
  1968. proc semSizeof(c: PContext, n: PNode): PNode =
  1969. if len(n) != 2:
  1970. localError(c.config, n.info, errXExpectsTypeOrValue % "sizeof")
  1971. else:
  1972. n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType})
  1973. #restoreOldStyleType(n.sons[1])
  1974. n.typ = getSysType(c.graph, n.info, tyInt)
  1975. result = foldSizeOf(c.config, n, n)
  1976. proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
  1977. # this is a hotspot in the compiler!
  1978. result = n
  1979. case s.magic # magics that need special treatment
  1980. of mAddr:
  1981. markUsed(c, n.info, s)
  1982. checkSonsLen(n, 2, c.config)
  1983. result[0] = newSymNode(s, n[0].info)
  1984. result[1] = semAddrArg(c, n.sons[1], s.name.s == "unsafeAddr")
  1985. result.typ = makePtrType(c, result[1].typ)
  1986. of mTypeOf:
  1987. markUsed(c, n.info, s)
  1988. result = semTypeOf(c, n)
  1989. of mDefined:
  1990. markUsed(c, n.info, s)
  1991. result = semDefined(c, setMs(n, s), false)
  1992. of mDefinedInScope:
  1993. markUsed(c, n.info, s)
  1994. result = semDefined(c, setMs(n, s), true)
  1995. of mCompiles:
  1996. markUsed(c, n.info, s)
  1997. result = semCompiles(c, setMs(n, s), flags)
  1998. of mIs:
  1999. markUsed(c, n.info, s)
  2000. result = semIs(c, setMs(n, s), flags)
  2001. of mShallowCopy:
  2002. markUsed(c, n.info, s)
  2003. result = semShallowCopy(c, n, flags)
  2004. of mExpandToAst:
  2005. markUsed(c, n.info, s)
  2006. result = semExpandToAst(c, n, s, flags)
  2007. of mQuoteAst:
  2008. markUsed(c, n.info, s)
  2009. result = semQuoteAst(c, n)
  2010. of mAstToStr:
  2011. markUsed(c, n.info, s)
  2012. checkSonsLen(n, 2, c.config)
  2013. result = newStrNodeT(renderTree(n[1], {renderNoComments}), n, c.graph)
  2014. result.typ = getSysType(c.graph, n.info, tyString)
  2015. of mParallel:
  2016. markUsed(c, n.info, s)
  2017. if parallel notin c.features:
  2018. localError(c.config, n.info, "use the {.experimental.} pragma to enable 'parallel'")
  2019. result = setMs(n, s)
  2020. var x = n.lastSon
  2021. if x.kind == nkDo: x = x.sons[bodyPos]
  2022. inc c.inParallelStmt
  2023. result.sons[1] = semStmt(c, x, {})
  2024. dec c.inParallelStmt
  2025. of mSpawn:
  2026. markUsed(c, n.info, s)
  2027. when defined(leanCompiler):
  2028. localError(c.config, n.info, "compiler was built without 'spawn' support")
  2029. result = n
  2030. else:
  2031. result = setMs(n, s)
  2032. for i in 1 ..< n.len:
  2033. result.sons[i] = semExpr(c, n.sons[i])
  2034. let typ = result[^1].typ
  2035. if not typ.isEmptyType:
  2036. if spawnResult(typ, c.inParallelStmt > 0) == srFlowVar:
  2037. result.typ = createFlowVar(c, typ, n.info)
  2038. else:
  2039. result.typ = typ
  2040. result.add instantiateCreateFlowVarCall(c, typ, n.info).newSymNode
  2041. else:
  2042. result.add c.graph.emptyNode
  2043. of mProcCall:
  2044. markUsed(c, n.info, s)
  2045. result = setMs(n, s)
  2046. result.sons[1] = semExpr(c, n.sons[1])
  2047. result.typ = n[1].typ
  2048. of mPlugin:
  2049. markUsed(c, n.info, s)
  2050. # semDirectOp with conditional 'afterCallActions':
  2051. let nOrig = n.copyTree
  2052. #semLazyOpAux(c, n)
  2053. result = semOverloadedCallAnalyseEffects(c, n, nOrig, flags)
  2054. if result == nil:
  2055. result = errorNode(c, n)
  2056. else:
  2057. let callee = result.sons[0].sym
  2058. if callee.magic == mNone:
  2059. semFinishOperands(c, result)
  2060. activate(c, result)
  2061. fixAbstractType(c, result)
  2062. analyseIfAddressTakenInCall(c, result)
  2063. if callee.magic != mNone:
  2064. result = magicsAfterOverloadResolution(c, result, flags)
  2065. of mRunnableExamples:
  2066. markUsed(c, n.info, s)
  2067. if c.config.cmd == cmdDoc and n.len >= 2 and n.lastSon.kind == nkStmtList:
  2068. when false:
  2069. # some of this dead code was moved to `prepareExamples`
  2070. if sfMainModule in c.module.flags:
  2071. let inp = toFullPath(c.config, c.module.info)
  2072. if c.runnableExamples == nil:
  2073. c.runnableExamples = newTree(nkStmtList,
  2074. newTree(nkImportStmt, newStrNode(nkStrLit, expandFilename(inp))))
  2075. let imports = newTree(nkStmtList)
  2076. var savedLastSon = copyTree n.lastSon
  2077. extractImports(savedLastSon, imports)
  2078. for imp in imports: c.runnableExamples.add imp
  2079. c.runnableExamples.add newTree(nkBlockStmt, c.graph.emptyNode, copyTree savedLastSon)
  2080. result = setMs(n, s)
  2081. else:
  2082. result = c.graph.emptyNode
  2083. of mSizeOf:
  2084. markUsed(c, n.info, s)
  2085. result = semSizeof(c, setMs(n, s))
  2086. else:
  2087. result = semDirectOp(c, n, flags)
  2088. proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
  2089. # If semCheck is set to false, ``when`` will return the verbatim AST of
  2090. # the correct branch. Otherwise the AST will be passed through semStmt.
  2091. result = nil
  2092. template setResult(e: untyped) =
  2093. if semCheck: result = semExpr(c, e) # do not open a new scope!
  2094. else: result = e
  2095. # Check if the node is "when nimvm"
  2096. # when nimvm:
  2097. # ...
  2098. # else:
  2099. # ...
  2100. var whenNimvm = false
  2101. var typ = commonTypeBegin
  2102. if n.sons.len == 2 and n.sons[0].kind == nkElifBranch and
  2103. n.sons[1].kind == nkElse:
  2104. let exprNode = n.sons[0].sons[0]
  2105. if exprNode.kind == nkIdent:
  2106. whenNimvm = lookUp(c, exprNode).magic == mNimvm
  2107. elif exprNode.kind == nkSym:
  2108. whenNimvm = exprNode.sym.magic == mNimvm
  2109. if whenNimvm: n.flags.incl nfLL
  2110. for i in 0 ..< len(n):
  2111. var it = n.sons[i]
  2112. case it.kind
  2113. of nkElifBranch, nkElifExpr:
  2114. checkSonsLen(it, 2, c.config)
  2115. if whenNimvm:
  2116. if semCheck:
  2117. it.sons[1] = semExpr(c, it.sons[1])
  2118. typ = commonType(typ, it.sons[1].typ)
  2119. result = n # when nimvm is not elimited until codegen
  2120. else:
  2121. let e = forceBool(c, semConstExpr(c, it.sons[0]))
  2122. if e.kind != nkIntLit:
  2123. # can happen for cascading errors, assume false
  2124. # InternalError(n.info, "semWhen")
  2125. discard
  2126. elif e.intVal != 0 and result == nil:
  2127. setResult(it.sons[1])
  2128. of nkElse, nkElseExpr:
  2129. checkSonsLen(it, 1, c.config)
  2130. if result == nil or whenNimvm:
  2131. if semCheck:
  2132. it.sons[0] = semExpr(c, it.sons[0])
  2133. typ = commonType(typ, it.sons[0].typ)
  2134. if result == nil:
  2135. result = it.sons[0]
  2136. else: illFormedAst(n, c.config)
  2137. if result == nil:
  2138. result = newNodeI(nkEmpty, n.info)
  2139. if whenNimvm: result.typ = typ
  2140. # The ``when`` statement implements the mechanism for platform dependent
  2141. # code. Thus we try to ensure here consistent ID allocation after the
  2142. # ``when`` statement.
  2143. idSynchronizationPoint(200)
  2144. proc semSetConstr(c: PContext, n: PNode): PNode =
  2145. result = newNodeI(nkCurly, n.info)
  2146. result.typ = newTypeS(tySet, c)
  2147. if len(n) == 0:
  2148. rawAddSon(result.typ, newTypeS(tyEmpty, c))
  2149. else:
  2150. # only semantic checking for all elements, later type checking:
  2151. var typ: PType = nil
  2152. for i in 0 ..< len(n):
  2153. if isRange(n.sons[i]):
  2154. checkSonsLen(n.sons[i], 3, c.config)
  2155. n.sons[i].sons[1] = semExprWithType(c, n.sons[i].sons[1])
  2156. n.sons[i].sons[2] = semExprWithType(c, n.sons[i].sons[2])
  2157. if typ == nil:
  2158. typ = skipTypes(n.sons[i].sons[1].typ,
  2159. {tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink})
  2160. n.sons[i].typ = n.sons[i].sons[2].typ # range node needs type too
  2161. elif n.sons[i].kind == nkRange:
  2162. # already semchecked
  2163. if typ == nil:
  2164. typ = skipTypes(n.sons[i].sons[0].typ,
  2165. {tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink})
  2166. else:
  2167. n.sons[i] = semExprWithType(c, n.sons[i])
  2168. if typ == nil:
  2169. typ = skipTypes(n.sons[i].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink})
  2170. if not isOrdinalType(typ, allowEnumWithHoles=true):
  2171. localError(c.config, n.info, errOrdinalTypeExpected)
  2172. typ = makeRangeType(c, 0, MaxSetElements-1, n.info)
  2173. elif lengthOrd(c.config, typ) > MaxSetElements:
  2174. typ = makeRangeType(c, 0, MaxSetElements-1, n.info)
  2175. addSonSkipIntLit(result.typ, typ)
  2176. for i in 0 ..< len(n):
  2177. var m: PNode
  2178. let info = n.sons[i].info
  2179. if isRange(n.sons[i]):
  2180. m = newNodeI(nkRange, info)
  2181. addSon(m, fitNode(c, typ, n.sons[i].sons[1], info))
  2182. addSon(m, fitNode(c, typ, n.sons[i].sons[2], info))
  2183. elif n.sons[i].kind == nkRange: m = n.sons[i] # already semchecked
  2184. else:
  2185. m = fitNode(c, typ, n.sons[i], info)
  2186. addSon(result, m)
  2187. proc semTableConstr(c: PContext, n: PNode): PNode =
  2188. # we simply transform ``{key: value, key2, key3: value}`` to
  2189. # ``[(key, value), (key2, value2), (key3, value2)]``
  2190. result = newNodeI(nkBracket, n.info)
  2191. var lastKey = 0
  2192. for i in 0..n.len-1:
  2193. var x = n.sons[i]
  2194. if x.kind == nkExprColonExpr and len(x) == 2:
  2195. for j in lastKey ..< i:
  2196. var pair = newNodeI(nkTupleConstr, x.info)
  2197. pair.add(n.sons[j])
  2198. pair.add(x[1])
  2199. result.add(pair)
  2200. var pair = newNodeI(nkTupleConstr, x.info)
  2201. pair.add(x[0])
  2202. pair.add(x[1])
  2203. result.add(pair)
  2204. lastKey = i+1
  2205. if lastKey != n.len: illFormedAst(n, c.config)
  2206. result = semExpr(c, result)
  2207. type
  2208. TParKind = enum
  2209. paNone, paSingle, paTupleFields, paTuplePositions
  2210. proc checkPar(c: PContext; n: PNode): TParKind =
  2211. var length = len(n)
  2212. if length == 0:
  2213. result = paTuplePositions # ()
  2214. elif length == 1:
  2215. if n.sons[0].kind == nkExprColonExpr: result = paTupleFields
  2216. elif n.kind == nkTupleConstr: result = paTuplePositions
  2217. else: result = paSingle # (expr)
  2218. else:
  2219. if n.sons[0].kind == nkExprColonExpr: result = paTupleFields
  2220. else: result = paTuplePositions
  2221. for i in 0 ..< length:
  2222. if result == paTupleFields:
  2223. if (n.sons[i].kind != nkExprColonExpr) or
  2224. n.sons[i].sons[0].kind notin {nkSym, nkIdent, nkAccQuoted}:
  2225. localError(c.config, n.sons[i].info, errNamedExprExpected)
  2226. return paNone
  2227. else:
  2228. if n.sons[i].kind == nkExprColonExpr:
  2229. localError(c.config, n.sons[i].info, errNamedExprNotAllowed)
  2230. return paNone
  2231. proc semTupleFieldsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
  2232. result = newNodeI(nkTupleConstr, n.info)
  2233. var typ = newTypeS(tyTuple, c)
  2234. typ.n = newNodeI(nkRecList, n.info) # nkIdentDefs
  2235. var ids = initIntSet()
  2236. for i in 0 ..< len(n):
  2237. if n[i].kind != nkExprColonExpr:
  2238. illFormedAst(n.sons[i], c.config)
  2239. let id = considerQuotedIdent(c, n[i][0])
  2240. if containsOrIncl(ids, id.id):
  2241. localError(c.config, n.sons[i].info, errFieldInitTwice % id.s)
  2242. n.sons[i].sons[1] = semExprWithType(c, n.sons[i].sons[1],
  2243. flags*{efAllowDestructor})
  2244. if n.sons[i].sons[1].typ.kind == tyTypeDesc:
  2245. localError(c.config, n.sons[i].sons[1].info, "typedesc not allowed as tuple field.")
  2246. n.sons[i].sons[1].typ = errorType(c)
  2247. var f = newSymS(skField, n.sons[i].sons[0], c)
  2248. f.typ = skipIntLit(n.sons[i].sons[1].typ)
  2249. f.position = i
  2250. rawAddSon(typ, f.typ)
  2251. addSon(typ.n, newSymNode(f))
  2252. n.sons[i].sons[0] = newSymNode(f)
  2253. addSon(result, n.sons[i])
  2254. result.typ = typ
  2255. proc semTuplePositionsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
  2256. result = n # we don't modify n, but compute the type:
  2257. result.kind = nkTupleConstr
  2258. var typ = newTypeS(tyTuple, c) # leave typ.n nil!
  2259. for i in 0 ..< len(n):
  2260. n.sons[i] = semExprWithType(c, n.sons[i], flags*{efAllowDestructor})
  2261. addSonSkipIntLit(typ, n.sons[i].typ)
  2262. result.typ = typ
  2263. include semobjconstr
  2264. proc semBlock(c: PContext, n: PNode; flags: TExprFlags): PNode =
  2265. result = n
  2266. inc(c.p.nestedBlockCounter)
  2267. checkSonsLen(n, 2, c.config)
  2268. openScope(c) # BUGFIX: label is in the scope of block!
  2269. if n.sons[0].kind != nkEmpty:
  2270. var labl = newSymG(skLabel, n.sons[0], c)
  2271. if sfGenSym notin labl.flags:
  2272. addDecl(c, labl)
  2273. elif labl.owner == nil:
  2274. labl.owner = c.p.owner
  2275. n.sons[0] = newSymNode(labl, n.sons[0].info)
  2276. suggestSym(c.config, n.sons[0].info, labl, c.graph.usageSym)
  2277. styleCheckDef(c.config, labl)
  2278. onDef(n[0].info, labl)
  2279. n.sons[1] = semExpr(c, n.sons[1], flags)
  2280. n.typ = n.sons[1].typ
  2281. if isEmptyType(n.typ): n.kind = nkBlockStmt
  2282. else: n.kind = nkBlockExpr
  2283. closeScope(c)
  2284. dec(c.p.nestedBlockCounter)
  2285. proc semExportExcept(c: PContext, n: PNode): PNode =
  2286. let moduleName = semExpr(c, n[0])
  2287. if moduleName.kind != nkSym or moduleName.sym.kind != skModule:
  2288. localError(c.config, n.info, "The export/except syntax expects a module name")
  2289. return n
  2290. let exceptSet = readExceptSet(c, n)
  2291. let exported = moduleName.sym
  2292. result = newNodeI(nkExportStmt, n.info)
  2293. strTableAdd(c.module.tab, exported)
  2294. var i: TTabIter
  2295. var s = initTabIter(i, exported.tab)
  2296. while s != nil:
  2297. if s.kind in ExportableSymKinds+{skModule} and
  2298. s.name.id notin exceptSet and sfError notin s.flags:
  2299. strTableAdd(c.module.tab, s)
  2300. result.add newSymNode(s, n.info)
  2301. s = nextIter(i, exported.tab)
  2302. markUsed(c, n.info, exported)
  2303. proc semExport(c: PContext, n: PNode): PNode =
  2304. result = newNodeI(nkExportStmt, n.info)
  2305. for i in 0..<n.len:
  2306. let a = n.sons[i]
  2307. var o: TOverloadIter
  2308. var s = initOverloadIter(o, c, a)
  2309. if s == nil:
  2310. localError(c.config, a.info, errGenerated, "cannot export: " & renderTree(a))
  2311. elif s.kind == skModule:
  2312. # forward everything from that module:
  2313. strTableAdd(c.module.tab, s)
  2314. var ti: TTabIter
  2315. var it = initTabIter(ti, s.tab)
  2316. while it != nil:
  2317. if it.kind in ExportableSymKinds+{skModule}:
  2318. strTableAdd(c.module.tab, it)
  2319. result.add newSymNode(it, a.info)
  2320. it = nextIter(ti, s.tab)
  2321. markUsed(c, n.info, s)
  2322. else:
  2323. while s != nil:
  2324. if s.kind == skEnumField:
  2325. localError(c.config, a.info, errGenerated, "cannot export: " & renderTree(a) &
  2326. "; enum field cannot be exported individually")
  2327. if s.kind in ExportableSymKinds+{skModule} and sfError notin s.flags:
  2328. result.add(newSymNode(s, a.info))
  2329. strTableAdd(c.module.tab, s)
  2330. markUsed(c, n.info, s)
  2331. s = nextOverloadIter(o, c, a)
  2332. proc semTupleConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
  2333. var tupexp = semTuplePositionsConstr(c, n, flags)
  2334. var isTupleType: bool
  2335. if tupexp.len > 0: # don't interpret () as type
  2336. isTupleType = tupexp[0].typ.kind == tyTypeDesc
  2337. # check if either everything or nothing is tyTypeDesc
  2338. for i in 1 ..< tupexp.len:
  2339. if isTupleType != (tupexp[i].typ.kind == tyTypeDesc):
  2340. localError(c.config, tupexp[i].info, "Mixing types and values in tuples is not allowed.")
  2341. return(errorNode(c,n))
  2342. if isTupleType: # expressions as ``(int, string)`` are reinterpret as type expressions
  2343. result = n
  2344. var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc})
  2345. result.typ = makeTypeDesc(c, typ)
  2346. else:
  2347. result = tupexp
  2348. proc shouldBeBracketExpr(n: PNode): bool =
  2349. assert n.kind in nkCallKinds
  2350. let a = n.sons[0]
  2351. if a.kind in nkCallKinds:
  2352. let b = a[0]
  2353. if b.kind in nkSymChoices:
  2354. for i in 0..<b.len:
  2355. if b[i].kind == nkSym and b[i].sym.magic == mArrGet:
  2356. let be = newNodeI(nkBracketExpr, n.info)
  2357. for i in 1..<a.len: be.add(a[i])
  2358. n.sons[0] = be
  2359. return true
  2360. proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
  2361. result = n
  2362. if c.config.cmd == cmdIdeTools: suggestExpr(c, n)
  2363. if nfSem in n.flags: return
  2364. case n.kind
  2365. of nkIdent, nkAccQuoted:
  2366. let checks = if efNoEvaluateGeneric in flags:
  2367. {checkUndeclared, checkPureEnumFields}
  2368. elif efInCall in flags:
  2369. {checkUndeclared, checkModule, checkPureEnumFields}
  2370. else:
  2371. {checkUndeclared, checkModule, checkAmbiguity, checkPureEnumFields}
  2372. var s = qualifiedLookUp(c, n, checks)
  2373. if c.matchedConcept == nil: semCaptureSym(s, c.p.owner)
  2374. if s.kind in {skProc, skFunc, skMethod, skConverter, skIterator}:
  2375. #performProcvarCheck(c, n, s)
  2376. result = symChoice(c, n, s, scClosed)
  2377. if result.kind == nkSym:
  2378. markIndirect(c, result.sym)
  2379. # if isGenericRoutine(result.sym):
  2380. # localError(c.config, n.info, errInstantiateXExplicitly, s.name.s)
  2381. # "procs literals" are 'owned'
  2382. if optOwnedRefs in c.config.globalOptions:
  2383. result.typ = makeVarType(c, result.typ, tyOwned)
  2384. else:
  2385. result = semSym(c, n, s, flags)
  2386. of nkSym:
  2387. # because of the changed symbol binding, this does not mean that we
  2388. # don't have to check the symbol for semantics here again!
  2389. result = semSym(c, n, n.sym, flags)
  2390. of nkEmpty, nkNone, nkCommentStmt, nkType:
  2391. discard
  2392. of nkNilLit:
  2393. if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyNil)
  2394. of nkIntLit:
  2395. if result.typ == nil: setIntLitType(c.graph, result)
  2396. of nkInt8Lit:
  2397. if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyInt8)
  2398. of nkInt16Lit:
  2399. if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyInt16)
  2400. of nkInt32Lit:
  2401. if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyInt32)
  2402. of nkInt64Lit:
  2403. if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyInt64)
  2404. of nkUIntLit:
  2405. if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyUInt)
  2406. of nkUInt8Lit:
  2407. if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyUInt8)
  2408. of nkUInt16Lit:
  2409. if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyUInt16)
  2410. of nkUInt32Lit:
  2411. if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyUInt32)
  2412. of nkUInt64Lit:
  2413. if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyUInt64)
  2414. #of nkFloatLit:
  2415. # if result.typ == nil: result.typ = getFloatLitType(result)
  2416. of nkFloat32Lit:
  2417. if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyFloat32)
  2418. of nkFloat64Lit, nkFloatLit:
  2419. if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyFloat64)
  2420. of nkFloat128Lit:
  2421. if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyFloat128)
  2422. of nkStrLit..nkTripleStrLit:
  2423. if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyString)
  2424. of nkCharLit:
  2425. if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyChar)
  2426. of nkDotExpr:
  2427. result = semFieldAccess(c, n, flags)
  2428. if result.kind == nkDotCall:
  2429. result.kind = nkCall
  2430. result = semExpr(c, result, flags)
  2431. of nkBind:
  2432. message(c.config, n.info, warnDeprecated, "bind is deprecated")
  2433. result = semExpr(c, n.sons[0], flags)
  2434. of nkTypeOfExpr, nkTupleTy, nkTupleClassTy, nkRefTy..nkEnumTy, nkStaticTy:
  2435. if c.matchedConcept != nil and n.len == 1:
  2436. let modifier = n.modifierTypeKindOfNode
  2437. if modifier != tyNone:
  2438. var baseType = semExpr(c, n[0]).typ.skipTypes({tyTypeDesc})
  2439. result.typ = c.makeTypeDesc(c.newTypeWithSons(modifier, @[baseType]))
  2440. return
  2441. var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc})
  2442. result.typ = makeTypeDesc(c, typ)
  2443. of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit:
  2444. # check if it is an expression macro:
  2445. checkMinSonsLen(n, 1, c.config)
  2446. #when defined(nimsuggest):
  2447. # if gIdeCmd == ideCon and c.config.m.trackPos == n.info: suggestExprNoCheck(c, n)
  2448. let mode = if nfDotField in n.flags: {} else: {checkUndeclared}
  2449. var s = qualifiedLookUp(c, n.sons[0], mode)
  2450. if s != nil:
  2451. #if c.config.cmd == cmdPretty and n.sons[0].kind == nkDotExpr:
  2452. # pretty.checkUse(n.sons[0].sons[1].info, s)
  2453. case s.kind
  2454. of skMacro, skTemplate:
  2455. result = semDirectOp(c, n, flags)
  2456. of skType:
  2457. # XXX think about this more (``set`` procs)
  2458. let ambig = contains(c.ambiguousSymbols, s.id)
  2459. if not (n[0].kind in {nkClosedSymChoice, nkOpenSymChoice, nkIdent} and ambig) and n.len == 2:
  2460. result = semConv(c, n)
  2461. elif ambig and n.len == 1:
  2462. errorUseQualifier(c, n.info, s)
  2463. elif n.len == 1:
  2464. result = semObjConstr(c, n, flags)
  2465. elif s.magic == mNone: result = semDirectOp(c, n, flags)
  2466. else: result = semMagic(c, n, s, flags)
  2467. of skProc, skFunc, skMethod, skConverter, skIterator:
  2468. if s.magic == mNone: result = semDirectOp(c, n, flags)
  2469. else: result = semMagic(c, n, s, flags)
  2470. else:
  2471. #liMessage(n.info, warnUser, renderTree(n));
  2472. result = semIndirectOp(c, n, flags)
  2473. elif (n[0].kind == nkBracketExpr or shouldBeBracketExpr(n)) and
  2474. isSymChoice(n[0][0]):
  2475. # indirectOp can deal with explicit instantiations; the fixes
  2476. # the 'newSeq[T](x)' bug
  2477. setGenericParams(c, n.sons[0])
  2478. result = semDirectOp(c, n, flags)
  2479. elif isSymChoice(n.sons[0]) or nfDotField in n.flags:
  2480. result = semDirectOp(c, n, flags)
  2481. else:
  2482. result = semIndirectOp(c, n, flags)
  2483. of nkWhen:
  2484. if efWantStmt in flags:
  2485. result = semWhen(c, n, true)
  2486. else:
  2487. result = semWhen(c, n, false)
  2488. if result == n:
  2489. # This is a "when nimvm" stmt.
  2490. result = semWhen(c, n, true)
  2491. else:
  2492. result = semExpr(c, result, flags)
  2493. of nkBracketExpr:
  2494. checkMinSonsLen(n, 1, c.config)
  2495. result = semArrayAccess(c, n, flags)
  2496. of nkCurlyExpr:
  2497. result = semExpr(c, buildOverloadedSubscripts(n, getIdent(c.cache, "{}")), flags)
  2498. of nkPragmaExpr:
  2499. var
  2500. pragma = n[1]
  2501. pragmaName = considerQuotedIdent(c, pragma[0])
  2502. flags = flags
  2503. finalNodeFlags: TNodeFlags = {}
  2504. case whichKeyword(pragmaName)
  2505. of wExplain:
  2506. flags.incl efExplain
  2507. of wExecuteOnReload:
  2508. finalNodeFlags.incl nfExecuteOnReload
  2509. else:
  2510. # what other pragmas are allowed for expressions? `likely`, `unlikely`
  2511. invalidPragma(c, n)
  2512. result = semExpr(c, n[0], flags)
  2513. result.flags.incl finalNodeFlags
  2514. of nkPar, nkTupleConstr:
  2515. case checkPar(c, n)
  2516. of paNone: result = errorNode(c, n)
  2517. of paTuplePositions: result = semTupleConstr(c, n, flags)
  2518. of paTupleFields: result = semTupleFieldsConstr(c, n, flags)
  2519. of paSingle: result = semExpr(c, n.sons[0], flags)
  2520. of nkCurly: result = semSetConstr(c, n)
  2521. of nkBracket: result = semArrayConstr(c, n, flags)
  2522. of nkObjConstr: result = semObjConstr(c, n, flags)
  2523. of nkLambdaKinds: result = semLambda(c, n, flags)
  2524. of nkDerefExpr: result = semDeref(c, n)
  2525. of nkAddr:
  2526. result = n
  2527. checkSonsLen(n, 1, c.config)
  2528. result[0] = semAddrArg(c, n.sons[0])
  2529. result.typ = makePtrType(c, result[0].typ)
  2530. of nkHiddenAddr, nkHiddenDeref:
  2531. checkSonsLen(n, 1, c.config)
  2532. n.sons[0] = semExpr(c, n.sons[0], flags)
  2533. of nkCast: result = semCast(c, n)
  2534. of nkIfExpr, nkIfStmt: result = semIf(c, n, flags)
  2535. of nkHiddenStdConv, nkHiddenSubConv, nkConv, nkHiddenCallConv:
  2536. checkSonsLen(n, 2, c.config)
  2537. considerGenSyms(c, n)
  2538. of nkStringToCString, nkCStringToString, nkObjDownConv, nkObjUpConv:
  2539. checkSonsLen(n, 1, c.config)
  2540. considerGenSyms(c, n)
  2541. of nkChckRangeF, nkChckRange64, nkChckRange:
  2542. checkSonsLen(n, 3, c.config)
  2543. considerGenSyms(c, n)
  2544. of nkCheckedFieldExpr:
  2545. checkMinSonsLen(n, 2, c.config)
  2546. considerGenSyms(c, n)
  2547. of nkTableConstr:
  2548. result = semTableConstr(c, n)
  2549. of nkClosedSymChoice, nkOpenSymChoice:
  2550. # handling of sym choices is context dependent
  2551. # the node is left intact for now
  2552. discard
  2553. of nkStaticExpr: result = semStaticExpr(c, n[0])
  2554. of nkAsgn: result = semAsgn(c, n)
  2555. of nkBlockStmt, nkBlockExpr: result = semBlock(c, n, flags)
  2556. of nkStmtList, nkStmtListExpr: result = semStmtList(c, n, flags)
  2557. of nkRaiseStmt: result = semRaise(c, n)
  2558. of nkVarSection: result = semVarOrLet(c, n, skVar)
  2559. of nkLetSection: result = semVarOrLet(c, n, skLet)
  2560. of nkConstSection: result = semConst(c, n)
  2561. of nkTypeSection: result = semTypeSection(c, n)
  2562. of nkDiscardStmt: result = semDiscard(c, n)
  2563. of nkWhileStmt: result = semWhile(c, n, flags)
  2564. of nkTryStmt, nkHiddenTryStmt: result = semTry(c, n, flags)
  2565. of nkBreakStmt, nkContinueStmt: result = semBreakOrContinue(c, n)
  2566. of nkForStmt, nkParForStmt: result = semFor(c, n, flags)
  2567. of nkCaseStmt: result = semCase(c, n, flags)
  2568. of nkReturnStmt: result = semReturn(c, n)
  2569. of nkUsingStmt: result = semUsing(c, n)
  2570. of nkAsmStmt: result = semAsm(c, n)
  2571. of nkYieldStmt: result = semYield(c, n)
  2572. of nkPragma: pragma(c, c.p.owner, n, stmtPragmas, true)
  2573. of nkIteratorDef: result = semIterator(c, n)
  2574. of nkProcDef: result = semProc(c, n)
  2575. of nkFuncDef: result = semFunc(c, n)
  2576. of nkMethodDef: result = semMethod(c, n)
  2577. of nkConverterDef: result = semConverterDef(c, n)
  2578. of nkMacroDef: result = semMacroDef(c, n)
  2579. of nkTemplateDef: result = semTemplateDef(c, n)
  2580. of nkImportStmt:
  2581. # this particular way allows 'import' in a 'compiles' context so that
  2582. # template canImport(x): bool =
  2583. # compiles:
  2584. # import x
  2585. #
  2586. # works:
  2587. if c.currentScope.depthLevel > 2 + c.compilesContextId:
  2588. localError(c.config, n.info, errXOnlyAtModuleScope % "import")
  2589. result = evalImport(c, n)
  2590. of nkImportExceptStmt:
  2591. if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "import")
  2592. result = evalImportExcept(c, n)
  2593. of nkFromStmt:
  2594. if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "from")
  2595. result = evalFrom(c, n)
  2596. of nkIncludeStmt:
  2597. #if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "include")
  2598. result = evalInclude(c, n)
  2599. of nkExportStmt:
  2600. if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "export")
  2601. result = semExport(c, n)
  2602. of nkExportExceptStmt:
  2603. if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "export")
  2604. result = semExportExcept(c, n)
  2605. of nkPragmaBlock:
  2606. result = semPragmaBlock(c, n)
  2607. of nkStaticStmt:
  2608. result = semStaticStmt(c, n)
  2609. of nkDefer:
  2610. if c.currentScope == c.topLevelScope:
  2611. localError(c.config, n.info, "defer statement not supported at top level")
  2612. n.sons[0] = semExpr(c, n.sons[0])
  2613. if not n.sons[0].typ.isEmptyType and not implicitlyDiscardable(n.sons[0]):
  2614. localError(c.config, n.info, "'defer' takes a 'void' expression")
  2615. #localError(c.config, n.info, errGenerated, "'defer' not allowed in this context")
  2616. of nkGotoState, nkState:
  2617. if n.len != 1 and n.len != 2: illFormedAst(n, c.config)
  2618. for i in 0 ..< n.len:
  2619. n.sons[i] = semExpr(c, n.sons[i])
  2620. of nkComesFrom: discard "ignore the comes from information for now"
  2621. else:
  2622. localError(c.config, n.info, "invalid expression: " &
  2623. renderTree(n, {renderNoComments}))
  2624. if result != nil: incl(result.flags, nfSem)