Skip to content

Commit c814c4d

Browse files
authored
fixes #3770; templates with untyped parameters resolve private fields wrongly in generics (#21554)
* fixes #3770; templates with untyped parameters resolve private fields wrongly * add a test case for #3770 * rename to `nfSkipFieldChecking`
1 parent f7e3af0 commit c814c4d

File tree

8 files changed

+48
-11
lines changed

8 files changed

+48
-11
lines changed

compiler/ast.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ type
510510
nfLastRead # this node is a last read
511511
nfFirstWrite # this node is a first write
512512
nfHasComment # node has a comment
513-
nfUseDefaultField # node has a default value (object constructor)
513+
nfSkipFieldChecking # node skips field visable checking
514514

515515
TNodeFlags* = set[TNodeFlag]
516516
TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 46)
@@ -1081,7 +1081,7 @@ const
10811081
nfIsRef, nfIsPtr, nfPreventCg, nfLL,
10821082
nfFromTemplate, nfDefaultRefsParam,
10831083
nfExecuteOnReload, nfLastRead,
1084-
nfFirstWrite, nfUseDefaultField}
1084+
nfFirstWrite, nfSkipFieldChecking}
10851085
namePos* = 0
10861086
patternPos* = 1 # empty except for term rewriting macros
10871087
genericParamsPos* = 2

compiler/sem.nim

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ proc defaultFieldsForTuple(c: PContext, recNode: PNode, hasDefault: var bool): s
572572
let asgnExpr = defaultNodeField(c, recNode, recNode.typ)
573573
if asgnExpr != nil:
574574
hasDefault = true
575-
asgnExpr.flags.incl nfUseDefaultField
575+
asgnExpr.flags.incl nfSkipFieldChecking
576576
result.add newTree(nkExprColonExpr, recNode, asgnExpr)
577577
return
578578

