forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Teach TreeTransform to substitute into resolved TemplateArguments.
This comes up when substituting into an already-substituted template argument during constraint satisfaction checking.
- Loading branch information
Showing
2 changed files
with
72 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// RUN: %clang_cc1 -std=c++2a -verify %s | ||
|
||
// When forming and checking satisfaction of atomic constraints, we will | ||
// substitute still-dependent template arguments into an expression, and later | ||
// substitute into the result. This creates some unique situations; check that | ||
// they work. | ||
|
||
namespace SubstIntoResolvedTypeTemplateArg { | ||
template<int, class> struct X {}; | ||
|
||
template<class T> concept A = true; | ||
template<class T> concept B = sizeof(T) != 0; | ||
template<class T> concept C = B<X<1, T>>; | ||
|
||
int f(A auto); // expected-note {{candidate}} | ||
int f(C auto); // expected-note {{candidate}} | ||
int k1 = f(0); // expected-error {{ambiguous}} | ||
|
||
template<class T> concept D = A<T> && B<X<1, T>>; | ||
int f(D auto); | ||
int k2 = f(0); // ok | ||
|
||
// The atomic constraint formed from B<X<(int)'\1', T>> is identical to the | ||
// one formed from C, even though the template arguments are written as | ||
// different expressions; the "equivalent" rules are used rather than the | ||
// "identical" rules when matching template arguments in concept-ids. | ||
template<class T> concept E = A<T> && B<X<(int)'\1', T>>; | ||
int g(C auto); | ||
int g(E auto); // expected-note {{candidate}} | ||
int k3 = g(0); | ||
|
||
int g(D auto); // expected-note {{candidate}} | ||
int k4 = g(0); // expected-error {{ambiguous}} | ||
} |