Skip to content

Commit 96cfec4

Browse files
authored
Merge pull request #85935 from meg-gupta/lifetimeflags
Fix swiftinterface printing of accessors and inferred lifetime dependencies when Lifetimes feature is enabled
2 parents f7c4dd8 + 4089775 commit 96cfec4

File tree

3 files changed

+64
-15
lines changed

3 files changed

+64
-15
lines changed

lib/AST/FeatureSet.cpp

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -150,36 +150,42 @@ UNINTERESTING_FEATURE(CheckImplementationOnly)
150150
UNINTERESTING_FEATURE(CheckImplementationOnlyStrict)
151151
UNINTERESTING_FEATURE(EnforceSPIOperatorGroup)
152152

153-
static bool findUnderscoredLifetimeAttr(Decl *decl) {
154-
auto hasUnderscoredLifetimeAttr = [](Decl *decl) {
153+
static bool findLifetimeAttr(Decl *decl, bool findUnderscored) {
154+
auto hasLifetimeAttr = [&](Decl *decl) {
155155
if (!decl->getAttrs().hasAttribute<LifetimeAttr>()) {
156156
return false;
157157
}
158158
// Since we ban mixing @lifetime and @_lifetime on the same decl, checking
159159
// any one LifetimeAttr on the decl is sufficient.
160160
// FIXME: Implement the ban.
161-
return decl->getAttrs().getAttribute<LifetimeAttr>()->isUnderscored();
161+
if (findUnderscored) {
162+
return decl->getAttrs().getAttribute<LifetimeAttr>()->isUnderscored();
163+
}
164+
return !decl->getAttrs().getAttribute<LifetimeAttr>()->isUnderscored();
162165
};
163166

164167
switch (decl->getKind()) {
165168
case DeclKind::Var: {
166169
auto *var = cast<VarDecl>(decl);
167-
return llvm::any_of(var->getAllAccessors(), hasUnderscoredLifetimeAttr);
170+
return llvm::any_of(var->getAllAccessors(), hasLifetimeAttr);
168171
}
169172
default:
170-
return hasUnderscoredLifetimeAttr(decl);
173+
return hasLifetimeAttr(decl);
171174
}
172175
}
173176

174177
static bool usesFeatureLifetimeDependence(Decl *decl) {
175-
if (decl->getAttrs().hasAttribute<LifetimeAttr>()) {
176-
if (findUnderscoredLifetimeAttr(decl)) {
177-
// Experimental feature Lifetimes will guard the decl.
178-
return false;
179-
}
178+
if (findLifetimeAttr(decl, /*findUnderscored*/ false)) {
180179
return true;
181180
}
182181

182+
// Guard inferred lifetime dependencies with LifetimeDependence if it was
183+
// enabled.
184+
if (!decl->getASTContext().LangOpts.hasFeature(Feature::LifetimeDependence)) {
185+
return false;
186+
}
187+
188+
// Check for inferred lifetime dependencies
183189
if (auto *afd = dyn_cast<AbstractFunctionDecl>(decl)) {
184190
return afd->getInterfaceType()
185191
->getAs<AnyFunctionType>()
@@ -192,7 +198,25 @@ static bool usesFeatureLifetimeDependence(Decl *decl) {
192198
}
193199

194200
static bool usesFeatureLifetimes(Decl *decl) {
195-
return findUnderscoredLifetimeAttr(decl);
201+
if (findLifetimeAttr(decl, /*findUnderscored*/ true)) {
202+
return true;
203+
}
204+
205+
// Guard inferred lifetime dependencies with Lifetimes if it was enabled.
206+
if (!decl->getASTContext().LangOpts.hasFeature(Feature::Lifetimes)) {
207+
return false;
208+
}
209+
210+
// Check for inferred lifetime dependencies
211+
if (auto *afd = dyn_cast<AbstractFunctionDecl>(decl)) {
212+
return afd->getInterfaceType()
213+
->getAs<AnyFunctionType>()
214+
->hasLifetimeDependencies();
215+
}
216+
if (auto *varDecl = dyn_cast<VarDecl>(decl)) {
217+
return !varDecl->getTypeInContext()->isEscapable();
218+
}
219+
return false;
196220
}
197221

198222
static bool usesFeatureInoutLifetimeDependence(Decl *decl) {

test/ModuleInterface/Inputs/lifetime_underscored_dependence.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,15 @@ extension Container {
7777
}
7878
}
7979
}
80+
81+
public struct RigidArray : ~Copyable {
82+
@usableFromInline let _ptr: UnsafeRawBufferPointer
83+
84+
public var span: RawSpan {
85+
@_lifetime(borrow self)
86+
get {
87+
return RawSpan(_unsafeBytes: _ptr)
88+
}
89+
}
90+
}
91+

test/ModuleInterface/lifetime_underscored_dependence_test.swift

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
// RUN: %target-swift-frontend -swift-version 5 -enable-library-evolution -emit-module \
44
// RUN: -enable-experimental-feature Lifetimes \
5-
// RUN: -enable-experimental-feature Lifetimes \
65
// RUN: -o %t/lifetime_underscored_dependence.swiftmodule \
76
// RUN: -emit-module-interface-path %t/lifetime_underscored_dependence.swiftinterface \
87
// RUN: %S/Inputs/lifetime_underscored_dependence.swift
@@ -105,8 +104,22 @@ import lifetime_underscored_dependence
105104
// CHECK:}
106105
// CHECK:#endif
107106

108-
// Check that an implicitly dependent variable accessor is guarded by LifetimeDependence.
109-
//
110107
// CHECK: extension lifetime_underscored_dependence.Container {
111-
// CHECK-NEXT: #if compiler(>=5.3) && $LifetimeDependence
108+
// CHECK-NEXT: #if compiler(>=5.3) && $Lifetimes
112109
// CHECK-NEXT: public var storage: lifetime_underscored_dependence.BufferView {
110+
111+
// CHECK: public struct RigidArray : ~Swift.Copyable {
112+
// CHECK: @usableFromInline
113+
// CHECK: internal let _ptr: Swift.UnsafeRawBufferPointer
114+
// CHECK: #if compiler(>=5.3) && $Lifetimes
115+
// CHECK: public var span: Swift.RawSpan {
116+
// CHECK: @_lifetime(borrow self)
117+
// CHECK: get
118+
// CHECK: }
119+
// CHECK: #else
120+
// CHECK: public var span: Swift.RawSpan {
121+
// CHECK: @lifetime(borrow self)
122+
// CHECK: get
123+
// CHECK: }
124+
// CHECK: #endif
125+
// CHECK: }

0 commit comments

Comments
 (0)