)]}'
{
  "commit": "a8028abedbc768bce84ede60b2e8cda629e11c01",
  "tree": "635cbbcf1e16bca3173f5df3a5776ee8c5d4d0f5",
  "parents": [
    "3bb7de6408fb8399102c43a105d54b221308e211",
    "7791bc22133cce1693b364f76e99416b50f4d348"
  ],
  "author": {
    "name": "Urgau",
    "email": "3616612+Urgau@users.noreply.github.com",
    "time": "Fri Jan 09 23:28:16 2026 +0100"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Fri Jan 09 23:28:16 2026 +0100"
  },
  "message": "Rollup merge of #150822 - fix-149981, r\u003d@Kivooeo\n\nFix for ICE: eii: fn / macro rules None in find_attr()\n\nCloses rust-lang/rust#149981\n\nThis used to ICE:\n```rust\nmacro_rules! foo_impl {}\n#[eii]\nfn foo_impl() {}\n```\n\n`#[eii]` generates a macro (called `foo_impl`) and a default impl. So the partial expansion used to roughly look like the following:\n\n```rust\nmacro_rules! foo_impl {} // actually resolves here\n\nextern \"Rust\" {\n    fn foo_impl();\n}\n\n#[eii_extern_target(foo_impl)]\nmacro foo_impl {\n    () \u003d\u003e {};\n}\n\nconst _: () \u003d {\n    #[implements_eii(foo_impl)] // assumed to name resolve to the macro v2 above\n    fn foo_impl() {}\n};\n```\n\nNow, shadowing rules for macrov2 and macrov1 are super weird! Take a look at this: https://play.rust-lang.org/?version\u003dnightly\u0026mode\u003ddebug\u0026edition\u003d2024\u0026gist\u003d23f21421921360478b0ec0276711ad36\n\nSo instead of resolving to the macrov2, we resolve the macrov1 named the same thing.\n\nA regression test was added to this, and some span_delayed_bugs were added to make sure we catch this in the right places. But that didn\u0027t fix the root cause.\n\nTo make sure this simply cannot happen again, I made it so that we don\u0027t even need to do a name resolution for the default. In other words, the new partial expansion looks more like:\n\n```rust\nmacro_rules! foo_impl {}\n\nextern \"Rust\" {\n    fn foo_impl(); // resolves to here now!!!\n}\n\n#[eii_extern_target(foo_impl)]\nmacro foo_impl {\n    () \u003d\u003e {};\n}\n\nconst _: () \u003d {\n    #[implements_eii(known_extern_target\u003dfoo_impl)] // still name resolved, but directly to the foreign function.\n    fn foo_impl() {}\n};\n```\n\nThe reason this helps is that name resolution for non-macros is much more predictable. It\u0027s not possible to have two functions like that with the same name in scope.\n\nWe used to key externally implementable items off of the defid of the macro, but now the unique identifier is the foreign function\u0027s defid which seems much more sane.\n\nFinally, I lied a tiny bit because the above partial expansion doesn\u0027t actually work.\n```rust\nextern \"Rust\" {\n    fn foo_impl(); // not to here\n}\n\nconst _: () \u003d {\n    #[implements_eii(known_extern_target\u003dfoo_impl)] // actually resolves to this function itself\n    fn foo_impl() {} // \u003c--- so to here\n};\n```\n\nSo the last few commits change the expansion to actually be this:\n\n```rust\nmacro_rules! foo_impl {}\n\nextern \"Rust\" {\n    fn foo_impl(); // resolves to here now!!!\n}\n\n#[eii_extern_target(foo_impl)]\nmacro foo_impl {\n    () \u003d\u003e {};\n}\n\nconst _: () \u003d {\n    mod dflt { // necessary, otherwise `super` doesn\u0027t work\n        use super::*;\n        #[implements_eii(known_extern_target\u003dsuper::foo_impl)] // now resolves to outside the `dflt` module, so the foreign item.\n        fn foo_impl() {}\n    }\n};\n```\n\nI apologize to whoever needs to review this, this is very subtle and I hope this makes it clear enough :sob:.\n",
  "tree_diff": []
}
