@@ -740,6 +740,24 @@ bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) {
740740 return false ;
741741}
742742
743+ // Returns all source deduction guides associated with the declared
744+ // deduction guides that have the specified deduction guide name.
745+ llvm::DenseSet<const NamedDecl *> getSourceDeductionGuides (DeclarationName Name,
746+ DeclContext *DC) {
747+ assert (Name.getNameKind () ==
748+ DeclarationName::NameKind::CXXDeductionGuideName &&
749+ " name must be a deduction guide name" );
750+ llvm::DenseSet<const NamedDecl *> Result;
751+ for (auto *D : DC->lookup (Name)) {
752+ if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
753+ D = FTD->getTemplatedDecl ();
754+
755+ if (const auto *GD = dyn_cast<CXXDeductionGuideDecl>(D))
756+ Result.insert (GD->getSourceDeductionGuide ());
757+ }
758+ return Result;
759+ }
760+
743761// Build the associated constraints for the alias deduction guides.
744762// C++ [over.match.class.deduct]p3.3:
745763// The associated constraints ([temp.constr.decl]) are the conjunction of the
@@ -1191,13 +1209,10 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
11911209 if (AliasTemplate->isInvalidDecl ())
11921210 return ;
11931211 auto &Context = SemaRef.Context ;
1194- // FIXME: if there is an explicit deduction guide after the first use of the
1195- // type alias usage, we will not cover this explicit deduction guide. fix this
1196- // case.
1197- if (hasDeclaredDeductionGuides (
1198- Context.DeclarationNames .getCXXDeductionGuideName (AliasTemplate),
1199- AliasTemplate->getDeclContext ()))
1200- return ;
1212+ auto SourceDeductionGuides = getSourceDeductionGuides (
1213+ Context.DeclarationNames .getCXXDeductionGuideName (AliasTemplate),
1214+ AliasTemplate->getDeclContext ());
1215+
12011216 auto [Template, AliasRhsTemplateArgs] =
12021217 getRHSTemplateDeclAndArgs (SemaRef, AliasTemplate);
12031218 if (!Template)
@@ -1210,6 +1225,8 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
12101225
12111226 for (auto *G : Guides) {
12121227 if (auto *DG = dyn_cast<CXXDeductionGuideDecl>(G)) {
1228+ if (SourceDeductionGuides.contains (DG))
1229+ continue ;
12131230 // The deduction guide is a non-template function decl, we just clone it.
12141231 auto *FunctionType =
12151232 SemaRef.Context .getTrivialTypeSourceInfo (DG->getType ());
@@ -1252,7 +1269,7 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
12521269 continue ;
12531270 }
12541271 FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(G);
1255- if (!F)
1272+ if (!F || SourceDeductionGuides. contains (F-> getTemplatedDecl ()) )
12561273 continue ;
12571274 // The **aggregate** deduction guides are handled in a different code path
12581275 // (DeclareAggregateDeductionGuideFromInitList), which involves the tricky
0 commit comments