xref: /llvm-project/clang/test/SemaTemplate/nested-deduction-guides.cpp (revision 869ac4064861b7e644ae52a72fb80efacfd86462)
1 // RUN: %clang_cc1 -std=c++17 -verify %s
2 
3 template<typename T> struct A {
4   template<typename U> struct B {
5     B(...);
6     B(const B &) = default;
7   };
8   template<typename U> B(U) -> B<U>;
9 };
10 A<void>::B b = 123;
11 A<void>::B copy = b;
12 
13 using T = decltype(b);
14 using T = A<void>::B<int>;
15 
16 using Copy = decltype(copy);
17 using Copy = A<void>::B<int>;
18 
19 namespace GH94614 {
20 
21 template <class, class> struct S {};
22 
23 struct trouble_1 {
24 } constexpr t1;
25 struct trouble_2 {
26 } constexpr t2;
27 struct trouble_3 {
28 } constexpr t3;
29 struct trouble_4 {
30 } constexpr t4;
31 struct trouble_5 {
32 } constexpr t5;
33 struct trouble_6 {
34 } constexpr t6;
35 struct trouble_7 {
36 } constexpr t7;
37 struct trouble_8 {
38 } constexpr t8;
39 struct trouble_9 {
40 } constexpr t9;
41 
42 template <class U, class... T> struct Unrelated {
43   using Trouble = S<U, T...>;
44 
45   template <class... V> using Trouble2 = S<V..., T...>;
46 };
47 
48 template <class T, class U> struct Outer {
49   using Trouble = S<U, T>;
50 
51   template <class V> using Trouble2 = S<V, T>;
52 
53   template <class V> using Trouble3 = S<U, T>;
54 
55   template <class V> struct Inner {
56     template <class W> struct Paranoid {
57       using Trouble4 = S<W, T>;
58 
59       template <class... X> using Trouble5 = S<X..., T>;
60     };
61 
62     Inner(trouble_1, V v, Trouble trouble) {}
63     Inner(trouble_2, V v, Trouble2<V> trouble) {}
64     Inner(trouble_3, V v, Trouble3<V> trouble) {}
65     Inner(trouble_4, V v, typename Unrelated<U, T>::template Trouble2<V> trouble) {}
66     Inner(trouble_5, V v, typename Unrelated<U, T>::Trouble trouble) {}
67     Inner(trouble_6, V v, typename Unrelated<V, T>::Trouble trouble) {}
68     Inner(trouble_7, V v, typename Paranoid<V>::Trouble4 trouble) {}
69     Inner(trouble_8, V v, typename Paranoid<V>::template Trouble5<V> trouble) {}
70     template <class W>
71     Inner(trouble_9, V v, W w, typename Paranoid<V>::template Trouble5<W> trouble) {}
72   };
73 };
74 
75 S<int, char> s;
76 
77 Outer<char, int>::Inner _1(t1, 42, s);
78 Outer<char, int>::Inner _2(t2, 42, s);
79 Outer<char, int>::Inner _3(t3, 42, s);
80 Outer<char, int>::Inner _4(t4, 42, s);
81 Outer<char, int>::Inner _5(t5, 42, s);
82 Outer<char, int>::Inner _6(t6, 42, s);
83 Outer<char, int>::Inner _7(t7, 42, s);
84 Outer<char, int>::Inner _8(t8, 42, s);
85 Outer<char, int>::Inner _9(t9, 42, 24, s);
86 
87 // Make sure we don't accidentally inject the TypedefNameDecl into the TU.
88 Trouble should_not_be_in_the_tu_decl; // expected-error {{unknown type name 'Trouble'}}
89 
90 } // namespace GH94614
91