Skip to content

Commit 38c8cc8

Browse files
Merge pull request #77661 from nate-chandler/general-coro/20241115/1
[CoroutineAccessors] Default implementations are transparent.
2 parents 7cab35b + bdf662a commit 38c8cc8

File tree

6 files changed

+80
-32
lines changed

6 files changed

+80
-32
lines changed

include/swift/AST/Decl.h

+5
Original file line numberDiff line numberDiff line change
@@ -8624,6 +8624,11 @@ class AccessorDecl final : public FuncDecl {
86248624
/// even when it does not have one _yet_.
86258625
bool doesAccessorHaveBody() const;
86268626

8627+
/// Whether this accessor is a protocol requirement for which a default
8628+
/// implementation must be provided for back-deployment. For example, read2
8629+
/// and modify2 requirements with early enough availability.
8630+
bool isRequirementWithSynthesizedDefaultImplementation() const;
8631+
86278632
static bool classof(const Decl *D) {
86288633
return D->getKind() == DeclKind::Accessor;
86298634
}

lib/AST/Decl.cpp

+33
Original file line numberDiff line numberDiff line change
@@ -10921,6 +10921,39 @@ ArrayRef<VarDecl *> AccessorDecl::getAccessedProperties() const {
1092110921
return {};
1092210922
}
1092310923

10924+
bool AccessorDecl::isRequirementWithSynthesizedDefaultImplementation() const {
10925+
if (!isa<ProtocolDecl>(getDeclContext()))
10926+
return false;
10927+
10928+
if (!getASTContext().LangOpts.hasFeature(Feature::CoroutineAccessors)) {
10929+
return false;
10930+
}
10931+
if (!requiresFeatureCoroutineAccessors(getAccessorKind())) {
10932+
return false;
10933+
}
10934+
if (getStorage()->getOverrideLoc()) {
10935+
return false;
10936+
}
10937+
return getStorage()->requiresCorrespondingUnderscoredCoroutineAccessor(
10938+
getAccessorKind(), this);
10939+
}
10940+
10941+
bool AccessorDecl::doesAccessorHaveBody() const {
10942+
auto *accessor = this;
10943+
auto *storage = accessor->getStorage();
10944+
10945+
if (isa<ProtocolDecl>(accessor->getDeclContext())) {
10946+
return isRequirementWithSynthesizedDefaultImplementation();
10947+
}
10948+
10949+
// NSManaged getters and setters don't have bodies.
10950+
if (storage->getAttrs().hasAttribute<NSManagedAttr>(/*AllowInvalid=*/true))
10951+
if (accessor->isGetterOrSetter())
10952+
return false;
10953+
10954+
return true;
10955+
}
10956+
1092410957
StaticSpellingKind FuncDecl::getCorrectStaticSpelling() const {
1092510958
assert(getDeclContext()->isTypeContext());
1092610959
if (!isStatic())

lib/SILGen/SILGenLValue.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -3913,7 +3913,7 @@ static bool isCurrentFunctionAccessor(SILGenFunction &SGF,
39133913
contextAccessorDecl->getAccessorKind() == accessorKind;
39143914
}
39153915

3916-
static bool isSynthesizedDefaultImplementionatThunk(SILGenFunction &SGF) {
3916+
static bool isSynthesizedDefaultImplementionThunk(SILGenFunction &SGF) {
39173917
if (!SGF.FunctionDC)
39183918
return false;
39193919

@@ -3956,7 +3956,7 @@ LValue SILGenLValue::visitMemberRefExpr(MemberRefExpr *e,
39563956
AccessStrategy strategy = var->getAccessStrategy(
39573957
accessSemantics, getFormalAccessKind(accessKind),
39583958
SGF.SGM.M.getSwiftModule(), SGF.F.getResilienceExpansion(),
3959-
/*useOldABI=*/isSynthesizedDefaultImplementionatThunk(SGF));
3959+
/*useOldABI=*/isSynthesizedDefaultImplementionThunk(SGF));
39603960

39613961
bool isOnSelfParameter = isCallToSelfOfCurrentFunction(SGF, e);
39623962

@@ -4165,7 +4165,7 @@ LValue SILGenLValue::visitSubscriptExpr(SubscriptExpr *e,
41654165
auto strategy = decl->getAccessStrategy(
41664166
accessSemantics, getFormalAccessKind(accessKind),
41674167
SGF.SGM.M.getSwiftModule(), SGF.F.getResilienceExpansion(),
4168-
/*useOldABI=*/isSynthesizedDefaultImplementionatThunk(SGF));
4168+
/*useOldABI=*/isSynthesizedDefaultImplementionThunk(SGF));
41694169

41704170
bool isOnSelfParameter = isCallToSelfOfCurrentFunction(SGF, e);
41714171
bool isContextRead = isCurrentFunctionAccessor(SGF, AccessorKind::Read);

lib/Sema/TypeCheckStorage.cpp

+5-28
Original file line numberDiff line numberDiff line change
@@ -948,34 +948,6 @@ buildIndexForwardingParamList(AbstractStorageDecl *storage,
948948
return ParameterList::create(context, elements);
949949
}
950950

951-
bool AccessorDecl::doesAccessorHaveBody() const {
952-
auto *accessor = this;
953-
auto *storage = accessor->getStorage();
954-
955-
if (isa<ProtocolDecl>(accessor->getDeclContext())) {
956-
if (!accessor->getASTContext().LangOpts.hasFeature(
957-
Feature::CoroutineAccessors)) {
958-
return false;
959-
}
960-
if (!requiresFeatureCoroutineAccessors(accessor->getAccessorKind())) {
961-
return false;
962-
}
963-
if (storage->getOverrideLoc()) {
964-
return false;
965-
}
966-
return accessor->getStorage()
967-
->requiresCorrespondingUnderscoredCoroutineAccessor(
968-
accessor->getAccessorKind(), accessor);
969-
}
970-
971-
// NSManaged getters and setters don't have bodies.
972-
if (storage->getAttrs().hasAttribute<NSManagedAttr>(/*AllowInvalid=*/true))
973-
if (accessor->isGetterOrSetter())
974-
return false;
975-
976-
return true;
977-
}
978-
979951
/// Build an argument list referencing the subscript parameters for this
980952
/// subscript accessor.
981953
static ArgumentList *buildSubscriptArgumentList(ASTContext &ctx,
@@ -2798,6 +2770,11 @@ IsAccessorTransparentRequest::evaluate(Evaluator &evaluator,
27982770
if (accessor->getAttrs().hasAttribute<TransparentAttr>())
27992771
return true;
28002772

2773+
// Default implementations of read2 and modify2 provided for back-deployment
2774+
// are transparent.
2775+
if (accessor->isRequirementWithSynthesizedDefaultImplementation())
2776+
return true;
2777+
28012778
if (!accessor->isImplicit())
28022779
return false;
28032780

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// RUN: %target-swift-emit-silgen \
2+
// RUN: %s \
3+
// RUN: -experimental-skip-non-inlinable-function-bodies \
4+
// RUN: -enable-library-evolution \
5+
// RUN: -enable-experimental-feature CoroutineAccessors \
6+
// RUN: | %FileCheck %s --check-prefixes=CHECK,CHECK-NOUNWIND
7+
8+
// RUN: %target-swift-emit-silgen \
9+
// RUN: %s \
10+
// RUN: -experimental-skip-non-inlinable-function-bodies \
11+
// RUN: -enable-library-evolution \
12+
// RUN: -enable-experimental-feature CoroutineAccessors \
13+
// RUN: -enable-experimental-feature CoroutineAccessorsUnwindOnCallerError \
14+
// RUN: | %FileCheck %s --check-prefixes=CHECK,CHECK-UNWIND
15+
16+
// REQUIRES: swift_feature_CoroutineAccessors
17+
// REQUIRES: swift_feature_CoroutineAccessorsUnwindOnCallerError
18+
19+
// CHECK-LABEL: sil_default_witness_table MutatableAssociatedField {
20+
// CHECK-NEXT: no_default
21+
// CHECK-NEXT: no_default
22+
// CHECK-NEXT: method #MutatableAssociatedField.field!read2
23+
// CHECK-SAME: : @$s24coroutine_accessors_skip24MutatableAssociatedFieldP5field5AssocQzvy
24+
// CHECK-NEXT: no_default
25+
// CHECK-NEXT: no_default
26+
// CHECK-NEXT: method #MutatableAssociatedField.field!modify2
27+
// CHECK-SAME: : @$s24coroutine_accessors_skip24MutatableAssociatedFieldP5field5AssocQzvx
28+
// CHECK-NEXT: }
29+
public protocol MutatableAssociatedField {
30+
associatedtype Assoc
31+
32+
var field: Assoc { read set }
33+
}

test/SILGen/read_requirements.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public protocol P1 : ~Copyable {
5555
// CHECK: unwind
5656
// CHECK-LABEL: } // end sil function '$s17read_requirements2P1P4ubgsAA1UVvy'
5757

58-
// CHECK-LABEL: sil [ossa] @$s17read_requirements2P1P4ubgsAA1UVvx : {{.*}} {
58+
// CHECK-LABEL: sil{{.*}} [ossa] @$s17read_requirements2P1P4ubgsAA1UVvx : {{.*}} {
5959
// CHECK: bb0(
6060
// CHECK-SAME: [[SELF_UNCHECKED:%[^:]+]]
6161
// CHECK-SAME: ):

0 commit comments

Comments
 (0)