Skip to content

Commit

Permalink
skip field visibility on resem and fix some generics issues (#569)
Browse files Browse the repository at this point in the history
* skip field visibility on resem and fix some generics issues

* add test for scoped type inst

* fix types
  • Loading branch information
metagn authored Feb 17, 2025
1 parent d4d4717 commit 1272cb0
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 32 deletions.
52 changes: 37 additions & 15 deletions src/nimony/sem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,9 @@ proc semTemplateCall(c: var SemContext; it: var Item; fnId: SymId; beforeCall: i
shrink c.dest, beforeCall
expandedInto.addParRi() # extra token so final `inc` doesn't break
var a = Item(n: cursorAt(expandedInto, 0), typ: c.types.autoType)
inc c.routine.inInst
semExpr c, a
dec c.routine.inInst
it.typ = a.typ
it.kind = a.kind
else:
Expand Down Expand Up @@ -1501,6 +1503,16 @@ proc resolveOverloads(c: var SemContext; it: var Item; cs: var CallState) =
returnType = semReturnType(c, subsReturnType)
swap c.dest, instReturnType
else:
if isMagic == NonMagicCall and cs.hasGenericArgs:
# add back explicit generic args since we cannot instantiate
var invokeBuf = createTokenBuf(16)
invokeBuf.addParLe(AtX, cs.fn.n.info)
invokeBuf.add symToken(finalFn.sym, cs.fn.n.info)
var genericArgsRead = genericArgs
while genericArgsRead.kind != ParRi:
takeTree invokeBuf, genericArgsRead
invokeBuf.addParRi()
replace c.dest, beginRead(invokeBuf), cs.beforeCall+1
if matched.returnType.kind == DotToken:
returnType = matched.returnType
else:
Expand Down Expand Up @@ -1762,23 +1774,25 @@ proc findObjFieldConsiderVis(c: var SemContext; decl: TypeDecl; name: StrId): Ob
if impl.typeKind in {RefT, PtrT}:
inc impl
result = findObjFieldAux(impl, name)
if result.level == 0:
result.rootOwner = genericRootSym(decl)
if result.level >= 0:
# check visibility
var visible = false
if result.exported:
visible = true
else:
let owner = result.rootOwner
if owner == SymId(0):
if c.routine.inInst == 0:
# only check visibility during first semcheck
if result.level == 0:
result.rootOwner = genericRootSym(decl)
if result.level >= 0:
# check visibility
var visible = false
if result.exported:
visible = true
else:
let ownerModule = extractModule(pool.syms[owner])
visible = ownerModule == "" or ownerModule == c.thisModuleSuffix
if not visible:
# treat as undeclared
result = ObjField(level: -1)
let owner = result.rootOwner
if owner == SymId(0):
visible = true
else:
let ownerModule = extractModule(pool.syms[owner])
visible = ownerModule == "" or ownerModule == c.thisModuleSuffix
if not visible:
# treat as undeclared
result = ObjField(level: -1)

proc findModuleSymbol(n: Cursor): SymId =
result = SymId(0)
Expand Down Expand Up @@ -2557,6 +2571,10 @@ proc semInvoke(c: var SemContext; n: var Cursor) =
var sub = createTokenBuf(30)
subsGenericTypeFromArgs c, sub, info, headId, targetSym, decl, args
c.dest.endRead()
let oldScope = c.currentScope
# move to top level scope:
while c.currentScope.up != nil:
c.currentScope = c.currentScope.up
var phase = SemcheckTopLevelSyms
var topLevel = createTokenBuf(30)
swap c.phase, phase
Expand All @@ -2571,6 +2589,7 @@ proc semInvoke(c: var SemContext; n: var Cursor) =
semTypeSection c, tn
swap c.dest, instance
swap c.phase, phase
c.currentScope = oldScope
publish targetSym, ensureMove instance
c.dest.shrink typeStart
c.dest.add symToken(targetSym, info)
Expand Down Expand Up @@ -3082,6 +3101,7 @@ proc semGenericParams(c: var SemContext; n: var Cursor) =
semGenericParam c, n
takeParRi c, n
elif n == $InvokeT:
inc c.routine.inInst
takeTree c, n
else:
buildErr c, n.info, "expected '.' or 'typevars'"
Expand Down Expand Up @@ -3908,6 +3928,7 @@ proc semTypeSection(c: var SemContext; n: var Cursor) =
c.phase != SemcheckTopLevelSyms):
var isGeneric: bool
let prevGeneric = c.routine.inGeneric
let prevInst = c.routine.inInst
if n.kind == DotToken:
takeToken c, n
isGeneric = false
Expand Down Expand Up @@ -3935,6 +3956,7 @@ proc semTypeSection(c: var SemContext; n: var Cursor) =
if isGeneric:
closeScope c
c.routine.inGeneric = prevGeneric # revert increase by semGenericParams
c.routine.inInst = prevInst
else:
c.takeTree n # generics
discard semTypePragmas(c, n, delayed.s.name, beforeExportMarker)
Expand Down
2 changes: 1 addition & 1 deletion src/nimony/semdata.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type
TypeCursor* = Cursor
SemRoutine* {.acyclic.} = ref object
kind*: SymKind
inGeneric*, inLoop*, inBlock*: int
inGeneric*, inLoop*, inBlock*, inInst*: int
returnType*: TypeCursor
pragmas*: set[PragmaKind]
resId*: SymId
Expand Down
11 changes: 9 additions & 2 deletions tests/nimony/modules/deps/mfieldvis.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@ type Generic*[T] = object
public*: T
private: T

proc getPrivate*(x: Foo): int = x.private
proc getPrivate*[T](x: Generic[T]): T = x.private
proc getPrivate*(x: Foo): int =
let y = Foo(public: x.public, private: x.private)
result = y.private
proc getPrivate*[T](x: Generic[T]): T =
let y = Generic[T](public: x.public, private: x.private)
result = y.private

template getPrivateTempl*(x: Foo): int = x.private
template getPrivateTempl*[T](x: Generic[T]): T = T(x.private)

proc createGeneric*[T](x: int): Generic[T] =
result = Generic[T](public: T(x), private: T(x))
14 changes: 0 additions & 14 deletions tests/nimony/modules/tfieldviserr.nim
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,3 @@ discard foo.private

var generic = Generic[int](private: 123)
discard generic.private

when false: # compiles and should compile but cannot test yet
var foo = Foo(public: 123)
discard getPrivate(foo)
discard getPrivateTempl(foo)

var generic = Generic[int](public: 123)
discard getPrivate(foo)
discard getPrivateTempl(foo)

template resem() =
foo = Foo(public: 123)
generic = Generic[int](public: 123)
resem()
20 changes: 20 additions & 0 deletions tests/nimony/modules/tfieldvisworking.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import deps/mfieldvis

var foo = Foo(public: 123)
discard getPrivate(foo)
discard getPrivateTempl(foo)

var generic = Generic[int](public: 123)
discard getPrivate(foo)
discard getPrivateTempl(foo)
generic = createGeneric[int](456)

template resem() =
foo = Foo(public: 123)
generic = Generic[int](public: 123)
discard getPrivateTempl(generic)
generic = createGeneric[int](456)
resem()

proc scope() =
let differentGeneric = createGeneric[float](123)

0 comments on commit 1272cb0

Please sign in to comment.