Skip to content

Commit be46a89

Browse files
authored
Merge pull request swiftlang#33925 from slavapestov/se-0268-parse-time-lookup
Fix SE-0268 implementation for removal of parse-time name lookup
2 parents 10de482 + c0d466e commit be46a89

14 files changed

+133
-84
lines changed

include/swift/AST/StorageImpl.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,11 @@ enum class ReadWriteImplKind {
223223
/// There's a modify coroutine.
224224
Modify,
225225

226-
/// We have a didSet which doesn't use the oldValue
227-
StoredWithSimpleDidSet,
228-
229-
/// We have a didSet which doesn't use the oldValue
230-
InheritedWithSimpleDidSet,
226+
/// We have a didSet, so we're either going to use
227+
/// MaterializeOrTemporary or the "simple didSet"
228+
// access pattern.
229+
StoredWithDidSet,
230+
InheritedWithDidSet,
231231
};
232232
enum { NumReadWriteImplKindBits = 4 };
233233

@@ -273,13 +273,13 @@ class StorageImplInfo {
273273
case WriteImplKind::StoredWithObservers:
274274
assert(readImpl == ReadImplKind::Stored);
275275
assert(readWriteImpl == ReadWriteImplKind::MaterializeToTemporary ||
276-
readWriteImpl == ReadWriteImplKind::StoredWithSimpleDidSet);
276+
readWriteImpl == ReadWriteImplKind::StoredWithDidSet);
277277
return;
278278

279279
case WriteImplKind::InheritedWithObservers:
280280
assert(readImpl == ReadImplKind::Inherited);
281281
assert(readWriteImpl == ReadWriteImplKind::MaterializeToTemporary ||
282-
readWriteImpl == ReadWriteImplKind::InheritedWithSimpleDidSet);
282+
readWriteImpl == ReadWriteImplKind::InheritedWithDidSet);
283283
return;
284284

285285
case WriteImplKind::Set:

lib/AST/ASTDumper.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,10 +286,10 @@ StringRef swift::getReadWriteImplKindName(ReadWriteImplKind kind) {
286286
return "materialize_to_temporary";
287287
case ReadWriteImplKind::Modify:
288288
return "modify_coroutine";
289-
case ReadWriteImplKind::StoredWithSimpleDidSet:
290-
return "stored_simple_didset";
291-
case ReadWriteImplKind::InheritedWithSimpleDidSet:
292-
return "inherited_simple_didset";
289+
case ReadWriteImplKind::StoredWithDidSet:
290+
return "stored_with_didset";
291+
case ReadWriteImplKind::InheritedWithDidSet:
292+
return "inherited_with_didset";
293293
}
294294
llvm_unreachable("bad kind");
295295
}

lib/AST/Decl.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -434,9 +434,15 @@ bool Decl::isInvalid() const {
434434
case DeclKind::Constructor:
435435
case DeclKind::Destructor:
436436
case DeclKind::Func:
437-
case DeclKind::Accessor:
438437
case DeclKind::EnumElement:
439438
return cast<ValueDecl>(this)->getInterfaceType()->hasError();
439+
440+
case DeclKind::Accessor: {
441+
auto *AD = cast<AccessorDecl>(this);
442+
if (AD->hasInterfaceType() && AD->getInterfaceType()->hasError())
443+
return true;
444+
return AD->getStorage()->isInvalid();
445+
}
440446
}
441447

