Skip to content

Refactor checkGenericArguments() and related code #31226

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 18 additions & 21 deletions lib/Sema/CSApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ Solution::computeSubstitutions(GenericSignature sig,

// FIXME: Retrieve the conformance from the solution itself.
return TypeChecker::conformsToProtocol(replacement, protoType,
getConstraintSystem().DC,
None);
getConstraintSystem().DC);
};

return SubstitutionMap::get(sig,
Expand Down Expand Up @@ -414,7 +413,7 @@ namespace {

return SubstitutionMap::get(sig,
QueryTypeSubstitutionMap{subs},
TypeChecker::LookUpConformance(cs.DC));
LookUpConformanceInModule(cs.DC->getParentModule()));
}

public:
Expand Down Expand Up @@ -447,7 +446,7 @@ namespace {
// the protocol requirement with Self == the concrete type, and SILGen
// (or later) can devirtualize as appropriate.
auto conformance =
TypeChecker::conformsToProtocol(baseTy, proto, cs.DC, None);
TypeChecker::conformsToProtocol(baseTy, proto, cs.DC);
if (conformance.isConcrete()) {
if (auto witness = conformance.getConcrete()->getWitnessDecl(decl)) {
bool isMemberOperator = witness->getDeclContext()->isTypeContext();
Expand Down Expand Up @@ -2082,8 +2081,7 @@ namespace {
auto bridgedToObjectiveCConformance
= TypeChecker::conformsToProtocol(valueType,
bridgedProto,
cs.DC,
None);
cs.DC);

FuncDecl *fn = nullptr;

Expand Down Expand Up @@ -2343,7 +2341,7 @@ namespace {
ProtocolDecl *protocol = TypeChecker::getProtocol(
ctx, expr->getLoc(), KnownProtocolKind::ExpressibleByStringLiteral);

if (!TypeChecker::conformsToProtocol(type, protocol, cs.DC, None)) {
if (!TypeChecker::conformsToProtocol(type, protocol, cs.DC)) {
// If the type does not conform to ExpressibleByStringLiteral, it should
// be ExpressibleByExtendedGraphemeClusterLiteral.
protocol = TypeChecker::getProtocol(
Expand All @@ -2352,7 +2350,7 @@ namespace {
isStringLiteral = false;
isGraphemeClusterLiteral = true;
}
if (!TypeChecker::conformsToProtocol(type, protocol, cs.DC, None)) {
if (!TypeChecker::conformsToProtocol(type, protocol, cs.DC)) {
// ... or it should be ExpressibleByUnicodeScalarLiteral.
protocol = TypeChecker::getProtocol(
cs.getASTContext(), expr->getLoc(),
Expand Down Expand Up @@ -2467,7 +2465,7 @@ namespace {
assert(proto && "Missing string interpolation protocol?");

auto conformance =
TypeChecker::conformsToProtocol(type, proto, cs.DC, None);
TypeChecker::conformsToProtocol(type, proto, cs.DC);
assert(conformance && "string interpolation type conforms to protocol");

DeclName constrName(ctx, DeclBaseName::createConstructor(), argLabels);
Expand Down Expand Up @@ -2573,7 +2571,7 @@ namespace {
auto proto = TypeChecker::getLiteralProtocol(cs.getASTContext(), expr);
assert(proto && "Missing object literal protocol?");
auto conformance =
TypeChecker::conformsToProtocol(conformingType, proto, cs.DC, None);
TypeChecker::conformsToProtocol(conformingType, proto, cs.DC);
assert(conformance && "object literal type conforms to protocol");

auto constrName = TypeChecker::getObjectLiteralConstructorName(ctx, expr);
Expand Down Expand Up @@ -3278,7 +3276,7 @@ namespace {
assert(arrayProto && "type-checked array literal w/o protocol?!");

auto conformance =
TypeChecker::conformsToProtocol(arrayTy, arrayProto, cs.DC, None);
TypeChecker::conformsToProtocol(arrayTy, arrayProto, cs.DC);
assert(conformance && "Type does not conform to protocol?");

DeclName name(ctx, DeclBaseName::createConstructor(),
Expand Down Expand Up @@ -3322,8 +3320,7 @@ namespace {
KnownProtocolKind::ExpressibleByDictionaryLiteral);

auto conformance =
TypeChecker::conformsToProtocol(dictionaryTy, dictionaryProto, cs.DC,
None);
TypeChecker::conformsToProtocol(dictionaryTy, dictionaryProto, cs.DC);
if (conformance.isInvalid())
return nullptr;

Expand Down Expand Up @@ -4062,7 +4059,7 @@ namespace {
// Special handle for literals conditional checked cast when they can
// be statically coerced to the cast type.
if (protocol && TypeChecker::conformsToProtocol(
toType, protocol, cs.DC, None)) {
toType, protocol, cs.DC)) {
ctx.Diags
.diagnose(expr->getLoc(),
diag::literal_conditional_downcast_to_coercion,
Expand Down Expand Up @@ -4939,7 +4936,7 @@ namespace {
// verified by the solver, we just need to get it again
// with all of the generic parameters resolved.
auto hashableConformance =
TypeChecker::conformsToProtocol(indexType, hashable, cs.DC, None);
TypeChecker::conformsToProtocol(indexType, hashable, cs.DC);
assert(hashableConformance);

conformances.push_back(hashableConformance);
Expand Down Expand Up @@ -5263,7 +5260,7 @@ collectExistentialConformances(Type fromType, Type toType,
SmallVector<ProtocolConformanceRef, 4> conformances;
for (auto proto : layout.getProtocols()) {
conformances.push_back(TypeChecker::containsProtocol(
fromType, proto->getDecl(), DC, None));
fromType, proto->getDecl(), DC));
}

return toType->getASTContext().AllocateCopy(conformances);
Expand Down Expand Up @@ -6430,7 +6427,7 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
auto hashable = ctx.getProtocol(KnownProtocolKind::Hashable);
auto conformance =
TypeChecker::conformsToProtocol(
cs.getType(expr), hashable, cs.DC, None);
cs.getType(expr), hashable, cs.DC);
assert(conformance && "must conform to Hashable");

return cs.cacheType(
Expand Down Expand Up @@ -6965,7 +6962,7 @@ Expr *ExprRewriter::convertLiteralInPlace(Expr *literal,
// initialize via the builtin protocol.
if (builtinProtocol) {
auto builtinConformance = TypeChecker::conformsToProtocol(
type, builtinProtocol, cs.DC, None);
type, builtinProtocol, cs.DC);
if (builtinConformance) {
// Find the witness that we'll use to initialize the type via a builtin
// literal.
Expand Down Expand Up @@ -6997,7 +6994,7 @@ Expr *ExprRewriter::convertLiteralInPlace(Expr *literal,

// This literal type must conform to the (non-builtin) protocol.
assert(protocol && "requirements should have stopped recursion");
auto conformance = TypeChecker::conformsToProtocol(type, protocol, cs.DC, None);
auto conformance = TypeChecker::conformsToProtocol(type, protocol, cs.DC);
assert(conformance && "must conform to literal protocol");

// Dig out the literal type and perform a builtin literal conversion to it.
Expand Down Expand Up @@ -7134,7 +7131,7 @@ ExprRewriter::buildDynamicCallable(ApplyExpr *apply, SelectedOverload selected,
auto dictLitProto =
ctx.getProtocol(KnownProtocolKind::ExpressibleByDictionaryLiteral);
auto conformance =
TypeChecker::conformsToProtocol(argumentType, dictLitProto, cs.DC, None);
TypeChecker::conformsToProtocol(argumentType, dictLitProto, cs.DC);
auto keyType = conformance.getTypeWitnessByName(argumentType, ctx.Id_Key);
auto valueType =
conformance.getTypeWitnessByName(argumentType, ctx.Id_Value);
Expand Down Expand Up @@ -8406,7 +8403,7 @@ ProtocolConformanceRef Solution::resolveConformance(
// itself rather than another conforms-to-protocol check.
Type substConformingType = simplifyType(conformingType);
return TypeChecker::conformsToProtocol(
substConformingType, proto, constraintSystem->DC, None);
substConformingType, proto, constraintSystem->DC);
}

return ProtocolConformanceRef::forInvalid();
Expand Down
4 changes: 1 addition & 3 deletions lib/Sema/CSBindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -766,9 +766,7 @@ ConstraintSystem::getPotentialBindings(TypeVariableType *typeVar) const {

do {
// If the type conforms to this protocol, we're covered.
if (TypeChecker::conformsToProtocol(
testType, protocol, DC,
ConformanceCheckFlags::SkipConditionalRequirements)) {
if (DC->getParentModule()->lookupConformance(testType, protocol)) {
coveredLiteralProtocols.insert(protocol);
break;
}
Expand Down
5 changes: 2 additions & 3 deletions lib/Sema/CSDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2451,7 +2451,7 @@ bool ContextualFailure::diagnoseThrowsTypeMismatch() const {
Ctx.getProtocol(KnownProtocolKind::ErrorCodeProtocol)) {
Type errorCodeType = getFromType();
auto conformance = TypeChecker::conformsToProtocol(
errorCodeType, errorCodeProtocol, getDC(), None);
errorCodeType, errorCodeProtocol, getDC());
if (conformance) {
Type errorType =
conformance
Expand Down Expand Up @@ -2781,8 +2781,7 @@ bool ContextualFailure::tryProtocolConformanceFixIt(
// Let's build a list of protocols that the context does not conform to.
SmallVector<std::string, 8> missingProtoTypeStrings;
for (auto protocol : layout.getProtocols()) {
if (!TypeChecker::conformsToProtocol(fromType, protocol->getDecl(), getDC(),
None)) {
if (!TypeChecker::conformsToProtocol(fromType, protocol->getDecl(), getDC())) {
missingProtoTypeStrings.push_back(protocol->getString());
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/CSGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ namespace {
if (otherArgTy && otherArgTy->getAnyNominal()) {
if (otherArgTy->isEqual(paramTy) &&
TypeChecker::conformsToProtocol(
otherArgTy, literalProto, CS.DC, None)) {
otherArgTy, literalProto, CS.DC)) {
return true;
}
} else if (Type defaultType =
Expand Down
4 changes: 1 addition & 3 deletions lib/Sema/CSRanking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,7 @@ computeSelfTypeRelationship(DeclContext *dc, ValueDecl *decl1,

// If the model type does not conform to the protocol, the bases are
// unrelated.
auto conformance = TypeChecker::conformsToProtocol(
modelTy, proto, dc,
ConformanceCheckFlags::SkipConditionalRequirements);
auto conformance = dc->getParentModule()->lookupConformance(modelTy, proto);
if (conformance.isInvalid())
return {SelfTypeRelationship::Unrelated, conformance};

Expand Down
13 changes: 5 additions & 8 deletions lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5179,18 +5179,16 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
switch (kind) {
case ConstraintKind::SelfObjectOfProtocol: {
auto conformance = TypeChecker::containsProtocol(
type, protocol, DC,
ConformanceCheckFlags::SkipConditionalRequirements);
type, protocol, DC, /*skipConditionalRequirements=*/true);
if (conformance) {
return recordConformance(conformance);
}
} break;
case ConstraintKind::ConformsTo:
case ConstraintKind::LiteralConformsTo: {
// Check whether this type conforms to the protocol.
auto conformance = TypeChecker::conformsToProtocol(
type, protocol, DC,
ConformanceCheckFlags::SkipConditionalRequirements);
auto conformance = DC->getParentModule()->lookupConformance(
type, protocol);
if (conformance) {
return recordConformance(conformance);
}
Expand Down Expand Up @@ -6869,9 +6867,8 @@ ConstraintSystem::simplifyValueWitnessConstraint(
// conformance already?
auto proto = requirement->getDeclContext()->getSelfProtocolDecl();
assert(proto && "Value witness constraint for a non-requirement");
auto conformance = TypeChecker::conformsToProtocol(
baseObjectType, proto, useDC,
ConformanceCheckFlags::SkipConditionalRequirements);
auto conformance = useDC->getParentModule()->lookupConformance(
baseObjectType, proto);
if (!conformance) {
// The conformance failed, so mark the member type as a "hole". We cannot
// do anything further here.
Expand Down
6 changes: 3 additions & 3 deletions lib/Sema/CSSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1726,10 +1726,10 @@ void ConstraintSystem::ArgumentInfoCollector::minimizeLiteralProtocols() {

auto first =
TypeChecker::conformsToProtocol(candidate.second, candidates[result].first,
CS.DC, None);
CS.DC);
auto second =
TypeChecker::conformsToProtocol(candidates[result].second, candidate.first,
CS.DC, None);
CS.DC);
if (first.isInvalid() == second.isInvalid())
return;

Expand Down Expand Up @@ -1955,7 +1955,7 @@ void ConstraintSystem::sortDesignatedTypes(
++nextType;
break;
} else if (auto *protoDecl = dyn_cast<ProtocolDecl>(nominalTypes[i])) {
if (TypeChecker::conformsToProtocol(argType, protoDecl, DC, None)) {
if (TypeChecker::conformsToProtocol(argType, protoDecl, DC)) {
std::swap(nominalTypes[nextType], nominalTypes[i]);
++nextType;
break;
Expand Down
6 changes: 2 additions & 4 deletions lib/Sema/CodeSynthesis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1130,10 +1130,8 @@ ResolveImplicitMemberRequest::evaluate(Evaluator &evaluator,
return false;

auto targetType = target->getDeclaredInterfaceType();
auto ref = TypeChecker::conformsToProtocol(
targetType, protocol, target,
ConformanceCheckFlags::SkipConditionalRequirements);

auto ref = target->getParentModule()->lookupConformance(
targetType, protocol);
if (ref.isInvalid()) {
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions lib/Sema/ConstraintSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3595,7 +3595,7 @@ bool constraints::conformsToKnownProtocol(ConstraintSystem &cs, Type type,
KnownProtocolKind protocol) {
if (auto *proto =
TypeChecker::getProtocol(cs.getASTContext(), SourceLoc(), protocol))
return (bool)TypeChecker::conformsToProtocol(type, proto, cs.DC, None);
return (bool)TypeChecker::conformsToProtocol(type, proto, cs.DC);
return false;
}

Expand All @@ -3609,7 +3609,7 @@ Type constraints::isRawRepresentable(ConstraintSystem &cs, Type type) {
if (!rawReprType)
return Type();

auto conformance = TypeChecker::conformsToProtocol(type, rawReprType, DC, None);
auto conformance = TypeChecker::conformsToProtocol(type, rawReprType, DC);
if (conformance.isInvalid())
return Type();

Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/DerivedConformanceAdditiveArithmetic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ bool DerivedConformance::canDeriveAdditiveArithmetic(NominalTypeDecl *nominal,
if (v->getInterfaceType()->hasError())
return false;
auto varType = DC->mapTypeIntoContext(v->getValueInterfaceType());
return (bool)TypeChecker::conformsToProtocol(varType, proto, DC, None);
return (bool)TypeChecker::conformsToProtocol(varType, proto, DC);
});
}

Expand Down
13 changes: 5 additions & 8 deletions lib/Sema/DerivedConformanceCodable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ static CodableConformanceType typeConformsToCodable(DeclContext *context,
false, proto);
}

auto conf = TypeChecker::conformsToProtocol(target, proto, context, None);
auto conf = TypeChecker::conformsToProtocol(target, proto, context);
return conf.isInvalid() ? DoesNotConform : Conforms;
}

Expand Down Expand Up @@ -264,7 +264,7 @@ static CodingKeysValidity hasValidCodingKeysEnum(DerivedConformance &derived) {
// Ensure that the type we found conforms to the CodingKey protocol.
auto *codingKeyProto = C.getProtocol(KnownProtocolKind::CodingKey);
if (!TypeChecker::conformsToProtocol(codingKeysType, codingKeyProto,
derived.getConformanceContext(), None)) {
derived.getConformanceContext())) {
// If CodingKeys is a typealias which doesn't point to a valid nominal type,
// codingKeysTypeDecl will be nullptr here. In that case, we need to warn on
// the location of the usage, since there isn't an underlying type to
Expand Down Expand Up @@ -847,10 +847,8 @@ deriveBodyDecodable_init(AbstractFunctionDecl *initDecl, void *) {
});
auto *encodableProto = C.getProtocol(KnownProtocolKind::Encodable);
bool conformsToEncodable =
TypeChecker::conformsToProtocol(
targetDecl->getDeclaredInterfaceType(), encodableProto,
conformanceDC,
ConformanceCheckFlags::SkipConditionalRequirements) != nullptr;
conformanceDC->getParentModule()->lookupConformance(
targetDecl->getDeclaredInterfaceType(), encodableProto) != nullptr;

// Strategy to use for CodingKeys enum diagnostic part - this is to
// make the behaviour more explicit:
Expand Down Expand Up @@ -1091,8 +1089,7 @@ static bool canSynthesize(DerivedConformance &derived, ValueDecl *requirement) {
if (auto *superclassDecl = classDecl->getSuperclassDecl()) {
DeclName memberName;
auto superType = superclassDecl->getDeclaredInterfaceType();
if (TypeChecker::conformsToProtocol(superType, proto, superclassDecl,
None)) {
if (TypeChecker::conformsToProtocol(superType, proto, superclassDecl)) {
// super.init(from:) must be accessible.
memberName = cast<ConstructorDecl>(requirement)->getName();
} else {
Expand Down
Loading