summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ast.nim4
-rw-r--r--compiler/sem.nim8
-rw-r--r--compiler/semgnrc.nim22
-rw-r--r--compiler/semobjconstr.nim4
-rw-r--r--compiler/semtypes.nim4
-rw-r--r--compiler/vmgen.nim2
-rw-r--r--tests/generics/m3770.nim6
-rw-r--r--tests/generics/t3770.nim9
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)