nico wrote:

Here's another snippet that builds fine before this patch but not after it:

```
#include <type_traits>

template <typename T>
class Foo;

struct Baz {
  Baz() = default;

#if 0
  Baz(Foo<int> foo) {}
#else
  template <typename T>
    requires(std::is_convertible_v<T, Foo<int>>)
  explicit Baz(T foo) {}
#endif
};

struct Quux {
  mutable Baz baz;
};
```

```
# libc++ built as described in libcxx/docs/VendorDocumentation.rst,
# but with -DCMAKE_INSTALL_PREFIX=$PWD/install-libcxx added to cmake invocation
# ninja -C build cxx cxxabi unwind
# ninja -C build install-cxx install-cxxabi install-unwind

out/gn/bin/clang -c repro.cc -std=c++20 -nostdinc++ -isystem 
install-libcxx/include/c++/v1 
```

Before, this built fine. After, it yields

```
% out/gn/bin/clang -c repro.cc -std=c++20 -nostdinc++ -isystem 
install-libcxx/include/c++/v1 
In file included from repro.cc:1:
In file included from install-libcxx/include/c++/v1/type_traits:491:
install-libcxx/include/c++/v1/__type_traits/is_convertible.h:26:96: error: 
implicit instantiation of undefined template 'Foo<int>'
   26 | _LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_convertible_v = 
__is_convertible(_From, _To);
      |                                                                         
                       ^
repro.cc:13:19: note: in instantiation of variable template specialization 
'std::is_convertible_v<Baz, Foo<int>>' requested here
   13 |     requires(std::is_convertible_v<T, Foo<int>>)
      |                   ^
repro.cc:13:14: note: while substituting template arguments into constraint 
expression here
   13 |     requires(std::is_convertible_v<T, Foo<int>>)
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
repro.cc:6:34: note: while checking constraint satisfaction for template 
'Baz<Baz>' required here
    6 | struct __attribute__((lockable)) Baz {
      |                                  ^~~
repro.cc:6:34: note: while substituting deduced template arguments into 
function template 'Baz' [with T = Baz]
repro.cc:18:8: note: while declaring the implicit copy constructor for 'Quux'
   18 | struct Quux {
      |        ^
repro.cc:4:7: note: template is declared here
    4 | class Foo;
      |       ^
1 error generated.
```

The snippet is a bit weird! The motivation is that it wants to say 
`Baz(Foo<int> foo) {}`, but `Foo<T>` is forward-declared, so it uses that 
template hack, and everyone who wants to call that ctor has to make sure to 
include a definition of `Foo<>`.

This worked before this change, but not after. Was that behavior change 
intentional? (The repro only works if the `mutable` is present somehow, which 
suggests that this isn't intentional.)

Maybe this is also what's causing the libc++-built-as-module diag mentioned 
above?

https://github.com/llvm/llvm-project/pull/121199
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to