Skip to content

Commit 979035a

Browse files
committed
[CodeCompletion] Ensure synthesized members are available before lookup
In ExprContextAnalyzer, when looking up members, some implicit members weren't populated. Ensure all implicit members available by force synthesizing them. rdar://89773376 (cherry picked from commit 4e62140)
1 parent 7aa36e5 commit 979035a

File tree

5 files changed

+50
-28
lines changed

5 files changed

+50
-28
lines changed

include/swift/AST/NameLookup.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,9 @@ void lookupVisibleMemberDecls(VisibleDeclConsumer &Consumer,
491491

492492
namespace namelookup {
493493

494+
/// Add semantic members to \p type before attempting a semantic lookup.
495+
void installSemanticMembersIfNeeded(Type type, DeclNameRef name);
496+
494497
void extractDirectlyReferencedNominalTypes(
495498
Type type, SmallVectorImpl<NominalTypeDecl *> &decls);
496499

lib/AST/NameLookup.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,6 +1592,32 @@ void namelookup::pruneLookupResultSet(const DeclContext *dc, NLOptions options,
15921592
filterForDiscriminator(decls, M->getDebugClient());
15931593
}
15941594

1595+
// An unfortunate hack to kick the decl checker into adding semantic members to
1596+
// the current type before we attempt a semantic lookup. The places this method
1597+
// looks needs to be in sync with \c extractDirectlyReferencedNominalTypes.
1598+
// See the note in \c synthesizeSemanticMembersIfNeeded about a better, more
1599+
// just, and peaceful world.
1600+
void namelookup::installSemanticMembersIfNeeded(Type type, DeclNameRef name) {
1601+
// Look-through class-bound archetypes to ensure we synthesize e.g.
1602+
// inherited constructors.
1603+
if (auto archetypeTy = type->getAs<ArchetypeType>()) {
1604+
if (auto super = archetypeTy->getSuperclass()) {
1605+
type = super;
1606+
}
1607+
}
1608+
1609+
if (type->isExistentialType()) {
1610+
auto layout = type->getExistentialLayout();
1611+
if (auto super = layout.explicitSuperclass) {
1612+
type = super;
1613+
}
1614+
}
1615+
1616+
if (auto *current = type->getAnyNominal()) {
1617+
current->synthesizeSemanticMembersIfNeeded(name.getFullName());
1618+
}
1619+
}
1620+
15951621
/// Inspect the given type to determine which nominal type declarations it
15961622
/// directly references, to facilitate name lookup into those types.
15971623
void namelookup::extractDirectlyReferencedNominalTypes(

lib/IDE/ExprContextAnalysis.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/AST/Initializer.h"
2222
#include "swift/AST/LazyResolver.h"
2323
#include "swift/AST/Module.h"
24+
#include "swift/AST/NameLookup.h"
2425
#include "swift/AST/ParameterList.h"
2526
#include "swift/AST/Pattern.h"
2627
#include "swift/AST/SourceFile.h"
@@ -364,6 +365,9 @@ static void collectPossibleCalleesByQualifiedLookup(
364365
if (!baseInstanceTy->mayHaveMembers())
365366
return;
366367

368+
// Make sure we've resolved implicit members.
369+
namelookup::installSemanticMembersIfNeeded(baseInstanceTy, name);
370+
367371
bool isOnMetaType = baseTy->is<AnyMetatypeType>();
368372

369373
SmallVector<ValueDecl *, 2> decls;

lib/Sema/TypeCheckNameLookup.cpp

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -273,32 +273,6 @@ LookupResult TypeChecker::lookupUnqualified(DeclContext *dc, DeclNameRef name,
273273
return result;
274274
}
275275

276-
// An unfortunate hack to kick the decl checker into adding semantic members to
277-
// the current type before we attempt a semantic lookup. The places this method
278-
// looks needs to be in sync with \c extractDirectlyReferencedNominalTypes.
279-
// See the note in \c synthesizeSemanticMembersIfNeeded about a better, more
280-
// just, and peaceful world.
281-
static void installSemanticMembersIfNeeded(Type type, DeclNameRef name) {
282-
// Look-through class-bound archetypes to ensure we synthesize e.g.
283-
// inherited constructors.
284-
if (auto archetypeTy = type->getAs<ArchetypeType>()) {
285-
if (auto super = archetypeTy->getSuperclass()) {
286-
type = super;
287-
}
288-
}
289-
290-
if (type->isExistentialType()) {
291-
auto layout = type->getExistentialLayout();
292-
if (auto super = layout.explicitSuperclass) {
293-
type = super;
294-
}
295-
}
296-
297-
if (auto *current = type->getAnyNominal()) {
298-
current->synthesizeSemanticMembersIfNeeded(name.getFullName());
299-
}
300-
}
301-
302276
LookupResult
303277
TypeChecker::lookupUnqualifiedType(DeclContext *dc, DeclNameRef name,
304278
SourceLoc loc,
@@ -346,7 +320,7 @@ LookupResult TypeChecker::lookupMember(DeclContext *dc,
346320
subOptions &= ~NL_RemoveNonVisible;
347321

348322
// Make sure we've resolved implicit members, if we need them.
349-
installSemanticMembersIfNeeded(type, name);
323+
namelookup::installSemanticMembersIfNeeded(type, name);
350324

351325
LookupResultBuilder builder(result, dc, options);
352326
SmallVector<ValueDecl *, 4> lookupResults;
@@ -438,7 +412,7 @@ LookupTypeResult TypeChecker::lookupMemberType(DeclContext *dc,
438412
subOptions |= NL_IncludeUsableFromInline;
439413

440414
// Make sure we've resolved implicit members, if we need them.
441-
installSemanticMembersIfNeeded(type, name);
415+
namelookup::installSemanticMembersIfNeeded(type, name);
442416

443417
if (!dc->lookupQualified(type, name, subOptions, decls))
444418
return result;

test/IDE/complete_call_arg.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,6 +1271,7 @@ func testSkippedCallArgInInvalidResultBuilderBody() {
12711271
Other(action: 2) {
12721272
MyImage(systemName: "", #^INVALID_RESULTBUILDER_ARG^#
12731273
struct Invalid
1274+
}
12741275
}
12751276

12761277
// INVALID_RESULTBUILDER_ARG: Begin completions, 1 item
@@ -1399,3 +1400,17 @@ func testVarInitializedByCallingClosure() {
13991400
// VAR_INITIALIZED_BY_CALLING_CLOSURE-DAG: Pattern/Local/Flair[ArgLabels]: {#withExtension: String?#}[#String?#];
14001401
// VAR_INITIALIZED_BY_CALLING_CLOSURE: End completions
14011402
}
1403+
1404+
struct Rdar89773376 {
1405+
var intVal: Int
1406+
}
1407+
extension Rdar89773376 {
1408+
init(string: String) { self.intVal = 1 }
1409+
}
1410+
func testRdar89773376(arry: [Int]) {
1411+
arry.map { Rdar89773376(#^RDAR89773376^#) }
1412+
// RDAR89773376: Begin completions, 2 items
1413+
// RDAR89773376-DAG: Decl[Constructor]/CurrNominal/Flair[ArgLabels]: ['(']{#string: String#}[')'][#Rdar89773376#];
1414+
// RDAR89773376-DAG: Decl[Constructor]/CurrNominal/Flair[ArgLabels]: ['(']{#intVal: Int#}[')'][#Rdar89773376#];
1415+
// RDAR89773376: End completions
1416+
}

0 commit comments

Comments
 (0)