Skip to content

Commit 73deb7e

Browse files
committed
Sema: Introduce a simpler form of checkGenericArguments()
1 parent ee33f12 commit 73deb7e

File tree

6 files changed

+55
-56
lines changed

6 files changed

+55
-56
lines changed

lib/Sema/CSStep.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -538,8 +538,8 @@ StepResult DisjunctionStep::resume(bool prevFailed) {
538538
}
539539

540540
bool IsDeclRefinementOfRequest::evaluate(Evaluator &evaluator,
541-
ValueDecl *declA,
542-
ValueDecl *declB) const {
541+
ValueDecl *declA,
542+
ValueDecl *declB) const {
543543
auto *typeA = declA->getInterfaceType()->getAs<GenericFunctionType>();
544544
auto *typeB = declB->getInterfaceType()->getAs<GenericFunctionType>();
545545

@@ -578,10 +578,7 @@ bool IsDeclRefinementOfRequest::evaluate(Evaluator &evaluator,
578578
return false;
579579

580580
auto result = TypeChecker::checkGenericArguments(
581-
declA->getDeclContext(), SourceLoc(), SourceLoc(), typeB,
582-
genericSignatureB->getGenericParams(),
583-
genericSignatureB->getRequirements(),
584-
QueryTypeSubstitutionMap{ substMap });
581+
genericSignatureB, QueryTypeSubstitutionMap{ substMap });
585582

586583
if (result != RequirementCheckResult::Success)
587584
return false;

lib/Sema/CodeSynthesis.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -745,9 +745,7 @@ createDesignatedInitOverride(ClassDecl *classDecl,
745745
// satisfied by the derived class. In this case, we don't want to inherit
746746
// this initializer; there's no way to call it on the derived class.
747747
auto checkResult = TypeChecker::checkGenericArguments(
748-
superclassCtor, SourceLoc(), SourceLoc(), Type(),
749-
superclassCtorSig->getGenericParams(),
750-
superclassCtorSig->getRequirements(),
748+
superclassCtorSig,
751749
[&](Type type) -> Type {
752750
auto substType = type.subst(overrideInfo.OverrideSubMap);
753751
return GenericEnvironment::mapTypeIntoContext(

lib/Sema/IDETypeCheckingRequests.cpp

Lines changed: 9 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -116,36 +116,6 @@ class ContainsSpecializableArchetype : public TypeWalker {
116116
}
117117
};
118118

119-
static bool areGenericRequirementsSatisfied(GenericSignature sig,
120-
SubstitutionMap substMap,
121-
bool isExtension) {
122-
SmallVector<Requirement, 4> worklist;
123-
124-
for (auto req : sig->getRequirements()) {
125-
if (auto resolved = req.subst(
126-
QuerySubstitutionMap{substMap},
127-
LookUpConformanceInSignature(sig.getPointer()))) {
128-
worklist.push_back(*resolved);
129-
} else if (isExtension) {
130-
return false;
131-
}
132-
// Unresolved requirements are requirements of the function itself. This
133-
// does not prevent it from being applied. E.g. func foo<T: Sequence>(x: T).
134-
}
135-
136-
while (!worklist.empty()) {
137-
auto req = worklist.pop_back_val();
138-
ArrayRef<Requirement> conditionalRequirements;
139-
if (req.isSatisfied(conditionalRequirements) != Requirement::Satisfied)
140-
return false;
141-
142-
worklist.append(conditionalRequirements.begin(),
143-
conditionalRequirements.end());
144-
}
145-
146-
return true;
147-
}
148-
149119
static bool isExtensionAppliedInternal(const DeclContext *DC, Type BaseTy,
150120
const ExtensionDecl *ED) {
151121
// We can't do anything if the base type has unbound generic parameters.
@@ -163,8 +133,9 @@ static bool isExtensionAppliedInternal(const DeclContext *DC, Type BaseTy,
163133
GenericSignature genericSig = ED->getGenericSignature();
164134
SubstitutionMap substMap = BaseTy->getContextSubstitutionMap(
165135
DC->getParentModule(), ED->getExtendedNominal());
166-
return areGenericRequirementsSatisfied(genericSig, substMap,
167-
/*isExtension=*/true);
136+
return TypeChecker::checkGenericArguments(
137+
genericSig, QuerySubstitutionMap{substMap})
138+
== RequirementCheckResult::Success;
168139
}
169140

170141
static bool isMemberDeclAppliedInternal(const DeclContext *DC, Type BaseTy,
@@ -187,8 +158,12 @@ static bool isMemberDeclAppliedInternal(const DeclContext *DC, Type BaseTy,
187158

188159
SubstitutionMap substMap = BaseTy->getContextSubstitutionMap(
189160
DC->getParentModule(), VD->getDeclContext());
190-
return areGenericRequirementsSatisfied(genericSig, substMap,
191-
/*isExtension=*/false);
161+
162+
// Note: we treat substitution failure as success, to avoid tripping
163+
// up over generic parameters introduced by the declaration itself.
164+
return TypeChecker::checkGenericArguments(
165+
genericSig, QuerySubstitutionMap{substMap})
166+
!= RequirementCheckResult::Failure;
192167
}
193168

194169
bool

lib/Sema/TypeCheckAttr.cpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2798,22 +2798,16 @@ TypeEraserHasViableInitRequest::evaluate(Evaluator &evaluator,
27982798
typeEraser->getContextSubstitutionMap(nominalTypeDecl->getParentModule(),
27992799
nominalTypeDecl);
28002800
QuerySubstitutionMap getSubstitution{baseMap};
2801-
auto subMap = SubstitutionMap::get(
2802-
genericSignature,
2803-
[&](SubstitutableType *type) -> Type {
2804-
if (type->isEqual(genericParamType))
2805-
return protocol->getSelfTypeInContext();
2806-
2807-
return getSubstitution(type);
2808-
},
2809-
LookUpConformanceInModule(dc->getParentModule()));
28102801

28112802
// Use invalid 'SourceLoc's to suppress diagnostics.
28122803
auto result = TypeChecker::checkGenericArguments(
2813-
dc, SourceLoc(), SourceLoc(), typeEraser,
2814-
genericSignature->getGenericParams(),
2815-
genericSignature->getRequirements(),
2816-
QuerySubstitutionMap{subMap});
2804+
genericSignature,
2805+
[&](SubstitutableType *type) -> Type {
2806+
if (type->isEqual(genericParamType))
2807+
return protocol->getSelfTypeInContext();
2808+
2809+
return getSubstitution(type);
2810+
});
28172811

28182812
if (result != RequirementCheckResult::Success) {
28192813
unviable.push_back(

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,37 @@ RequirementCheckResult TypeChecker::checkGenericArguments(
870870
return RequirementCheckResult::SubstitutionFailure;
871871
}
872872

873+
RequirementCheckResult
874+
TypeChecker::checkGenericArguments(GenericSignature sig,
875+
TypeSubstitutionFn substitutions) {
876+
SmallVector<Requirement, 4> worklist;
877+
bool valid = true;
878+
879+
for (auto req : sig->getRequirements()) {
880+
if (auto resolved = req.subst(
881+
substitutions,
882+
LookUpConformanceInSignature(sig.getPointer()))) {
883+
worklist.push_back(*resolved);
884+
} else {
885+
valid = false;
886+
}
887+
}
888+
889+
while (!worklist.empty()) {
890+
auto req = worklist.pop_back_val();
891+
ArrayRef<Requirement> conditionalRequirements;
892+
if (!req.isSatisfied(conditionalRequirements))
893+
return RequirementCheckResult::Failure;
894+
895+
worklist.append(conditionalRequirements.begin(),
896+
conditionalRequirements.end());
897+
}
898+
899+
if (valid)
900+
return RequirementCheckResult::Success;
901+
return RequirementCheckResult::SubstitutionFailure;
902+
}
903+
873904
Requirement
874905
RequirementRequest::evaluate(Evaluator &evaluator,
875906
WhereClauseOwner owner,

lib/Sema/TypeChecker.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,10 @@ RequirementCheckResult checkGenericArguments(
498498
ArrayRef<Requirement> requirements, TypeSubstitutionFn substitutions,
499499
SubstOptions options = None);
500500

501+
/// A lower-level version of the above without diagnostic emission.
502+
RequirementCheckResult checkGenericArguments(
503+
GenericSignature sig, TypeSubstitutionFn substitutions);
504+
501505
bool checkContextualRequirements(GenericTypeDecl *decl,
502506
Type parentTy,
503507
SourceLoc loc,

0 commit comments

Comments
 (0)