mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
These functions don't need a TypeChecker
This commit is contained in:
@@ -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`
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user