Skip to content

Commit e65d867

Browse files
authored
Merge pull request #6552 from slavapestov/protocol-typealias-unqualified-lookup
Unqualified lookup can now find protocol typealiases
2 parents 6c9f99f + 41dde88 commit e65d867

24 files changed

+239
-204
lines changed

include/swift/AST/Types.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -648,9 +648,17 @@ class alignas(1 << TypeAlignInBits) TypeBase {
648648
/// with a class type.
649649
bool mayHaveSuperclass();
650650

651-
/// \brief Determine whether this type may have nested types, which holds for
652-
/// nominal types, existentials and archetypes.
653-
bool mayHaveMemberTypes() {
651+
/// \brief Determine whether this type can be used as a base type for AST
652+
/// name lookup, which is the case for nominal types, protocol compositions
653+
/// and archetypes.
654+
///
655+
/// Generally, the static vs instanec and mutating vs nonmutating distinction
656+
/// is handled elsewhere, so metatypes, lvalue types and inout types are not
657+
/// allowed here.
658+
///
659+
/// Similarly, tuples formally have members, but this does not go through
660+
/// name lookup.
661+
bool mayHaveMembers() {
654662
return (is<ArchetypeType>() ||
655663
is<ModuleType>() ||
656664
isExistentialType() ||

lib/AST/ASTPrinter.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ struct SynthesizedExtensionAnalyzer::Implementation {
224224
// the extension to the interface types of the base type's
225225
// declaration.
226226
TypeSubstitutionMap subMap;
227-
if (!BaseType->isAnyExistentialType())
227+
if (!BaseType->isExistentialType())
228228
subMap = BaseType->getContextSubstitutions(Ext);
229229
auto *M = DC->getParentModule();
230230

@@ -453,7 +453,9 @@ void PrintOptions::clearSynthesizedExtension() {
453453
}
454454

455455
TypeTransformContext::TypeTransformContext(Type T)
456-
: BaseType(T.getPointer()) {}
456+
: BaseType(T.getPointer()) {
457+
assert(T->mayHaveMembers());
458+
}
457459

458460
TypeTransformContext::TypeTransformContext(NominalTypeDecl *NTD)
459461
: BaseType(NTD->getDeclaredTypeInContext().getPointer()), Nominal(NTD) {}
@@ -984,8 +986,9 @@ class PrintAST : public ASTVisitor<PrintAST> {
984986
Type OldType = CurrentType;
985987
if (CurrentType && (Old != nullptr || Options.PrintAsMember)) {
986988
if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
987-
CurrentType = CurrentType->getTypeOfMember(
988-
Options.CurrentModule, NTD, nullptr);
989+
CurrentType = NTD->getDeclaredInterfaceType().subst(
990+
Options.CurrentModule,
991+
CurrentType->getContextSubstitutions(NTD->getDeclContext()));
989992
}
990993
}
991994

@@ -1259,7 +1262,7 @@ void PrintAST::printSingleDepthOfGenericSignature(
12591262
ModuleDecl *M = nullptr;
12601263

12611264
if (CurrentType) {
1262-
if (!CurrentType->isAnyExistentialType()) {
1265+
if (!CurrentType->isExistentialType()) {
12631266
auto *DC = Current->getInnermostDeclContext()->getInnermostTypeContext();
12641267
subMap = CurrentType->getContextSubstitutions(DC);
12651268
M = DC->getParentModule();

lib/AST/NameLookup.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,17 +1316,6 @@ bool DeclContext::lookupQualified(Type type,
13161316
}
13171317
};
13181318

1319-
// Look through lvalue and inout types.
1320-
type = type->getLValueOrInOutObjectType();
1321-
1322-
// Look through metatypes.
1323-
if (auto metaTy = type->getAs<AnyMetatypeType>())
1324-
type = metaTy->getInstanceType();
1325-
1326-
// Look through DynamicSelf.
1327-
if (auto dynamicSelf = type->getAs<DynamicSelfType>())
1328-
type = dynamicSelf->getSelfType();
1329-
13301319
// Look for module references.
13311320
if (auto moduleTy = type->getAs<ModuleType>()) {
13321321
Module *module = moduleTy->getModule();
@@ -1438,6 +1427,8 @@ bool DeclContext::lookupQualified(Type type,
14381427
}
14391428
}
14401429
}
1430+
} else {
1431+
llvm_unreachable("Bad type for qualified lookup");
14411432
}
14421433

14431434
// Allow filtering of the visible declarations based on various

lib/AST/Type.cpp

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3099,23 +3099,15 @@ Type TypeBase::getSuperclassForDecl(const ClassDecl *baseClass,
30993099
}
31003100

31013101
TypeSubstitutionMap TypeBase::getContextSubstitutions(const DeclContext *dc) {
3102+
assert(dc->isTypeContext());
3103+
Type baseTy(this);
31023104

3103-
// Ignore lvalues in the base type.
3104-
Type baseTy(getRValueType());
3105-
3106-
// Look through the metatype; it has no bearing on the result.
3107-
if (auto metaBase = baseTy->getAs<AnyMetatypeType>()) {
3108-
baseTy = metaBase->getInstanceType()->getRValueType();
3109-
}
3105+
assert(!baseTy->isLValueType() && !baseTy->is<AnyMetatypeType>());
31103106

31113107
// The resulting set of substitutions. Always use this to ensure we
31123108
// don't miss out on NRVO anywhere.
31133109
TypeSubstitutionMap substitutions;
31143110

3115-
// Look through non-type contexts.
3116-
while (!dc->isTypeContext())
3117-
dc = dc->getParent();
3118-
31193111
// If the member is part of a protocol or extension thereof, we need
31203112
// to substitute in the type of Self.
31213113
if (dc->getAsProtocolOrProtocolExtensionContext()) {
@@ -3127,19 +3119,24 @@ TypeSubstitutionMap TypeBase::getContextSubstitutions(const DeclContext *dc) {
31273119
return substitutions;
31283120
}
31293121

3122+
// If we found a member of a concrete type from a protocol extension,
3123+
// get the superclass out of the archetype.
3124+
if (auto *archetypeTy = baseTy->getAs<ArchetypeType>())
3125+
baseTy = archetypeTy->getSuperclass();
3126+
31303127
// Extract the lazy resolver.
31313128
LazyResolver *resolver = dc->getASTContext().getLazyResolver();
31323129

31333130
// Find the superclass type with the context matching that of the member.
31343131
//
31353132
// FIXME: Do this in the caller?
3136-
if (baseTy->getAnyNominal()) {
3137-
auto *ownerNominal = dc->getAsNominalTypeOrNominalTypeExtensionContext();
3138-
if (auto *ownerClass = dyn_cast<ClassDecl>(ownerNominal))
3139-
baseTy = baseTy->getSuperclassForDecl(ownerClass, resolver);
3133+
assert(baseTy->getAnyNominal());
31403134

3141-
assert(ownerNominal == baseTy->getAnyNominal());
3142-
}
3135+
auto *ownerNominal = dc->getAsNominalTypeOrNominalTypeExtensionContext();
3136+
if (auto *ownerClass = dyn_cast<ClassDecl>(ownerNominal))
3137+
baseTy = baseTy->getSuperclassForDecl(ownerClass, resolver);
3138+
3139+
assert(ownerNominal == baseTy->getAnyNominal());
31433140

31443141
// If the base type isn't specialized, there's nothing to substitute.
31453142
if (!baseTy->isSpecialized())
@@ -3177,8 +3174,7 @@ TypeSubstitutionMap TypeBase::getContextSubstitutions(const DeclContext *dc) {
31773174
continue;
31783175
}
31793176

3180-
// We're done.
3181-
break;
3177+
llvm_unreachable("Bad base type");
31823178
}
31833179

31843180
return substitutions;

lib/IDE/CodeCompletion.cpp

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,8 +1975,13 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
19751975
Type ContextTy = VD->getDeclContext()->getDeclaredInterfaceType();
19761976
if (ContextTy) {
19771977
// Look through lvalue types and metatypes
1978-
Type MaybeNominalType = (*ExprType)->getRValueType()
1979-
->getRValueInstanceType();
1978+
Type MaybeNominalType = (*ExprType)->getRValueType();
1979+
1980+
if (auto Metatype = MaybeNominalType->getAs<MetatypeType>())
1981+
MaybeNominalType = Metatype->getInstanceType();
1982+
1983+
if (auto SelfType = MaybeNominalType->getAs<DynamicSelfType>())
1984+
MaybeNominalType = SelfType->getSelfType();
19801985

19811986
// For optional protocol requirements and dynamic dispatch,
19821987
// strip off optionality from the base type, but only if
@@ -1989,6 +1994,12 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
19891994
if (MaybeNominalType->isAnyObject())
19901995
return T;
19911996

1997+
// FIXME: Sometimes ExprType is the type of the member here,
1998+
// and not the type of the base. That is inconsistent and
1999+
// should be cleaned up.
2000+
if (!MaybeNominalType->mayHaveMembers())
2001+
return T;
2002+
19922003
// For everything else, substitute in the base type.
19932004
auto Subs = MaybeNominalType->getMemberSubstitutions(VD);
19942005

@@ -2865,23 +2876,24 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
28652876

28662877
if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
28672878
addNominalTypeRef(NTD, Reason);
2868-
addConstructorCallsForType(NTD->getInterfaceType(), NTD->getName(),
2869-
Reason);
2879+
addConstructorCallsForType(NTD->getDeclaredInterfaceType(),
2880+
NTD->getName(), Reason);
28702881
return;
28712882
}
28722883

28732884
if (auto *TAD = dyn_cast<TypeAliasDecl>(D)) {
28742885
addTypeAliasRef(TAD, Reason);
28752886
auto type = TAD->mapTypeIntoContext(TAD->getUnderlyingTypeLoc().getType());
2876-
addConstructorCallsForType(type, TAD->getName(), Reason);
2887+
if (type->mayHaveMembers())
2888+
addConstructorCallsForType(type, TAD->getName(), Reason);
28772889
return;
28782890
}
28792891

28802892
if (auto *GP = dyn_cast<GenericTypeParamDecl>(D)) {
28812893
addGenericTypeParamRef(GP, Reason);
28822894
for (auto *protocol : GP->getConformingProtocols())
2883-
addConstructorCallsForType(protocol->getInterfaceType(), GP->getName(),
2884-
Reason);
2895+
addConstructorCallsForType(protocol->getDeclaredInterfaceType(),
2896+
GP->getName(), Reason);
28852897
return;
28862898
}
28872899

@@ -2934,23 +2946,24 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
29342946

29352947
if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
29362948
addNominalTypeRef(NTD, Reason);
2937-
addConstructorCallsForType(NTD->getInterfaceType(), NTD->getName(),
2938-
Reason);
2949+
addConstructorCallsForType(NTD->getDeclaredInterfaceType(),
2950+
NTD->getName(), Reason);
29392951
return;
29402952
}
29412953

29422954
if (auto *TAD = dyn_cast<TypeAliasDecl>(D)) {
29432955
addTypeAliasRef(TAD, Reason);
29442956
auto type = TAD->mapTypeIntoContext(TAD->getDeclaredInterfaceType());
2945-
addConstructorCallsForType(type, TAD->getName(), Reason);
2957+
if (type->mayHaveMembers())
2958+
addConstructorCallsForType(type, TAD->getName(), Reason);
29462959
return;
29472960
}
29482961

29492962
if (auto *GP = dyn_cast<GenericTypeParamDecl>(D)) {
29502963
addGenericTypeParamRef(GP, Reason);
29512964
for (auto *protocol : GP->getConformingProtocols())
2952-
addConstructorCallsForType(protocol->getInterfaceType(), GP->getName(),
2953-
Reason);
2965+
addConstructorCallsForType(protocol->getDeclaredInterfaceType(),
2966+
GP->getName(), Reason);
29542967
return;
29552968
}
29562969

lib/SILGen/SILGenMaterializeForSet.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,8 @@ struct MaterializeForSetEmitter {
385385
/// Given part of the witness's interface type, produce its
386386
/// substitution according to the witness substitutions.
387387
CanType getSubstWitnessInterfaceType(CanType type) {
388-
auto subs = SubstSelfType->getMemberSubstitutions(WitnessStorage);
388+
auto subs = SubstSelfType->getRValueInstanceType()
389+
->getMemberSubstitutions(WitnessStorage);
389390
return type.subst(SGM.SwiftModule, subs)->getCanonicalType();
390391
}
391392

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5852,7 +5852,7 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
58525852
auto toObjType = toType->getLValueOrInOutObjectType();
58535853

58545854
// Conversion to/from UnresolvedType (looking through @lvalue or inout).
5855-
if (fromObjType->is<UnresolvedType>() || toObjType->is<UnresolvedType>())
5855+
if (fromObjType->hasUnresolvedType() || toObjType->hasUnresolvedType())
58565856
return cs.cacheType(new (tc.Context)
58575857
UnresolvedTypeConversionExpr(expr, toType));
58585858

0 commit comments

Comments
 (0)