Skip to content

Commit a4a6d09

Browse files
authored
Merge pull request #59479 from beccadax/you-completion-me
Allow @objc protocols to declare async alternatives
2 parents a8ad273 + 5459737 commit a4a6d09

22 files changed

+174
-59
lines changed

include/swift/AST/Decl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6757,7 +6757,7 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
67576757
bool hasDynamicSelfResult() const;
67586758

67596759
/// The async function marked as the alternative to this function, if any.
6760-
AbstractFunctionDecl *getAsyncAlternative() const;
6760+
AbstractFunctionDecl *getAsyncAlternative(bool isKnownObjC = false) const;
67616761

67626762
/// If \p asyncAlternative is set, then compare its parameters to this
67636763
/// (presumed synchronous) function's parameters to find the index of the

include/swift/AST/ModuleLoader.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,11 @@ class ModuleLoader {
226226
virtual void loadExtensions(NominalTypeDecl *nominal,
227227
unsigned previousGeneration) { }
228228

229-
/// Load the methods within the given class that produce
229+
/// Load the methods within the given type that produce
230230
/// Objective-C class or instance methods with the given selector.
231231
///
232-
/// \param classDecl The class in which we are searching for @objc methods.
233-
/// The search only considers this class and its extensions; not any
232+
/// \param typeDecl The type in which we are searching for @objc methods.
233+
/// The search only considers this type and its extensions; not any
234234
/// superclasses.
235235
///
236236
/// \param selector The selector to search for.
@@ -246,7 +246,7 @@ class ModuleLoader {
246246
/// selector and are instance/class methods as requested. This list will be
247247
/// extended with any methods found in subsequent generations.
248248
virtual void loadObjCMethods(
249-
ClassDecl *classDecl,
249+
NominalTypeDecl *typeDecl,
250250
ObjCSelector selector,
251251
bool isInstanceMethod,
252252
unsigned previousGeneration,

include/swift/AST/SourceFile.h

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/AST/Import.h"
1818
#include "swift/AST/SynthesizedFileUnit.h"
1919
#include "swift/Basic/Debug.h"
20+
#include "llvm/ADT/Hashing.h"
2021
#include "llvm/ADT/SetVector.h"
2122
#include "llvm/ADT/SmallPtrSet.h"
2223

@@ -243,11 +244,20 @@ class SourceFile final : public FileUnit {
243244
std::vector<ObjCUnsatisfiedOptReq> ObjCUnsatisfiedOptReqs;
244245

245246
/// A selector that is used by two different declarations in the same class.
246-
/// Fields: typeDecl, selector, isInstanceMethod.
247-
using ObjCMethodConflict = std::tuple<NominalTypeDecl *, ObjCSelector, bool>;
247+
struct ObjCMethodConflict {
248+
NominalTypeDecl *typeDecl;
249+
ObjCSelector selector;
250+
bool isInstanceMethod;
251+
252+
ObjCMethodConflict(NominalTypeDecl *typeDecl, ObjCSelector selector,
253+
bool isInstanceMethod)
254+
: typeDecl(typeDecl), selector(selector),
255+
isInstanceMethod(isInstanceMethod)
256+
{}
257+
};
248258

249259
/// List of Objective-C member conflicts we have found during type checking.
250-
std::vector<ObjCMethodConflict> ObjCMethodConflicts;
260+
llvm::SetVector<ObjCMethodConflict> ObjCMethodConflicts;
251261

252262
/// List of attributes added by access notes, used to emit remarks for valid
253263
/// ones.
@@ -636,4 +646,30 @@ inline void simple_display(llvm::raw_ostream &out, const SourceFile *SF) {
636646
}
637647
} // end namespace swift
638648

649+
namespace llvm {
650+
651+
template<>
652+
struct DenseMapInfo<swift::SourceFile::ObjCMethodConflict> {
653+
using ObjCMethodConflict = swift::SourceFile::ObjCMethodConflict;
654+
655+
static inline ObjCMethodConflict getEmptyKey() {
656+
return ObjCMethodConflict(nullptr, {}, false);
657+
}
658+
static inline ObjCMethodConflict getTombstoneKey() {
659+
return ObjCMethodConflict(nullptr, {}, true);
660+
}
661+
static inline unsigned getHashValue(ObjCMethodConflict a) {
662+
return hash_combine(hash_value(a.typeDecl),
663+
DenseMapInfo<swift::ObjCSelector>::getHashValue(a.selector),
664+
hash_value(a.isInstanceMethod));
665+
}
666+
static bool isEqual(ObjCMethodConflict a, ObjCMethodConflict b) {
667+
return a.typeDecl == b.typeDecl && a.selector == b.selector &&
668+
a.isInstanceMethod == b.isInstanceMethod;
669+
}
670+
};
671+
672+
}
673+
674+
639675
#endif

include/swift/AST/TypeCheckRequests.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3441,7 +3441,8 @@ class ConditionalRequirementsRequest
34413441

34423442
class RenamedDeclRequest
34433443
: public SimpleRequest<RenamedDeclRequest,
3444-
ValueDecl *(const ValueDecl *, const AvailableAttr *),
3444+
ValueDecl *(const ValueDecl *, const AvailableAttr *,
3445+
bool isKnownObjC),
34453446
RequestFlags::Cached> {
34463447
public:
34473448
using SimpleRequest::SimpleRequest;
@@ -3450,7 +3451,7 @@ class RenamedDeclRequest
34503451
friend SimpleRequest;
34513452

34523453
ValueDecl *evaluate(Evaluator &evaluator, const ValueDecl *attached,
3453-
const AvailableAttr *attr) const;
3454+
const AvailableAttr *attr, bool isKnownObjC) const;
34543455

34553456
public:
34563457
bool isCached() const { return true; }

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ SWIFT_REQUEST(TypeChecker, GetImplicitSendableRequest,
390390
ProtocolConformance *(NominalTypeDecl *),
391391
Cached, NoLocationInfo)
392392
SWIFT_REQUEST(TypeChecker, RenamedDeclRequest,
393-
ValueDecl *(const ValueDecl *),
393+
ValueDecl *(const ValueDecl *, const AvailableAttr *, bool),
394394
Cached, NoLocationInfo)
395395
SWIFT_REQUEST(TypeChecker, ClosureEffectsRequest,
396396
FunctionType::ExtInfo(ClosureExpr *),

include/swift/ClangImporter/ClangImporter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ class ClangImporter final : public ClangModuleLoader {
309309
unsigned previousGeneration) override;
310310

311311
virtual void loadObjCMethods(
312-
ClassDecl *classDecl,
312+
NominalTypeDecl *typeDecl,
313313
ObjCSelector selector,
314314
bool isInstanceMethod,
315315
unsigned previousGeneration,

include/swift/Sema/SourceLoader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class SourceLoader : public ModuleLoader {
8585
unsigned previousGeneration) override;
8686

8787
virtual void loadObjCMethods(
88-
ClassDecl *classDecl,
88+
NominalTypeDecl *typeDecl,
8989
ObjCSelector selector,
9090
bool isInstanceMethod,
9191
unsigned previousGeneration,

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ class SerializedModuleLoaderBase : public ModuleLoader {
190190
unsigned previousGeneration) override;
191191

192192
virtual void loadObjCMethods(
193-
ClassDecl *classDecl,
193+
NominalTypeDecl *typeDecl,
194194
ObjCSelector selector,
195195
bool isInstanceMethod,
196196
unsigned previousGeneration,

lib/AST/ASTContext.cpp

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1919,24 +1919,12 @@ void ASTContext::loadObjCMethods(
19191919
PrettyStackTraceSelector stackTraceSelector("looking for", selector);
19201920
PrettyStackTraceDecl stackTraceDecl("...in", tyDecl);
19211921

1922-
// @objc protocols cannot have @objc extension members, so if we've recorded
1923-
// everything in the protocol definition, we've recorded everything. And we
1924-
// only ever use the ObjCSelector version of `NominalTypeDecl::lookupDirect()`
1925-
// on protocols in primary file typechecking, so we don't care about protocols
1926-
// that need to be loaded from files.
1927-
// TODO: Rework `ModuleLoader::loadObjCMethods()` to support protocols too if
1928-
// selector-based `NominalTypeDecl::lookupDirect()` ever needs to work
1929-
// in more situations.
1930-
ClassDecl *classDecl = dyn_cast<ClassDecl>(tyDecl);
1931-
if (!classDecl)
1932-
return;
1933-
19341922
for (auto &loader : getImpl().ModuleLoaders) {
19351923
// Ignore the Clang importer if we've been asked for Swift-only results.
19361924
if (swiftOnly && loader.get() == getClangModuleLoader())
19371925
continue;
19381926

1939-
loader->loadObjCMethods(classDecl, selector, isInstanceMethod,
1927+
loader->loadObjCMethods(tyDecl, selector, isInstanceMethod,
19401928
previousGeneration, methods);
19411929
}
19421930
}

lib/AST/Decl.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7627,7 +7627,8 @@ bool AbstractFunctionDecl::hasDynamicSelfResult() const {
76277627
return isa<ConstructorDecl>(this);
76287628
}
76297629

7630-
AbstractFunctionDecl *AbstractFunctionDecl::getAsyncAlternative() const {
7630+
AbstractFunctionDecl *
7631+
AbstractFunctionDecl::getAsyncAlternative(bool isKnownObjC) const {
76317632
// Async functions can't have async alternatives
76327633
if (hasAsync())
76337634
return nullptr;
@@ -7651,7 +7652,8 @@ AbstractFunctionDecl *AbstractFunctionDecl::getAsyncAlternative() const {
76517652
}
76527653

76537654
auto *renamedDecl = evaluateOrDefault(
7654-
getASTContext().evaluator, RenamedDeclRequest{this, avAttr}, nullptr);
7655+
getASTContext().evaluator, RenamedDeclRequest{this, avAttr, isKnownObjC},
7656+
nullptr);
76557657
auto *alternative = dyn_cast_or_null<AbstractFunctionDecl>(renamedDecl);
76567658
if (!alternative || !alternative->hasAsync())
76577659
return nullptr;

0 commit comments

Comments
 (0)