semtypinst.nim 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2015 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 instantiation of generic types.
  10. import std / tables
  11. import ast, astalgo, msgs, types, magicsys, semdata, renderer, options,
  12. lineinfos, modulegraphs, layeredtable
  13. when defined(nimPreviewSlimSystem):
  14. import std/assertions
  15. const tfInstClearedFlags = {tfHasMeta, tfUnresolved}
  16. proc checkPartialConstructedType(conf: ConfigRef; info: TLineInfo, t: PType) =
  17. if t.kind in {tyVar, tyLent} and t.elementType.kind in {tyVar, tyLent}:
  18. localError(conf, info, "type 'var var' is not allowed")
  19. proc checkConstructedType*(conf: ConfigRef; info: TLineInfo, typ: PType) =
  20. var t = typ.skipTypes({tyDistinct})
  21. if t.kind in tyTypeClasses: discard
  22. elif t.kind in {tyVar, tyLent} and t.elementType.kind in {tyVar, tyLent}:
  23. localError(conf, info, "type 'var var' is not allowed")
  24. elif computeSize(conf, t) == szIllegalRecursion or isTupleRecursive(t):
  25. localError(conf, info, "illegal recursion in type '" & typeToString(t) & "'")
  26. proc searchInstTypes*(g: ModuleGraph; key: PType): PType =
  27. result = nil
  28. let genericTyp = key[0]
  29. if not (genericTyp.kind == tyGenericBody and
  30. genericTyp.sym != nil): return
  31. for inst in typeInstCacheItems(g, genericTyp.sym):
  32. if inst.id == key.id: return inst
  33. if inst.kidsLen < key.kidsLen:
  34. # XXX: This happens for prematurely cached
  35. # types such as Channel[empty]. Why?
  36. # See the notes for PActor in handleGenericInvocation
  37. # if this is return the same type gets cached more than it needs to
  38. continue
  39. if not sameFlags(inst, key):
  40. continue
  41. block matchType:
  42. for j in FirstGenericParamAt..<key.kidsLen:
  43. # XXX sameType is not really correct for nested generics?
  44. if not compareTypes(inst[j], key[j],
  45. flags = {ExactGenericParams, PickyCAliases}):
  46. break matchType
  47. return inst
  48. proc cacheTypeInst(c: PContext; inst: PType) =
  49. let gt = inst[0]
  50. let t = if gt.kind == tyGenericBody: gt.typeBodyImpl else: gt
  51. if t.kind in {tyStatic, tyError, tyGenericParam} + tyTypeClasses:
  52. return
  53. addToGenericCache(c, gt.sym, inst)
  54. type
  55. TReplTypeVars* = object
  56. c*: PContext
  57. typeMap*: LayeredIdTable # map PType to PType
  58. symMap*: SymMapping # map PSym to PSym
  59. localCache*: TypeMapping # local cache for remembering already replaced
  60. # types during instantiation of meta types
  61. # (they are not stored in the global cache)
  62. info*: TLineInfo
  63. allowMetaTypes*: bool # allow types such as seq[Number]
  64. # i.e. the result contains unresolved generics
  65. skipTypedesc*: bool # whether we should skip typeDescs
  66. isReturnType*: bool
  67. owner*: PSym # where this instantiation comes from
  68. recursionLimit: int
  69. proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType, isInstValue = false): PType
  70. proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym, t: PType): PSym
  71. proc replaceTypeVarsN*(cl: var TReplTypeVars, n: PNode; start=0; expectedType: PType = nil): PNode
  72. proc newTypeMapLayer*(cl: var TReplTypeVars): LayeredIdTable =
  73. result = newTypeMapLayer(cl.typeMap)
  74. template checkMetaInvariants(cl: TReplTypeVars, t: PType) = # noop code
  75. when false:
  76. if t != nil and tfHasMeta in t.flags and
  77. cl.allowMetaTypes == false:
  78. echo "UNEXPECTED META ", t.id, " ", instantiationInfo(-1)
  79. debug t
  80. writeStackTrace()
  81. proc replaceTypeVarsT*(cl: var TReplTypeVars, t: PType, isInstValue = false): PType =
  82. result = replaceTypeVarsTAux(cl, t, isInstValue)
  83. checkMetaInvariants(cl, result)
  84. proc prepareNode*(cl: var TReplTypeVars, n: PNode): PNode =
  85. ## instantiates a given generic expression, not a type node
  86. if n.kind == nkSym and n.sym.kind == skType and
  87. n.sym.typ != nil and n.sym.typ.kind == tyGenericBody:
  88. # generic body types are allowed as user expressions, see #24090
  89. return n
  90. let t = replaceTypeVarsT(cl, n.typ)
  91. if t != nil and t.kind == tyStatic and t.n != nil:
  92. return if tfUnresolved in t.flags: prepareNode(cl, t.n)
  93. else: t.n
  94. result = copyNode(n)
  95. result.typ() = t
  96. if result.kind == nkSym:
  97. result.sym =
  98. if n.typ != nil and n.typ == n.sym.typ:
  99. replaceTypeVarsS(cl, n.sym, result.typ)
  100. else:
  101. replaceTypeVarsS(cl, n.sym, replaceTypeVarsT(cl, n.sym.typ))
  102. # we need to avoid trying to instantiate nodes that can have uninstantiated
  103. # types, like generic proc symbols or raw generic type symbols
  104. case n.kind
  105. of nkSymChoices:
  106. # don't try to instantiate symchoice symbols, they can be
  107. # generic procs which the compiler will think are uninstantiated
  108. # because their type will contain uninstantiated params
  109. for i in 0..<n.len:
  110. result.add(n[i])
  111. of nkCallKinds:
  112. # don't try to instantiate call names since they may be generic proc syms
  113. # also bracket expressions can turn into calls with symchoice [] and
  114. # we need to not instantiate the Generic in Generic[int]
  115. # exception exists for the call name being a dot expression since
  116. # dot expressions need their LHS instantiated
  117. assert n.len != 0
  118. # avoid instantiating generic proc symbols, refine condition if needed:
  119. let ignoreFirst = n[0].kind notin {nkDotExpr, nkBracketExpr} + nkCallKinds
  120. let name = n[0].getPIdent
  121. let ignoreSecond = name != nil and name.s == "[]" and n.len > 1 and
  122. # generic type instantiation:
  123. ((n[1].typ != nil and n[1].typ.kind == tyTypeDesc) or
  124. # generic proc instantiation:
  125. (n[1].kind == nkSym and n[1].sym.isGenericRoutineStrict))
  126. if ignoreFirst:
  127. result.add(n[0])
  128. else:
  129. result.add(prepareNode(cl, n[0]))
  130. if n.len > 1:
  131. if ignoreSecond:
  132. result.add(n[1])
  133. else:
  134. result.add(prepareNode(cl, n[1]))
  135. for i in 2..<n.len:
  136. result.add(prepareNode(cl, n[i]))
  137. of nkBracketExpr:
  138. # don't instantiate Generic body type in expression like Generic[T]
  139. # exception exists for the call name being a dot expression since
  140. # dot expressions need their LHS instantiated
  141. assert n.len != 0
  142. let ignoreFirst = n[0].kind != nkDotExpr and
  143. # generic type instantiation:
  144. ((n[0].typ != nil and n[0].typ.kind == tyTypeDesc) or
  145. # generic proc instantiation:
  146. (n[0].kind == nkSym and n[0].sym.isGenericRoutineStrict))
  147. if ignoreFirst:
  148. result.add(n[0])
  149. else:
  150. result.add(prepareNode(cl, n[0]))
  151. for i in 1..<n.len:
  152. result.add(prepareNode(cl, n[i]))
  153. of nkDotExpr:
  154. # don't try to instantiate RHS of dot expression, it can outright be
  155. # undeclared, but definitely instantiate LHS
  156. assert n.len >= 2
  157. result.add(prepareNode(cl, n[0]))
  158. result.add(n[1])
  159. for i in 2..<n.len:
  160. result.add(prepareNode(cl, n[i]))
  161. else:
  162. for i in 0..<n.safeLen:
  163. result.add(prepareNode(cl, n[i]))
  164. proc isTypeParam(n: PNode): bool =
  165. # XXX: generic params should use skGenericParam instead of skType
  166. return n.kind == nkSym and
  167. (n.sym.kind == skGenericParam or
  168. (n.sym.kind == skType and sfFromGeneric in n.sym.flags))
  169. when false: # old workaround
  170. proc reResolveCallsWithTypedescParams(cl: var TReplTypeVars, n: PNode): PNode =
  171. # This is needed for tuninstantiatedgenericcalls
  172. # It's possible that a generic param will be used in a proc call to a
  173. # typedesc accepting proc. After generic param substitution, such procs
  174. # should be optionally instantiated with the correct type. In order to
  175. # perform this instantiation, we need to re-run the generateInstance path
  176. # in the compiler, but it's quite complicated to do so at the moment so we
  177. # resort to a mild hack; the head symbol of the call is temporary reset and
  178. # overload resolution is executed again (which may trigger generateInstance).
  179. if n.kind in nkCallKinds and sfFromGeneric in n[0].sym.flags:
  180. var needsFixing = false
  181. for i in 1..<n.safeLen:
  182. if isTypeParam(n[i]): needsFixing = true
  183. if needsFixing:
  184. n[0] = newSymNode(n[0].sym.owner)
  185. return cl.c.semOverloadedCall(cl.c, n, n, {skProc, skFunc}, {})
  186. for i in 0..<n.safeLen:
  187. n[i] = reResolveCallsWithTypedescParams(cl, n[i])
  188. return n
  189. proc replaceObjBranches(cl: TReplTypeVars, n: PNode): PNode =
  190. result = n
  191. case n.kind
  192. of nkNone..nkNilLit:
  193. discard
  194. of nkRecWhen:
  195. var branch: PNode = nil # the branch to take
  196. for i in 0..<n.len:
  197. var it = n[i]
  198. if it == nil: illFormedAst(n, cl.c.config)
  199. case it.kind
  200. of nkElifBranch:
  201. checkSonsLen(it, 2, cl.c.config)
  202. var cond = it[0]
  203. var e = cl.c.semConstExpr(cl.c, cond)
  204. if e.kind != nkIntLit:
  205. internalError(cl.c.config, e.info, "ReplaceTypeVarsN: when condition not a bool")
  206. if e.intVal != 0 and branch == nil: branch = it[1]
  207. of nkElse:
  208. checkSonsLen(it, 1, cl.c.config)
  209. if branch == nil: branch = it[0]
  210. else: illFormedAst(n, cl.c.config)
  211. if branch != nil:
  212. result = replaceObjBranches(cl, branch)
  213. else:
  214. result = newNodeI(nkRecList, n.info)
  215. else:
  216. for i in 0..<n.len:
  217. n[i] = replaceObjBranches(cl, n[i])
  218. proc hasValuelessStatics(n: PNode): bool =
  219. # We should only attempt to call an expression that has no tyStatics
  220. # As those are unresolved generic parameters, which means in the following
  221. # The compiler attempts to do `T == 300` which errors since the typeclass `MyThing` lacks a parameter
  222. #[
  223. type MyThing[T: static int] = object
  224. when T == 300:
  225. a
  226. proc doThing(_: MyThing)
  227. ]#
  228. if n.safeLen == 0 and n.kind != nkEmpty: # Some empty nodes can get in here
  229. n.typ == nil or n.typ.kind == tyStatic
  230. else:
  231. for x in n:
  232. if hasValuelessStatics(x):
  233. return true
  234. false
  235. proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0; expectedType: PType = nil): PNode =
  236. if n == nil: return
  237. result = copyNode(n)
  238. if n.typ != nil:
  239. if n.typ.kind == tyFromExpr:
  240. # type of node should not be evaluated as a static value
  241. n.typ.flags.incl tfNonConstExpr
  242. result.typ() = replaceTypeVarsT(cl, n.typ)
  243. checkMetaInvariants(cl, result.typ)
  244. case n.kind
  245. of nkNone..pred(nkSym), succ(nkSym)..nkNilLit:
  246. discard
  247. of nkOpenSymChoice, nkClosedSymChoice: result = n
  248. of nkSym:
  249. result.sym =
  250. if n.typ != nil and n.typ == n.sym.typ:
  251. replaceTypeVarsS(cl, n.sym, result.typ)
  252. else:
  253. replaceTypeVarsS(cl, n.sym, replaceTypeVarsT(cl, n.sym.typ))
  254. if result.sym.kind == skField and result.sym.ast != nil and
  255. (cl.owner == nil or result.sym.owner == cl.owner):
  256. # instantiate default value of object/tuple field
  257. cl.c.fitDefaultNode(cl.c, result.sym.ast, result.sym.typ)
  258. result.sym.typ = result.sym.ast.typ
  259. # sym type can be nil if was gensym created by macro, see #24048
  260. if result.sym.typ != nil and result.sym.typ.kind == tyVoid:
  261. # don't add the 'void' field
  262. result = newNodeI(nkRecList, n.info)
  263. of nkRecWhen:
  264. var branch: PNode = nil # the branch to take
  265. for i in 0..<n.len:
  266. var it = n[i]
  267. if it == nil: illFormedAst(n, cl.c.config)
  268. case it.kind
  269. of nkElifBranch:
  270. checkSonsLen(it, 2, cl.c.config)
  271. var cond = prepareNode(cl, it[0])
  272. if not cond.hasValuelessStatics:
  273. var e = cl.c.semConstExpr(cl.c, cond)
  274. if e.kind != nkIntLit:
  275. internalError(cl.c.config, e.info, "ReplaceTypeVarsN: when condition not a bool")
  276. if e.intVal != 0 and branch == nil: branch = it[1]
  277. of nkElse:
  278. checkSonsLen(it, 1, cl.c.config)
  279. if branch == nil: branch = it[0]
  280. else: illFormedAst(n, cl.c.config)
  281. if branch != nil:
  282. result = replaceTypeVarsN(cl, branch)
  283. else:
  284. result = newNodeI(nkRecList, n.info)
  285. of nkStaticExpr:
  286. var n = prepareNode(cl, n)
  287. when false:
  288. n = reResolveCallsWithTypedescParams(cl, n)
  289. result = if cl.allowMetaTypes: n
  290. else: cl.c.semExpr(cl.c, n, {}, expectedType)
  291. if not cl.allowMetaTypes and expectedType != nil:
  292. assert result.kind notin nkCallKinds
  293. else:
  294. if n.len > 0:
  295. newSons(result, n.len)
  296. if start > 0:
  297. result[0] = n[0]
  298. for i in start..<n.len:
  299. result[i] = replaceTypeVarsN(cl, n[i])
  300. proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym, t: PType): PSym =
  301. if s == nil: return nil
  302. # symbol is not our business:
  303. if cl.owner != nil and s.owner != cl.owner:
  304. return s
  305. # XXX: Bound symbols in default parameter expressions may reach here.
  306. # We cannot process them, because `sym.n` may point to a proc body with
  307. # cyclic references that will lead to an infinite recursion.
  308. # Perhaps we should not use a black-list here, but a whitelist instead
  309. # (e.g. skGenericParam and skType).
  310. # Note: `s.magic` may be `mType` in an example such as:
  311. # proc foo[T](a: T, b = myDefault(type(a)))
  312. if s.kind in routineKinds+{skLet, skConst, skVar} or s.magic != mNone:
  313. return s
  314. #result = PSym(idTableGet(cl.symMap, s))
  315. #if result == nil:
  316. #[
  317. We cannot naively check for symbol recursions, because otherwise
  318. object types A, B whould share their fields!
  319. import tables
  320. type
  321. Table[S, T] = object
  322. x: S
  323. y: T
  324. G[T] = object
  325. inodes: Table[int, T] # A
  326. rnodes: Table[T, int] # B
  327. var g: G[string]
  328. ]#
  329. result = copySym(s, cl.c.idgen)
  330. incl(result.flags, sfFromGeneric)
  331. #idTablePut(cl.symMap, s, result)
  332. setOwner(result, s.owner)
  333. result.typ = t
  334. if result.kind != skType:
  335. result.ast = replaceTypeVarsN(cl, s.ast)
  336. proc lookupTypeVar(cl: var TReplTypeVars, t: PType): PType =
  337. if tfRetType in t.flags and t.kind == tyAnything:
  338. # don't bind `auto` return type to a previous binding of `auto`
  339. return nil
  340. result = cl.typeMap.lookup(t)
  341. if result == nil:
  342. if cl.allowMetaTypes or tfRetType in t.flags: return
  343. localError(cl.c.config, t.sym.info, "cannot instantiate: '" & typeToString(t) & "'")
  344. result = errorType(cl.c)
  345. # In order to prevent endless recursions, we must remember
  346. # this bad lookup and replace it with errorType everywhere.
  347. # These code paths are only active in "nim check"
  348. cl.typeMap.put(t, result)
  349. elif result.kind == tyGenericParam and not cl.allowMetaTypes:
  350. internalError(cl.c.config, cl.info, "substitution with generic parameter")
  351. proc instCopyType*(cl: var TReplTypeVars, t: PType): PType =
  352. # XXX: relying on allowMetaTypes is a kludge
  353. if cl.allowMetaTypes:
  354. result = t.exactReplica
  355. else:
  356. result = copyType(t, cl.c.idgen, t.owner)
  357. copyTypeProps(cl.c.graph, cl.c.idgen.module, result, t)
  358. #cl.typeMap.topLayer.idTablePut(result, t)
  359. if cl.allowMetaTypes: return
  360. result.flags.incl tfFromGeneric
  361. if not (t.kind in tyMetaTypes or
  362. (t.kind == tyStatic and t.n == nil)):
  363. result.flags.excl tfInstClearedFlags
  364. else:
  365. result.flags.excl tfHasAsgn
  366. when false:
  367. if newDestructors:
  368. result.assignment = nil
  369. result.destructor = nil
  370. result.sink = nil
  371. proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
  372. # tyGenericInvocation[A, tyGenericInvocation[A, B]]
  373. # is difficult to handle:
  374. var body = t.genericHead
  375. if body.kind != tyGenericBody:
  376. internalError(cl.c.config, cl.info, "no generic body")
  377. var header = t
  378. # search for some instantiation here:
  379. if cl.allowMetaTypes:
  380. result = getOrDefault(cl.localCache, t.itemId)
  381. else:
  382. result = searchInstTypes(cl.c.graph, t)
  383. if result != nil and sameFlags(result, t):
  384. when defined(reportCacheHits):
  385. echo "Generic instantiation cached ", typeToString(result), " for ", typeToString(t)
  386. return
  387. for i in FirstGenericParamAt..<t.kidsLen:
  388. var x = t[i]
  389. if x.kind in {tyGenericParam}:
  390. x = lookupTypeVar(cl, x)
  391. if x != nil:
  392. if header == t: header = instCopyType(cl, t)
  393. header[i] = x
  394. propagateToOwner(header, x)
  395. else:
  396. propagateToOwner(header, x)
  397. if header != t:
  398. # search again after first pass:
  399. result = searchInstTypes(cl.c.graph, header)
  400. if result != nil and sameFlags(result, t):
  401. when defined(reportCacheHits):
  402. echo "Generic instantiation cached ", typeToString(result), " for ",
  403. typeToString(t), " header ", typeToString(header)
  404. return
  405. else:
  406. header = instCopyType(cl, t)
  407. result = newType(tyGenericInst, cl.c.idgen, t.genericHead.owner, son = header.genericHead)
  408. result.flags = header.flags
  409. # be careful not to propagate unnecessary flags here (don't use rawAddSon)
  410. # ugh need another pass for deeply recursive generic types (e.g. PActor)
  411. # we need to add the candidate here, before it's fully instantiated for
  412. # recursive instantions:
  413. if not cl.allowMetaTypes:
  414. cacheTypeInst(cl.c, result)
  415. else:
  416. cl.localCache[t.itemId] = result
  417. let oldSkipTypedesc = cl.skipTypedesc
  418. cl.skipTypedesc = true
  419. cl.typeMap = newTypeMapLayer(cl)
  420. for i in FirstGenericParamAt..<t.kidsLen:
  421. var x = replaceTypeVarsT(cl):
  422. if header[i].kind == tyGenericInst:
  423. t[i]
  424. else:
  425. header[i]
  426. assert x.kind != tyGenericInvocation
  427. header[i] = x
  428. propagateToOwner(header, x)
  429. cl.typeMap.put(body[i-1], x)
  430. for i in FirstGenericParamAt..<t.kidsLen:
  431. # if one of the params is not concrete, we cannot do anything
  432. # but we already raised an error!
  433. rawAddSon(result, header[i], propagateHasAsgn = false)
  434. if body.kind == tyError:
  435. return
  436. let bbody = last body
  437. var newbody = replaceTypeVarsT(cl, bbody, isInstValue = true)
  438. cl.skipTypedesc = oldSkipTypedesc
  439. newbody.flags = newbody.flags + (t.flags + body.flags - tfInstClearedFlags)
  440. result.flags = result.flags + newbody.flags - tfInstClearedFlags
  441. setToPreviousLayer(cl.typeMap)
  442. # This is actually wrong: tgeneric_closure fails with this line:
  443. #newbody.callConv = body.callConv
  444. # This type may be a generic alias and we want to resolve it here.
  445. # One step is enough, because the recursive nature of
  446. # handleGenericInvocation will handle the alias-to-alias-to-alias case
  447. if newbody.isGenericAlias: newbody = newbody.skipGenericAlias
  448. rawAddSon(result, newbody)
  449. checkPartialConstructedType(cl.c.config, cl.info, newbody)
  450. if not cl.allowMetaTypes:
  451. let dc = cl.c.graph.getAttachedOp(newbody, attachedDeepCopy)
  452. if dc != nil and sfFromGeneric notin dc.flags:
  453. # 'deepCopy' needs to be instantiated for
  454. # generics *when the type is constructed*:
  455. cl.c.graph.setAttachedOp(cl.c.module.position, newbody, attachedDeepCopy,
  456. cl.c.instTypeBoundOp(cl.c, dc, result, cl.info, attachedDeepCopy, 1))
  457. if newbody.typeInst == nil:
  458. # doAssert newbody.typeInst == nil
  459. newbody.typeInst = result
  460. if tfRefsAnonObj in newbody.flags and newbody.kind != tyGenericInst:
  461. # can come here for tyGenericInst too, see tests/metatype/ttypeor.nim
  462. # need to look into this issue later
  463. assert newbody.kind in {tyRef, tyPtr}
  464. if newbody.last.typeInst != nil:
  465. #internalError(cl.c.config, cl.info, "ref already has a 'typeInst' field")
  466. discard
  467. else:
  468. newbody.last.typeInst = result
  469. # DESTROY: adding object|opt for opt[topttree.Tree]
  470. # sigmatch: Formal opt[=destroy.T] real opt[topttree.Tree]
  471. # adding myseq for myseq[system.int]
  472. # sigmatch: Formal myseq[=destroy.T] real myseq[system.int]
  473. #echo "DESTROY: adding ", typeToString(newbody), " for ", typeToString(result, preferDesc)
  474. let mm = skipTypes(bbody, abstractPtrs)
  475. if tfFromGeneric notin mm.flags:
  476. # bug #5479, prevent endless recursions here:
  477. incl mm.flags, tfFromGeneric
  478. for col, meth in methodsForGeneric(cl.c.graph, mm):
  479. # we instantiate the known methods belonging to that type, this causes
  480. # them to be registered and that's enough, so we 'discard' the result.
  481. discard cl.c.instTypeBoundOp(cl.c, meth, result, cl.info,
  482. attachedAsgn, col)
  483. excl mm.flags, tfFromGeneric
  484. proc eraseVoidParams*(t: PType) =
  485. # transform '(): void' into '()' because old parts of the compiler really
  486. # don't deal with '(): void':
  487. if t.returnType != nil and t.returnType.kind == tyVoid:
  488. t.setReturnType nil
  489. for i in FirstParamAt..<t.signatureLen:
  490. # don't touch any memory unless necessary
  491. if t[i].kind == tyVoid:
  492. var pos = i
  493. for j in i+1..<t.signatureLen:
  494. if t[j].kind != tyVoid:
  495. t[pos] = t[j]
  496. t.n[pos] = t.n[j]
  497. inc pos
  498. newSons t, pos
  499. setLen t.n.sons, pos
  500. break
  501. proc skipIntLiteralParams*(t: PType; idgen: IdGenerator) =
  502. for i, p in t.ikids:
  503. if p == nil: continue
  504. let skipped = p.skipIntLit(idgen)
  505. if skipped != p:
  506. t[i] = skipped
  507. if i > 0: t.n[i].sym.typ = skipped
  508. # when the typeof operator is used on a static input
  509. # param, the results gets infected with static as well:
  510. if t.returnType != nil and t.returnType.kind == tyStatic:
  511. t.setReturnType t.returnType.skipModifier
  512. proc propagateFieldFlags(t: PType, n: PNode) =
  513. # This is meant for objects and tuples
  514. # The type must be fully instantiated!
  515. if n.isNil:
  516. return
  517. #internalAssert n.kind != nkRecWhen
  518. case n.kind
  519. of nkSym:
  520. propagateToOwner(t, n.sym.typ)
  521. of nkRecList, nkRecCase, nkOfBranch, nkElse:
  522. for son in n:
  523. propagateFieldFlags(t, son)
  524. else: discard
  525. proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType, isInstValue = false): PType =
  526. template bailout =
  527. if (t.sym == nil) or (t.sym != nil and sfGeneratedType in t.sym.flags):
  528. # In the first case 't.sym' can be 'nil' if the type is a ref/ptr, see
  529. # issue https://github.com/nim-lang/Nim/issues/20416 for more details.
  530. # Fortunately for us this works for now because partial ref/ptr types are
  531. # not allowed in object construction, eg.
  532. # type
  533. # Container[T] = ...
  534. # O = object
  535. # val: ref Container
  536. #
  537. # In the second case only consider the recursion limit if the symbol is a
  538. # type with generic parameters that have not been explicitly supplied,
  539. # typechecking should terminate when generic parameters are explicitly
  540. # supplied.
  541. if cl.recursionLimit > 100:
  542. # bail out, see bug #2509. But note this caching is in general wrong,
  543. # look at this example where TwoVectors should not share the generic
  544. # instantiations (bug #3112):
  545. # type
  546. # Vector[N: static[int]] = array[N, float64]
  547. # TwoVectors[Na, Nb: static[int]] = (Vector[Na], Vector[Nb])
  548. result = getOrDefault(cl.localCache, t.itemId)
  549. if result != nil: return result
  550. inc cl.recursionLimit
  551. result = t
  552. if t == nil: return
  553. const lookupMetas = {tyStatic, tyGenericParam, tyConcept} + tyTypeClasses - {tyAnything}
  554. if t.kind in lookupMetas or
  555. (t.kind == tyAnything and tfRetType notin t.flags):
  556. let lookup = cl.typeMap.lookup(t)
  557. if lookup != nil: return lookup
  558. case t.kind
  559. of tyGenericInvocation:
  560. result = handleGenericInvocation(cl, t)
  561. if result.last.kind == tyUserTypeClass:
  562. result.kind = tyUserTypeClassInst
  563. of tyGenericBody:
  564. if cl.allowMetaTypes: return
  565. localError(
  566. cl.c.config,
  567. cl.info,
  568. "cannot instantiate: '" &
  569. typeToString(t, preferDesc) &
  570. "'; Maybe generic arguments are missing?")
  571. result = errorType(cl.c)
  572. #result = replaceTypeVarsT(cl, lastSon(t))
  573. of tyFromExpr:
  574. if cl.allowMetaTypes: return
  575. # This assert is triggered when a tyFromExpr was created in a cyclic
  576. # way. You should break the cycle at the point of creation by introducing
  577. # a call such as: `n.typ = makeTypeFromExpr(c, n.copyTree)`
  578. # Otherwise, the cycle will be fatal for the prepareNode call below
  579. assert t.n.typ != t
  580. var n = prepareNode(cl, t.n)
  581. if n.kind != nkEmpty:
  582. if tfNonConstExpr in t.flags:
  583. n = cl.c.semExprWithType(cl.c, n, flags = {efInTypeof})
  584. else:
  585. n = cl.c.semConstExpr(cl.c, n)
  586. if n.typ.kind == tyTypeDesc:
  587. # XXX: sometimes, chained typedescs enter here.
  588. # It may be worth investigating why this is happening,
  589. # because it may cause other bugs elsewhere.
  590. result = n.typ.skipTypes({tyTypeDesc})
  591. # result = n.typ.base
  592. elif tfNonConstExpr in t.flags:
  593. result = n.typ
  594. else:
  595. if n.typ.kind != tyStatic and n.kind != nkType:
  596. # XXX: In the future, semConstExpr should
  597. # return tyStatic values to let anyone make
  598. # use of this knowledge. The patching here
  599. # won't be necessary then.
  600. result = newTypeS(tyStatic, cl.c, son = n.typ)
  601. result.n = n
  602. else:
  603. result = n.typ
  604. of tyInt, tyFloat:
  605. result = skipIntLit(t, cl.c.idgen)
  606. of tyTypeDesc:
  607. let lookup = cl.typeMap.lookup(t)
  608. if lookup != nil:
  609. result = lookup
  610. if result.kind != tyTypeDesc:
  611. result = makeTypeDesc(cl.c, result)
  612. elif tfUnresolved in t.flags or cl.skipTypedesc:
  613. result = result.base
  614. elif t.elementType.kind != tyNone:
  615. result = makeTypeDesc(cl.c, replaceTypeVarsT(cl, t.elementType))
  616. of tyUserTypeClass:
  617. result = t
  618. of tyStatic:
  619. if cl.c.matchedConcept != nil:
  620. # allow concepts to not instantiate statics for now
  621. # they can't always infer them
  622. return
  623. if not containsGenericType(t) and (t.n == nil or t.n.kind in nkLiterals):
  624. # no need to instantiate
  625. return
  626. bailout()
  627. result = instCopyType(cl, t)
  628. cl.localCache[t.itemId] = result
  629. for i in FirstGenericParamAt..<result.kidsLen:
  630. var r = result[i]
  631. if r != nil:
  632. r = replaceTypeVarsT(cl, r)
  633. result[i] = r
  634. propagateToOwner(result, r)
  635. result.n = replaceTypeVarsN(cl, result.n)
  636. if not cl.allowMetaTypes and result.n != nil and
  637. result.base.kind != tyNone:
  638. result.n = cl.c.semConstExpr(cl.c, result.n)
  639. result.n.typ() = result.base
  640. of tyGenericInst, tyUserTypeClassInst:
  641. bailout()
  642. result = instCopyType(cl, t)
  643. cl.localCache[t.itemId] = result
  644. for i in FirstGenericParamAt..<result.kidsLen:
  645. result[i] = replaceTypeVarsT(cl, result[i])
  646. propagateToOwner(result, result.last)
  647. else:
  648. if containsGenericType(t) or
  649. # nominal types as direct generic instantiation values
  650. # are re-instantiated even if they don't contain generic fields
  651. (isInstValue and (t.kind in {tyDistinct, tyObject} or isRefPtrObject(t))):
  652. #if not cl.allowMetaTypes:
  653. bailout()
  654. result = instCopyType(cl, t)
  655. result.size = -1 # needs to be recomputed
  656. #if not cl.allowMetaTypes:
  657. cl.localCache[t.itemId] = result
  658. let propagateInstValue = isInstValue and isRefPtrObject(t)
  659. for i, resulti in result.ikids:
  660. if resulti != nil:
  661. if resulti.kind == tyGenericBody and not cl.allowMetaTypes:
  662. localError(cl.c.config, if t.sym != nil: t.sym.info else: cl.info,
  663. "cannot instantiate '" &
  664. typeToString(result[i], preferDesc) &
  665. "' inside of type definition: '" &
  666. t.owner.name.s & "'; Maybe generic arguments are missing?")
  667. var r = replaceTypeVarsT(cl, resulti, isInstValue = propagateInstValue)
  668. if result.kind == tyObject:
  669. # carefully coded to not skip the precious tyGenericInst:
  670. let r2 = r.skipTypes({tyAlias, tySink, tyOwned})
  671. if r2.kind in {tyPtr, tyRef}:
  672. r = skipTypes(r2, {tyPtr, tyRef})
  673. result[i] = r
  674. if result.kind != tyArray or i != 0:
  675. propagateToOwner(result, r)
  676. # bug #4677: Do not instantiate effect lists
  677. result.n = replaceTypeVarsN(cl, result.n, ord(result.kind==tyProc))
  678. case result.kind
  679. of tyArray:
  680. let idx = result.indexType
  681. internalAssert cl.c.config, idx.kind != tyStatic
  682. of tyObject, tyTuple:
  683. propagateFieldFlags(result, result.n)
  684. if result.kind == tyObject and cl.c.computeRequiresInit(cl.c, result):
  685. result.flags.incl tfRequiresInit
  686. of tyProc:
  687. eraseVoidParams(result)
  688. skipIntLiteralParams(result, cl.c.idgen)
  689. of tyRange:
  690. result.setIndexType result.indexType.skipTypes({tyStatic, tyDistinct})
  691. else: discard
  692. else:
  693. # If this type doesn't refer to a generic type we may still want to run it
  694. # trough replaceObjBranches in order to resolve any pending nkRecWhen nodes
  695. result = t
  696. # Slow path, we have some work to do
  697. if t.kind == tyRef and t.hasElementType and t.elementType.kind == tyObject and t.elementType.n != nil:
  698. discard replaceObjBranches(cl, t.elementType.n)
  699. elif result.n != nil and t.kind == tyObject:
  700. # Invalidate the type size as we may alter its structure
  701. result.size = -1
  702. result.n = replaceObjBranches(cl, result.n)
  703. proc initTypeVars*(p: PContext, typeMap: LayeredIdTable, info: TLineInfo;
  704. owner: PSym): TReplTypeVars =
  705. result = TReplTypeVars(symMap: initSymMapping(),
  706. localCache: initTypeMapping(), typeMap: typeMap,
  707. info: info, c: p, owner: owner)
  708. proc replaceTypesInBody*(p: PContext, pt: LayeredIdTable, n: PNode;
  709. owner: PSym, allowMetaTypes = false,
  710. fromStaticExpr = false, expectedType: PType = nil): PNode =
  711. var typeMap = shallowCopy(pt) # use previous bindings without writing to them
  712. var cl = initTypeVars(p, typeMap, n.info, owner)
  713. cl.allowMetaTypes = allowMetaTypes
  714. pushInfoContext(p.config, n.info)
  715. result = replaceTypeVarsN(cl, n, expectedType = expectedType)
  716. popInfoContext(p.config)
  717. proc prepareTypesInBody*(p: PContext, pt: LayeredIdTable, n: PNode;
  718. owner: PSym = nil): PNode =
  719. var typeMap = shallowCopy(pt) # use previous bindings without writing to them
  720. var cl = initTypeVars(p, typeMap, n.info, owner)
  721. pushInfoContext(p.config, n.info)
  722. result = prepareNode(cl, n)
  723. popInfoContext(p.config)
  724. when false:
  725. # deadcode
  726. proc replaceTypesForLambda*(p: PContext, pt: TIdTable, n: PNode;
  727. original, new: PSym): PNode =
  728. var typeMap = initLayeredTypeMap(pt)
  729. var cl = initTypeVars(p, typeMap, n.info, original)
  730. idTablePut(cl.symMap, original, new)
  731. pushInfoContext(p.config, n.info)
  732. result = replaceTypeVarsN(cl, n)
  733. popInfoContext(p.config)
  734. proc recomputeFieldPositions*(t: PType; obj: PNode; currPosition: var int) =
  735. if t != nil and t.baseClass != nil:
  736. let b = skipTypes(t.baseClass, skipPtrs)
  737. recomputeFieldPositions(b, b.n, currPosition)
  738. case obj.kind
  739. of nkRecList:
  740. for i in 0..<obj.len: recomputeFieldPositions(nil, obj[i], currPosition)
  741. of nkRecCase:
  742. recomputeFieldPositions(nil, obj[0], currPosition)
  743. for i in 1..<obj.len:
  744. recomputeFieldPositions(nil, lastSon(obj[i]), currPosition)
  745. of nkSym:
  746. obj.sym.position = currPosition
  747. inc currPosition
  748. else: discard "cannot happen"
  749. proc generateTypeInstance*(p: PContext, pt: LayeredIdTable, info: TLineInfo,
  750. t: PType): PType =
  751. # Given `t` like Foo[T]
  752. # pt: Table with type mappings: T -> int
  753. # Desired result: Foo[int]
  754. # proc (x: T = 0); T -> int ----> proc (x: int = 0)
  755. var typeMap = shallowCopy(pt) # use previous bindings without writing to them
  756. var cl = initTypeVars(p, typeMap, info, nil)
  757. pushInfoContext(p.config, info)
  758. result = replaceTypeVarsT(cl, t)
  759. popInfoContext(p.config)
  760. let objType = result.skipTypes(abstractInst)
  761. if objType.kind == tyObject:
  762. var position = 0
  763. recomputeFieldPositions(objType, objType.n, position)
  764. proc prepareMetatypeForSigmatch*(p: PContext, pt: LayeredIdTable, info: TLineInfo,
  765. t: PType): PType =
  766. var typeMap = shallowCopy(pt) # use previous bindings without writing to them
  767. var cl = initTypeVars(p, typeMap, info, nil)
  768. cl.allowMetaTypes = true
  769. pushInfoContext(p.config, info)
  770. result = replaceTypeVarsT(cl, t)
  771. popInfoContext(p.config)
  772. template generateTypeInstance*(p: PContext, pt: LayeredIdTable, arg: PNode,
  773. t: PType): untyped =
  774. generateTypeInstance(p, pt, arg.info, t)