These functions don't need a TypeChecker

This commit is contained in:
Hamish Knight
2019-10-18 12:57:59 -07:00
parent 8b9cced36b
commit be23ecc878
5 changed files with 35 additions and 43 deletions

View File

@@ -1813,15 +1813,13 @@ AssignmentFailure::getMemberRef(ConstraintLocator *locator) const {
return member->choice;
auto *DC = getDC();
auto &TC = getTypeChecker();
auto *decl = member->choice.getDecl();
if (isa<SubscriptDecl>(decl) &&
isValidDynamicMemberLookupSubscript(cast<SubscriptDecl>(decl), DC, TC)) {
isValidDynamicMemberLookupSubscript(cast<SubscriptDecl>(decl), DC)) {
auto *subscript = cast<SubscriptDecl>(decl);
// If this is a keypath dynamic member lookup, we have to
// adjust the locator to find member referred by it.
if (isValidKeyPathDynamicMemberLookup(subscript, TC)) {
if (isValidKeyPathDynamicMemberLookup(subscript)) {
auto &cs = getConstraintSystem();
// Type has a following format:
// `(Self) -> (dynamicMember: {Writable}KeyPath<T, U>) -> U`

View File

@@ -5218,7 +5218,7 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
if (memberLocator &&
::hasDynamicMemberLookupAttribute(instanceTy,
DynamicMemberLookupCache) &&
isValidKeyPathDynamicMemberLookup(subscript, TC)) {
isValidKeyPathDynamicMemberLookup(subscript)) {
auto info = getArgumentInfo(memberLocator);
if (!(info && info->Labels.size() == 1 &&
@@ -5324,9 +5324,9 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
auto name = memberName.getBaseIdentifier();
for (const auto &candidate : subscripts.ViableCandidates) {
auto *SD = cast<SubscriptDecl>(candidate.getDecl());
bool isKeyPathBased = isValidKeyPathDynamicMemberLookup(SD, TC);
bool isKeyPathBased = isValidKeyPathDynamicMemberLookup(SD);
if (isValidStringDynamicMemberLookup(SD, DC, TC) || isKeyPathBased)
if (isValidStringDynamicMemberLookup(SD, DC) || isKeyPathBased)
result.addViable(OverloadChoice::getDynamicMemberLookup(
baseTy, SD, name, isKeyPathBased));
}
@@ -5335,7 +5335,7 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
auto *SD =
cast<SubscriptDecl>(subscripts.UnviableCandidates[index].getDecl());
auto choice = OverloadChoice::getDynamicMemberLookup(
baseTy, SD, name, isValidKeyPathDynamicMemberLookup(SD, TC));
baseTy, SD, name, isValidKeyPathDynamicMemberLookup(SD));
result.addUnviable(choice, subscripts.UnviableReasons[index]);
}
}
@@ -7094,7 +7094,7 @@ lookupDynamicCallableMethods(Type type, ConstraintSystem &CS,
auto candidates = matches.ViableCandidates;
auto filter = [&](OverloadChoice choice) {
auto cand = cast<FuncDecl>(choice.getDecl());
return !isValidDynamicCallableMethod(cand, decl, CS.TC, hasKeywordArgs);
return !isValidDynamicCallableMethod(cand, decl, hasKeywordArgs);
};
candidates.erase(
std::remove_if(candidates.begin(), candidates.end(), filter),

View File

@@ -114,9 +114,7 @@ TypeRelationCheckRequest::evaluate(Evaluator &evaluator,
llvm::Expected<TypePair>
RootAndResultTypeOfKeypathDynamicMemberRequest::evaluate(Evaluator &evaluator,
SubscriptDecl *subscript) const {
auto &TC = TypeChecker::createForContext(subscript->getASTContext());
if (!isValidKeyPathDynamicMemberLookup(subscript, TC))
if (!isValidKeyPathDynamicMemberLookup(subscript))
return TypePair();
const auto *param = subscript->getIndices()->get(0);

View File

@@ -1058,8 +1058,8 @@ void TypeChecker::checkDeclAttributes(Decl *D) {
/// as one of the following: `dynamicallyCall(withArguments:)` or
/// `dynamicallyCall(withKeywordArguments:)`.
bool swift::isValidDynamicCallableMethod(FuncDecl *decl, DeclContext *DC,
TypeChecker &TC,
bool hasKeywordArguments) {
auto &ctx = decl->getASTContext();
// There are two cases to check.
// 1. `dynamicallyCall(withArguments:)`.
// In this case, the method is valid if the argument has type `A` where
@@ -1081,7 +1081,7 @@ bool swift::isValidDynamicCallableMethod(FuncDecl *decl, DeclContext *DC,
// `ExpressibleByArrayLiteral`.
if (!hasKeywordArguments) {
auto arrayLitProto =
TC.Context.getProtocol(KnownProtocolKind::ExpressibleByArrayLiteral);
ctx.getProtocol(KnownProtocolKind::ExpressibleByArrayLiteral);
return TypeChecker::conformsToProtocol(argType, arrayLitProto, DC,
ConformanceCheckOptions()).hasValue();
}
@@ -1089,35 +1089,33 @@ bool swift::isValidDynamicCallableMethod(FuncDecl *decl, DeclContext *DC,
// `ExpressibleByDictionaryLiteral` and that the `Key` associated type
// conforms to `ExpressibleByStringLiteral`.
auto stringLitProtocol =
TC.Context.getProtocol(KnownProtocolKind::ExpressibleByStringLiteral);
ctx.getProtocol(KnownProtocolKind::ExpressibleByStringLiteral);
auto dictLitProto =
TC.Context.getProtocol(KnownProtocolKind::ExpressibleByDictionaryLiteral);
ctx.getProtocol(KnownProtocolKind::ExpressibleByDictionaryLiteral);
auto dictConf = TypeChecker::conformsToProtocol(argType, dictLitProto, DC,
ConformanceCheckOptions());
if (!dictConf) return false;
auto keyType = dictConf.getValue().getTypeWitnessByName(
argType, TC.Context.Id_Key);
auto keyType = dictConf.getValue().getTypeWitnessByName(argType, ctx.Id_Key);
return TypeChecker::conformsToProtocol(keyType, stringLitProtocol, DC,
ConformanceCheckOptions()).hasValue();
}
/// Returns true if the given nominal type has a valid implementation of a
/// @dynamicCallable attribute requirement with the given argument name.
static bool hasValidDynamicCallableMethod(TypeChecker &TC,
NominalTypeDecl *decl,
static bool hasValidDynamicCallableMethod(NominalTypeDecl *decl,
Identifier argumentName,
bool hasKeywordArgs) {
auto &ctx = decl->getASTContext();
auto declType = decl->getDeclaredType();
auto methodName = DeclName(TC.Context,
DeclBaseName(TC.Context.Id_dynamicallyCall),
auto methodName = DeclName(ctx, DeclBaseName(ctx.Id_dynamicallyCall),
{ argumentName });
auto candidates = TC.lookupMember(decl, declType, methodName);
auto candidates = TypeChecker::lookupMember(decl, declType, methodName);
if (candidates.empty()) return false;
// Filter valid candidates.
candidates.filter([&](LookupResultEntry entry, bool isOuter) {
auto candidate = cast<FuncDecl>(entry.getValueDecl());
return isValidDynamicCallableMethod(candidate, decl, TC, hasKeywordArgs);
return isValidDynamicCallableMethod(candidate, decl, hasKeywordArgs);
});
// If there are no valid candidates, return false.
@@ -1133,10 +1131,10 @@ visitDynamicCallableAttr(DynamicCallableAttr *attr) {
bool hasValidMethod = false;
hasValidMethod |=
hasValidDynamicCallableMethod(TC, decl, TC.Context.Id_withArguments,
hasValidDynamicCallableMethod(decl, TC.Context.Id_withArguments,
/*hasKeywordArgs*/ false);
hasValidMethod |=
hasValidDynamicCallableMethod(TC, decl, TC.Context.Id_withKeywordArguments,
hasValidDynamicCallableMethod(decl, TC.Context.Id_withKeywordArguments,
/*hasKeywordArgs*/ true);
if (!hasValidMethod) {
TC.diagnose(attr->getLocation(), diag::invalid_dynamic_callable_type, type);
@@ -1167,22 +1165,22 @@ static bool hasSingleNonVariadicParam(SubscriptDecl *decl,
/// The method is given to be defined as `subscript(dynamicMember:)`.
bool swift::isValidDynamicMemberLookupSubscript(SubscriptDecl *decl,
DeclContext *DC,
TypeChecker &TC,
bool ignoreLabel) {
// It could be
// - `subscript(dynamicMember: {Writable}KeyPath<...>)`; or
// - `subscript(dynamicMember: String*)`
return isValidKeyPathDynamicMemberLookup(decl, TC, ignoreLabel) ||
isValidStringDynamicMemberLookup(decl, DC, TC, ignoreLabel);
return isValidKeyPathDynamicMemberLookup(decl, ignoreLabel) ||
isValidStringDynamicMemberLookup(decl, DC, ignoreLabel);
}
bool swift::isValidStringDynamicMemberLookup(SubscriptDecl *decl,
DeclContext *DC, TypeChecker &TC,
DeclContext *DC,
bool ignoreLabel) {
auto &ctx = decl->getASTContext();
// There are two requirements:
// - The subscript method has exactly one, non-variadic parameter.
// - The parameter type conforms to `ExpressibleByStringLiteral`.
if (!hasSingleNonVariadicParam(decl, TC.Context.Id_dynamicMember,
if (!hasSingleNonVariadicParam(decl, ctx.Id_dynamicMember,
ignoreLabel))
return false;
@@ -1190,7 +1188,7 @@ bool swift::isValidStringDynamicMemberLookup(SubscriptDecl *decl,
auto paramType = param->getType();
auto stringLitProto =
TC.Context.getProtocol(KnownProtocolKind::ExpressibleByStringLiteral);
ctx.getProtocol(KnownProtocolKind::ExpressibleByStringLiteral);
// If this is `subscript(dynamicMember: String*)`
return bool(TypeChecker::conformsToProtocol(paramType, stringLitProto, DC,
@@ -1198,17 +1196,17 @@ bool swift::isValidStringDynamicMemberLookup(SubscriptDecl *decl,
}
bool swift::isValidKeyPathDynamicMemberLookup(SubscriptDecl *decl,
TypeChecker &TC,
bool ignoreLabel) {
if (!hasSingleNonVariadicParam(decl, TC.Context.Id_dynamicMember,
auto &ctx = decl->getASTContext();
if (!hasSingleNonVariadicParam(decl, ctx.Id_dynamicMember,
ignoreLabel))
return false;
const auto *param = decl->getIndices()->get(0);
if (auto NTD = param->getType()->getAnyNominal()) {
return NTD == TC.Context.getKeyPathDecl() ||
NTD == TC.Context.getWritableKeyPathDecl() ||
NTD == TC.Context.getReferenceWritableKeyPathDecl();
return NTD == ctx.getKeyPathDecl() ||
NTD == ctx.getWritableKeyPathDecl() ||
NTD == ctx.getReferenceWritableKeyPathDecl();
}
return false;
}
@@ -1245,7 +1243,7 @@ visitDynamicMemberLookupAttr(DynamicMemberLookupAttr *attr) {
auto cand = cast<SubscriptDecl>(entry.getValueDecl());
// FIXME(InterfaceTypeRequest): Remove this.
(void)cand->getInterfaceType();
return isValidDynamicMemberLookupSubscript(cand, decl, TC);
return isValidDynamicMemberLookupSubscript(cand, decl);
});
if (candidates.empty()) {
@@ -1269,7 +1267,7 @@ visitDynamicMemberLookupAttr(DynamicMemberLookupAttr *attr) {
auto cand = cast<SubscriptDecl>(entry.getValueDecl());
// FIXME(InterfaceTypeRequest): Remove this.
(void)cand->getInterfaceType();
return isValidDynamicMemberLookupSubscript(cand, decl, TC,
return isValidDynamicMemberLookupSubscript(cand, decl,
/*ignoreLabel*/ true);
});

View File

@@ -1976,13 +1976,12 @@ public:
/// as one of the following: `dynamicallyCall(withArguments:)` or
/// `dynamicallyCall(withKeywordArguments:)`.
bool isValidDynamicCallableMethod(FuncDecl *decl, DeclContext *DC,
TypeChecker &TC, bool hasKeywordArguments);
bool hasKeywordArguments);
/// Returns true if the given subscript method is an valid implementation of
/// the `subscript(dynamicMember:)` requirement for @dynamicMemberLookup.
/// The method is given to be defined as `subscript(dynamicMember:)`.
bool isValidDynamicMemberLookupSubscript(SubscriptDecl *decl, DeclContext *DC,
TypeChecker &TC,
bool ignoreLabel = false);
/// Returns true if the given subscript method is an valid implementation of
@@ -1991,7 +1990,6 @@ bool isValidDynamicMemberLookupSubscript(SubscriptDecl *decl, DeclContext *DC,
/// takes a single non-variadic parameter that conforms to
/// `ExpressibleByStringLiteral` protocol.
bool isValidStringDynamicMemberLookup(SubscriptDecl *decl, DeclContext *DC,
TypeChecker &TC,
bool ignoreLabel = false);
/// Returns true if the given subscript method is an valid implementation of
@@ -1999,7 +1997,7 @@ bool isValidStringDynamicMemberLookup(SubscriptDecl *decl, DeclContext *DC,
/// @dynamicMemberLookup.
/// The method is given to be defined as `subscript(dynamicMember:)` which
/// takes a single non-variadic parameter of `{Writable}KeyPath<T, U>` type.
bool isValidKeyPathDynamicMemberLookup(SubscriptDecl *decl, TypeChecker &TC,
bool isValidKeyPathDynamicMemberLookup(SubscriptDecl *decl,
bool ignoreLabel = false);
/// Compute the wrapped value type for the given property that has attached