mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-22 15:25:22 +00:00
first implementation of package level types that allow forwarding across module boundaries
This commit is contained in:
@@ -1668,5 +1668,5 @@ template hasDestructor*(t: PType): bool = tfHasAsgn in t.flags
|
||||
template incompleteType*(t: PType): bool =
|
||||
t.sym != nil and {sfForward, sfNoForward} * t.sym.flags == {sfForward}
|
||||
|
||||
template typeCompleted*(t: PType) =
|
||||
incl t.sym.flags, sfNoForward
|
||||
template typeCompleted*(s: PSym) =
|
||||
incl s.flags, sfNoForward
|
||||
|
||||
@@ -155,7 +155,7 @@ proc ensureNoMissingOrUnusedSymbols(scope: PScope) =
|
||||
var s = initTabIter(it, scope.symbols)
|
||||
var missingImpls = 0
|
||||
while s != nil:
|
||||
if sfForward in s.flags:
|
||||
if sfForward in s.flags and s.kind != skType:
|
||||
# too many 'implementation of X' errors are annoying
|
||||
# and slow 'suggest' down:
|
||||
if missingImpls == 0:
|
||||
|
||||
@@ -55,7 +55,7 @@ const
|
||||
wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow,
|
||||
wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef,
|
||||
wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked,
|
||||
wBorrow, wGcSafe, wExportNims, wPartial, wUsed, wExplain, wForward}
|
||||
wBorrow, wGcSafe, wExportNims, wPartial, wUsed, wExplain, wPackage}
|
||||
fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
|
||||
wImportCpp, wImportObjC, wError, wGuard, wBitsize, wUsed}
|
||||
varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
|
||||
@@ -799,7 +799,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
|
||||
noVal(it)
|
||||
if sym.typ == nil or tfFinal in sym.typ.flags: invalidPragma(it)
|
||||
else: incl(sym.typ.flags, tfInheritable)
|
||||
of wForward:
|
||||
of wPackage:
|
||||
noVal(it)
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
else: incl(sym.flags, sfForward)
|
||||
|
||||
@@ -775,21 +775,52 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) =
|
||||
checkSonsLen(a, 3)
|
||||
let name = a.sons[0]
|
||||
var s: PSym
|
||||
if name.kind == nkDotExpr:
|
||||
s = qualifiedLookUp(c, name, {checkUndeclared, checkModule})
|
||||
if s.kind != skType or
|
||||
s.typ.skipTypes(abstractPtrs).kind != tyObject or
|
||||
tfPartial notin s.typ.skipTypes(abstractPtrs).flags:
|
||||
localError(name.info, "only .partial objects can be extended")
|
||||
if name.kind == nkDotExpr and a[2].kind == nkObjectTy:
|
||||
let pkgName = considerQuotedIdent(name[0])
|
||||
let typName = considerQuotedIdent(name[1])
|
||||
let pkg = c.graph.packageSyms.strTableGet(pkgName)
|
||||
if pkg.isNil or pkg.kind != skPackage:
|
||||
localError(name.info, "unknown package name: " & pkgName.s)
|
||||
else:
|
||||
let typsym = pkg.tab.strTableGet(typName)
|
||||
if typsym.isNil:
|
||||
s = semIdentDef(c, name[1], skType)
|
||||
s.typ = newTypeS(tyObject, c)
|
||||
s.typ.sym = s
|
||||
s.flags.incl sfForward
|
||||
pkg.tab.strTableAdd s
|
||||
addInterfaceDecl(c, s)
|
||||
elif typsym.kind == skType and sfForward in typsym.flags:
|
||||
s = typsym
|
||||
addInterfaceDecl(c, s)
|
||||
else:
|
||||
localError(name.info, typsym.name.s & " is not a type that can be forwarded")
|
||||
s = typsym
|
||||
when false:
|
||||
s = qualifiedLookUp(c, name, {checkUndeclared, checkModule})
|
||||
if s.kind != skType or
|
||||
s.typ.skipTypes(abstractPtrs).kind != tyObject or
|
||||
tfPartial notin s.typ.skipTypes(abstractPtrs).flags:
|
||||
localError(name.info, "only .partial objects can be extended")
|
||||
else:
|
||||
s = semIdentDef(c, name, skType)
|
||||
s.typ = newTypeS(tyForward, c)
|
||||
s.typ.sym = s # process pragmas:
|
||||
if name.kind == nkPragmaExpr:
|
||||
pragma(c, s, name.sons[1], typePragmas)
|
||||
if sfForward in s.flags: strTableAdd(c.graph.forwardedTypes, s)
|
||||
if sfForward in s.flags:
|
||||
# check if the symbol already exists:
|
||||
let pkg = c.module.owner
|
||||
if not isTopLevel(c) or pkg.isNil:
|
||||
localError(name.info, "only top level types in a package can be 'forward'")
|
||||
else:
|
||||
let typsym = pkg.tab.strTableGet(s.name)
|
||||
if typsym != nil:
|
||||
typeCompleted(typsym)
|
||||
s = typsym
|
||||
# add it here, so that recursive types are possible:
|
||||
if sfGenSym notin s.flags: addInterfaceDecl(c, s)
|
||||
|
||||
a.sons[0] = newSymNode(s)
|
||||
|
||||
proc checkCovariantParamsUsages(genericType: PType) =
|
||||
|
||||
@@ -55,7 +55,7 @@ type
|
||||
wFloatchecks, wNanChecks, wInfChecks,
|
||||
wAssertions, wPatterns, wWarnings,
|
||||
wHints, wOptimization, wRaises, wWrites, wReads, wSize, wEffects, wTags,
|
||||
wDeadCodeElim, wSafecode, wForward, wNoForward, wReorder, wNoRewrite,
|
||||
wDeadCodeElim, wSafecode, wPackage, wNoForward, wReorder, wNoRewrite,
|
||||
wPragma,
|
||||
wCompileTime, wNoInit,
|
||||
wPassc, wPassl, wBorrow, wDiscardable,
|
||||
@@ -143,7 +143,7 @@ const
|
||||
|
||||
"assertions", "patterns", "warnings", "hints",
|
||||
"optimization", "raises", "writes", "reads", "size", "effects", "tags",
|
||||
"deadcodeelim", "safecode", "forward", "noforward", "reorder", "norewrite",
|
||||
"deadcodeelim", "safecode", "package", "noforward", "reorder", "norewrite",
|
||||
"pragma",
|
||||
"compiletime", "noinit",
|
||||
"passc", "passl", "borrow", "discardable", "fieldchecks",
|
||||
|
||||
@@ -6,12 +6,8 @@ discard """
|
||||
{.this: self.}
|
||||
|
||||
type
|
||||
Foo {.partial.} = object
|
||||
a, b: int
|
||||
|
||||
type
|
||||
tupcomingfeatures.Foo = object
|
||||
x: int
|
||||
Foo = object
|
||||
a, b, x: int
|
||||
|
||||
proc yay(self: Foo) =
|
||||
echo a, " ", b, " ", x
|
||||
|
||||
1
todo.txt
1
todo.txt
@@ -23,7 +23,6 @@ Not critical for 1.0
|
||||
- make '--implicitStatic:on' the default; then we can also clean up the
|
||||
'static[T]' mess in the compiler!
|
||||
- ``not`` or ``~`` for the effects system
|
||||
- document and stress test ``.partial`` object declarations
|
||||
- figure out why C++ bootstrapping is so much slower
|
||||
- The bitwise 'not' operator cold be renamed to 'bnot' to
|
||||
prevent 'not 4 == 5' from compiling. -> requires 'mixin' annotation for procs!
|
||||
|
||||
Reference in New Issue
Block a user