mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[CSSimplify] Detect and diagnose conformance failures related to AnyHashable conversion
Failure of an argument to AnyHashable parameter to conform to Hashable protocol should be detected in `simplifyConformsToConstraint` and fixed there. Doing so requires impact assessment adjustment because regular conformance requirements have default impact of 1, this is going to have argument impact of 2 not avoid clashing with other failures.
This commit is contained in:
@@ -2785,6 +2785,23 @@ assessRequirementFailureImpact(ConstraintSystem &cs, Type requirementType,
|
||||
impact += choiceImpact - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// If this requirement is associated with a call that is itself
|
||||
// incorrect, let's increase impact to indicate that this failure
|
||||
// has a compounding effect on viability of the overload choice it
|
||||
// comes from.
|
||||
if (locator.endsWith<LocatorPathElt::AnyRequirement>()) {
|
||||
if (auto *expr = getAsExpr(anchor)) {
|
||||
if (auto *call = getAsExpr<ApplyExpr>(cs.getParentExpr(expr))) {
|
||||
if (call->getFn() == expr &&
|
||||
llvm::any_of(cs.getFixes(), [&](const auto &fix) {
|
||||
return getAsExpr(fix->getAnchor()) == call;
|
||||
}))
|
||||
impact += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return impact;
|
||||
}
|
||||
|
||||
@@ -8409,6 +8426,15 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
|
||||
return SolutionKind::Solved;
|
||||
}
|
||||
|
||||
// Conformance constraint that is introduced by an implicit conversion
|
||||
// for example to `AnyHashable`.
|
||||
if (kind == ConstraintKind::ConformsTo &&
|
||||
loc->isLastElement<LocatorPathElt::ApplyArgToParam>()) {
|
||||
auto *fix = AllowArgumentMismatch::create(*this, type, protocolTy, loc);
|
||||
return recordFix(fix, /*impact=*/2) ? SolutionKind::Error
|
||||
: SolutionKind::Solved;
|
||||
}
|
||||
|
||||
// If this is an implicit Hashable conformance check generated for each
|
||||
// index argument of the keypath subscript component, we could just treat
|
||||
// it as though it conforms.
|
||||
|
||||
@@ -661,10 +661,7 @@ example21890157.property = "confusing" // expected-error {{value of optional ty
|
||||
|
||||
|
||||
struct UnaryOp {}
|
||||
|
||||
_ = -UnaryOp() // expected-error {{unary operator '-' cannot be applied to an operand of type 'UnaryOp'}}
|
||||
// expected-note@-1 {{overloads for '-' exist with these partially matching parameter lists: (Double), (Float)}}
|
||||
|
||||
|
||||
// <rdar://problem/23433271> Swift compiler segfault in failure diagnosis
|
||||
func f23433271(_ x : UnsafePointer<Int>) {}
|
||||
@@ -1551,3 +1548,12 @@ func rdar86611718(list: [Int]) {
|
||||
String(list.count())
|
||||
// expected-error@-1 {{cannot call value of non-function type 'Int'}}
|
||||
}
|
||||
|
||||
// rdar://108977234 - failed to produce diagnostic when argument to AnyHashable parameter doesn't conform to Hashable protocol
|
||||
do {
|
||||
struct NonHashable {}
|
||||
|
||||
func test(result: inout [AnyHashable], value: NonHashable) {
|
||||
result.append(value) // expected-error {{argument type 'NonHashable' does not conform to expected type 'Hashable'}}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user