Skip to content

Commit a61223a

Browse files
authored
[CS] Visit all fixed bindings for constraint re-activation (#30886)
[CS] Visit all fixed bindings for constraint re-activation
2 parents 486e667 + 78072de commit a61223a

16 files changed

+523
-438
lines changed

Diff for: include/swift/AST/DiagnosticsSema.def

+4
Original file line numberDiff line numberDiff line change
@@ -1068,6 +1068,10 @@ ERROR(missing_unwrap_optional_try,none,
10681068
ERROR(missing_forced_downcast,none,
10691069
"%0 is not convertible to %1; "
10701070
"did you mean to use 'as!' to force downcast?", (Type, Type))
1071+
WARNING(coercion_may_fail_warning,none,
1072+
"coercion from %0 to %1 may fail; use 'as?' or 'as!' instead",
1073+
(Type, Type))
1074+
10711075
ERROR(missing_explicit_conversion,none,
10721076
"%0 is not implicitly convertible to %1; "
10731077
"did you mean to use 'as' to explicitly convert?", (Type, Type))

Diff for: lib/Sema/CSDiagnostics.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -6199,3 +6199,11 @@ bool MissingQuialifierInMemberRefFailure::diagnoseAsError() {
61996199
emitDiagnostic(choice, diag::decl_declared_here, choice->getFullName());
62006200
return true;
62016201
}
6202+
6203+
bool CoercionAsForceCastFailure::diagnoseAsError() {
6204+
auto *coercion = cast<CoerceExpr>(getRawAnchor());
6205+
emitDiagnostic(coercion->getLoc(), diag::coercion_may_fail_warning,
6206+
getFromType(), getToType())
6207+
.highlight(coercion->getSourceRange());
6208+
return true;
6209+
}

Diff for: lib/Sema/CSDiagnostics.h

+10
Original file line numberDiff line numberDiff line change
@@ -1953,6 +1953,16 @@ class MissingQuialifierInMemberRefFailure final : public FailureDiagnostic {
19531953
bool diagnoseAsError();
19541954
};
19551955

1956+
/// Emits a warning about an attempt to use the 'as' operator as the 'as!'
1957+
/// operator.
1958+
class CoercionAsForceCastFailure final : public ContextualFailure {
1959+
public:
1960+
CoercionAsForceCastFailure(const Solution &solution, Type fromType,
1961+
Type toType, ConstraintLocator *locator)
1962+
: ContextualFailure(solution, fromType, toType, locator) {}
1963+
1964+
bool diagnoseAsError() override;
1965+
};
19561966
} // end namespace constraints
19571967
} // end namespace swift
19581968

Diff for: lib/Sema/CSFix.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -1279,3 +1279,17 @@ AddQualifierToAccessTopLevelName::create(ConstraintSystem &cs,
12791279
ConstraintLocator *locator) {
12801280
return new (cs.getAllocator()) AddQualifierToAccessTopLevelName(cs, locator);
12811281
}
1282+
1283+
bool AllowCoercionToForceCast::diagnose(const Solution &solution,
1284+
bool asNote) const {
1285+
CoercionAsForceCastFailure failure(solution, getFromType(), getToType(),
1286+
getLocator());
1287+
return failure.diagnose(asNote);
1288+
}
1289+
1290+
AllowCoercionToForceCast *
1291+
AllowCoercionToForceCast::create(ConstraintSystem &cs, Type fromType,
1292+
Type toType, ConstraintLocator *locator) {
1293+
return new (cs.getAllocator())
1294+
AllowCoercionToForceCast(cs, fromType, toType, locator);
1295+
}

Diff for: lib/Sema/CSFix.h

+31
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,9 @@ enum class FixKind : uint8_t {
248248
/// Member shadows a top-level name, such a name could only be accessed by
249249
/// prefixing it with a module name.
250250
AddQualifierToAccessTopLevelName,
251+
252+
/// A warning fix that allows a coercion to perform a force-cast.
253+
AllowCoercionToForceCast,
251254
};
252255

253256
class ConstraintFix {
@@ -1737,6 +1740,34 @@ class AllowNonClassTypeToConvertToAnyObject final : public ContextualMismatch {
17371740
create(ConstraintSystem &cs, Type type, ConstraintLocator *locator);
17381741
};
17391742

1743+
/// A warning fix to maintain compatibility with the following:
1744+
///
1745+
/// \code
1746+
/// func foo(_ arr: [Any]?) {
1747+
/// _ = (arr ?? []) as [NSObject]
1748+
/// }
1749+
/// \endcode
1750+
///
1751+
/// which performs a force-cast of the array's elements, despite being spelled
1752+
/// as a coercion.
1753+
class AllowCoercionToForceCast final : public ContextualMismatch {
1754+
AllowCoercionToForceCast(ConstraintSystem &cs, Type fromType, Type toType,
1755+
ConstraintLocator *locator)
1756+
: ContextualMismatch(cs, FixKind::AllowCoercionToForceCast, fromType,
1757+
toType, locator, /*warning*/ true) {}
1758+
1759+
public:
1760+
std::string getName() const {
1761+
return "allow coercion to be treated as a force-cast";
1762+
}
1763+
1764+
bool diagnose(const Solution &solution, bool asNote = false) const;
1765+
1766+
static AllowCoercionToForceCast *create(ConstraintSystem &cs, Type fromType,
1767+
Type toType,
1768+
ConstraintLocator *locator);
1769+
};
1770+
17401771
} // end namespace constraints
17411772
} // end namespace swift
17421773

0 commit comments

Comments
 (0)