Skip to content

Commit e43ff71

Browse files
authored
Merge pull request #14299 from rudkx/iuo-remove-the-type
IUO: Generate Optional<T> rather than ImplicitlyUnwrappedOptional<T>
2 parents 9ee856f + 8d115b8 commit e43ff71

File tree

102 files changed

+664
-657
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+664
-657
lines changed

include/swift/AST/Expr.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,10 @@ class alignas(8) Expr {
303303
NumVariadicArgs : 16
304304
);
305305

306+
SWIFT_INLINE_BITFIELD(ForceValueExpr, Expr, 1,
307+
ForcedIUO : 1
308+
);
309+
306310
SWIFT_INLINE_BITFIELD(InOutToPointerExpr, ImplicitConversionExpr, 1,
307311
IsNonAccessing : 1
308312
);
@@ -2507,9 +2511,11 @@ class ForceValueExpr : public Expr {
25072511
SourceLoc ExclaimLoc;
25082512

25092513
public:
2510-
ForceValueExpr(Expr *subExpr, SourceLoc exclaimLoc)
2514+
ForceValueExpr(Expr *subExpr, SourceLoc exclaimLoc, bool forcedIUO = false)
25112515
: Expr(ExprKind::ForceValue, /*Implicit=*/exclaimLoc.isInvalid(), Type()),
2512-
SubExpr(subExpr), ExclaimLoc(exclaimLoc) {}
2516+
SubExpr(subExpr), ExclaimLoc(exclaimLoc) {
2517+
Bits.ForceValueExpr.ForcedIUO = forcedIUO;
2518+
}
25132519

25142520
SourceRange getSourceRange() const {
25152521
if (ExclaimLoc.isInvalid())
@@ -2534,6 +2540,10 @@ class ForceValueExpr : public Expr {
25342540
Expr *getSubExpr() const { return SubExpr; }
25352541
void setSubExpr(Expr *expr) { SubExpr = expr; }
25362542

2543+
bool isForceOfImplicitlyUnwrappedOptional() const {
2544+
return Bits.ForceValueExpr.ForcedIUO;
2545+
}
2546+
25372547
static bool classof(const Expr *E) {
25382548
return E->getKind() == ExprKind::ForceValue;
25392549
}

include/swift/AST/Types.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4114,7 +4114,9 @@ class ImplicitlyUnwrappedOptionalType : public UnarySyntaxSugarType {
41144114
ImplicitlyUnwrappedOptionalType(const ASTContext &ctx, Type base,
41154115
RecursiveTypeProperties properties)
41164116
: UnarySyntaxSugarType(TypeKind::ImplicitlyUnwrappedOptional, ctx, base,
4117-
properties) {}
4117+
properties) {
4118+
//llvm_unreachable("ImplicitlyUnwrappedOptionalType::ImplicitlyUnwrappedOptionalType");
4119+
}
41184120

41194121
public:
41204122
/// Return a uniqued optional type with the specified base type.

lib/AST/ASTVerifier.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,17 +1069,8 @@ class Verifier : public ASTWalker {
10691069
Type srcObj = checkLValue(E->getSubExpr()->getType(),
10701070
"result of InOutExpr");
10711071
auto DestTy = E->getType()->castTo<InOutType>()->getObjectType();
1072-
1073-
// HACK: Allow differences in optionality of the source and
1074-
// result types. When IUO is gone from the type system we'll no
1075-
// longer need this.
1076-
auto srcOptObjTy = srcObj->getAnyOptionalObjectType();
1077-
auto dstOptObjTy = DestTy->getAnyOptionalObjectType();
1078-
if (srcOptObjTy && dstOptObjTy) {
1079-
checkSameType(srcOptObjTy, dstOptObjTy, "object types for InOutExpr");
1080-
} else {
1081-
checkSameType(DestTy, srcObj, "object types for InOutExpr");
1082-
}
1072+
1073+
checkSameType(DestTy, srcObj, "object types for InOutExpr");
10831074
verifyCheckedBase(E);
10841075
}
10851076

lib/ClangImporter/ImportDecl.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,7 +1792,7 @@ static ImportedType rectifySubscriptTypes(Type getterType, bool getterIsIUO,
17921792

17931793
// Create an optional of the object type that can be implicitly
17941794
// unwrapped which subsumes both behaviors.
1795-
return {ImplicitlyUnwrappedOptionalType::get(setterType), true};
1795+
return {OptionalType::get(setterType), true};
17961796
}
17971797

17981798
/// Add an AvailableAttr to the declaration for the given
@@ -4073,7 +4073,7 @@ namespace {
40734073
nullability = translateNullability(*typeNullability);
40744074
}
40754075
if (nullability != OTK_None && !errorConvention.hasValue()) {
4076-
resultTy = OptionalType::get(nullability, resultTy);
4076+
resultTy = OptionalType::get(resultTy);
40774077
isIUO = nullability == OTK_ImplicitlyUnwrappedOptional;
40784078
}
40794079

@@ -6115,8 +6115,8 @@ ConstructorDecl *SwiftDeclConverter::importConstructor(
61156115

61166116
// Rebuild the function type with the appropriate result type;
61176117
Type resultTy = selfTy;
6118-
if (failability)
6119-
resultTy = OptionalType::get(failability, resultTy);
6118+
if (failability != OTK_None)
6119+
resultTy = OptionalType::get(resultTy);
61206120

61216121
type = FunctionType::get(oldFnType->getInput(), resultTy,
61226122
oldFnType->getExtInfo());

lib/ClangImporter/ImportType.cpp

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -160,17 +160,6 @@ namespace {
160160
return OptKind;
161161
}
162162

163-
/// Wrap a type in the Optional type appropriate to the import kind.
164-
static Type getOptionalType(Type payloadType, ImportTypeKind kind,
165-
OptionalTypeKind OptKind) {
166-
OptKind = getOptionalKind(kind, OptKind);
167-
168-
if (OptKind == OTK_None)
169-
return payloadType;
170-
171-
return OptionalType::get(OptKind, payloadType);
172-
}
173-
174163
class SwiftTypeConverter :
175164
public clang::TypeVisitor<SwiftTypeConverter, ImportResult>
176165
{
@@ -1277,7 +1266,7 @@ static ImportedType adjustTypeForConcreteImport(
12771266
auto resultTy = boundGenericTy->getGenericArgs().front();
12781267
if (OTK != OTK_None) {
12791268
assert(OTK != OTK_ImplicitlyUnwrappedOptional);
1280-
resultTy = OptionalType::get(OTK, resultTy);
1269+
resultTy = OptionalType::get(resultTy);
12811270
}
12821271

12831272
StringRef pointerName;
@@ -1398,14 +1387,6 @@ static ImportedType adjustTypeForConcreteImport(
13981387
return {importedType, isIUO};
13991388
}
14001389

1401-
static Type adjustOptionality(ImportedType importedType) {
1402-
if (!importedType.isImplicitlyUnwrapped())
1403-
return importedType.getType();
1404-
1405-
return ImplicitlyUnwrappedOptionalType::get(
1406-
importedType.getType()->getOptionalObjectType());
1407-
}
1408-
14091390
ImportedType ClangImporter::Implementation::importType(
14101391
clang::QualType type, ImportTypeKind importKind, bool allowNSUIntegerAsInt,
14111392
Bridgeability bridging, OptionalTypeKind optionality,
@@ -1460,10 +1441,7 @@ ImportedType ClangImporter::Implementation::importType(
14601441
assert(!adjustedType ||
14611442
!adjustedType.getType()->getImplicitlyUnwrappedOptionalObjectType());
14621443

1463-
// Make an IUO type based on isIUO. This will be removed when IUOs
1464-
// are removed from the type system.
1465-
return {adjustOptionality(adjustedType),
1466-
adjustedType.isImplicitlyUnwrapped()};
1444+
return adjustedType;
14671445
}
14681446

14691447
Type ClangImporter::Implementation::importTypeIgnoreIUO(
@@ -1474,12 +1452,8 @@ Type ClangImporter::Implementation::importTypeIgnoreIUO(
14741452
auto importedType = importType(type, importKind, allowNSUIntegerAsInt,
14751453
bridging, optionality, resugarNSErrorPointer);
14761454

1477-
// We allow IUO types to be returned at the moment. At some point we
1478-
// will never generate them and this can be removed.
1479-
assert(!importedType || importedType.isImplicitlyUnwrapped() ==
1480-
!importedType.getType()
1481-
->getImplicitlyUnwrappedOptionalObjectType()
1482-
.isNull());
1455+
assert(!importedType ||
1456+
!importedType.getType()->getImplicitlyUnwrappedOptionalObjectType());
14831457

14841458
return importedType.getType();
14851459
}
@@ -1558,7 +1532,7 @@ static Type applyNoEscape(Type type) {
15581532
// Recurse into optional types.
15591533
OptionalTypeKind optKind;
15601534
if (Type objectType = type->getAnyOptionalObjectType(optKind)) {
1561-
return OptionalType::get(optKind, applyNoEscape(objectType));
1535+
return OptionalType::get(applyNoEscape(objectType));
15621536
}
15631537

15641538
// Apply @noescape to function types.
@@ -2013,7 +1987,7 @@ ImportedType ClangImporter::Implementation::importMethodType(
20131987
if (nonOptionalTy->isAnyClassReferenceType()) {
20141988
swiftResultTy = getUnmanagedType(*this, nonOptionalTy);
20151989
if (OptionalityOfReturn != OTK_None)
2016-
swiftResultTy = OptionalType::get(OptionalityOfReturn, swiftResultTy);
1990+
swiftResultTy = OptionalType::get(swiftResultTy);
20171991
}
20181992
}
20191993

@@ -2085,11 +2059,14 @@ ImportedType ClangImporter::Implementation::importMethodType(
20852059
bool paramIsIUO;
20862060
if (kind == SpecialMethodKind::NSDictionarySubscriptGetter &&
20872061
paramTy->isObjCIdType()) {
2088-
swiftParamTy = getOptionalType(getNSCopyingType(),
2089-
ImportTypeKind::Parameter,
2090-
optionalityOfParam);
20912062
auto optKind =
20922063
getOptionalKind(ImportTypeKind::Parameter, optionalityOfParam);
2064+
2065+
if (optKind == OTK_None)
2066+
swiftParamTy = getNSCopyingType();
2067+
else
2068+
swiftParamTy = OptionalType::get(getNSCopyingType());
2069+
20932070
paramIsIUO = optKind == OTK_ImplicitlyUnwrappedOptional;
20942071
} else {
20952072
ImportTypeKind importKind = ImportTypeKind::Parameter;

lib/IDE/CodeCompletion.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1944,9 +1944,6 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
19441944
suffix = "!";
19451945
}
19461946

1947-
// FIXME: This goes away when IUOs are removed from the type system.
1948-
assert(T->getReferenceStorageReferent()->getImplicitlyUnwrappedOptionalObjectType());
1949-
19501947
Type ObjectType =
19511948
T->getReferenceStorageReferent()->getAnyOptionalObjectType();
19521949

@@ -3188,6 +3185,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
31883185
}
31893186
}
31903187
} else if (Type Unwrapped = ExprType->getImplicitlyUnwrappedOptionalObjectType()) {
3188+
// FIXME: This can go away when IUOs have been removed from the type
3189+
// system.
31913190
lookupVisibleMemberDecls(*this, Unwrapped, CurrDeclContext,
31923191
TypeResolver.get(),
31933192
IncludeInstanceMembers);

lib/SILGen/SILGenConvert.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,8 +1153,7 @@ Optional<Conversion> Conversion::adjustForInitialForceValue() const {
11531153

11541154
case BridgeToObjC: {
11551155
auto sourceOptType =
1156-
ImplicitlyUnwrappedOptionalType::get(getBridgingSourceType())
1157-
->getCanonicalType();
1156+
OptionalType::get(getBridgingSourceType())->getCanonicalType();
11581157
return Conversion::getBridging(ForceAndBridgeToObjC,
11591158
sourceOptType,
11601159
getBridgingResultType(),

lib/SILGen/SILGenExpr.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5066,8 +5066,7 @@ RValue RValueEmitter::emitForceValue(ForceValueExpr *loc, Expr *E,
50665066
// If this is an implicit force of an ImplicitlyUnwrappedOptional,
50675067
// and we're emitting into an unbridging conversion, try adjusting the
50685068
// context.
5069-
if (loc->isImplicit() &&
5070-
E->getType()->getImplicitlyUnwrappedOptionalObjectType()) {
5069+
if (loc->isImplicit() && loc->isForceOfImplicitlyUnwrappedOptional()) {
50715070
if (auto conv = C.getAsConversion()) {
50725071
if (auto adjusted = conv->getConversion().adjustForInitialForceValue()) {
50735072
auto value =

lib/SILGen/SILGenPoly.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -392,9 +392,10 @@ ManagedValue Transform::transform(ManagedValue v,
392392
});
393393
}
394394

395-
// If the value is IUO, but the desired formal type isn't optional, force it.
396-
if (inputOTK == OTK_ImplicitlyUnwrappedOptional
397-
&& outputOTK == OTK_None) {
395+
// If the value is an optional, but the desired formal type isn't an
396+
// optional or Any, force it.
397+
if (inputOTK != OTK_None && outputOTK == OTK_None
398+
&& !outputSubstType->isExistentialType()) {
398399
v = SGF.emitCheckedGetOptionalValueFrom(Loc, v,
399400
SGF.getTypeLowering(v.getType()),
400401
SGFContext());

0 commit comments

Comments
 (0)