Skip to content

Commit be0e164

Browse files
authored
Merge pull request #18720 from DougGregor/kill-type-resolver-context-generic-signature
2 parents 6dfff66 + 50763fc commit be0e164

File tree

12 files changed

+82
-174
lines changed

12 files changed

+82
-174
lines changed

include/swift/AST/Decl.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3779,10 +3779,6 @@ struct SelfReferenceKind {
37793779
class ProtocolDecl final : public NominalTypeDecl {
37803780
SourceLoc ProtocolLoc;
37813781

3782-
/// The syntactic representation of the where clause in a protocol like
3783-
/// `protocol ... where ... { ... }`.
3784-
TrailingWhereClause *TrailingWhere;
3785-
37863782
llvm::DenseMap<ValueDecl *, Witness> DefaultWitnesses;
37873783

37883784
/// The generic signature representing exactly the new requirements introduced
@@ -3995,11 +3991,6 @@ class ProtocolDecl final : public NominalTypeDecl {
39953991
/// created yet.
39963992
void createGenericParamsIfMissing();
39973993

3998-
/// Retrieve the trailing where clause on this protocol, if it exists.
3999-
TrailingWhereClause *getTrailingWhereClause() const {
4000-
return TrailingWhere;
4001-
}
4002-
40033994
/// Retrieve the requirements that describe this protocol.
40043995
///
40053996
/// These are the requirements including any inherited protocols

lib/AST/Decl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3569,7 +3569,7 @@ ProtocolDecl::ProtocolDecl(DeclContext *DC, SourceLoc ProtocolLoc,
35693569
TrailingWhereClause *TrailingWhere)
35703570
: NominalTypeDecl(DeclKind::Protocol, DC, Name, NameLoc, Inherited,
35713571
nullptr),
3572-
ProtocolLoc(ProtocolLoc), TrailingWhere(TrailingWhere) {
3572+
ProtocolLoc(ProtocolLoc) {
35733573
Bits.ProtocolDecl.RequiresClassValid = false;
35743574
Bits.ProtocolDecl.RequiresClass = false;
35753575
Bits.ProtocolDecl.ExistentialConformsToSelfValid = false;
@@ -3579,6 +3579,7 @@ ProtocolDecl::ProtocolDecl(DeclContext *DC, SourceLoc ProtocolLoc,
35793579
Bits.ProtocolDecl.NumRequirementsInSignature = 0;
35803580
Bits.ProtocolDecl.HasMissingRequirements = false;
35813581
Bits.ProtocolDecl.KnownProtocol = 0;
3582+
setTrailingWhereClause(TrailingWhere);
35823583
}
35833584

35843585
llvm::TinyPtrVector<ProtocolDecl *>

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7491,6 +7491,17 @@ GenericSignature *GenericSignatureBuilder::computeGenericSignature(
74917491
return sig;
74927492
}
74937493

7494+
/// Add all of the generic parameters from the given parameter list (and it's
7495+
/// outer generic parameter lists) to the given generic signature builder.
7496+
static void addAllGenericParams(GenericSignatureBuilder &builder,
7497+
GenericParamList *genericParams) {
7498+
if (!genericParams) return;
7499+
7500+
addAllGenericParams(builder, genericParams->getOuterParameters());
7501+
for (auto gp : *genericParams)
7502+
builder.addGenericParameter(gp);
7503+
}
7504+
74947505
GenericSignature *GenericSignatureBuilder::computeRequirementSignature(
74957506
ProtocolDecl *proto) {
74967507
GenericSignatureBuilder builder(proto->getASTContext());
@@ -7501,12 +7512,12 @@ GenericSignature *GenericSignatureBuilder::computeRequirementSignature(
75017512
lazyResolver->resolveDeclSignature(proto);
75027513
}
75037514

7504-
// Add the 'self' parameter.
7505-
auto selfType =
7506-
proto->getSelfInterfaceType()->castTo<GenericTypeParamType>();
7507-
builder.addGenericParameter(selfType);
7515+
// Add all of the generic parameters.
7516+
addAllGenericParams(builder, proto->getGenericParams());
75087517

75097518
// Add the conformance of 'self' to the protocol.
7519+
auto selfType =
7520+
proto->getSelfInterfaceType()->castTo<GenericTypeParamType>();
75107521
auto requirement =
75117522
Requirement(RequirementKind::Conformance, selfType,
75127523
proto->getDeclaredInterfaceType());

lib/AST/NameLookup.cpp

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,41 @@ SelfBoundsFromWhereClauseRequest::evaluate(Evaluator &evaluator,
579579
return result;
580580
}
581581

582+
namespace {
583+
584+
/// Determine whether unqualified lookup should look at the members of the
585+
/// given nominal type or extension, vs. only looking at type parameters.
586+
template<typename D>
587+
bool shouldLookupMembers(D *decl, SourceLoc loc) {
588+
// Only look at members of this type (or its inherited types) when
589+
// inside the body or a protocol's top-level 'where' clause. (Why the
590+
// 'where' clause? Because that's where you put constraints on
591+
// inherited associated types.)
592+
593+
// When we have no source-location information, we have to perform member
594+
// lookup.
595+
if (loc.isInvalid() || decl->getBraces().isInvalid())
596+
return true;
597+
598+
// Within the braces, always look for members.
599+
auto &ctx = decl->getASTContext();
600+
if (ctx.SourceMgr.rangeContainsTokenLoc(decl->getBraces(), loc))
601+
return true;
602+
603+
// Within 'where' clause, we can also look for members.
604+
if (auto *whereClause = decl->getTrailingWhereClause()) {
605+
SourceRange whereClauseRange = whereClause->getSourceRange();
606+
if (whereClauseRange.isValid() &&
607+
ctx.SourceMgr.rangeContainsTokenLoc(whereClauseRange, loc)) {
608+
return true;
609+
}
610+
}
611+
612+
// Don't look at the members.
613+
return false;
614+
}
615+
} // end anonymous namespace
616+
582617
UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC,
583618
LazyResolver *TypeResolver, SourceLoc Loc,
584619
Options options)
@@ -922,14 +957,16 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC,
922957
continue;
923958
}
924959

925-
populateLookupDeclsFromContext(ED);
960+
if (shouldLookupMembers(ED, Loc))
961+
populateLookupDeclsFromContext(ED);
926962

927963
BaseDC = ED;
928964
MetaBaseDC = ED;
929965
if (!isCascadingUse.hasValue())
930966
isCascadingUse = ED->isCascadingContextForLookup(false);
931967
} else if (auto *ND = dyn_cast<NominalTypeDecl>(DC)) {
932-
populateLookupDeclsFromContext(ND);
968+
if (shouldLookupMembers(ND, Loc))
969+
populateLookupDeclsFromContext(ND);
933970
BaseDC = DC;
934971
MetaBaseDC = DC;
935972
if (!isCascadingUse.hasValue())

lib/AST/Type.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3192,7 +3192,17 @@ Type TypeBase::getSuperclassForDecl(const ClassDecl *baseClass,
31923192

31933193
t = t->getSuperclass(useArchetypes);
31943194
}
3195-
llvm_unreachable("no inheritance relationship between given classes");
3195+
3196+
#ifndef NDEBUG
3197+
auto *currentClass = getConcreteTypeForSuperclassTraversing(this)
3198+
->getClassOrBoundGenericClass();
3199+
while (currentClass && currentClass != baseClass)
3200+
currentClass = currentClass->getSuperclassDecl();
3201+
assert(currentClass == baseClass &&
3202+
"no inheritance relationship between given classes");
3203+
#endif
3204+
3205+
return ErrorType::get(this);
31963206
}
31973207

31983208
TypeSubstitutionMap

lib/Sema/TypeCheckDecl.cpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -244,29 +244,10 @@ void TypeChecker::checkInheritanceClause(Decl *decl,
244244
DeclContext *DC;
245245
if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
246246
DC = nominal;
247-
options = TypeResolutionOptions(TypeResolverContext::GenericSignature);
248247
options |= TypeResolutionFlags::AllowUnavailableProtocol;
249248
} else if (auto ext = dyn_cast<ExtensionDecl>(decl)) {
250249
DC = ext;
251-
options = TypeResolutionOptions(TypeResolverContext::GenericSignature);
252250
options |= TypeResolutionFlags::AllowUnavailableProtocol;
253-
} else if (isa<GenericTypeParamDecl>(decl)) {
254-
// For generic parameters, we want name lookup to look at just the
255-
// signature of the enclosing entity.
256-
DC = decl->getDeclContext();
257-
if (auto nominal = dyn_cast<NominalTypeDecl>(DC)) {
258-
DC = nominal;
259-
options = TypeResolutionOptions(TypeResolverContext::GenericSignature);
260-
} else if (auto ext = dyn_cast<ExtensionDecl>(DC)) {
261-
DC = ext;
262-
options = TypeResolutionOptions(TypeResolverContext::GenericSignature);
263-
} else if (auto func = dyn_cast<AbstractFunctionDecl>(DC)) {
264-
DC = func;
265-
options = TypeResolutionOptions(TypeResolverContext::GenericSignature);
266-
} else if (!DC->isModuleScopeContext()) {
267-
// Skip the generic parameter's context entirely.
268-
DC = DC->getParent();
269-
}
270251
} else {
271252
DC = decl->getDeclContext();
272253
}

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -242,18 +242,9 @@ void TypeChecker::checkGenericParamList(GenericSignatureBuilder *builder,
242242
assert(genericParams->size() > 0 &&
243243
"Parsed an empty generic parameter list?");
244244

245-
// Determine where and how to perform name lookup for the generic
246-
// parameter lists and where clause.
245+
// Determine where and how to perform name lookup.
247246
TypeResolutionOptions options = None;
248247
DeclContext *lookupDC = genericParams->begin()[0]->getDeclContext();
249-
if (!lookupDC->isModuleScopeContext()) {
250-
assert((isa<GenericTypeDecl>(lookupDC) ||
251-
isa<ExtensionDecl>(lookupDC) ||
252-
isa<AbstractFunctionDecl>(lookupDC) ||
253-
isa<SubscriptDecl>(lookupDC)) &&
254-
"not a proper generic parameter context?");
255-
options = TypeResolutionOptions(TypeResolverContext::GenericSignature);
256-
}
257248

258249
// First, add the generic parameters to the generic signature builder.
259250
// Do this before checking the inheritance clause, since it may

lib/Sema/TypeCheckRequestFunctions.cpp

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,33 +30,13 @@ Type InheritedTypeRequest::evaluate(
3030
if (auto typeDecl = decl.dyn_cast<TypeDecl *>()) {
3131
if (auto nominal = dyn_cast<NominalTypeDecl>(typeDecl)) {
3232
dc = nominal;
33-
options = TypeResolutionOptions(TypeResolverContext::GenericSignature);
3433
options |= TypeResolutionFlags::AllowUnavailableProtocol;
3534
} else {
3635
dc = typeDecl->getDeclContext();
37-
38-
if (isa<GenericTypeParamDecl>(typeDecl)) {
39-
// For generic parameters, we want name lookup to look at just the
40-
// signature of the enclosing entity.
41-
if (auto nominal = dyn_cast<NominalTypeDecl>(dc)) {
42-
dc = nominal;
43-
options = TypeResolutionOptions(TypeResolverContext::GenericSignature);
44-
} else if (auto ext = dyn_cast<ExtensionDecl>(dc)) {
45-
dc = ext;
46-
options = TypeResolutionOptions(TypeResolverContext::GenericSignature);
47-
} else if (auto func = dyn_cast<AbstractFunctionDecl>(dc)) {
48-
dc = func;
49-
options = TypeResolutionOptions(TypeResolverContext::GenericSignature);
50-
} else if (!dc->isModuleScopeContext()) {
51-
// Skip the generic parameter's context entirely.
52-
dc = dc->getParent();
53-
}
54-
}
5536
}
5637
} else {
5738
auto ext = decl.get<ExtensionDecl *>();
5839
dc = ext;
59-
options = TypeResolutionOptions(TypeResolverContext::GenericSignature);
6040
options |= TypeResolutionFlags::AllowUnavailableProtocol;
6141
}
6242

lib/Sema/TypeCheckType.cpp

Lines changed: 11 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,12 @@ Type TypeChecker::resolveTypeInContext(
297297
//
298298
// Get the superclass of the 'Self' type parameter.
299299
auto *sig = foundDC->getGenericSignatureOfContext();
300+
if (!sig)
301+
return ErrorType::get(Context);
300302
auto superclassType = sig->getSuperclassBound(selfType);
301-
assert(superclassType);
303+
if (!superclassType)
304+
return ErrorType::get(Context);
305+
302306
selfType = superclassType;
303307
}
304308
}
@@ -763,15 +767,12 @@ static Type diagnoseUnknownType(TypeChecker &tc, DeclContext *dc,
763767

764768
// Try ignoring access control.
765769
DeclContext *lookupDC = dc;
766-
if (options.getBaseContext() == TypeResolverContext::GenericSignature)
767-
lookupDC = dc->getParentForLookup();
768-
769770
NameLookupOptions relookupOptions = lookupOptions;
770771
relookupOptions |= NameLookupFlags::KnownPrivate;
771772
relookupOptions |= NameLookupFlags::IgnoreAccessControl;
772773
auto inaccessibleResults =
773-
tc.lookupUnqualifiedType(lookupDC, comp->getIdentifier(), comp->getIdLoc(),
774-
relookupOptions);
774+
tc.lookupUnqualifiedType(lookupDC, comp->getIdentifier(),
775+
comp->getIdLoc(), relookupOptions);
775776
if (!inaccessibleResults.empty()) {
776777
// FIXME: What if the unviable candidates have different levels of access?
777778
auto first = cast<TypeDecl>(inaccessibleResults.front().getValueDecl());
@@ -890,84 +891,6 @@ static Type diagnoseUnknownType(TypeChecker &tc, DeclContext *dc,
890891
return ErrorType::get(tc.Context);
891892
}
892893

893-
static Type
894-
resolveTopLevelIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
895-
ComponentIdentTypeRepr *comp,
896-
TypeResolutionOptions options,
897-
GenericTypeResolver *resolver);
898-
899-
static Type
900-
resolveGenericSignatureComponent(TypeChecker &TC, DeclContext *DC,
901-
ComponentIdentTypeRepr *comp,
902-
TypeResolutionOptions options,
903-
GenericTypeResolver *resolver) {
904-
if (!DC->isInnermostContextGeneric())
905-
return Type();
906-
907-
auto *genericParams = DC->getGenericParamsOfContext();
908-
909-
if (!isa<ExtensionDecl>(DC)) {
910-
auto matchingParam =
911-
std::find_if(genericParams->begin(), genericParams->end(),
912-
[comp](const GenericTypeParamDecl *param) {
913-
return param->getFullName().matchesRef(comp->getIdentifier());
914-
});
915-
916-
if (matchingParam == genericParams->end())
917-
return Type();
918-
919-
comp->setValue(*matchingParam, nullptr);
920-
return resolveTopLevelIdentTypeComponent(TC, DC, comp, options, resolver);
921-
}
922-
923-
// If we are inside an extension of a nested type, we have to visit
924-
// all outer parameter lists. Otherwise, we will visit them when
925-
// name lookup goes ahead and checks the outer DeclContext.
926-
for (auto *outerParams = genericParams;
927-
outerParams != nullptr;
928-
outerParams = outerParams->getOuterParameters()) {
929-
auto matchingParam =
930-
std::find_if(outerParams->begin(), outerParams->end(),
931-
[comp](const GenericTypeParamDecl *param) {
932-
return param->getFullName().matchesRef(comp->getIdentifier());
933-
});
934-
935-
if (matchingParam != outerParams->end()) {
936-
comp->setValue(*matchingParam, nullptr);
937-
return resolveTopLevelIdentTypeComponent(TC, DC, comp, options, resolver);
938-
}
939-
}
940-
941-
// If the lookup occurs from within a trailing 'where' clause of
942-
// a constrained extension, also look for associated types and typealiases
943-
// in the protocol.
944-
if (genericParams->hasTrailingWhereClause() &&
945-
comp->getIdLoc().isValid() &&
946-
TC.Context.SourceMgr.rangeContainsTokenLoc(
947-
genericParams->getTrailingWhereClauseSourceRange(),
948-
comp->getIdLoc())) {
949-
auto nominal = DC->getAsNominalTypeOrNominalTypeExtensionContext();
950-
SmallVector<ValueDecl *, 4> decls;
951-
if (DC->lookupQualified(nominal,
952-
comp->getIdentifier(),
953-
NL_OnlyTypes|NL_QualifiedDefault|NL_ProtocolMembers,
954-
decls)) {
955-
for (const auto decl : decls) {
956-
// FIXME: Better ambiguity handling.
957-
auto typeDecl = cast<TypeDecl>(decl);
958-
959-
if (!isa<ProtocolDecl>(typeDecl->getDeclContext())) continue;
960-
961-
comp->setValue(typeDecl, DC);
962-
return resolveTopLevelIdentTypeComponent(TC, DC, comp, options,
963-
resolver);
964-
}
965-
}
966-
}
967-
968-
return Type();
969-
}
970-
971894
/// Resolve the given identifier type representation as an unqualified type,
972895
/// returning the type it references.
973896
///
@@ -1010,20 +933,6 @@ resolveTopLevelIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
1010933
return DynamicSelfType::get(selfType, TC.Context);
1011934
}
1012935

1013-
// For lookups within the generic signature, look at the generic
1014-
// parameters (only), then move up to the enclosing context.
1015-
if (options.getBaseContext() == TypeResolverContext::GenericSignature) {
1016-
Type type = resolveGenericSignatureComponent(
1017-
TC, DC, comp, options, resolver);
1018-
if (type)
1019-
return type;
1020-
1021-
if (!DC->isCascadingContextForLookup(/*excludeFunctions*/false))
1022-
options |= TypeResolutionFlags::KnownNonCascadingDependency;
1023-
1024-
lookupDC = DC->getParentForLookup();
1025-
}
1026-
1027936
auto id = comp->getIdentifier();
1028937

1029938
NameLookupOptions lookupOptions = defaultUnqualifiedLookupOptions;
@@ -2692,7 +2601,6 @@ Type TypeResolver::resolveImplicitlyUnwrappedOptionalType(
26922601
case TypeResolverContext::EnumPatternPayload:
26932602
case TypeResolverContext::TypeAliasDecl:
26942603
case TypeResolverContext::GenericRequirement:
2695-
case TypeResolverContext::GenericSignature:
26962604
case TypeResolverContext::ImmediateOptionalTypeArgument:
26972605
case TypeResolverContext::InExpression:
26982606
case TypeResolverContext::EditorPlaceholderExpr:
@@ -2945,7 +2853,10 @@ Type TypeChecker::substMemberTypeWithBase(ModuleDecl *module,
29452853
nominalDecl, baseTy,
29462854
nominalDecl->getASTContext());
29472855
}
2948-
2856+
2857+
if (baseTy && baseTy->is<ErrorType>())
2858+
return baseTy;
2859+
29492860
return NominalType::get(
29502861
nominalDecl, baseTy,
29512862
nominalDecl->getASTContext());

0 commit comments

Comments
 (0)