@@ -523,10 +523,10 @@ class FailureDiagnosis :public ASTVisitor<FailureDiagnosis, /*exprresult*/bool>{
523523 // / Given a result of name lookup that had no viable results, diagnose the
524524 // / unviable ones.
525525 void diagnoseUnviableLookupResults (MemberLookupResult &lookupResults,
526- Type baseObjTy, Expr *baseExpr,
526+ Expr *expr, Type baseObjTy, Expr *baseExpr,
527527 DeclName memberName, DeclNameLoc nameLoc,
528528 SourceLoc loc);
529-
529+
530530 // / Produce a diagnostic for a general overload resolution failure
531531 // / (irrespective of the exact expression kind).
532532 bool diagnoseGeneralOverloadFailure (Constraint *constraint);
@@ -913,125 +913,23 @@ diagnoseTypeMemberOnInstanceLookup(Type baseObjTy,
913913 return ;
914914}
915915
916- // / When a user refers a enum case with a wrong member name, we try to find a enum
917- // / element whose name differs from the wrong name only in convention; meaning their
918- // / lower case counterparts are identical.
919- // / - DeclName is valid when such a correct case is found; invalid otherwise.
920- static DeclName
921- findCorrectEnumCaseName (Type Ty, TypoCorrectionResults &corrections,
922- DeclName memberName) {
923- if (memberName.isSpecial () || !memberName.isSimpleName ())
924- return DeclName ();
925- if (!Ty->is <EnumType>() &&
926- !Ty->is <BoundGenericEnumType>())
927- return DeclName ();
928- auto candidate =
929- corrections.getUniqueCandidateMatching ([&](ValueDecl *candidate) {
930- return (isa<EnumElementDecl>(candidate) &&
931- candidate->getFullName ().getBaseIdentifier ().str ()
932- .equals_lower (memberName.getBaseIdentifier ().str ()));
933- });
934- return (candidate ? candidate->getFullName () : DeclName ());
935- }
936-
937916// / Given a result of name lookup that had no viable results, diagnose the
938917// / unviable ones.
939- void FailureDiagnosis::
940- diagnoseUnviableLookupResults (MemberLookupResult &result, Type baseObjTy,
941- Expr *baseExpr,
942- DeclName memberName, DeclNameLoc nameLoc,
943- SourceLoc loc) {
918+ void FailureDiagnosis::diagnoseUnviableLookupResults (
919+ MemberLookupResult &result, Expr *E, Type baseObjTy, Expr *baseExpr,
920+ DeclName memberName, DeclNameLoc nameLoc, SourceLoc loc) {
944921 SourceRange baseRange = baseExpr ? baseExpr->getSourceRange () : SourceRange ();
945-
922+
946923 // If we found no results at all, mention that fact.
947924 if (result.UnviableCandidates .empty ()) {
948- TypoCorrectionResults corrections (CS.TC , memberName, nameLoc);
949- auto tryTypoCorrection = [&] {
950- CS.TC .performTypoCorrection (CS.DC , DeclRefKind::Ordinary, baseObjTy,
951- defaultMemberLookupOptions, corrections);
952- };
953-
954- // TODO: This should handle tuple member lookups, like x.1231 as well.
955- if (memberName.getBaseName ().getKind () == DeclBaseName::Kind::Subscript) {
956- diagnose (loc, diag::could_not_find_value_subscript, baseObjTy)
957- .highlight (baseRange);
958- } else if (memberName.getBaseName () == " deinit" ) {
959- // Specialised diagnostic if trying to access deinitialisers
960- diagnose (loc, diag::destructor_not_accessible).highlight (baseRange);
961- } else if (auto metatypeTy = baseObjTy->getAs <MetatypeType>()) {
962- auto instanceTy = metatypeTy->getInstanceType ();
963- tryTypoCorrection ();
964-
965- if (DeclName rightName = findCorrectEnumCaseName (instanceTy,
966- corrections,
967- memberName)) {
968- diagnose (loc, diag::could_not_find_enum_case, instanceTy,
969- memberName, rightName)
970- .fixItReplace (nameLoc.getBaseNameLoc (),
971- rightName.getBaseIdentifier ().str ());
972- return ;
973- }
974-
975- if (auto correction = corrections.claimUniqueCorrection ()) {
976- auto diagnostic =
977- diagnose (loc, diag::could_not_find_type_member_corrected,
978- instanceTy, memberName, correction->CorrectedName );
979- diagnostic.highlight (baseRange).highlight (nameLoc.getSourceRange ());
980- correction->addFixits (diagnostic);
981- } else {
982- diagnose (loc, diag::could_not_find_type_member, instanceTy, memberName)
983- .highlight (baseRange).highlight (nameLoc.getSourceRange ());
984- }
985- } else if (auto moduleTy = baseObjTy->getAs <ModuleType>()) {
986- diagnose (baseExpr->getLoc (), diag::no_member_of_module,
987- moduleTy->getModule ()->getName (), memberName)
988- .highlight (baseRange)
989- .highlight (nameLoc.getSourceRange ());
990- return ;
991- } else {
992- auto emitBasicError = [&] {
993- diagnose (loc, diag::could_not_find_value_member,
994- baseObjTy, memberName)
995- .highlight (baseRange).highlight (nameLoc.getSourceRange ());
996- };
997-
998- // Check for a few common cases that can cause missing members.
999- if (baseObjTy->is <EnumType>() && memberName.isSimpleName (" rawValue" )) {
1000- auto loc = baseObjTy->castTo <EnumType>()->getDecl ()->getNameLoc ();
1001- if (loc.isValid ()) {
1002- emitBasicError ();
1003- diagnose (loc, diag::did_you_mean_raw_type);
1004- return ;
1005- }
1006- } else if (baseObjTy->isAny ()) {
1007- emitBasicError ();
1008- diagnose (loc, diag::any_as_anyobject_fixit)
1009- .fixItInsert (baseExpr->getStartLoc (), " (" )
1010- .fixItInsertAfter (baseExpr->getEndLoc (), " as AnyObject)" );
1011- return ;
1012- }
1013-
1014- tryTypoCorrection ();
1015-
1016- if (auto correction = corrections.claimUniqueCorrection ()) {
1017- auto diagnostic =
1018- diagnose (loc, diag::could_not_find_value_member_corrected,
1019- baseObjTy, memberName, correction->CorrectedName );
1020- diagnostic.highlight (baseRange).highlight (nameLoc.getSourceRange ());
1021- correction->addFixits (diagnostic);
1022- } else {
1023- emitBasicError ();
1024- }
1025- }
1026-
1027- // Note all the correction candidates.
1028- corrections.noteAllCandidates ();
1029-
1030- // TODO: recover?
925+ MissingMemberFailure failure (nullptr , CS, baseObjTy, memberName,
926+ CS.getConstraintLocator (E));
927+ auto diagnosed = failure.diagnoseAsError ();
928+ assert (diagnosed && " Failed to produce missing member diagnostic" );
929+ (void )diagnosed;
1031930 return ;
1032931 }
1033932
1034-
1035933 // Otherwise, we have at least one (and potentially many) viable candidates
1036934 // sort them out. If all of the candidates have the same problem (commonly
1037935 // because there is exactly one candidate!) diagnose this.
@@ -4632,7 +4530,7 @@ bool FailureDiagnosis::diagnoseMethodAttributeFailures(
46324530 // If one of the unviable candidates matches arguments exactly,
46334531 // that means that actual problem is related to function attributes.
46344532 if (unviableCandidates.closeness == CC_ExactMatch) {
4635- diagnoseUnviableLookupResults (results, baseType, base, UDE->getName (),
4533+ diagnoseUnviableLookupResults (results, UDE, baseType, base, UDE->getName (),
46364534 UDE->getNameLoc (), UDE->getLoc ());
46374535 return true ;
46384536 }
@@ -7451,7 +7349,7 @@ bool FailureDiagnosis::diagnoseMemberFailures(
74517349 }
74527350
74537351 // FIXME: Dig out the property DeclNameLoc.
7454- diagnoseUnviableLookupResults (result, baseObjTy, baseExpr, memberName,
7352+ diagnoseUnviableLookupResults (result, E, baseObjTy, baseExpr, memberName,
74557353 NameLoc, BaseLoc);
74567354 return true ;
74577355 }
@@ -8219,6 +8117,20 @@ void FailureDiagnosis::diagnoseAmbiguity(Expr *E) {
82198117 }
82208118 }
82218119
8120+ // Before giving up completely let's try to see if there are any
8121+ // fixes recorded by constraint generator, which point to structural
8122+ // problems that might not result in solution even if fixed e.g.
8123+ // missing members involved in protocol composition in expression
8124+ // context which are interpreted as binary operator expressions instead.
8125+ {
8126+ bool diagnosed = false ;
8127+ for (auto *fix : CS.getFixes ())
8128+ diagnosed |= fix->diagnose (expr);
8129+
8130+ if (diagnosed)
8131+ return ;
8132+ }
8133+
82228134 // If there are no posted constraints or failures, then there was
82238135 // not enough contextual information available to infer a type for the
82248136 // expression.
0 commit comments