iwyu: map std::hash to <functional> #35073

pull Sjors wants to merge 1 commits into bitcoin:master from Sjors:2026/04/iwyu changing 1 files +6 −0
  1. Sjors commented at 6:40 PM on April 14, 2026: member

    IWYU incorrectly suggests <variant> for std::hash, as observed in #33922.

    On Ubuntu with include-what-you-use 0.26 based clang version 22.1.1, it incorrectly suggested <string_view>.

    On macOS with IWYU 0.26 based on clang version 22.1.2, it correctly suggests <functional>.

    Fix this by adding the mapping.

    Tracked upstream: https://github.com/include-what-you-use/include-what-you-use/issues/2007

  2. DrahtBot commented at 6:40 PM on April 14, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    Concept NACK maflcko

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #33922 (mining: add getMemoryLoad() and track template non-mempool memory footprint by Sjors)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  3. fanquake commented at 6:44 PM on April 14, 2026: member

    Can you link to the relevant upstream issue (or open one).

  4. Sjors commented at 6:48 PM on April 14, 2026: member

    @fanquake I can't find an upstream issue for this specific case. IIUC https://github.com/include-what-you-use/include-what-you-use/issues/785 would prevent this in the most general way?

  5. in contrib/devtools/iwyu/bitcoin.core.imp:9 in 32f1f60685 outdated
       4 | @@ -5,4 +5,6 @@
       5 |    { "include": [ "<mmintrin.h>", "private", "<immintrin.h>", "public" ] },
       6 |    { "include": [ "<smmintrin.h>", "private", "<immintrin.h>", "public" ] },
       7 |    { "include": [ "<tmmintrin.h>", "private", "<immintrin.h>", "public" ] },
       8 | +
       9 | +  { "symbol": ["std::hash", "private", "<functional>", "public"] },
    


    maflcko commented at 6:58 PM on April 14, 2026:

    Seems fine, but this is equally wrong.

    Any header is fine, see:

    https://en.cppreference.com/w/cpp/utility/hash.html

    I think iwyu should just tolerate any of them


    Sjors commented at 8:11 PM on April 14, 2026:

    How do I specify "any header"?


    maflcko commented at 6:21 AM on April 16, 2026:

    Not sure if this is possible without fixing up iwyu.

    In any case, I wanted to say that I don't see the point of this pull request. What is the exact harm you are trying to fix? What is the risk?

    Right now, all you are doing is swapping one perfectly fine thing (for the compiler) with another one. Both are equally confusing and "wrong" for a reader, so I don't see the point for this churn here. Why does it need to change?


    hebasto commented at 2:32 PM on April 16, 2026:

    In the context of #33922, we can simply redeclare the primary template:

    namespace std {
    // Redeclaration of the primary template.
    template <class T>
    struct hash; // IWYU pragma: keep
    
    /** Disable default std::hash for CTransactionRef to prevent accidentally
     *  comparing by pointer. Use CTransactionRefSaltedHash or provide a custom
     *  hasher. */
    template <>
    struct hash<CTransactionRef> {
        size_t operator()(const CTransactionRef&) const = delete;
    };
    } // namespace std
    

    Sjors commented at 12:54 PM on April 17, 2026:

    What is the exact harm you are trying to fix?

    CI spuriously fails for #33922.


    maflcko commented at 2:01 PM on April 17, 2026:

    What is the exact harm you are trying to fix?

    CI spuriously fails for #33922.

    Given how iwyu works, it is a harmless and arguably valid suggestion. Recall that the goal of using iwyu is to avoid missing includes, which have lead to compile failures in the past. Adding an include that already exists implicitly is harmless. And fwiw, CI did pass on commit 10acf818ed70d4cd2af864278a35a6b64de0bb16.

    Working around that in the wrong way will just achieve the opposite. E.g. a no_include pragma may lead to the exact compile failures we are trying to avoid, down the line.

  6. Sjors marked this as a draft on Apr 14, 2026
  7. Sjors commented at 9:04 PM on April 14, 2026: member

    This might be a clang vs libc++ thing, because I can't reproduce the CI failure locally: include-what-you-use 0.26 based on clang version 22.1.2

  8. fanquake commented at 1:49 AM on April 15, 2026: member
  9. Sjors force-pushed on Apr 15, 2026
  10. Sjors marked this as ready for review on Apr 15, 2026
  11. Sjors commented at 1:33 PM on April 15, 2026: member

    I was able to reproduce a similar, but not identical, result on Ubuntu (see PR description), where it suggested <string_view> instead of <variant>. Since I can't reproduce the issue on macOS, the issue seems specific to libstdc++.

  12. Sjors marked this as a draft on Apr 15, 2026
  13. iwyu: map std::hash to <functional>
    IWYU incorrectly suggested <variant> for std::hash in #33922.
    On Ubuntu with include-what-you-use 0.26 based clang version 22.1.1,
    it incorrectly suggested <string_view>.
    
    On macOS with IWYU 0.26 based on clang version 22.1.2, it correctly
    suggests <functional>.
    
    Fix this by adding the mapping.
    4e50c575d8
  14. Sjors force-pushed on Apr 15, 2026
  15. Sjors marked this as ready for review on Apr 15, 2026
  16. Sjors commented at 1:35 PM on April 15, 2026: member

    (accidentally pushed part of #33922, it should be good for review now)

    Tracking upstream: https://github.com/include-what-you-use/include-what-you-use/issues/2007

  17. DrahtBot added the label CI failed on Apr 15, 2026
  18. in contrib/devtools/iwyu/bitcoin.core.imp:10 in 4e50c575d8
       4 | @@ -5,4 +5,10 @@
       5 |    { "include": [ "<mmintrin.h>", "private", "<immintrin.h>", "public" ] },
       6 |    { "include": [ "<smmintrin.h>", "private", "<immintrin.h>", "public" ] },
       7 |    { "include": [ "<tmmintrin.h>", "private", "<immintrin.h>", "public" ] },
       8 | +
       9 | +  # IWYU's std_symbol_map.inc maps std::hash<T> specializations to their
      10 | +  # correct headers, but with libstdc++ IWYU still suggests a wrong
    


    maflcko commented at 1:43 PM on April 15, 2026:

    Can we use libc++, if libstdc++ yields the wrong result?


    Sjors commented at 2:08 PM on April 15, 2026:

    Not sure if it's worth switching based on this N=1 example.


    maflcko commented at 2:56 PM on April 16, 2026:

    To give some background why I suggested it (but I haven't confirmed any of this): libc++ has the option -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES. Further, assuming that the "wrong" header was just picked because it was the first one present anyway (ref https://github.com/include-what-you-use/include-what-you-use/issues/2007#issuecomment-4259912191), it seems that D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES may improve the end result minimally. Though, I haven't checked any of this.

  19. DrahtBot removed the label CI failed on Apr 15, 2026
  20. hebasto commented at 4:47 PM on April 15, 2026: member
  21. Sjors commented at 8:36 PM on April 15, 2026: member

    @hebasto so should I use <memory> instead of <functional>? Or is there just no way to get a universal rule and do we somehow disable the linter for this case?

  22. hebasto commented at 8:39 AM on April 16, 2026: member

    @hebasto so should I use <memory> instead of <functional>? Or is there just no way to get a universal rule and do we somehow disable the linter for this case?

    I would suggest the following approach in #33922:

    // IWYU erroneously suggests including <variant> instead of <memory>
    // for std::hash<CTransactionRef>.
    // See https://github.com/include-what-you-use/include-what-you-use/issues/2007.
    // IWYU pragma: no_include <variant>
    
  23. maflcko commented at 8:43 AM on April 16, 2026: member
    // IWYU pragma: no_include <variant>
    

    I disagree. This patch would be harmful. If std::variant is used any time in the future, it would be missing the include and lead to compile failures.

    As per my last comment (https://github.com/bitcoin/bitcoin/pull/35073#discussion_r3091132596), I don't understand why this pull requests exists and what it is trying to achieve. There is no real bug and any attempted fix is just going to add more harm and risks.

    NACK

  24. purpleKarrot commented at 2:43 PM on April 16, 2026: contributor

    What exactly is the root problem here? Is it that IWYU does not recognize std::hash<CTransactionRef> as a template specialization for std::shared_ptr and therefore does not map it to <memory>? Would it help to add a mapping for that type?

      { "symbol": ["std::hash<CTransactionRef>", "private", "<memory>", "public"] },
    
  25. hebasto commented at 2:46 PM on April 16, 2026: member

    What exactly is the root problem here? Is it that IWYU does not recognize std::hash<CTransactionRef> as a template specialization for std::shared_ptr and therefore does not map it to <memory>? Would it help to add a mapping for that type?

      { "symbol": ["std::hash<CTransactionRef>", "private", "<memory>", "public"] },
    

    See https://github.com/include-what-you-use/include-what-you-use/issues/2007#issuecomment-4259912191.

  26. Sjors commented at 1:17 PM on April 17, 2026: member

    @hebasto's workaround from #35073 (review) doesn't work unfortunately, see (iwyu ci log).

    If I keep the <functional> include, it wants it removed. When I remove it, demands <variant> again.

    Happy to close this is it's incorrect, but I don't think we should be enforcing buggy linters project-wide. This sort of spurious CI failure is impossible to debug without deep compiler / build system knowledge.

  27. Sjors commented at 1:22 PM on April 17, 2026: member

    Actually @hebasto suggested two different workarounds.

    1. redeclare the primary template: this doesn't work, per my previous comment
    2. IWYU pragma: no_include <variant>: I'm trying that now
  28. maflcko commented at 1:40 PM on April 17, 2026: member

    redeclare the primary template: this doesn't work, per my previous comment

    You pushed the wrong thing. You can use the copy-paste icon in the upper right on GitHub to properly copy-paste it.

  29. Sjors commented at 1:50 PM on April 17, 2026: member

    Workaround (2) worked: ci log

    It's the most narrow fix, so closing this.

  30. Sjors closed this on Apr 17, 2026

  31. Sjors commented at 1:53 PM on April 17, 2026: member

    @maflcko for (1) I pushed this:

    template <class T>
    struct hash; // IWYU pragma: keep
    

    Which is from: #35073 (review)

    Here's the commit: https://github.com/bitcoin/bitcoin/commit/4673836a656a2638292fd02453e5d8ef42cd8eab

    Here's the CI failure: https://github.com/bitcoin/bitcoin/actions/runs/24566460651/job/71827949758

  32. maflcko commented at 2:03 PM on April 17, 2026: member

    @maflcko for (1) I pushed this:

    Yes, that is wrong, because it is missing the namespace. You'll have to copy-paste the full suggestion.

  33. Sjors commented at 3:46 PM on April 17, 2026: member

    That didn't work either, but b89942d29f1e71429070b2d1140d2792eb33bf47 does.

  34. Sjors commented at 7:50 PM on April 17, 2026: member

    Ended up with a less verbose approach in #35101.


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-21 09:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me