<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/116087>116087</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [Clang] [Modules] Importing a function returning a transform view containing a lambda causes problems.
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang:frontend,
            clang:modules,
            rejects-valid
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          Sirraide
      </td>
    </tr>
</table>

<pre>
    Consider (https://godbolt.org/z/97rdzMq58):
```c++
// a.ccm
module; 
#include <ranges>
#include <vector>
export module A;

export std::vector<int> vec;
export auto bar() {
    return vec | std::views::transform([](auto& s) -> int& { return s; });
}

// b.ccm
module;
#include <ranges>
#include <vector>
export module B;
import A;

// Identical to 'bar()' above.
auto bar2() {
    return vec | std::views::transform([](auto& s) -> int& { return s; });
}

void foo() {
    bar2() | std::views::transform([](auto s) { return s; }); // Ok.
    bar()  | std::views::transform([](auto s) { return s; }); // Error? 
}
```

In `foo()` in module `B`, we call `bar()`, which is imported from module `A` and returns a transform view that is passed a lambda. Attempting to pipe that to another transform view fails, even though it works just fine if we define the function in the same module as `foo`
```console
/opt/compiler-explorer/clang-assertions-trunk/bin/clang++ --gcc-toolchain=/opt/compiler-explorer/gcc-snapshot   -fcolor-diagnostics -fno-crash-diagnostics -std=c++26 -isystem/opt/compiler-explorer/libs/fmt/7.1.3/include -O2 -g -DNDEBUG -std=c++26 -MD -MT CMakeFiles/bug.dir/b.ccm.o -MF CMakeFiles/bug.dir/b.ccm.o.d @CMakeFiles/bug.dir/b.ccm.o.modmap -o CMakeFiles/bug.dir/b.ccm.o -c /app/b.ccm
In module 'A' imported from /app/b.ccm:5:
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:224:2: error: no matching constructor for initialization of '(lambda at /app/a.ccm:8:40)'
  224 |         __box(__box&&) = default;
      |         ^~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:1871:11: note: in defaulted move constructor for 'std::ranges::__detail::__box<(lambda at /app/a.ccm:8:40)>' first required here
 1871 |     class transform_view : public view_interface<transform_view<_Vp, _Fp>>
      |           ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:1431:13: note: in implicit move constructor for 'std::ranges::transform_view<std::ranges::ref_view<std::vector<int>>, (lambda at /app/a.ccm:8:40)>' first required here
 1431 |             return std::forward<_Range>(__r);
      |                    ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:1444:30: note: in instantiation of function template specialization 'std::ranges::views::_All::operator()<std::ranges::transform_view<std::ranges::ref_view<std::vector<int>>, (lambda at /app/a.ccm:8:40)>>' requested here
 1444 |       using all_t = decltype(all(std::declval<_Range>()));
      |                              ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:2221:60: note: in instantiation of template type alias 'all_t' requested here
 2221 |     transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
      |                                                            ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:2229:17: note: while substituting deduced template arguments into function template '<deduction guide for transform_view>' [with _Range = std::ranges::transform_view<std::ranges::ref_view<std::vector<int>>, (lambda at /app/a.ccm:8:40)>, _Fp = (lambda at /app/b.ccm:17:35)]
 2229 |           = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
      |                        ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:2229:17: note: (skipping 13 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:931:9: note: while substituting template arguments into constraint expression here
  931 |       = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:969:10: note: while checking the satisfaction of concept '__adaptor_invocable<std::ranges::views::__adaptor::_Partial<std::ranges::views::_Transform, (lambda at /app/b.ccm:17:35)>, std::ranges::transform_view<std::ranges::ref_view<std::vector<int>>, (lambda at /app/a.ccm:8:40)>>' requested here
  969 |       && __adaptor_invocable<_Self, _Range>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/ranges:969:10: note: while substituting template arguments into constraint expression here
  969 |       && __adaptor_invocable<_Self, _Range>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
b.ccm:17:11: note: while checking constraint satisfaction for template 'operator|<std::ranges::views::__adaptor::_Partial<std::ranges::views::_Transform, (lambda at /app/b.ccm:17:35)>, std::ranges::transform_view<std::ranges::ref_view<std::vector<int>>, (lambda at /app/a.ccm:8:40)>>' required here
   17 |     bar() | std::views::transform([](auto s) { return s; });
      |           ^
b.ccm:17:11: note: in instantiation of function template specialization 'std::ranges::views::__adaptor::operator|<std::ranges::views::__adaptor::_Partial<std::ranges::views::_Transform, (lambda at /app/b.ccm:17:35)>, std::ranges::transform_view<std::ranges::ref_view<std::vector<int>>, (lambda at /app/a.ccm:8:40)>>' requested here
a.ccm:8:40: note: candidate template ignored: could not match 'auto (*)(auto &) -> int &' against '(lambda at /app/a.ccm:8:40)'
    8 |     return vec | std::views::transform([](auto& s) -> int& { return s; });
      |                                        ^
```

We seem to be failing to... construct a lambda that has no captures, which is weird. Considering that the problem also goes away if I pass e.g. `std::identity{}` to `transform` in `bar()`, this feels like it’s just #110401 all over again, but this time we’re failing to find the right constructor.

I might look into that later today or tomorrow if I can find the time.

CC @ChuanqiXu9
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWktv4zgS_jXMpSBBomzJPvjg2PGiD9lZ7Mw-bgYtURInlKghKSfpQ__2RVEPy47TSQ96dtLANIy4xUeR_Orjx6LKzBhR1JyvyPyWzLc3rLWl0qufhdZMZPzmoLLn1UbVRmRcA6GL0trGkGhN6I7QXaGyg5LWV7ogdPeZ0N0y0dnn-9_mC0KX2CzYkmBN4qD7pITe4qcrdSaA-WladSWVylrJSXQLQ4tI1KlsMw4k2mhWF9yQ6O5a5ZGnVumxkj81SlvoDMKaRMOY01pjM5xitB46b0RtSXQHR56OPfq2rLUKDkwTiisDkvTVAACa21bX2AtIspmYFfzRdP-1mtUmV7rC_g5qQhdok9AYDFr0cGAcn8ZofTBqHBrJ1sE5LCLZTlfT43i4guP3hfF2tCgqV36Jaz-TTxmvrUiZBKuA0GSEjdAE2EEdud-1H0ClHxDVoxIZ5Epdm9rZlL9xat28Xp0L9Bj-9OCfjdcP94eNd6c1-n0Hl2AMW3eKzacaSByM4JA4AFEPLCFxcIvt6QYeOaRMSiw6caCvKkVagjDQUYlnkGtVTWzgyMDqrJ-2AQbjGgEXDrZkFi00zBieAQPJqkPGfFhby6vGirpAAjai4V1bq4DVypZcX5rKmZAGp8WPvAZbqrYoQVh4VPrBwK-tsZCLmoPIcU0Zdw-25JC3dWqFqnH9-GxYxYdFMDOgNKI36qCqjZJ83DWqsYTuUlU1QnLt8adGKs01lklWFx6uUOM4xrO6rR8I3R1EPVR3ogqeV6SpZ5WSaclETaLtVy1jY1OzxpTKAoCXp0oq7WWCFbUyVqQGvLxWXqqZKc-LHQG3vZjTGDxhno3l1VfHk-JgCN3lFTZI_NCPCN0N0uP9RMErwNv-fXt3-6-_XRnifgve_S-wuWcPfCckR1uHtvAzgcad-PkKvPvdG038DMgseKNNpbKKNeCpN8dLcQOxphnKxg0yMJkma5S9c5pf9InW89NZ-V6fdZB2hYTunhbxPp55UtTtk1fULaG7cO4HfkDozvdf_umRx4H6Q3nSYTgj1pTO8C-J1sA7hVhDraBiNi1xfyGRrW7x0IBcaRC1sIJJ8Zm5XaFyBIDQRbc1gdnT0lm_9AWJ1rOgOx0GyaN05pRu-LffH9QToYv-O3afJZBoi5uRtdKOMt51mHYm87svX758-YjwhoskxK-ww9Vy_Bb1sCieQaWO_AXKhCbjGTDaItF6v8-4ZUIOTwhWtHkv_NEdEjUX2ljQ_LdWaJ5ByXUvU4CTHYFNJTPmJKN7J6M4-6Y9SJE6Wd2L2nKds5STaHPelESb_b8bVNz9rsGRh4jjpfucAz-k82aRc1504TxRNVKkwn6b717gc7WV5vmL-ovo1flxA9_N67MovPDHGJuNU8iVfmQ6Q6_-E2frrC72ez0NsK659uP7eIYCGAWXPq6NZbUVo8yNgQCGHpJZDqbh6UQKX_P7JIbbr2W_dVXDNUOndiHTK2T4EynTsQb5wo29JMxsKt6twXOCSbm3vV6n0j43HMNTKQldjJPCmiOTFyRyB8Py3Tz68IyilKJqxG8yaiQSogVMCownaeKQfBV8tD5Cc8EPuuhx7c_PTnuHS9ILMk2I2Y155peTcH-bV35Uny1RDJKpzx5LITmY9mCssK27bWQ8a1OenVzHdNFWvLYG76DqikhgzBNtXD9XUbQi4-6cuPSH23BkfvsobAmdI9x--mjK0DHDTe16ryHkdWhGc-w2357ou7w8_KPtcC4Zd419wer3CMjk0jxp1TF41Jj-XvxuRv9IbEWcHkTTIE3DCKMSy58cL-HA0gerXZR2C63h4OUDP72xzpOiEpZE2wCv0YajIkkE7QMCsHRx2fKNzfraJu0CNiZqC_yp0dwY3JgTjYXlWUT0gqDXmLbOWNO_WOvptpjW6sKMVT6u9B1k7K81v-_fh3Rb7GgbvPRbWvL0wfnMvWKxwuQsHc7JVNUpb1Bgkv2edTjvRX1UKTtI_pr2TcOuoVf_-A-m8Q77np6_nN66vSaSV-SuU8mPJtxfCelgGU9luQsg4Dra-5-5zN0pMGrwa2r6Hgb_WET9XgLzJ8N9xtnzlxMXG3KylrN96SKYSZAzXmiSzV878tt35OWlHCBMRudOs1LfNznwjlcyX6HKH3ZNPmfHX9T6rmJ_0Xziz5TVmcjcjXRwnihqpXnmalUrM2zbvRx2V9XW5f8WhK67kKcviKeZue45AVYwZMvve18MsBgJ-v_OG755TXj92nAtt_YfjtF1hVH2gbvEVJfH8n3_9C5xTHZ1ia2SGagVpKyxrebmLL_2yIXOfBhy-F0UxawLpRqtDpJXwKRRUChugD2yZxA5fHJZNeB-4QOJgxFE4VK79pkktwhD7G4DJA5OiHa5wCsZP1sKAznn0oAUDxyEJXeULAKyXPYpNkKjMAxmQYh3C1BHrjtWYO9DazsLVlQcHvnYV09BglzUmVuaFkVppy9f_bMEJlSuXir10B3KDhPktAarMvYMeICpSmmtHjtAUlafzOMszixuNi6tVLas_k38t13eZKsoW0ZLdsNXYRKFcxomi_CmXNE0nYV8zvM4SGeLWbjIDzGfJyyJgkU8S7MbsaIBnYVhGIWLMKahT3MaL_MZi6NwcQjnczILeMWE9KU8Vr7SxY0wpuWrMIyDRXIj2YFL437QQWmXH4zWucYLX50RSgndTCq6NJUZyzX_lafWeEcmhWs9397oFY7kHdrCkFkghbHmNLYVVrqfj2ycxfkWyPz2vrc638Inl_hy7wBP6t9tp67wIhWLN1Mm-rqe5ClrDTcDXY1_02q5uvglirBle_BTVWEIKI_Dl9dohSvC4A5RMhjRdUAdV_R_AQAA__9Bym32">