Skip to content

Commit ebacfd1

Browse files
authored
Merge pull request #21723 from slavapestov/code-completion-fixes-5.0
Code completion fixes [5.0]
2 parents d319242 + 34df231 commit ebacfd1

16 files changed

+247
-293
lines changed

lib/AST/LookupVisibleDecls.cpp

Lines changed: 57 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -230,27 +230,8 @@ static void lookupTypeMembers(Type BaseType, Type LookupType,
230230
NominalTypeDecl *D = LookupType->getAnyNominal();
231231
assert(D && "should have a nominal type");
232232

233-
bool LookupFromChildDeclContext = false;
234-
const DeclContext *TempDC = CurrDC;
235-
while (!TempDC->isModuleContext()) {
236-
if (TempDC == D) {
237-
LookupFromChildDeclContext = true;
238-
break;
239-
}
240-
TempDC = TempDC->getParent();
241-
}
242-
243233
SmallVector<ValueDecl*, 2> FoundDecls;
244234

245-
if (LookupFromChildDeclContext) {
246-
// Current decl context is contained inside 'D', so generic parameters
247-
// are visible.
248-
if (D->getGenericParams())
249-
for (auto Param : *D->getGenericParams())
250-
if (isDeclVisibleInLookupMode(Param, LS, CurrDC, TypeResolver))
251-
FoundDecls.push_back(Param);
252-
}
253-
254235
for (Decl *Member : D->getMembers()) {
255236
if (auto *VD = dyn_cast<ValueDecl>(Member))
256237
if (isDeclVisibleInLookupMode(VD, LS, CurrDC, TypeResolver))
@@ -471,92 +452,6 @@ lookupVisibleMemberDeclsImpl(Type BaseTy, VisibleDeclConsumer &Consumer,
471452
GenericSignatureBuilder *GSB,
472453
VisitedSet &Visited);
473454

474-
// Filters out restated declarations from a protocol hierarchy
475-
// or equivalent requirements from protocol composition types.
476-
class RestateFilteringConsumer : public VisibleDeclConsumer {
477-
LazyResolver *resolver;
478-
479-
using FoundDecl = std::pair<ValueDecl*, DeclVisibilityKind>;
480-
using NameAndType = std::pair<DeclName, CanType>;
481-
482-
llvm::DenseMap<DeclName, FoundDecl> foundVars;
483-
llvm::DenseMap<NameAndType, FoundDecl> foundFuncs;
484-
llvm::MapVector<ValueDecl*, DeclVisibilityKind> declsToReport;
485-
486-
template <typename K>
487-
void addDecl(llvm::DenseMap<K, FoundDecl> &Map, K Key, FoundDecl FD) {
488-
// Add the declaration if we haven't found an equivalent yet, otherwise
489-
// replace the equivalent if the found decl has a higher access level.
490-
auto existingDecl = Map.find(Key);
491-
492-
if ((existingDecl == Map.end()) ||
493-
(Map[Key].first->getFormalAccess() < FD.first->getFormalAccess())) {
494-
if (existingDecl != Map.end())
495-
declsToReport.erase({existingDecl->getSecond().first});
496-
Map[Key] = FD;
497-
declsToReport.insert(FD);
498-
}
499-
}
500-
501-
CanType stripSelfRequirementsIfNeeded(ValueDecl *VD,
502-
GenericFunctionType *GFT) const {
503-
// Preserve the generic signature if this is a subscript, which are uncurried,
504-
// or if we have generic params other than Self. Otherwise, use
505-
// the resultType of the curried function type.
506-
// When we keep the generic signature, we remove the requirements
507-
// from Self to make sure they don't prevent us from recognizing restatements.
508-
auto params = GFT->getGenericParams();
509-
if (params.size() == 1 && !isa<SubscriptDecl>(VD)) {
510-
return GFT->getResult()->getCanonicalType();
511-
}
512-
auto Self = VD->getDeclContext()->getSelfInterfaceType();
513-
SmallVector<Requirement, 4> newReqs;
514-
for (auto req: GFT->getRequirements()) {
515-
if (!Self->isEqual(req.getFirstType()))
516-
newReqs.push_back(req);
517-
}
518-
auto newSig = GenericSignature::get(params, newReqs, false);
519-
520-
return GenericFunctionType::get(newSig, GFT->getParams(),
521-
GFT->getResult(), GFT->getExtInfo())
522-
->getCanonicalType();
523-
}
524-
525-
public:
526-
RestateFilteringConsumer(Type baseTy, const DeclContext *DC,
527-
LazyResolver *resolver)
528-
: resolver(resolver) {
529-
assert(DC && baseTy && !baseTy->hasLValueType());
530-
}
531-
532-
void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override {
533-
assert(VD);
534-
// If this isn't a protocol context, don't look further into the decl.
535-
if (!isa<ProtocolDecl>(VD->getDeclContext())) {
536-
declsToReport.insert({VD, Reason});
537-
return;
538-
}
539-
if (resolver)
540-
resolver->resolveDeclSignature(VD);
541-
542-
if (!VD->hasInterfaceType()) {
543-
declsToReport.insert({VD, Reason});
544-
return;
545-
}
546-
if (auto GFT = VD->getInterfaceType()->getAs<GenericFunctionType>()) {
547-
auto type = stripSelfRequirementsIfNeeded(VD, GFT);
548-
addDecl(foundFuncs, {VD->getFullName(), type}, {VD, Reason});
549-
return;
550-
}
551-
addDecl(foundVars, VD->getFullName(), {VD, Reason});
552-
}
553-
554-
void feedResultsToConsumer(VisibleDeclConsumer &Consumer) const {
555-
for (const auto entry: declsToReport)
556-
Consumer.foundDecl(entry.first, entry.second);
557-
}
558-
};
559-
560455
static void
561456
lookupVisibleProtocolMemberDecls(Type BaseTy, ProtocolType *PT,
562457
VisibleDeclConsumer &Consumer,
@@ -642,12 +537,11 @@ static void lookupVisibleMemberDeclsImpl(
642537
for (auto Proto : Archetype->getConformsTo())
643538
lookupVisibleProtocolMemberDecls(
644539
BaseTy, Proto->getDeclaredType(), Consumer, CurrDC, LS,
645-
getReasonForSuper(Reason), TypeResolver, GSB, Visited);
540+
Reason, TypeResolver, GSB, Visited);
646541

647542
if (auto superclass = Archetype->getSuperclass())
648543
lookupVisibleMemberDeclsImpl(superclass, Consumer, CurrDC, LS,
649-
getReasonForSuper(Reason), TypeResolver,
650-
GSB, Visited);
544+
Reason, TypeResolver, GSB, Visited);
651545
return;
652546
}
653547

@@ -766,19 +660,25 @@ template <> struct DenseMapInfo<FoundDeclTy> {
766660

767661
} // namespace llvm
768662

769-
namespace {
770-
771-
/// Hack to guess at whether substituting into the type of a declaration will
772-
/// be okay.
773-
/// FIXME: This is awful. We should either have Type::subst() work for
774-
/// GenericFunctionType, or we should kill it outright.
775-
static bool shouldSubstIntoDeclType(Type type) {
776-
auto genericFnType = type->getAs<GenericFunctionType>();
777-
if (!genericFnType) return true;
663+
// If a class 'Base' conforms to 'Proto', and my base type is a subclass
664+
// 'Derived' of 'Base', use 'Base' not 'Derived' as the 'Self' type in the
665+
// substitution map.
666+
static Type getBaseTypeForMember(ModuleDecl *M, ValueDecl *OtherVD, Type BaseTy) {
667+
if (auto *Proto = OtherVD->getDeclContext()->getSelfProtocolDecl()) {
668+
if (BaseTy->getClassOrBoundGenericClass()) {
669+
if (auto Conformance = M->lookupConformance(BaseTy, Proto)) {
670+
auto *Superclass = Conformance->getConcrete()->getRootConformance()
671+
->getType()->getClassOrBoundGenericClass();
672+
return BaseTy->getSuperclassForDecl(Superclass);
673+
}
674+
}
675+
}
778676

779-
return false;
677+
return BaseTy;
780678
}
781679

680+
namespace {
681+
782682
class OverrideFilteringConsumer : public VisibleDeclConsumer {
783683
public:
784684
std::set<ValueDecl *> AllFoundDecls;
@@ -787,16 +687,12 @@ class OverrideFilteringConsumer : public VisibleDeclConsumer {
787687
Type BaseTy;
788688
const DeclContext *DC;
789689
LazyResolver *TypeResolver;
790-
bool IsTypeLookup = false;
791690

792691
OverrideFilteringConsumer(Type BaseTy, const DeclContext *DC,
793692
LazyResolver *resolver)
794-
: BaseTy(BaseTy), DC(DC), TypeResolver(resolver) {
693+
: BaseTy(BaseTy->getMetatypeInstanceType()),
694+
DC(DC), TypeResolver(resolver) {
795695
assert(!BaseTy->hasLValueType());
796-
if (auto *MetaTy = BaseTy->getAs<AnyMetatypeType>()) {
797-
BaseTy = MetaTy->getInstanceType();
798-
IsTypeLookup = true;
799-
}
800696
assert(DC && BaseTy);
801697
}
802698

@@ -806,7 +702,9 @@ class OverrideFilteringConsumer : public VisibleDeclConsumer {
806702

807703
// If this kind of declaration doesn't participate in overriding, there's
808704
// no filtering to do here.
809-
if (!isa<AbstractFunctionDecl>(VD) && !isa<AbstractStorageDecl>(VD)) {
705+
if (!isa<AbstractFunctionDecl>(VD) &&
706+
!isa<AbstractStorageDecl>(VD) &&
707+
!isa<AssociatedTypeDecl>(VD)) {
810708
DeclsToReport.insert(FoundDeclTy(VD, Reason));
811709
return;
812710
}
@@ -857,7 +755,8 @@ class OverrideFilteringConsumer : public VisibleDeclConsumer {
857755
// don't substitute either.
858756
bool shouldSubst = (!BaseTy->isAnyObject() &&
859757
!BaseTy->hasTypeVariable() &&
860-
BaseTy->getNominalOrBoundGenericNominal() &&
758+
(BaseTy->getNominalOrBoundGenericNominal() ||
759+
BaseTy->is<ArchetypeType>()) &&
861760
VD->getDeclContext()->isTypeContext());
862761
ModuleDecl *M = DC->getParentModule();
863762

@@ -870,8 +769,7 @@ class OverrideFilteringConsumer : public VisibleDeclConsumer {
870769

871770
auto FoundSignature = VD->getOverloadSignature();
872771
auto FoundSignatureType = VD->getOverloadSignatureType();
873-
if (FoundSignatureType && shouldSubst &&
874-
shouldSubstIntoDeclType(FoundSignatureType)) {
772+
if (FoundSignatureType && shouldSubst) {
875773
auto subs = BaseTy->getMemberSubstitutionMap(M, VD);
876774
if (auto CT = FoundSignatureType.subst(subs))
877775
FoundSignatureType = CT->getCanonicalType();
@@ -888,9 +786,9 @@ class OverrideFilteringConsumer : public VisibleDeclConsumer {
888786

889787
auto OtherSignature = OtherVD->getOverloadSignature();
890788
auto OtherSignatureType = OtherVD->getOverloadSignatureType();
891-
if (OtherSignatureType && shouldSubst &&
892-
shouldSubstIntoDeclType(OtherSignatureType)) {
893-
auto subs = BaseTy->getMemberSubstitutionMap(M, OtherVD);
789+
if (OtherSignatureType && shouldSubst) {
790+
auto ActualBaseTy = getBaseTypeForMember(M, OtherVD, BaseTy);
791+
auto subs = ActualBaseTy->getMemberSubstitutionMap(M, OtherVD);
894792
if (auto CT = OtherSignatureType.subst(subs))
895793
OtherSignatureType = CT->getCanonicalType();
896794
}
@@ -931,13 +829,11 @@ static void lookupVisibleMemberDecls(
931829
LookupState LS, DeclVisibilityKind Reason, LazyResolver *TypeResolver,
932830
GenericSignatureBuilder *GSB) {
933831
OverrideFilteringConsumer overrideConsumer(BaseTy, CurrDC, TypeResolver);
934-
RestateFilteringConsumer restateConsumer(BaseTy, CurrDC, TypeResolver);
935832
VisitedSet Visited;
936-
lookupVisibleMemberDeclsImpl(BaseTy, restateConsumer, CurrDC, LS, Reason,
833+
lookupVisibleMemberDeclsImpl(BaseTy, overrideConsumer, CurrDC, LS, Reason,
937834
TypeResolver, GSB, Visited);
938835

939836
// Report the declarations we found to the real consumer.
940-
restateConsumer.feedResultsToConsumer(overrideConsumer);
941837
for (const auto &DeclAndReason : overrideConsumer.DeclsToReport)
942838
Consumer.foundDecl(DeclAndReason.D, DeclAndReason.Reason);
943839
}
@@ -953,7 +849,7 @@ static void lookupVisibleDeclsImpl(VisibleDeclConsumer &Consumer,
953849
// If we are inside of a method, check to see if there are any ivars in scope,
954850
// and if so, whether this is a reference to one of them.
955851
while (!DC->isModuleScopeContext()) {
956-
const ValueDecl *BaseDecl = nullptr;
852+
GenericParamList *GenericParams = nullptr;
957853
Type ExtendedType;
958854
auto LS = LookupState::makeUnqualified();
959855

@@ -977,7 +873,6 @@ static void lookupVisibleDeclsImpl(VisibleDeclConsumer &Consumer,
977873
if (auto *SE = dyn_cast<SubscriptDecl>(DC)) {
978874
ExtendedType = SE->getDeclContext()->getSelfTypeInContext();
979875
DC = DC->getParent();
980-
BaseDecl = DC->getSelfNominalTypeDecl();
981876
} else if (auto *AFD = dyn_cast<AbstractFunctionDecl>(DC)) {
982877

983878
// Look for local variables; normally, the parser resolves these
@@ -996,9 +891,10 @@ static void lookupVisibleDeclsImpl(VisibleDeclConsumer &Consumer,
996891
namelookup::FindLocalVal(SM, Loc, Consumer).checkParameterList(
997892
AFD->getParameters());
998893

894+
GenericParams = AFD->getGenericParams();
895+
999896
if (AFD->getDeclContext()->isTypeContext()) {
1000897
ExtendedType = AFD->getDeclContext()->getSelfTypeInContext();
1001-
BaseDecl = AFD->getImplicitSelfDecl();
1002898
DC = DC->getParent();
1003899

1004900
if (auto *FD = dyn_cast<FuncDecl>(AFD))
@@ -1014,14 +910,34 @@ static void lookupVisibleDeclsImpl(VisibleDeclConsumer &Consumer,
1014910
}
1015911
} else if (auto ED = dyn_cast<ExtensionDecl>(DC)) {
1016912
ExtendedType = ED->getSelfTypeInContext();
1017-
if (ExtendedType)
1018-
BaseDecl = ExtendedType->getNominalOrBoundGenericNominal();
1019913
} else if (auto ND = dyn_cast<NominalTypeDecl>(DC)) {
1020914
ExtendedType = ND->getSelfTypeInContext();
1021-
BaseDecl = ND;
1022915
}
1023916

1024-
if (BaseDecl && ExtendedType)
917+
// If we're inside a function context, we've already moved to
918+
// the parent DC, so we have to check the function's generic
919+
// parameters first.
920+
if (GenericParams) {
921+
namelookup::FindLocalVal localVal(SM, Loc, Consumer);
922+
localVal.checkGenericParams(GenericParams);
923+
}
924+
925+
// Check the generic parameters of our context.
926+
GenericParamList *dcGenericParams = nullptr;
927+
if (auto nominal = dyn_cast<NominalTypeDecl>(DC))
928+
dcGenericParams = nominal->getGenericParams();
929+
else if (auto ext = dyn_cast<ExtensionDecl>(DC))
930+
dcGenericParams = ext->getGenericParams();
931+
else if (auto subscript = dyn_cast<SubscriptDecl>(DC))
932+
dcGenericParams = subscript->getGenericParams();
933+
934+
while (dcGenericParams) {
935+
namelookup::FindLocalVal localVal(SM, Loc, Consumer);
936+
localVal.checkGenericParams(dcGenericParams);
937+
dcGenericParams = dcGenericParams->getOuterParameters();
938+
}
939+
940+
if (ExtendedType)
1025941
::lookupVisibleMemberDecls(ExtendedType, Consumer, DC, LS, Reason,
1026942
TypeResolver, nullptr);
1027943

lib/AST/Type.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ Type TypeBase::addCurriedSelfType(const DeclContext *dc) {
439439
genericFn->getExtInfo());
440440
}
441441

442-
auto selfTy = dc->getDeclaredInterfaceType();
442+
auto selfTy = dc->getSelfInterfaceType();
443443
auto selfParam = AnyFunctionType::Param(selfTy);
444444
if (sig)
445445
return GenericFunctionType::get(sig, {selfParam}, type);
@@ -860,7 +860,6 @@ Type TypeBase::getMetatypeInstanceType() {
860860
if (auto metaTy = getAs<AnyMetatypeType>())
861861
return metaTy->getInstanceType();
862862

863-
// For mutable value type methods, we need to dig through inout types.
864863
return this;
865864
}
866865

0 commit comments

Comments
 (0)