Skip to content

Commit 131d3f4

Browse files
committed
Sema: Pass down a ModuleDecl instead of a DeclContext to conformsToProtocol()
... and a bunch of follow-up simplifications pushing ModuleDecls further up, since I couldn't resist the yak shave.
1 parent b556cb5 commit 131d3f4

35 files changed

+294
-272
lines changed

include/swift/AST/ActorIsolation.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class raw_ostream;
2525

2626
namespace swift {
2727
class DeclContext;
28+
class ModuleDecl;
2829
class NominalTypeDecl;
2930
class SubstitutionMap;
3031

@@ -33,7 +34,7 @@ class SubstitutionMap;
3334
bool areTypesEqual(Type type1, Type type2);
3435

3536
/// Determine whether the given type is suitable as a concurrent value type.
36-
bool isSendableType(const DeclContext *dc, Type type);
37+
bool isSendableType(ModuleDecl *module, Type type);
3738

3839
/// Describes the actor isolation of a given declaration, which determines
3940
/// the actors with which it can interact.

include/swift/Sema/ConstraintSystem.h

+1-9
Original file line numberDiff line numberDiff line change
@@ -5269,17 +5269,9 @@ bool hasAppliedSelf(ConstraintSystem &cs, const OverloadChoice &choice);
52695269
bool hasAppliedSelf(const OverloadChoice &choice,
52705270
llvm::function_ref<Type(Type)> getFixedType);
52715271

5272-
/// Check whether type conforms to a given known protocol.
5273-
bool conformsToKnownProtocol(DeclContext *dc, Type type,
5274-
KnownProtocolKind protocol);
5275-
5276-
/// Check whether given type conforms to `RawPepresentable` protocol
5272+
/// Check whether given type conforms to `RawRepresentable` protocol
52775273
/// and return witness type.
52785274
Type isRawRepresentable(ConstraintSystem &cs, Type type);
5279-
/// Check whether given type conforms to a specific known kind
5280-
/// `RawPepresentable` protocol and return witness type.
5281-
Type isRawRepresentable(ConstraintSystem &cs, Type type,
5282-
KnownProtocolKind rawRepresentableProtocol);
52835275

52845276
/// Compute the type that shall stand in for dynamic 'Self' in a member
52855277
/// reference with a base of the given object type.

lib/IDE/CodeCompletion.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -2539,20 +2539,21 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
25392539

25402540
// If the reference is 'async', all types must be 'Sendable'.
25412541
if (implicitlyAsync && T) {
2542+
auto *M = CurrDeclContext->getParentModule();
25422543
if (isa<VarDecl>(VD)) {
2543-
if (!isSendableType(CurrDeclContext, T)) {
2544+
if (!isSendableType(M, T)) {
25442545
NotRecommended = NotRecommendedReason::CrossActorReference;
25452546
}
25462547
} else {
25472548
assert(isa<FuncDecl>(VD) || isa<SubscriptDecl>(VD));
25482549
// Check if the result and the param types are all 'Sendable'.
25492550
auto *AFT = T->castTo<AnyFunctionType>();
2550-
if (!isSendableType(CurrDeclContext, AFT->getResult())) {
2551+
if (!isSendableType(M, AFT->getResult())) {
25512552
NotRecommended = NotRecommendedReason::CrossActorReference;
25522553
} else {
25532554
for (auto &param : AFT->getParams()) {
25542555
Type paramType = param.getPlainType();
2555-
if (!isSendableType(CurrDeclContext, paramType)) {
2556+
if (!isSendableType(M, paramType)) {
25562557
NotRecommended = NotRecommendedReason::CrossActorReference;
25572558
break;
25582559
}

lib/Sema/CSApply.cpp

+26-19
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ Solution::computeSubstitutions(GenericSignature sig,
101101

102102
// FIXME: Retrieve the conformance from the solution itself.
103103
return TypeChecker::conformsToProtocol(replacement, protoType,
104-
getConstraintSystem().DC);
104+
getConstraintSystem().DC->getParentModule());
105105
};
106106

107107
return SubstitutionMap::get(sig,
@@ -620,7 +620,7 @@ namespace {
620620
// the protocol requirement with Self == the concrete type, and SILGen
621621
// (or later) can devirtualize as appropriate.
622622
auto conformance =
623-
TypeChecker::conformsToProtocol(baseTy, proto, cs.DC);
623+
TypeChecker::conformsToProtocol(baseTy, proto, cs.DC->getParentModule());
624624
if (conformance.isConcrete()) {
625625
if (auto witness = conformance.getConcrete()->getWitnessDecl(decl)) {
626626
bool isMemberOperator = witness->getDeclContext()->isTypeContext();
@@ -2418,7 +2418,7 @@ namespace {
24182418
auto bridgedToObjectiveCConformance
24192419
= TypeChecker::conformsToProtocol(valueType,
24202420
bridgedProto,
2421-
cs.DC);
2421+
cs.DC->getParentModule());
24222422

24232423
FuncDecl *fn = nullptr;
24242424

@@ -2678,7 +2678,7 @@ namespace {
26782678
ProtocolDecl *protocol = TypeChecker::getProtocol(
26792679
ctx, expr->getLoc(), KnownProtocolKind::ExpressibleByStringLiteral);
26802680

2681-
if (!TypeChecker::conformsToProtocol(type, protocol, cs.DC)) {
2681+
if (!TypeChecker::conformsToProtocol(type, protocol, cs.DC->getParentModule())) {
26822682
// If the type does not conform to ExpressibleByStringLiteral, it should
26832683
// be ExpressibleByExtendedGraphemeClusterLiteral.
26842684
protocol = TypeChecker::getProtocol(
@@ -2687,7 +2687,7 @@ namespace {
26872687
isStringLiteral = false;
26882688
isGraphemeClusterLiteral = true;
26892689
}
2690-
if (!TypeChecker::conformsToProtocol(type, protocol, cs.DC)) {
2690+
if (!TypeChecker::conformsToProtocol(type, protocol, cs.DC->getParentModule())) {
26912691
// ... or it should be ExpressibleByUnicodeScalarLiteral.
26922692
protocol = TypeChecker::getProtocol(
26932693
cs.getASTContext(), expr->getLoc(),
@@ -2802,7 +2802,7 @@ namespace {
28022802
assert(proto && "Missing string interpolation protocol?");
28032803

28042804
auto conformance =
2805-
TypeChecker::conformsToProtocol(type, proto, cs.DC);
2805+
TypeChecker::conformsToProtocol(type, proto, cs.DC->getParentModule());
28062806
assert(conformance && "string interpolation type conforms to protocol");
28072807

28082808
DeclName constrName(ctx, DeclBaseName::createConstructor(), argLabels);
@@ -2908,7 +2908,8 @@ namespace {
29082908
auto proto = TypeChecker::getLiteralProtocol(ctx, expr);
29092909
assert(proto && "Missing object literal protocol?");
29102910
auto conformance =
2911-
TypeChecker::conformsToProtocol(conformingType, proto, cs.DC);
2911+
TypeChecker::conformsToProtocol(conformingType, proto,
2912+
cs.DC->getParentModule());
29122913
assert(conformance && "object literal type conforms to protocol");
29132914

29142915
auto constrName = TypeChecker::getObjectLiteralConstructorName(ctx, expr);
@@ -3511,7 +3512,8 @@ namespace {
35113512
assert(arrayProto && "type-checked array literal w/o protocol?!");
35123513

35133514
auto conformance =
3514-
TypeChecker::conformsToProtocol(arrayTy, arrayProto, cs.DC);
3515+
TypeChecker::conformsToProtocol(arrayTy, arrayProto,
3516+
cs.DC->getParentModule());
35153517
assert(conformance && "Type does not conform to protocol?");
35163518

35173519
DeclName name(ctx, DeclBaseName::createConstructor(),
@@ -3555,7 +3557,8 @@ namespace {
35553557
KnownProtocolKind::ExpressibleByDictionaryLiteral);
35563558

35573559
auto conformance =
3558-
TypeChecker::conformsToProtocol(dictionaryTy, dictionaryProto, cs.DC);
3560+
TypeChecker::conformsToProtocol(dictionaryTy, dictionaryProto,
3561+
cs.DC->getParentModule());
35593562
if (conformance.isInvalid())
35603563
return nullptr;
35613564

@@ -4298,7 +4301,7 @@ namespace {
42984301
// Special handle for literals conditional checked cast when they can
42994302
// be statically coerced to the cast type.
43004303
if (protocol && TypeChecker::conformsToProtocol(
4301-
toType, protocol, cs.DC)) {
4304+
toType, protocol, cs.DC->getParentModule())) {
43024305
ctx.Diags
43034306
.diagnose(expr->getLoc(),
43044307
diag::literal_conditional_downcast_to_coercion,
@@ -5193,7 +5196,8 @@ namespace {
51935196
// verified by the solver, we just need to get it again
51945197
// with all of the generic parameters resolved.
51955198
auto hashableConformance =
5196-
TypeChecker::conformsToProtocol(indexType, hashable, cs.DC);
5199+
TypeChecker::conformsToProtocol(indexType, hashable,
5200+
cs.DC->getParentModule());
51975201
assert(hashableConformance);
51985202

51995203
conformances.push_back(hashableConformance);
@@ -5503,13 +5507,13 @@ Expr *ExprRewriter::coerceSuperclass(Expr *expr, Type toType) {
55035507
/// conformances.
55045508
static ArrayRef<ProtocolConformanceRef>
55055509
collectExistentialConformances(Type fromType, Type toType,
5506-
DeclContext *DC) {
5510+
ModuleDecl *module) {
55075511
auto layout = toType->getExistentialLayout();
55085512

55095513
SmallVector<ProtocolConformanceRef, 4> conformances;
55105514
for (auto proto : layout.getProtocols()) {
55115515
conformances.push_back(TypeChecker::containsProtocol(
5512-
fromType, proto->getDecl(), DC));
5516+
fromType, proto->getDecl(), module));
55135517
}
55145518

55155519
return toType->getASTContext().AllocateCopy(conformances);
@@ -5532,7 +5536,8 @@ Expr *ExprRewriter::coerceExistential(Expr *expr, Type toType) {
55325536
ASTContext &ctx = cs.getASTContext();
55335537

55345538
auto conformances =
5535-
collectExistentialConformances(fromInstanceType, toInstanceType, cs.DC);
5539+
collectExistentialConformances(fromInstanceType, toInstanceType,
5540+
cs.DC->getParentModule());
55365541

55375542
// For existential-to-existential coercions, open the source existential.
55385543
if (fromType->isAnyExistentialType()) {
@@ -6689,7 +6694,7 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
66896694
auto hashable = ctx.getProtocol(KnownProtocolKind::Hashable);
66906695
auto conformance =
66916696
TypeChecker::conformsToProtocol(
6692-
cs.getType(expr), hashable, cs.DC);
6697+
cs.getType(expr), hashable, cs.DC->getParentModule());
66936698
assert(conformance && "must conform to Hashable");
66946699

66956700
return cs.cacheType(
@@ -7359,7 +7364,7 @@ Expr *ExprRewriter::convertLiteralInPlace(
73597364
// initialize via the builtin protocol.
73607365
if (builtinProtocol) {
73617366
auto builtinConformance = TypeChecker::conformsToProtocol(
7362-
type, builtinProtocol, cs.DC);
7367+
type, builtinProtocol, cs.DC->getParentModule());
73637368
if (builtinConformance) {
73647369
// Find the witness that we'll use to initialize the type via a builtin
73657370
// literal.
@@ -7382,7 +7387,8 @@ Expr *ExprRewriter::convertLiteralInPlace(
73827387

73837388
// This literal type must conform to the (non-builtin) protocol.
73847389
assert(protocol && "requirements should have stopped recursion");
7385-
auto conformance = TypeChecker::conformsToProtocol(type, protocol, cs.DC);
7390+
auto conformance = TypeChecker::conformsToProtocol(type, protocol,
7391+
cs.DC->getParentModule());
73867392
assert(conformance && "must conform to literal protocol");
73877393

73887394
// Dig out the literal type and perform a builtin literal conversion to it.
@@ -7510,7 +7516,8 @@ ExprRewriter::buildDynamicCallable(ApplyExpr *apply, SelectedOverload selected,
75107516
auto dictLitProto =
75117517
ctx.getProtocol(KnownProtocolKind::ExpressibleByDictionaryLiteral);
75127518
auto conformance =
7513-
TypeChecker::conformsToProtocol(argumentType, dictLitProto, cs.DC);
7519+
TypeChecker::conformsToProtocol(argumentType, dictLitProto,
7520+
cs.DC->getParentModule());
75147521
auto keyType = conformance.getTypeWitnessByName(argumentType, ctx.Id_Key);
75157522
auto valueType =
75167523
conformance.getTypeWitnessByName(argumentType, ctx.Id_Value);
@@ -8448,7 +8455,7 @@ static Optional<SolutionApplicationTarget> applySolutionToForEachStmt(
84488455
stmt->getAwaitLoc().isValid() ?
84498456
KnownProtocolKind::AsyncSequence : KnownProtocolKind::Sequence);
84508457
auto sequenceConformance = TypeChecker::conformsToProtocol(
8451-
forEachStmtInfo.sequenceType, sequenceProto, cs.DC);
8458+
forEachStmtInfo.sequenceType, sequenceProto, cs.DC->getParentModule());
84528459
assert(!sequenceConformance.isInvalid() &&
84538460
"Couldn't find sequence conformance");
84548461

lib/Sema/CSBindings.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,8 @@ bool LiteralRequirement::isCoveredBy(Type type, DeclContext *useDC) const {
859859
if (hasDefaultType() && coversDefaultType(type, getDefaultType()))
860860
return true;
861861

862-
return bool(TypeChecker::conformsToProtocol(type, getProtocol(), useDC));
862+
return (bool)TypeChecker::conformsToProtocol(type, getProtocol(),
863+
useDC->getParentModule());
863864
}
864865

865866
std::pair<bool, Type>

lib/Sema/CSDiagnostics.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ Type FailureDiagnostic::restoreGenericParameters(
165165
bool FailureDiagnostic::conformsToKnownProtocol(
166166
Type type, KnownProtocolKind protocol) const {
167167
auto &cs = getConstraintSystem();
168-
return constraints::conformsToKnownProtocol(cs.DC, type, protocol);
168+
return TypeChecker::conformsToKnownProtocol(type, protocol,
169+
cs.DC->getParentModule());
169170
}
170171

171172
Type RequirementFailure::getOwnerType() const {
@@ -2073,10 +2074,10 @@ AssignmentFailure::getMemberRef(ConstraintLocator *locator) const {
20732074
if (!member->choice.isDecl())
20742075
return member->choice;
20752076

2076-
auto *DC = getDC();
20772077
auto *decl = member->choice.getDecl();
20782078
if (isa<SubscriptDecl>(decl) &&
2079-
isValidDynamicMemberLookupSubscript(cast<SubscriptDecl>(decl), DC)) {
2079+
isValidDynamicMemberLookupSubscript(cast<SubscriptDecl>(decl),
2080+
getParentModule())) {
20802081
auto *subscript = cast<SubscriptDecl>(decl);
20812082
// If this is a keypath dynamic member lookup, we have to
20822083
// adjust the locator to find member referred by it.
@@ -2754,7 +2755,7 @@ bool ContextualFailure::diagnoseThrowsTypeMismatch() const {
27542755
Ctx.getProtocol(KnownProtocolKind::ErrorCodeProtocol)) {
27552756
Type errorCodeType = getFromType();
27562757
auto conformance = TypeChecker::conformsToProtocol(
2757-
errorCodeType, errorCodeProtocol, getDC());
2758+
errorCodeType, errorCodeProtocol, getParentModule());
27582759
if (conformance) {
27592760
Type errorType =
27602761
conformance
@@ -2962,7 +2963,8 @@ bool ContextualFailure::tryProtocolConformanceFixIt(
29622963
SmallVector<std::string, 8> missingProtoTypeStrings;
29632964
SmallVector<ProtocolDecl *, 8> missingProtocols;
29642965
for (auto protocol : layout.getProtocols()) {
2965-
if (!TypeChecker::conformsToProtocol(fromType, protocol->getDecl(), getDC())) {
2966+
if (!TypeChecker::conformsToProtocol(fromType, protocol->getDecl(),
2967+
getParentModule())) {
29662968
missingProtoTypeStrings.push_back(protocol->getString());
29672969
missingProtocols.push_back(protocol->getDecl());
29682970
}

lib/Sema/CSDiagnostics.h

+4
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,10 @@ class FailureDiagnostic {
150150
return cs.DC;
151151
}
152152

153+
ModuleDecl *getParentModule() const {
154+
return getDC()->getParentModule();
155+
}
156+
153157
ASTContext &getASTContext() const {
154158
auto &cs = getConstraintSystem();
155159
return cs.getASTContext();

lib/Sema/CSGen.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ namespace {
411411
if (otherArgTy && otherArgTy->getAnyNominal()) {
412412
if (otherArgTy->isEqual(paramTy) &&
413413
TypeChecker::conformsToProtocol(
414-
otherArgTy, literalProto, CS.DC)) {
414+
otherArgTy, literalProto, CS.DC->getParentModule())) {
415415
return true;
416416
}
417417
} else if (Type defaultType =
@@ -1737,13 +1737,15 @@ namespace {
17371737
if (!contextualType)
17381738
return false;
17391739

1740+
auto *M = CS.DC->getParentModule();
1741+
17401742
auto type = contextualType->lookThroughAllOptionalTypes();
1741-
if (conformsToKnownProtocol(
1742-
CS.DC, type, KnownProtocolKind::ExpressibleByArrayLiteral))
1743+
if (TypeChecker::conformsToKnownProtocol(
1744+
type, KnownProtocolKind::ExpressibleByArrayLiteral, M))
17431745
return false;
17441746

1745-
return conformsToKnownProtocol(
1746-
CS.DC, type, KnownProtocolKind::ExpressibleByDictionaryLiteral);
1747+
return TypeChecker::conformsToKnownProtocol(
1748+
type, KnownProtocolKind::ExpressibleByDictionaryLiteral, M);
17471749
};
17481750

17491751
if (isDictionaryContextualType(contextualType)) {

lib/Sema/CSSimplify.cpp

+12-8
Original file line numberDiff line numberDiff line change
@@ -3469,9 +3469,10 @@ static bool repairArrayLiteralUsedAsDictionary(
34693469
if (unwrappedDict->isTypeVariableOrMember())
34703470
return false;
34713471

3472-
if (!conformsToKnownProtocol(
3473-
cs.DC, unwrappedDict,
3474-
KnownProtocolKind::ExpressibleByDictionaryLiteral))
3472+
if (!TypeChecker::conformsToKnownProtocol(
3473+
unwrappedDict,
3474+
KnownProtocolKind::ExpressibleByDictionaryLiteral,
3475+
cs.DC->getParentModule()))
34753476
return false;
34763477

34773478
// Ignore any attempts at promoting the value to an optional as even after
@@ -6108,7 +6109,8 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
61086109
switch (kind) {
61096110
case ConstraintKind::SelfObjectOfProtocol: {
61106111
auto conformance = TypeChecker::containsProtocol(
6111-
type, protocol, DC, /*skipConditionalRequirements=*/true);
6112+
type, protocol, DC->getParentModule(),
6113+
/*skipConditionalRequirements=*/true);
61126114
if (conformance) {
61136115
return recordConformance(conformance);
61146116
}
@@ -6237,7 +6239,8 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
62376239

62386240
if (auto rawValue = isRawRepresentable(*this, type)) {
62396241
if (!rawValue->isTypeVariableOrMember() &&
6240-
TypeChecker::conformsToProtocol(rawValue, protocol, DC)) {
6242+
TypeChecker::conformsToProtocol(rawValue, protocol,
6243+
DC->getParentModule())) {
62416244
auto *fix = UseRawValue::create(*this, type, protocolTy, loc);
62426245
return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
62436246
}
@@ -7575,7 +7578,8 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
75757578
auto *SD = cast<SubscriptDecl>(candidate.getDecl());
75767579
bool isKeyPathBased = isValidKeyPathDynamicMemberLookup(SD);
75777580

7578-
if (isValidStringDynamicMemberLookup(SD, DC) || isKeyPathBased)
7581+
if (isValidStringDynamicMemberLookup(SD, DC->getParentModule()) ||
7582+
isKeyPathBased)
75797583
result.addViable(OverloadChoice::getDynamicMemberLookup(
75807584
baseTy, SD, name, isKeyPathBased));
75817585
}
@@ -10212,7 +10216,6 @@ lookupDynamicCallableMethods(Type type, ConstraintSystem &CS,
1021210216
const ConstraintLocatorBuilder &locator,
1021310217
Identifier argumentName, bool hasKeywordArgs) {
1021410218
auto &ctx = CS.getASTContext();
10215-
auto decl = type->getAnyNominal();
1021610219
DeclNameRef methodName({ ctx, ctx.Id_dynamicallyCall, { argumentName } });
1021710220
auto matches = CS.performMemberLookup(
1021810221
ConstraintKind::ValueMember, methodName, type,
@@ -10222,7 +10225,8 @@ lookupDynamicCallableMethods(Type type, ConstraintSystem &CS,
1022210225
auto candidates = matches.ViableCandidates;
1022310226
auto filter = [&](OverloadChoice choice) {
1022410227
auto cand = cast<FuncDecl>(choice.getDecl());
10225-
return !isValidDynamicCallableMethod(cand, decl, hasKeywordArgs);
10228+
return !isValidDynamicCallableMethod(cand, CS.DC->getParentModule(),
10229+
hasKeywordArgs);
1022610230
};
1022710231
candidates.erase(
1022810232
std::remove_if(candidates.begin(), candidates.end(), filter),

0 commit comments

Comments
 (0)