mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-12 22:33:49 +00:00
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`
This commit is contained in:
@@ -505,6 +505,7 @@ type
|
||||
nfLastRead # this node is a last read
|
||||
nfFirstWrite# this node is a first write
|
||||
nfHasComment # node has a comment
|
||||
nfSkipFieldChecking # node skips field visable checking
|
||||
|
||||
TNodeFlags* = set[TNodeFlag]
|
||||
TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 45)
|
||||
@@ -1071,7 +1072,8 @@ const
|
||||
nfDotSetter, nfDotField,
|
||||
nfIsRef, nfIsPtr, nfPreventCg, nfLL,
|
||||
nfFromTemplate, nfDefaultRefsParam,
|
||||
nfExecuteOnReload, nfLastRead, nfFirstWrite}
|
||||
nfExecuteOnReload, nfLastRead,
|
||||
nfFirstWrite, nfSkipFieldChecking}
|
||||
namePos* = 0
|
||||
patternPos* = 1 # empty except for term rewriting macros
|
||||
genericParamsPos* = 2
|
||||
|
||||
@@ -78,14 +78,18 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
|
||||
if macroToExpandSym(s):
|
||||
onUse(n.info, s)
|
||||
result = semTemplateExpr(c, n, s, {efNoSemCheck})
|
||||
c.friendModules.add(s.owner.getModule)
|
||||
result = semGenericStmt(c, result, {}, ctx)
|
||||
discard c.friendModules.pop()
|
||||
else:
|
||||
result = symChoice(c, n, s, scOpen)
|
||||
of skMacro:
|
||||
if macroToExpandSym(s):
|
||||
onUse(n.info, s)
|
||||
result = semMacroExpr(c, n, n, s, {efNoSemCheck})
|
||||
c.friendModules.add(s.owner.getModule)
|
||||
result = semGenericStmt(c, result, {}, ctx)
|
||||
discard c.friendModules.pop()
|
||||
else:
|
||||
result = symChoice(c, n, s, scOpen)
|
||||
of skGenericParam:
|
||||
@@ -249,7 +253,9 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||
if macroToExpand(s) and sc.safeLen <= 1:
|
||||
onUse(fn.info, s)
|
||||
result = semMacroExpr(c, n, n, s, {efNoSemCheck})
|
||||
c.friendModules.add(s.owner.getModule)
|
||||
result = semGenericStmt(c, result, flags, ctx)
|
||||
discard c.friendModules.pop()
|
||||
else:
|
||||
n[0] = sc
|
||||
result = n
|
||||
@@ -258,7 +264,9 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||
if macroToExpand(s) and sc.safeLen <= 1:
|
||||
onUse(fn.info, s)
|
||||
result = semTemplateExpr(c, n, s, {efNoSemCheck})
|
||||
c.friendModules.add(s.owner.getModule)
|
||||
result = semGenericStmt(c, result, flags, ctx)
|
||||
discard c.friendModules.pop()
|
||||
else:
|
||||
n[0] = sc
|
||||
result = n
|
||||
@@ -497,6 +505,20 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||
of nkExprColonExpr, nkExprEqExpr:
|
||||
checkMinSonsLen(n, 2, c.config)
|
||||
result[1] = semGenericStmt(c, n[1], flags, ctx)
|
||||
of nkObjConstr:
|
||||
for i in 0..<n.len:
|
||||
result[i] = semGenericStmt(c, n[i], flags, ctx)
|
||||
if result[0].kind == nkSym:
|
||||
let fmoduleId = getModule(result[0].sym).id
|
||||
var isVisable = false
|
||||
for module in c.friendModules:
|
||||
if module.id == fmoduleId:
|
||||
isVisable = true
|
||||
break
|
||||
if isVisable:
|
||||
for i in 1..<result.len:
|
||||
if result[i].kind == nkExprColonExpr:
|
||||
result[i][1].flags.incl nfSkipFieldChecking
|
||||
else:
|
||||
for i in 0..<n.len:
|
||||
result[i] = semGenericStmt(c, n[i], flags, ctx)
|
||||
|
||||
@@ -72,7 +72,9 @@ proc semConstrField(c: PContext, flags: TExprFlags,
|
||||
let assignment = locateFieldInInitExpr(c, field, initExpr)
|
||||
if assignment != nil:
|
||||
if nfSem in assignment.flags: return assignment[1]
|
||||
if not fieldVisible(c, field):
|
||||
if nfSkipFieldChecking in assignment[1].flags:
|
||||
discard
|
||||
elif not fieldVisible(c, field):
|
||||
localError(c.config, initExpr.info,
|
||||
"the field '$1' is not accessible." % [field.name.s])
|
||||
return
|
||||
|
||||
6
tests/generics/m3770.nim
Normal file
6
tests/generics/m3770.nim
Normal file
@@ -0,0 +1,6 @@
|
||||
type
|
||||
Noice* = object
|
||||
hidden: int
|
||||
|
||||
template jjj*: Noice =
|
||||
Noice(hidden: 15)
|
||||
9
tests/generics/t3770.nim
Normal file
9
tests/generics/t3770.nim
Normal file
@@ -0,0 +1,9 @@
|
||||
# bug #3770
|
||||
import m3770
|
||||
|
||||
doAssert $jjj() == "(hidden: 15)" # works
|
||||
|
||||
proc someGeneric(_: type) =
|
||||
doAssert $jjj() == "(hidden: 15)" # fails: "Error: the field 'hidden' is not accessible."
|
||||
|
||||
someGeneric(int)
|
||||
Reference in New Issue
Block a user