Skip to content

Commit eeb3963

Browse files
committed
[Constraint solver] Downgrade/ignore concurrency issues more generally.
Instead of the `warning` Boolean threaded through the solver's diagnostics, thread `DiagnosticBehavior` to be used as the behavior limit. Use this for concurrency checking (specifically dropped `@Sendable` and dropped global actors) so the solver gets more control over these diagnostics. This change restores the diagnostics to a usable state after the prior change, which introduced extra noise. The only change from existing beavior is that dropping a global actor from a function type is now always a warning in Swift < 6. This is partly intentional, because there are some places where dropping the global actor is well-formed.
1 parent f4b75ac commit eeb3963

File tree

8 files changed

+102
-74
lines changed

8 files changed

+102
-74
lines changed

include/swift/Sema/CSFix.h

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -401,14 +401,14 @@ class ConstraintFix {
401401
FixKind Kind;
402402
ConstraintLocator *Locator;
403403

404-
/// Determines whether this fix is simplify a warning which doesn't
405-
/// require immediate source changes.
406-
bool IsWarning;
404+
/// The behavior limit to apply to the diagnostics emitted.
405+
DiagnosticBehavior behaviorLimit;
407406

408407
public:
409408
ConstraintFix(ConstraintSystem &cs, FixKind kind, ConstraintLocator *locator,
410-
bool warning = false)
411-
: CS(cs), Kind(kind), Locator(locator), IsWarning(warning) {}
409+
DiagnosticBehavior behaviorLimit =
410+
DiagnosticBehavior::Unspecified)
411+
: CS(cs), Kind(kind), Locator(locator), behaviorLimit(behaviorLimit) {}
412412

413413
virtual ~ConstraintFix();
414414

@@ -419,7 +419,14 @@ class ConstraintFix {
419419

420420
FixKind getKind() const { return Kind; }
421421

422-
bool isWarning() const { return IsWarning; }
422+
bool isWarning() const {
423+
return behaviorLimit == DiagnosticBehavior::Warning ||
424+
behaviorLimit == DiagnosticBehavior::Ignore;
425+
}
426+
427+
/// The diagnostic behavior limit that will be applied to any emitted
428+
/// diagnostics.
429+
DiagnosticBehavior diagBehaviorLimit() const { return behaviorLimit; }
423430

424431
virtual std::string getName() const = 0;
425432

@@ -664,14 +671,17 @@ class ContextualMismatch : public ConstraintFix {
664671
Type LHS, RHS;
665672

666673
ContextualMismatch(ConstraintSystem &cs, Type lhs, Type rhs,
667-
ConstraintLocator *locator, bool warning)
668-
: ConstraintFix(cs, FixKind::ContextualMismatch, locator, warning),
674+
ConstraintLocator *locator,
675+
DiagnosticBehavior behaviorLimit)
676+
: ConstraintFix(cs, FixKind::ContextualMismatch, locator, behaviorLimit),
669677
LHS(lhs), RHS(rhs) {}
670678

671679
protected:
672680
ContextualMismatch(ConstraintSystem &cs, FixKind kind, Type lhs, Type rhs,
673-
ConstraintLocator *locator, bool warning = false)
674-
: ConstraintFix(cs, kind, locator, warning), LHS(lhs), RHS(rhs) {}
681+
ConstraintLocator *locator,
682+
DiagnosticBehavior behaviorLimit =
683+
DiagnosticBehavior::Unspecified)
684+
: ConstraintFix(cs, kind, locator, behaviorLimit), LHS(lhs), RHS(rhs) {}
675685

