Skip to content

Commit df76275

Browse files
authored
Merge pull request #39169 from hborla/bogus-missing-function-call-error
[ConstraintSystem] Fix a bogus missing function call error message.
2 parents 69f3b28 + 03777c3 commit df76275

File tree

6 files changed

+80
-52
lines changed

6 files changed

+80
-52
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2240,7 +2240,7 @@ bool ContextualFailure::diagnoseAsError() {
22402240
return false;
22412241
}
22422242

2243-
if (diagnoseMissingFunctionCall())
2243+
if (diagnoseExtraneousAssociatedValues())
22442244
return true;
22452245

22462246
// Special case of some common conversions involving Swift.String
@@ -2640,24 +2640,7 @@ void ContextualFailure::tryFixIts(InFlightDiagnostic &diagnostic) const {
26402640
return;
26412641
}
26422642

2643-
bool ContextualFailure::diagnoseMissingFunctionCall() const {
2644-
if (getLocator()
2645-
->isLastElement<LocatorPathElt::UnresolvedMemberChainResult>())
2646-
return false;
2647-
2648-
auto *srcFT = getFromType()->getAs<FunctionType>();
2649-
if (!srcFT ||
2650-
!(srcFT->getParams().empty() ||
2651-
getLocator()->isLastElement<LocatorPathElt::PatternMatch>()))
2652-
return false;
2653-
2654-
auto toType = getToType();
2655-
if (toType->is<AnyFunctionType>() ||
2656-
!TypeChecker::isConvertibleTo(srcFT->getResult(), toType, getDC()))
2657-
return false;
2658-
2659-
// Diagnose cases where the pattern tried to match associated values but
2660-
// the case we found had none.
2643+
bool ContextualFailure::diagnoseExtraneousAssociatedValues() const {
26612644
if (auto match =
26622645
getLocator()->getLastElementAs<LocatorPathElt::PatternMatch>()) {
26632646
if (auto enumElementPattern =
@@ -2672,12 +2655,7 @@ bool ContextualFailure::diagnoseMissingFunctionCall() const {
26722655
}
26732656
}
26742657

2675-
emitDiagnostic(diag::missing_nullary_call, srcFT->getResult())
2676-
.highlight(getSourceRange())
2677-
.fixItInsertAfter(getSourceRange().End, "()");
2678-
2679-
tryComputedPropertyFixIts();
2680-
return true;
2658+
return false;
26812659
}
26822660

26832661
bool ContextualFailure::diagnoseCoercionToUnrelatedType() const {
@@ -3083,7 +3061,7 @@ bool ContextualFailure::tryProtocolConformanceFixIt(
30833061
return true;
30843062
}
30853063

3086-
void ContextualFailure::tryComputedPropertyFixIts() const {
3064+
void MissingCallFailure::tryComputedPropertyFixIts() const {
30873065
if (!isExpr<ClosureExpr>(getAnchor()))
30883066
return;
30893067

@@ -3294,7 +3272,8 @@ bool MissingCallFailure::diagnoseAsError() {
32943272
if (isExpr<KeyPathExpr>(anchor))
32953273
return false;
32963274

3297-
auto path = getLocator()->getPath();
3275+
auto *locator = getLocator();
3276+
auto path = locator->getPath();
32983277
if (!path.empty()) {
32993278
const auto &last = path.back();
33003279

@@ -3303,8 +3282,17 @@ bool MissingCallFailure::diagnoseAsError() {
33033282
case ConstraintLocator::ApplyArgToParam: {
33043283
auto type = getType(anchor)->lookThroughAllOptionalTypes();
33053284
auto fnType = type->castTo<FunctionType>();
3285+
3286+
if (MissingArgumentsFailure::isMisplacedMissingArgument(getSolution(), locator)) {
3287+
ArgumentMismatchFailure failure(
3288+
getSolution(), fnType, fnType->getResult(), locator);
3289+
return failure.diagnoseMisplacedMissingArgument();
3290+
}
3291+
33063292
emitDiagnostic(diag::missing_nullary_call, fnType->getResult())
3293+
.highlight(getSourceRange())
33073294
.fixItInsertAfter(insertLoc, "()");
3295+
tryComputedPropertyFixIts();
33083296
return true;
33093297
}
33103298

@@ -4697,8 +4685,9 @@ bool MissingArgumentsFailure::isMisplacedMissingArgument(
46974685
auto *argLoc = solution.getConstraintLocator(
46984686
callLocator, LocatorPathElt::ApplyArgToParam(0, 0, argFlags));
46994687

4700-
if (!(hasFixFor(FixKind::AllowArgumentTypeMismatch, argLoc) &&
4701-
hasFixFor(FixKind::AddMissingArguments, callLocator)))
4688+
bool hasArgumentMismatch = hasFixFor(FixKind::AllowArgumentTypeMismatch, argLoc) ||
4689+
hasFixFor(FixKind::InsertCall, argLoc);
4690+
if (!(hasArgumentMismatch && hasFixFor(FixKind::AddMissingArguments, callLocator)))
47024691
return false;
47034692

47044693
auto *anchorExpr = getAsExpr(anchor);

lib/Sema/CSDiagnostics.h

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -633,9 +633,9 @@ class ContextualFailure : public FailureDiagnostic {
633633
/// Diagnose failed conversion in a `CoerceExpr`.
634634
bool diagnoseCoercionToUnrelatedType() const;
635635

636-
/// If we're trying to convert something of type "() -> T" to T,
637-
/// then we probably meant to call the value.
638-
bool diagnoseMissingFunctionCall() const;
636+
/// Diagnose cases where a pattern tried to match associated values but
637+
/// the enum case had none.
638+
bool diagnoseExtraneousAssociatedValues() const;
639639

640640
/// Produce a specialized diagnostic if this is an invalid conversion to Bool.
641641
bool diagnoseConversionToBool() const;
@@ -683,10 +683,6 @@ class ContextualFailure : public FailureDiagnostic {
683683
return resolveType(rawType)->getWithoutSpecifierType();
684684
}
685685

686-
/// Try to add a fix-it to convert a stored property into a computed
687-
/// property
688-
void tryComputedPropertyFixIts() const;
689-
690686
bool isIntegerType(Type type) const {
691687
return conformsToKnownProtocol(
692688
type, KnownProtocolKind::ExpressibleByIntegerLiteral);
@@ -1046,6 +1042,10 @@ class NonOptionalUnwrapFailure final : public FailureDiagnostic {
10461042
};
10471043

10481044
class MissingCallFailure final : public FailureDiagnostic {
1045+
/// Try to add a fix-it to convert a stored property into a computed
1046+
/// property
1047+
void tryComputedPropertyFixIts() const;
1048+
10491049
public:
10501050
MissingCallFailure(const Solution &solution, ConstraintLocator *locator)
10511051
: FailureDiagnostic(solution, locator) {}
@@ -1954,6 +1954,15 @@ class ArgumentMismatchFailure : public ContextualFailure {
19541954
/// result value.
19551955
bool diagnoseKeyPathAsFunctionResultMismatch() const;
19561956

1957+
/// Situations like this:
1958+
///
1959+
/// func foo(_: Int, _: String) {}
1960+
/// foo("")
1961+
///
1962+
/// Are currently impossible to fix correctly,
1963+
/// so we have to attend to that in diagnostics.
1964+
bool diagnoseMisplacedMissingArgument() const;
1965+
19571966
protected:
19581967
/// \returns The position of the argument being diagnosed, starting at 1.
19591968
unsigned getArgPosition() const { return Info.getArgPosition(); }
@@ -2038,15 +2047,6 @@ class ArgumentMismatchFailure : public ContextualFailure {
20382047
ParameterTypeFlags getParameterFlagsAtIndex(unsigned idx) const {
20392048
return Info.getParameterFlagsAtIndex(idx);
20402049
}
2041-
2042-
/// Situations like this:
2043-
///
2044-
/// func foo(_: Int, _: String) {}
2045-
/// foo("")
2046-
///
2047-
/// Are currently impossible to fix correctly,
2048-
/// so we have to attend to that in diagnostics.
2049-
bool diagnoseMisplacedMissingArgument() const;
20502050
};
20512051

20522052
/// Replace a coercion ('as') with a runtime checked cast ('as!' or 'as?').

lib/Sema/CSSimplify.cpp

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3657,15 +3657,27 @@ bool ConstraintSystem::repairFailures(
36573657
if (!fnType)
36583658
return false;
36593659

3660+
// If the locator isn't anchored at an expression, or the expression is
3661+
// implicit, don't try to insert an explicit call into the source code.
3662+
auto *loc = getConstraintLocator(locator);
3663+
auto *anchor = getAsExpr(simplifyLocatorToAnchor(loc));
3664+
if (!anchor || anchor->isImplicit())
3665+
return false;
3666+
3667+
if (isArgumentOfPatternMatchingOperator(loc))
3668+
return false;
3669+
3670+
// Don't attempt this fix for trailing closures.
3671+
if (auto elt = loc->getLastElementAs<LocatorPathElt::ApplyArgToParam>()) {
3672+
auto argumentList = getArgumentList(loc);
3673+
if (argumentList->isTrailingClosureIndex(elt->getArgIdx()))
3674+
return false;
3675+
}
3676+
36603677
// If argument is a function type and all of its parameters have
36613678
// default values, let's see whether error is related to missing
36623679
// explicit call.
36633680
if (fnType->getNumParams() > 0) {
3664-
auto *loc = getConstraintLocator(locator);
3665-
auto *anchor = getAsExpr(simplifyLocatorToAnchor(loc));
3666-
if (!anchor)
3667-
return false;
3668-
36693681
auto overload = findSelectedOverloadFor(anchor);
36703682
if (!(overload && overload->choice.isDecl()))
36713683
return false;
@@ -3701,7 +3713,14 @@ bool ConstraintSystem::repairFailures(
37013713
convertTo->isAny())
37023714
return false;
37033715

3704-
auto result = matchTypes(resultType, dstType, ConstraintKind::Conversion,
3716+
ConstraintKind matchKind;
3717+
if (resultType->is<TypeVariableType>()) {
3718+
matchKind = ConstraintKind::Equal;
3719+
} else {
3720+
matchKind = ConstraintKind::Conversion;
3721+
}
3722+
3723+
auto result = matchTypes(resultType, dstType, matchKind,
37053724
TypeMatchFlags::TMF_ApplyingFix, locator);
37063725

37073726
if (result.isSuccess()) {
@@ -4538,6 +4557,9 @@ bool ConstraintSystem::repairFailures(
45384557

45394558
case ConstraintLocator::ClosureBody:
45404559
case ConstraintLocator::ClosureResult: {
4560+
if (repairByInsertingExplicitCall(lhs, rhs))
4561+
break;
4562+
45414563
if (repairViaOptionalUnwrap(*this, lhs, rhs, matchKind, conversionsOrFixes,
45424564
locator))
45434565
return true;

lib/Sema/ConstraintSystem.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4327,6 +4327,12 @@ void constraints::simplifyLocator(ASTNode &anchor,
43274327
continue;
43284328
}
43294329

4330+
// If the anchor is an unapplied decl ref, there's nothing to extract.
4331+
if (isExpr<DeclRefExpr>(anchor) || isExpr<OverloadedDeclRefExpr>(anchor)) {
4332+
path = path.slice(1);
4333+
continue;
4334+
}
4335+
43304336
break;
43314337

43324338
case ConstraintLocator::AutoclosureResult:

test/decl/var/property_wrappers.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,17 @@ struct SR_10899_Usage {
10111011
@SR_10899_Wrapper var thing: Bool // expected-error{{property type 'Bool' does not match 'wrappedValue' type 'String'}}
10121012
}
10131013

1014+
// https://bugs.swift.org/browse/SR-14730
1015+
@propertyWrapper
1016+
struct StringWrappedValue {
1017+
var wrappedValue: String
1018+
}
1019+
1020+
struct SR_14730 {
1021+
// expected-error@+1 {{property type '() -> String' does not match 'wrappedValue' type 'String'}}
1022+
@StringWrappedValue var value: () -> String
1023+
}
1024+
10141025
// SR-11061 / rdar://problem/52593304 assertion with DeclContext mismatches
10151026
class SomeValue {
10161027
@SomeA(closure: { $0 }) var some: Int = 100

test/type/types.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ var d2 : () -> Int = { 4 }
1616

1717
var d3 : () -> Float = { 4 }
1818

19-
var d4 : () -> Int = { d2 } // expected-error{{function produces expected type 'Int'; did you mean to call it with '()'?}} {{26-26=()}}
19+
var d4 : () -> Int = { d2 } // expected-error{{function 'd2' was used as a property; add () to call it}} {{26-26=()}}
2020

2121
if #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) {
2222
var e0 : [Int]

0 commit comments

Comments
 (0)