@@ -565,6 +565,23 @@ void swift::conformToCxxSequenceIfNeeded(
565565 }
566566}
567567
568+ static bool isStdSetType (const clang::CXXRecordDecl *clangDecl) {
569+ return isStdDecl (clangDecl, {" set" , " unordered_set" , " multiset" });
570+ }
571+
572+ bool swift::isUnsafeStdMethod (const clang::CXXMethodDecl *methodDecl) {
573+ auto parentDecl =
574+ dyn_cast<clang::CXXRecordDecl>(methodDecl->getDeclContext ());
575+ if (!parentDecl)
576+ return false ;
577+ if (!isStdSetType (parentDecl))
578+ return false ;
579+ if (methodDecl->getDeclName ().isIdentifier () &&
580+ methodDecl->getName () == " insert" )
581+ return true ;
582+ return false ;
583+ }
584+
568585void swift::conformToCxxSetIfNeeded (ClangImporter::Implementation &impl,
569586 NominalTypeDecl *decl,
570587 const clang::CXXRecordDecl *clangDecl) {
@@ -576,7 +593,7 @@ void swift::conformToCxxSetIfNeeded(ClangImporter::Implementation &impl,
576593
577594 // Only auto-conform types from the C++ standard library. Custom user types
578595 // might have a similar interface but different semantics.
579- if (!isStdDecl (clangDecl, { " set " , " unordered_set " , " multiset " } ))
596+ if (!isStdSetType (clangDecl))
580597 return ;
581598
582599 auto valueType = lookupDirectSingleWithoutExtensions<TypeAliasDecl>(
@@ -586,10 +603,33 @@ void swift::conformToCxxSetIfNeeded(ClangImporter::Implementation &impl,
586603 if (!valueType || !sizeType)
587604 return ;
588605
606+ auto insertId = ctx.getIdentifier (" __insertUnsafe" );
607+ auto inserts = lookupDirectWithoutExtensions (decl, insertId);
608+ FuncDecl *insert = nullptr ;
609+ for (auto candidate : inserts) {
610+ if (auto candidateMethod = dyn_cast<FuncDecl>(candidate)) {
611+ if (!candidateMethod->hasParameterList ())
612+ continue ;
613+ auto params = candidateMethod->getParameters ();
614+ if (params->size () != 1 )
615+ continue ;
616+ auto param = params->front ();
617+ if (param->getType ()->getCanonicalType () !=
618+ valueType->getUnderlyingType ()->getCanonicalType ())
619+ continue ;
620+ insert = candidateMethod;
621+ break ;
622+ }
623+ }
624+ if (!insert)
625+ return ;
626+
589627 impl.addSynthesizedTypealias (decl, ctx.Id_Element ,
590628 valueType->getUnderlyingType ());
591629 impl.addSynthesizedTypealias (decl, ctx.getIdentifier (" Size" ),
592630 sizeType->getUnderlyingType ());
631+ impl.addSynthesizedTypealias (decl, ctx.getIdentifier (" InsertionResult" ),
632+ insert->getResultInterfaceType ());
593633 impl.addSynthesizedProtocolAttrs (decl, {KnownProtocolKind::CxxSet});
594634}
595635
0 commit comments