676686
public:
677687
std::string getName() const override { return "fix contextual mismatch"; }
@@ -755,9 +765,10 @@ class MarkExplicitlyEscaping final : public ContextualMismatch {
755765
/// Mark function type as being part of a global actor.
756766
class MarkGlobalActorFunction final : public ContextualMismatch {
757767
MarkGlobalActorFunction(ConstraintSystem &cs, Type lhs, Type rhs,
758-
ConstraintLocator *locator, bool warning)
768+
ConstraintLocator *locator,
769+
DiagnosticBehavior behaviorLimit)
759770
: ContextualMismatch(cs, FixKind::MarkGlobalActorFunction, lhs, rhs,
760-
locator, warning) {
771+
locator, behaviorLimit) {
761772
}
762773

763774
public:
@@ -767,7 +778,7 @@ class MarkGlobalActorFunction final : public ContextualMismatch {
767778

768779
static MarkGlobalActorFunction *create(ConstraintSystem &cs, Type lhs,
769780
Type rhs, ConstraintLocator *locator,
770-
bool warning);
781+
DiagnosticBehavior behaviorLimit);
771782

772783
static bool classof(ConstraintFix *fix) {
773784
return fix->getKind() == FixKind::MarkGlobalActorFunction;
@@ -803,9 +814,9 @@ class ForceOptional final : public ContextualMismatch {
803814
class AddSendableAttribute final : public ContextualMismatch {
804815
AddSendableAttribute(ConstraintSystem &cs, FunctionType *fromType,
805816
FunctionType *toType, ConstraintLocator *locator,
806-
bool warning)
817+
DiagnosticBehavior behaviorLimit)
807818
: ContextualMismatch(cs, FixKind::AddSendableAttribute, fromType, toType,
808-
locator, warning) {
819+
locator, behaviorLimit) {
809820
assert(fromType->isSendable() != toType->isSendable());
810821
}
811822

@@ -818,7 +829,7 @@ class AddSendableAttribute final : public ContextualMismatch {
818829
FunctionType *fromType,
819830
FunctionType *toType,
820831
ConstraintLocator *locator,
821-
bool warning);
832+
DiagnosticBehavior behaviorLimit);
822833

823834
static bool classof(ConstraintFix *fix) {
824835
return fix->getKind() == FixKind::AddSendableAttribute;
@@ -1384,7 +1395,8 @@ class AllowInvalidPartialApplication final : public ConstraintFix {
13841395
AllowInvalidPartialApplication(bool isWarning, ConstraintSystem &cs,
13851396
ConstraintLocator *locator)
13861397
: ConstraintFix(cs, FixKind::AllowInvalidPartialApplication, locator,
1387-
isWarning) {}
1398+
isWarning ? DiagnosticBehavior::Warning
1399+
: DiagnosticBehavior::Unspecified) {}
13881400

13891401
public:
13901402
std::string getName() const override {
@@ -2118,8 +2130,10 @@ class AllowArgumentMismatch : public ContextualMismatch {
21182130

21192131
AllowArgumentMismatch(ConstraintSystem &cs, FixKind kind, Type argType,
21202132
Type paramType, ConstraintLocator *locator,
2121-
bool warning = false)
2122-
: ContextualMismatch(cs, kind, argType, paramType, locator, warning) {}
2133+
DiagnosticBehavior behaviorLimit =
2134+
DiagnosticBehavior::Unspecified)
2135+
: ContextualMismatch(
2136+
cs, kind, argType, paramType, locator, behaviorLimit) {}
21232137

21242138
public:
21252139
std::string getName() const override {
@@ -2267,9 +2281,9 @@ class TreatEphemeralAsNonEphemeral final : public AllowArgumentMismatch {
22672281
TreatEphemeralAsNonEphemeral(ConstraintSystem &cs, ConstraintLocator *locator,
22682282
Type srcType, Type dstType,
22692283
ConversionRestrictionKind conversionKind,
2270-
bool downgradeToWarning)
2284+
DiagnosticBehavior behaviorLimit)
22712285
: AllowArgumentMismatch(cs, FixKind::TreatEphemeralAsNonEphemeral,
2272-
srcType, dstType, locator, downgradeToWarning),
2286+
srcType, dstType, locator, behaviorLimit),
22732287
ConversionKind(conversionKind) {}
22742288

22752289
public:
@@ -2433,7 +2447,7 @@ class AllowCoercionToForceCast final : public ContextualMismatch {
24332447
AllowCoercionToForceCast(ConstraintSystem &cs, Type fromType, Type toType,
24342448
ConstraintLocator *locator)
24352449
: ContextualMismatch(cs, FixKind::AllowCoercionToForceCast, fromType,
2436-
toType, locator, /*warning*/ true) {}
2450+
toType, locator, DiagnosticBehavior::Warning) {}
24372451

24382452
public:
24392453
std::string getName() const override {
@@ -2547,7 +2561,7 @@ class SpecifyLabelToAssociateTrailingClosure final : public ConstraintFix {
25472561
SpecifyLabelToAssociateTrailingClosure(ConstraintSystem &cs,
25482562
ConstraintLocator *locator)
25492563
: ConstraintFix(cs, FixKind::SpecifyLabelToAssociateTrailingClosure,
2550-
locator, /*isWarning=*/true) {}
2564+
locator, DiagnosticBehavior::Warning) {}
25512565

25522566
public:
25532567
std::string getName() const override {
@@ -2717,7 +2731,7 @@ class SpecifyBaseTypeForOptionalUnresolvedMember final : public ConstraintFix {
27172731
DeclNameRef memberName,
27182732
ConstraintLocator *locator)
27192733
: ConstraintFix(cs, FixKind::SpecifyBaseTypeForOptionalUnresolvedMember,
2720-
locator, /*isWarning=*/true),
2734+
locator, DiagnosticBehavior::Warning),
27212735
MemberName(memberName) {}
27222736
DeclNameRef MemberName;
27232737

@@ -2748,7 +2762,7 @@ class CheckedCastContextualMismatchWarning : public ContextualMismatch {
27482762
CheckedCastKind kind,
27492763
ConstraintLocator *locator)
27502764
: ContextualMismatch(cs, fixKind, fromType, toType, locator,
2751-
/*isWarning*/ true),
2765+
DiagnosticBehavior::Warning),
27522766
CastKind(kind) {}
27532767
CheckedCastKind CastKind;
27542768
};
@@ -2859,7 +2873,7 @@ class AllowTupleLabelMismatch final : public ContextualMismatch {
28592873
AllowTupleLabelMismatch(ConstraintSystem &cs, Type fromType, Type toType,
28602874
ConstraintLocator *locator)
28612875
: ContextualMismatch(cs, FixKind::AllowTupleLabelMismatch, fromType,
2862-
toType, locator, /*warning*/ true) {}
2876+
toType, locator, DiagnosticBehavior::Warning) {}
28632877

28642878
public:
28652879
std::string getName() const override { return "allow tuple label mismatch"; }

lib/Sema/CSDiagnostics.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,8 @@ template <typename... ArgTypes>
103103
InFlightDiagnostic
104104
FailureDiagnostic::emitDiagnosticAt(ArgTypes &&... Args) const {
105105
auto &DE = getASTContext().Diags;
106-
auto behavior = isWarning ? DiagnosticBehavior::Warning
107-
: DiagnosticBehavior::Unspecified;
108106
return std::move(DE.diagnose(std::forward<ArgTypes>(Args)...)
109-
.limitBehavior(behavior));
107+
.limitBehavior(behaviorLimit));
110108
}
111109

112110
Expr *FailureDiagnostic::findParentExpr(const Expr *subExpr) const {

lib/Sema/CSDiagnostics.h

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,19 @@ class FunctionArgApplyInfo;
4242
class FailureDiagnostic {
4343
const Solution &S;
4444
ConstraintLocator *Locator;
45-
bool isWarning;
45+
DiagnosticBehavior behaviorLimit;
4646

4747
public:
4848
FailureDiagnostic(const Solution &solution, ConstraintLocator *locator,
49-
bool isWarning = false)
50-
: S(solution), Locator(locator), isWarning(isWarning) {}
49+
DiagnosticBehavior behaviorLimit =
50+
DiagnosticBehavior::Unspecified)
51+
: S(solution), Locator(locator), behaviorLimit(behaviorLimit) {}
5152

5253
FailureDiagnostic(const Solution &solution, ASTNode anchor,
53-
bool isWarning = false)
54+
DiagnosticBehavior behaviorLimit =
55+
DiagnosticBehavior::Unspecified)
5456
: FailureDiagnostic(solution, solution.getConstraintLocator(anchor),
55-
isWarning) { }
57+
behaviorLimit) { }
5658

5759
virtual ~FailureDiagnostic();
5860

@@ -605,20 +607,23 @@ class ContextualFailure : public FailureDiagnostic {
605607

606608
public:
607609
ContextualFailure(const Solution &solution, Type lhs, Type rhs,
608-
ConstraintLocator *locator, bool isWarning = false)
610+
ConstraintLocator *locator,
611+
DiagnosticBehavior behaviorLimit =
612+
DiagnosticBehavior::Unspecified)
609613
: ContextualFailure(
610614
solution,
611615
locator->isForContextualType()
612616
? locator->castLastElementTo<LocatorPathElt::ContextualType>()
613617
.getPurpose()
614618
: solution.getConstraintSystem().getContextualTypePurpose(
615619
locator->getAnchor()),
616-
lhs, rhs, locator, isWarning) {}
620+
lhs, rhs, locator, behaviorLimit) {}
617621

