Skip to content

Commit a061a96

Browse files
authored
Merge pull request swiftlang#39251 from xedin/classof-for-fixes
[CSFix] Add support for `classof` for all fixes
2 parents b750c37 + 46415cc commit a061a96

File tree

8 files changed

+442
-82
lines changed

8 files changed

+442
-82
lines changed

include/swift/Sema/CSFix.h

Lines changed: 393 additions & 44 deletions
Large diffs are not rendered by default.

lib/Sema/CSBindings.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1871,8 +1871,9 @@ TypeVariableBinding::fixForHole(ConstraintSystem &cs) const {
18711871
// If the whole body is being ignored due to a pre-check failure,
18721872
// let's not record a fix about result type since there is
18731873
// just not enough context to infer it without a body.
1874-
if (cs.hasFixFor(cs.getConstraintLocator(closure),
1875-
FixKind::IgnoreInvalidResultBuilderBody))
1874+
auto *closureLoc = cs.getConstraintLocator(closure);
1875+
if (cs.hasFixFor(closureLoc, FixKind::IgnoreInvalidResultBuilderBody) ||
1876+
cs.hasFixFor(closureLoc, FixKind::IgnoreResultBuilderWithReturnStmts))
18761877
return None;
18771878

18781879
ConstraintFix *fix = SpecifyClosureReturnType::create(cs, dstLocator);

lib/Sema/CSDiagnostics.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7722,7 +7722,7 @@ bool CoercibleOptionalCheckedCastFailure::diagnoseConditionalCastExpr() const {
77227722
return true;
77237723
}
77247724

7725-
bool AlwaysSucceedCheckedCastFailure::diagnoseIfExpr() const {
7725+
bool NoopCheckedCast::diagnoseIfExpr() const {
77267726
auto *expr = getAsExpr<IsExpr>(CastExpr);
77277727
if (!expr)
77287728
return false;
@@ -7731,7 +7731,7 @@ bool AlwaysSucceedCheckedCastFailure::diagnoseIfExpr() const {
77317731
return true;
77327732
}
77337733

7734-
bool AlwaysSucceedCheckedCastFailure::diagnoseConditionalCastExpr() const {
7734+
bool NoopCheckedCast::diagnoseConditionalCastExpr() const {
77357735
auto *expr = getAsExpr<ConditionalCheckedCastExpr>(CastExpr);
77367736
if (!expr)
77377737
return false;
@@ -7741,7 +7741,7 @@ bool AlwaysSucceedCheckedCastFailure::diagnoseConditionalCastExpr() const {
77417741
return true;
77427742
}
77437743

7744-
bool AlwaysSucceedCheckedCastFailure::diagnoseForcedCastExpr() const {
7744+
bool NoopCheckedCast::diagnoseForcedCastExpr() const {
77457745
auto *expr = getAsExpr<ForcedCheckedCastExpr>(CastExpr);
77467746
if (!expr)
77477747
return false;
@@ -7766,7 +7766,7 @@ bool AlwaysSucceedCheckedCastFailure::diagnoseForcedCastExpr() const {
77667766
return true;
77677767
}
77687768

7769-
bool AlwaysSucceedCheckedCastFailure::diagnoseAsError() {
7769+
bool NoopCheckedCast::diagnoseAsError() {
77707770
if (diagnoseIfExpr())
77717771
return true;
77727772

lib/Sema/CSDiagnostics.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2537,11 +2537,10 @@ class CoercibleOptionalCheckedCastFailure final
25372537

25382538
/// Warn situations where the compiler can statically know a runtime
25392539
/// checked cast always succeed.
2540-
class AlwaysSucceedCheckedCastFailure final : public CheckedCastBaseFailure {
2540+
class NoopCheckedCast final : public CheckedCastBaseFailure {
25412541
public:
2542-
AlwaysSucceedCheckedCastFailure(const Solution &solution, Type fromType,
2543-
Type toType, CheckedCastKind kind,
2544-
ConstraintLocator *locator)
2542+
NoopCheckedCast(const Solution &solution, Type fromType, Type toType,
2543+
CheckedCastKind kind, ConstraintLocator *locator)
25452544
: CheckedCastBaseFailure(solution, fromType, toType, kind, locator) {}
25462545

25472546
bool diagnoseAsError() override;

lib/Sema/CSFix.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1920,19 +1920,19 @@ bool AllowCheckedCastCoercibleOptionalType::diagnose(const Solution &solution,
19201920
return failure.diagnose(asNote);
19211921
}
19221922

1923-
AllowAlwaysSucceedCheckedCast *
1924-
AllowAlwaysSucceedCheckedCast::create(ConstraintSystem &cs, Type fromType,
1925-
Type toType, CheckedCastKind kind,
1926-
ConstraintLocator *locator) {
1923+
AllowNoopCheckedCast *AllowNoopCheckedCast::create(ConstraintSystem &cs,
1924+
Type fromType, Type toType,
1925+
CheckedCastKind kind,
1926+
ConstraintLocator *locator) {
19271927
return new (cs.getAllocator())
1928-
AllowAlwaysSucceedCheckedCast(cs, fromType, toType, kind, locator);
1928+
AllowNoopCheckedCast(cs, fromType, toType, kind, locator);
19291929
}
19301930

1931-
bool AllowAlwaysSucceedCheckedCast::diagnose(const Solution &solution,
1932-
bool asNote) const {
1933-
AlwaysSucceedCheckedCastFailure failure(solution, getFromType(), getToType(),
1934-
CastKind, getLocator());
1935-
return failure.diagnose(asNote);
1931+
bool AllowNoopCheckedCast::diagnose(const Solution &solution,
1932+
bool asNote) const {
1933+
NoopCheckedCast warning(solution, getFromType(), getToType(), CastKind,
1934+
getLocator());
1935+
return warning.diagnose(asNote);
19361936
}
19371937

19381938
// Although function types maybe compile-time convertible because

lib/Sema/CSSimplify.cpp

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4596,12 +4596,12 @@ bool ConstraintSystem::repairFailures(
45964596
return true;
45974597

45984598
// If we could record a generic arguments mismatch instead of this fix,
4599-
// don't record a ContextualMismatch here.
4599+
// don't record a contextual type mismatch here.
46004600
if (hasConversionOrRestriction(ConversionRestrictionKind::DeepEquality))
46014601
break;
46024602

4603-
auto *fix = ContextualMismatch::create(*this, lhs, rhs,
4604-
getConstraintLocator(locator));
4603+
auto *fix = IgnoreContextualType::create(*this, lhs, rhs,
4604+
getConstraintLocator(locator));
46054605
conversionsOrFixes.push_back(fix);
46064606
break;
46074607
}
@@ -4940,7 +4940,7 @@ bool ConstraintSystem::repairFailures(
49404940
if (contextualType->isEqual(rhs)) {
49414941
auto *loc = getConstraintLocator(
49424942
anchor, LocatorPathElt::ContextualType(purpose));
4943-
if (hasFixFor(loc, FixKind::ContextualMismatch))
4943+
if (hasFixFor(loc, FixKind::IgnoreContextualType))
49444944
return true;
49454945

49464946
if (contextualType->isVoid() && purpose == CTP_ReturnStmt) {
@@ -4949,7 +4949,7 @@ bool ConstraintSystem::repairFailures(
49494949
}
49504950

49514951
conversionsOrFixes.push_back(
4952-
ContextualMismatch::create(*this, lhs, rhs, loc));
4952+
IgnoreContextualType::create(*this, lhs, rhs, loc));
49534953
break;
49544954
}
49554955
}
@@ -6708,9 +6708,9 @@ static ConstraintFix *maybeWarnAboutExtraneousCast(
67086708

67096709
// Always succeed
67106710
if (isCastToExpressibleByNilLiteral(cs, origFromType, toType)) {
6711-
return AllowAlwaysSucceedCheckedCast::create(
6712-
cs, fromType, toType, CheckedCastKind::Coercion,
6713-
cs.getConstraintLocator(locator));
6711+
return AllowNoopCheckedCast::create(cs, fromType, toType,
6712+
CheckedCastKind::Coercion,
6713+
cs.getConstraintLocator(locator));
67146714
}
67156715

67166716
// If both original are metatypes we have to use them because most of the
@@ -6745,10 +6745,9 @@ static ConstraintFix *maybeWarnAboutExtraneousCast(
67456745
cs, origFromType, origToType, castKind,
67466746
cs.getConstraintLocator(locator));
67476747
} else {
6748-
// No optionals, just a trivial cast that always succeed.
6749-
return AllowAlwaysSucceedCheckedCast::create(
6750-
cs, origFromType, origToType, castKind,
6751-
cs.getConstraintLocator(locator));
6748+
// No optionals, just a trivial cast that always succeeds.
6749+
return AllowNoopCheckedCast::create(cs, origFromType, origToType, castKind,
6750+
cs.getConstraintLocator(locator));
67526751
}
67536752
}
67546753

@@ -11583,16 +11582,19 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
1158311582
case FixKind::SpecifyLabelToAssociateTrailingClosure:
1158411583
case FixKind::AllowKeyPathWithoutComponents:
1158511584
case FixKind::IgnoreInvalidResultBuilderBody:
11585+
case FixKind::IgnoreResultBuilderWithReturnStmts:
1158611586
case FixKind::SpecifyContextualTypeForNil:
1158711587
case FixKind::AllowRefToInvalidDecl:
1158811588
case FixKind::SpecifyBaseTypeForOptionalUnresolvedMember:
1158911589
case FixKind::AllowCheckedCastCoercibleOptionalType:
11590+
case FixKind::AllowNoopCheckedCast:
1159011591
case FixKind::AllowUnsupportedRuntimeCheckedCast:
11591-
case FixKind::AllowAlwaysSucceedCheckedCast:
1159211592
case FixKind::AllowInvalidStaticMemberRefOnProtocolMetatype:
1159311593
case FixKind::AllowWrappedValueMismatch:
1159411594
case FixKind::RemoveExtraneousArguments:
11595-
case FixKind::SpecifyTypeForPlaceholder: {
11595+
case FixKind::SpecifyTypeForPlaceholder:
11596+
case FixKind::AllowAutoClosurePointerConversion:
11597+
case FixKind::IgnoreKeyPathContextualMismatch: {
1159611598
return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
1159711599
}
1159811600

@@ -11713,7 +11715,11 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
1171311715
return matchTypes(*elemTy, dictionaryKeyTy, kind, subflags, elemLoc);
1171411716
}
1171511717

11716-
case FixKind::ContextualMismatch: {
11718+
case FixKind::ContextualMismatch:
11719+
case FixKind::IgnoreContextualType:
11720+
case FixKind::IgnoreAssignmentDestinationType:
11721+
case FixKind::AllowConversionThroughInOut:
11722+
case FixKind::IgnoreCollectionElementContextualMismatch: {
1171711723
auto impact = 1;
1171811724

1171911725
auto locator = fix->getLocator();
@@ -11793,6 +11799,9 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
1179311799
case FixKind::SpecifyClosureParameterType:
1179411800
case FixKind::SpecifyClosureReturnType:
1179511801
case FixKind::AddQualifierToAccessTopLevelName:
11802+
case FixKind::AddSendableAttribute:
11803+
case FixKind::DropThrowsAttribute:
11804+
case FixKind::DropAsyncAttribute:
1179611805
llvm_unreachable("handled elsewhere");
1179711806
}
1179811807

lib/Sema/ConstraintSystem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3885,7 +3885,7 @@ static bool diagnoseContextualFunctionCallGenericAmbiguity(
38853885
if (fixLocator->isForContextualType())
38863886
return true;
38873887

3888-
if (!(fix.second->getKind() == FixKind::ContextualMismatch ||
3888+
if (!(fix.second->getKind() == FixKind::IgnoreContextualType ||
38893889
fix.second->getKind() == FixKind::AllowTupleTypeMismatch))
38903890
return false;
38913891

test/Constraints/without_actually_escaping.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,10 @@ func rethrowThroughWAE(_ zz: (Int, Int, Int) throws -> Int, _ value: Int) throws
6060
}
6161
}
6262

63-
let _: ((Int) -> Int, (@escaping (Int) -> Int) -> ()) -> ()
64-
= withoutActuallyEscaping(_:do:) // expected-error{{}}
63+
// There should be two errors - here one for async -> sync, and another throws -> non-throws
64+
let _: ((Int) -> Int, (@escaping (Int) -> Int) -> ()) -> () = withoutActuallyEscaping(_:do:)
65+
// expected-error@-1 {{invalid conversion from throwing function of type '((Int) -> Int, (@escaping (Int) -> Int) async throws -> ()) async throws -> ()' to non-throwing function type '((Int) -> Int, (@escaping (Int) -> Int) -> ()) -> ()'}}
66+
// expected-error@-2 {{invalid conversion from 'async' function of type '((Int) -> Int, (@escaping (Int) -> Int) async throws -> ()) async throws -> ()' to synchronous function type '((Int) -> Int, (@escaping (Int) -> Int) -> ()) -> ()'}}
6567

6668

6769
// Failing to propagate @noescape into non-single-expression

0 commit comments

Comments
 (0)