[CSSimplify] Remove ad-hoc optional mismatch handling for arguments

Since we have `repairViaOptionalUnwrap`, let's use that to fix
argument/parameter mismatches instead of doing ad-hoc matching.
This commit is contained in:
Pavel Yaskevich
2025-05-29 15:50:22 -07:00
parent 2d1f9d3f18
commit b12d844fcc
3 changed files with 13 additions and 42 deletions

View File

@@ -4989,8 +4989,18 @@ repairViaOptionalUnwrap(ConstraintSystem &cs, Type fromType, Type toType,
// First, let's check whether it has been determined that // First, let's check whether it has been determined that
// it was incorrect to use `?` in this position. // it was incorrect to use `?` in this position.
if (cs.hasFixFor(cs.getConstraintLocator(subExpr), FixKind::RemoveUnwrap)) if (cs.hasFixFor(cs.getConstraintLocator(subExpr), FixKind::RemoveUnwrap)) {
if (auto *typeVar =
fromType->getOptionalObjectType()->getAs<TypeVariableType>()) {
// If the optional chain is invalid let's unwrap optional and
// re-introduce the constraint to be solved later once both sides
// are sufficiently resolved, this would allow to diagnose not only
// the invalid unwrap but an invalid conversion (if any) as well.
cs.addConstraint(matchKind, typeVar, toType,
cs.getConstraintLocator(locator));
}
return true; return true;
}
auto type = cs.getType(subExpr); auto type = cs.getType(subExpr);
// If the type of sub-expression is optional, type of the // If the type of sub-expression is optional, type of the
@@ -5919,43 +5929,6 @@ bool ConstraintSystem::repairFailures(
if (repairByTreatingRValueAsLValue(lhs, rhs)) if (repairByTreatingRValueAsLValue(lhs, rhs))
break; break;
// If the problem is related to missing unwrap, there is a special
// fix for that.
if (lhs->getOptionalObjectType() && !rhs->getOptionalObjectType()) {
// If this is an attempt to check whether optional conforms to a
// particular protocol, let's do that before attempting to force
// unwrap the optional.
if (hasConversionOrRestriction(ConversionRestrictionKind::Existential))
break;
if (auto *typeVar =
lhs->getOptionalObjectType()->getAs<TypeVariableType>()) {
auto *argLoc = typeVar->getImpl().getLocator();
if (argLoc->directlyAt<OptionalEvaluationExpr>()) {
auto OEE = castToExpr<OptionalEvaluationExpr>(argLoc->getAnchor());
// If the optional chain in the argument position is invalid
// let's unwrap optional and re-introduce the constraint to
// be solved later once both sides are sufficiently resolved,
// this would allow to diagnose not only the invalid unwrap
// but an invalid conversion (if any) as well.
if (hasFixFor(getConstraintLocator(OEE->getSubExpr()),
FixKind::RemoveUnwrap)) {
addConstraint(matchKind, typeVar, rhs, loc);
return true;
}
}
}
auto result = matchTypes(lhs->getOptionalObjectType(), rhs, matchKind,
TMF_ApplyingFix, locator);
if (result.isSuccess()) {
conversionsOrFixes.push_back(
ForceOptional::create(*this, lhs, rhs, loc));
break;
}
}
// If argument in l-value type and parameter is `inout` or a pointer, // If argument in l-value type and parameter is `inout` or a pointer,
// let's see if it's generic parameter matches and suggest adding explicit // let's see if it's generic parameter matches and suggest adding explicit
// `&`. // `&`.
@@ -6082,7 +6055,7 @@ bool ConstraintSystem::repairFailures(
if (repairViaOptionalUnwrap(*this, lhs, rhs, matchKind, conversionsOrFixes, if (repairViaOptionalUnwrap(*this, lhs, rhs, matchKind, conversionsOrFixes,
locator)) locator))
break; return true;
{ {
auto *calleeLocator = getCalleeLocator(loc); auto *calleeLocator = getCalleeLocator(loc);

View File

@@ -705,6 +705,7 @@ func builderInClosure() {
func testInvalidOptionalChainingInIfContext() { func testInvalidOptionalChainingInIfContext() {
let v63796 = 1 let v63796 = 1
if v63796? {} // expected-error{{cannot use optional chaining on non-optional value of type 'Int'}} if v63796? {} // expected-error{{cannot use optional chaining on non-optional value of type 'Int'}}
// expected-error@-1 {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}}
} }
// https://github.com/swiftlang/swift/issues/79395 // https://github.com/swiftlang/swift/issues/79395

View File

@@ -10,6 +10,3 @@ func foo<T: P>(_: () throws -> T) -> T.A? { // expected-note {{where 'T' = 'Neve
let _ = foo() {fatalError()} & nil let _ = foo() {fatalError()} & nil
// expected-error@-1 {{global function 'foo' requires that 'Never' conform to 'P'}} // expected-error@-1 {{global function 'foo' requires that 'Never' conform to 'P'}}
// expected-error@-2 {{value of optional type 'Never.A?' must be unwrapped to a value of type 'Never.A'}}
// expected-note@-3 {{coalesce using '??' to provide a default when the optional value contains 'nil'}}
// expected-note@-4 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}