Skip to content

Commit 766acd4

Browse files
authored
Make 'rawValue' and 'init(rawValue:)' inlinable for non-resilient enums (#15589)
Small potential perf win...or rather regain, since we apparently used to do this. It's a bit trickier to say whether we should do the same for resilient enums, since /in theory/ a later version of the library might decide to use different raw values. https://bugs.swift.org/browse/SR-7094
1 parent f6b67f3 commit 766acd4

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

lib/Sema/DerivedConformanceRawRepresentable.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,17 @@ static VarDecl *deriveRawRepresentable_raw(TypeChecker &tc,
145145
addGetterToReadOnlyDerivedProperty(tc, propDecl, rawType);
146146
getterDecl->setBodySynthesizer(&deriveBodyRawRepresentable_raw);
147147

148+
// If the containing module is not resilient, make sure clients can get at
149+
// the raw value without function call overhead.
150+
if (parentDC->getParentModule()->getResilienceStrategy() !=
151+
ResilienceStrategy::Resilient) {
152+
AccessScope access =
153+
enumDecl->getFormalAccessScope(nullptr,
154+
/*treatUsableFromInlineAsPublic*/true);
155+
if (access.isPublic())
156+
getterDecl->getAttrs().add(new (C) InlinableAttr(/*implicit*/false));
157+
}
158+
148159
auto dc = cast<IterableDeclContext>(parentDecl);
149160
dc->addMember(getterDecl);
150161
dc->addMember(propDecl);
@@ -343,6 +354,17 @@ static ConstructorDecl *deriveRawRepresentable_init(TypeChecker &tc,
343354
initDecl->copyFormalAccessFrom(enumDecl, /*sourceIsParentContext*/true);
344355
initDecl->setValidationStarted();
345356

357+
// If the containing module is not resilient, make sure clients can construct
358+
// an instance without function call overhead.
359+
if (parentDC->getParentModule()->getResilienceStrategy() !=
360+
ResilienceStrategy::Resilient) {
361+
AccessScope access =
362+
enumDecl->getFormalAccessScope(nullptr,
363+
/*treatUsableFromInlineAsPublic*/true);
364+
if (access.isPublic())
365+
initDecl->getAttrs().add(new (C) InlinableAttr(/*implicit*/false));
366+
}
367+
346368
tc.Context.addSynthesizedDecl(initDecl);
347369

348370
cast<IterableDeclContext>(parentDecl)->addMember(initDecl);

lib/Sema/TypeCheckAttr.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1984,7 +1984,10 @@ void AttributeChecker::visitUsableFromInlineAttr(UsableFromInlineAttr *attr) {
19841984

19851985
// On internal declarations, @inlinable implies @usableFromInline.
19861986
if (VD->getAttrs().hasAttribute<InlinableAttr>()) {
1987-
diagnoseAndRemoveAttr(attr, diag::inlinable_implies_usable_from_inline);
1987+
if (attr->isImplicit())
1988+
attr->setInvalid();
1989+
else
1990+
diagnoseAndRemoveAttr(attr, diag::inlinable_implies_usable_from_inline);
19881991
return;
19891992
}
19901993
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %target-swift-frontend -emit-silgen -enable-sil-ownership %s | %FileCheck %s
2+
// RUN: %target-swift-frontend -emit-silgen -enable-sil-ownership -enable-resilience %s | %FileCheck -check-prefix=CHECK-RESILIENT %s
3+
4+
public enum E: Int {
5+
case a, b, c
6+
}
7+
8+
// CHECK-DAG: sil [serialized] @$S22enum_raw_representable1EO0B5ValueACSgSi_tcfC
9+
// CHECK-DAG: sil [serialized] @$S22enum_raw_representable1EO0B5ValueSivg
10+
11+
// CHECK-RESILIENT-DAG: sil @$S22enum_raw_representable1EO0B5ValueACSgSi_tcfC
12+
// CHECK-RESILIENT-DAG: sil @$S22enum_raw_representable1EO0B5ValueSivg

0 commit comments

Comments
 (0)