semtypes.nim 81 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2012 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. # this module does the semantic checking of type declarations
  10. # included from sem.nim
  11. import math
  12. const
  13. errStringOrIdentNodeExpected = "string or ident node expected"
  14. errStringLiteralExpected = "string literal expected"
  15. errIntLiteralExpected = "integer literal expected"
  16. errWrongNumberOfVariables = "wrong number of variables"
  17. errInvalidOrderInEnumX = "invalid order in enum '$1'"
  18. errOrdinalTypeExpected = "ordinal type expected"
  19. errSetTooBig = "set is too large"
  20. errBaseTypeMustBeOrdinal = "base type of a set must be an ordinal"
  21. errInheritanceOnlyWithNonFinalObjects = "inheritance only works with non-final objects"
  22. errXExpectsOneTypeParam = "'$1' expects one type parameter"
  23. errArrayExpectsTwoTypeParams = "array expects two type parameters"
  24. errInvalidVisibilityX = "invalid visibility: '$1'"
  25. errInitHereNotAllowed = "initialization not allowed here"
  26. errXCannotBeAssignedTo = "'$1' cannot be assigned to"
  27. errIteratorNotAllowed = "iterators can only be defined at the module's top level"
  28. errXNeedsReturnType = "$1 needs a return type"
  29. errNoReturnTypeDeclared = "no return type declared"
  30. errTIsNotAConcreteType = "'$1' is not a concrete type"
  31. errTypeExpected = "type expected"
  32. errXOnlyAtModuleScope = "'$1' is only allowed at top level"
  33. errDuplicateCaseLabel = "duplicate case label"
  34. errMacroBodyDependsOnGenericTypes = "the macro body cannot be compiled, " &
  35. "because the parameter '$1' has a generic type"
  36. errIllegalRecursionInTypeX = "illegal recursion in type '$1'"
  37. errNoGenericParamsAllowedForX = "no generic parameters allowed for $1"
  38. errInOutFlagNotExtern = "the '$1' modifier can be used only with imported types"
  39. proc newOrPrevType(kind: TTypeKind, prev: PType, c: PContext): PType =
  40. if prev == nil:
  41. result = newTypeS(kind, c)
  42. else:
  43. result = prev
  44. if result.kind == tyForward: result.kind = kind
  45. #if kind == tyError: result.flags.incl tfCheckedForDestructor
  46. proc newConstraint(c: PContext, k: TTypeKind): PType =
  47. result = newTypeS(tyBuiltInTypeClass, c)
  48. result.flags.incl tfCheckedForDestructor
  49. result.addSonSkipIntLit(newTypeS(k, c))
  50. proc semEnum(c: PContext, n: PNode, prev: PType): PType =
  51. if n.len == 0: return newConstraint(c, tyEnum)
  52. elif n.len == 1:
  53. # don't create an empty tyEnum; fixes #3052
  54. return errorType(c)
  55. var
  56. counter, x: BiggestInt
  57. e: PSym
  58. base: PType
  59. counter = 0
  60. base = nil
  61. result = newOrPrevType(tyEnum, prev, c)
  62. result.n = newNodeI(nkEnumTy, n.info)
  63. checkMinSonsLen(n, 1, c.config)
  64. if n[0].kind != nkEmpty:
  65. base = semTypeNode(c, n[0][0], nil)
  66. if base.kind != tyEnum:
  67. localError(c.config, n[0].info, "inheritance only works with an enum")
  68. counter = toInt64(lastOrd(c.config, base)) + 1
  69. rawAddSon(result, base)
  70. let isPure = result.sym != nil and sfPure in result.sym.flags
  71. var symbols: TStrTable
  72. if isPure: initStrTable(symbols)
  73. var hasNull = false
  74. for i in 1..<n.len:
  75. if n[i].kind == nkEmpty: continue
  76. case n[i].kind
  77. of nkEnumFieldDef:
  78. if n[i][0].kind == nkPragmaExpr:
  79. e = newSymS(skEnumField, n[i][0][0], c)
  80. pragma(c, e, n[i][0][1], enumFieldPragmas)
  81. else:
  82. e = newSymS(skEnumField, n[i][0], c)
  83. var v = semConstExpr(c, n[i][1])
  84. var strVal: PNode = nil
  85. case skipTypes(v.typ, abstractInst-{tyTypeDesc}).kind
  86. of tyTuple:
  87. if v.len == 2:
  88. strVal = v[1] # second tuple part is the string value
  89. if skipTypes(strVal.typ, abstractInst).kind in {tyString, tyCString}:
  90. if not isOrdinalType(v[0].typ, allowEnumWithHoles=true):
  91. localError(c.config, v[0].info, errOrdinalTypeExpected & "; given: " & typeToString(v[0].typ, preferDesc))
  92. x = toInt64(getOrdValue(v[0])) # first tuple part is the ordinal
  93. else:
  94. localError(c.config, strVal.info, errStringLiteralExpected)
  95. else:
  96. localError(c.config, v.info, errWrongNumberOfVariables)
  97. of tyString, tyCString:
  98. strVal = v
  99. x = counter
  100. else:
  101. if not isOrdinalType(v.typ, allowEnumWithHoles=true):
  102. localError(c.config, v.info, errOrdinalTypeExpected & "; given: " & typeToString(v.typ, preferDesc))
  103. x = toInt64(getOrdValue(v))
  104. if i != 1:
  105. if x != counter: incl(result.flags, tfEnumHasHoles)
  106. if x < counter:
  107. localError(c.config, n[i].info, errInvalidOrderInEnumX % e.name.s)
  108. x = counter
  109. e.ast = strVal # might be nil
  110. counter = x
  111. of nkSym:
  112. e = n[i].sym
  113. of nkIdent, nkAccQuoted:
  114. e = newSymS(skEnumField, n[i], c)
  115. of nkPragmaExpr:
  116. e = newSymS(skEnumField, n[i][0], c)
  117. pragma(c, e, n[i][1], enumFieldPragmas)
  118. else:
  119. illFormedAst(n[i], c.config)
  120. e.typ = result
  121. e.position = int(counter)
  122. if e.position == 0: hasNull = true
  123. if result.sym != nil and sfExported in result.sym.flags:
  124. incl(e.flags, sfUsed)
  125. incl(e.flags, sfExported)
  126. if not isPure: strTableAdd(c.module.tab, e)
  127. result.n.add newSymNode(e)
  128. styleCheckDef(c.config, e)
  129. onDef(e.info, e)
  130. if sfGenSym notin e.flags:
  131. if not isPure: addDecl(c, e)
  132. else: importPureEnumField(c, e)
  133. if isPure and (let conflict = strTableInclReportConflict(symbols, e); conflict != nil):
  134. wrongRedefinition(c, e.info, e.name.s, conflict.info)
  135. inc(counter)
  136. if tfNotNil in e.typ.flags and not hasNull:
  137. result.flags.incl tfRequiresInit
  138. proc semSet(c: PContext, n: PNode, prev: PType): PType =
  139. result = newOrPrevType(tySet, prev, c)
  140. if n.len == 2 and n[1].kind != nkEmpty:
  141. var base = semTypeNode(c, n[1], nil)
  142. addSonSkipIntLit(result, base)
  143. if base.kind in {tyGenericInst, tyAlias, tySink}: base = lastSon(base)
  144. if base.kind != tyGenericParam:
  145. if not isOrdinalType(base, allowEnumWithHoles = true):
  146. localError(c.config, n.info, errOrdinalTypeExpected)
  147. elif lengthOrd(c.config, base) > MaxSetElements:
  148. localError(c.config, n.info, errSetTooBig)
  149. else:
  150. localError(c.config, n.info, errXExpectsOneTypeParam % "set")
  151. addSonSkipIntLit(result, errorType(c))
  152. proc semContainerArg(c: PContext; n: PNode, kindStr: string; result: PType) =
  153. if n.len == 2:
  154. var base = semTypeNode(c, n[1], nil)
  155. if base.kind == tyVoid:
  156. localError(c.config, n.info, errTIsNotAConcreteType % typeToString(base))
  157. addSonSkipIntLit(result, base)
  158. else:
  159. localError(c.config, n.info, errXExpectsOneTypeParam % kindStr)
  160. addSonSkipIntLit(result, errorType(c))
  161. proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string,
  162. prev: PType): PType =
  163. result = newOrPrevType(kind, prev, c)
  164. semContainerArg(c, n, kindStr, result)
  165. proc semVarargs(c: PContext, n: PNode, prev: PType): PType =
  166. result = newOrPrevType(tyVarargs, prev, c)
  167. if n.len == 2 or n.len == 3:
  168. var base = semTypeNode(c, n[1], nil)
  169. addSonSkipIntLit(result, base)
  170. if n.len == 3:
  171. result.n = newIdentNode(considerQuotedIdent(c, n[2]), n[2].info)
  172. else:
  173. localError(c.config, n.info, errXExpectsOneTypeParam % "varargs")
  174. addSonSkipIntLit(result, errorType(c))
  175. proc semVarType(c: PContext, n: PNode, prev: PType): PType =
  176. if n.len == 1:
  177. result = newOrPrevType(tyVar, prev, c)
  178. var base = semTypeNode(c, n[0], nil).skipTypes({tyTypeDesc})
  179. if base.kind == tyVar:
  180. localError(c.config, n.info, "type 'var var' is not allowed")
  181. base = base[0]
  182. addSonSkipIntLit(result, base)
  183. else:
  184. result = newConstraint(c, tyVar)
  185. proc semDistinct(c: PContext, n: PNode, prev: PType): PType =
  186. if n.len == 0: return newConstraint(c, tyDistinct)
  187. result = newOrPrevType(tyDistinct, prev, c)
  188. addSonSkipIntLit(result, semTypeNode(c, n[0], nil))
  189. if n.len > 1: result.n = n[1]
  190. proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
  191. assert isRange(n)
  192. checkSonsLen(n, 3, c.config)
  193. result = newOrPrevType(tyRange, prev, c)
  194. result.n = newNodeI(nkRange, n.info)
  195. # always create a 'valid' range type, but overwrite it later
  196. # because 'semExprWithType' can raise an exception. See bug #6895.
  197. addSonSkipIntLit(result, errorType(c))
  198. if (n[1].kind == nkEmpty) or (n[2].kind == nkEmpty):
  199. localError(c.config, n.info, "range is empty")
  200. var range: array[2, PNode]
  201. range[0] = semExprWithType(c, n[1], {efDetermineType})
  202. range[1] = semExprWithType(c, n[2], {efDetermineType})
  203. var rangeT: array[2, PType]
  204. for i in 0..1:
  205. rangeT[i] = range[i].typ.skipTypes({tyStatic}).skipIntLit
  206. let hasUnknownTypes = c.inGenericContext > 0 and
  207. rangeT[0].kind == tyFromExpr or rangeT[1].kind == tyFromExpr
  208. if not hasUnknownTypes:
  209. if not sameType(rangeT[0].skipTypes({tyRange}), rangeT[1].skipTypes({tyRange})):
  210. localError(c.config, n.info, "type mismatch")
  211. elif not isOrdinalType(rangeT[0]) and rangeT[0].kind notin {tyFloat..tyFloat128} or
  212. rangeT[0].kind == tyBool:
  213. localError(c.config, n.info, "ordinal or float type expected")
  214. elif enumHasHoles(rangeT[0]):
  215. localError(c.config, n.info, "enum '$1' has holes" % typeToString(rangeT[0]))
  216. for i in 0..1:
  217. if hasUnresolvedArgs(c, range[i]):
  218. result.n.add makeStaticExpr(c, range[i])
  219. result.flags.incl tfUnresolved
  220. else:
  221. result.n.add semConstExpr(c, range[i])
  222. if (result.n[0].kind in {nkFloatLit..nkFloat64Lit} and classify(result.n[0].floatVal) == fcNan) or
  223. (result.n[1].kind in {nkFloatLit..nkFloat64Lit} and classify(result.n[1].floatVal) == fcNan):
  224. localError(c.config, n.info, "NaN is not a valid start or end for a range")
  225. if weakLeValue(result.n[0], result.n[1]) == impNo:
  226. localError(c.config, n.info, "range is empty")
  227. result[0] = rangeT[0]
  228. proc semRange(c: PContext, n: PNode, prev: PType): PType =
  229. result = nil
  230. if n.len == 2:
  231. if isRange(n[1]):
  232. result = semRangeAux(c, n[1], prev)
  233. let n = result.n
  234. if n[0].kind in {nkCharLit..nkUInt64Lit} and n[0].intVal > 0:
  235. incl(result.flags, tfRequiresInit)
  236. elif n[1].kind in {nkCharLit..nkUInt64Lit} and n[1].intVal < 0:
  237. incl(result.flags, tfRequiresInit)
  238. elif n[0].kind in {nkFloatLit..nkFloat64Lit} and
  239. n[0].floatVal > 0.0:
  240. incl(result.flags, tfRequiresInit)
  241. elif n[1].kind in {nkFloatLit..nkFloat64Lit} and
  242. n[1].floatVal < 0.0:
  243. incl(result.flags, tfRequiresInit)
  244. else:
  245. if n[1].kind == nkInfix and considerQuotedIdent(c, n[1][0]).s == "..<":
  246. localError(c.config, n[0].info, "range types need to be constructed with '..', '..<' is not supported")
  247. else:
  248. localError(c.config, n[0].info, "expected range")
  249. result = newOrPrevType(tyError, prev, c)
  250. else:
  251. localError(c.config, n.info, errXExpectsOneTypeParam % "range")
  252. result = newOrPrevType(tyError, prev, c)
  253. proc semArrayIndex(c: PContext, n: PNode): PType =
  254. if isRange(n):
  255. result = semRangeAux(c, n, nil)
  256. else:
  257. let e = semExprWithType(c, n, {efDetermineType})
  258. if e.typ.kind == tyFromExpr:
  259. result = makeRangeWithStaticExpr(c, e.typ.n)
  260. elif e.kind in {nkIntLit..nkUInt64Lit}:
  261. if e.intVal < 0:
  262. localError(c.config, n[1].info,
  263. "Array length can't be negative, but was " & $e.intVal)
  264. result = makeRangeType(c, 0, e.intVal-1, n.info, e.typ)
  265. elif e.kind == nkSym and e.typ.kind == tyStatic:
  266. if e.sym.ast != nil:
  267. return semArrayIndex(c, e.sym.ast)
  268. if not isOrdinalType(e.typ.lastSon):
  269. let info = if n.safeLen > 1: n[1].info else: n.info
  270. localError(c.config, info, errOrdinalTypeExpected)
  271. result = makeRangeWithStaticExpr(c, e)
  272. if c.inGenericContext > 0: result.flags.incl tfUnresolved
  273. elif e.kind in (nkCallKinds + {nkBracketExpr}) and hasUnresolvedArgs(c, e):
  274. if not isOrdinalType(e.typ):
  275. localError(c.config, n[1].info, errOrdinalTypeExpected)
  276. # This is an int returning call, depending on an
  277. # yet unknown generic param (see tgenericshardcases).
  278. # We are going to construct a range type that will be
  279. # properly filled-out in semtypinst (see how tyStaticExpr
  280. # is handled there).
  281. result = makeRangeWithStaticExpr(c, e)
  282. elif e.kind == nkIdent:
  283. result = e.typ.skipTypes({tyTypeDesc})
  284. else:
  285. let x = semConstExpr(c, e)
  286. if x.kind in {nkIntLit..nkUInt64Lit}:
  287. result = makeRangeType(c, 0, x.intVal-1, n.info,
  288. x.typ.skipTypes({tyTypeDesc}))
  289. else:
  290. result = x.typ.skipTypes({tyTypeDesc})
  291. #localError(c.config, n[1].info, errConstExprExpected)
  292. proc semArray(c: PContext, n: PNode, prev: PType): PType =
  293. var base: PType
  294. if n.len == 3:
  295. # 3 = length(array indx base)
  296. let indx = semArrayIndex(c, n[1])
  297. var indxB = indx
  298. if indxB.kind in {tyGenericInst, tyAlias, tySink}: indxB = lastSon(indxB)
  299. if indxB.kind notin {tyGenericParam, tyStatic, tyFromExpr}:
  300. if indxB.skipTypes({tyRange}).kind in {tyUInt, tyUInt64}:
  301. discard
  302. elif not isOrdinalType(indxB):
  303. localError(c.config, n[1].info, errOrdinalTypeExpected)
  304. elif enumHasHoles(indxB):
  305. localError(c.config, n[1].info, "enum '$1' has holes" %
  306. typeToString(indxB.skipTypes({tyRange})))
  307. base = semTypeNode(c, n[2], nil)
  308. # ensure we only construct a tyArray when there was no error (bug #3048):
  309. result = newOrPrevType(tyArray, prev, c)
  310. # bug #6682: Do not propagate initialization requirements etc for the
  311. # index type:
  312. rawAddSonNoPropagationOfTypeFlags(result, indx)
  313. addSonSkipIntLit(result, base)
  314. else:
  315. localError(c.config, n.info, errArrayExpectsTwoTypeParams)
  316. result = newOrPrevType(tyError, prev, c)
  317. proc semOrdinal(c: PContext, n: PNode, prev: PType): PType =
  318. result = newOrPrevType(tyOrdinal, prev, c)
  319. if n.len == 2:
  320. var base = semTypeNode(c, n[1], nil)
  321. if base.kind != tyGenericParam:
  322. if not isOrdinalType(base):
  323. localError(c.config, n[1].info, errOrdinalTypeExpected)
  324. addSonSkipIntLit(result, base)
  325. else:
  326. localError(c.config, n.info, errXExpectsOneTypeParam % "ordinal")
  327. result = newOrPrevType(tyError, prev, c)
  328. proc semTypeIdent(c: PContext, n: PNode): PSym =
  329. if n.kind == nkSym:
  330. result = getGenSym(c, n.sym)
  331. else:
  332. result = pickSym(c, n, {skType, skGenericParam, skParam})
  333. if result.isNil:
  334. result = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared})
  335. if result != nil:
  336. markUsed(c, n.info, result)
  337. onUse(n.info, result)
  338. if result.kind == skParam and result.typ.kind == tyTypeDesc:
  339. # This is a typedesc param. is it already bound?
  340. # it's not bound when it's used multiple times in the
  341. # proc signature for example
  342. if c.inGenericInst > 0:
  343. let bound = result.typ[0].sym
  344. if bound != nil: return bound
  345. return result
  346. if result.typ.sym == nil:
  347. localError(c.config, n.info, errTypeExpected)
  348. return errorSym(c, n)
  349. result = result.typ.sym.copySym
  350. result.typ = exactReplica(result.typ)
  351. result.typ.flags.incl tfUnresolved
  352. if result.kind == skGenericParam:
  353. if result.typ.kind == tyGenericParam and result.typ.len == 0 and
  354. tfWildcard in result.typ.flags:
  355. # collapse the wild-card param to a type
  356. result.transitionGenericParamToType()
  357. result.typ.flags.excl tfWildcard
  358. return
  359. else:
  360. localError(c.config, n.info, errTypeExpected)
  361. return errorSym(c, n)
  362. if result.kind != skType and result.magic notin {mStatic, mType, mTypeOf}:
  363. # this implements the wanted ``var v: V, x: V`` feature ...
  364. var ov: TOverloadIter
  365. var amb = initOverloadIter(ov, c, n)
  366. while amb != nil and amb.kind != skType:
  367. amb = nextOverloadIter(ov, c, n)
  368. if amb != nil: result = amb
  369. else:
  370. if result.kind != skError: localError(c.config, n.info, errTypeExpected)
  371. return errorSym(c, n)
  372. if result.typ.kind != tyGenericParam:
  373. # XXX get rid of this hack!
  374. var oldInfo = n.info
  375. when defined(useNodeIds):
  376. let oldId = n.id
  377. reset(n[])
  378. when defined(useNodeIds):
  379. n.id = oldId
  380. n.transitionNoneToSym()
  381. n.sym = result
  382. n.info = oldInfo
  383. n.typ = result.typ
  384. else:
  385. localError(c.config, n.info, "identifier expected")
  386. result = errorSym(c, n)
  387. proc semAnonTuple(c: PContext, n: PNode, prev: PType): PType =
  388. if n.len == 0:
  389. localError(c.config, n.info, errTypeExpected)
  390. result = newOrPrevType(tyTuple, prev, c)
  391. for it in n:
  392. addSonSkipIntLit(result, semTypeNode(c, it, nil))
  393. proc semTuple(c: PContext, n: PNode, prev: PType): PType =
  394. var typ: PType
  395. result = newOrPrevType(tyTuple, prev, c)
  396. result.n = newNodeI(nkRecList, n.info)
  397. var check = initIntSet()
  398. var counter = 0
  399. for i in ord(n.kind == nkBracketExpr)..<n.len:
  400. var a = n[i]
  401. if (a.kind != nkIdentDefs): illFormedAst(a, c.config)
  402. checkMinSonsLen(a, 3, c.config)
  403. if a[^2].kind != nkEmpty:
  404. typ = semTypeNode(c, a[^2], nil)
  405. else:
  406. localError(c.config, a.info, errTypeExpected)
  407. typ = errorType(c)
  408. if a[^1].kind != nkEmpty:
  409. localError(c.config, a[^1].info, errInitHereNotAllowed)
  410. for j in 0..<a.len - 2:
  411. var field = newSymG(skField, a[j], c)
  412. field.typ = typ
  413. field.position = counter
  414. inc(counter)
  415. if containsOrIncl(check, field.name.id):
  416. localError(c.config, a[j].info, "attempt to redefine: '" & field.name.s & "'")
  417. else:
  418. result.n.add newSymNode(field)
  419. addSonSkipIntLit(result, typ)
  420. styleCheckDef(c.config, a[j].info, field)
  421. onDef(field.info, field)
  422. if result.n.len == 0: result.n = nil
  423. if isTupleRecursive(result):
  424. localError(c.config, n.info, errIllegalRecursionInTypeX % typeToString(result))
  425. proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
  426. allowed: TSymFlags): PSym =
  427. # identifier with visibility
  428. if n.kind == nkPostfix:
  429. if n.len == 2:
  430. # for gensym'ed identifiers the identifier may already have been
  431. # transformed to a symbol and we need to use that here:
  432. result = newSymG(kind, n[1], c)
  433. var v = considerQuotedIdent(c, n[0])
  434. if sfExported in allowed and v.id == ord(wStar):
  435. incl(result.flags, sfExported)
  436. else:
  437. if not (sfExported in allowed):
  438. localError(c.config, n[0].info, errXOnlyAtModuleScope % "export")
  439. else:
  440. localError(c.config, n[0].info, errInvalidVisibilityX % renderTree(n[0]))
  441. else:
  442. illFormedAst(n, c.config)
  443. else:
  444. result = newSymG(kind, n, c)
  445. proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode,
  446. allowed: TSymFlags): PSym =
  447. if n.kind == nkPragmaExpr:
  448. checkSonsLen(n, 2, c.config)
  449. result = semIdentVis(c, kind, n[0], allowed)
  450. case kind
  451. of skType:
  452. # process pragmas later, because result.typ has not been set yet
  453. discard
  454. of skField: pragma(c, result, n[1], fieldPragmas)
  455. of skVar: pragma(c, result, n[1], varPragmas)
  456. of skLet: pragma(c, result, n[1], letPragmas)
  457. of skConst: pragma(c, result, n[1], constPragmas)
  458. else: discard
  459. else:
  460. result = semIdentVis(c, kind, n, allowed)
  461. proc checkForOverlap(c: PContext, t: PNode, currentEx, branchIndex: int) =
  462. let ex = t[branchIndex][currentEx].skipConv
  463. for i in 1..branchIndex:
  464. for j in 0..<t[i].len - 1:
  465. if i == branchIndex and j == currentEx: break
  466. if overlap(t[i][j].skipConv, ex):
  467. localError(c.config, ex.info, errDuplicateCaseLabel)
  468. proc semBranchRange(c: PContext, t, a, b: PNode, covered: var Int128): PNode =
  469. checkMinSonsLen(t, 1, c.config)
  470. let ac = semConstExpr(c, a)
  471. let bc = semConstExpr(c, b)
  472. let at = fitNode(c, t[0].typ, ac, ac.info).skipConvTakeType
  473. let bt = fitNode(c, t[0].typ, bc, bc.info).skipConvTakeType
  474. result = newNodeI(nkRange, a.info)
  475. result.add(at)
  476. result.add(bt)
  477. if emptyRange(ac, bc): localError(c.config, b.info, "range is empty")
  478. else: covered = covered + getOrdValue(bc) + 1 - getOrdValue(ac)
  479. proc semCaseBranchRange(c: PContext, t, b: PNode,
  480. covered: var Int128): PNode =
  481. checkSonsLen(b, 3, c.config)
  482. result = semBranchRange(c, t, b[1], b[2], covered)
  483. proc semCaseBranchSetElem(c: PContext, t, b: PNode,
  484. covered: var Int128): PNode =
  485. if isRange(b):
  486. checkSonsLen(b, 3, c.config)
  487. result = semBranchRange(c, t, b[1], b[2], covered)
  488. elif b.kind == nkRange:
  489. checkSonsLen(b, 2, c.config)
  490. result = semBranchRange(c, t, b[0], b[1], covered)
  491. else:
  492. result = fitNode(c, t[0].typ, b, b.info)
  493. inc(covered)
  494. proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
  495. covered: var Int128) =
  496. let lastIndex = branch.len - 2
  497. for i in 0..lastIndex:
  498. var b = branch[i]
  499. if b.kind == nkRange:
  500. branch[i] = b
  501. elif isRange(b):
  502. branch[i] = semCaseBranchRange(c, t, b, covered)
  503. else:
  504. # constant sets and arrays are allowed:
  505. var r = semConstExpr(c, b)
  506. if r.kind in {nkCurly, nkBracket} and r.len == 0 and branch.len == 2:
  507. # discarding ``{}`` and ``[]`` branches silently
  508. delSon(branch, 0)
  509. return
  510. elif r.kind notin {nkCurly, nkBracket} or r.len == 0:
  511. checkMinSonsLen(t, 1, c.config)
  512. var tmp = fitNode(c, t[0].typ, r, r.info)
  513. # the call to fitNode may introduce a call to a converter
  514. if tmp.kind in {nkHiddenCallConv}: tmp = semConstExpr(c, tmp)
  515. branch[i] = skipConv(tmp)
  516. inc(covered)
  517. else:
  518. if r.kind == nkCurly:
  519. r = deduplicate(c.config, r)
  520. # first element is special and will overwrite: branch[i]:
  521. branch[i] = semCaseBranchSetElem(c, t, r[0], covered)
  522. # other elements have to be added to ``branch``
  523. for j in 1..<r.len:
  524. branch.add(semCaseBranchSetElem(c, t, r[j], covered))
  525. # caution! last son of branch must be the actions to execute:
  526. swap(branch[^2], branch[^1])
  527. checkForOverlap(c, t, i, branchIndex)
  528. # Elements added above needs to be checked for overlaps.
  529. for i in lastIndex.succ..<branch.len - 1:
  530. checkForOverlap(c, t, i, branchIndex)
  531. proc toCover(c: PContext, t: PType): Int128 =
  532. let t2 = skipTypes(t, abstractVarRange-{tyTypeDesc})
  533. if t2.kind == tyEnum and enumHasHoles(t2):
  534. result = toInt128(t2.n.len)
  535. else:
  536. # <----
  537. let t = skipTypes(t, abstractVar-{tyTypeDesc})
  538. # XXX: hack incoming. lengthOrd is incorrect for 64bit integer
  539. # types because it doesn't uset Int128 yet. This entire branching
  540. # should be removed as soon as lengthOrd uses int128.
  541. if t.kind in {tyInt64, tyUInt64}:
  542. result = toInt128(1) shl 64
  543. elif t.kind in {tyInt, tyUInt}:
  544. result = toInt128(1) shl (c.config.target.intSize * 8)
  545. else:
  546. result = lengthOrd(c.config, t)
  547. proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
  548. father: PNode, rectype: PType, hasCaseFields = false)
  549. proc getIntSetOfType(c: PContext, t: PType): IntSet =
  550. result = initIntSet()
  551. if t.enumHasHoles:
  552. let t = t.skipTypes(abstractRange)
  553. for field in t.n.sons:
  554. result.incl(field.sym.position)
  555. else:
  556. assert(lengthOrd(c.config, t) <= BiggestInt(MaxSetElements))
  557. for i in toInt64(firstOrd(c.config, t))..toInt64(lastOrd(c.config, t)):
  558. result.incl(i.int)
  559. iterator processBranchVals(b: PNode): int =
  560. assert b.kind in {nkOfBranch, nkElifBranch, nkElse}
  561. if b.kind == nkOfBranch:
  562. for i in 0..<b.len-1:
  563. if b[i].kind in {nkIntLit, nkCharLit}:
  564. yield b[i].intVal.int
  565. elif b[i].kind == nkRange:
  566. for i in b[i][0].intVal..b[i][1].intVal:
  567. yield i.int
  568. proc renderAsType(vals: IntSet, t: PType): string =
  569. result = "{"
  570. let t = t.skipTypes(abstractRange)
  571. var enumSymOffset = 0
  572. var i = 0
  573. for val in vals:
  574. if result.len > 1:
  575. result &= ", "
  576. case t.kind:
  577. of tyEnum, tyBool:
  578. while t.n[enumSymOffset].sym.position < val: inc(enumSymOffset)
  579. result &= t.n[enumSymOffset].sym.name.s
  580. of tyChar:
  581. result.addQuoted(char(val))
  582. else:
  583. if i == 64:
  584. result &= "omitted $1 values..." % $(vals.len - i)
  585. break
  586. else:
  587. result &= $val
  588. inc(i)
  589. result &= "}"
  590. proc formatMissingEnums(c: PContext, n: PNode): string =
  591. var coveredCases = initIntSet()
  592. for i in 1..<n.len:
  593. for val in processBranchVals(n[i]):
  594. coveredCases.incl val
  595. result = (c.getIntSetOfType(n[0].typ) - coveredCases).renderAsType(n[0].typ)
  596. proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int,
  597. father: PNode, rectype: PType) =
  598. var a = copyNode(n)
  599. checkMinSonsLen(n, 2, c.config)
  600. semRecordNodeAux(c, n[0], check, pos, a, rectype, hasCaseFields = true)
  601. if a[0].kind != nkSym:
  602. internalError(c.config, "semRecordCase: discriminant is no symbol")
  603. return
  604. incl(a[0].sym.flags, sfDiscriminant)
  605. var covered: Int128 = toInt128(0)
  606. var chckCovered = false
  607. var typ = skipTypes(a[0].typ, abstractVar-{tyTypeDesc})
  608. const shouldChckCovered = {tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool}
  609. case typ.kind
  610. of shouldChckCovered:
  611. chckCovered = true
  612. of tyFloat..tyFloat128, tyError:
  613. discard
  614. of tyRange:
  615. if skipTypes(typ[0], abstractInst).kind in shouldChckCovered:
  616. chckCovered = true
  617. of tyForward:
  618. errorUndeclaredIdentifier(c, n[0].info, typ.sym.name.s)
  619. elif not isOrdinalType(typ):
  620. localError(c.config, n[0].info, "selector must be of an ordinal type, float")
  621. if firstOrd(c.config, typ) != 0:
  622. localError(c.config, n.info, "low(" & $a[0].sym.name.s &
  623. ") must be 0 for discriminant")
  624. elif lengthOrd(c.config, typ) > 0x00007FFF:
  625. localError(c.config, n.info, "len($1) must be less than 32768" % a[0].sym.name.s)
  626. for i in 1..<n.len:
  627. var b = copyTree(n[i])
  628. a.add b
  629. case n[i].kind
  630. of nkOfBranch:
  631. checkMinSonsLen(b, 2, c.config)
  632. semCaseBranch(c, a, b, i, covered)
  633. of nkElse:
  634. checkSonsLen(b, 1, c.config)
  635. if chckCovered and covered == toCover(c, a[0].typ):
  636. localError(c.config, b.info, "invalid else, all cases are already covered")
  637. chckCovered = false
  638. else: illFormedAst(n, c.config)
  639. delSon(b, b.len - 1)
  640. semRecordNodeAux(c, lastSon(n[i]), check, pos, b, rectype, hasCaseFields = true)
  641. if chckCovered and covered != toCover(c, a[0].typ):
  642. if a[0].typ.skipTypes(abstractRange).kind == tyEnum:
  643. localError(c.config, a.info, "not all cases are covered; missing: $1" %
  644. formatMissingEnums(c, a))
  645. else:
  646. localError(c.config, a.info, "not all cases are covered")
  647. father.add a
  648. proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
  649. father: PNode, rectype: PType, hasCaseFields: bool) =
  650. if n == nil: return
  651. case n.kind
  652. of nkRecWhen:
  653. var branch: PNode = nil # the branch to take
  654. for i in 0..<n.len:
  655. var it = n[i]
  656. if it == nil: illFormedAst(n, c.config)
  657. var idx = 1
  658. case it.kind
  659. of nkElifBranch:
  660. checkSonsLen(it, 2, c.config)
  661. if c.inGenericContext == 0:
  662. var e = semConstBoolExpr(c, it[0])
  663. if e.kind != nkIntLit: internalError(c.config, e.info, "semRecordNodeAux")
  664. elif e.intVal != 0 and branch == nil: branch = it[1]
  665. else:
  666. it[0] = forceBool(c, semExprWithType(c, it[0]))
  667. of nkElse:
  668. checkSonsLen(it, 1, c.config)
  669. if branch == nil: branch = it[0]
  670. idx = 0
  671. else: illFormedAst(n, c.config)
  672. if c.inGenericContext > 0:
  673. # use a new check intset here for each branch:
  674. var newCheck: IntSet
  675. assign(newCheck, check)
  676. var newPos = pos
  677. var newf = newNodeI(nkRecList, n.info)
  678. semRecordNodeAux(c, it[idx], newCheck, newPos, newf, rectype, hasCaseFields)
  679. it[idx] = if newf.len == 1: newf[0] else: newf
  680. if c.inGenericContext > 0:
  681. father.add n
  682. elif branch != nil:
  683. semRecordNodeAux(c, branch, check, pos, father, rectype, hasCaseFields)
  684. of nkRecCase:
  685. semRecordCase(c, n, check, pos, father, rectype)
  686. of nkNilLit:
  687. if father.kind != nkRecList: father.add newNodeI(nkRecList, n.info)
  688. of nkRecList:
  689. # attempt to keep the nesting at a sane level:
  690. var a = if father.kind == nkRecList: father else: copyNode(n)
  691. for i in 0..<n.len:
  692. semRecordNodeAux(c, n[i], check, pos, a, rectype, hasCaseFields)
  693. if a != father: father.add a
  694. of nkIdentDefs:
  695. checkMinSonsLen(n, 3, c.config)
  696. var a: PNode
  697. if father.kind != nkRecList and n.len >= 4: a = newNodeI(nkRecList, n.info)
  698. else: a = newNodeI(nkEmpty, n.info)
  699. if n[^1].kind != nkEmpty:
  700. localError(c.config, n[^1].info, errInitHereNotAllowed)
  701. var typ: PType
  702. if n[^2].kind == nkEmpty:
  703. localError(c.config, n.info, errTypeExpected)
  704. typ = errorType(c)
  705. else:
  706. typ = semTypeNode(c, n[^2], nil)
  707. propagateToOwner(rectype, typ)
  708. var fieldOwner = if c.inGenericContext > 0: c.getCurrOwner
  709. else: rectype.sym
  710. for i in 0..<n.len-2:
  711. var f = semIdentWithPragma(c, skField, n[i], {sfExported})
  712. let info = if n[i].kind == nkPostfix:
  713. n[i][1].info
  714. else:
  715. n[i].info
  716. suggestSym(c.config, info, f, c.graph.usageSym)
  717. f.typ = typ
  718. f.position = pos
  719. f.options = c.config.options
  720. if fieldOwner != nil and
  721. {sfImportc, sfExportc} * fieldOwner.flags != {} and
  722. not hasCaseFields and f.loc.r == nil:
  723. f.loc.r = rope(f.name.s)
  724. f.flags = f.flags + ({sfImportc, sfExportc} * fieldOwner.flags)
  725. inc(pos)
  726. if containsOrIncl(check, f.name.id):
  727. localError(c.config, info, "attempt to redefine: '" & f.name.s & "'")
  728. if a.kind == nkEmpty: father.add newSymNode(f)
  729. else: a.add newSymNode(f)
  730. styleCheckDef(c.config, f)
  731. onDef(f.info, f)
  732. if a.kind != nkEmpty: father.add a
  733. of nkSym:
  734. # This branch only valid during generic object
  735. # inherited from generic/partial specialized parent second check.
  736. # There is no branch validity check here
  737. if containsOrIncl(check, n.sym.name.id):
  738. localError(c.config, n.info, "attempt to redefine: '" & n.sym.name.s & "'")
  739. father.add n
  740. of nkEmpty: discard
  741. else: illFormedAst(n, c.config)
  742. proc addInheritedFieldsAux(c: PContext, check: var IntSet, pos: var int,
  743. n: PNode) =
  744. case n.kind
  745. of nkRecCase:
  746. if (n[0].kind != nkSym): internalError(c.config, n.info, "addInheritedFieldsAux")
  747. addInheritedFieldsAux(c, check, pos, n[0])
  748. for i in 1..<n.len:
  749. case n[i].kind
  750. of nkOfBranch, nkElse:
  751. addInheritedFieldsAux(c, check, pos, lastSon(n[i]))
  752. else: internalError(c.config, n.info, "addInheritedFieldsAux(record case branch)")
  753. of nkRecList, nkRecWhen, nkElifBranch, nkElse:
  754. for i in int(n.kind == nkElifBranch)..<n.len:
  755. addInheritedFieldsAux(c, check, pos, n[i])
  756. of nkSym:
  757. incl(check, n.sym.name.id)
  758. inc(pos)
  759. else: internalError(c.config, n.info, "addInheritedFieldsAux()")
  760. proc skipGenericInvocation(t: PType): PType {.inline.} =
  761. result = t
  762. if result.kind == tyGenericInvocation:
  763. result = result[0]
  764. while result.kind in {tyGenericInst, tyGenericBody, tyRef, tyPtr, tyAlias, tySink, tyOwned}:
  765. result = lastSon(result)
  766. proc addInheritedFields(c: PContext, check: var IntSet, pos: var int,
  767. obj: PType) =
  768. assert obj.kind == tyObject
  769. if (obj.len > 0) and (obj[0] != nil):
  770. addInheritedFields(c, check, pos, obj[0].skipGenericInvocation)
  771. addInheritedFieldsAux(c, check, pos, obj.n)
  772. proc semObjectNode(c: PContext, n: PNode, prev: PType; isInheritable: bool): PType =
  773. if n.len == 0:
  774. return newConstraint(c, tyObject)
  775. var check = initIntSet()
  776. var pos = 0
  777. var base, realBase: PType = nil
  778. # n[0] contains the pragmas (if any). We process these later...
  779. checkSonsLen(n, 3, c.config)
  780. if n[1].kind != nkEmpty:
  781. realBase = semTypeNode(c, n[1][0], nil)
  782. base = skipTypesOrNil(realBase, skipPtrs)
  783. if base.isNil:
  784. localError(c.config, n.info, "cannot inherit from a type that is not an object type")
  785. else:
  786. var concreteBase = skipGenericInvocation(base)
  787. if concreteBase.kind in {tyObject, tyGenericParam,
  788. tyGenericInvocation} and tfFinal notin concreteBase.flags:
  789. # we only check fields duplication of object inherited from
  790. # concrete object. If inheriting from generic object or partial
  791. # specialized object, there will be second check after instantiation
  792. # located in semGeneric.
  793. if concreteBase.kind == tyObject:
  794. if concreteBase.sym != nil and concreteBase.sym.magic == mException and
  795. sfSystemModule notin c.module.flags:
  796. message(c.config, n.info, warnInheritFromException, "")
  797. addInheritedFields(c, check, pos, concreteBase)
  798. else:
  799. if concreteBase.kind != tyError:
  800. localError(c.config, n[1].info, "inheritance only works with non-final objects; " &
  801. "for " & typeToString(realBase) & " to be inheritable it must be " &
  802. "'object of RootObj' instead of 'object'")
  803. base = nil
  804. realBase = nil
  805. if n.kind != nkObjectTy: internalError(c.config, n.info, "semObjectNode")
  806. result = newOrPrevType(tyObject, prev, c)
  807. rawAddSon(result, realBase)
  808. if realBase == nil and isInheritable:
  809. result.flags.incl tfInheritable
  810. if result.n.isNil:
  811. result.n = newNodeI(nkRecList, n.info)
  812. else:
  813. # partial object so add things to the check
  814. addInheritedFields(c, check, pos, result)
  815. semRecordNodeAux(c, n[2], check, pos, result.n, result)
  816. if n[0].kind != nkEmpty:
  817. # dummy symbol for `pragma`:
  818. var s = newSymS(skType, newIdentNode(getIdent(c.cache, "dummy"), n.info), c)
  819. s.typ = result
  820. pragma(c, s, n[0], typePragmas)
  821. if base == nil and tfInheritable notin result.flags:
  822. incl(result.flags, tfFinal)
  823. if c.inGenericContext == 0 and computeRequiresInit(c, result):
  824. result.flags.incl tfRequiresInit
  825. proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
  826. if n.len < 1:
  827. result = newConstraint(c, kind)
  828. else:
  829. let isCall = int ord(n.kind in nkCallKinds+{nkBracketExpr})
  830. let n = if n[0].kind == nkBracket: n[0] else: n
  831. checkMinSonsLen(n, 1, c.config)
  832. let body = n.lastSon
  833. var t = if prev != nil and body.kind == nkObjectTy and tfInheritable in prev.flags:
  834. semObjectNode(c, body, nil, isInheritable=true)
  835. else:
  836. semTypeNode(c, body, nil)
  837. if t.kind == tyTypeDesc and tfUnresolved notin t.flags:
  838. t = t.base
  839. if t.kind == tyVoid:
  840. const kindToStr: array[tyPtr..tyRef, string] = ["ptr", "ref"]
  841. localError(c.config, n.info, "type '$1 void' is not allowed" % kindToStr[kind])
  842. result = newOrPrevType(kind, prev, c)
  843. var isNilable = false
  844. var wrapperKind = tyNone
  845. # check every except the last is an object:
  846. for i in isCall..<n.len-1:
  847. let ni = n[i]
  848. if ni.kind == nkNilLit:
  849. isNilable = true
  850. else:
  851. let region = semTypeNode(c, ni, nil)
  852. if region.kind in {tyOwned, tySink}:
  853. wrapperKind = region.kind
  854. elif region.skipTypes({tyGenericInst, tyAlias, tySink}).kind notin {
  855. tyError, tyObject}:
  856. message c.config, n[i].info, errGenerated, "region needs to be an object type"
  857. addSonSkipIntLit(result, region)
  858. else:
  859. message(c.config, n.info, warnDeprecated, "region for pointer types is deprecated")
  860. addSonSkipIntLit(result, region)
  861. addSonSkipIntLit(result, t)
  862. if tfPartial in result.flags:
  863. if result.lastSon.kind == tyObject: incl(result.lastSon.flags, tfPartial)
  864. #if not isNilable: result.flags.incl tfNotNil
  865. case wrapperKind
  866. of tyOwned:
  867. if optOwnedRefs in c.config.globalOptions:
  868. let t = newTypeS(tyOwned, c)
  869. t.flags.incl tfHasOwned
  870. t.rawAddSonNoPropagationOfTypeFlags result
  871. result = t
  872. of tySink:
  873. let t = newTypeS(tySink, c)
  874. t.rawAddSonNoPropagationOfTypeFlags result
  875. result = t
  876. else: discard
  877. #if result.kind == tyRef and c.config.selectedGC == gcDestructors:
  878. # result.flags.incl tfHasAsgn
  879. # XXX Something like this is a good idea but it should be done
  880. # in sempass2!
  881. proc findEnforcedStaticType(t: PType): PType =
  882. # This handles types such as `static[T] and Foo`,
  883. # which are subset of `static[T]`, hence they could
  884. # be treated in the same way
  885. if t == nil: return nil
  886. if t.kind == tyStatic: return t
  887. if t.kind == tyAnd:
  888. for s in t.sons:
  889. let t = findEnforcedStaticType(s)
  890. if t != nil: return t
  891. proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) =
  892. if kind == skMacro:
  893. let staticType = findEnforcedStaticType(param.typ)
  894. if staticType != nil:
  895. var a = copySym(param)
  896. a.typ = staticType.base
  897. addDecl(c, a)
  898. #elif param.typ != nil and param.typ.kind == tyTypeDesc:
  899. # addDecl(c, param)
  900. else:
  901. # within a macro, every param has the type NimNode!
  902. let nn = getSysSym(c.graph, param.info, "NimNode")
  903. var a = copySym(param)
  904. a.typ = nn.typ
  905. addDecl(c, a)
  906. else:
  907. if sfGenSym in param.flags:
  908. # bug #XXX, fix the gensym'ed parameters owner:
  909. if param.owner == nil:
  910. param.owner = getCurrOwner(c)
  911. else: addDecl(c, param)
  912. template shouldHaveMeta(t) =
  913. internalAssert c.config, tfHasMeta in t.flags
  914. # result.lastSon.flags.incl tfHasMeta
  915. proc addImplicitGeneric(c: PContext; typeClass: PType, typId: PIdent;
  916. info: TLineInfo; genericParams: PNode;
  917. paramName: string): PType =
  918. if genericParams == nil:
  919. # This happens with anonymous proc types appearing in signatures
  920. # XXX: we need to lift these earlier
  921. return
  922. let finalTypId = if typId != nil: typId
  923. else: getIdent(c.cache, paramName & ":type")
  924. # is this a bindOnce type class already present in the param list?
  925. for i in 0..<genericParams.len:
  926. if genericParams[i].sym.name.id == finalTypId.id:
  927. return genericParams[i].typ
  928. let owner = if typeClass.sym != nil: typeClass.sym
  929. else: getCurrOwner(c)
  930. var s = newSym(skType, finalTypId, owner, info)
  931. if sfExplain in owner.flags: s.flags.incl sfExplain
  932. if typId == nil: s.flags.incl(sfAnon)
  933. s.linkTo(typeClass)
  934. typeClass.flags.incl tfImplicitTypeParam
  935. s.position = genericParams.len
  936. genericParams.add newSymNode(s)
  937. result = typeClass
  938. addDecl(c, s)
  939. proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
  940. paramType: PType, paramName: string,
  941. info: TLineInfo, anon = false): PType =
  942. if paramType == nil: return # (e.g. proc return type)
  943. template recurse(typ: PType, anonFlag = false): untyped =
  944. liftParamType(c, procKind, genericParams, typ, paramName, info, anonFlag)
  945. var paramTypId = if not anon and paramType.sym != nil: paramType.sym.name
  946. else: nil
  947. case paramType.kind:
  948. of tyAnything:
  949. result = addImplicitGeneric(c, newTypeS(tyGenericParam, c), nil, info, genericParams, paramName)
  950. of tyStatic:
  951. if paramType.base.kind != tyNone and paramType.n != nil:
  952. # this is a concrete static value
  953. return
  954. if tfUnresolved in paramType.flags: return # already lifted
  955. let lifted = recurse(paramType.base)
  956. let base = (if lifted != nil: lifted else: paramType.base)
  957. if base.isMetaType and procKind == skMacro:
  958. localError(c.config, info, errMacroBodyDependsOnGenericTypes % paramName)
  959. result = addImplicitGeneric(c, c.newTypeWithSons(tyStatic, @[base]),
  960. paramTypId, info, genericParams, paramName)
  961. if result != nil: result.flags.incl({tfHasStatic, tfUnresolved})
  962. of tyTypeDesc:
  963. if tfUnresolved notin paramType.flags:
  964. # naked typedescs are not bindOnce types
  965. if paramType.base.kind == tyNone and paramTypId != nil and
  966. (paramTypId.id == getIdent(c.cache, "typedesc").id or
  967. paramTypId.id == getIdent(c.cache, "type").id):
  968. # XXX Why doesn't this check for tyTypeDesc instead?
  969. paramTypId = nil
  970. let t = c.newTypeWithSons(tyTypeDesc, @[paramType.base])
  971. incl t.flags, tfCheckedForDestructor
  972. result = addImplicitGeneric(c, t, paramTypId, info, genericParams, paramName)
  973. of tyDistinct:
  974. if paramType.len == 1:
  975. # disable the bindOnce behavior for the type class
  976. result = recurse(paramType.base, true)
  977. of tyAlias, tyOwned:
  978. result = recurse(paramType.base)
  979. of tySequence, tySet, tyArray, tyOpenArray,
  980. tyVar, tyLent, tyPtr, tyRef, tyProc:
  981. # XXX: this is a bit strange, but proc(s: seq)
  982. # produces tySequence(tyGenericParam, tyNone).
  983. # This also seems to be true when creating aliases
  984. # like: type myseq = distinct seq.
  985. # Maybe there is another better place to associate
  986. # the seq type class with the seq identifier.
  987. if paramType.kind == tySequence and paramType.lastSon.kind == tyNone:
  988. let typ = c.newTypeWithSons(tyBuiltInTypeClass,
  989. @[newTypeS(paramType.kind, c)])
  990. result = addImplicitGeneric(c, typ, paramTypId, info, genericParams, paramName)
  991. else:
  992. for i in 0..<paramType.len:
  993. if paramType[i] == paramType:
  994. globalError(c.config, info, errIllegalRecursionInTypeX % typeToString(paramType))
  995. var lifted = recurse(paramType[i])
  996. if lifted != nil:
  997. paramType[i] = lifted
  998. result = paramType
  999. of tyGenericBody:
  1000. result = newTypeS(tyGenericInvocation, c)
  1001. result.rawAddSon(paramType)
  1002. for i in 0..<paramType.len - 1:
  1003. if paramType[i].kind == tyStatic:
  1004. var staticCopy = paramType[i].exactReplica
  1005. staticCopy.flags.incl tfInferrableStatic
  1006. result.rawAddSon staticCopy
  1007. else:
  1008. result.rawAddSon newTypeS(tyAnything, c)
  1009. if paramType.lastSon.kind == tyUserTypeClass:
  1010. result.kind = tyUserTypeClassInst
  1011. result.rawAddSon paramType.lastSon
  1012. return addImplicitGeneric(c, result, paramTypId, info, genericParams, paramName)
  1013. let x = instGenericContainer(c, paramType.sym.info, result,
  1014. allowMetaTypes = true)
  1015. result = newTypeWithSons(c, tyCompositeTypeClass, @[paramType, x])
  1016. #result = newTypeS(tyCompositeTypeClass, c)
  1017. #for i in 0..<x.len: result.rawAddSon(x[i])
  1018. result = addImplicitGeneric(c, result, paramTypId, info, genericParams, paramName)
  1019. of tyGenericInst:
  1020. if paramType.lastSon.kind == tyUserTypeClass:
  1021. var cp = copyType(paramType, getCurrOwner(c), false)
  1022. cp.kind = tyUserTypeClassInst
  1023. return addImplicitGeneric(c, cp, paramTypId, info, genericParams, paramName)
  1024. for i in 1..<paramType.len-1:
  1025. var lifted = recurse(paramType[i])
  1026. if lifted != nil:
  1027. paramType[i] = lifted
  1028. result = paramType
  1029. result.lastSon.shouldHaveMeta
  1030. let liftBody = recurse(paramType.lastSon, true)
  1031. if liftBody != nil:
  1032. result = liftBody
  1033. result.flags.incl tfHasMeta
  1034. #result.shouldHaveMeta
  1035. of tyGenericInvocation:
  1036. for i in 1..<paramType.len:
  1037. #if paramType[i].kind != tyTypeDesc:
  1038. let lifted = recurse(paramType[i])
  1039. if lifted != nil: paramType[i] = lifted
  1040. let body = paramType.base
  1041. if body.kind in {tyForward, tyError}:
  1042. # this may happen for proc type appearing in a type section
  1043. # before one of its param types
  1044. return
  1045. if body.lastSon.kind == tyUserTypeClass:
  1046. let expanded = instGenericContainer(c, info, paramType,
  1047. allowMetaTypes = true)
  1048. result = recurse(expanded, true)
  1049. of tyUserTypeClasses, tyBuiltInTypeClass, tyCompositeTypeClass,
  1050. tyAnd, tyOr, tyNot:
  1051. result = addImplicitGeneric(c,
  1052. copyType(paramType, getCurrOwner(c), false), paramTypId,
  1053. info, genericParams, paramName)
  1054. of tyGenericParam:
  1055. markUsed(c, paramType.sym.info, paramType.sym)
  1056. onUse(paramType.sym.info, paramType.sym)
  1057. if tfWildcard in paramType.flags:
  1058. paramType.flags.excl tfWildcard
  1059. paramType.sym.transitionGenericParamToType()
  1060. else: discard
  1061. proc semParamType(c: PContext, n: PNode, constraint: var PNode): PType =
  1062. if n.kind == nkCurlyExpr:
  1063. result = semTypeNode(c, n[0], nil)
  1064. constraint = semNodeKindConstraints(n, c.config, 1)
  1065. elif n.kind == nkCall and
  1066. n[0].kind in {nkIdent, nkSym, nkOpenSymChoice, nkClosedSymChoice} and
  1067. considerQuotedIdent(c, n[0]).s == "{}":
  1068. result = semTypeNode(c, n[1], nil)
  1069. constraint = semNodeKindConstraints(n, c.config, 2)
  1070. else:
  1071. result = semTypeNode(c, n, nil)
  1072. proc newProcType(c: PContext; info: TLineInfo; prev: PType = nil): PType =
  1073. result = newOrPrevType(tyProc, prev, c)
  1074. result.callConv = lastOptionEntry(c).defaultCC
  1075. result.n = newNodeI(nkFormalParams, info)
  1076. rawAddSon(result, nil) # return type
  1077. # result.n[0] used to be `nkType`, but now it's `nkEffectList` because
  1078. # the effects are now stored in there too ... this is a bit hacky, but as
  1079. # usual we desperately try to save memory:
  1080. result.n.add newNodeI(nkEffectList, info)
  1081. proc isMagic(sym: PSym): bool =
  1082. let nPragmas = sym.ast[pragmasPos]
  1083. return hasPragma(nPragmas, wMagic)
  1084. proc semProcTypeNode(c: PContext, n, genericParams: PNode,
  1085. prev: PType, kind: TSymKind; isType=false): PType =
  1086. # for historical reasons (code grows) this is invoked for parameter
  1087. # lists too and then 'isType' is false.
  1088. checkMinSonsLen(n, 1, c.config)
  1089. result = newProcType(c, n.info, prev)
  1090. var check = initIntSet()
  1091. var counter = 0
  1092. for i in 1..<n.len:
  1093. var a = n[i]
  1094. if a.kind != nkIdentDefs:
  1095. # for some generic instantiations the passed ':env' parameter
  1096. # for closures has already been produced (see bug #898). We simply
  1097. # skip this parameter here. It'll then be re-generated in another LL
  1098. # pass over this instantiation:
  1099. if a.kind == nkSym and sfFromGeneric in a.sym.flags: continue
  1100. illFormedAst(a, c.config)
  1101. checkMinSonsLen(a, 3, c.config)
  1102. var
  1103. typ: PType = nil
  1104. def: PNode = nil
  1105. constraint: PNode = nil
  1106. hasType = a[^2].kind != nkEmpty
  1107. hasDefault = a[^1].kind != nkEmpty
  1108. if hasType:
  1109. typ = semParamType(c, a[^2], constraint)
  1110. let sym = getCurrOwner(c)
  1111. var owner = sym.owner
  1112. # TODO: Disallow typed/untyped in procs in the compiler/stdlib
  1113. if kind == skProc and (typ.kind == tyTyped or typ.kind == tyUntyped):
  1114. if not isMagic(sym):
  1115. localError(c.config, a[^2].info, "'" & typ.sym.name.s & "' is only allowed in templates and macros or magic procs")
  1116. if hasDefault:
  1117. def = a[^1]
  1118. block determineType:
  1119. if genericParams != nil and genericParams.len > 0:
  1120. def = semGenericStmt(c, def)
  1121. if hasUnresolvedArgs(c, def):
  1122. def.typ = makeTypeFromExpr(c, def.copyTree)
  1123. break determineType
  1124. def = semExprWithType(c, def, {efDetermineType})
  1125. if def.referencesAnotherParam(getCurrOwner(c)):
  1126. def.flags.incl nfDefaultRefsParam
  1127. if typ == nil:
  1128. typ = def.typ
  1129. if isEmptyContainer(typ):
  1130. localError(c.config, a.info, "cannot infer the type of parameter '" & a[0].ident.s & "'")
  1131. if typ.kind == tyTypeDesc:
  1132. # consider a proc such as:
  1133. # proc takesType(T = int)
  1134. # a naive analysis may conclude that the proc type is type[int]
  1135. # which will prevent other types from matching - clearly a very
  1136. # surprising behavior. We must instead fix the expected type of
  1137. # the proc to be the unbound typedesc type:
  1138. typ = newTypeWithSons(c, tyTypeDesc, @[newTypeS(tyNone, c)])
  1139. typ.flags.incl tfCheckedForDestructor
  1140. else:
  1141. # if def.typ != nil and def.typ.kind != tyNone:
  1142. # example code that triggers it:
  1143. # proc sort[T](cmp: proc(a, b: T): int = cmp)
  1144. if not containsGenericType(typ):
  1145. # check type compatibility between def.typ and typ:
  1146. def = fitNode(c, typ, def, def.info)
  1147. elif typ.kind == tyStatic:
  1148. def = semConstExpr(c, def)
  1149. def = fitNode(c, typ, def, def.info)
  1150. if not hasType and not hasDefault:
  1151. if isType: localError(c.config, a.info, "':' expected")
  1152. if kind in {skTemplate, skMacro}:
  1153. typ = newTypeS(tyUntyped, c)
  1154. elif skipTypes(typ, {tyGenericInst, tyAlias, tySink}).kind == tyVoid:
  1155. continue
  1156. for j in 0..<a.len-2:
  1157. var arg = newSymG(skParam, a[j], c)
  1158. if not hasType and not hasDefault and kind notin {skTemplate, skMacro}:
  1159. let param = strTableGet(c.signatures, arg.name)
  1160. if param != nil: typ = param.typ
  1161. else:
  1162. localError(c.config, a.info, "typeless parameters are obsolete")
  1163. typ = errorType(c)
  1164. let lifted = liftParamType(c, kind, genericParams, typ,
  1165. arg.name.s, arg.info)
  1166. let finalType = if lifted != nil: lifted else: typ.skipIntLit
  1167. arg.typ = finalType
  1168. arg.position = counter
  1169. arg.constraint = constraint
  1170. inc(counter)
  1171. if def != nil and def.kind != nkEmpty:
  1172. arg.ast = copyTree(def)
  1173. if containsOrIncl(check, arg.name.id):
  1174. localError(c.config, a[j].info, "attempt to redefine: '" & arg.name.s & "'")
  1175. result.n.add newSymNode(arg)
  1176. rawAddSon(result, finalType)
  1177. addParamOrResult(c, arg, kind)
  1178. styleCheckDef(c.config, a[j].info, arg)
  1179. onDef(a[j].info, arg)
  1180. var r: PType
  1181. if n[0].kind != nkEmpty:
  1182. r = semTypeNode(c, n[0], nil)
  1183. if r != nil and kind in {skMacro, skTemplate} and r.kind == tyTyped:
  1184. # XXX: To implement the propesed change in the warning, just
  1185. # delete this entire if block. The rest is (at least at time of
  1186. # writing this comment) already implemented.
  1187. let info = n[0].info
  1188. const msg = "`typed` will change its meaning in future versions of Nim. " &
  1189. "`void` or no return type declaration at all has the same " &
  1190. "meaning as the current meaning of `typed` as return type " &
  1191. "declaration."
  1192. message(c.config, info, warnDeprecated, msg)
  1193. r = nil
  1194. if r != nil:
  1195. # turn explicit 'void' return type into 'nil' because the rest of the
  1196. # compiler only checks for 'nil':
  1197. if skipTypes(r, {tyGenericInst, tyAlias, tySink}).kind != tyVoid:
  1198. if kind notin {skMacro, skTemplate} and r.kind in {tyTyped, tyUntyped}:
  1199. localError(c.config, n[0].info, "return type '" & typeToString(r) &
  1200. "' is only valid for macros and templates")
  1201. # 'auto' as a return type does not imply a generic:
  1202. elif r.kind == tyAnything:
  1203. # 'p(): auto' and 'p(): expr' are equivalent, but the rest of the
  1204. # compiler is hardly aware of 'auto':
  1205. r = newTypeS(tyUntyped, c)
  1206. elif r.kind == tyStatic:
  1207. # type allowed should forbid this type
  1208. discard
  1209. else:
  1210. if r.sym == nil or sfAnon notin r.sym.flags:
  1211. let lifted = liftParamType(c, kind, genericParams, r, "result",
  1212. n[0].info)
  1213. if lifted != nil:
  1214. r = lifted
  1215. #if r.kind != tyGenericParam:
  1216. #echo "came here for ", typeToString(r)
  1217. r.flags.incl tfRetType
  1218. r = skipIntLit(r)
  1219. if kind == skIterator:
  1220. # see tchainediterators
  1221. # in cases like iterator foo(it: iterator): type(it)
  1222. # we don't need to change the return type to iter[T]
  1223. result.flags.incl tfIterator
  1224. # XXX Would be nice if we could get rid of this
  1225. result[0] = r
  1226. let oldFlags = result.flags
  1227. propagateToOwner(result, r)
  1228. if oldFlags != result.flags:
  1229. # XXX This rather hacky way keeps 'tflatmap' compiling:
  1230. if tfHasMeta notin oldFlags:
  1231. result.flags.excl tfHasMeta
  1232. result.n.typ = r
  1233. if genericParams != nil and genericParams.len > 0:
  1234. for n in genericParams:
  1235. if {sfUsed, sfAnon} * n.sym.flags == {}:
  1236. result.flags.incl tfUnresolved
  1237. if tfWildcard in n.sym.typ.flags:
  1238. n.sym.transitionGenericParamToType()
  1239. n.sym.typ.flags.excl tfWildcard
  1240. proc semStmtListType(c: PContext, n: PNode, prev: PType): PType =
  1241. checkMinSonsLen(n, 1, c.config)
  1242. for i in 0..<n.len - 1:
  1243. n[i] = semStmt(c, n[i], {})
  1244. if n.len > 0:
  1245. result = semTypeNode(c, n[^1], prev)
  1246. n.typ = result
  1247. n[^1].typ = result
  1248. else:
  1249. result = nil
  1250. proc semBlockType(c: PContext, n: PNode, prev: PType): PType =
  1251. inc(c.p.nestedBlockCounter)
  1252. checkSonsLen(n, 2, c.config)
  1253. openScope(c)
  1254. if n[0].kind notin {nkEmpty, nkSym}:
  1255. addDecl(c, newSymS(skLabel, n[0], c))
  1256. result = semStmtListType(c, n[1], prev)
  1257. n[1].typ = result
  1258. n.typ = result
  1259. closeScope(c)
  1260. dec(c.p.nestedBlockCounter)
  1261. proc semGenericParamInInvocation(c: PContext, n: PNode): PType =
  1262. result = semTypeNode(c, n, nil)
  1263. n.typ = makeTypeDesc(c, result)
  1264. proc semObjectTypeForInheritedGenericInst(c: PContext, n: PNode, t: PType) =
  1265. var
  1266. check = initIntSet()
  1267. pos = 0
  1268. let
  1269. realBase = t[0]
  1270. base = skipTypesOrNil(realBase, skipPtrs)
  1271. if base.isNil:
  1272. localError(c.config, n.info, errIllegalRecursionInTypeX % "object")
  1273. else:
  1274. let concreteBase = skipGenericInvocation(base)
  1275. if concreteBase.kind == tyObject and tfFinal notin concreteBase.flags:
  1276. addInheritedFields(c, check, pos, concreteBase)
  1277. else:
  1278. if concreteBase.kind != tyError:
  1279. localError(c.config, n.info, errInheritanceOnlyWithNonFinalObjects)
  1280. var newf = newNodeI(nkRecList, n.info)
  1281. semRecordNodeAux(c, t.n, check, pos, newf, t)
  1282. proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
  1283. if s.typ == nil:
  1284. localError(c.config, n.info, "cannot instantiate the '$1' $2" %
  1285. [s.name.s, ($s.kind).substr(2).toLowerAscii])
  1286. return newOrPrevType(tyError, prev, c)
  1287. var t = s.typ
  1288. if t.kind in {tyCompositeTypeClass, tyAlias} and t.base.kind == tyGenericBody:
  1289. t = t.base
  1290. result = newOrPrevType(tyGenericInvocation, prev, c)
  1291. addSonSkipIntLit(result, t)
  1292. template addToResult(typ) =
  1293. if typ.isNil:
  1294. internalAssert c.config, false
  1295. rawAddSon(result, typ)
  1296. else: addSonSkipIntLit(result, typ)
  1297. if t.kind == tyForward:
  1298. for i in 1..<n.len:
  1299. var elem = semGenericParamInInvocation(c, n[i])
  1300. addToResult(elem)
  1301. return
  1302. elif t.kind != tyGenericBody:
  1303. # we likely got code of the form TypeA[TypeB] where TypeA is
  1304. # not generic.
  1305. localError(c.config, n.info, errNoGenericParamsAllowedForX % s.name.s)
  1306. return newOrPrevType(tyError, prev, c)
  1307. else:
  1308. var m = newCandidate(c, t)
  1309. m.isNoCall = true
  1310. matches(c, n, copyTree(n), m)
  1311. if m.state != csMatch:
  1312. let err = "cannot instantiate " & typeToString(t) & "\n" &
  1313. "got: <" & describeArgs(c, n) & ">\n" &
  1314. "but expected: <" & describeArgs(c, t.n, 0) & ">"
  1315. localError(c.config, n.info, errGenerated, err)
  1316. return newOrPrevType(tyError, prev, c)
  1317. var isConcrete = true
  1318. for i in 1..<m.call.len:
  1319. var typ = m.call[i].typ
  1320. # is this a 'typedesc' *parameter*? If so, use the typedesc type,
  1321. # unstripped.
  1322. if m.call[i].kind == nkSym and m.call[i].sym.kind == skParam and
  1323. typ.kind == tyTypeDesc and containsGenericType(typ):
  1324. isConcrete = false
  1325. addToResult(typ)
  1326. else:
  1327. typ = typ.skipTypes({tyTypeDesc})
  1328. if containsGenericType(typ): isConcrete = false
  1329. addToResult(typ)
  1330. if isConcrete:
  1331. if s.ast == nil and s.typ.kind != tyCompositeTypeClass:
  1332. # XXX: What kind of error is this? is it still relevant?
  1333. localError(c.config, n.info, errCannotInstantiateX % s.name.s)
  1334. result = newOrPrevType(tyError, prev, c)
  1335. else:
  1336. result = instGenericContainer(c, n.info, result,
  1337. allowMetaTypes = false)
  1338. # special check for generic object with
  1339. # generic/partial specialized parent
  1340. let tx = result.skipTypes(abstractPtrs, 50)
  1341. if tx.isNil or isTupleRecursive(tx):
  1342. localError(c.config, n.info, "illegal recursion in type '$1'" % typeToString(result[0]))
  1343. return errorType(c)
  1344. if tx != result and tx.kind == tyObject:
  1345. if tx[0] != nil:
  1346. semObjectTypeForInheritedGenericInst(c, n, tx)
  1347. var position = 0
  1348. recomputeFieldPositions(tx, tx.n, position)
  1349. proc maybeAliasType(c: PContext; typeExpr, prev: PType): PType =
  1350. if typeExpr.kind in {tyObject, tyEnum, tyDistinct, tyForward, tyGenericBody} and prev != nil:
  1351. result = newTypeS(tyAlias, c)
  1352. result.rawAddSon typeExpr
  1353. result.sym = prev.sym
  1354. assignType(prev, result)
  1355. proc fixupTypeOf(c: PContext, prev: PType, typExpr: PNode) =
  1356. if prev != nil:
  1357. let result = newTypeS(tyAlias, c)
  1358. result.rawAddSon typExpr.typ
  1359. result.sym = prev.sym
  1360. assignType(prev, result)
  1361. proc semTypeExpr(c: PContext, n: PNode; prev: PType): PType =
  1362. var n = semExprWithType(c, n, {efDetermineType})
  1363. if n.typ.kind == tyTypeDesc:
  1364. result = n.typ.base
  1365. # fix types constructed by macros/template:
  1366. if prev != nil and prev.sym != nil:
  1367. if result.sym.isNil:
  1368. # Behold! you're witnessing enormous power yielded
  1369. # by macros. Only macros can summon unnamed types
  1370. # and cast spell upon AST. Here we need to give
  1371. # it a name taken from left hand side's node
  1372. result.sym = prev.sym
  1373. result.sym.typ = result
  1374. else:
  1375. # Less powerful routine like template do not have
  1376. # the ability to produce unnamed types. But still
  1377. # it has wild power to push a type a bit too far.
  1378. # So we need to hold it back using alias and prevent
  1379. # unnecessary new type creation
  1380. let alias = maybeAliasType(c, result, prev)
  1381. if alias != nil: result = alias
  1382. else:
  1383. localError(c.config, n.info, "expected type, but got: " & n.renderTree)
  1384. result = errorType(c)
  1385. proc freshType(res, prev: PType): PType {.inline.} =
  1386. if prev.isNil:
  1387. result = copyType(res, res.owner, keepId=false)
  1388. else:
  1389. result = res
  1390. template modifierTypeKindOfNode(n: PNode): TTypeKind =
  1391. case n.kind
  1392. of nkVarTy: tyVar
  1393. of nkRefTy: tyRef
  1394. of nkPtrTy: tyPtr
  1395. of nkStaticTy: tyStatic
  1396. of nkTypeOfExpr: tyTypeDesc
  1397. else: tyNone
  1398. proc semTypeClass(c: PContext, n: PNode, prev: PType): PType =
  1399. # if n.len == 0: return newConstraint(c, tyTypeClass)
  1400. let
  1401. pragmas = n[1]
  1402. inherited = n[2]
  1403. result = newOrPrevType(tyUserTypeClass, prev, c)
  1404. result.flags.incl tfCheckedForDestructor
  1405. var owner = getCurrOwner(c)
  1406. var candidateTypeSlot = newTypeWithSons(owner, tyAlias, @[c.errorType])
  1407. result.sons = @[candidateTypeSlot]
  1408. result.n = n
  1409. if inherited.kind != nkEmpty:
  1410. for n in inherited.sons:
  1411. let typ = semTypeNode(c, n, nil)
  1412. result.add(typ)
  1413. openScope(c)
  1414. for param in n[0]:
  1415. var
  1416. dummyName: PNode
  1417. dummyType: PType
  1418. let modifier = param.modifierTypeKindOfNode
  1419. if modifier != tyNone:
  1420. dummyName = param[0]
  1421. dummyType = c.makeTypeWithModifier(modifier, candidateTypeSlot)
  1422. if modifier == tyTypeDesc:
  1423. dummyType.flags.incl tfConceptMatchedTypeSym
  1424. dummyType.flags.incl tfCheckedForDestructor
  1425. else:
  1426. dummyName = param
  1427. dummyType = candidateTypeSlot
  1428. # this can be true for 'nim check' on incomplete concepts,
  1429. # see bug #8230
  1430. if dummyName.kind == nkEmpty: continue
  1431. internalAssert c.config, dummyName.kind == nkIdent
  1432. var dummyParam = newSym(if modifier == tyTypeDesc: skType else: skVar,
  1433. dummyName.ident, owner, param.info)
  1434. dummyParam.typ = dummyType
  1435. incl dummyParam.flags, sfUsed
  1436. addDecl(c, dummyParam)
  1437. result.n[3] = semConceptBody(c, n[3])
  1438. closeScope(c)
  1439. proc applyTypeSectionPragmas(c: PContext; pragmas, operand: PNode): PNode =
  1440. for p in pragmas:
  1441. let key = if p.kind in nkPragmaCallKinds and p.len >= 1: p[0] else: p
  1442. if p.kind == nkEmpty or whichPragma(p) != wInvalid:
  1443. discard "builtin pragma"
  1444. else:
  1445. let ident = considerQuotedIdent(c, key)
  1446. if strTableGet(c.userPragmas, ident) != nil:
  1447. discard "User-defined pragma"
  1448. else:
  1449. let sym = searchInScopes(c, ident)
  1450. if sym != nil and sfCustomPragma in sym.flags:
  1451. discard "Custom user pragma"
  1452. else:
  1453. # we transform ``(arg1, arg2: T) {.m, rest.}`` into ``m((arg1, arg2: T) {.rest.})`` and
  1454. # let the semantic checker deal with it:
  1455. var x = newNodeI(nkCall, key.info)
  1456. x.add(key)
  1457. if p.kind in nkPragmaCallKinds and p.len > 1:
  1458. # pass pragma arguments to the macro too:
  1459. for i in 1 ..< p.len:
  1460. x.add(p[i])
  1461. # Also pass the node the pragma has been applied to
  1462. x.add(operand.copyTreeWithoutNode(p))
  1463. # recursion assures that this works for multiple macro annotations too:
  1464. var r = semOverloadedCall(c, x, x, {skMacro, skTemplate}, {efNoUndeclared})
  1465. if r != nil:
  1466. doAssert r[0].kind == nkSym
  1467. let m = r[0].sym
  1468. case m.kind
  1469. of skMacro: return semMacroExpr(c, r, r, m, {efNoSemCheck})
  1470. of skTemplate: return semTemplateExpr(c, r, m, {efNoSemCheck})
  1471. else: doAssert(false, "cannot happen")
  1472. proc semProcTypeWithScope(c: PContext, n: PNode,
  1473. prev: PType, kind: TSymKind): PType =
  1474. checkSonsLen(n, 2, c.config)
  1475. if n[1].kind != nkEmpty and n[1].len > 0:
  1476. let macroEval = applyTypeSectionPragmas(c, n[1], n)
  1477. if macroEval != nil:
  1478. return semTypeNode(c, macroEval, prev)
  1479. openScope(c)
  1480. result = semProcTypeNode(c, n[0], nil, prev, kind, isType=true)
  1481. # start with 'ccClosure', but of course pragmas can overwrite this:
  1482. result.callConv = ccClosure
  1483. # dummy symbol for `pragma`:
  1484. var s = newSymS(kind, newIdentNode(getIdent(c.cache, "dummy"), n.info), c)
  1485. s.typ = result
  1486. if n[1].kind != nkEmpty and n[1].len > 0:
  1487. pragma(c, s, n[1], procTypePragmas)
  1488. when useEffectSystem: setEffectsForProcType(c.graph, result, n[1])
  1489. elif c.optionStack.len > 0 and optNimV1Emulation notin c.config.globalOptions:
  1490. # we construct a fake 'nkProcDef' for the 'mergePragmas' inside 'implicitPragmas'...
  1491. s.ast = newTree(nkProcDef, newNodeI(nkEmpty, n.info), newNodeI(nkEmpty, n.info),
  1492. newNodeI(nkEmpty, n.info), newNodeI(nkEmpty, n.info), newNodeI(nkEmpty, n.info))
  1493. implicitPragmas(c, s, n, {wTags, wRaises})
  1494. when useEffectSystem: setEffectsForProcType(c.graph, result, s.ast[pragmasPos])
  1495. closeScope(c)
  1496. proc symFromExpectedTypeNode(c: PContext, n: PNode): PSym =
  1497. if n.kind == nkType:
  1498. result = symFromType(c, n.typ, n.info)
  1499. else:
  1500. localError(c.config, n.info, errTypeExpected)
  1501. result = errorSym(c, n)
  1502. proc semStaticType(c: PContext, childNode: PNode, prev: PType): PType =
  1503. result = newOrPrevType(tyStatic, prev, c)
  1504. var base = semTypeNode(c, childNode, nil).skipTypes({tyTypeDesc, tyAlias})
  1505. result.rawAddSon(base)
  1506. result.flags.incl tfHasStatic
  1507. proc semTypeof(c: PContext; n: PNode; prev: PType): PType =
  1508. openScope(c)
  1509. let t = semExprWithType(c, n, {efInTypeof})
  1510. closeScope(c)
  1511. fixupTypeOf(c, prev, t)
  1512. result = t.typ
  1513. proc semTypeof2(c: PContext; n: PNode; prev: PType): PType =
  1514. openScope(c)
  1515. var m = BiggestInt 1 # typeOfIter
  1516. if n.len == 3:
  1517. let mode = semConstExpr(c, n[2])
  1518. if mode.kind != nkIntLit:
  1519. localError(c.config, n.info, "typeof: cannot evaluate 'mode' parameter at compile-time")
  1520. else:
  1521. m = mode.intVal
  1522. let t = semExprWithType(c, n[1], if m == 1: {efInTypeof} else: {})
  1523. closeScope(c)
  1524. fixupTypeOf(c, prev, t)
  1525. result = t.typ
  1526. proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
  1527. result = nil
  1528. inc c.inTypeContext
  1529. if c.config.cmd == cmdIdeTools: suggestExpr(c, n)
  1530. case n.kind
  1531. of nkEmpty: result = n.typ
  1532. of nkTypeOfExpr:
  1533. # for ``type(countup(1,3))``, see ``tests/ttoseq``.
  1534. checkSonsLen(n, 1, c.config)
  1535. result = semTypeof(c, n[0], prev)
  1536. if result.kind == tyTypeDesc: result.flags.incl tfExplicit
  1537. of nkPar:
  1538. if n.len == 1: result = semTypeNode(c, n[0], prev)
  1539. else:
  1540. result = semAnonTuple(c, n, prev)
  1541. of nkTupleConstr: result = semAnonTuple(c, n, prev)
  1542. of nkCallKinds:
  1543. let x = n[0]
  1544. let ident = case x.kind
  1545. of nkIdent: x.ident
  1546. of nkSym: x.sym.name
  1547. of nkClosedSymChoice, nkOpenSymChoice: x[0].sym.name
  1548. else: nil
  1549. if ident != nil and ident.s == "[]":
  1550. let b = newNodeI(nkBracketExpr, n.info)
  1551. for i in 1..<n.len: b.add(n[i])
  1552. result = semTypeNode(c, b, prev)
  1553. elif ident != nil and ident.id == ord(wDotDot):
  1554. result = semRangeAux(c, n, prev)
  1555. elif n[0].kind == nkNilLit and n.len == 2:
  1556. result = semTypeNode(c, n[1], prev)
  1557. if result.skipTypes({tyGenericInst, tyAlias, tySink, tyOwned}).kind in NilableTypes+GenericTypes:
  1558. if tfNotNil in result.flags:
  1559. result = freshType(result, prev)
  1560. result.flags.excl(tfNotNil)
  1561. else:
  1562. localError(c.config, n.info, errGenerated, "invalid type")
  1563. elif n[0].kind notin nkIdentKinds:
  1564. result = semTypeExpr(c, n, prev)
  1565. else:
  1566. let op = considerQuotedIdent(c, n[0])
  1567. if op.id in {ord(wAnd), ord(wOr)} or op.s == "|":
  1568. checkSonsLen(n, 3, c.config)
  1569. var
  1570. t1 = semTypeNode(c, n[1], nil)
  1571. t2 = semTypeNode(c, n[2], nil)
  1572. if t1 == nil:
  1573. localError(c.config, n[1].info, errTypeExpected)
  1574. result = newOrPrevType(tyError, prev, c)
  1575. elif t2 == nil:
  1576. localError(c.config, n[2].info, errTypeExpected)
  1577. result = newOrPrevType(tyError, prev, c)
  1578. else:
  1579. result = if op.id == ord(wAnd): makeAndType(c, t1, t2)
  1580. else: makeOrType(c, t1, t2)
  1581. elif op.id == ord(wNot):
  1582. case n.len
  1583. of 3:
  1584. result = semTypeNode(c, n[1], prev)
  1585. if result.kind == tyTypeDesc and tfUnresolved notin result.flags:
  1586. result = result.base
  1587. if n[2].kind != nkNilLit:
  1588. localError(c.config, n.info,
  1589. "Invalid syntax. When used with a type, 'not' can be followed only by 'nil'")
  1590. if notnil notin c.features:
  1591. localError(c.config, n.info,
  1592. "enable the 'not nil' annotation with {.experimental: \"notnil\".}")
  1593. let resolvedType = result.skipTypes({tyGenericInst, tyAlias, tySink, tyOwned})
  1594. case resolvedType.kind
  1595. of tyGenericParam, tyTypeDesc, tyFromExpr:
  1596. # XXX: This is a really inappropraite hack, but it solves
  1597. # https://github.com/nim-lang/Nim/issues/4907 for now.
  1598. #
  1599. # A proper solution is to introduce a new type kind such
  1600. # as `tyNotNil[tyRef[SomeGenericParam]]`. This will allow
  1601. # semtypinst to replace the generic param correctly in
  1602. # situations like the following:
  1603. #
  1604. # type Foo[T] = object
  1605. # bar: ref T not nil
  1606. # baz: ref T
  1607. #
  1608. # The root of the problem is that `T` here must have a specific
  1609. # ID that is bound to a concrete type during instantiation.
  1610. # The use of `freshType` below breaks this. Another hack would
  1611. # be to reuse the same ID for the not nil type, but this will
  1612. # fail if the `T` parameter is referenced multiple times as in
  1613. # the example above.
  1614. #
  1615. # I suggest revisiting this once the language decides on whether
  1616. # `not nil` should be the default. We can then map nilable refs
  1617. # to other types such as `Option[T]`.
  1618. result = makeTypeFromExpr(c, newTree(nkStmtListType, n.copyTree))
  1619. of NilableTypes + {tyGenericInvocation, tyForward}:
  1620. result = freshType(result, prev)
  1621. result.flags.incl(tfNotNil)
  1622. else:
  1623. localError(c.config, n.info, errGenerated, "invalid type")
  1624. of 2:
  1625. let negated = semTypeNode(c, n[1], prev)
  1626. result = makeNotType(c, negated)
  1627. else:
  1628. localError(c.config, n.info, errGenerated, "invalid type")
  1629. elif op.id == ord(wPtr):
  1630. result = semAnyRef(c, n, tyPtr, prev)
  1631. elif op.id == ord(wRef):
  1632. result = semAnyRef(c, n, tyRef, prev)
  1633. elif op.id == ord(wType):
  1634. checkSonsLen(n, 2, c.config)
  1635. result = semTypeof(c, n[1], prev)
  1636. elif op.s == "typeof" and n[0].kind == nkSym and n[0].sym.magic == mTypeOf:
  1637. result = semTypeof2(c, n, prev)
  1638. elif op.s == "owned" and optOwnedRefs notin c.config.globalOptions and n.len == 2:
  1639. result = semTypeExpr(c, n[1], prev)
  1640. else:
  1641. if c.inGenericContext > 0 and n.kind == nkCall:
  1642. result = makeTypeFromExpr(c, n.copyTree)
  1643. else:
  1644. result = semTypeExpr(c, n, prev)
  1645. of nkWhenStmt:
  1646. var whenResult = semWhen(c, n, false)
  1647. if whenResult.kind == nkStmtList: whenResult.transitionSonsKind(nkStmtListType)
  1648. result = semTypeNode(c, whenResult, prev)
  1649. of nkBracketExpr:
  1650. checkMinSonsLen(n, 2, c.config)
  1651. var head = n[0]
  1652. var s = if head.kind notin nkCallKinds: semTypeIdent(c, head)
  1653. else: symFromExpectedTypeNode(c, semExpr(c, head))
  1654. case s.magic
  1655. of mArray: result = semArray(c, n, prev)
  1656. of mOpenArray: result = semContainer(c, n, tyOpenArray, "openarray", prev)
  1657. of mUncheckedArray: result = semContainer(c, n, tyUncheckedArray, "UncheckedArray", prev)
  1658. of mRange: result = semRange(c, n, prev)
  1659. of mSet: result = semSet(c, n, prev)
  1660. of mOrdinal: result = semOrdinal(c, n, prev)
  1661. of mSeq:
  1662. result = semContainer(c, n, tySequence, "seq", prev)
  1663. if optSeqDestructors in c.config.globalOptions:
  1664. incl result.flags, tfHasAsgn
  1665. of mOpt: result = semContainer(c, n, tyOpt, "opt", prev)
  1666. of mVarargs: result = semVarargs(c, n, prev)
  1667. of mTypeDesc, mType, mTypeOf:
  1668. result = makeTypeDesc(c, semTypeNode(c, n[1], nil))
  1669. result.flags.incl tfExplicit
  1670. of mStatic:
  1671. result = semStaticType(c, n[1], prev)
  1672. of mExpr:
  1673. result = semTypeNode(c, n[0], nil)
  1674. if result != nil:
  1675. result = copyType(result, getCurrOwner(c), false)
  1676. for i in 1..<n.len:
  1677. result.rawAddSon(semTypeNode(c, n[i], nil))
  1678. of mDistinct:
  1679. result = newOrPrevType(tyDistinct, prev, c)
  1680. addSonSkipIntLit(result, semTypeNode(c, n[1], nil))
  1681. of mVar:
  1682. result = newOrPrevType(tyVar, prev, c)
  1683. var base = semTypeNode(c, n[1], nil)
  1684. if base.kind in {tyVar, tyLent}:
  1685. localError(c.config, n.info, "type 'var var' is not allowed")
  1686. base = base[0]
  1687. addSonSkipIntLit(result, base)
  1688. of mRef: result = semAnyRef(c, n, tyRef, prev)
  1689. of mPtr: result = semAnyRef(c, n, tyPtr, prev)
  1690. of mTuple: result = semTuple(c, n, prev)
  1691. else: result = semGeneric(c, n, s, prev)
  1692. of nkDotExpr:
  1693. let typeExpr = semExpr(c, n)
  1694. if typeExpr.typ.isNil:
  1695. localError(c.config, n.info, "object constructor needs an object type;" &
  1696. " for named arguments use '=' instead of ':'")
  1697. result = errorType(c)
  1698. elif typeExpr.typ.kind == tyFromExpr:
  1699. result = typeExpr.typ
  1700. elif typeExpr.typ.kind != tyTypeDesc:
  1701. localError(c.config, n.info, errTypeExpected)
  1702. result = errorType(c)
  1703. else:
  1704. result = typeExpr.typ.base
  1705. if result.isMetaType and
  1706. result.kind != tyUserTypeClass:
  1707. # the dot expression may refer to a concept type in
  1708. # a different module. allow a normal alias then.
  1709. let preprocessed = semGenericStmt(c, n)
  1710. result = makeTypeFromExpr(c, preprocessed.copyTree)
  1711. else:
  1712. let alias = maybeAliasType(c, result, prev)
  1713. if alias != nil: result = alias
  1714. of nkIdent, nkAccQuoted:
  1715. var s = semTypeIdent(c, n)
  1716. if s.typ == nil:
  1717. if s.kind != skError: localError(c.config, n.info, errTypeExpected)
  1718. result = newOrPrevType(tyError, prev, c)
  1719. elif s.kind == skParam and s.typ.kind == tyTypeDesc:
  1720. internalAssert c.config, s.typ.base.kind != tyNone and prev == nil
  1721. result = s.typ.base
  1722. elif prev == nil:
  1723. result = s.typ
  1724. else:
  1725. let alias = maybeAliasType(c, s.typ, prev)
  1726. if alias != nil:
  1727. result = alias
  1728. else:
  1729. assignType(prev, s.typ)
  1730. # bugfix: keep the fresh id for aliases to integral types:
  1731. if s.typ.kind notin {tyBool, tyChar, tyInt..tyInt64, tyFloat..tyFloat128,
  1732. tyUInt..tyUInt64}:
  1733. prev.id = s.typ.id
  1734. result = prev
  1735. of nkSym:
  1736. let s = getGenSym(c, n.sym)
  1737. if s.typ != nil and (s.kind == skType or s.typ.kind == tyTypeDesc):
  1738. var t =
  1739. if s.kind == skType:
  1740. s.typ
  1741. else:
  1742. internalAssert c.config, s.typ.base.kind != tyNone and prev == nil
  1743. s.typ.base
  1744. let alias = maybeAliasType(c, t, prev)
  1745. if alias != nil:
  1746. result = alias
  1747. elif prev == nil:
  1748. result = t
  1749. else:
  1750. assignType(prev, t)
  1751. result = prev
  1752. markUsed(c, n.info, n.sym)
  1753. onUse(n.info, n.sym)
  1754. else:
  1755. if s.kind != skError:
  1756. if s.typ == nil:
  1757. localError(c.config, n.info, "type expected, but symbol '$1' has no type." % [s.name.s])
  1758. else:
  1759. localError(c.config, n.info, "type expected, but got symbol '$1' of kind '$2'" %
  1760. [s.name.s, substr($s.kind, 2)])
  1761. result = newOrPrevType(tyError, prev, c)
  1762. of nkObjectTy: result = semObjectNode(c, n, prev, isInheritable=false)
  1763. of nkTupleTy: result = semTuple(c, n, prev)
  1764. of nkTupleClassTy: result = newConstraint(c, tyTuple)
  1765. of nkTypeClassTy: result = semTypeClass(c, n, prev)
  1766. of nkRefTy: result = semAnyRef(c, n, tyRef, prev)
  1767. of nkPtrTy: result = semAnyRef(c, n, tyPtr, prev)
  1768. of nkVarTy: result = semVarType(c, n, prev)
  1769. of nkDistinctTy: result = semDistinct(c, n, prev)
  1770. of nkStaticTy: result = semStaticType(c, n[0], prev)
  1771. of nkIteratorTy:
  1772. if n.len == 0:
  1773. result = newTypeS(tyBuiltInTypeClass, c)
  1774. let child = newTypeS(tyProc, c)
  1775. child.flags.incl tfIterator
  1776. result.addSonSkipIntLit(child)
  1777. else:
  1778. result = semProcTypeWithScope(c, n, prev, skIterator)
  1779. if result.kind == tyProc:
  1780. result.flags.incl(tfIterator)
  1781. if n.lastSon.kind == nkPragma and hasPragma(n.lastSon, wInline):
  1782. result.callConv = ccInline
  1783. else:
  1784. result.callConv = ccClosure
  1785. of nkProcTy:
  1786. if n.len == 0:
  1787. result = newConstraint(c, tyProc)
  1788. else:
  1789. result = semProcTypeWithScope(c, n, prev, skProc)
  1790. of nkEnumTy: result = semEnum(c, n, prev)
  1791. of nkType: result = n.typ
  1792. of nkStmtListType: result = semStmtListType(c, n, prev)
  1793. of nkBlockType: result = semBlockType(c, n, prev)
  1794. else:
  1795. localError(c.config, n.info, "type expected, but got: " & renderTree(n))
  1796. result = newOrPrevType(tyError, prev, c)
  1797. n.typ = result
  1798. dec c.inTypeContext
  1799. if false: # c.inTypeContext == 0:
  1800. #if $n == "var seq[StackTraceEntry]":
  1801. # echo "begin ", n
  1802. instAllTypeBoundOp(c, n.info)
  1803. proc setMagicType(conf: ConfigRef; m: PSym, kind: TTypeKind, size: int) =
  1804. # source : https://en.wikipedia.org/wiki/Data_structure_alignment#x86
  1805. m.typ.kind = kind
  1806. m.typ.size = size
  1807. # this usually works for most basic types
  1808. # Assuming that since ARM, ARM64 don't support unaligned access
  1809. # data is aligned to type size
  1810. m.typ.align = size.int16
  1811. # FIXME: proper support for clongdouble should be added.
  1812. # long double size can be 8, 10, 12, 16 bytes depending on platform & compiler
  1813. if kind in {tyFloat64, tyFloat, tyInt, tyUInt, tyInt64, tyUInt64} and size == 8:
  1814. m.typ.align = int16(conf.floatInt64Align)
  1815. proc setMagicIntegral(conf: ConfigRef; m: PSym, kind: TTypeKind, size: int) =
  1816. setMagicType(conf, m, kind, size)
  1817. incl m.typ.flags, tfCheckedForDestructor
  1818. proc processMagicType(c: PContext, m: PSym) =
  1819. case m.magic
  1820. of mInt: setMagicIntegral(c.config, m, tyInt, c.config.target.intSize)
  1821. of mInt8: setMagicIntegral(c.config, m, tyInt8, 1)
  1822. of mInt16: setMagicIntegral(c.config, m, tyInt16, 2)
  1823. of mInt32: setMagicIntegral(c.config, m, tyInt32, 4)
  1824. of mInt64: setMagicIntegral(c.config, m, tyInt64, 8)
  1825. of mUInt: setMagicIntegral(c.config, m, tyUInt, c.config.target.intSize)
  1826. of mUInt8: setMagicIntegral(c.config, m, tyUInt8, 1)
  1827. of mUInt16: setMagicIntegral(c.config, m, tyUInt16, 2)
  1828. of mUInt32: setMagicIntegral(c.config, m, tyUInt32, 4)
  1829. of mUInt64: setMagicIntegral(c.config, m, tyUInt64, 8)
  1830. of mFloat: setMagicIntegral(c.config, m, tyFloat, c.config.target.floatSize)
  1831. of mFloat32: setMagicIntegral(c.config, m, tyFloat32, 4)
  1832. of mFloat64: setMagicIntegral(c.config, m, tyFloat64, 8)
  1833. of mFloat128: setMagicIntegral(c.config, m, tyFloat128, 16)
  1834. of mBool: setMagicIntegral(c.config, m, tyBool, 1)
  1835. of mChar: setMagicIntegral(c.config, m, tyChar, 1)
  1836. of mString:
  1837. setMagicType(c.config, m, tyString, szUncomputedSize)
  1838. rawAddSon(m.typ, getSysType(c.graph, m.info, tyChar))
  1839. if optSeqDestructors in c.config.globalOptions:
  1840. incl m.typ.flags, tfHasAsgn
  1841. of mCstring:
  1842. setMagicIntegral(c.config, m, tyCString, c.config.target.ptrSize)
  1843. rawAddSon(m.typ, getSysType(c.graph, m.info, tyChar))
  1844. of mPointer: setMagicIntegral(c.config, m, tyPointer, c.config.target.ptrSize)
  1845. of mNil: setMagicType(c.config, m, tyNil, c.config.target.ptrSize)
  1846. of mExpr:
  1847. if m.name.s == "auto":
  1848. setMagicIntegral(c.config, m, tyAnything, 0)
  1849. else:
  1850. setMagicIntegral(c.config, m, tyUntyped, 0)
  1851. of mStmt:
  1852. setMagicIntegral(c.config, m, tyTyped, 0)
  1853. of mTypeDesc, mType:
  1854. setMagicIntegral(c.config, m, tyTypeDesc, 0)
  1855. rawAddSon(m.typ, newTypeS(tyNone, c))
  1856. of mStatic:
  1857. setMagicType(c.config, m, tyStatic, 0)
  1858. rawAddSon(m.typ, newTypeS(tyNone, c))
  1859. of mVoidType:
  1860. setMagicIntegral(c.config, m, tyVoid, 0)
  1861. of mArray:
  1862. setMagicType(c.config, m, tyArray, szUncomputedSize)
  1863. of mOpenArray:
  1864. setMagicType(c.config, m, tyOpenArray, szUncomputedSize)
  1865. of mVarargs:
  1866. setMagicType(c.config, m, tyVarargs, szUncomputedSize)
  1867. of mRange:
  1868. setMagicIntegral(c.config, m, tyRange, szUncomputedSize)
  1869. rawAddSon(m.typ, newTypeS(tyNone, c))
  1870. of mSet:
  1871. setMagicIntegral(c.config, m, tySet, szUncomputedSize)
  1872. of mUncheckedArray:
  1873. setMagicIntegral(c.config, m, tyUncheckedArray, szUncomputedSize)
  1874. of mSeq:
  1875. setMagicType(c.config, m, tySequence, szUncomputedSize)
  1876. if optSeqDestructors in c.config.globalOptions:
  1877. incl m.typ.flags, tfHasAsgn
  1878. assert c.graph.sysTypes[tySequence] == nil
  1879. c.graph.sysTypes[tySequence] = m.typ
  1880. of mOrdinal:
  1881. setMagicIntegral(c.config, m, tyOrdinal, szUncomputedSize)
  1882. rawAddSon(m.typ, newTypeS(tyNone, c))
  1883. of mPNimrodNode:
  1884. incl m.typ.flags, tfTriggersCompileTime
  1885. incl m.typ.flags, tfCheckedForDestructor
  1886. of mException: discard
  1887. of mBuiltinType:
  1888. case m.name.s
  1889. of "lent": setMagicType(c.config, m, tyLent, c.config.target.ptrSize)
  1890. of "sink": setMagicType(c.config, m, tySink, szUncomputedSize)
  1891. of "owned":
  1892. setMagicType(c.config, m, tyOwned, c.config.target.ptrSize)
  1893. incl m.typ.flags, tfHasOwned
  1894. else: localError(c.config, m.info, errTypeExpected)
  1895. else: localError(c.config, m.info, errTypeExpected)
  1896. proc semGenericConstraints(c: PContext, x: PType): PType =
  1897. result = newTypeWithSons(c, tyGenericParam, @[x])
  1898. proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
  1899. result = copyNode(n)
  1900. if n.kind != nkGenericParams:
  1901. illFormedAst(n, c.config)
  1902. return
  1903. for i in 0..<n.len:
  1904. var a = n[i]
  1905. if a.kind != nkIdentDefs: illFormedAst(n, c.config)
  1906. var def = a[^1]
  1907. let constraint = a[^2]
  1908. var typ: PType
  1909. if constraint.kind != nkEmpty:
  1910. typ = semTypeNode(c, constraint, nil)
  1911. if typ.kind != tyStatic or typ.len == 0:
  1912. if typ.kind == tyTypeDesc:
  1913. if typ[0].kind == tyNone:
  1914. typ = newTypeWithSons(c, tyTypeDesc, @[newTypeS(tyNone, c)])
  1915. incl typ.flags, tfCheckedForDestructor
  1916. else:
  1917. typ = semGenericConstraints(c, typ)
  1918. if def.kind != nkEmpty:
  1919. def = semConstExpr(c, def)
  1920. if typ == nil:
  1921. if def.typ.kind != tyTypeDesc:
  1922. typ = newTypeWithSons(c, tyStatic, @[def.typ])
  1923. else:
  1924. # the following line fixes ``TV2*[T:SomeNumber=TR] = array[0..1, T]``
  1925. # from manyloc/named_argument_bug/triengine:
  1926. def.typ = def.typ.skipTypes({tyTypeDesc})
  1927. if not containsGenericType(def.typ):
  1928. def = fitNode(c, typ, def, def.info)
  1929. if typ == nil:
  1930. typ = newTypeS(tyGenericParam, c)
  1931. if father == nil: typ.flags.incl tfWildcard
  1932. typ.flags.incl tfGenericTypeParam
  1933. for j in 0..<a.len-2:
  1934. let finalType = if j == 0: typ
  1935. else: copyType(typ, typ.owner, false)
  1936. # it's important the we create an unique
  1937. # type for each generic param. the index
  1938. # of the parameter will be stored in the
  1939. # attached symbol.
  1940. var paramName = a[j]
  1941. var covarianceFlag = tfUnresolved
  1942. if paramName.safeLen == 2:
  1943. if not nimEnableCovariance or paramName[0].ident.s == "in":
  1944. if father == nil or sfImportc notin father.sym.flags:
  1945. localError(c.config, paramName.info, errInOutFlagNotExtern % $paramName[0])
  1946. covarianceFlag = if paramName[0].ident.s == "in": tfContravariant
  1947. else: tfCovariant
  1948. if father != nil: father.flags.incl tfCovariant
  1949. paramName = paramName[1]
  1950. var s = if finalType.kind == tyStatic or tfWildcard in typ.flags:
  1951. newSymG(skGenericParam, paramName, c).linkTo(finalType)
  1952. else:
  1953. newSymG(skType, paramName, c).linkTo(finalType)
  1954. if covarianceFlag != tfUnresolved: s.typ.flags.incl(covarianceFlag)
  1955. if def.kind != nkEmpty: s.ast = def
  1956. if father != nil: addSonSkipIntLit(father, s.typ)
  1957. s.position = result.len
  1958. result.add newSymNode(s)
  1959. if sfGenSym notin s.flags: addDecl(c, s)