Skip to content

Commit 19d283d

Browse files
committed
AST: Replace ImplicitlyUnwrappedOptionalAttr with Decl::{is,set}ImplicitlyUnwrappedOptional()
1 parent 3639bc4 commit 19d283d

31 files changed

+132
-168
lines changed

include/swift/AST/Attr.def

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -348,10 +348,7 @@ DECL_ATTR(_restatedObjCConformance, RestatedObjCConformance,
348348
LongAttribute | RejectByParser |
349349
NotSerialized, 70)
350350
// NOTE: 71 is unused
351-
SIMPLE_DECL_ATTR(_implicitly_unwrapped_optional, ImplicitlyUnwrappedOptional,
352-
OnFunc | OnAccessor | OnVar | OnParam | OnSubscript | OnConstructor |
353-
RejectByParser,
354-
72)
351+
// NOTE: 72 is unused
355352
DECL_ATTR(_optimize, Optimize,
356353
OnAbstractFunction | OnSubscript | OnVar |
357354
UserInaccessible,

include/swift/AST/Decl.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2412,6 +2412,13 @@ class ValueDecl : public Decl {
24122412
/// Whether this declaration is 'final'. A final class can't be subclassed,
24132413
/// a final class member can't be overriden.
24142414
unsigned isFinal : 1;
2415+
2416+
/// Whether the "isIUO" bit" has been computed yet.
2417+
unsigned isIUOComputed : 1;
2418+
2419+
/// Whether this declaration produces an implicitly unwrapped
2420+
/// optional result.
2421+
unsigned isIUO : 1;
24152422
} LazySemanticInfo = { };
24162423

24172424
friend class OverriddenDeclsRequest;
@@ -2686,6 +2693,21 @@ class ValueDecl : public Decl {
26862693
/// Returns true if this decl can be found by id-style dynamic lookup.
26872694
bool canBeAccessedByDynamicLookup() const;
26882695

2696+
/// Returns true if this declaration has an implicitly unwrapped optional
2697+
/// result. The precise meaning depends on the declaration kind:
2698+
/// - for properties, the value is IUO
2699+
/// - for subscripts, the element type is IUO
2700+
/// - for functions, the result type is IUO
2701+
/// - for constructors, the failability kind is IUO
2702+
bool isImplicitlyUnwrappedOptional() const;
2703+
2704+
/// Should only be set on imported and deserialized declarations; parsed
2705+
/// declarations compute this lazily via a request.
2706+
void setImplicitlyUnwrappedOptional(bool isIUO) {
2707+
LazySemanticInfo.isIUOComputed = 1;
2708+
LazySemanticInfo.isIUO = isIUO;
2709+
}
2710+
26892711
/// Returns the protocol requirements that this decl conforms to.
26902712
ArrayRef<ValueDecl *>
26912713
getSatisfiedProtocolRequirements(bool Sorted = false) const;

include/swift/AST/PrintOptions.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,7 @@ struct PrintOptions {
292292
/// List of attribute kinds that should not be printed.
293293
std::vector<AnyAttrKind> ExcludeAttrList = {DAK_Transparent, DAK_Effects,
294294
DAK_FixedLayout,
295-
DAK_ShowInInterface,
296-
DAK_ImplicitlyUnwrappedOptional};
295+
DAK_ShowInInterface};
297296

298297
/// List of attribute kinds that should be printed exclusively.
299298
/// Empty means allow all.

include/swift/Serialization/ModuleFormat.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5252
/// describe what change you made. The content of this comment isn't important;
5353
/// it just ensures a conflict if two people change the module format.
5454
/// Don't worry about adhering to the 80-column limit for this line.
55-
const uint16_t SWIFTMODULE_VERSION_MINOR = 509; // [dynamic_lifetime] sil flag
55+
const uint16_t SWIFTMODULE_VERSION_MINOR = 510; // serialize isIUO bit on ValueDecls
5656

5757
using DeclIDField = BCFixed<31>;
5858

@@ -1059,6 +1059,7 @@ namespace decls_block {
10591059
ReadWriteImplKindField, // read-write implementation
10601060
AccessorCountField, // number of accessors
10611061
TypeIDField, // interface type
1062+
BCFixed<1>, // IUO value?
10621063
DeclIDField, // overridden decl
10631064
AccessLevelField, // access level
10641065
AccessLevelField, // setter access, if applicable
@@ -1075,6 +1076,7 @@ namespace decls_block {
10751076
DeclContextIDField, // context decl
10761077
ParamDeclSpecifierField, // specifier
10771078
TypeIDField, // interface type
1079+
BCFixed<1>, // isIUO?
10781080
BCFixed<1>, // isVariadic?
10791081
BCFixed<1>, // isAutoClosure?
10801082
DefaultArgumentField, // default argument kind
@@ -1093,6 +1095,7 @@ namespace decls_block {
10931095
BCFixed<1>, // throws?
10941096
GenericEnvironmentIDField, // generic environment
10951097
TypeIDField, // result interface type
1098+
BCFixed<1>, // IUO result?
10961099
DeclIDField, // operator decl
10971100
DeclIDField, // overridden function
10981101
BCVBR<5>, // 0 for a simple name, otherwise the number of parameter name
@@ -1134,6 +1137,7 @@ namespace decls_block {
11341137
BCFixed<1>, // throws?
11351138
GenericEnvironmentIDField, // generic environment
11361139
TypeIDField, // result interface type
1140+
BCFixed<1>, // IUO result?
11371141
DeclIDField, // overridden function
11381142
DeclIDField, // AccessorStorageDecl
11391143
AccessorKindField, // accessor kind
@@ -1220,6 +1224,7 @@ namespace decls_block {
12201224
AccessorCountField, // number of accessors
12211225
GenericEnvironmentIDField, // generic environment
12221226
TypeIDField, // element interface type
1227+
BCFixed<1>, // IUO element?
12231228
DeclIDField, // overridden decl
12241229
AccessLevelField, // access level
12251230
AccessLevelField, // setter access, if applicable

lib/AST/ASTPrinter.cpp

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,7 @@ PrintOptions PrintOptions::printParseableInterfaceFile(bool preferTypeRepr) {
191191
// the default to 'public' and mark the 'internal' things.
192192
result.PrintAccess = true;
193193

194-
result.ExcludeAttrList = {DAK_ImplicitlyUnwrappedOptional, DAK_AccessControl,
195-
DAK_SetterAccess, DAK_Lazy};
194+
result.ExcludeAttrList = {DAK_AccessControl, DAK_SetterAccess, DAK_Lazy};
196195

197196
return result;
198197
}
@@ -703,9 +702,9 @@ class PrintAST : public ASTVisitor<PrintAST> {
703702

704703
void printTypeLoc(const TypeLoc &TL) { printTypeLocWithOptions(TL, Options); }
705704

706-
void printTypeLocForImplicitlyUnwrappedOptional(TypeLoc TL) {
705+
void printTypeLocForImplicitlyUnwrappedOptional(TypeLoc TL, bool IUO) {
707706
PrintOptions options = Options;
708-
options.PrintOptionalAsImplicitlyUnwrapped = true;
707+
options.PrintOptionalAsImplicitlyUnwrapped = IUO;
709708
printTypeLocWithOptions(TL, options);
710709
}
711710

@@ -993,12 +992,9 @@ void PrintAST::printTypedPattern(const TypedPattern *TP) {
993992
bool isIUO = false;
994993
if (auto *named = dyn_cast<NamedPattern>(TP->getSubPattern()))
995994
if (auto decl = named->getDecl())
996-
isIUO = decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
995+
isIUO = decl->isImplicitlyUnwrappedOptional();
997996

998-
if (isIUO)
999-
printTypeLocForImplicitlyUnwrappedOptional(TP->getTypeLoc());
1000-
else
1001-
printTypeLoc(TP->getTypeLoc());
997+
printTypeLocForImplicitlyUnwrappedOptional(TP->getTypeLoc(), isIUO);
1002998
}
1003999

10041000
/// Determines if we are required to print the name of a property declaration,
@@ -2528,10 +2524,8 @@ void PrintAST::visitVarDecl(VarDecl *decl) {
25282524
x(Options.OpaqueReturnTypePrinting,
25292525
PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword);
25302526

2531-
if (decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
2532-
printTypeLocForImplicitlyUnwrappedOptional(tyLoc);
2533-
else
2534-
printTypeLoc(tyLoc);
2527+
printTypeLocForImplicitlyUnwrappedOptional(
2528+
tyLoc, decl->isImplicitlyUnwrappedOptional());
25352529
}
25362530

25372531
printAccessors(decl);
@@ -2608,10 +2602,8 @@ void PrintAST::printOneParameter(const ParamDecl *param,
26082602
isEscaping(type));
26092603
}
26102604

2611-
if (param->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
2612-
printTypeLocForImplicitlyUnwrappedOptional(TheTypeLoc);
2613-
else
2614-
printTypeLoc(TheTypeLoc);
2605+
printTypeLocForImplicitlyUnwrappedOptional(
2606+
TheTypeLoc, param->isImplicitlyUnwrappedOptional());
26152607

26162608
if (param->isVariadic())
26172609
Printer << "...";
@@ -2832,10 +2824,8 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {
28322824
x(Options.OpaqueReturnTypePrinting,
28332825
PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword);
28342826

2835-
if (decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
2836-
printTypeLocForImplicitlyUnwrappedOptional(ResultTyLoc);
2837-
else
2838-
printTypeLoc(ResultTyLoc);
2827+
printTypeLocForImplicitlyUnwrappedOptional(
2828+
ResultTyLoc, decl->isImplicitlyUnwrappedOptional());
28392829
Printer.printStructurePost(PrintStructureKind::FunctionReturnType);
28402830
}
28412831
printGenericDeclGenericRequirements(decl);
@@ -2982,10 +2972,8 @@ void PrintAST::visitSubscriptDecl(SubscriptDecl *decl) {
29822972
x(Options.OpaqueReturnTypePrinting,
29832973
PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword);
29842974

2985-
if (decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
2986-
printTypeLocForImplicitlyUnwrappedOptional(elementTy);
2987-
else
2988-
printTypeLoc(elementTy);
2975+
printTypeLocForImplicitlyUnwrappedOptional(
2976+
elementTy, decl->isImplicitlyUnwrappedOptional());
29892977
Printer.printStructurePost(PrintStructureKind::FunctionReturnType);
29902978
printGenericDeclGenericRequirements(decl);
29912979
printAccessors(decl);

lib/AST/ASTVerifier.cpp

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2526,9 +2526,8 @@ class Verifier : public ASTWalker {
25262526
}
25272527
}
25282528

2529-
if (var->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>()) {
2530-
auto varTy = var->getInterfaceType()
2531-
->getReferenceStorageReferent();
2529+
if (var->isImplicitlyUnwrappedOptional()) {
2530+
auto varTy = var->getValueInterfaceType();
25322531

25332532
// FIXME: Update to look for plain Optional once
25342533
// ImplicitlyUnwrappedOptional is removed
@@ -2975,14 +2974,7 @@ class Verifier : public ASTWalker {
29752974
}
29762975
}
29772976

2978-
if (CD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>()) {
2979-
if (!CD->getInterfaceType() ||
2980-
!CD->getInterfaceType()->is<AnyFunctionType>()) {
2981-
Out << "Expected ConstructorDecl to have a function type!\n";
2982-
CD->dump(llvm::errs());
2983-
abort();
2984-
}
2985-
2977+
if (CD->isImplicitlyUnwrappedOptional()) {
29862978
if (CD->getFailability() != OTK_ImplicitlyUnwrappedOptional) {
29872979
Out << "Expected IUO failability for constructor with IUO decl "
29882980
"attribute!\n";
@@ -2992,8 +2984,6 @@ class Verifier : public ASTWalker {
29922984

29932985
auto resultTy = CD->getResultInterfaceType();
29942986

2995-
// FIXME: Update to look for plain Optional once
2996-
// ImplicitlyUnwrappedOptional is removed
29972987
if (!resultTy->getOptionalObjectType()) {
29982988
Out << "implicitly unwrapped optional attribute should only be set "
29992989
"on constructors with optional return types\n";
@@ -3192,17 +3182,8 @@ class Verifier : public ASTWalker {
31923182
}
31933183
}
31943184

3195-
if (FD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>()) {
3196-
if (!FD->getInterfaceType() ||
3197-
!FD->getInterfaceType()->is<AnyFunctionType>()) {
3198-
Out << "Expected FuncDecl to have a function type!\n";
3199-
abort();
3200-
}
3201-
3185+
if (FD->isImplicitlyUnwrappedOptional()) {
32023186
auto resultTy = FD->getResultInterfaceType();
3203-
3204-
// FIXME: Update to look for plain Optional once
3205-
// ImplicitlyUnwrappedOptional is removed
32063187
if (!resultTy->getOptionalObjectType()) {
32073188
Out << "implicitly unwrapped optional attribute should only be set "
32083189
"on functions with optional return types\n";

lib/AST/Decl.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2685,6 +2685,10 @@ bool ValueDecl::canBeAccessedByDynamicLookup() const {
26852685
return true;
26862686
}
26872687

2688+
bool ValueDecl::isImplicitlyUnwrappedOptional() const {
2689+
return LazySemanticInfo.isIUO;
2690+
}
2691+
26882692
ArrayRef<ValueDecl *>
26892693
ValueDecl::getSatisfiedProtocolRequirements(bool Sorted) const {
26902694
// Dig out the nominal type.
@@ -5711,10 +5715,7 @@ ParamDecl::ParamDecl(ParamDecl *PD, bool withTypes)
57115715
if (withTypes && PD->hasInterfaceType())
57125716
setInterfaceType(PD->getInterfaceType());
57135717

5714-
// FIXME: We should clone the entire attribute list.
5715-
if (PD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
5716-
getAttrs().add(new (PD->getASTContext())
5717-
ImplicitlyUnwrappedOptionalAttr(/* implicit= */ true));
5718+
setImplicitlyUnwrappedOptional(PD->isImplicitlyUnwrappedOptional());
57185719
}
57195720

57205721

lib/ClangImporter/ImportDecl.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,8 +1432,7 @@ createValueConstructor(ClangImporter::Implementation &Impl,
14321432
SourceLoc(), var->getName(), structDecl);
14331433
param->setInterfaceType(var->getInterfaceType());
14341434
param->setValidationToChecked();
1435-
Impl.recordImplicitUnwrapForDecl(
1436-
param, var->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>());
1435+
Impl.recordImplicitUnwrapForDecl(param, var->isImplicitlyUnwrappedOptional());
14371436
valueParameters.push_back(param);
14381437
}
14391438

@@ -6696,8 +6695,7 @@ SwiftDeclConverter::importSubscript(Decl *decl,
66966695
// If we have a setter, rectify it with the getter.
66976696
ParamDecl *setterIndex;
66986697
bool getterAndSetterInSameType = false;
6699-
bool isIUO =
6700-
getter->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
6698+
bool isIUO = getter->isImplicitlyUnwrappedOptional();
67016699
if (setter) {
67026700
// Whether there is an existing read-only subscript for which
67036701
// we have now found a setter.

lib/ClangImporter/ImporterImpl.h

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -615,28 +615,23 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
615615
ModuleDecl *loadModuleDWARF(SourceLoc importLoc,
616616
ArrayRef<std::pair<Identifier, SourceLoc>> path);
617617

618-
void recordImplicitUnwrapForDecl(Decl *decl, bool isIUO) {
618+
void recordImplicitUnwrapForDecl(ValueDecl *decl, bool isIUO) {
619+
if (!isIUO)
620+
return;
621+
619622
#if !defined(NDEBUG)
620623
Type ty;
621624
if (auto *FD = dyn_cast<FuncDecl>(decl)) {
622-
assert(FD->getInterfaceType());
623625
ty = FD->getResultInterfaceType();
624626
} else if (auto *CD = dyn_cast<ConstructorDecl>(decl)) {
625-
assert(CD->getInterfaceType());
626627
ty = CD->getResultInterfaceType();
627628
} else {
628629
ty = cast<AbstractStorageDecl>(decl)->getValueInterfaceType();
629630
}
630-
#endif
631-
632-
if (!isIUO)
633-
return;
634-
635631
assert(ty->getOptionalObjectType());
632+
#endif
636633

637-
auto *IUOAttr = new (SwiftContext)
638-
ImplicitlyUnwrappedOptionalAttr(/* implicit= */ true);
639-
decl->getAttrs().add(IUOAttr);
634+
decl->setImplicitlyUnwrappedOptional(true);
640635
}
641636

642637
/// Retrieve the Clang AST context.

lib/IDE/CodeCompletion.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,7 +2145,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
21452145
// Optional<T> type. Same applies to optional members.
21462146
VarType = OptionalType::get(VarType);
21472147
}
2148-
if (VD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
2148+
if (VD->isImplicitlyUnwrappedOptional())
21492149
addTypeAnnotationForImplicitlyUnwrappedOptional(Builder, VarType,
21502150
DynamicOrOptional);
21512151
else
@@ -2222,7 +2222,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
22222222
continue;
22232223
argName = PD->getArgumentName();
22242224
bodyName = PD->getParameterName();
2225-
isIUO = PD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
2225+
isIUO = PD->isImplicitlyUnwrappedOptional();
22262226
} else {
22272227
isIUO = false;
22282228
argName = typeParam.getLabel();
@@ -2368,7 +2368,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
23682368
Builder.addRightBracket();
23692369
else
23702370
Builder.addAnnotatedRightBracket();
2371-
if (SD && SD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
2371+
if (SD && SD->isImplicitlyUnwrappedOptional())
23722372
addTypeAnnotationForImplicitlyUnwrappedOptional(Builder,
23732373
AFT->getResult());
23742374
else
@@ -2415,7 +2415,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
24152415
addThrows(Builder, AFT, AFD);
24162416

24172417
if (AFD &&
2418-
AFD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
2418+
AFD->isImplicitlyUnwrappedOptional())
24192419
addTypeAnnotationForImplicitlyUnwrappedOptional(Builder,
24202420
AFT->getResult());
24212421
else
@@ -2580,7 +2580,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
25802580
// unwrapped optional results.
25812581
bool IsIUO =
25822582
!IsImplicitlyCurriedInstanceMethod &&
2583-
FD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
2583+
FD->isImplicitlyUnwrappedOptional();
25842584

25852585
PrintOptions PO;
25862586
PO.OpaqueReturnTypePrinting =
@@ -2666,7 +2666,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
26662666

26672667
addThrows(Builder, ConstructorType, CD);
26682668

2669-
if (CD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>()) {
2669+
if (CD->isImplicitlyUnwrappedOptional()) {
26702670
addTypeAnnotationForImplicitlyUnwrappedOptional(
26712671
Builder, Result.hasValue() ? Result.getValue()
26722672
: ConstructorType->getResult());
@@ -3306,8 +3306,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
33063306
ExprType = OptionalType::get(ExprType);
33073307

33083308
// Handle special cases
3309-
bool isIUO = VD && VD->getAttrs()
3310-
.hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
3309+
bool isIUO = VD && VD->isImplicitlyUnwrappedOptional();
33113310
if (tryFunctionCallCompletions(ExprType, VD))
33123311
return;
33133312
if (tryModuleCompletions(ExprType))

0 commit comments

Comments
 (0)