@@ -3212,6 +3212,9 @@ bool MissingMemberFailure::diagnoseAsError() {
3212
3212
if (diagnoseInLiteralCollectionContext ())
3213
3213
return true ;
3214
3214
3215
+ if (diagnoseForSubscriptMemberWithTupleBase ())
3216
+ return true ;
3217
+
3215
3218
auto baseType = resolveType (getBaseType ())->getWithoutSpecifierType ();
3216
3219
3217
3220
DeclNameLoc nameLoc (::getLoc (anchor));
@@ -3428,6 +3431,42 @@ bool MissingMemberFailure::diagnoseInLiteralCollectionContext() const {
3428
3431
return false ;
3429
3432
}
3430
3433
3434
+ bool MissingMemberFailure::diagnoseForSubscriptMemberWithTupleBase () const {
3435
+ auto locator = getLocator ();
3436
+ auto baseType = resolveType (getBaseType ())->getWithoutSpecifierType ();
3437
+
3438
+ if (!locator->isLastElement <LocatorPathElt::SubscriptMember>())
3439
+ return false ;
3440
+
3441
+ auto tupleType = baseType->getAs <TupleType>();
3442
+ // For non-tuple type or empty tuples, let's fallback to the general
3443
+ // diagnostic logic.
3444
+ if (!tupleType || tupleType->getNumElements () == 0 )
3445
+ return false ;
3446
+
3447
+ auto *SE = castToExpr<SubscriptExpr>(locator->getAnchor ());
3448
+ auto *index = SE->getIndex ();
3449
+
3450
+ if (SE->getNumArguments () == 1 ) {
3451
+ auto *literal =
3452
+ dyn_cast<IntegerLiteralExpr>(index->getSemanticsProvidingExpr ());
3453
+ if (literal && !literal->isNegative ()) {
3454
+ llvm::SmallString<4 > dotAccess;
3455
+ llvm::raw_svector_ostream OS (dotAccess);
3456
+ OS << " ." << literal->getDigitsText ();
3457
+
3458
+ emitDiagnostic (
3459
+ diag::could_not_find_subscript_member_tuple_did_you_mean_use_dot,
3460
+ baseType)
3461
+ .fixItReplace (index->getSourceRange (), OS.str ());
3462
+ return true ;
3463
+ }
3464
+ }
3465
+
3466
+ emitDiagnostic (diag::could_not_find_subscript_member_tuple, baseType);
3467
+ return true ;
3468
+ }
3469
+
3431
3470
bool UnintendedExtraGenericParamMemberFailure::diagnoseAsError () {
3432
3471
MissingMemberFailure::diagnoseAsError ();
3433
3472
0 commit comments