@@ -479,6 +479,169 @@ A a{.f1 = {1}};
479
479
480
480
} // namespace GH83368
481
481
482
+ namespace GH60777 {
483
+
484
+ template <typename ... Ts> constexpr bool True () { return true ; }
485
+
486
+ template <typename T>
487
+ requires (sizeof (T) > 1 )
488
+ struct A {
489
+ template <typename ... Ts>
490
+ requires (sizeof ...(Ts) == 0 )
491
+ A (T val, Ts... tail)
492
+ requires (True<Ts...>())
493
+ {}
494
+ };
495
+
496
+ A a (42 );
497
+
498
+ // `requires (sizeof(T) > 1)` goes into the deduction guide together with
499
+ // `requires (True<Ts...>())`, while `requires(sizeof...(Ts) == 0)` goes into
500
+ // the template parameter list of the synthesized declaration.
501
+
502
+ // CHECK-LABEL: Dumping GH60777::<deduction guide for A>:
503
+ // CHECK-NEXT: FunctionTemplateDecl 0x{{.+}} <{{.+}}> {{.+}} implicit <deduction guide for A>
504
+ // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <{{.+}}> col:20 referenced typename depth 0 index 0 T
505
+ // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <{{.+}}> col:25 typename depth 0 index 1 ... Ts
506
+ // CHECK-NEXT: |-ParenExpr 0x{{.+}} <{{.+}}> 'bool'
507
+ // CHECK-NEXT: | `-BinaryOperator 0x{{.+}} <{{.+}}> 'bool' '=='
508
+ // CHECK-NEXT: | |-SizeOfPackExpr {{.+}} Ts
509
+ // CHECK-NEXT: | | `-TemplateArgument type 'Ts...':'type-parameter-0-1...'
510
+ // CHECK-NEXT: | | `-PackExpansionType 0x{{.+}} 'Ts...' dependent
511
+ // CHECK-NEXT: | | `-TemplateTypeParmType 0x{{.+}} 'Ts' dependent contains_unexpanded_pack depth 0 index 1 pack
512
+ // CHECK-NEXT: | | `-TemplateTypeParm 0x{{.+}} 'Ts'
513
+ // CHECK-NEXT: | `-ImplicitCastExpr {{.+}} <IntegralCast>
514
+ // CHECK-NEXT: | `-IntegerLiteral 0x{{.+}} <{{.+}}> 'int' 0
515
+ // CHECK-NEXT: |-CXXDeductionGuideDecl 0x{{.+}} <{{.+}}> line:{{.+}} implicit <deduction guide for A> 'auto (T, Ts...) -> A<T>'
516
+ // CHECK-NEXT: | |-ParmVarDecl 0x{{.+}} <{{.+}}> col:{{.+}} val 'T'
517
+ // CHECK-NEXT: | |-ParmVarDecl 0x{{.+}} <{{.+}}> col:{{.+}} tail 'Ts...' pack
518
+ // CHECK-NEXT: | `-BinaryOperator 0x{{.+}} <{{.+}}> 'bool' '&&'
519
+ // CHECK-NEXT: | |-ParenExpr 0x{{.+}} <{{.+}}> 'bool'
520
+ // CHECK-NEXT: | | `-BinaryOperator 0x{{.+}} <{{.+}}> 'bool' '>'
521
+ // CHECK-NEXT: | | |-UnaryExprOrTypeTraitExpr {{.+}} sizeof 'T'
522
+ // CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <IntegralCast>
523
+ // CHECK-NEXT: | | `-IntegerLiteral 0x{{.+}} <{{.+}}> 'int' 1
524
+ // CHECK-NEXT: | `-ParenExpr 0x{{.+}} <{{.+}}> '<dependent type>'
525
+ // CHECK-NEXT: | `-CallExpr 0x{{.+}} <{{.+}}> '<dependent type>'
526
+ // CHECK-NEXT: | `-UnresolvedLookupExpr 0x{{.+}} <col:14, col:24> '<dependent type>' {{.+}}
527
+ // CHECK-NEXT: | `-TemplateArgument type 'Ts...':'type-parameter-0-1...'
528
+ // CHECK-NEXT: | `-PackExpansionType 0x{{.+}} 'Ts...' dependent
529
+ // CHECK-NEXT: | `-TemplateTypeParmType 0x{{.+}} 'Ts' dependent contains_unexpanded_pack depth 0 index 1 pack
530
+ // CHECK-NEXT: | `-TemplateTypeParm 0x{{.+}} 'Ts'
531
+
532
+ template <typename T>
533
+ struct B {
534
+ template <typename ... Ts>
535
+ B (T val, Ts... tail)
536
+ requires (True<tail...>())
537
+ {}
538
+ };
539
+
540
+ B b (42 , 43 );
541
+ // expected-error@-1 {{no viable constructor}} \
542
+ // expected-note@-6 {{constraints not satisfied}} \
543
+ // expected-note@-5 {{because substituted constraint expression is ill-formed}} \
544
+ // expected-note@-6 {{implicit deduction guide declared as 'template <typename T, typename ...Ts> B(T val, Ts ...tail) -> B<T> requires (True<tail...>())'}} \
545
+ // expected-note@-8 {{function template not viable}} \
546
+ // expected-note@-8 {{implicit deduction guide declared as 'template <typename T> B(B<T>) -> B<T>'}}
547
+
548
+ } // namespace GH60777
549
+
550
+ // Examples from @hokein.
551
+ namespace GH98592 {
552
+
553
+ template <class T > concept True = true ;
554
+ double arr3[3 ];
555
+
556
+ template <class T >
557
+ struct X {
558
+ const int size;
559
+ template <class U >
560
+ constexpr X (T, U(&)[3]) requires True<T> : size(sizeof (T)) {}
561
+ };
562
+
563
+ template <typename T, typename U>
564
+ X (T, U (&)[3 ]) -> X<U>;
565
+
566
+ constexpr X x (3 , arr3);
567
+
568
+ // The synthesized deduction guide is more constrained than the explicit one.
569
+ static_assert (x.size == 4 );
570
+
571
+ // CHECK-LABEL: Dumping GH98592::<deduction guide for X>:
572
+ // CHECK-NEXT: FunctionTemplateDecl 0x{{.+}} <{{.+}}> col:13 implicit <deduction guide for X>
573
+ // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <{{.+}}> col:17 referenced class depth 0 index 0 T
574
+ // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <{{.+}}> col:19 class depth 0 index 1 U
575
+ // CHECK-NEXT: |-CXXDeductionGuideDecl 0x{{.+}} <{{.+}}> col:13 implicit <deduction guide for X> 'auto (T, U (&)[3]) -> X<T>'
576
+ // CHECK-NEXT: | |-ParmVarDecl 0x{{.+}} <col:15> col:16 'T'
577
+ // CHECK-NEXT: | |-ParmVarDecl 0x{{.+}} <col:18, col:24> col:21 'U (&)[3]'
578
+ // CHECK-NEXT: | `-ConceptSpecializationExpr 0x{{.+}} <col:36, col:42> 'bool' Concept 0x{{.+}} 'True'
579
+ // CHECK-NEXT: | |-ImplicitConceptSpecializationDecl 0x{{.+}} <{{.+}}> col:28
580
+ // CHECK-NEXT: | | `-TemplateArgument type 'type-parameter-0-0'
581
+ // CHECK-NEXT: | | `-TemplateTypeParmType 0x{{.+}} 'type-parameter-0-0' dependent depth 0 index 0
582
+ // CHECK-NEXT: | `-TemplateArgument <{{.+}}> type 'T':'type-parameter-0-0'
583
+ // CHECK-NEXT: | `-TemplateTypeParmType 0x{{.+}} 'T' dependent depth 0 index 0
584
+ // CHECK-NEXT: | `-TemplateTypeParm 0x{{.+}} 'T'
585
+ // CHECK-NEXT: `-CXXDeductionGuideDecl 0x{{.+}} <col:3, col:63> col:13 implicit used <deduction guide for X> 'auto (int, double (&)[3]) -> GH98592::X<int>' implicit_instantiation
586
+ // CHECK-NEXT: |-TemplateArgument type 'int'
587
+ // CHECK-NEXT: | `-BuiltinType 0x{{.+}} 'int'
588
+ // CHECK-NEXT: |-TemplateArgument type 'double'
589
+ // CHECK-NEXT: | `-BuiltinType 0x{{.+}} 'double'
590
+ // CHECK-NEXT: |-ParmVarDecl 0x{{.+}} <col:15> col:16 'int'
591
+ // CHECK-NEXT: |-ParmVarDecl 0x{{.+}} <col:18, col:24> col:21 'double (&)[3]'
592
+ // CHECK-NEXT: `-ConceptSpecializationExpr 0x{{.+}} <col:36, col:42> 'bool' Concept 0x{{.+}} 'True'
593
+ // CHECK-NEXT: |-ImplicitConceptSpecializationDecl 0x{{.+}} <{{.+}}> col:28
594
+ // CHECK-NEXT: | `-TemplateArgument type 'type-parameter-0-0'
595
+ // CHECK-NEXT: | `-TemplateTypeParmType 0x{{.+}} 'type-parameter-0-0' dependent depth 0 index 0
596
+ // CHECK-NEXT: `-TemplateArgument <{{.+}}> type 'T':'type-parameter-0-0'
597
+ // CHECK-NEXT: `-TemplateTypeParmType 0x{{.+}} 'T' dependent depth 0 index 0
598
+ // CHECK-NEXT: `-TemplateTypeParm 0x{{.+}} 'T'
599
+
600
+ template <class T > requires True<T> struct Y {
601
+ const int size;
602
+ template <class U >
603
+ constexpr Y (T, U(&)[3]) : size(sizeof (T)) {}
604
+ };
605
+
606
+ template <typename T, typename U> Y (T, U (&)[3]) -> Y<U>;
607
+
608
+ constexpr Y y (3 , arr3);
609
+
610
+ // Likewise, the synthesized deduction guide should be preferred
611
+ // according to [over.match.class.deduct]p1.
612
+ static_assert (y.size == 4 );
613
+
614
+ // Dumping GH98592::<deduction guide for Y>:
615
+ // FunctionTemplateDecl 0x{{.+}} <{{.+}}> col:13 implicit <deduction guide for Y>
616
+ // |-TemplateTypeParmDecl 0x{{.+}} <{{.+}}> col:17 referenced class depth 0 index 0 T
617
+ // |-TemplateTypeParmDecl 0x{{.+}} <{{.+}}> col:19 class depth 0 index 1 U
618
+ // |-CXXDeductionGuideDecl 0x{{.+}} <{{.+}}> col:13 implicit <deduction guide for Y> 'auto (T, U (&)[3]) -> Y<T>'
619
+ // | |-ParmVarDecl 0x{{.+}} <col:15> col:16 'T'
620
+ // | |-ParmVarDecl 0x{{.+}} <col:18, col:24> col:21 'U (&)[3]'
621
+ // | `-ConceptSpecializationExpr 0x{{.+}} <{{.+}}> 'bool' Concept 0x{{.+}} 'True'
622
+ // | |-ImplicitConceptSpecializationDecl 0x{{.+}} <{{.+}}> col:28
623
+ // | | `-TemplateArgument type 'type-parameter-0-0'
624
+ // | | `-TemplateTypeParmType 0x{{.+}} 'type-parameter-0-0' dependent depth 0 index 0
625
+ // | `-TemplateArgument <{{.+}}> type 'T':'type-parameter-0-0'
626
+ // | `-TemplateTypeParmType 0x{{.+}} 'T' dependent depth 0 index 0
627
+ // | `-TemplateTypeParm 0x{{.+}} 'T'
628
+ // `-CXXDeductionGuideDecl 0x{{.+}} <{{.+}}> col:13 implicit used <deduction guide for Y> 'auto (int, double (&)[3]) -> GH98592::Y<int>' implicit_instantiation
629
+ // |-TemplateArgument type 'int'
630
+ // | `-BuiltinType 0x{{.+}} 'int'
631
+ // |-TemplateArgument type 'double'
632
+ // | `-BuiltinType 0x{{.+}} 'double'
633
+ // |-ParmVarDecl 0x{{.+}} <col:15> col:16 'int'
634
+ // |-ParmVarDecl 0x{{.+}} <col:18, col:24> col:21 'double (&)[3]'
635
+ // `-ConceptSpecializationExpr 0x{{.+}} <{{.+}}> 'bool' Concept 0x{{.+}} 'True'
636
+ // |-ImplicitConceptSpecializationDecl 0x{{.+}} <{{.+}}> col:28
637
+ // | `-TemplateArgument type 'type-parameter-0-0'
638
+ // | `-TemplateTypeParmType 0x{{.+}} 'type-parameter-0-0' dependent depth 0 index 0
639
+ // `-TemplateArgument <{{.+}}> type 'T':'type-parameter-0-0'
640
+ // `-TemplateTypeParmType 0x{{.+}} 'T' dependent depth 0 index 0
641
+ // `-TemplateTypeParm 0x{{.+}} 'T'
642
+
643
+ } // namespce GH98592
644
+
482
645
namespace GH122134 {
483
646
484
647
template <class , class >
0 commit comments