618622
ContextualFailure(const Solution &solution, ContextualTypePurpose purpose,
619623
Type lhs, Type rhs, ConstraintLocator *locator,
620-
bool isWarning = false)
621-
: FailureDiagnostic(solution, locator, isWarning), CTP(purpose),
624+
DiagnosticBehavior behaviorLimit =
625+
DiagnosticBehavior::Unspecified)
626+
: FailureDiagnostic(solution, locator, behaviorLimit), CTP(purpose),
622627
RawFromType(lhs), RawToType(rhs) {
623628
assert(lhs && "Expected a valid 'from' type");
624629
assert(rhs && "Expected a valid 'to' type");
@@ -759,8 +764,9 @@ class AttributedFuncToTypeConversionFailure final : public ContextualFailure {
759764
AttributedFuncToTypeConversionFailure(const Solution &solution, Type fromType,
760765
Type toType, ConstraintLocator *locator,
761766
AttributeKind attributeKind,
762-
bool isWarning = false)
763-
: ContextualFailure(solution, fromType, toType, locator, isWarning),
767+
DiagnosticBehavior behaviorLimit =
768+
DiagnosticBehavior::Unspecified)
769+
: ContextualFailure(solution, fromType, toType, locator, behaviorLimit),
764770
attributeKind(attributeKind) {}
765771

766772
bool diagnoseAsError() override;
@@ -784,8 +790,8 @@ class DroppedGlobalActorFunctionAttr final : public ContextualFailure {
784790
public:
785791
DroppedGlobalActorFunctionAttr(const Solution &solution, Type fromType,
786792
Type toType, ConstraintLocator *locator,
787-
bool isWarning)
788-
: ContextualFailure(solution, fromType, toType, locator, isWarning) { }
793+
DiagnosticBehavior behaviorLimit)
794+
: ContextualFailure(solution, fromType, toType, locator, behaviorLimit) { }
789795

790796
bool diagnoseAsError() override;
791797
};
@@ -1955,8 +1961,9 @@ class ArgumentMismatchFailure : public ContextualFailure {
19551961
public:
19561962
ArgumentMismatchFailure(const Solution &solution, Type argType,
19571963
Type paramType, ConstraintLocator *locator,
1958-
bool warning = false)
1959-
: ContextualFailure(solution, argType, paramType, locator, warning),
1964+
DiagnosticBehavior behaviorLimit =
1965+
DiagnosticBehavior::Unspecified)
1966+
: ContextualFailure(solution, argType, paramType, locator, behaviorLimit),
19601967
Info(*getFunctionArgApplyInfo(getLocator())) {}
19611968