442448
llvm_unreachable("Unknown decl kind");
@@ -2013,9 +2019,10 @@ getDirectReadWriteAccessStrategy(const AbstractStorageDecl *storage) {
20132019
case ReadWriteImplKind::Modify:
20142020
return AccessStrategy::getAccessor(AccessorKind::Modify,
20152021
/*dispatch*/ false);
2016-
case ReadWriteImplKind::StoredWithSimpleDidSet:
2017-
case ReadWriteImplKind::InheritedWithSimpleDidSet:
2018-
if (storage->requiresOpaqueModifyCoroutine()) {
2022+
case ReadWriteImplKind::StoredWithDidSet:
2023+
case ReadWriteImplKind::InheritedWithDidSet:
2024+
if (storage->requiresOpaqueModifyCoroutine() &&
2025+
storage->getParsedAccessor(AccessorKind::DidSet)->isSimpleDidSet()) {
20192026
return AccessStrategy::getAccessor(AccessorKind::Modify,
20202027
/*dispatch*/ false);
20212028
} else {

lib/SIL/IR/TypeLowering.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2684,10 +2684,13 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
26842684
collectAccessorCaptures(AccessorKind::MutableAddress);
26852685
break;
26862686
case ReadWriteImplKind::Modify:
2687-
case ReadWriteImplKind::StoredWithSimpleDidSet:
2688-
case ReadWriteImplKind::InheritedWithSimpleDidSet:
26892687
collectAccessorCaptures(AccessorKind::Modify);
26902688
break;
2689+
case ReadWriteImplKind::StoredWithDidSet:
2690+
// We've already processed the didSet operation.
2691+
break;
2692+
case ReadWriteImplKind::InheritedWithDidSet:
2693+
llvm_unreachable("inherited local variable");
26912694
}
26922695
}
26932696

lib/Sema/TypeCheckDecl.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,7 +1191,7 @@ bool SimpleDidSetRequest::evaluate(Evaluator &evaluator,
11911191
// If we find a reference to the implicit 'oldValue' parameter, then it is
11921192
// not a "simple" didSet because we need to fetch it.
11931193
auto walker = OldValueFinder(param);
1194-
decl->getBody()->walk(walker);
1194+
decl->getTypecheckedBody()->walk(walker);
11951195
auto hasOldValueRef = walker.didFindOldValueRef();
11961196
if (!hasOldValueRef) {
11971197
// If the body does not refer to implicit 'oldValue', it means we can
@@ -1639,13 +1639,9 @@ static ParamDecl *getOriginalParamFromAccessor(AbstractStorageDecl *storage,
16391639
switch (accessor->getAccessorKind()) {
16401640
case AccessorKind::DidSet:
16411641
case AccessorKind::WillSet:
1642-
case AccessorKind::Set:
1643-
if (accessor->isSimpleDidSet()) {
1644-
// If this is a "simple" didSet, there won't be
1645-
// a parameter.
16461642
return nullptr;
1647-
}
16481643

1644+
case AccessorKind::Set:
16491645
if (param == accessorParams->get(0)) {
16501646
// This is the 'newValue' parameter.
16511647
return nullptr;

lib/Sema/TypeCheckDeclObjC.cpp

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -528,16 +528,21 @@ bool swift::isRepresentableInObjC(
528528
Reason != ObjCReason::WitnessToObjC &&
529529
Reason != ObjCReason::MemberOfObjCProtocol) {
530530
if (Diagnose) {
531-
auto error = accessor->isGetter()
532-
? (isa<VarDecl>(storage)
533-
? diag::objc_getter_for_nonobjc_property
534-
: diag::objc_getter_for_nonobjc_subscript)
535-
: (isa<VarDecl>(storage)
536-
? diag::objc_setter_for_nonobjc_property
537-
: diag::objc_setter_for_nonobjc_subscript);
538-
539-
accessor->diagnose(error);
540-
describeObjCReason(accessor, Reason);
531+
if (accessor->isGetter()) {
532+
auto error = isa<VarDecl>(storage)
533+
? diag::objc_getter_for_nonobjc_property
534+
: diag::objc_getter_for_nonobjc_subscript;
535+
536+
accessor->diagnose(error);
537+
describeObjCReason(accessor, Reason);
538+
} else if (accessor->isSetter()) {
539+
auto error = isa<VarDecl>(storage)
540+
? diag::objc_setter_for_nonobjc_property
541+
: diag::objc_setter_for_nonobjc_subscript;
542+
543+
accessor->diagnose(error);
544+
describeObjCReason(accessor, Reason);
545+
}
541546
}
542547
return false;
543548
}
@@ -1443,19 +1448,9 @@ bool IsObjCRequest::evaluate(Evaluator &evaluator, ValueDecl *VD) const {
14431448
// Cannot be @objc.
14441449
}
14451450

1446-
// Perform some icky stateful hackery to mark this declaration as
1447-
// not being @objc.
1448-
auto makeNotObjC = [&] {
1449-
if (auto objcAttr = VD->getAttrs().getAttribute<ObjCAttr>()) {
1450-
objcAttr->setInvalid();
1451-
}
1452-
};
1453-
14541451
// If this declaration should not be exposed to Objective-C, we're done.
1455-
if (!isObjC) {
1456-
makeNotObjC();
1452+
if (!isObjC)
14571453
return false;
1458-
}
14591454

14601455
if (auto accessor = dyn_cast<AccessorDecl>(VD)) {
14611456
auto storage = accessor->getStorage();
@@ -1479,23 +1474,17 @@ bool IsObjCRequest::evaluate(Evaluator &evaluator, ValueDecl *VD) const {
14791474
Optional<ForeignAsyncConvention> asyncConvention;
14801475
Optional<ForeignErrorConvention> errorConvention;
14811476
if (auto var = dyn_cast<VarDecl>(VD)) {
1482-
if (!isRepresentableInObjC(var, *isObjC)) {
1483-
makeNotObjC();
1477+
if (!isRepresentableInObjC(var, *isObjC))
14841478
return false;
1485-
}
14861479
} else if (auto subscript = dyn_cast<SubscriptDecl>(VD)) {
1487-
if (!isRepresentableInObjC(subscript, *isObjC)) {
1488-
makeNotObjC();
1480+
if (!isRepresentableInObjC(subscript, *isObjC))
14891481
return false;
1490-
}
14911482
} else if (isa<DestructorDecl>(VD)) {
14921483
// Destructors need no additional checking.
14931484
} else if (auto func = dyn_cast<AbstractFunctionDecl>(VD)) {
14941485
if (!isRepresentableInObjC(
1495-
func, *isObjC, asyncConvention, errorConvention)) {
1496-
makeNotObjC();
1486+
func, *isObjC, asyncConvention, errorConvention))
14971487
return false;
1498-
}
14991488
}
15001489

15011490
// Note that this declaration is exposed to Objective-C.

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2031,13 +2031,30 @@ OverriddenDeclsRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
20312031
// Accessors determine their overrides based on their abstract storage
20322032
// declarations.
20332033
if (auto accessor = dyn_cast<AccessorDecl>(decl)) {
2034+
auto kind = accessor->getAccessorKind();
2035+
2036+
switch (kind) {
2037+
case AccessorKind::Get:
2038+
case AccessorKind::Set:
2039+
case AccessorKind::Read:
2040+
case AccessorKind::Modify:
2041+
break;
2042+
2043+
case AccessorKind::WillSet:
2044+
case AccessorKind::DidSet:
2045+
case AccessorKind::Address:
2046+
case AccessorKind::MutableAddress:
2047+
// These accessors are never part of the opaque set. Bail out early
2048+
// to avoid computing the overridden declarations of the storage.
2049+
return noResults;
2050+
}
2051+
20342052
auto overridingASD = accessor->getStorage();
20352053

20362054
// Check the various overridden storage declarations.
20372055
SmallVector<OverrideMatch, 2> matches;
20382056
for (auto overridden : overridingASD->getOverriddenDecls()) {
20392057
auto baseASD = cast<AbstractStorageDecl>(overridden);
2040-
auto kind = accessor->getAccessorKind();
20412058

20422059
// If the base doesn't consider this an opaque accessor,
20432060
// this isn't really an override.

lib/Sema/TypeCheckStorage.cpp

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -345,9 +345,7 @@ IsSetterMutatingRequest::evaluate(Evaluator &evaluator,
345345
if (auto *didSet = var->getParsedAccessor(AccessorKind::DidSet)) {
346346
// If there's a didSet, we call the getter for the 'oldValue', and so
347347
// should consider the getter's mutatingness as well
348-
if (!didSet->isSimpleDidSet()) {
349-
isMutating |= (mut->Getter == PropertyWrapperMutability::Mutating);
350-
}
348+
isMutating |= (mut->Getter == PropertyWrapperMutability::Mutating);
351349
isMutating |= didSet->getAttrs().hasAttribute<MutatingAttr>();
352350
}
353351
if (auto *willSet = var->getParsedAccessor(AccessorKind::WillSet))
@@ -1761,9 +1759,10 @@ synthesizeCoroutineAccessorBody(AccessorDecl *accessor, ASTContext &ctx) {
17611759
// serialized, which prevents them from being able to directly reference
17621760
// didSet/willSet accessors, which are private.
17631761
if (isModify &&
1764-
(storageReadWriteImpl == ReadWriteImplKind::StoredWithSimpleDidSet ||
1765-
storageReadWriteImpl == ReadWriteImplKind::InheritedWithSimpleDidSet) &&
1766-
!accessor->hasForcedStaticDispatch()) {
1762+
!accessor->hasForcedStaticDispatch() &&
1763+
(storageReadWriteImpl == ReadWriteImplKind::StoredWithDidSet ||
1764+
storageReadWriteImpl == ReadWriteImplKind::InheritedWithDidSet) &&
1765+
storage->getParsedAccessor(AccessorKind::DidSet)->isSimpleDidSet()) {
17671766
return synthesizeModifyCoroutineBodyWithSimpleDidSet(accessor, ctx);
17681767
}
17691768

@@ -2321,9 +2320,11 @@ IsAccessorTransparentRequest::evaluate(Evaluator &evaluator,
23212320
}
23222321

23232322
switch (storage->getReadWriteImpl()) {
2324-
case ReadWriteImplKind::StoredWithSimpleDidSet:
2325-
case ReadWriteImplKind::InheritedWithSimpleDidSet:
2326-
return false;
2323+
case ReadWriteImplKind::StoredWithDidSet:
2324+
case ReadWriteImplKind::InheritedWithDidSet:
2325+
if (storage->getAccessor(AccessorKind::DidSet)->isSimpleDidSet())
2326+
return false;
2327+
break;
23272328
default:
23282329
break;
23292330
}
@@ -3078,10 +3079,6 @@ StorageImplInfoRequest::evaluate(Evaluator &evaluator,
30783079
bool hasSetter = storage->getParsedAccessor(AccessorKind::Set);
30793080
bool hasModify = storage->getParsedAccessor(AccessorKind::Modify);
30803081
bool hasMutableAddress = storage->getParsedAccessor(AccessorKind::MutableAddress);
3081-
bool hasSimpleDidSet =
3082-
hasDidSet && const_cast<AccessorDecl *>(
3083-
storage->getParsedAccessor(AccessorKind::DidSet))
3084-
->isSimpleDidSet();
30853082

30863083
// 'get', 'read', and a non-mutable addressor are all exclusive.
30873084
ReadImplKind readImpl;
@@ -3143,22 +3140,22 @@ StorageImplInfoRequest::evaluate(Evaluator &evaluator,
31433140
// Check if we have observers.
31443141
} else if (readImpl == ReadImplKind::Inherited) {
31453142
writeImpl = WriteImplKind::InheritedWithObservers;
3146-
readWriteImpl = ReadWriteImplKind::MaterializeToTemporary;
31473143

3148-
if (!hasWillSet && hasSimpleDidSet) {
3149-
readWriteImpl = ReadWriteImplKind::InheritedWithSimpleDidSet;
3150-
}
3144+
if (hasWillSet)
3145+
readWriteImpl = ReadWriteImplKind::MaterializeToTemporary;
3146+
else
3147+
readWriteImpl = ReadWriteImplKind::InheritedWithDidSet;
31513148

31523149
// Otherwise, it's stored.
31533150
} else if (readImpl == ReadImplKind::Stored &&
31543151
!cast<VarDecl>(storage)->isLet()) {
31553152
if (hasWillSet || hasDidSet) {
31563153
writeImpl = WriteImplKind::StoredWithObservers;
3157-
readWriteImpl = ReadWriteImplKind::MaterializeToTemporary;
31583154

3159-
if (!hasWillSet && hasSimpleDidSet) {
3160-
readWriteImpl = ReadWriteImplKind::StoredWithSimpleDidSet;
3161-
}
3155+
if (hasWillSet)
3156+
readWriteImpl = ReadWriteImplKind::MaterializeToTemporary;
3157+
else
3158+
readWriteImpl = ReadWriteImplKind::StoredWithDidSet;
31623159
} else {
31633160
writeImpl = WriteImplKind::Stored;
31643161
readWriteImpl = ReadWriteImplKind::Stored;

lib/Serialization/Deserialization.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,8 +2199,8 @@ getActualReadWriteImplKind(unsigned rawKind) {
21992199
CASE(MutableAddress)
22002200
CASE(MaterializeToTemporary)
22012201
CASE(Modify)
2202-
CASE(StoredWithSimpleDidSet)
2203-
CASE(InheritedWithSimpleDidSet)
2202+
CASE(StoredWithDidSet)
2203+
CASE(InheritedWithDidSet)
22042204
#undef CASE
22052205
}
22062206
return None;

lib/Serialization/ModuleFormat.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5555
/// describe what change you made. The content of this comment isn't important;
5656
/// it just ensures a conflict if two people change the module format.
5757
/// Don't worry about adhering to the 80-column limit for this line.
58-
const uint16_t SWIFTMODULE_VERSION_MINOR = 576; // hasCReferences
58+
const uint16_t SWIFTMODULE_VERSION_MINOR = 577; // isSimpleDidSet() change
5959

6060
/// A standard hash seed used for all string hashes in a serialized module.
6161
///
@@ -208,8 +208,8 @@ enum class ReadWriteImplKind : uint8_t {
208208
MutableAddress,
209209
MaterializeToTemporary,
210210
Modify,
211-
StoredWithSimpleDidSet,
212-
InheritedWithSimpleDidSet,
211+
StoredWithDidSet,
212+
InheritedWithDidSet,
213213
};
214214
using ReadWriteImplKindField = BCFixed<3>;
215215

0 commit comments

Comments
 (0)