Skip to content

[CSFix] Add support for classof for all fixes #39251

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Sep 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
3265042
[CSFix] NFC: Add `classof` implementation to most of the fixes
xedin Sep 10, 2021
1039b76
[CSFix] NFC: Fix code formatting for `SpecifyKeyPathRootType` fix
xedin Sep 10, 2021
057563e
[CSFix] Add a specific kind for `AddSendableAttribute`
xedin Sep 10, 2021
d1d2846
[CSFix] Add a specific kind for `DropThrowsAttribute`
xedin Sep 10, 2021
934e875
[CSFix] Add a specific kind for `DropAsyncAttribute`
xedin Sep 10, 2021
04b35e4
[CSFix] Add a specific kind for `AllowAutoClosurePointerConversion`
xedin Sep 10, 2021
2e5ab93
[CSFix] Add a specific kind for `IgnoreContextualType`
xedin Sep 10, 2021
4f5b33b
[CSFix] Add a specific kind for `IgnoreAssignmentDestinationType`
xedin Sep 10, 2021
48cdb58
[CSFix] Add a specific kind for `AllowInOutConversion`
xedin Sep 10, 2021
152cf0b
[CSFix] Add a specific kind for `IgnoreKeyPathContextualMismatch`
xedin Sep 10, 2021
0f2ee14
[CSFix] Add a specific kind for `CollectionElementContextualMismatch`
xedin Sep 10, 2021
4c84597
[CSFix] Require all sub-classes of `ContextualMismatch` to supply a kind
xedin Sep 10, 2021
0a42548
[CSFix] NFC: Rename fix/diagnostic for checked casts that always succeed
xedin Sep 10, 2021
06a762b
[CSFix] Add a specific kind for `IgnoreResultBuilderWithReturnStmts`
xedin Sep 10, 2021
e512473
[Diagnostics] Use `IgnoreContextualType` fix for mismatches between t…
xedin Sep 10, 2021
150203c
[Diagnostics] Use `IgnoreContextualType` for contextual failures rela…
xedin Sep 11, 2021
46415cc
[TypeChecker] NFC: Update improved `without_actually_escaping` test-case
xedin Sep 11, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
437 changes: 393 additions & 44 deletions include/swift/Sema/CSFix.h

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions lib/Sema/CSBindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1871,8 +1871,9 @@ TypeVariableBinding::fixForHole(ConstraintSystem &cs) const {
// If the whole body is being ignored due to a pre-check failure,
// let's not record a fix about result type since there is
// just not enough context to infer it without a body.
if (cs.hasFixFor(cs.getConstraintLocator(closure),
FixKind::IgnoreInvalidResultBuilderBody))
auto *closureLoc = cs.getConstraintLocator(closure);
if (cs.hasFixFor(closureLoc, FixKind::IgnoreInvalidResultBuilderBody) ||
cs.hasFixFor(closureLoc, FixKind::IgnoreResultBuilderWithReturnStmts))
return None;

ConstraintFix *fix = SpecifyClosureReturnType::create(cs, dstLocator);
Expand Down
8 changes: 4 additions & 4 deletions lib/Sema/CSDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7698,7 +7698,7 @@ bool CoercibleOptionalCheckedCastFailure::diagnoseConditionalCastExpr() const {
return true;
}

bool AlwaysSucceedCheckedCastFailure::diagnoseIfExpr() const {
bool NoopCheckedCast::diagnoseIfExpr() const {
auto *expr = getAsExpr<IsExpr>(CastExpr);
if (!expr)
return false;
Expand All @@ -7707,7 +7707,7 @@ bool AlwaysSucceedCheckedCastFailure::diagnoseIfExpr() const {
return true;
}

bool AlwaysSucceedCheckedCastFailure::diagnoseConditionalCastExpr() const {
bool NoopCheckedCast::diagnoseConditionalCastExpr() const {
auto *expr = getAsExpr<ConditionalCheckedCastExpr>(CastExpr);
if (!expr)
return false;
Expand All @@ -7717,7 +7717,7 @@ bool AlwaysSucceedCheckedCastFailure::diagnoseConditionalCastExpr() const {
return true;
}

bool AlwaysSucceedCheckedCastFailure::diagnoseForcedCastExpr() const {
bool NoopCheckedCast::diagnoseForcedCastExpr() const {
auto *expr = getAsExpr<ForcedCheckedCastExpr>(CastExpr);
if (!expr)
return false;
Expand All @@ -7742,7 +7742,7 @@ bool AlwaysSucceedCheckedCastFailure::diagnoseForcedCastExpr() const {
return true;
}

bool AlwaysSucceedCheckedCastFailure::diagnoseAsError() {
bool NoopCheckedCast::diagnoseAsError() {
if (diagnoseIfExpr())
return true;

Expand Down
7 changes: 3 additions & 4 deletions lib/Sema/CSDiagnostics.h
Original file line number Diff line number Diff line change
Expand Up @@ -2537,11 +2537,10 @@ class CoercibleOptionalCheckedCastFailure final

/// Warn situations where the compiler can statically know a runtime
/// checked cast always succeed.
class AlwaysSucceedCheckedCastFailure final : public CheckedCastBaseFailure {
class NoopCheckedCast final : public CheckedCastBaseFailure {
public:
AlwaysSucceedCheckedCastFailure(const Solution &solution, Type fromType,
Type toType, CheckedCastKind kind,
ConstraintLocator *locator)
NoopCheckedCast(const Solution &solution, Type fromType, Type toType,
CheckedCastKind kind, ConstraintLocator *locator)
: CheckedCastBaseFailure(solution, fromType, toType, kind, locator) {}

bool diagnoseAsError() override;
Expand Down
20 changes: 10 additions & 10 deletions lib/Sema/CSFix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1920,19 +1920,19 @@ bool AllowCheckedCastCoercibleOptionalType::diagnose(const Solution &solution,
return failure.diagnose(asNote);
}

AllowAlwaysSucceedCheckedCast *
AllowAlwaysSucceedCheckedCast::create(ConstraintSystem &cs, Type fromType,
Type toType, CheckedCastKind kind,
ConstraintLocator *locator) {
AllowNoopCheckedCast *AllowNoopCheckedCast::create(ConstraintSystem &cs,
Type fromType, Type toType,
CheckedCastKind kind,
ConstraintLocator *locator) {
return new (cs.getAllocator())
AllowAlwaysSucceedCheckedCast(cs, fromType, toType, kind, locator);
AllowNoopCheckedCast(cs, fromType, toType, kind, locator);
}

bool AllowAlwaysSucceedCheckedCast::diagnose(const Solution &solution,
bool asNote) const {
AlwaysSucceedCheckedCastFailure failure(solution, getFromType(), getToType(),
CastKind, getLocator());
return failure.diagnose(asNote);
bool AllowNoopCheckedCast::diagnose(const Solution &solution,
bool asNote) const {
NoopCheckedCast warning(solution, getFromType(), getToType(), CastKind,
getLocator());
return warning.diagnose(asNote);
}

// Although function types maybe compile-time convertible because
Expand Down
39 changes: 24 additions & 15 deletions lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4565,12 +4565,12 @@ bool ConstraintSystem::repairFailures(
return true;

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

auto *fix = ContextualMismatch::create(*this, lhs, rhs,
getConstraintLocator(locator));
auto *fix = IgnoreContextualType::create(*this, lhs, rhs,
getConstraintLocator(locator));
conversionsOrFixes.push_back(fix);
break;
}
Expand Down Expand Up @@ -4909,7 +4909,7 @@ bool ConstraintSystem::repairFailures(
if (contextualType->isEqual(rhs)) {
auto *loc = getConstraintLocator(
anchor, LocatorPathElt::ContextualType(purpose));
if (hasFixFor(loc, FixKind::ContextualMismatch))
if (hasFixFor(loc, FixKind::IgnoreContextualType))
return true;

if (contextualType->isVoid() && purpose == CTP_ReturnStmt) {
Expand All @@ -4918,7 +4918,7 @@ bool ConstraintSystem::repairFailures(
}

conversionsOrFixes.push_back(
ContextualMismatch::create(*this, lhs, rhs, loc));
IgnoreContextualType::create(*this, lhs, rhs, loc));
break;
}
}
Expand Down Expand Up @@ -6678,9 +6678,9 @@ static ConstraintFix *maybeWarnAboutExtraneousCast(

// Always succeed
if (isCastToExpressibleByNilLiteral(cs, origFromType, toType)) {
return AllowAlwaysSucceedCheckedCast::create(
cs, fromType, toType, CheckedCastKind::Coercion,
cs.getConstraintLocator(locator));
return AllowNoopCheckedCast::create(cs, fromType, toType,
CheckedCastKind::Coercion,
cs.getConstraintLocator(locator));
}

// If both original are metatypes we have to use them because most of the
Expand Down Expand Up @@ -6715,10 +6715,9 @@ static ConstraintFix *maybeWarnAboutExtraneousCast(
cs, origFromType, origToType, castKind,
cs.getConstraintLocator(locator));
} else {
// No optionals, just a trivial cast that always succeed.
return AllowAlwaysSucceedCheckedCast::create(
cs, origFromType, origToType, castKind,
cs.getConstraintLocator(locator));
// No optionals, just a trivial cast that always succeeds.
return AllowNoopCheckedCast::create(cs, origFromType, origToType, castKind,
cs.getConstraintLocator(locator));
}
}

Expand Down Expand Up @@ -11554,16 +11553,19 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
case FixKind::SpecifyLabelToAssociateTrailingClosure:
case FixKind::AllowKeyPathWithoutComponents:
case FixKind::IgnoreInvalidResultBuilderBody:
case FixKind::IgnoreResultBuilderWithReturnStmts:
case FixKind::SpecifyContextualTypeForNil:
case FixKind::AllowRefToInvalidDecl:
case FixKind::SpecifyBaseTypeForOptionalUnresolvedMember:
case FixKind::AllowCheckedCastCoercibleOptionalType:
case FixKind::AllowNoopCheckedCast:
case FixKind::AllowUnsupportedRuntimeCheckedCast:
case FixKind::AllowAlwaysSucceedCheckedCast:
case FixKind::AllowInvalidStaticMemberRefOnProtocolMetatype:
case FixKind::AllowWrappedValueMismatch:
case FixKind::RemoveExtraneousArguments:
case FixKind::SpecifyTypeForPlaceholder: {
case FixKind::SpecifyTypeForPlaceholder:
case FixKind::AllowAutoClosurePointerConversion:
case FixKind::IgnoreKeyPathContextualMismatch: {
return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
}

Expand Down Expand Up @@ -11684,7 +11686,11 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
return matchTypes(*elemTy, dictionaryKeyTy, kind, subflags, elemLoc);
}

case FixKind::ContextualMismatch: {
case FixKind::ContextualMismatch:
case FixKind::IgnoreContextualType:
case FixKind::IgnoreAssignmentDestinationType:
case FixKind::AllowConversionThroughInOut:
case FixKind::IgnoreCollectionElementContextualMismatch: {
auto impact = 1;

auto locator = fix->getLocator();
Expand Down Expand Up @@ -11764,6 +11770,9 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
case FixKind::SpecifyClosureParameterType:
case FixKind::SpecifyClosureReturnType:
case FixKind::AddQualifierToAccessTopLevelName:
case FixKind::AddSendableAttribute:
case FixKind::DropThrowsAttribute:
case FixKind::DropAsyncAttribute:
llvm_unreachable("handled elsewhere");
}

Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/ConstraintSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3885,7 +3885,7 @@ static bool diagnoseContextualFunctionCallGenericAmbiguity(
if (fixLocator->isForContextualType())
return true;

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

Expand Down
6 changes: 4 additions & 2 deletions test/Constraints/without_actually_escaping.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ func rethrowThroughWAE(_ zz: (Int, Int, Int) throws -> Int, _ value: Int) throws
}
}

let _: ((Int) -> Int, (@escaping (Int) -> Int) -> ()) -> ()
= withoutActuallyEscaping(_:do:) // expected-error{{}}
// There should be two errors - here one for async -> sync, and another throws -> non-throws
let _: ((Int) -> Int, (@escaping (Int) -> Int) -> ()) -> () = withoutActuallyEscaping(_:do:)
// 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) -> ()) -> ()'}}
// 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) -> ()) -> ()'}}


// Failing to propagate @noescape into non-single-expression
Expand Down