Skip to content

Commit 08e2382

Browse files
committed
IUO: Generate Optional<T> rather than ImplicitlyUnwrappedOptional<T>.
Stop creating ImplicitlyUnwrappedOptional<T> so that we can remove it from the type system. Enable the code that generates disjunctions for Optional<T> and rewrites expressions based on the original declared type being 'T!'. This effectively means ImplicitlyUnwrappedOptional<T> is no longer part of the type system, although I haven't actually removed all of the code dealing with it yet. Most of the changes supporting this were previously merged to master, but some things, like support for dynamic lookup were difficult to put on master without actually removing IUOs. ImplicitlyUnwrappedOptional<T> is is dead, long live implicitly unwrapped Optional<T>! Resolves rdar://problem/33272674.
1 parent 5e1fc01 commit 08e2382

File tree

96 files changed

+553
-530
lines changed

Some content is hidden

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

96 files changed

+553
-530
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
@@ -4094,7 +4094,9 @@ class ImplicitlyUnwrappedOptionalType : public UnarySyntaxSugarType {
40944094
ImplicitlyUnwrappedOptionalType(const ASTContext &ctx, Type base,
40954095
RecursiveTypeProperties properties)
40964096
: UnarySyntaxSugarType(TypeKind::ImplicitlyUnwrappedOptional, ctx, base,
4097-
properties) {}
4097+
properties) {
4098+
//llvm_unreachable("ImplicitlyUnwrappedOptionalType::ImplicitlyUnwrappedOptionalType");
4099+
}
40984100

40994101
public:
41004102
/// Return a uniqued optional type with the specified base type.

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
@@ -4059,7 +4059,7 @@ namespace {
40594059
nullability = translateNullability(*typeNullability);
40604060
}
40614061
if (nullability != OTK_None && !errorConvention.hasValue()) {
4062-
resultTy = OptionalType::get(nullability, resultTy);
4062+
resultTy = OptionalType::get(resultTy);
40634063
isIUO = nullability == OTK_ImplicitlyUnwrappedOptional;
40644064
}
40654065

@@ -6101,8 +6101,8 @@ ConstructorDecl *SwiftDeclConverter::importConstructor(
61016101

61026102
// Rebuild the function type with the appropriate result type;
61036103
Type resultTy = selfTy;
6104-
if (failability)
6105-
resultTy = OptionalType::get(failability, resultTy);
6104+
if (failability != OTK_None)
6105+
resultTy = OptionalType::get(resultTy);
61066106

61076107
type = FunctionType::get(oldFnType->getInput(), resultTy,
61086108
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

@@ -3182,6 +3179,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
31823179
}
31833180
}
31843181
} else if (Type Unwrapped = ExprType->getImplicitlyUnwrappedOptionalObjectType()) {
3182+
// FIXME: This can go away when IUOs have been removed from the type
3183+
// system.
31853184
lookupVisibleMemberDecls(*this, Unwrapped, CurrDeclContext,
31863185
TypeResolver.get(),
31873186
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
@@ -5068,8 +5068,7 @@ RValue RValueEmitter::emitForceValue(ForceValueExpr *loc, Expr *E,
50685068
// If this is an implicit force of an ImplicitlyUnwrappedOptional,
50695069
// and we're emitting into an unbridging conversion, try adjusting the
50705070
// context.
5071-
if (loc->isImplicit() &&
5072-
E->getType()->getImplicitlyUnwrappedOptionalObjectType()) {
5071+
if (loc->isImplicit() && loc->isForceOfImplicitlyUnwrappedOptional()) {
50735072
if (auto conv = C.getAsConversion()) {
50745073
if (auto adjusted = conv->getConversion().adjustForInitialForceValue()) {
50755074
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)