19621969
bool diagnoseAsError() override;
@@ -2135,8 +2142,9 @@ class NonEphemeralConversionFailure final : public ArgumentMismatchFailure {
21352142
ConstraintLocator *locator, Type fromType,
21362143
Type toType,
21372144
ConversionRestrictionKind conversionKind,
2138-
bool warning)
2139-
: ArgumentMismatchFailure(solution, fromType, toType, locator, warning),
2145+
DiagnosticBehavior behaviorLimit)
2146+
: ArgumentMismatchFailure(
2147+
solution, fromType, toType, locator, behaviorLimit),
21402148
ConversionKind(conversionKind) {
21412149
}
21422150

lib/Sema/CSFix.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -201,28 +201,29 @@ MarkExplicitlyEscaping::create(ConstraintSystem &cs, Type lhs, Type rhs,
201201
}
202202

203203
bool MarkGlobalActorFunction::diagnose(const Solution &solution,
204-
bool asNote) const {
204+
bool asNote) const {
205205
DroppedGlobalActorFunctionAttr failure(
206-
solution, getFromType(), getToType(), getLocator(), isWarning());
206+
solution, getFromType(), getToType(), getLocator(), diagBehaviorLimit());
207207
return failure.diagnose(asNote);
208208
}
209209

210210
MarkGlobalActorFunction *
211211
MarkGlobalActorFunction::create(ConstraintSystem &cs, Type lhs, Type rhs,
212-
ConstraintLocator *locator, bool warning) {
212+
ConstraintLocator *locator,
213+
DiagnosticBehavior behaviorLimit) {
213214
if (locator->isLastElement<LocatorPathElt::ApplyArgToParam>())
214215
locator = cs.getConstraintLocator(
215216
locator, LocatorPathElt::ArgumentAttribute::forGlobalActor());
216217

217218
return new (cs.getAllocator()) MarkGlobalActorFunction(
218-
cs, lhs, rhs, locator, warning);
219+
cs, lhs, rhs, locator, behaviorLimit);
219220
}
220221

