@@ -3089,34 +3089,35 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
3089
3089
3090
3090
// Local function that adds the given declaration if it is a
3091
3091
// reasonable choice.
3092
- auto addChoice = [&](ValueDecl *cand, bool isBridged,
3093
- bool isUnwrappedOptional) {
3092
+ auto addChoice = [&](OverloadChoice candidate) {
3093
+ auto decl = candidate.getDecl ();
3094
+
3094
3095
// If the result is invalid, skip it.
3095
- TC.validateDecl (cand );
3096
- if (cand ->isInvalid ()) {
3096
+ TC.validateDecl (decl );
3097
+ if (decl ->isInvalid ()) {
3097
3098
result.markErrorAlreadyDiagnosed ();
3098
3099
return ;
3099
3100
}
3100
3101
3101
3102
// FIXME: Deal with broken recursion
3102
- if (!cand ->hasInterfaceType ())
3103
+ if (!decl ->hasInterfaceType ())
3103
3104
return ;
3104
3105
3105
3106
// If the argument labels for this result are incompatible with
3106
3107
// the call site, skip it.
3107
- if (!hasCompatibleArgumentLabels (cand )) {
3108
+ if (!hasCompatibleArgumentLabels (decl )) {
3108
3109
labelMismatch = true ;
3109
- result.addUnviable (cand , MemberLookupResult::UR_LabelMismatch);
3110
+ result.addUnviable (candidate , MemberLookupResult::UR_LabelMismatch);
3110
3111
return ;
3111
3112
}
3112
3113
3113
3114
// If our base is an existential type, we can't make use of any
3114
3115
// member whose signature involves associated types.
3115
3116
if (isExistential) {
3116
- if (auto *proto = cand ->getDeclContext ()
3117
+ if (auto *proto = decl ->getDeclContext ()
3117
3118
->getAsProtocolOrProtocolExtensionContext ()) {
3118
- if (!proto->isAvailableInExistential (cand )) {
3119
- result.addUnviable (cand ,
3119
+ if (!proto->isAvailableInExistential (decl )) {
3120
+ result.addUnviable (candidate ,
3120
3121
MemberLookupResult::UR_UnavailableInExistential);
3121
3122
return ;
3122
3123
}
@@ -3126,117 +3127,121 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
3126
3127
// If the invocation's argument expression has a favored type,
3127
3128
// use that information to determine whether a specific overload for
3128
3129
// the candidate should be favored.
3129
- if (isa<ConstructorDecl>(cand ) && favoredType &&
3130
+ if (isa<ConstructorDecl>(decl ) && favoredType &&
3130
3131
result.FavoredChoice == ~0U ) {
3131
3132
// Only try and favor monomorphic initializers.
3132
- if (auto fnTypeWithSelf = cand->getInterfaceType ()
3133
- ->getAs <FunctionType>()) {
3134
- if (auto fnType = fnTypeWithSelf->getResult ()
3135
- ->getAs <FunctionType>()) {
3133
+ if (auto fnTypeWithSelf = decl->getInterfaceType ()
3134
+ ->getAs <FunctionType>()) {
3135
+ if (auto fnType = fnTypeWithSelf->getResult ()->getAs <FunctionType>()) {
3136
3136
auto argType = fnType->getInput ()->getWithoutParens ();
3137
- argType = cand ->getInnermostDeclContext ()
3137
+ argType = decl ->getInnermostDeclContext ()
3138
3138
->mapTypeIntoContext (argType);
3139
3139
if (argType->isEqual (favoredType))
3140
- if (!cand ->getAttrs ().isUnavailable (getASTContext ()))
3140
+ if (!decl ->getAttrs ().isUnavailable (getASTContext ()))
3141
3141
result.FavoredChoice = result.ViableCandidates .size ();
3142
3142
}
3143
3143
}
3144
3144
}
3145
3145
3146
3146
// See if we have an instance method, instance member or static method,
3147
3147
// and check if it can be accessed on our base type.
3148
- if (cand->isInstanceMember ()) {
3149
- if ((isa<FuncDecl>(cand) && !hasInstanceMethods) ||
3150
- (!isa<FuncDecl>(cand) && !hasInstanceMembers)) {
3151
- result.addUnviable (cand, MemberLookupResult::UR_InstanceMemberOnType);
3148
+ if (decl->isInstanceMember ()) {
3149
+ if ((isa<FuncDecl>(decl) && !hasInstanceMethods) ||
3150
+ (!isa<FuncDecl>(decl) && !hasInstanceMembers)) {
3151
+ result.addUnviable (candidate,
3152
+ MemberLookupResult::UR_InstanceMemberOnType);
3152
3153
return ;
3153
3154
}
3154
3155
3155
3156
// If the underlying type of a typealias is fully concrete, it is legal
3156
3157
// to access the type with a protocol metatype base.
3157
3158
} else if (isExistential &&
3158
- isa<TypeAliasDecl>(cand ) &&
3159
- !cast<TypeAliasDecl>(cand )->getInterfaceType ()->getCanonicalType ()
3159
+ isa<TypeAliasDecl>(decl ) &&
3160
+ !cast<TypeAliasDecl>(decl )->getInterfaceType ()->getCanonicalType ()
3160
3161
->hasTypeParameter ()) {
3161
3162
3162
3163
/* We're OK */
3163
3164
3164
3165
} else {
3165
3166
if (!hasStaticMembers) {
3166
- result.addUnviable (cand, MemberLookupResult::UR_TypeMemberOnInstance);
3167
+ result.addUnviable (candidate,
3168
+ MemberLookupResult::UR_TypeMemberOnInstance);
3167
3169
return ;
3168
3170
}
3169
3171
}
3170
3172
3171
3173
// If we have an rvalue base, make sure that the result isn't 'mutating'
3172
3174
// (only valid on lvalues).
3173
3175
if (!isMetatype &&
3174
- !baseTy->is <LValueType>() && cand ->isInstanceMember ()) {
3175
- if (auto *FD = dyn_cast<FuncDecl>(cand ))
3176
+ !baseTy->is <LValueType>() && decl ->isInstanceMember ()) {
3177
+ if (auto *FD = dyn_cast<FuncDecl>(decl ))
3176
3178
if (FD->isMutating ()) {
3177
- result.addUnviable (cand ,
3179
+ result.addUnviable (candidate ,
3178
3180
MemberLookupResult::UR_MutatingMemberOnRValue);
3179
3181
return ;
3180
3182
}
3181
3183
3182
3184
// Subscripts and computed properties are ok on rvalues so long
3183
3185
// as the getter is nonmutating.
3184
- if (auto storage = dyn_cast<AbstractStorageDecl>(cand )) {
3186
+ if (auto storage = dyn_cast<AbstractStorageDecl>(decl )) {
3185
3187
if (storage->isGetterMutating ()) {
3186
- result.addUnviable (cand ,
3188
+ result.addUnviable (candidate ,
3187
3189
MemberLookupResult::UR_MutatingGetterOnRValue);
3188
3190
return ;
3189
3191
}
3190
3192
}
3191
3193
}
3192
3194
3193
3195
// If the result's type contains delayed members, we need to force them now.
3194
- if (auto NT = dyn_cast<NominalType>(cand ->getInterfaceType ().getPointer ())) {
3196
+ if (auto NT = dyn_cast<NominalType>(decl ->getInterfaceType ().getPointer ())){
3195
3197
if (auto *NTD = dyn_cast<NominalTypeDecl>(NT->getDecl ())) {
3196
3198
TC.forceExternalDeclMembers (NTD);
3197
3199
}
3198
3200
}
3199
3201
3202
+ // Otherwise, we're good, add the candidate to the list.
3203
+ result.addViable (candidate);
3204
+ };
3205
+
3206
+ // Local function that turns a ValueDecl into a properly configured
3207
+ // OverloadChoice.
3208
+ auto getOverloadChoice = [&](ValueDecl *cand, bool isBridged,
3209
+ bool isUnwrappedOptional) -> OverloadChoice {
3200
3210
// If we're looking into an existential type, check whether this
3201
3211
// result was found via dynamic lookup.
3202
3212
if (isDynamicLookup) {
3203
3213
assert (cand->getDeclContext ()->isTypeContext () && " Dynamic lookup bug" );
3204
-
3214
+
3205
3215
// We found this declaration via dynamic lookup, record it as such.
3206
- result.addViable (OverloadChoice::getDeclViaDynamic (baseTy, cand,
3207
- functionRefKind));
3208
- return ;
3216
+ return OverloadChoice::getDeclViaDynamic (baseTy, cand, functionRefKind);
3209
3217
}
3210
-
3218
+
3211
3219
// If we have a bridged type, we found this declaration via bridging.
3212
- if (isBridged) {
3213
- result.addViable (OverloadChoice::getDeclViaBridge (bridgedType, cand,
3214
- functionRefKind));
3215
- return ;
3216
- }
3217
-
3220
+ if (isBridged)
3221
+ return OverloadChoice::getDeclViaBridge (bridgedType, cand,
3222
+ functionRefKind);
3223
+
3218
3224
// If we got the choice by unwrapping an optional type, unwrap the base
3219
3225
// type.
3220
3226
Type ovlBaseTy = baseTy;
3221
3227
if (isUnwrappedOptional) {
3222
3228
ovlBaseTy = MetatypeType::get (baseTy->castTo <MetatypeType>()
3223
- ->getInstanceType ()
3224
- ->getAnyOptionalObjectType ());
3225
- result.addViable (
3226
- OverloadChoice::getDeclViaUnwrappedOptional (ovlBaseTy, cand,
3227
- functionRefKind));
3228
- } else {
3229
- result.addViable (OverloadChoice (ovlBaseTy, cand, functionRefKind));
3229
+ ->getInstanceType ()
3230
+ ->getAnyOptionalObjectType ());
3231
+ return OverloadChoice::getDeclViaUnwrappedOptional (ovlBaseTy, cand,
3232
+ functionRefKind);
3230
3233
}
3234
+
3235
+ return OverloadChoice (ovlBaseTy, cand, functionRefKind);
3231
3236
};
3232
-
3237
+
3233
3238
// Add all results from this lookup.
3234
3239
retry_after_fail:
3235
3240
labelMismatch = false ;
3236
3241
for (auto result : lookup)
3237
- addChoice (result.getValueDecl (),
3238
- /* isBridged=*/ false ,
3239
- /* isUnwrappedOptional=*/ false );
3242
+ addChoice (getOverloadChoice ( result.getValueDecl (),
3243
+ /* isBridged=*/ false ,
3244
+ /* isUnwrappedOptional=*/ false ) );
3240
3245
3241
3246
// If the instance type is a bridged to an Objective-C type, perform
3242
3247
// a lookup into that Objective-C type.
@@ -3259,9 +3264,9 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
3259
3264
continue ;
3260
3265
}
3261
3266
3262
- addChoice (result.getValueDecl (),
3263
- /* isBridged=*/ true ,
3264
- /* isUnwrappedOptional=*/ false );
3267
+ addChoice (getOverloadChoice ( result.getValueDecl (),
3268
+ /* isBridged=*/ true ,
3269
+ /* isUnwrappedOptional=*/ false ) );
3265
3270
}
3266
3271
}
3267
3272
@@ -3275,9 +3280,9 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
3275
3280
if (objectType->mayHaveMembers ()) {
3276
3281
LookupResult &optionalLookup = lookupMember (objectType, memberName);
3277
3282
for (auto result : optionalLookup)
3278
- addChoice (result.getValueDecl (),
3279
- /* bridged*/ false ,
3280
- /* isUnwrappedOptional=*/ true );
3283
+ addChoice (getOverloadChoice ( result.getValueDecl (),
3284
+ /* bridged*/ false ,
3285
+ /* isUnwrappedOptional=*/ true ) );
3281
3286
}
3282
3287
}
3283
3288
}
@@ -3319,7 +3324,9 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
3319
3324
if (!cand->hasInterfaceType ())
3320
3325
continue ;
3321
3326
3322
- result.addUnviable (cand, MemberLookupResult::UR_Inaccessible);
3327
+ result.addUnviable (getOverloadChoice (cand, /* isBridged=*/ false ,
3328
+ /* isUnwrappedOptional=*/ false ),
3329
+ MemberLookupResult::UR_Inaccessible);
3323
3330
}
3324
3331
}
3325
3332
0 commit comments