Skip to content

Commit f9dae94

Browse files
committed
[CSFix] Add fix to track invalid @autoclosure forwarding
1 parent ab37099 commit f9dae94

File tree

3 files changed

+48
-5
lines changed

3 files changed

+48
-5
lines changed

lib/Sema/CSFix.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,12 @@ ContextualMismatch *ContextualMismatch::create(ConstraintSystem &cs, Type lhs,
202202
ConstraintLocator *locator) {
203203
return new (cs.getAllocator()) ContextualMismatch(cs, lhs, rhs, locator);
204204
}
205+
206+
bool AutoClosureForwarding::diagnose(Expr *root, bool asNote) const {
207+
return false;
208+
}
209+
210+
AutoClosureForwarding *AutoClosureForwarding::create(ConstraintSystem &cs,
211+
ConstraintLocator *locator) {
212+
return new (cs.getAllocator()) AutoClosureForwarding(cs, locator);
213+
}

lib/Sema/CSFix.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ enum class FixKind : uint8_t {
8383
/// Fix up one of the sides of conversion to make it seem
8484
/// like the types are aligned.
8585
ContextualMismatch,
86+
87+
/// Fix up @autoclosure argument to the @autoclosure parameter,
88+
/// to for a call to be able to foward it properly, since
89+
/// @autoclosure conversions are unsupported starting from
90+
/// Swift version 5.
91+
AutoClosureForwarding,
8692
};
8793

8894
class ConstraintFix {
@@ -379,6 +385,29 @@ class ContextualMismatch : public ConstraintFix {
379385
ConstraintLocator *locator);
380386
};
381387

388+
/// Detect situations when argument of the @autoclosure parameter is itself
389+
/// marked as @autoclosure and is not applied. Form a fix which suggests a
390+
/// proper way to forward such arguments, e.g.:
391+
///
392+
/// ```swift
393+
/// func foo(_ fn: @autoclosure () -> Int) {}
394+
/// func bar(_ fn: @autoclosure () -> Int) {
395+
/// foo(fn) // error - fn should be called
396+
/// }
397+
/// ```
398+
class AutoClosureForwarding final : public ConstraintFix {
399+
public:
400+
AutoClosureForwarding(ConstraintSystem &cs, ConstraintLocator *locator)
401+
: ConstraintFix(cs, FixKind::AutoClosureForwarding, locator) {}
402+
403+
std::string getName() const override { return "fix @autoclosure forwarding"; }
404+
405+
bool diagnose(Expr *root, bool asNote = false) const override;
406+
407+
static AutoClosureForwarding *create(ConstraintSystem &cs,
408+
ConstraintLocator *locator);
409+
};
410+
382411
} // end namespace constraints
383412
} // end namespace swift
384413

lib/Sema/CSSimplify.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -895,11 +895,15 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
895895
// is itself `@autoclosure` function type in Swift < 5,
896896
// let's fix that up by making it look like argument is
897897
// called implicitly.
898-
if (!cs.getASTContext().isSwiftVersionAtLeast(5)) {
899-
if (param.isAutoClosure() &&
900-
isAutoClosureArg(locator.getAnchor(), argIdx)) {
901-
argTy = argTy->castTo<FunctionType>()->getResult();
902-
cs.increaseScore(SK_FunctionConversion);
898+
if (param.isAutoClosure() &&
899+
isAutoClosureArg(locator.getAnchor(), argIdx)) {
900+
argTy = argTy->castTo<FunctionType>()->getResult();
901+
cs.increaseScore(SK_FunctionConversion);
902+
903+
if (cs.getASTContext().isSwiftVersionAtLeast(5)) {
904+
auto *fixLoc = cs.getConstraintLocator(loc);
905+
if (cs.recordFix(AutoClosureForwarding::create(cs, fixLoc)))
906+
return cs.getTypeMatchFailure(loc);
903907
}
904908
}
905909

@@ -5431,6 +5435,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
54315435
case FixKind::CoerceToCheckedCast:
54325436
case FixKind::RelabelArguments:
54335437
case FixKind::AddConformance:
5438+
case FixKind::AutoClosureForwarding:
54345439
llvm_unreachable("handled elsewhere");
54355440
}
54365441

0 commit comments

Comments
 (0)