)]}'
{
  "commit": "a85e4f4a1752d0cbc0b4c054c3c67c8b2d5ce161",
  "tree": "edc18d71bf8229091e074f9c02adfcdfd2573b4f",
  "parents": [
    "aaeeab9f5217cae9043d84fe2003c9d768d5cd91"
  ],
  "author": {
    "name": "Paul Berry",
    "email": "paulberry@google.com",
    "time": "Tue Aug 08 17:26:09 2023 +0000"
  },
  "committer": {
    "name": "dart-internal-monorepo",
    "email": "dart-internal-monorepo@dart-ci-internal.iam.gserviceaccount.com",
    "time": "Tue Aug 08 10:28:17 2023 -0700"
  },
  "message": "Flow analysis: fix field promotion within cascades of non-promotable targets.\n\nPreviously, flow analysis used a hack to make it easy to generate \"why\nnot promoted\" messages when the user tried to promote a non-promotable\nfield: it treated all field accesses as stable for the purpose of\nassigning SSA nodes, but avoided promoting non-promotable fields by\nsetting the `_Reference.isPromotable` flag to `false`. So, for\ninstance, in the following code, both subexpressions `c.i` got\nassigned the same SSA node, even though there\u0027s no guarantee that\n`C.x` will return the same value each time it\u0027s invoked.\n\n    class C {\n      int? get i \u003d\u003e ...;\n    }\n    f(C c) {\n      if (c.i !\u003d null) {\n        var i \u003d c.i; // Inferred type `int?`\n      }\n    }\n\nThis mostly worked, since the SSA node assigned by flow analysis is\nonly used for promotion, and promotion is disabled for non-promotable\nfields. However, it broke when the field in question was used as the\ntarget of a cascade, because fields within cascades always had their\n`_Reference.isPromotable` flag set to `true` regardless of whether the\ncorresponding cascade target is promotable. For example:\n\n    class C {\n      D? get d \u003d\u003e ...;\n    }\n    class D {\n      final E? _e;\n      ...\n    }\n    class E {\n      m() { ... }\n    }\n    f(C c) {\n      (c.d)\n        .._e!.m() // OK; promotes _e\n        .._e.m(); // OK; _e is promoted now\n      (c.d)\n        .._e.m(); // OOPS, _e is still promoted; it shouldn\u0027t be\n    }\n\nSee\n`tests/language/inference_update_2/cascaded_field_promotion_unstable_target_test.dart`\nfor a more detailed example.\n\nThis CL removes the hack; now, when a non-promotable property is\naccessed more than once, flow analysis assignes a different SSA node\nfor each access. As a result, the `_Reference.isPromotable` is not\nneeded, because non-promotable fields simply never have the chance to\nbe promoted (since every field access gets a separate SSA node, so\ntype checking one field access has no effect on others).\n\nTo preserve the ability to generate \"why not promoted\" messages, the\n`_PropertySsaNode` class now contains a `previousSsaNode` pointer,\nwhich links together the separate SSA nodes allocated for\nnon-promotable properties, so that they form a linked list. The \"why\nnot promoted\" logic traverses this list to figure out which promotions\n*would* have occurred if the property had been promotable.\n\nIn order to make it efficient to create this linked list, the\n`SsaNode` class also had to acquire a `_nonPromotableProperties` map,\nwhich records the SSA node that was allocated the last time each\nproperty was accessed.\n\nFixes https://github.com/dart-lang/sdk/issues/52728.\n\nChange-Id: I16a7b27f77c309bdccce86195a53398e32e8f75d\nBug: https://github.com/dart-lang/sdk/issues/52728\nReviewed-on: https://dart-review.googlesource.com/c/sdk/+/318745\nReviewed-by: Konstantin Shcheglov \u003cscheglov@google.com\u003e\nCommit-Queue: Paul Berry \u003cpaulberry@google.com\u003e\n\nhttps://dart.googlesource.com/sdk/+/9a3420f1d4e0f5e37cf758acc159ed0c651f95e4\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "8d7d3d9268b7b3bb8ca9f5994824ca30c85c6822",
      "old_mode": 33188,
      "old_path": "DEPS",
      "new_id": "820f138245541b2347a1e4bd3a24f18ffa64eabb",
      "new_mode": 33188,
      "new_path": "DEPS"
    },
    {
      "type": "modify",
      "old_id": "548a46db638953dbc601a6e22a412ea49dc6562f",
      "old_mode": 33188,
      "old_path": "commits.json",
      "new_id": "a1daceb8b30d47d3fd964864bb90c7ce435b31a5",
      "new_mode": 33188,
      "new_path": "commits.json"
    }
  ]
}
