Skip to content

Commit 4df55a1

Browse files
authored
Merge pull request #76834 from meg-gupta/lifetimedepmultiple
Replace dependsOn with @Lifetime
2 parents 24e5a82 + a3740ae commit 4df55a1

File tree

59 files changed

+883
-1621
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+883
-1621
lines changed

include/swift/AST/Attr.h

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2640,25 +2640,20 @@ class RawLayoutAttr final : public DeclAttribute {
26402640
}
26412641
};
26422642

2643-
class LifetimeAttr final
2644-
: public DeclAttribute,
2645-
private llvm::TrailingObjects<LifetimeAttr, LifetimeEntry> {
2646-
2647-
friend TrailingObjects;
2643+
class LifetimeAttr final : public DeclAttribute {
2644+
LifetimeEntry *entry;
26482645

2649-
unsigned NumEntries = 0;
2650-
2651-
explicit LifetimeAttr(SourceLoc atLoc, SourceRange baseRange, bool implicit,
2652-
ArrayRef<LifetimeEntry> entries);
2646+
LifetimeAttr(SourceLoc atLoc, SourceRange baseRange, bool implicit,
2647+
LifetimeEntry *entry)
2648+
: DeclAttribute(DeclAttrKind::Lifetime, atLoc, baseRange, implicit),
2649+
entry(entry) {}
26532650

26542651
public:
26552652
static LifetimeAttr *create(ASTContext &context, SourceLoc atLoc,
26562653
SourceRange baseRange, bool implicit,
2657-
ArrayRef<LifetimeEntry> entries);
2654+
LifetimeEntry *entry);
26582655

2659-
ArrayRef<LifetimeEntry> getLifetimeEntries() const {
2660-
return {getTrailingObjects<LifetimeEntry>(), NumEntries};
2661-
}
2656+
LifetimeEntry *getLifetimeEntry() const { return entry; }
26622657

26632658
static bool classof(const DeclAttribute *DA) {
26642659
return DA->getKind() == DeclAttrKind::Lifetime;

include/swift/AST/Decl.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8805,8 +8805,6 @@ class ConstructorDecl : public AbstractFunctionDecl {
88058805
Bits.ConstructorDecl.HasStubImplementation = stub;
88068806
}
88078807

8808-
bool hasLifetimeDependentReturn() const;
8809-
88108808
ConstructorDecl *getOverriddenDecl() const {
88118809
return cast_or_null<ConstructorDecl>(
88128810
AbstractFunctionDecl::getOverriddenDecl());

include/swift/AST/DeclAttr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ SIMPLE_DECL_ATTR(unsafe, Unsafe,
510510
160)
511511

512512
DECL_ATTR(lifetime, Lifetime,
513-
OnAccessor | OnConstructor | OnFunc | OnSubscript | LongAttribute | ABIBreakingToAdd | ABIStableToRemove | APIBreakingToAdd | APIStableToRemove,
513+
OnAccessor | OnConstructor | OnFunc | OnSubscript | LongAttribute | ABIBreakingToAdd | ABIStableToRemove | APIBreakingToAdd | APIStableToRemove | AllowMultipleAttributes,
514514
161)
515515

516516
LAST_DECL_ATTR(Lifetime)

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7948,9 +7948,9 @@ ERROR(pack_iteration_where_clause_not_supported, none,
79487948
//------------------------------------------------------------------------------
79497949

79507950
ERROR(lifetime_dependence_invalid_param_name, none,
7951-
"invalid parameter name specified %0", (Identifier))
7951+
"invalid parameter name specified '%0'", (StringRef))
79527952
ERROR(lifetime_dependence_invalid_param_index, none,
7953-
"invalid parameter index specified %0", (unsigned))
7953+
"invalid parameter index specified '%0'", (unsigned))
79547954
ERROR(lifetime_dependence_invalid_self_in_static, none,
79557955
"invalid lifetime dependence specifier on non-existent self", ())
79567956
ERROR(lifetime_dependence_invalid_self_in_init, none,
@@ -7992,7 +7992,7 @@ ERROR(lifetime_dependence_cannot_infer_ambiguous_candidate, none,
79927992
"Escapable",
79937993
())
79947994
ERROR(lifetime_dependence_immortal_conflict_name, none,
7995-
"conflict between the parameter name and immortal keyword", ())
7995+
"conflict between the parameter name and 'immortal' contextual keyword", ())
79967996
ERROR(lifetime_dependence_function_type, none,
79977997
"lifetime dependencies on function types are not supported",
79987998
())
@@ -8005,6 +8005,8 @@ ERROR(lifetime_dependence_invalid_inherit_escapable_type, none,
80058005
ERROR(lifetime_dependence_cannot_use_parsed_borrow_consuming, none,
80068006
"invalid use of borrow dependence with consuming ownership",
80078007
())
8008+
ERROR(lifetime_dependence_duplicate_target, none,
8009+
"invalid duplicate target lifetime dependencies on function", ())
80088010

80098011
//===----------------------------------------------------------------------===//
80108012
// MARK: Sending

include/swift/AST/LifetimeDependence.h

Lines changed: 125 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "swift/Basic/SourceLoc.h"
2727

2828
#include "llvm/ADT/ArrayRef.h"
29+
#include "llvm/Support/TrailingObjects.h"
2930

3031
namespace swift {
3132

@@ -43,102 +44,162 @@ enum class ParsedLifetimeDependenceKind : uint8_t {
4344

4445
enum class LifetimeDependenceKind : uint8_t { Inherit = 0, Scope };
4546

46-
enum class LifetimeEntryKind { Named, Ordered, Self, Immortal };
47-
48-
class LifetimeEntry {
49-
private:
50-
SourceLoc loc;
51-
LifetimeEntryKind lifetimeEntryKind;
52-
ParsedLifetimeDependenceKind parsedLifetimeDependenceKind;
47+
struct LifetimeDescriptor {
5348
union Value {
5449
struct {
55-
Identifier name;
50+
StringRef name;
5651
} Named;
5752
struct {
5853
unsigned index;
5954
} Ordered;
6055
struct {
61-
} self;
62-
Value(Identifier name) : Named({name}) {}
56+
} Self;
57+
Value(StringRef name) : Named({name}) {}
6358
Value(unsigned index) : Ordered({index}) {}
64-
Value() {}
59+
Value() : Self() {}
6560
} value;
6661

67-
LifetimeEntry(SourceLoc loc, LifetimeEntryKind lifetimeEntryKind,
68-
ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
69-
Value value)
70-
: loc(loc), lifetimeEntryKind(lifetimeEntryKind),
71-
parsedLifetimeDependenceKind(parsedLifetimeDependenceKind),
72-
value(value) {}
62+
enum class DescriptorKind { Named, Ordered, Self } kind;
7363

74-
public:
75-
static LifetimeEntry
76-
getNamedLifetimeEntry(SourceLoc loc, Identifier name,
77-
ParsedLifetimeDependenceKind kind =
78-
ParsedLifetimeDependenceKind::Default) {
79-
return {loc, LifetimeEntryKind::Named, kind, name};
80-
}
64+
ParsedLifetimeDependenceKind parsedLifetimeDependenceKind;
8165

82-
static LifetimeEntry getImmortalLifetimeEntry(SourceLoc loc) {
83-
return {loc, LifetimeEntryKind::Immortal, {}, {}};
84-
}
66+
SourceLoc loc;
8567

86-
static LifetimeEntry
87-
getOrderedLifetimeEntry(SourceLoc loc, unsigned index,
88-
ParsedLifetimeDependenceKind kind =
89-
ParsedLifetimeDependenceKind::Default) {
90-
return {loc, LifetimeEntryKind::Ordered, kind, index};
91-
}
68+
private:
69+
LifetimeDescriptor(StringRef name,
70+
ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
71+
SourceLoc loc)
72+
: value{name}, kind(DescriptorKind::Named),
73+
parsedLifetimeDependenceKind(parsedLifetimeDependenceKind), loc(loc) {}
74+
LifetimeDescriptor(unsigned index,
75+
ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
76+
SourceLoc loc)
77+
: value{index}, kind(DescriptorKind::Ordered),
78+
parsedLifetimeDependenceKind(parsedLifetimeDependenceKind), loc(loc) {}
79+
LifetimeDescriptor(ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
80+
SourceLoc loc)
81+
: value{}, kind(DescriptorKind::Self),
82+
parsedLifetimeDependenceKind(parsedLifetimeDependenceKind), loc(loc) {}
9283

93-
static LifetimeEntry
94-
getSelfLifetimeEntry(SourceLoc loc,
95-
ParsedLifetimeDependenceKind kind =
96-
ParsedLifetimeDependenceKind::Default) {
97-
return {loc, LifetimeEntryKind::Self, kind, {}};
84+
public:
85+
static LifetimeDescriptor
86+
forNamed(StringRef name,
87+
ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
88+
SourceLoc loc) {
89+
return {name, parsedLifetimeDependenceKind, loc};
90+
}
91+
static LifetimeDescriptor
92+
forOrdered(unsigned index,
93+
ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
94+
SourceLoc loc) {
95+
return {index, parsedLifetimeDependenceKind, loc};
96+
}
97+
static LifetimeDescriptor
98+
forSelf(ParsedLifetimeDependenceKind parsedLifetimeDependenceKind,
99+
SourceLoc loc) {
100+
return {parsedLifetimeDependenceKind, loc};
98101
}
99-
100-
SourceLoc getLoc() const { return loc; }
101-
102-
LifetimeEntryKind getLifetimeEntryKind() const { return lifetimeEntryKind; }
103102

104103
ParsedLifetimeDependenceKind getParsedLifetimeDependenceKind() const {
105104
return parsedLifetimeDependenceKind;
106105
}
107106

108-
Identifier getName() const {
109-
assert(lifetimeEntryKind == LifetimeEntryKind::Named);
107+
StringRef getName() const {
108+
assert(kind == DescriptorKind::Named);
110109
return value.Named.name;
111110
}
112111

113112
unsigned getIndex() const {
114-
assert(lifetimeEntryKind == LifetimeEntryKind::Ordered);
113+
assert(kind == DescriptorKind::Ordered);
115114
return value.Ordered.index;
116115
}
117116

118-
std::string getParamString() const {
119-
switch (lifetimeEntryKind) {
120-
case LifetimeEntryKind::Named:
121-
return value.Named.name.str().str();
122-
case LifetimeEntryKind::Self:
117+
DescriptorKind getDescriptorKind() const { return kind; }
118+
119+
SourceLoc getLoc() const { return loc; }
120+
121+
bool isImmortal() const {
122+
if (getDescriptorKind() != LifetimeDescriptor::DescriptorKind::Named) {
123+
return false;
124+
}
125+
return getName() == "immortal";
126+
}
127+
128+
std::string getString() const {
129+
switch (kind) {
130+
case DescriptorKind::Named:
131+
return getName().str();
132+
case DescriptorKind::Ordered:
133+
return std::to_string(getIndex());
134+
case DescriptorKind::Self:
123135
return "self";
124-
case LifetimeEntryKind::Ordered:
125-
return std::to_string(value.Ordered.index);
126-
case LifetimeEntryKind::Immortal:
127-
return "immortal";
128136
}
129-
llvm_unreachable("Invalid LifetimeEntryKind");
137+
llvm_unreachable("Invalid DescriptorKind");
138+
}
139+
};
140+
141+
class LifetimeEntry final
142+
: private llvm::TrailingObjects<LifetimeEntry, LifetimeDescriptor> {
143+
friend TrailingObjects;
144+
145+
private:
146+
SourceLoc startLoc, endLoc;
147+
unsigned numSources;
148+
std::optional<LifetimeDescriptor> targetDescriptor;
149+
150+
LifetimeEntry(
151+
SourceLoc startLoc, SourceLoc endLoc,
152+
ArrayRef<LifetimeDescriptor> sources,
153+
std::optional<LifetimeDescriptor> targetDescriptor = std::nullopt)
154+
: startLoc(startLoc), endLoc(endLoc), numSources(sources.size()),
155+
targetDescriptor(targetDescriptor) {
156+
std::uninitialized_copy(sources.begin(), sources.end(),
157+
getTrailingObjects<LifetimeDescriptor>());
158+
}
159+
160+
size_t numTrailingObjects(OverloadToken<LifetimeDescriptor>) const {
161+
return numSources;
162+
}
163+
164+
public:
165+
static LifetimeEntry *
166+
create(const ASTContext &ctx, SourceLoc startLoc, SourceLoc endLoc,
167+
ArrayRef<LifetimeDescriptor> sources,
168+
std::optional<LifetimeDescriptor> targetDescriptor = std::nullopt);
169+
170+
SourceLoc getLoc() const { return startLoc; }
171+
SourceLoc getStartLoc() const { return startLoc; }
172+
SourceLoc getEndLoc() const { return endLoc; }
173+
174+
ArrayRef<LifetimeDescriptor> getSources() const {
175+
return {getTrailingObjects<LifetimeDescriptor>(), numSources};
176+
}
177+
178+
std::optional<LifetimeDescriptor> getTargetDescriptor() const {
179+
return targetDescriptor;
130180
}
131181

132-
std::string getDependsOnString() const {
133-
switch (parsedLifetimeDependenceKind) {
134-
case ParsedLifetimeDependenceKind::Default:
135-
return "dependsOn(" + getParamString() + ")";
136-
case ParsedLifetimeDependenceKind::Scope:
137-
return "dependsOn(scoped " + getParamString() + ")";
138-
case ParsedLifetimeDependenceKind::Inherit:
139-
return "dependsOn(inherited " + getParamString() + ")";
182+
std::string getString() const {
183+
std::string result = "@lifetime(";
184+
if (targetDescriptor.has_value()) {
185+
result += targetDescriptor->getString();
186+
result += ": ";
187+
}
188+
189+
bool firstElem = true;
190+
for (auto source : getSources()) {
191+
if (!firstElem) {
192+
result += ", ";
193+
}
194+
if (source.getParsedLifetimeDependenceKind() ==
195+
ParsedLifetimeDependenceKind::Scope) {
196+
result += "borrow ";
197+
}
198+
result += source.getString();
199+
firstElem = false;
140200
}
141-
llvm_unreachable("Invalid LifetimeEntry::ParsedLifetimeDependenceKind");
201+
result += ")";
202+
return result;
142203
}
143204
};
144205

@@ -157,11 +218,6 @@ class LifetimeDependenceInfo {
157218
static std::optional<ArrayRef<LifetimeDependenceInfo>>
158219
fromLifetimeAttribute(AbstractFunctionDecl *afd);
159220

160-
/// Builds LifetimeDependenceInfo from dependsOn type modifier
161-
static std::optional<LifetimeDependenceInfo>
162-
fromDependsOn(AbstractFunctionDecl *afd, TypeRepr *targetRepr,
163-
Type targetType, unsigned targetIndex);
164-
165221
/// Infer LifetimeDependenceInfo on result
166222
static std::optional<LifetimeDependenceInfo> infer(AbstractFunctionDecl *afd);
167223

include/swift/AST/TypeRepr.h

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,6 @@ class alignas(1 << TypeReprAlignInBits) TypeRepr
111111
/// The number of elements contained.
112112
NumElements : 32
113113
);
114-
115-
SWIFT_INLINE_BITFIELD_FULL(LifetimeDependentTypeRepr, TypeRepr, 32,
116-
: NumPadBits,
117-
NumDependencies : 32
118-
);
119114
} Bits;
120115
// clang-format on
121116

@@ -1531,32 +1526,19 @@ class SILBoxTypeRepr final : public TypeRepr,
15311526
friend TypeRepr;
15321527
};
15331528

1534-
class LifetimeDependentTypeRepr final
1535-
: public SpecifierTypeRepr,
1536-
private llvm::TrailingObjects<LifetimeDependentTypeRepr, LifetimeEntry> {
1537-
friend TrailingObjects;
1538-
1539-
size_t numTrailingObjects(OverloadToken<LifetimeDependentTypeRepr>) const {
1540-
return Bits.LifetimeDependentTypeRepr.NumDependencies;
1541-
}
1529+
class LifetimeDependentTypeRepr final : public SpecifierTypeRepr {
1530+
LifetimeEntry *entry;
15421531

15431532
public:
1544-
LifetimeDependentTypeRepr(TypeRepr *base, ArrayRef<LifetimeEntry> specifiers)
1533+
LifetimeDependentTypeRepr(TypeRepr *base, LifetimeEntry *entry)
15451534
: SpecifierTypeRepr(TypeReprKind::LifetimeDependent, base,
1546-
specifiers.front().getLoc()) {
1547-
assert(base);
1548-
Bits.LifetimeDependentTypeRepr.NumDependencies = specifiers.size();
1549-
std::uninitialized_copy(specifiers.begin(), specifiers.end(),
1550-
getTrailingObjects<LifetimeEntry>());
1551-
}
1535+
entry->getLoc()),
1536+
entry(entry) {}
15521537

15531538
static LifetimeDependentTypeRepr *create(ASTContext &C, TypeRepr *base,
1554-
ArrayRef<LifetimeEntry> specifiers);
1539+
LifetimeEntry *entry);
15551540

1556-
ArrayRef<LifetimeEntry> getLifetimeDependencies() const {
1557-
return {getTrailingObjects<LifetimeEntry>(),
1558-
Bits.LifetimeDependentTypeRepr.NumDependencies};
1559-
}
1541+
LifetimeEntry *getLifetimeEntry() const { return entry; }
15601542

15611543
static bool classof(const TypeRepr *T) {
15621544
return T->getKind() == TypeReprKind::LifetimeDependent;

0 commit comments

Comments
 (0)