diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2023-03-21 22:22:07 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-21 15:22:07 +0100 |
commit | c814c4d993675551ecf388b6a583c471a1b8bc5e (patch) | |
tree | 0add411394b804e4de42fd19ce40ddaed4bb5d20 | |
parent | f7e3af0c2d68035a649cf9449cc4e02a7ea59e84 (diff) | |
download | Nim-c814c4d993675551ecf388b6a583c471a1b8bc5e.tar.gz |
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`
-rw-r--r-- | compiler/ast.nim | 4 | ||||
-rw-r--r-- | compiler/sem.nim | 8 | ||||
-rw-r--r-- | compiler/semgnrc.nim | 22 | ||||
-rw-r--r-- | compiler/semobjconstr.nim | 4 | ||||
-rw-r--r-- | compiler/semtypes.nim | 4 | ||||
-rw-r--r-- | compiler/vmgen.nim | 2 | ||||
-rw-r--r-- | tests/generics/m3770.nim | 6 | ||||
-rw-r--r-- | tests/generics/t3770.nim | 9 |
8 files changed, 48 insertions, 11 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index f93c8d910..b5306c423 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -510,7 +510,7 @@ type nfLastRead # this node is a last read nfFirstWrite # this node is a first write nfHasComment # node has a comment - nfUseDefaultField # node has a default value (object constructor) + nfSkipFieldChecking # node skips field visable checking TNodeFlags* = set[TNodeFlag] TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 46) @@ -1081,7 +1081,7 @@ const nfIsRef, nfIsPtr, nfPreventCg, nfLL, nfFromTemplate, nfDefaultRefsParam, nfExecuteOnReload, nfLastRead, - nfFirstWrite, nfUseDefaultField} + nfFirstWrite, nfSkipFieldChecking} namePos* = 0 patternPos* = 1 # empty except for term rewriting macros genericParamsPos* = 2 diff --git a/compiler/sem.nim b/compiler/sem.nim index 48a7d56c8..1c15f905e 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -572,7 +572,7 @@ proc defaultFieldsForTuple(c: PContext, recNode: PNode, hasDefault: var bool): s let asgnExpr = defaultNodeField(c, recNode, recNode.typ) if asgnExpr != nil: hasDefault = true - asgnExpr.flags.incl nfUseDefaultField + asgnExpr.flags.incl nfSkipFieldChecking result.add newTree(nkExprColonExpr, recNode, asgnExpr) return @@ -582,7 +582,7 @@ proc defaultFieldsForTuple(c: PContext, recNode: PNode, hasDefault: var bool): s newSymNode(getSysMagic(c.graph, recNode.info, "zeroDefault", mZeroDefault)), newNodeIT(nkType, recNode.info, asgnType) ) - asgnExpr.flags.incl nfUseDefaultField + asgnExpr.flags.incl nfSkipFieldChecking asgnExpr.typ = recType result.add newTree(nkExprColonExpr, recNode, asgnExpr) else: @@ -604,7 +604,7 @@ proc defaultFieldsForTheUninitialized(c: PContext, recNode: PNode): seq[PNode] = defaultValue = newIntNode(nkIntLit#[c.graph]#, 0) defaultValue.typ = discriminator.typ selectedBranch = recNode.pickCaseBranchIndex defaultValue - defaultValue.flags.incl nfUseDefaultField + defaultValue.flags.incl nfSkipFieldChecking result.add newTree(nkExprColonExpr, discriminator, defaultValue) result.add defaultFieldsForTheUninitialized(c, recNode[selectedBranch][^1]) of nkSym: @@ -616,7 +616,7 @@ proc defaultFieldsForTheUninitialized(c: PContext, recNode: PNode): seq[PNode] = let asgnExpr = defaultNodeField(c, recNode, recType) if asgnExpr != nil: asgnExpr.typ = recType - asgnExpr.flags.incl nfUseDefaultField + asgnExpr.flags.incl nfSkipFieldChecking result.add newTree(nkExprColonExpr, recNode, asgnExpr) else: doAssert false diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 0827e6845..fa37af850 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -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: @@ -245,7 +249,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 @@ -254,7 +260,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 @@ -493,6 +501,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) diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim index 29067cfa4..2d95da50d 100644 --- a/compiler/semobjconstr.nim +++ b/compiler/semobjconstr.nim @@ -76,7 +76,7 @@ proc semConstrField(c: PContext, flags: TExprFlags, let assignment = locateFieldInInitExpr(c, field, initExpr) if assignment != nil: if nfSem in assignment.flags: return assignment[1] - if nfUseDefaultField in assignment[1].flags: + if nfSkipFieldChecking in assignment[1].flags: discard elif not fieldVisible(c, field): localError(c.config, initExpr.info, @@ -178,7 +178,7 @@ proc collectOrAddMissingCaseFields(c: PContext, branchNode: PNode, newSymNode(getSysMagic(c.graph, constrCtx.initExpr.info, "zeroDefault", mZeroDefault)), newNodeIT(nkType, constrCtx.initExpr.info, asgnType) ) - asgnExpr.flags.incl nfUseDefaultField + asgnExpr.flags.incl nfSkipFieldChecking asgnExpr.typ = recTyp defaults.add newTree(nkExprColonExpr, newSymNode(sym), asgnExpr) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 26493703d..2f485d65b 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -519,7 +519,7 @@ proc semTuple(c: PContext, n: PNode, prev: PType): PType = let fSym = newSymNode(field) if hasDefaultField: fSym.sym.ast = a[^1] - fSym.sym.ast.flags.incl nfUseDefaultField + fSym.sym.ast.flags.incl nfSkipFieldChecking result.n.add fSym addSonSkipIntLit(result, typ, c.idgen) styleCheckDef(c, a[j].info, field) @@ -868,7 +868,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, let fSym = newSymNode(f) if hasDefaultField: fSym.sym.ast = n[^1] - fSym.sym.ast.flags.incl nfUseDefaultField + fSym.sym.ast.flags.incl nfSkipFieldChecking if a.kind == nkEmpty: father.add fSym else: a.add fSym styleCheckDef(c, f) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 937d4b095..aa4a83900 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1829,7 +1829,7 @@ proc getNullValueAux(t: PType; obj: PNode, result: PNode; conf: ConfigRef; currP let field = newNodeI(nkExprColonExpr, result.info) field.add(obj) let value = getNullValue(obj.sym.typ, result.info, conf) - value.flags.incl nfUseDefaultField + value.flags.incl nfSkipFieldChecking field.add(value) result.add field doAssert obj.sym.position == currPosition diff --git a/tests/generics/m3770.nim b/tests/generics/m3770.nim new file mode 100644 index 000000000..2c6a2bd11 --- /dev/null +++ b/tests/generics/m3770.nim @@ -0,0 +1,6 @@ +type + Noice* = object + hidden: int + +template jjj*: Noice = + Noice(hidden: 15) \ No newline at end of file diff --git a/tests/generics/t3770.nim b/tests/generics/t3770.nim new file mode 100644 index 000000000..fa9c97df8 --- /dev/null +++ b/tests/generics/t3770.nim @@ -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) |