Skip to content

Commit afaff48

Browse files
authored
Merge pull request swiftlang#30932 from xedin/failure-diagnostic-gardening
[Diagnostics] A couple of adjustments to `FailureDiagnostic`
2 parents 3ef8360 + 42bdfc9 commit afaff48

File tree

2 files changed

+73
-97
lines changed

2 files changed

+73
-97
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 63 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -50,29 +50,25 @@ bool FailureDiagnostic::diagnoseAsNote() {
5050
return false;
5151
}
5252

53-
std::pair<Expr *, bool> FailureDiagnostic::computeAnchor() const {
53+
Expr *FailureDiagnostic::computeAnchor() const {
5454
auto &cs = getConstraintSystem();
5555

5656
auto *locator = getLocator();
5757
// Resolve the locator to a specific expression.
5858
SourceRange range;
59-
bool isSubscriptMember =
60-
(!locator->getPath().empty() && locator->getPath().back().getKind() ==
61-
ConstraintLocator::SubscriptMember);
62-
6359
ConstraintLocator *resolved = simplifyLocator(cs, locator, range);
6460
if (!resolved || !resolved->getAnchor())
65-
return {locator->getAnchor(), true};
61+
return locator->getAnchor();
6662

6763
Expr *anchor = resolved->getAnchor();
6864
// FIXME: Work around an odd locator representation that doesn't separate the
6965
// base of a subscript member from the member access.
70-
if (isSubscriptMember) {
66+
if (locator->isLastElement<LocatorPathElt::SubscriptMember>()) {
7167
if (auto subscript = dyn_cast<SubscriptExpr>(anchor))
7268
anchor = subscript->getBase();
7369
}
7470

75-
return {anchor, !resolved->getPath().empty()};
71+
return anchor;
7672
}
7773

7874
Type FailureDiagnostic::getType(Expr *expr, bool wantRValue) const {
@@ -130,11 +126,6 @@ Expr *FailureDiagnostic::getBaseExprFor(Expr *anchor) const {
130126
return nullptr;
131127
}
132128

133-
Optional<SelectedOverload>
134-
FailureDiagnostic::getChoiceFor(ConstraintLocator *locator) const {
135-
return getOverloadChoiceIfAvailable(S.getCalleeLocator(locator));
136-
}
137-
138129
Type FailureDiagnostic::restoreGenericParameters(
139130
Type type,
140131
llvm::function_ref<void(GenericTypeParamType *, Type)> substitution) {
@@ -231,7 +222,7 @@ ValueDecl *RequirementFailure::getDeclRef() const {
231222
return getAffectedDeclFromType(
232223
getContextualType(getLocator()->getAnchor()));
233224

234-
if (auto overload = getChoiceFor(getLocator())) {
225+
if (auto overload = getCalleeOverloadChoiceIfAvailable(getLocator())) {
235226
// If there is a declaration associated with this
236227
// failure e.g. an overload choice of the call
237228
// expression, let's see whether failure is
@@ -761,7 +752,7 @@ bool LabelingFailure::diagnoseAsNote() {
761752
return "(" + str + ")";
762753
};
763754

764-
auto selectedOverload = getChoiceFor(getLocator());
755+
auto selectedOverload = getCalleeOverloadChoiceIfAvailable(getLocator());
765756
if (!selectedOverload)
766757
return false;
767758

@@ -874,9 +865,6 @@ bool NoEscapeFuncToTypeConversionFailure::diagnoseParameterUse() const {
874865
}
875866

876867
bool MissingForcedDowncastFailure::diagnoseAsError() {
877-
if (hasComplexLocator())
878-
return false;
879-
880868
auto *expr = getAnchor();
881869
if (auto *assignExpr = dyn_cast<AssignExpr>(expr))
882870
expr = assignExpr->getSrc();
@@ -894,9 +882,6 @@ bool MissingForcedDowncastFailure::diagnoseAsError() {
894882
}
895883

896884
bool MissingAddressOfFailure::diagnoseAsError() {
897-
if (hasComplexLocator())
898-
return false;
899-
900885
auto *anchor = getAnchor();
901886
auto argTy = getFromType();
902887
auto paramTy = getToType();
@@ -913,9 +898,6 @@ bool MissingAddressOfFailure::diagnoseAsError() {
913898
}
914899

915900
bool MissingExplicitConversionFailure::diagnoseAsError() {
916-
if (hasComplexLocator())
917-
return false;
918-
919901
auto *DC = getDC();
920902
auto *anchor = getAnchor();
921903
if (auto *assign = dyn_cast<AssignExpr>(anchor))
@@ -976,9 +958,6 @@ bool MissingExplicitConversionFailure::diagnoseAsError() {
976958
}
977959

978960
bool MemberAccessOnOptionalBaseFailure::diagnoseAsError() {
979-
if (hasComplexLocator())
980-
return false;
981-
982961
auto *anchor = getAnchor();
983962
auto baseType = getType(anchor);
984963
bool resultIsOptional = ResultTypeIsOptional;
@@ -1101,9 +1080,6 @@ class VarDeclMultipleReferencesChecker : public ASTWalker {
11011080
};
11021081

11031082
bool MissingOptionalUnwrapFailure::diagnoseAsError() {
1104-
if (hasComplexLocator())
1105-
return false;
1106-
11071083
if (!getUnwrappedType()->isBool()) {
11081084
if (diagnoseConversionToBool())
11091085
return true;
@@ -1261,19 +1237,41 @@ bool RValueTreatedAsLValueFailure::diagnoseAsError() {
12611237
subElementDiagID = diag::assignment_lhs_is_apply_expression;
12621238
}
12631239
} else if (auto inoutExpr = dyn_cast<InOutExpr>(diagExpr)) {
1264-
if (auto restriction = getRestrictionForType(getType(inoutExpr))) {
1265-
PointerTypeKind pointerKind;
1266-
if (restriction->second == ConversionRestrictionKind::ArrayToPointer &&
1267-
restriction->first->getAnyPointerElementType(pointerKind) &&
1268-
(pointerKind == PTK_UnsafePointer ||
1269-
pointerKind == PTK_UnsafeRawPointer)) {
1270-
// If we're converting to an UnsafePointer, then the programmer
1271-
// specified an & unnecessarily. Produce a fixit hint to remove it.
1272-
emitDiagnostic(inoutExpr->getLoc(),
1273-
diag::extra_address_of_unsafepointer, restriction->first)
1274-
.highlight(inoutExpr->getSourceRange())
1275-
.fixItRemove(inoutExpr->getStartLoc());
1276-
return true;
1240+
if (auto *parentExpr = findParentExpr(inoutExpr)) {
1241+
if (auto *call =
1242+
dyn_cast_or_null<ApplyExpr>(findParentExpr(parentExpr))) {
1243+
// Since this `inout` expression is an argument to a call/operator
1244+
// let's figure out whether this is an impliict conversion from
1245+
// array to an unsafe pointer type and diagnose it.
1246+
unsigned argIdx = 0;
1247+
if (auto *TE = dyn_cast<TupleExpr>(parentExpr)) {
1248+
for (unsigned n = TE->getNumElements(); argIdx != n; ++argIdx) {
1249+
if (TE->getElement(argIdx) == inoutExpr)
1250+
break;
1251+
}
1252+
}
1253+
1254+
auto *argLoc = getConstraintLocator(
1255+
call, {ConstraintLocator::ApplyArgument,
1256+
LocatorPathElt::ApplyArgToParam(argIdx, argIdx,
1257+
ParameterTypeFlags())});
1258+
1259+
if (auto info = getFunctionArgApplyInfo(argLoc)) {
1260+
auto &cs = getConstraintSystem();
1261+
auto paramType = info->getParamType();
1262+
auto argType = getType(inoutExpr)->getWithoutSpecifierType();
1263+
1264+
PointerTypeKind ptr;
1265+
if (cs.isArrayType(argType) &&
1266+
paramType->getAnyPointerElementType(ptr) &&
1267+
(ptr == PTK_UnsafePointer || ptr == PTK_UnsafeRawPointer)) {
1268+
emitDiagnostic(inoutExpr->getLoc(),
1269+
diag::extra_address_of_unsafepointer, paramType)
1270+
.highlight(inoutExpr->getSourceRange())
1271+
.fixItRemove(inoutExpr->getStartLoc());
1272+
return true;
1273+
}
1274+
}
12771275
}
12781276
}
12791277

@@ -1296,8 +1294,10 @@ bool RValueTreatedAsLValueFailure::diagnoseAsError() {
12961294
ConstructorDecl::BodyInitKind::Delegating) {
12971295
emitDiagnostic(loc, diag::assignment_let_property_delegating_init,
12981296
member->getName());
1299-
if (auto *ref = getResolvedMemberRef(member)) {
1300-
emitDiagnostic(ref, diag::decl_declared_here, ref->getFullName());
1297+
if (auto overload = getOverloadChoiceIfAvailable(
1298+
getConstraintLocator(member, ConstraintLocator::Member))) {
1299+
if (auto *ref = overload->choice.getDeclOrNull())
1300+
emitDiagnostic(ref, diag::decl_declared_here, ref->getFullName());
13011301
}
13021302
return true;
13031303
}
@@ -1328,7 +1328,7 @@ bool RValueTreatedAsLValueFailure::diagnoseAsError() {
13281328
}
13291329

13301330
bool RValueTreatedAsLValueFailure::diagnoseAsNote() {
1331-
auto overload = getChoiceFor(getLocator());
1331+
auto overload = getCalleeOverloadChoiceIfAvailable(getLocator());
13321332
if (!(overload && overload->choice.isDecl()))
13331333
return false;
13341334

@@ -2020,8 +2020,8 @@ bool ContextualFailure::diagnoseAsError() {
20202020
case ConstraintLocator::RValueAdjustment: {
20212021
auto &cs = getConstraintSystem();
20222022

2023-
auto overload = getChoiceFor(
2024-
cs.getConstraintLocator(anchor, ConstraintLocator::UnresolvedMember));
2023+
auto overload = getOverloadChoiceIfAvailable(
2024+
getConstraintLocator(anchor, ConstraintLocator::UnresolvedMember));
20252025
if (!(overload && overload->choice.isDecl()))
20262026
return false;
20272027

@@ -2084,7 +2084,7 @@ bool ContextualFailure::diagnoseAsError() {
20842084
}
20852085

20862086
bool ContextualFailure::diagnoseAsNote() {
2087-
auto overload = getChoiceFor(getLocator());
2087+
auto overload = getCalleeOverloadChoiceIfAvailable(getLocator());
20882088
if (!(overload && overload->choice.isDecl()))
20892089
return false;
20902090

@@ -3512,7 +3512,7 @@ bool AllowTypeOrInstanceMemberFailure::diagnoseAsError() {
35123512
};
35133513

35143514
auto *baseLoc = cs.getConstraintLocator(ctorRef->getBase());
3515-
if (auto selection = getChoiceFor(baseLoc)) {
3515+
if (auto selection = getCalleeOverloadChoiceIfAvailable(baseLoc)) {
35163516
OverloadChoice choice = selection->choice;
35173517
if (choice.isDecl() && isMutable(choice.getDecl()) &&
35183518
!isCallArgument(initCall) &&
@@ -3923,7 +3923,7 @@ bool MissingArgumentsFailure::diagnoseAsError() {
39233923

39243924
diag.flush();
39253925

3926-
if (auto selectedOverload = getChoiceFor(locator)) {
3926+
if (auto selectedOverload = getCalleeOverloadChoiceIfAvailable(locator)) {
39273927
if (auto *decl = selectedOverload->choice.getDeclOrNull()) {
39283928
emitDiagnostic(decl, diag::decl_declared_here, decl->getFullName());
39293929
}
@@ -3934,7 +3934,7 @@ bool MissingArgumentsFailure::diagnoseAsError() {
39343934

39353935
bool MissingArgumentsFailure::diagnoseAsNote() {
39363936
auto *locator = getLocator();
3937-
if (auto overload = getChoiceFor(locator)) {
3937+
if (auto overload = getCalleeOverloadChoiceIfAvailable(locator)) {
39383938
auto *fn = resolveType(overload->openedType)->getAs<AnyFunctionType>();
39393939
auto loc = overload->choice.getDecl()->getLoc();
39403940
if (loc.isInvalid())
@@ -4055,7 +4055,8 @@ bool MissingArgumentsFailure::diagnoseSingleMissingArgument() const {
40554055
.fixItInsert(insertLoc, insertText.str());
40564056
}
40574057

4058-
if (auto selectedOverload = getChoiceFor(getLocator())) {
4058+
if (auto selectedOverload =
4059+
getCalleeOverloadChoiceIfAvailable(getLocator())) {
40594060
if (auto *decl = selectedOverload->choice.getDeclOrNull()) {
40604061
emitDiagnostic(decl, diag::decl_declared_here, decl->getFullName());
40614062
}
@@ -4175,7 +4176,7 @@ bool MissingArgumentsFailure::diagnoseInvalidTupleDestructuring() const {
41754176
if (!(argExpr && getType(argExpr)->getRValueType()->is<TupleType>()))
41764177
return false;
41774178

4178-
auto selectedOverload = getChoiceFor(locator);
4179+
auto selectedOverload = getCalleeOverloadChoiceIfAvailable(locator);
41794180
if (!selectedOverload)
41804181
return false;
41814182

@@ -4603,7 +4604,7 @@ bool ExtraneousArgumentsFailure::diagnoseAsError() {
46034604

46044605
emitDiagnostic(anchor->getLoc(), diag::extra_arguments_in_call, OS.str());
46054606

4606-
if (auto overload = getChoiceFor(getLocator())) {
4607+
if (auto overload = getCalleeOverloadChoiceIfAvailable(getLocator())) {
46074608
if (auto *decl = overload->choice.getDeclOrNull()) {
46084609
emitDiagnostic(decl, diag::decl_declared_here, decl->getFullName());
46094610
}
@@ -4613,7 +4614,7 @@ bool ExtraneousArgumentsFailure::diagnoseAsError() {
46134614
}
46144615

46154616
bool ExtraneousArgumentsFailure::diagnoseAsNote() {
4616-
auto overload = getChoiceFor(getLocator());
4617+
auto overload = getCalleeOverloadChoiceIfAvailable(getLocator());
46174618
if (!(overload && overload->choice.isDecl()))
46184619
return false;
46194620

@@ -5251,7 +5252,7 @@ bool MutatingMemberRefOnImmutableBase::diagnoseAsError() {
52515252
}
52525253

52535254
bool InvalidTupleSplatWithSingleParameterFailure::diagnoseAsError() {
5254-
auto selectedOverload = getChoiceFor(getLocator());
5255+
auto selectedOverload = getCalleeOverloadChoiceIfAvailable(getLocator());
52555256
if (!selectedOverload || !selectedOverload->choice.isDecl())
52565257
return false;
52575258

@@ -5716,7 +5717,7 @@ bool ExpandArrayIntoVarargsFailure::diagnoseAsError() {
57165717
}
57175718

57185719
bool ExpandArrayIntoVarargsFailure::diagnoseAsNote() {
5719-
auto overload = getChoiceFor(getLocator());
5720+
auto overload = getCalleeOverloadChoiceIfAvailable(getLocator());
57205721
auto anchor = getAnchor();
57215722
if (!overload || !anchor)
57225723
return false;
@@ -5750,7 +5751,7 @@ bool ExtraneousCallFailure::diagnoseAsError() {
57505751
}
57515752
};
57525753

5753-
if (auto overload = getChoiceFor(cs.getCalleeLocator(locator))) {
5754+
if (auto overload = getCalleeOverloadChoiceIfAvailable(locator)) {
57545755
if (auto *decl = overload->choice.getDeclOrNull()) {
57555756
if (auto *enumCase = dyn_cast<EnumElementDecl>(decl)) {
57565757
auto diagnostic = emitDiagnostic(
@@ -5783,13 +5784,12 @@ bool ExtraneousCallFailure::diagnoseAsError() {
57835784

57845785
bool InvalidUseOfTrailingClosure::diagnoseAsError() {
57855786
auto *anchor = getAnchor();
5786-
auto &cs = getConstraintSystem();
57875787

57885788
emitDiagnostic(anchor->getLoc(), diag::trailing_closure_bad_param,
57895789
getToType())
57905790
.highlight(anchor->getSourceRange());
57915791

5792-
if (auto overload = getChoiceFor(cs.getCalleeLocator(getLocator()))) {
5792+
if (auto overload = getCalleeOverloadChoiceIfAvailable(getLocator())) {
57935793
if (auto *decl = overload->choice.getDeclOrNull()) {
57945794
emitDiagnostic(decl, diag::decl_declared_here, decl->getFullName());
57955795
}
@@ -6042,9 +6042,9 @@ bool AssignmentTypeMismatchFailure::diagnoseAsError() {
60426042

60436043
bool AssignmentTypeMismatchFailure::diagnoseAsNote() {
60446044
auto *anchor = getAnchor();
6045-
auto &cs = getConstraintSystem();
60466045

6047-
if (auto overload = getChoiceFor(cs.getConstraintLocator(anchor))) {
6046+
if (auto overload =
6047+
getCalleeOverloadChoiceIfAvailable(getConstraintLocator(anchor))) {
60486048
if (auto *decl = overload->choice.getDeclOrNull()) {
60496049
emitDiagnostic(decl,
60506050
diag::cannot_convert_candidate_result_to_contextual_type,

0 commit comments

Comments
 (0)