{"action":"created","comment":{"url":"https://api.github.com/repos/D-Programming-Language/dmd/pulls/comments/57997454","id":57997454,"diff_hunk":"@@ -215,78 +208,136 @@ public:\n             sd.semanticTypeInfoMembers();\n     }\n \n-    abstract void finalizeSize();\n-\n-    override final uint size(Loc loc)\n+    /***************************************\n+     * Find all instance fields, then push them into `fields`.\n+     *\n+     * Runs semantic() for all instance field variables, but also\n+     * the field types can reamin yet not resolved forward references,\n+     * except direct recursive definitions.\n+     * After the process sizeok is set to SIZEOKfwd.\n+     *\n+     * Returns:\n+     *      false if any errors occur.\n+     */\n+    final bool determineFields()\n     {\n-        //printf(\"AggregateDeclaration::size() %s, scope = %p\\n\", toChars(), scope);\n-        if (loc.linnum == 0)\n-            loc = this.loc;\n-        if (sizeok != SIZEOKdone && _scope)\n-        {\n-            semantic(null);\n+        if (sizeok != SIZEOKnone)\n+            return true;\n \n-            // Determine the instance size of base class first.\n-            if (ClassDeclaration cd = isClassDeclaration())\n-                cd.baseClass.size(loc);\n-        }\n+        //printf(\"determineFields() %s, fields.dim = %d\\n\", toChars(), fields.dim);\n \n-        if (sizeok != SIZEOKdone && members)\n+        extern (C++) static int func(Dsymbol s, void* param)\n         {\n-            /* See if enough is done to determine the size,\n-             * meaning all the fields are done.\n-             */\n-            struct SV\n+            auto v = s.isVarDeclaration();\n+            if (!v)\n+                return 0;\n+            if (v.storage_class & STCmanifest)\n+                return 0;\n+\n+            if (v._scope)\n+                v.semantic(null);\n+            if (v.aliassym)\n+                return 0;   // If this variable was really a tuple, skip it.\n+\n+            if (v.storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCmanifest | STCctfe | STCtemplateparameter))\n+                return 0;\n+            if (!v.isField() || v.sem < SemanticDone)\n+                return 1;   // unresolvable forward referernce\n+\n+            auto ad = cast(AggregateDeclaration)param;\n+            ad.fields.push(v);\n+\n+            if (v.storage_class & STCref)\n+                return 0;\n+            auto tv = v.type.baseElemOf();\n+            if (tv.ty != Tstruct)\n+                return 0;\n+            if (ad == (cast(TypeStruct)tv).sym)\n             {\n-                /* Returns:\n-                 *  0       this member doesn't need further processing to determine struct size\n-                 *  1       this member does\n-                 */\n-                extern (C++) static int func(Dsymbol s, void* param)\n-                {\n-                    VarDeclaration v = s.isVarDeclaration();\n-                    if (v)\n-                    {\n-                        /* Bugzilla 12799: enum a = ...; is a VarDeclaration and\n-                         * STCmanifest is already set in parssing stage. So we can\n-                         * check this before the semantic() call.\n-                         */\n-                        if (v.storage_class & STCmanifest)\n-                            return 0;\n-\n-                        if (v._scope)\n-                            v.semantic(null);\n-                        if (v.storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCmanifest | STCctfe | STCtemplateparameter))\n-                            return 0;\n-                        if (v.isField() && v.sem >= SemanticDone)\n-                            return 0;\n-                        return 1;\n-                    }\n-                    return 0;\n-                }\n+                const(char)* psz = (v.type.toBasetype().ty == Tsarray) ? \"static array of \" : \"\";\n+                ad.error(\"cannot have field %s with %ssame struct type\", v.toChars(), psz);\n+                ad.type = Type.terror;\n+                ad.errors = true;\n+                return 1;\n             }\n+            return 0;\n+        }\n \n-            SV sv;\n-            for (size_t i = 0; i < members.dim; i++)\n-            {\n-                Dsymbol s = (*members)[i];\n-                if (s.apply(&SV.func, &sv))\n-                    goto L1;\n-            }\n-            finalizeSize();\n+        fields.setDim(0);\n \n-        L1:\n+        for (size_t i = 0; i < members.dim; i++)\n+        {\n+            auto s = (*members)[i];\n+            if (s.apply(&func, cast(void*)this))\n+                return false;\n         }\n \n+        if (sizeok != SIZEOKdone)\n+            sizeok = SIZEOKfwd;\n+\n+        return true;\n+    }\n+\n+    /***************************************\n+     * Collect all instance fields, then determine instance size.\n+     * Returns:\n+     *      false if failed to determine the size.\n+     */\n+    final bool determineSize(Loc loc)\n+    {\n+        //printf(\"AggregateDeclaration::determineSize() %s, sizeok = %d\\n\", toChars(), sizeok);\n+\n+        // The previous instance size finalizing had:\n+        if (type.ty == Terror)\n+            return false;   // failed already\n+        if (sizeok == SIZEOKdone)\n+            return true;    // succeeded\n+\n         if (!members)\n         {\n             error(loc, \"unknown size\");\n+            return true;","path":"src/aggregate.d","position":188,"original_position":188,"commit_id":"a48df86059aa37df32dcf1d58076900170887ebd","original_commit_id":"a085eb8a42c677410471ff07f70fa58ff045f3a3","user":{"login":"WalterBright","id":568298,"avatar_url":"https://avatars.githubusercontent.com/u/568298?v=3","gravatar_id":"","url":"https://api.github.com/users/WalterBright","html_url":"https://github.com/WalterBright","followers_url":"https://api.github.com/users/WalterBright/followers","following_url":"https://api.github.com/users/WalterBright/following{/other_user}","gists_url":"https://api.github.com/users/WalterBright/gists{/gist_id}","starred_url":"https://api.github.com/users/WalterBright/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/WalterBright/subscriptions","organizations_url":"https://api.github.com/users/WalterBright/orgs","repos_url":"https://api.github.com/users/WalterBright/repos","events_url":"https://api.github.com/users/WalterBright/events{/privacy}","received_events_url":"https://api.github.com/users/WalterBright/received_events","type":"User","site_admin":false},"body":"Doesn't \"unknown size\" mean it failed and should return false?","created_at":"2016-03-31T03:40:35Z","updated_at":"2016-03-31T03:40:35Z","html_url":"https://github.com/D-Programming-Language/dmd/pull/5500#discussion_r57997454","pull_request_url":"https://api.github.com/repos/D-Programming-Language/dmd/pulls/5500","_links":{"self":{"href":"https://api.github.com/repos/D-Programming-Language/dmd/pulls/comments/57997454"},"html":{"href":"https://github.com/D-Programming-Language/dmd/pull/5500#discussion_r57997454"},"pull_request":{"href":"https://api.github.com/repos/D-Programming-Language/dmd/pulls/5500"}}},"pull_request":{"url":"https://api.github.com/repos/D-Programming-Language/dmd/pulls/5500","id":61712140,"html_url":"https://github.com/D-Programming-Language/dmd/pull/5500","diff_url":"https://github.com/D-Programming-Language/dmd/pull/5500.diff","patch_url":"https://github.com/D-Programming-Language/dmd/pull/5500.patch","issue_url":"https://api.github.com/repos/D-Programming-Language/dmd/issues/5500","number":5500,"state":"open","locked":false,"title":"[REG2.068.0] Issue 15726 - forward reference error for circular classes, RefCounted","user":{"login":"9rnsr","id":254394,"avatar_url":"https://avatars.githubusercontent.com/u/254394?v=3","gravatar_id":"","url":"https://api.github.com/users/9rnsr","html_url":"https://github.com/9rnsr","followers_url":"https://api.github.com/users/9rnsr/followers","following_url":"https://api.github.com/users/9rnsr/following{/other_user}","gists_url":"https://api.github.com/users/9rnsr/gists{/gist_id}","starred_url":"https://api.github.com/users/9rnsr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/9rnsr/subscriptions","organizations_url":"https://api.github.com/users/9rnsr/orgs","repos_url":"https://api.github.com/users/9rnsr/repos","events_url":"https://api.github.com/users/9rnsr/events{/privacy}","received_events_url":"https://api.github.com/users/9rnsr/received_events","type":"User","site_admin":false},"body":"Defer aggregate instance size finalization until semantic2 at maximum\r\n\r\nFrom long ago, an instance size finalization had been done during `semantic()` stage, but it had had a known problem. When an aggregate 'A' tries to build its dtor or postblit, they should know each types of instance fields. But the field type analysis could recursively reach to A's `sematnic()` (especially with `RefCounted`, `Variant`, etc) and it had caused forward reference issues.\r\n\r\nAgainst that, we've tried many ways to detect/break the problematic recursive analysis. So far it has been mostly finished to monitoring `sizeok` field, though it has been still fragile.\r\n\r\nFinally I found an essential solution. During the dtor or postblit building, we don't have to finalize instance size. Instead we just need to know the complete list of instance fields at that time.\r\n\r\nFrom the view, I divide instance size determination process into two stages.\r\n\r\nThe first is `determineFields()`, it collects all instance fields then pushes into `AggregateDeclaration.fields`. It's called in aggregate's `semantic()` and makes preparations for `buildDtor()` and `buildPostBlit()`.\r\n\r\nThe second is `determineSize()`, it requests finalizing each type sizes of instance fields and determine the field offsets. If no declarations' `semantic()` depend on the instance size, `determineSize()` could be deferred until `semantic2()` stage at maximum.\r\n\r\nFinally, a failure of `determineSize()` can mean an existence of unresolvable forward references (circular dependency, use of opaque struct, etc).\r\n\r\n---\r\n\r\nThis PR is intentionally based on master branch, because this change is too big as a regression fix.","created_at":"2016-03-04T13:33:52Z","updated_at":"2016-03-31T03:40:35Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0e16449f26c40d139bc2f448d93f7d0f2c209d6b","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/D-Programming-Language/dmd/pulls/5500/commits","review_comments_url":"https://api.github.com/repos/D-Programming-Language/dmd/pulls/5500/comments","review_comment_url":"https://api.github.com/repos/D-Programming-Language/dmd/pulls/comments{/number}","comments_url":"https://api.github.com/repos/D-Programming-Language/dmd/issues/5500/comments","statuses_url":"https://api.github.com/repos/D-Programming-Language/dmd/statuses/a48df86059aa37df32dcf1d58076900170887ebd","head":{"label":"9rnsr:fix15726","ref":"fix15726","sha":"a48df86059aa37df32dcf1d58076900170887ebd","user":{"login":"9rnsr","id":254394,"avatar_url":"https://avatars.githubusercontent.com/u/254394?v=3","gravatar_id":"","url":"https://api.github.com/users/9rnsr","html_url":"https://github.com/9rnsr","followers_url":"https://api.github.com/users/9rnsr/followers","following_url":"https://api.github.com/users/9rnsr/following{/other_user}","gists_url":"https://api.github.com/users/9rnsr/gists{/gist_id}","starred_url":"https://api.github.com/users/9rnsr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/9rnsr/subscriptions","organizations_url":"https://api.github.com/users/9rnsr/orgs","repos_url":"https://api.github.com/users/9rnsr/repos","events_url":"https://api.github.com/users/9rnsr/events{/privacy}","received_events_url":"https://api.github.com/users/9rnsr/received_events","type":"User","site_admin":false},"repo":{"id":1434550,"name":"dmd","full_name":"9rnsr/dmd","owner":{"login":"9rnsr","id":254394,"avatar_url":"https://avatars.githubusercontent.com/u/254394?v=3","gravatar_id":"","url":"https://api.github.com/users/9rnsr","html_url":"https://github.com/9rnsr","followers_url":"https://api.github.com/users/9rnsr/followers","following_url":"https://api.github.com/users/9rnsr/following{/other_user}","gists_url":"https://api.github.com/users/9rnsr/gists{/gist_id}","starred_url":"https://api.github.com/users/9rnsr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/9rnsr/subscriptions","organizations_url":"https://api.github.com/users/9rnsr/orgs","repos_url":"https://api.github.com/users/9rnsr/repos","events_url":"https://api.github.com/users/9rnsr/events{/privacy}","received_events_url":"https://api.github.com/users/9rnsr/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/9rnsr/dmd","description":"dmd D Programming Language compiler","fork":true,"url":"https://api.github.com/repos/9rnsr/dmd","forks_url":"https://api.github.com/repos/9rnsr/dmd/forks","keys_url":"https://api.github.com/repos/9rnsr/dmd/keys{/key_id}","collaborators_url":"https://api.github.com/repos/9rnsr/dmd/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/9rnsr/dmd/teams","hooks_url":"https://api.github.com/repos/9rnsr/dmd/hooks","issue_events_url":"https://api.github.com/repos/9rnsr/dmd/issues/events{/number}","events_url":"https://api.github.com/repos/9rnsr/dmd/events","assignees_url":"https://api.github.com/repos/9rnsr/dmd/assignees{/user}","branches_url":"https://api.github.com/repos/9rnsr/dmd/branches{/branch}","tags_url":"https://api.github.com/repos/9rnsr/dmd/tags","blobs_url":"https://api.github.com/repos/9rnsr/dmd/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/9rnsr/dmd/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/9rnsr/dmd/git/refs{/sha}","trees_url":"https://api.github.com/repos/9rnsr/dmd/git/trees{/sha}","statuses_url":"https://api.github.com/repos/9rnsr/dmd/statuses/{sha}","languages_url":"https://api.github.com/repos/9rnsr/dmd/languages","stargazers_url":"https://api.github.com/repos/9rnsr/dmd/stargazers","contributors_url":"https://api.github.com/repos/9rnsr/dmd/contributors","subscribers_url":"https://api.github.com/repos/9rnsr/dmd/subscribers","subscription_url":"https://api.github.com/repos/9rnsr/dmd/subscription","commits_url":"https://api.github.com/repos/9rnsr/dmd/commits{/sha}","git_commits_url":"https://api.github.com/repos/9rnsr/dmd/git/commits{/sha}","comments_url":"https://api.github.com/repos/9rnsr/dmd/comments{/number}","issue_comment_url":"https://api.github.com/repos/9rnsr/dmd/issues/comments{/number}","contents_url":"https://api.github.com/repos/9rnsr/dmd/contents/{+path}","compare_url":"https://api.github.com/repos/9rnsr/dmd/compare/{base}...{head}","merges_url":"https://api.github.com/repos/9rnsr/dmd/merges","archive_url":"https://api.github.com/repos/9rnsr/dmd/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/9rnsr/dmd/downloads","issues_url":"https://api.github.com/repos/9rnsr/dmd/issues{/number}","pulls_url":"https://api.github.com/repos/9rnsr/dmd/pulls{/number}","milestones_url":"https://api.github.com/repos/9rnsr/dmd/milestones{/number}","notifications_url":"https://api.github.com/repos/9rnsr/dmd/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/9rnsr/dmd/labels{/name}","releases_url":"https://api.github.com/repos/9rnsr/dmd/releases{/id}","deployments_url":"https://api.github.com/repos/9rnsr/dmd/deployments","created_at":"2011-03-03T10:24:37Z","updated_at":"2015-08-23T13:19:40Z","pushed_at":"2016-03-31T01:30:56Z","git_url":"git://github.com/9rnsr/dmd.git","ssh_url":"git@github.com:9rnsr/dmd.git","clone_url":"https://github.com/9rnsr/dmd.git","svn_url":"https://github.com/9rnsr/dmd","homepage":"d-programming-language.org","size":66289,"stargazers_count":2,"watchers_count":2,"language":"D","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":2,"default_branch":"master"}},"base":{"label":"D-Programming-Language:master","ref":"master","sha":"b2cb2f003a0c82d4fcf4f45b5280b233d8f80390","user":{"login":"D-Programming-Language","id":565913,"avatar_url":"https://avatars.githubusercontent.com/u/565913?v=3","gravatar_id":"","url":"https://api.github.com/users/D-Programming-Language","html_url":"https://github.com/D-Programming-Language","followers_url":"https://api.github.com/users/D-Programming-Language/followers","following_url":"https://api.github.com/users/D-Programming-Language/following{/other_user}","gists_url":"https://api.github.com/users/D-Programming-Language/gists{/gist_id}","starred_url":"https://api.github.com/users/D-Programming-Language/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/D-Programming-Language/subscriptions","organizations_url":"https://api.github.com/users/D-Programming-Language/orgs","repos_url":"https://api.github.com/users/D-Programming-Language/repos","events_url":"https://api.github.com/users/D-Programming-Language/events{/privacy}","received_events_url":"https://api.github.com/users/D-Programming-Language/received_events","type":"Organization","site_admin":false},"repo":{"id":1257070,"name":"dmd","full_name":"D-Programming-Language/dmd","owner":{"login":"D-Programming-Language","id":565913,"avatar_url":"https://avatars.githubusercontent.com/u/565913?v=3","gravatar_id":"","url":"https://api.github.com/users/D-Programming-Language","html_url":"https://github.com/D-Programming-Language","followers_url":"https://api.github.com/users/D-Programming-Language/followers","following_url":"https://api.github.com/users/D-Programming-Language/following{/other_user}","gists_url":"https://api.github.com/users/D-Programming-Language/gists{/gist_id}","starred_url":"https://api.github.com/users/D-Programming-Language/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/D-Programming-Language/subscriptions","organizations_url":"https://api.github.com/users/D-Programming-Language/orgs","repos_url":"https://api.github.com/users/D-Programming-Language/repos","events_url":"https://api.github.com/users/D-Programming-Language/events{/privacy}","received_events_url":"https://api.github.com/users/D-Programming-Language/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/D-Programming-Language/dmd","description":"dmd D Programming Language compiler","fork":false,"url":"https://api.github.com/repos/D-Programming-Language/dmd","forks_url":"https://api.github.com/repos/D-Programming-Language/dmd/forks","keys_url":"https://api.github.com/repos/D-Programming-Language/dmd/keys{/key_id}","collaborators_url":"https://api.github.com/repos/D-Programming-Language/dmd/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/D-Programming-Language/dmd/teams","hooks_url":"https://api.github.com/repos/D-Programming-Language/dmd/hooks","issue_events_url":"https://api.github.com/repos/D-Programming-Language/dmd/issues/events{/number}","events_url":"https://api.github.com/repos/D-Programming-Language/dmd/events","assignees_url":"https://api.github.com/repos/D-Programming-Language/dmd/assignees{/user}","branches_url":"https://api.github.com/repos/D-Programming-Language/dmd/branches{/branch}","tags_url":"https://api.github.com/repos/D-Programming-Language/dmd/tags","blobs_url":"https://api.github.com/repos/D-Programming-Language/dmd/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/D-Programming-Language/dmd/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/D-Programming-Language/dmd/git/refs{/sha}","trees_url":"https://api.github.com/repos/D-Programming-Language/dmd/git/trees{/sha}","statuses_url":"https://api.github.com/repos/D-Programming-Language/dmd/statuses/{sha}","languages_url":"https://api.github.com/repos/D-Programming-Language/dmd/languages","stargazers_url":"https://api.github.com/repos/D-Programming-Language/dmd/stargazers","contributors_url":"https://api.github.com/repos/D-Programming-Language/dmd/contributors","subscribers_url":"https://api.github.com/repos/D-Programming-Language/dmd/subscribers","subscription_url":"https://api.github.com/repos/D-Programming-Language/dmd/subscription","commits_url":"https://api.github.com/repos/D-Programming-Language/dmd/commits{/sha}","git_commits_url":"https://api.github.com/repos/D-Programming-Language/dmd/git/commits{/sha}","comments_url":"https://api.github.com/repos/D-Programming-Language/dmd/comments{/number}","issue_comment_url":"https://api.github.com/repos/D-Programming-Language/dmd/issues/comments{/number}","contents_url":"https://api.github.com/repos/D-Programming-Language/dmd/contents/{+path}","compare_url":"https://api.github.com/repos/D-Programming-Language/dmd/compare/{base}...{head}","merges_url":"https://api.github.com/repos/D-Programming-Language/dmd/merges","archive_url":"https://api.github.com/repos/D-Programming-Language/dmd/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/D-Programming-Language/dmd/downloads","issues_url":"https://api.github.com/repos/D-Programming-Language/dmd/issues{/number}","pulls_url":"https://api.github.com/repos/D-Programming-Language/dmd/pulls{/number}","milestones_url":"https://api.github.com/repos/D-Programming-Language/dmd/milestones{/number}","notifications_url":"https://api.github.com/repos/D-Programming-Language/dmd/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/D-Programming-Language/dmd/labels{/name}","releases_url":"https://api.github.com/repos/D-Programming-Language/dmd/releases{/id}","deployments_url":"https://api.github.com/repos/D-Programming-Language/dmd/deployments","created_at":"2011-01-15T06:53:53Z","updated_at":"2016-03-29T14:36:23Z","pushed_at":"2016-03-31T01:34:21Z","git_url":"git://github.com/D-Programming-Language/dmd.git","ssh_url":"git@github.com:D-Programming-Language/dmd.git","clone_url":"https://github.com/D-Programming-Language/dmd.git","svn_url":"https://github.com/D-Programming-Language/dmd","homepage":"dlang.org","size":87046,"stargazers_count":1205,"watchers_count":1205,"language":"D","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":362,"mirror_url":null,"open_issues_count":143,"forks":362,"open_issues":143,"watchers":1205,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/D-Programming-Language/dmd/pulls/5500"},"html":{"href":"https://github.com/D-Programming-Language/dmd/pull/5500"},"issue":{"href":"https://api.github.com/repos/D-Programming-Language/dmd/issues/5500"},"comments":{"href":"https://api.github.com/repos/D-Programming-Language/dmd/issues/5500/comments"},"review_comments":{"href":"https://api.github.com/repos/D-Programming-Language/dmd/pulls/5500/comments"},"review_comment":{"href":"https://api.github.com/repos/D-Programming-Language/dmd/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/D-Programming-Language/dmd/pulls/5500/commits"},"statuses":{"href":"https://api.github.com/repos/D-Programming-Language/dmd/statuses/a48df86059aa37df32dcf1d58076900170887ebd"}}}}