Skip to content

Commit f141ddf

Browse files
authored
Merge pull request swiftlang#71466 from meg-gupta/lifetimedependencegeneric
Add LifetimeDependence to GenericFunctionType
2 parents 2aba85f + eb7a3d1 commit f141ddf

File tree

6 files changed

+70
-19
lines changed

6 files changed

+70
-19
lines changed

include/swift/AST/Types.h

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3866,10 +3866,11 @@ std::string getParamListAsString(ArrayRef<AnyFunctionType::Param> parameters);
38663866
/// on those parameters and dependent member types thereof. The input and
38673867
/// output types of the generic function can be expressed in terms of those
38683868
/// generic parameters.
3869-
class GenericFunctionType final : public AnyFunctionType,
3870-
public llvm::FoldingSetNode,
3871-
private llvm::TrailingObjects<GenericFunctionType, AnyFunctionType::Param,
3872-
Type> {
3869+
class GenericFunctionType final
3870+
: public AnyFunctionType,
3871+
public llvm::FoldingSetNode,
3872+
private llvm::TrailingObjects<GenericFunctionType, AnyFunctionType::Param,
3873+
Type, LifetimeDependenceInfo> {
38733874
friend TrailingObjects;
38743875

38753876
GenericSignature Signature;
@@ -3882,6 +3883,10 @@ class GenericFunctionType final : public AnyFunctionType,
38823883
return hasGlobalActor() + hasThrownError();
38833884
}
38843885

3886+
size_t numTrailingObjects(OverloadToken<LifetimeDependenceInfo>) const {
3887+
return hasLifetimeDependenceInfo() ? 1 : 0;
3888+
}
3889+
38853890
/// Construct a new generic function type.
38863891
GenericFunctionType(GenericSignature sig, ArrayRef<Param> params, Type result,
38873892
llvm::Optional<ExtInfo> info, const ASTContext *ctx,
@@ -3909,7 +3914,17 @@ class GenericFunctionType final : public AnyFunctionType,
39093914
return Type();
39103915
return getTrailingObjects<Type>()[hasGlobalActor()];
39113916
}
3912-
3917+
3918+
LifetimeDependenceInfo getLifetimeDependenceInfo() const {
3919+
if (!hasLifetimeDependenceInfo()) {
3920+
return LifetimeDependenceInfo();
3921+
}
3922+
auto *info = getTrailingObjects<LifetimeDependenceInfo>();
3923+
assert(!info->empty() && "If the LifetimeDependenceInfo was empty, we "
3924+
"shouldn't have stored it.");
3925+
return *info;
3926+
}
3927+
39133928
/// Retrieve the generic signature of this function type.
39143929
GenericSignature getGenericSignature() const {
39153930
return Signature;

lib/AST/ASTContext.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4490,9 +4490,13 @@ GenericFunctionType *GenericFunctionType::get(GenericSignature sig,
44904490
if (globalActor && !sig->isReducedType(globalActor))
44914491
isCanonical = false;
44924492

4493+
bool hasLifetimeDependenceInfo =
4494+
info.has_value() && !info.value().getLifetimeDependenceInfo().empty();
4495+
44934496
unsigned numTypes = (globalActor ? 1 : 0) + (thrownError ? 1 : 0);
4494-
size_t allocSize = totalSizeToAlloc<AnyFunctionType::Param, Type>(
4495-
params.size(), numTypes);
4497+
size_t allocSize =
4498+
totalSizeToAlloc<AnyFunctionType::Param, Type, LifetimeDependenceInfo>(
4499+
params.size(), numTypes, hasLifetimeDependenceInfo ? 1 : 0);
44964500
void *mem = ctx.Allocate(allocSize, alignof(GenericFunctionType));
44974501

44984502
auto properties = getGenericFunctionRecursiveProperties(params, result);
@@ -4522,6 +4526,11 @@ GenericFunctionType::GenericFunctionType(
45224526
}
45234527
if (Type thrownError = info->getThrownError())
45244528
getTrailingObjects<Type>()[thrownErrorIndex] = thrownError;
4529+
4530+
auto lifetimeDependenceInfo = info->getLifetimeDependenceInfo();
4531+
if (!lifetimeDependenceInfo.empty()) {
4532+
*getTrailingObjects<LifetimeDependenceInfo>() = lifetimeDependenceInfo;
4533+
}
45254534
}
45264535
}
45274536

lib/AST/Type.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4121,8 +4121,7 @@ LifetimeDependenceInfo AnyFunctionType::getLifetimeDependenceInfo() const {
41214121
case TypeKind::Function:
41224122
return cast<FunctionType>(this)->getLifetimeDependenceInfo();
41234123
case TypeKind::GenericFunction:
4124-
// TODO: Handle GenericFunction
4125-
return LifetimeDependenceInfo();
4124+
return cast<GenericFunctionType>(this)->getLifetimeDependenceInfo();
41264125

41274126
default:
41284127
llvm_unreachable("Illegal type kind for AnyFunctionType.");

test/SIL/explicit_lifetime_dependence_specifiers.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
// RUN: -disable-experimental-parser-round-trip \
66
// RUN: -enable-experimental-feature NoncopyableGenerics \
77
// RUN: -enable-experimental-lifetime-dependence-inference | %FileCheck %s
8-
// REQUIRES: asserts
98
// REQUIRES: noncopyable_generics
109

1110
import Builtin
@@ -48,7 +47,6 @@ struct MutableBufferView : ~Escapable, ~Copyable {
4847
}
4948
}
5049

51-
/*
5250
// rdar://121983770
5351
func testBasic() {
5452
let capacity = 4
@@ -60,7 +58,6 @@ func testBasic() {
6058
use(newView)
6159
}
6260
}
63-
*/
6461

6562
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers6deriveyAA10BufferViewVADF : $@convention(thin) (@guaranteed BufferView) -> _borrow(1) @owned BufferView {
6663
func derive(_ x: borrowing BufferView) -> _borrow(x) BufferView {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: %target-swift-frontend %s -emit-sil \
2+
// RUN: -disable-experimental-parser-round-trip \
3+
// RUN: -enable-experimental-feature NonescapableTypes \
4+
// RUN: -enable-experimental-feature NoncopyableGenerics \
5+
// RUN: -enable-experimental-lifetime-dependence-inference | %FileCheck %s
6+
// REQUIRES: noncopyable_generics
7+
8+
protocol P {
9+
associatedtype E: ~Escapable
10+
borrowing func getE() -> _borrow(self) E
11+
}
12+
13+
extension P {
14+
borrowing func getDefault() -> _borrow(self) E {
15+
return getE()
16+
}
17+
}
18+
19+
public struct View: ~Escapable {
20+
@_unsafeNonescapableResult
21+
init() { }
22+
}
23+
24+
public struct PView: P {
25+
borrowing func getE() -> _borrow(self) View { return View() }
26+
}
27+
28+
public func test(pview: consuming PView) -> _consume(pview) View {
29+
return pview.getDefault()
30+
}
31+
32+
// CHECK: sil hidden @$s28lifetime_dependence_generics1PPAAE10getDefault1EQzyF : $@convention(method) <Self where Self : P> (@in_guaranteed Self) -> _borrow(0) @out Self.E {
33+
34+
// CHECK: sil hidden @$s28lifetime_dependence_generics5PViewV4getEAA4ViewVyF : $@convention(method) (PView) -> _borrow(0) @owned View {
35+
36+
// CHECK: sil private [transparent] [thunk] @$s28lifetime_dependence_generics5PViewVAA1PA2aDP4getE1EQzyFTW : $@convention(witness_method: P) (@in_guaranteed PView) -> _borrow(0) @out View {
37+
38+
// CHECK: sil @$s28lifetime_dependence_generics4test5pviewAA4ViewVAA5PViewVn_tF : $@convention(thin) (PView) -> _inherit(1) @owned View {

test/Sema/explicit_lifetime_dependence_specifiers.swift

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,3 @@ struct Wrapper : ~Escapable {
129129
return view
130130
}
131131
}
132-
133-
struct ArrayOfBufferView : ~Escapable {
134-
let arr: [BufferView]
135-
subscript(index: Int) -> _borrow(self) BufferView {
136-
return arr[index]
137-
}
138-
}

0 commit comments

Comments
 (0)