semtypes.nim 76 KB

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