@@ -582,7 +582,7 @@ proc defaultFieldsForTuple(c: PContext, recNode: PNode, hasDefault: var bool): s
582582
newSymNode(getSysMagic(c.graph, recNode.info, "zeroDefault", mZeroDefault)),
583583
newNodeIT(nkType, recNode.info, asgnType)
584584
)
585-
asgnExpr.flags.incl nfUseDefaultField
585+
asgnExpr.flags.incl nfSkipFieldChecking
586586
asgnExpr.typ = recType
587587
result.add newTree(nkExprColonExpr, recNode, asgnExpr)
588588
else:
@@ -604,7 +604,7 @@ proc defaultFieldsForTheUninitialized(c: PContext, recNode: PNode): seq[PNode] =
604604
defaultValue = newIntNode(nkIntLit#[c.graph]#, 0)
605605
defaultValue.typ = discriminator.typ
606606
selectedBranch = recNode.pickCaseBranchIndex defaultValue
607-
defaultValue.flags.incl nfUseDefaultField
607+
defaultValue.flags.incl nfSkipFieldChecking
608608
result.add newTree(nkExprColonExpr, discriminator, defaultValue)
609609
result.add defaultFieldsForTheUninitialized(c, recNode[selectedBranch][^1])
610610
of nkSym:
@@ -616,7 +616,7 @@ proc defaultFieldsForTheUninitialized(c: PContext, recNode: PNode): seq[PNode] =
616616
let asgnExpr = defaultNodeField(c, recNode, recType)
617617
if asgnExpr != nil:
618618
asgnExpr.typ = recType
619-
asgnExpr.flags.incl nfUseDefaultField
619+
asgnExpr.flags.incl nfSkipFieldChecking
620620
result.add newTree(nkExprColonExpr, recNode, asgnExpr)
621621
else:
622622
doAssert false

compiler/semgnrc.nim

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,18 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
7878
if macroToExpandSym(s):
7979
onUse(n.info, s)
8080
result = semTemplateExpr(c, n, s, {efNoSemCheck})
81+
c.friendModules.add(s.owner.getModule)
8182
result = semGenericStmt(c, result, {}, ctx)
83+
discard c.friendModules.pop()
8284
else:
8385
result = symChoice(c, n, s, scOpen)
8486
of skMacro:
8587
if macroToExpandSym(s):
8688
onUse(n.info, s)
8789
result = semMacroExpr(c, n, n, s, {efNoSemCheck})
90+
c.friendModules.add(s.owner.getModule)
8891
result = semGenericStmt(c, result, {}, ctx)
92+
discard c.friendModules.pop()
8993
else:
9094
result = symChoice(c, n, s, scOpen)
9195
of skGenericParam:
@@ -245,7 +249,9 @@ proc semGenericStmt(c: PContext, n: PNode,
245249
if macroToExpand(s) and sc.safeLen <= 1:
246250
onUse(fn.info, s)
247251
result = semMacroExpr(c, n, n, s, {efNoSemCheck})
252+
c.friendModules.add(s.owner.getModule)
248253
result = semGenericStmt(c, result, flags, ctx)
254+
discard c.friendModules.pop()
249255
else:
250256
n[0] = sc
251257
result = n
@@ -254,7 +260,9 @@ proc semGenericStmt(c: PContext, n: PNode,
254260
if macroToExpand(s) and sc.safeLen <= 1:
255261
onUse(fn.info, s)
256262
result = semTemplateExpr(c, n, s, {efNoSemCheck})
263+
c.friendModules.add(s.owner.getModule)
257264
result = semGenericStmt(c, result, flags, ctx)
265+
discard c.friendModules.pop()
258266
else:
259267
n[0] = sc
260268
result = n
@@ -493,6 +501,20 @@ proc semGenericStmt(c: PContext, n: PNode,
493501
of nkExprColonExpr, nkExprEqExpr:
494502
checkMinSonsLen(n, 2, c.config)
495503
result[1] = semGenericStmt(c, n[1], flags, ctx)
504+
of nkObjConstr:
505+
for i in 0..<n.len:
506+
result[i] = semGenericStmt(c, n[i], flags, ctx)
507+
if result[0].kind == nkSym:
508+
let fmoduleId = getModule(result[0].sym).id
509+
var isVisable = false
510+
for module in c.friendModules:
511+
if module.id == fmoduleId:
512+
isVisable = true
513+
break
514+
if isVisable:
515+
for i in 1..<result.len:
516+
if result[i].kind == nkExprColonExpr:
517+
result[i][1].flags.incl nfSkipFieldChecking
496518
else:
497519
for i in 0..<n.len:
498520
result[i] = semGenericStmt(c, n[i], flags, ctx)

compiler/semobjconstr.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ proc semConstrField(c: PContext, flags: TExprFlags,
7676
let assignment = locateFieldInInitExpr(c, field, initExpr)
7777
if assignment != nil:
7878
if nfSem in assignment.flags: return assignment[1]
79-
if nfUseDefaultField in assignment[1].flags:
79+
if nfSkipFieldChecking in assignment[1].flags:
8080
discard
8181
elif not fieldVisible(c, field):
8282
localError(c.config, initExpr.info,
@@ -178,7 +178,7 @@ proc collectOrAddMissingCaseFields(c: PContext, branchNode: PNode,
178178
newSymNode(getSysMagic(c.graph, constrCtx.initExpr.info, "zeroDefault", mZeroDefault)),
179179
newNodeIT(nkType, constrCtx.initExpr.info, asgnType)
180180
)
181-
asgnExpr.flags.incl nfUseDefaultField
181+
asgnExpr.flags.incl nfSkipFieldChecking
182182
asgnExpr.typ = recTyp
183183
defaults.add newTree(nkExprColonExpr, newSymNode(sym), asgnExpr)
184184

compiler/semtypes.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ proc semTuple(c: PContext, n: PNode, prev: PType): PType =
519519
let fSym = newSymNode(field)
520520
if hasDefaultField:
521521
fSym.sym.ast = a[^1]
522-
fSym.sym.ast.flags.incl nfUseDefaultField
522+
fSym.sym.ast.flags.incl nfSkipFieldChecking
523523
result.n.add fSym
524524
addSonSkipIntLit(result, typ, c.idgen)
525525
styleCheckDef(c, a[j].info, field)
@@ -868,7 +868,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
868868
let fSym = newSymNode(f)
869869
if hasDefaultField:
870870
fSym.sym.ast = n[^1]
871-
fSym.sym.ast.flags.incl nfUseDefaultField
871+
fSym.sym.ast.flags.incl nfSkipFieldChecking
872872
if a.kind == nkEmpty: father.add fSym
873873
else: a.add fSym
874874
styleCheckDef(c, f)

compiler/vmgen.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1829,7 +1829,7 @@ proc getNullValueAux(t: PType; obj: PNode, result: PNode; conf: ConfigRef; currP
18291829
let field = newNodeI(nkExprColonExpr, result.info)
18301830
field.add(obj)
18311831
let value = getNullValue(obj.sym.typ, result.info, conf)
1832-
value.flags.incl nfUseDefaultField
1832+
value.flags.incl nfSkipFieldChecking
18331833
field.add(value)
18341834
result.add field
18351835
doAssert obj.sym.position == currPosition

tests/generics/m3770.nim

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
type
2+
Noice* = object
3+
hidden: int
4+
5+
template jjj*: Noice =
6+
Noice(hidden: 15)

tests/generics/t3770.nim

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# bug #3770
2+
import m3770
3+
4+
doAssert $jjj() == "(hidden: 15)" # works
5+
6+
proc someGeneric(_: type) =
7+
doAssert $jjj() == "(hidden: 15)" # fails: "Error: the field 'hidden' is not accessible."
8+
9+
someGeneric(int)

0 commit comments

Comments
 (0)