Skip to content

Commit 8ccaad3

Browse files
authored
Merge pull request #59975 from DougGregor/cleanup-fix-behavior
Cleanup after recent refactoring for fix behaviors
2 parents 732078b + db14ab1 commit 8ccaad3

File tree

6 files changed

+119
-82
lines changed

6 files changed

+119
-82
lines changed

include/swift/Sema/CSFix.h

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -411,10 +411,10 @@ class ConstraintFix {
411411
FixKind Kind;
412412
ConstraintLocator *Locator;
413413

414+
public:
414415
/// The behavior limit to apply to the diagnostics emitted.
415-
FixBehavior fixBehavior;
416+
const FixBehavior fixBehavior;
416417

417-
public:
418418
ConstraintFix(ConstraintSystem &cs, FixKind kind, ConstraintLocator *locator,
419419
FixBehavior fixBehavior = FixBehavior::Error)
420420
: CS(cs), Kind(kind), Locator(locator), fixBehavior(fixBehavior) {}
@@ -428,27 +428,22 @@ class ConstraintFix {
428428

429429
FixKind getKind() const { return Kind; }
430430

431-
/// Whether it is still possible to "apply" a solution containing this kind
432-
/// of fix to get a usable AST.
433-
bool canApplySolution() const {
431+
/// Whether this fix fatal for the constraint solver, meaning that it cannot
432+
/// produce a usable type-checked AST.
433+
bool isFatal() const {
434434
switch (fixBehavior) {
435435
case FixBehavior::AlwaysWarning:
436436
case FixBehavior::DowngradeToWarning:
437437
case FixBehavior::Suppress:
438-
return true;
438+
return false;
439439

440440
case FixBehavior::Error:
441-
return false;
441+
return true;
442442
}
443443
}
444444

445-
/// Whether this kind of fix affects the solution score, and which score
446-
/// it affects.
447-
Optional<ScoreKind> affectsSolutionScore() const;
448-
449-
/// The diagnostic behavior limit that will be applied to any emitted
450-
/// diagnostics.
451-
FixBehavior diagfixBehavior() const { return fixBehavior; }
445+
/// Determine the impact of this fix on the solution score, if any.
446+
Optional<ScoreKind> impact() const;
452447

453448
virtual std::string getName() const = 0;
454449

@@ -804,6 +799,16 @@ class MarkGlobalActorFunction final : public ContextualMismatch {
804799
Type rhs, ConstraintLocator *locator,
805800
FixBehavior fixBehavior);
806801

802+
/// Try to apply this fix to the given types.
803+
///
804+
/// \returns \c true if the fix cannot be applied and the solver must fail,
805+
/// or \c false if the fix has been applied and the solver can continue.
806+
static bool attempt(ConstraintSystem &cs,
807+
ConstraintKind constraintKind,
808+
FunctionType *fromType,
809+
FunctionType *toType,
810+
ConstraintLocatorBuilder locator);
811+
807812
static bool classof(ConstraintFix *fix) {
808813
return fix->getKind() == FixKind::MarkGlobalActorFunction;
809814
}
@@ -855,6 +860,16 @@ class AddSendableAttribute final : public ContextualMismatch {
855860
ConstraintLocator *locator,
856861
FixBehavior fixBehavior);
857862

863+
/// Try to apply this fix to the given types.
864+
///
865+
/// \returns \c true if the fix cannot be applied and the solver must fail,
866+
/// or \c false if the fix has been applied and the solver can continue.
867+
static bool attempt(ConstraintSystem &cs,
868+
ConstraintKind constraintKind,
869+
FunctionType *fromType,
870+
FunctionType *toType,
871+
ConstraintLocatorBuilder locator);
872+
858873
static bool classof(ConstraintFix *fix) {
859874
return fix->getKind() == FixKind::AddSendableAttribute;
860875
}

include/swift/Sema/ConstraintSystem.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3820,6 +3820,10 @@ class ConstraintSystem {
38203820
});
38213821
}
38223822

3823+
/// Determine whether the callee for the given locator is marked as
3824+
/// `@preconcurrency`.
3825+
bool hasPreconcurrencyCallee(ConstraintLocatorBuilder locator);
3826+
38233827
/// Determine whether the given declaration is unavailable from the
38243828
/// current context.
38253829
bool isDeclUnavailable(const Decl *D,

lib/Sema/CSApply.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8483,7 +8483,7 @@ bool ConstraintSystem::applySolutionFixes(const Solution &solution) {
84838483

84848484
auto diagnosed =
84858485
primaryFix->coalesceAndDiagnose(solution, secondaryFixes);
8486-
if (primaryFix->canApplySolution()) {
8486+
if (!primaryFix->isFatal()) {
84878487
assert(diagnosed && "warnings should always be diagnosed");
84888488
(void)diagnosed;
84898489
} else {
@@ -9143,9 +9143,9 @@ Optional<SolutionApplicationTarget> ConstraintSystem::applySolution(
91439143
bool diagnosedErrorsViaFixes = applySolutionFixes(solution);
91449144
bool canApplySolution = true;
91459145
for (const auto fix : solution.Fixes) {
9146-
if (!fix->canApplySolution())
9146+
if (fix->isFatal())
91479147
canApplySolution = false;
9148-
if (fix->affectsSolutionScore() == SK_Fix && fix->canApplySolution())
9148+
if (fix->impact() == SK_Fix && !fix->isFatal())
91499149
++numResolvableFixes;
91509150
}
91519151

lib/Sema/CSFix.cpp

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
//===----------------------------------------------------------------------===//
1818

1919
#include "CSDiagnostics.h"
20+
#include "TypeCheckConcurrency.h"
2021
#include "swift/AST/Expr.h"
2122
#include "swift/AST/ParameterList.h"
2223
#include "swift/AST/Type.h"
@@ -37,7 +38,7 @@ using namespace constraints;
3738

3839
ConstraintFix::~ConstraintFix() {}
3940

40-
Optional<ScoreKind> ConstraintFix::affectsSolutionScore() const {
41+
Optional<ScoreKind> ConstraintFix::impact() const {
4142
switch (fixBehavior) {
4243
case FixBehavior::AlwaysWarning:
4344
return None;
@@ -243,10 +244,42 @@ MarkExplicitlyEscaping::create(ConstraintSystem &cs, Type lhs, Type rhs,
243244
bool MarkGlobalActorFunction::diagnose(const Solution &solution,
244245
bool asNote) const {
245246
DroppedGlobalActorFunctionAttr failure(
246-
solution, getFromType(), getToType(), getLocator(), diagfixBehavior());
247+
solution, getFromType(), getToType(), getLocator(), fixBehavior);
247248
return failure.diagnose(asNote);
248249
}
249250

251+
/// The fix behavior to apply to a concurrency-related diagnostic.
252+
static Optional<FixBehavior>
253+
getConcurrencyFixBehavior(
254+
ConstraintSystem &cs, ConstraintKind constraintKind,
255+
ConstraintLocatorBuilder locator, bool forSendable) {
256+
// We can only handle the downgrade for conversions.
257+
switch (constraintKind) {
258+
case ConstraintKind::Conversion:
259+
case ConstraintKind::ArgumentConversion:
260+
break;
261+
262+
default:
263+
if (!cs.shouldAttemptFixes())
264+
return None;
265+
266+
return FixBehavior::Error;
267+
}
268+
269+
// For a @preconcurrency callee outside of a strict concurrency
270+
// context, ignore.
271+
if (cs.hasPreconcurrencyCallee(locator) &&
272+
!contextRequiresStrictConcurrencyChecking(
273+
cs.DC, GetClosureType{cs}, ClosureIsolatedByPreconcurrency{cs}))
274+
return FixBehavior::Suppress;
275+
276+
// Otherwise, warn until Swift 6.
277+
if (!cs.getASTContext().LangOpts.isSwiftVersionAtLeast(6))
278+
return FixBehavior::DowngradeToWarning;
279+
280+
return FixBehavior::Error;
281+
}
282+
250283
MarkGlobalActorFunction *
251284
MarkGlobalActorFunction::create(ConstraintSystem &cs, Type lhs, Type rhs,
252285
ConstraintLocator *locator,
@@ -259,11 +292,28 @@ MarkGlobalActorFunction::create(ConstraintSystem &cs, Type lhs, Type rhs,
259292
cs, lhs, rhs, locator, fixBehavior);
260293
}
261294

295+
bool MarkGlobalActorFunction::attempt(ConstraintSystem &cs,
296+
ConstraintKind constraintKind,
297+
FunctionType *fromType,
298+
FunctionType *toType,
299+
ConstraintLocatorBuilder locator) {
300+
auto fixBehavior = getConcurrencyFixBehavior(
301+
cs, constraintKind, locator, /*forSendable=*/false);
302+
if (!fixBehavior)
303+
return true;
304+
305+
auto *fix = MarkGlobalActorFunction::create(
306+
cs, fromType, toType, cs.getConstraintLocator(locator),
307+
*fixBehavior);
308+
309+
return cs.recordFix(fix);
310+
}
311+
262312
bool AddSendableAttribute::diagnose(const Solution &solution,
263313
bool asNote) const {
264314
AttributedFuncToTypeConversionFailure failure(
265315
solution, getFromType(), getToType(), getLocator(),
266-
AttributedFuncToTypeConversionFailure::Concurrent, diagfixBehavior());
316+
AttributedFuncToTypeConversionFailure::Concurrent, fixBehavior);
267317
return failure.diagnose(asNote);
268318
}
269319

@@ -280,6 +330,22 @@ AddSendableAttribute::create(ConstraintSystem &cs,
280330
return new (cs.getAllocator()) AddSendableAttribute(
281331
cs, fromType, toType, locator, fixBehavior);
282332
}
333+
334+
bool AddSendableAttribute::attempt(ConstraintSystem &cs,
335+
ConstraintKind constraintKind,
336+
FunctionType *fromType,
337+
FunctionType *toType,
338+
ConstraintLocatorBuilder locator) {
339+
auto fixBehavior = getConcurrencyFixBehavior(
340+
cs, constraintKind, locator, /*forSendable=*/true);
341+
if (!fixBehavior)
342+
return true;
343+
344+
auto *fix = AddSendableAttribute::create(
345+
cs, fromType, toType, cs.getConstraintLocator(locator), *fixBehavior);
346+
return cs.recordFix(fix);
347+
}
348+
283349
bool RelabelArguments::diagnose(const Solution &solution, bool asNote) const {
284350
LabelingFailure failure(solution, getLocator(), getLabels());
285351
return failure.diagnose(asNote);
@@ -1639,7 +1705,7 @@ bool TreatEphemeralAsNonEphemeral::diagnose(const Solution &solution,
16391705
bool asNote) const {
16401706
NonEphemeralConversionFailure failure(solution, getLocator(), getFromType(),
16411707
getToType(), ConversionKind,
1642-
diagfixBehavior());
1708+
fixBehavior);
16431709
return failure.diagnose(asNote);
16441710
}
16451711

@@ -2233,7 +2299,7 @@ IgnoreDefaultExprTypeMismatch::create(ConstraintSystem &cs, Type argType,
22332299
bool AddExplicitExistentialCoercion::diagnose(const Solution &solution,
22342300
bool asNote) const {
22352301
MissingExplicitExistentialCoercion failure(solution, ErasedResultType,
2236-
getLocator(), diagfixBehavior());
2302+
getLocator(), fixBehavior);
22372303
return failure.diagnose(asNote);
22382304
}
22392305

lib/Sema/CSSimplify.cpp

Lines changed: 10 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2655,14 +2655,10 @@ static bool fixExtraneousArguments(ConstraintSystem &cs,
26552655
/*impact=*/numExtraneous * 2);
26562656
}
26572657

2658-
bool hasPreconcurrencyCallee(ConstraintSystem *cs,
2659-
ConstraintLocatorBuilder locator) {
2660-
if (cs->getASTContext().isSwiftVersionAtLeast(6))
2661-
// Swift 6 mode does not reduce errors to warnings.
2662-
return false;
2663-
2664-
auto calleeLocator = cs->getCalleeLocator(cs->getConstraintLocator(locator));
2665-
auto calleeOverload = cs->findSelectedOverloadFor(calleeLocator);
2658+
bool ConstraintSystem::hasPreconcurrencyCallee(
2659+
ConstraintLocatorBuilder locator) {
2660+
auto calleeLocator = getCalleeLocator(getConstraintLocator(locator));
2661+
auto calleeOverload = findSelectedOverloadFor(calleeLocator);
26662662
if (!calleeOverload || !calleeOverload->choice.isDecl())
26672663
return false;
26682664

@@ -2716,48 +2712,12 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
27162712
increaseScore(SK_SyncInAsync);
27172713
}
27182714

2719-
/// The behavior limit to apply to a concurrency check.
2720-
auto getConcurrencyFixBehavior = [&](
2721-
bool forSendable
2722-
) -> Optional<FixBehavior> {
2723-
// We can only handle the downgrade for conversions.
2724-
switch (kind) {
2725-
case ConstraintKind::Conversion:
2726-
case ConstraintKind::ArgumentConversion:
2727-
break;
2728-
2729-
default:
2730-
if (!shouldAttemptFixes())
2731-
return None;
2732-
2733-
return FixBehavior::Error;
2734-
}
2735-
2736-
// For a @preconcurrency callee outside of a strict concurrency
2737-
// context, ignore.
2738-
if (hasPreconcurrencyCallee(this, locator) &&
2739-
!contextRequiresStrictConcurrencyChecking(DC, GetClosureType{*this}, ClosureIsolatedByPreconcurrency{*this}))
2740-
return FixBehavior::Suppress;
2741-
2742-
// Otherwise, warn until Swift 6.
2743-
if (!getASTContext().LangOpts.isSwiftVersionAtLeast(6))
2744-
return FixBehavior::DowngradeToWarning;
2745-
2746-
return FixBehavior::Error;
2747-
};
2748-
27492715
// A @Sendable function can be a subtype of a non-@Sendable function.
27502716
if (func1->isSendable() != func2->isSendable()) {
27512717
// Cannot add '@Sendable'.
27522718
if (func2->isSendable() || kind < ConstraintKind::Subtype) {
2753-
if (auto fixBehavior = getConcurrencyFixBehavior(true)) {
2754-
auto *fix = AddSendableAttribute::create(
2755-
*this, func1, func2, getConstraintLocator(locator), *fixBehavior);
2756-
if (recordFix(fix))
2757-
return getTypeMatchFailure(locator);
2758-
} else {
2719+
if (AddSendableAttribute::attempt(*this, kind, func1, func2, locator))
27592720
return getTypeMatchFailure(locator);
2760-
}
27612721
}
27622722
}
27632723

@@ -2785,16 +2745,8 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
27852745
return getTypeMatchFailure(locator);
27862746
} else if (func1->getGlobalActor() && !func2->isAsync()) {
27872747
// Cannot remove a global actor from a synchronous function.
2788-
if (auto fixBehavior = getConcurrencyFixBehavior(false)) {
2789-
auto *fix = MarkGlobalActorFunction::create(
2790-
*this, func1, func2, getConstraintLocator(locator),
2791-
*fixBehavior);
2792-
2793-
if (recordFix(fix))
2794-
return getTypeMatchFailure(locator);
2795-
} else {
2748+
if (MarkGlobalActorFunction::attempt(*this, kind, func1, func2, locator))
27962749
return getTypeMatchFailure(locator);
2797-
}
27982750
} else if (kind < ConstraintKind::Subtype) {
27992751
return getTypeMatchFailure(locator);
28002752
}
@@ -9839,7 +9791,7 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
98399791
auto *inferredClosureType = getClosureType(closure);
98409792

98419793
// Note if this closure is isolated by preconcurrency.
9842-
if (hasPreconcurrencyCallee(this, locator))
9794+
if (hasPreconcurrencyCallee(locator))
98439795
preconcurrencyClosures.insert(closure);
98449796

98459797
// Let's look through all optionals associated with contextual
@@ -12711,8 +12663,8 @@ bool ConstraintSystem::recordFix(ConstraintFix *fix, unsigned impact) {
1271112663
// Record the fix.
1271212664

1271312665
// If this should affect the solution score, do so.
12714-
if (auto scoreKind = fix->affectsSolutionScore())
12715-
increaseScore(*scoreKind, impact);
12666+
if (auto impactScoreKind = fix->impact())
12667+
increaseScore(*impactScoreKind, impact);
1271612668

1271712669
// If we've made the current solution worse than the best solution we've seen
1271812670
// already, stop now.
@@ -12735,7 +12687,7 @@ bool ConstraintSystem::recordFix(ConstraintFix *fix, unsigned impact) {
1273512687
// Fixes that don't affect the score shouldn't be considered because even
1273612688
// if such a fix is recorded at that anchor this should not
1273712689
// have any affect in the recording of any other fix.
12738-
if (!fix->affectsSolutionScore())
12690+
if (!fix->impact())
1273912691
continue;
1274012692

1274112693
anchors.insert(fix->getAnchor());

lib/Sema/ConstraintSystem.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4621,7 +4621,7 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
46214621
// let's diagnose this as regular ambiguity.
46224622
if (llvm::all_of(solutions, [](const Solution &solution) {
46234623
return llvm::all_of(solution.Fixes, [](const ConstraintFix *fix) {
4624-
return fix->canApplySolution();
4624+
return !fix->isFatal();
46254625
});
46264626
})) {
46274627
return diagnoseAmbiguity(solutions);
@@ -4643,7 +4643,7 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
46434643
// source of ambiguity or failures.
46444644
// Ignore warnings in favor of actual error fixes,
46454645
// because they are not the source of ambiguity/failures.
4646-
if (!fix->affectsSolutionScore())
4646+
if (!fix->impact())
46474647
continue;
46484648

46494649
fixes.insert({&solution, fix});

0 commit comments

Comments
 (0)