221222
bool AddSendableAttribute::diagnose(const Solution &solution,
222223
bool asNote) const {
223224
AttributedFuncToTypeConversionFailure failure(
224225
solution, getFromType(), getToType(), getLocator(),
225-
AttributedFuncToTypeConversionFailure::Concurrent, isWarning());
226+
AttributedFuncToTypeConversionFailure::Concurrent, diagBehaviorLimit());
226227
return failure.diagnose(asNote);
227228
}
228229

@@ -231,13 +232,13 @@ AddSendableAttribute::create(ConstraintSystem &cs,
231232
FunctionType *fromType,
232233
FunctionType *toType,
233234
ConstraintLocator *locator,
234-
bool warning) {
235+
DiagnosticBehavior behaviorLimit) {
235236
if (locator->isLastElement<LocatorPathElt::ApplyArgToParam>())
236237
locator = cs.getConstraintLocator(
237238
locator, LocatorPathElt::ArgumentAttribute::forConcurrent());
238239

239240
return new (cs.getAllocator()) AddSendableAttribute(
240-
cs, fromType, toType, locator, warning);
241+
cs, fromType, toType, locator, behaviorLimit);
241242
}
242243
bool RelabelArguments::diagnose(const Solution &solution, bool asNote) const {
243244
LabelingFailure failure(solution, getLocator(), getLabels());
@@ -406,7 +407,7 @@ ContextualMismatch *ContextualMismatch::create(ConstraintSystem &cs, Type lhs,
406407
Type rhs,
407408
ConstraintLocator *locator) {
408409
return new (cs.getAllocator()) ContextualMismatch(
409-
cs, lhs, rhs, locator, /*warning=*/false);
410+
cs, lhs, rhs, locator, DiagnosticBehavior::Unspecified);
410411
}
411412

412413
bool AllowWrappedValueMismatch::diagnose(const Solution &solution, bool asError) const {
@@ -1167,7 +1168,7 @@ NotCompileTimeConst::NotCompileTimeConst(ConstraintSystem &cs, Type paramTy,
11671168
ConstraintLocator *locator):
11681169
ContextualMismatch(cs, FixKind::NotCompileTimeConst, paramTy,
11691170
cs.getASTContext().TheEmptyTupleType, locator,
1170-
/*warning*/true) {}
1171+
DiagnosticBehavior::Warning) {}
11711172

11721173
NotCompileTimeConst *
11731174
NotCompileTimeConst::create(ConstraintSystem &cs, Type paramTy,
@@ -1598,7 +1599,7 @@ bool TreatEphemeralAsNonEphemeral::diagnose(const Solution &solution,
15981599
bool asNote) const {
15991600
NonEphemeralConversionFailure failure(solution, getLocator(), getFromType(),
16001601
getToType(), ConversionKind,
1601-
isWarning());
1602+
diagBehaviorLimit());
16021603
return failure.diagnose(asNote);
16031604
}
16041605

@@ -1607,7 +1608,9 @@ TreatEphemeralAsNonEphemeral *TreatEphemeralAsNonEphemeral::create(
16071608
Type dstType, ConversionRestrictionKind conversionKind,
16081609
bool downgradeToWarning) {
16091610
return new (cs.getAllocator()) TreatEphemeralAsNonEphemeral(
1610-
cs, locator, srcType, dstType, conversionKind, downgradeToWarning);
1611+
cs, locator, srcType, dstType, conversionKind,
1612+
downgradeToWarning ? DiagnosticBehavior::Warning
1613+
: DiagnosticBehavior::Unspecified);
16111614
}
16121615

16131616
std::string TreatEphemeralAsNonEphemeral::getName() const {

0 commit comments

Comments
 (0)