@@ -22,11 +22,32 @@ using namespace swift;
2222using namespace ide ;
2323using TypeRelation = CodeCompletionResultTypeRelation;
2424
25+ // MARK: - Utilities
26+
27+ // / Returns the kind of attributes \c Ty can be used as.
28+ static OptionSet<CustomAttributeKind> getCustomAttributeKinds (Type Ty) {
29+ OptionSet<CustomAttributeKind> Result;
30+ if (auto NominalTy = Ty->getAs <NominalType>()) {
31+ auto NominalDecl = NominalTy->getDecl ();
32+ if (NominalDecl->getAttrs ().hasAttribute <PropertyWrapperAttr>()) {
33+ Result |= CustomAttributeKind::PropertyWrapper;
34+ }
35+ if (NominalDecl->getAttrs ().hasAttribute <ResultBuilderAttr>()) {
36+ Result |= CustomAttributeKind::ResultBuilder;
37+ }
38+ if (NominalDecl->isGlobalActor ()) {
39+ Result |= CustomAttributeKind::GlobalActor;
40+ }
41+ }
42+ return Result;
43+ }
44+
2545// MARK: - USRBasedTypeContext
2646
2747USRBasedTypeContext::USRBasedTypeContext (const ExpectedTypeContext *TypeContext,
2848 USRBasedTypeArena &Arena)
29- : Arena(Arena) {
49+ : Arena(Arena), ExpectedCustomAttributeKinds(
50+ TypeContext->getExpectedCustomAttributeKinds ()) {
3051
3152 for (auto possibleTy : TypeContext->getPossibleTypes ()) {
3253 ContextualTypes.emplace_back (USRBasedType::fromType (possibleTy, Arena));
@@ -63,6 +84,11 @@ USRBasedTypeContext::USRBasedTypeContext(const ExpectedTypeContext *TypeContext,
6384
6485TypeRelation
6586USRBasedTypeContext::typeRelation (const USRBasedType *ResultType) const {
87+ if (ExpectedCustomAttributeKinds) {
88+ return ResultType->getCustomAttributeKinds () & ExpectedCustomAttributeKinds
89+ ? TypeRelation::Convertible
90+ : TypeRelation::Unrelated;
91+ }
6692 const USRBasedType *VoidType = Arena.getVoidType ();
6793 if (ResultType == VoidType) {
6894 // Void is not convertible to anything and we don't report Void <-> Void
@@ -85,7 +111,7 @@ USRBasedTypeContext::typeRelation(const USRBasedType *ResultType) const {
85111
86112USRBasedTypeArena::USRBasedTypeArena () {
87113 // '$sytD' is the USR of the Void type.
88- VoidType = USRBasedType::fromUSR (" $sytD" , {}, *this );
114+ VoidType = USRBasedType::fromUSR (" $sytD" , {}, {}, *this );
89115}
90116
91117const USRBasedType *USRBasedTypeArena::getVoidType () const { return VoidType; }
@@ -125,11 +151,12 @@ TypeRelation USRBasedType::typeRelationImpl(
125151}
126152
127153const USRBasedType *USRBasedType::null (USRBasedTypeArena &Arena) {
128- return USRBasedType::fromUSR (/* USR=*/ " " , /* Supertypes=*/ {}, Arena);
154+ return USRBasedType::fromUSR (/* USR=*/ " " , /* Supertypes=*/ {}, {}, Arena);
129155}
130156
131157const USRBasedType *
132158USRBasedType::fromUSR (StringRef USR, ArrayRef<const USRBasedType *> Supertypes,
159+ OptionSet<CustomAttributeKind> CustomAttributeKinds,
133160 USRBasedTypeArena &Arena) {
134161 auto ExistingTypeIt = Arena.CanonicalTypes .find (USR);
135162 if (ExistingTypeIt != Arena.CanonicalTypes .end ()) {
@@ -142,7 +169,7 @@ USRBasedType::fromUSR(StringRef USR, ArrayRef<const USRBasedType *> Supertypes,
142169 Supertypes = Supertypes.copy (Arena.Allocator );
143170
144171 const USRBasedType *Result =
145- new (Arena.Allocator ) USRBasedType (USR, Supertypes);
172+ new (Arena.Allocator ) USRBasedType (USR, Supertypes, CustomAttributeKinds );
146173 Arena.CanonicalTypes [USR] = Result;
147174 return Result;
148175}
@@ -251,7 +278,8 @@ const USRBasedType *USRBasedType::fromType(Type Ty, USRBasedTypeArena &Arena) {
251278 return ImpliedSupertypes.contains (Ty);
252279 });
253280
254- return USRBasedType::fromUSR (USR, Supertypes, Arena);
281+ return USRBasedType::fromUSR (USR, Supertypes, ::getCustomAttributeKinds (Ty),
282+ Arena);
255283}
256284
257285TypeRelation USRBasedType::typeRelation (const USRBasedType *ResultType,
@@ -309,6 +337,12 @@ calculateMaxTypeRelation(Type Ty, const ExpectedTypeContext &typeContext,
309337 const DeclContext &DC) {
310338 if (Ty->isVoid () && typeContext.requiresNonVoid ())
311339 return TypeRelation::Invalid;
340+ if (typeContext.getExpectedCustomAttributeKinds ()) {
341+ return (getCustomAttributeKinds (Ty) &
342+ typeContext.getExpectedCustomAttributeKinds ())
343+ ? TypeRelation::Convertible
344+ : TypeRelation::Unrelated;
345+ }
312346 if (typeContext.empty ())
313347 return TypeRelation::Unknown;
314348
0 commit comments