mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-10 19:29:32 +00:00
IC: bugfix (#25982)
This commit is contained in:
@@ -288,6 +288,14 @@ proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
|
||||
result = copySym(result)
|
||||
result.ast = n.sym.ast
|
||||
put(c.p, n.sym, result)
|
||||
if result.state == Sealed:
|
||||
# the symbol was loaded from another module's NIF cache (e.g. a param
|
||||
# symbol spliced out of an imported proc type by a `typed` macro) and is
|
||||
# therefore immutable; the caller re-owns it and assigns its type/flags,
|
||||
# so hand back a fresh, mutable copy owned by the current module instead.
|
||||
let fresh = copySym(result, c.idgen)
|
||||
fresh.ast = result.ast
|
||||
result = fresh
|
||||
# when there is a nested proc inside a template, semtmpl
|
||||
# will assign a wrong owner during the first pass over the
|
||||
# template; we must fix it here: see #909
|
||||
|
||||
2
koch.nim
2
koch.nim
@@ -619,7 +619,7 @@ proc runIcTestFile(inp: string) =
|
||||
const icSuite = ["thallo", "tconverter", "timp", "tmiscs", "tparseutils",
|
||||
"tcompiletimeglobal", "tsighashstable", "tpureenum", "tgenericoffer",
|
||||
"tconverterreexport", "ttypeoffer", "ttransitiveoffer",
|
||||
"tmodsymref", "tmethupref", "temit"]
|
||||
"tmodsymref", "tmethupref", "temit", "ttraitparam"]
|
||||
|
||||
proc icTest(args: string) =
|
||||
temp("")
|
||||
|
||||
34
tests/ic/mtraitparam.nim
Normal file
34
tests/ic/mtraitparam.nim
Normal file
@@ -0,0 +1,34 @@
|
||||
import std/macros
|
||||
|
||||
type
|
||||
Chunk* = ref object
|
||||
x*: int32
|
||||
ChunkTrait* = distinct tuple[
|
||||
loaded: proc(self: pointer, chunk: Chunk)
|
||||
]
|
||||
|
||||
macro makeVTable*(traitType: typedesc): untyped =
|
||||
## Splice the param symbols out of an imported proc type into a fresh proc
|
||||
## type nested in a fresh tuple type. Under `nim ic` the imported trait is
|
||||
## loaded from a NIF cache, so its param symbols are `Sealed`; re-owning them
|
||||
## in `semProcTypeNode` used to trip `ast.nim` `s.state != Sealed`.
|
||||
var t = traitType.getTypeInst[1].getTypeImpl
|
||||
if t.kind == nnkDistinctTy: t = t[0]
|
||||
let formalParams = t[0][1][0]
|
||||
var bridgeParams = nnkFormalParams.newTree(formalParams[0].copyNimTree)
|
||||
bridgeParams.add nnkIdentDefs.newTree(ident"p", ident"pointer", newEmptyNode())
|
||||
for j in 2 ..< formalParams.len:
|
||||
bridgeParams.add formalParams[j].copyNimTree
|
||||
let vtType = nnkTupleTy.newTree(
|
||||
nnkIdentDefs.newTree(ident"m0",
|
||||
nnkProcTy.newTree(bridgeParams, nnkPragma.newTree(ident"nimcall")),
|
||||
newEmptyNode()))
|
||||
let vtName = genSym(nskType, "VT")
|
||||
let vtVar = genSym(nskVar, "vt")
|
||||
result = nnkStmtList.newTree(
|
||||
nnkTypeSection.newTree(
|
||||
nnkTypeDef.newTree(vtName, newEmptyNode(), vtType)),
|
||||
nnkVarSection.newTree(
|
||||
nnkIdentDefs.newTree(
|
||||
nnkPragmaExpr.newTree(vtVar, nnkPragma.newTree(ident"used")),
|
||||
vtName, newEmptyNode())))
|
||||
14
tests/ic/ttraitparam.nim
Normal file
14
tests/ic/ttraitparam.nim
Normal file
@@ -0,0 +1,14 @@
|
||||
discard """
|
||||
output: '''ok'''
|
||||
"""
|
||||
|
||||
# Regression test: a `typed` macro in an imported module splices param symbols
|
||||
# out of an imported proc type into a freshly semchecked proc type. Under
|
||||
# `nim ic` those param symbols are loaded `Sealed` from the NIF cache; reusing
|
||||
# them in `newSymG`/`semProcTypeNode` used to fail `ast.nim` `s.state != Sealed`.
|
||||
|
||||
import mtraitparam
|
||||
|
||||
makeVTable(ChunkTrait)
|
||||
|
||||
echo "ok"
|
||||
Reference in New Issue
Block a user