diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim index d9317c3320..769f88b6f2 100644 --- a/compiler/semobjconstr.nim +++ b/compiler/semobjconstr.nim @@ -486,6 +486,11 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType # we have to watch out, there are also 'owned proc' types that can be used # multiple times as long as they don't have closures. result.typ.incl tfHasOwned + if t.kind == tyForward and efDetermineType in flags: + # a forward object type does not error during determine-type analysis; + # it now stays unresolved long enough for the existing delayed field-default pass to resolve it after the type section finishes. + result.typ = t + return result if t.kind != tyObject: return localErrorNode(c, result, if t.kind != tyGenericBody: "object constructor needs an object type".dup(addTypeNodeDeclaredLoc(c.config, t)) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 4c2d84c29f..8009f7293c 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -370,6 +370,7 @@ proc semFieldDefault(c: PContext; owner, expectedType: PType; field: PNode): PTy propagateToOwner(owner, result) proc semDelayedFieldDefault(c: PContext; owner, expectedType: PType; field: PNode) = + resetSemFlag(field[^1]) fitDefaultNode(c, field[^1], expectedType) propagateToOwner(owner, field[^1].typ.skipIntLit(c.idgen)) diff --git a/tests/objects/tobject_default_value.nim b/tests/objects/tobject_default_value.nim index 5b0a5cd8e6..69e35bf826 100644 --- a/tests/objects/tobject_default_value.nim +++ b/tests/objects/tobject_default_value.nim @@ -833,4 +833,37 @@ proc overloaded[T: object](x: T) = var v: typeof(val) overloaded(v) -overloaded(Thing()) \ No newline at end of file +overloaded(Thing()) + +block: + type + Foo = object + x = Bar() + + Bar = object + x: int + + var f = Foo() + doassert f.x.x == 0 + +block: + type + Foo = object + x = Bar(x: 55) + + Bar = object + x: int + + var f = Foo() + doassert f.x.x == 55 + +block: + type + Bar = object + x: int + + Foo = object + x = Bar() + + var f = Foo() + doassert f.x.x == 0