mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
IUO: Put the pieces in place to handle coercions and casts to IUO types.
For casts like 'x as T!' or 'x as! T!', generate a disjunction that attempts to bind both the optional and non-optional T, preferring the optional branch of the disjunction. Note that this should effectively be NFC at the moment because we're still generating the IUO type for T! rather than a plain optional, so we first attempt the IUO type (as opposed to an Optional<T>) which goes through existing logic that handles the IUOs as part of the type system. The new rewriting logic will actually do something once we switch over to generating Optional<T> when T! is uttered.
This commit is contained in:
@@ -2494,6 +2494,18 @@ namespace {
|
||||
llvm_unreachable("Already type-checked");
|
||||
}
|
||||
|
||||
Type
|
||||
createTypeVariableAndDisjunctionForIUOCoercion(Type toType,
|
||||
ConstraintLocator *locator) {
|
||||
auto implicitUnwrapLocator = CS.getConstraintLocator(
|
||||
locator, ConstraintLocator::ImplicitlyUnwrappedCoercionResult);
|
||||
auto typeVar =
|
||||
CS.createTypeVariable(implicitUnwrapLocator, /*options=*/0);
|
||||
CS.buildDisjunctionForImplicitlyUnwrappedOptional(typeVar, toType,
|
||||
implicitUnwrapLocator);
|
||||
return typeVar;
|
||||
}
|
||||
|
||||
Type visitForcedCheckedCastExpr(ForcedCheckedCastExpr *expr) {
|
||||
auto &tc = CS.getTypeChecker();
|
||||
auto fromExpr = expr->getSubExpr();
|
||||
@@ -2517,6 +2529,12 @@ namespace {
|
||||
// The source type can be checked-cast to the destination type.
|
||||
CS.addConstraint(ConstraintKind::CheckedCast, fromType, toType, locator);
|
||||
|
||||
// If the result type was declared IUO, add a disjunction for
|
||||
// bindings for the result of the coercion.
|
||||
auto *TR = expr->getCastTypeLoc().getTypeRepr();
|
||||
if (TR && TR->getKind() == TypeReprKind::ImplicitlyUnwrappedOptional)
|
||||
return createTypeVariableAndDisjunctionForIUOCoercion(toType, locator);
|
||||
|
||||
return toType;
|
||||
}
|
||||
|
||||
@@ -2537,8 +2555,17 @@ namespace {
|
||||
auto fromType = CS.getType(expr->getSubExpr());
|
||||
auto locator = CS.getConstraintLocator(expr);
|
||||
|
||||
CS.addExplicitConversionConstraint(fromType, toType, /*allowFixes=*/true,
|
||||
locator);
|
||||
// Add a conversion constraint for the direct conversion between
|
||||
// types.
|
||||
CS.addExplicitConversionConstraint(fromType, toType,
|
||||
/*allowFixes=*/true, locator);
|
||||
|
||||
// If the result type was declared IUO, add a disjunction for
|
||||
// bindings for the result of the coercion.
|
||||
auto *TR = expr->getCastTypeLoc().getTypeRepr();
|
||||
if (TR && TR->getKind() == TypeReprKind::ImplicitlyUnwrappedOptional)
|
||||
return createTypeVariableAndDisjunctionForIUOCoercion(toType, locator);
|
||||
|
||||
return toType;
|
||||
}
|
||||
|
||||
@@ -2561,7 +2588,16 @@ namespace {
|
||||
|
||||
auto fromType = CS.getType(fromExpr);
|
||||
auto locator = CS.getConstraintLocator(expr);
|
||||
|
||||
CS.addConstraint(ConstraintKind::CheckedCast, fromType, toType, locator);
|
||||
|
||||
// If the result type was declared IUO, add a disjunction for
|
||||
// bindings for the result of the coercion.
|
||||
auto *TR = expr->getCastTypeLoc().getTypeRepr();
|
||||
if (TR && TR->getKind() == TypeReprKind::ImplicitlyUnwrappedOptional)
|
||||
return createTypeVariableAndDisjunctionForIUOCoercion(
|
||||
OptionalType::get(toType), locator);
|
||||
|
||||
return OptionalType::get(toType);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user