@@ -2153,10 +2153,11 @@ class FailureDiagnosis :public ASTVisitor<FailureDiagnosis, /*exprresult*/bool>{
2153
2153
CalleeCandidateInfo &candidates,
2154
2154
ArrayRef<Identifier> argLabels);
2155
2155
2156
- bool diagnoseMemberFailures (Expr *baseEpxr, ConstraintKind lookupKind,
2157
- DeclName memberName, FunctionRefKind funcRefKind,
2158
- ConstraintLocator *locator,
2159
- bool includeInaccessibleMembers = true );
2156
+ bool diagnoseMemberFailures (
2157
+ Expr *baseEpxr, ConstraintKind lookupKind, DeclName memberName,
2158
+ FunctionRefKind funcRefKind, ConstraintLocator *locator,
2159
+ Optional<std::function<bool (ArrayRef<OverloadChoice>)>> callback = None,
2160
+ bool includeInaccessibleMembers = true);
2160
2161
2161
2162
bool visitExpr (Expr *E);
2162
2163
bool visitIdentityExpr (IdentityExpr *E);
@@ -5395,147 +5396,125 @@ bool FailureDiagnosis::visitSubscriptExpr(SubscriptExpr *SE) {
5395
5396
auto baseExpr = typeCheckChildIndependently (SE->getBase ());
5396
5397
if (!baseExpr) return true ;
5397
5398
auto baseType = baseExpr->getType ();
5398
-
5399
+
5399
5400
if (isa<NilLiteralExpr>(baseExpr)) {
5400
5401
diagnose (baseExpr->getLoc (), diag::cannot_subscript_nil_literal)
5401
5402
.highlight (baseExpr->getSourceRange ());
5402
5403
return true ;
5403
5404
}
5404
5405
5405
- auto locator =
5406
- CS->getConstraintLocator (SE, ConstraintLocator::SubscriptMember);
5406
+ std::function<bool (ArrayRef<OverloadChoice>)> callback =
5407
+ [&](ArrayRef<OverloadChoice> candidates) -> bool {
5408
+ CalleeCandidateInfo calleeInfo (Type (), candidates, SE->hasTrailingClosure (),
5409
+ CS,
5410
+ /* selfAlreadyApplied*/ false );
5407
5411
5408
- auto subscriptName = CS->getASTContext ().Id_subscript ;
5409
- if (diagnoseMemberFailures (baseExpr, ConstraintKind::ValueMember,
5410
- subscriptName, FunctionRefKind::DoubleApply,
5411
- locator))
5412
- return true ;
5412
+ // We're about to typecheck the index list, which needs to be processed with
5413
+ // self already applied.
5414
+ for (unsigned i = 0 , e = calleeInfo.size (); i != e; ++i)
5415
+ ++calleeInfo.candidates [i].level ;
5413
5416
5414
- MemberLookupResult result =
5415
- CS-> performMemberLookup (ConstraintKind::ValueMember, subscriptName,
5416
- baseType, FunctionRefKind::DoubleApply, locator,
5417
- /* includeInaccessibleMembers */ true ) ;
5417
+ auto indexExpr =
5418
+ typeCheckArgumentChildIndependently (SE-> getIndex (), Type (), calleeInfo);
5419
+ if (!indexExpr)
5420
+ return true ;
5418
5421
5419
-
5420
- switch (result.OverallResult ) {
5421
- case MemberLookupResult::Unsolved:
5422
- return false ;
5423
- case MemberLookupResult::ErrorAlreadyDiagnosed:
5424
- // If an error was already emitted, then we're done, don't emit anything
5425
- // redundant.
5426
- return true ;
5427
- case MemberLookupResult::HasResults:
5428
- break ; // Interesting case. :-)
5429
- }
5430
-
5431
- // Don't noise up diagnostics with key path application candidates, since they
5432
- // appear on every type.
5433
- SmallVector<OverloadChoice, 4 > viableCandidatesToReport;
5434
- for (auto candidate : result.ViableCandidates )
5435
- if (candidate.getKind () != OverloadChoiceKind::KeyPathApplication)
5436
- viableCandidatesToReport.push_back (candidate);
5422
+ // Back to analyzing the candidate list with self applied.
5423
+ for (unsigned i = 0 , e = calleeInfo.size (); i != e; ++i)
5424
+ --calleeInfo.candidates [i].level ;
5437
5425
5438
- CalleeCandidateInfo calleeInfo ( Type (), viableCandidatesToReport,
5439
- SE-> hasTrailingClosure (), CS,
5440
- /* selfAlreadyApplied */ false ) ;
5426
+ ArrayRef<Identifier> argLabels = SE-> getArgumentLabels ();
5427
+ if ( diagnoseParameterErrors (calleeInfo, SE, indexExpr, argLabels))
5428
+ return true ;
5441
5429
5442
- // We're about to typecheck the index list, which needs to be processed with
5443
- // self already applied.
5444
- for (unsigned i = 0 , e = calleeInfo.size (); i != e; ++i)
5445
- ++calleeInfo.candidates [i].level ;
5446
-
5447
- auto indexExpr = typeCheckArgumentChildIndependently (SE->getIndex (),
5448
- Type (), calleeInfo);
5449
- if (!indexExpr) return true ;
5430
+ auto indexType = indexExpr->getType ();
5431
+
5432
+ auto decomposedBaseType = decomposeArgType (baseType, {Identifier ()});
5433
+ auto decomposedIndexType = decomposeArgType (indexType, argLabels);
5434
+ calleeInfo.filterList (
5435
+ [&](UncurriedCandidate cand) -> CalleeCandidateInfo::ClosenessResultTy {
5436
+ // Classify how close this match is. Non-subscript decls don't match.
5437
+ if (!dyn_cast_or_null<SubscriptDecl>(cand.getDecl ()))
5438
+ return {CC_GeneralMismatch, {}};
5439
+
5440
+ // Check whether the self type matches.
5441
+ auto selfConstraint = CC_ExactMatch;
5442
+ if (calleeInfo.evaluateCloseness (cand, decomposedBaseType).first !=
5443
+ CC_ExactMatch)
5444
+ selfConstraint = CC_SelfMismatch;
5445
+
5446
+ // Increase the uncurry level to look past the self argument to the
5447
+ // indices.
5448
+ cand.level ++;
5449
+
5450
+ // Explode out multi-index subscripts to find the best match.
5451
+ auto indexResult =
5452
+ calleeInfo.evaluateCloseness (cand, decomposedIndexType);
5453
+ if (selfConstraint > indexResult.first )
5454
+ return {selfConstraint, {}};
5455
+ return indexResult;
5456
+ });
5450
5457
5451
- // Back to analyzing the candidate list with self applied.
5452
- for (unsigned i = 0 , e = calleeInfo.size (); i != e; ++i)
5453
- --calleeInfo.candidates [i].level ;
5458
+ // If the closest matches all mismatch on self, we either have something
5459
+ // that
5460
+ // cannot be subscripted, or an ambiguity.
5461
+ if (calleeInfo.closeness == CC_SelfMismatch) {
5462
+ diagnose (SE->getLoc (), diag::cannot_subscript_base, baseType)
5463
+ .highlight (SE->getBase ()->getSourceRange ());
5464
+ // FIXME: Should suggest overload set, but we're not ready for that until
5465
+ // it points to candidates and identifies the self type in the diagnostic.
5466
+ // calleeInfo.suggestPotentialOverloads(SE->getLoc());
5467
+ return true ;
5468
+ }
5454
5469
5455
- ArrayRef<Identifier> argLabels = SE-> getArgumentLabels ();
5456
- if ( diagnoseParameterErrors (calleeInfo, SE, indexExpr, argLabels) )
5457
- return true ;
5470
+ // Any other failures relate to the index list.
5471
+ for ( unsigned i = 0 , e = calleeInfo. size (); i != e; ++i )
5472
+ ++calleeInfo. candidates [i]. level ;
5458
5473
5459
- auto indexType = indexExpr-> getType ();
5474
+ // TODO: Is there any reason to check for CC_NonLValueInOut here?
5460
5475
5461
- auto decomposedBaseType = decomposeArgType (baseType, { Identifier () });
5462
- auto decomposedIndexType = decomposeArgType (indexType, argLabels);
5463
- calleeInfo.filterList ([&](UncurriedCandidate cand) ->
5464
- CalleeCandidateInfo::ClosenessResultTy
5465
- {
5466
- // Classify how close this match is. Non-subscript decls don't match.
5467
- if (!dyn_cast_or_null<SubscriptDecl>(cand.getDecl ()))
5468
- return { CC_GeneralMismatch, {}};
5469
-
5470
- // Check whether the self type matches.
5471
- auto selfConstraint = CC_ExactMatch;
5472
- if (calleeInfo.evaluateCloseness (cand, decomposedBaseType)
5473
- .first != CC_ExactMatch)
5474
- selfConstraint = CC_SelfMismatch;
5475
-
5476
- // Increase the uncurry level to look past the self argument to the indices.
5477
- cand.level ++;
5478
-
5479
- // Explode out multi-index subscripts to find the best match.
5480
- auto indexResult =
5481
- calleeInfo.evaluateCloseness (cand, decomposedIndexType);
5482
- if (selfConstraint > indexResult.first )
5483
- return {selfConstraint, {}};
5484
- return indexResult;
5485
- });
5476
+ if (calleeInfo.closeness == CC_ExactMatch) {
5477
+ // Otherwise, whatever the result type of the call happened to be must not
5478
+ // have been what we were looking for. Lets diagnose it as a conversion
5479
+ // or ambiguity failure.
5480
+ if (calleeInfo.size () == 1 )
5481
+ return false ;
5486
5482
5487
- // If the closest matches all mismatch on self, we either have something that
5488
- // cannot be subscripted, or an ambiguity.
5489
- if (calleeInfo.closeness == CC_SelfMismatch) {
5490
- diagnose (SE->getLoc (), diag::cannot_subscript_base, baseType)
5491
- .highlight (SE->getBase ()->getSourceRange ());
5492
- // FIXME: Should suggest overload set, but we're not ready for that until
5493
- // it points to candidates and identifies the self type in the diagnostic.
5494
- // calleeInfo.suggestPotentialOverloads(SE->getLoc());
5495
- return true ;
5496
- }
5483
+ diagnose (SE->getLoc (), diag::ambiguous_subscript, baseType, indexType)
5484
+ .highlight (indexExpr->getSourceRange ())
5485
+ .highlight (baseExpr->getSourceRange ());
5497
5486
5498
- // Any other failures relate to the index list.
5499
- for (unsigned i = 0 , e = calleeInfo.size (); i != e; ++i)
5500
- ++calleeInfo.candidates [i].level ;
5501
-
5502
- // TODO: Is there any reason to check for CC_NonLValueInOut here?
5503
-
5504
- if (calleeInfo.closeness == CC_ExactMatch) {
5505
- // Otherwise, whatever the result type of the call happened to be must not
5506
- // have been what we were looking for. Lets diagnose it as a conversion
5507
- // or ambiguity failure.
5508
- if (calleeInfo.size () == 1 )
5509
- return false ;
5487
+ // FIXME: suggestPotentialOverloads should do this.
5488
+ // calleeInfo.suggestPotentialOverloads(SE->getLoc());
5489
+ for (auto candidate : calleeInfo.candidates )
5490
+ if (auto decl = candidate.getDecl ())
5491
+ diagnose (decl, diag::found_candidate);
5492
+ else
5493
+ diagnose (candidate.getExpr ()->getLoc (), diag::found_candidate);
5510
5494
5511
- diagnose (SE->getLoc (), diag::ambiguous_subscript, baseType, indexType)
5512
- .highlight (indexExpr->getSourceRange ())
5513
- .highlight (baseExpr->getSourceRange ());
5514
-
5515
- // FIXME: suggestPotentialOverloads should do this.
5516
- // calleeInfo.suggestPotentialOverloads(SE->getLoc());
5517
- for (auto candidate : calleeInfo.candidates )
5518
- if (auto decl = candidate.getDecl ())
5519
- diagnose (decl, diag::found_candidate);
5520
- else
5521
- diagnose (candidate.getExpr ()->getLoc (), diag::found_candidate);
5495
+ return true ;
5496
+ }
5522
5497
5523
- return true ;
5524
- }
5498
+ if ( diagnoseParameterErrors (calleeInfo, SE, indexExpr, argLabels))
5499
+ return true ;
5525
5500
5526
- if (diagnoseParameterErrors (calleeInfo, SE, indexExpr, argLabels))
5527
- return true ;
5501
+ // Diagnose some simple and common errors.
5502
+ if (calleeInfo.diagnoseSimpleErrors (SE))
5503
+ return true ;
5528
5504
5529
- // Diagnose some simple and common errors.
5530
- if (calleeInfo.diagnoseSimpleErrors (SE))
5531
- return true ;
5505
+ diagnose (SE->getLoc (), diag::cannot_subscript_with_index, baseType,
5506
+ indexType);
5532
5507
5508
+ calleeInfo.suggestPotentialOverloads (SE->getLoc ());
5509
+ return true ;
5510
+ };
5533
5511
5534
- diagnose (SE-> getLoc (), diag::cannot_subscript_with_index,
5535
- baseType, indexType );
5512
+ auto locator =
5513
+ CS-> getConstraintLocator (SE, ConstraintLocator::SubscriptMember );
5536
5514
5537
- calleeInfo.suggestPotentialOverloads (SE->getLoc ());
5538
- return true ;
5515
+ return diagnoseMemberFailures (
5516
+ baseExpr, ConstraintKind::ValueMember, CS->getASTContext ().Id_subscript ,
5517
+ FunctionRefKind::DoubleApply, locator, callback);
5539
5518
}
5540
5519
5541
5520
@@ -7652,12 +7631,11 @@ bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
7652
7631
llvm_unreachable (" all cases should be handled" );
7653
7632
}
7654
7633
7655
- bool FailureDiagnosis::diagnoseMemberFailures (Expr *baseExpr,
7656
- ConstraintKind lookupKind,
7657
- DeclName memberName,
7658
- FunctionRefKind funcRefKind,
7659
- ConstraintLocator *locator,
7660
- bool includeInaccessibleMembers) {
7634
+ bool FailureDiagnosis::diagnoseMemberFailures (
7635
+ Expr *baseExpr, ConstraintKind lookupKind, DeclName memberName,
7636
+ FunctionRefKind funcRefKind, ConstraintLocator *locator,
7637
+ Optional<std::function<bool (ArrayRef<OverloadChoice>)>> callback,
7638
+ bool includeInaccessibleMembers) {
7661
7639
auto isInitializer = memberName.isSimpleName (CS->TC .Context .Id_init );
7662
7640
7663
7641
// Get the referenced base expression from the failed constraint, along with
@@ -7881,8 +7859,7 @@ bool FailureDiagnosis::diagnoseMemberFailures(Expr *baseExpr,
7881
7859
return true ;
7882
7860
}
7883
7861
7884
- // Otherwise, we don't know why this failed.
7885
- return false ;
7862
+ return callback.hasValue () ? (*callback)(viableCandidatesToReport) : false ;
7886
7863
}
7887
7864
7888
7865
bool FailureDiagnosis::visitUnresolvedDotExpr (UnresolvedDotExpr *UDE) {
0 commit comments