Skip to content

Commit 0cb805b

Browse files
committed
Add Sema support for LifetimeDependence
1 parent d37b0cf commit 0cb805b

14 files changed

+426
-4
lines changed

include/swift/AST/DiagnosticsSema.def

+18
Original file line numberDiff line numberDiff line change
@@ -7765,5 +7765,23 @@ ERROR(result_depends_on_no_result,none,
77657765
ERROR(pack_iteration_where_clause_not_supported, none,
77667766
"'where' clause in pack iteration is not supported", ())
77677767

7768+
7769+
//------------------------------------------------------------------------------
7770+
// MARK: Lifetime Dependence Diagnostics
7771+
//------------------------------------------------------------------------------
7772+
7773+
ERROR(lifetime_dependence_invalid_param_name, none,
7774+
"invalid parameter name specified %0", (Identifier))
7775+
ERROR(lifetime_dependence_invalid_param_index, none,
7776+
"invalid parameter index specified %0", (unsigned))
7777+
ERROR(lifetime_dependence_invalid_self, none,
7778+
"invalid lifetime dependence specifier, self is valid in non-static "
7779+
"methods only", ())
7780+
ERROR(lifetime_dependence_duplicate_param_id, none,
7781+
"duplicate lifetime dependence specifier", ())
7782+
ERROR(lifetime_dependence_cannot_use_kind, none,
7783+
"invalid use of %0 lifetime dependence for %1 ownership",
7784+
(StringRef, StringRef))
7785+
77687786
#define UNDEFINE_DIAGNOSTIC_MACROS
77697787
#include "DefineDiagnosticMacros.h"

include/swift/AST/ExtInfo.h

+21
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,27 @@ class ClangTypeInfo {
8585
void dump(llvm::raw_ostream &os, const clang::ASTContext &ctx) const;
8686
};
8787

88+
class LifetimeDependenceInfo {
89+
IndexSubset *copyLifetimeParamIndices;
90+
IndexSubset *borrowLifetimeParamIndices;
91+
92+
public:
93+
LifetimeDependenceInfo()
94+
: copyLifetimeParamIndices(nullptr), borrowLifetimeParamIndices(nullptr) {
95+
}
96+
LifetimeDependenceInfo(IndexSubset *copyLifetimeParamIndices,
97+
IndexSubset *borrowLifetimeParamIndices)
98+
: copyLifetimeParamIndices(copyLifetimeParamIndices),
99+
borrowLifetimeParamIndices(borrowLifetimeParamIndices) {}
100+
101+
operator bool() const { return empty(); }
102+
103+
bool empty() const {
104+
return copyLifetimeParamIndices == nullptr &&
105+
borrowLifetimeParamIndices == nullptr;
106+
}
107+
};
108+
88109
// MARK: - UnexpectedClangTypeError
89110
/// Potential errors when trying to store a Clang type in an ExtInfo.
90111
struct UnexpectedClangTypeError {

include/swift/AST/LifetimeDependence.h

+11
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,17 @@ class LifetimeDependenceSpecifier {
9393
assert(specifierKind == SpecifierKind::Ordered);
9494
return value.Ordered.index;
9595
}
96+
std::string getParamString() const {
97+
switch (specifierKind) {
98+
case SpecifierKind::Named:
99+
return value.Named.name.str().str();
100+
case SpecifierKind::Self:
101+
return "self";
102+
case SpecifierKind::Ordered:
103+
return std::to_string(value.Ordered.index);
104+
}
105+
llvm_unreachable("Invalid LifetimeDependenceSpecifier::SpecifierKind");
106+
}
96107
};
97108
} // namespace swift
98109

include/swift/AST/Ownership.h

+13
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,19 @@ enum class ValueOwnership : uint8_t {
142142
enum : unsigned { NumValueOwnershipBits =
143143
countBitsUsed(static_cast<unsigned>(ValueOwnership::Last_Kind)) };
144144

145+
static inline llvm::StringRef getOwnershipSpelling(ValueOwnership ownership) {
146+
switch (ownership) {
147+
case ValueOwnership::Default:
148+
return "";
149+
case ValueOwnership::InOut:
150+
return "inout";
151+
case ValueOwnership::Shared:
152+
return "borrowing";
153+
case ValueOwnership::Owned:
154+
return "consuming";
155+
}
156+
llvm_unreachable("Invalid ValueOwnership");
157+
}
145158
} // end namespace swift
146159

147160
#endif

include/swift/AST/TypeRepr.h

+55-4
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@
2222
#include "swift/AST/DiagnosticEngine.h"
2323
#include "swift/AST/GenericSignature.h"
2424
#include "swift/AST/Identifier.h"
25+
#include "swift/AST/LifetimeDependence.h"
2526
#include "swift/AST/Type.h"
2627
#include "swift/AST/TypeAlignments.h"
28+
#include "swift/Basic/Debug.h"
29+
#include "swift/Basic/InlineBitfield.h"
30+
#include "swift/Basic/Located.h"
2731
#include "llvm/ADT/ArrayRef.h"
2832
#include "llvm/ADT/PointerUnion.h"
2933
#include "llvm/ADT/STLExtras.h"
30-
#include "swift/Basic/Debug.h"
31-
#include "swift/Basic/Located.h"
32-
#include "swift/Basic/InlineBitfield.h"
3334
#include "llvm/Support/ErrorHandling.h"
3435
#include "llvm/Support/TrailingObjects.h"
3536

@@ -109,6 +110,10 @@ class alignas(1 << TypeReprAlignInBits) TypeRepr
109110
NumElements : 32
110111
);
111112

113+
SWIFT_INLINE_BITFIELD_FULL(LifetimeDependentReturnTypeRepr, TypeRepr, 32,
114+
: NumPadBits,
115+
NumDependencies : 32
116+
);
112117
} Bits;
113118
// clang-format on
114119

@@ -1093,7 +1098,8 @@ class SpecifierTypeRepr : public TypeRepr {
10931098
return T->getKind() == TypeReprKind::Ownership ||
10941099
T->getKind() == TypeReprKind::Isolated ||
10951100
T->getKind() == TypeReprKind::CompileTimeConst ||
1096-
T->getKind() == TypeReprKind::ResultDependsOn;
1101+
T->getKind() == TypeReprKind::ResultDependsOn ||
1102+
T->getKind() == TypeReprKind::LifetimeDependentReturn;
10971103
}
10981104
static bool classof(const SpecifierTypeRepr *T) { return true; }
10991105

@@ -1505,6 +1511,50 @@ class SILBoxTypeRepr final : public TypeRepr,
15051511
friend TypeRepr;
15061512
};
15071513

1514+
class LifetimeDependentReturnTypeRepr final
1515+
: public SpecifierTypeRepr,
1516+
private llvm::TrailingObjects<LifetimeDependentReturnTypeRepr,
1517+
LifetimeDependenceSpecifier> {
1518+
friend TrailingObjects;
1519+
1520+
size_t
1521+
numTrailingObjects(OverloadToken<LifetimeDependentReturnTypeRepr>) const {
1522+
return Bits.LifetimeDependentReturnTypeRepr.NumDependencies;
1523+
}
1524+
1525+
public:
1526+
LifetimeDependentReturnTypeRepr(
1527+
TypeRepr *base, ArrayRef<LifetimeDependenceSpecifier> specifiers)
1528+
: SpecifierTypeRepr(TypeReprKind::LifetimeDependentReturn, base,
1529+
specifiers.front().getLoc()) {
1530+
assert(base);
1531+
Bits.LifetimeDependentReturnTypeRepr.NumDependencies = specifiers.size();
1532+
std::uninitialized_copy(specifiers.begin(), specifiers.end(),
1533+
getTrailingObjects<LifetimeDependenceSpecifier>());
1534+
}
1535+
1536+
static LifetimeDependentReturnTypeRepr *
1537+
create(ASTContext &C, TypeRepr *base,
1538+
ArrayRef<LifetimeDependenceSpecifier> specifiers);
1539+
1540+
ArrayRef<LifetimeDependenceSpecifier> getLifetimeDependencies() const {
1541+
return {getTrailingObjects<LifetimeDependenceSpecifier>(),
1542+
Bits.LifetimeDependentReturnTypeRepr.NumDependencies};
1543+
}
1544+
1545+
static bool classof(const TypeRepr *T) {
1546+
return T->getKind() == TypeReprKind::LifetimeDependentReturn;
1547+
}
1548+
static bool classof(const LifetimeDependentReturnTypeRepr *T) { return true; }
1549+
1550+
private:
1551+
SourceLoc getStartLocImpl() const;
1552+
SourceLoc getEndLocImpl() const;
1553+
SourceLoc getLocImpl() const;
1554+
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
1555+
friend class TypeRepr;
1556+
};
1557+
15081558
inline bool TypeRepr::isSimple() const {
15091559
// NOTE: Please keep this logic in sync with TypeBase::hasSimpleTypeRepr().
15101560
switch (getKind()) {
@@ -1539,6 +1589,7 @@ inline bool TypeRepr::isSimple() const {
15391589
case TypeReprKind::Placeholder:
15401590
case TypeReprKind::CompileTimeConst:
15411591
case TypeReprKind::ResultDependsOn:
1592+
case TypeReprKind::LifetimeDependentReturn:
15421593
return true;
15431594
}
15441595
llvm_unreachable("bad TypeRepr kind");

include/swift/AST/TypeReprNodes.def

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ ABSTRACT_TYPEREPR(Specifier, TypeRepr)
7777
TYPEREPR(Fixed, TypeRepr)
7878
TYPEREPR(SILBox, TypeRepr)
7979
TYPEREPR(Self, TypeRepr)
80+
TYPEREPR(LifetimeDependentReturn, TypeRepr)
8081
LAST_TYPEREPR(Self)
8182

8283
#undef SPECIFIER_TYPEREPR

lib/AST/ASTDumper.cpp

+29
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,20 @@ static size_t getDumpString(size_t value) {
447447
}
448448
static void *getDumpString(void *value) { return value; }
449449

450+
static StringRef getDumpString(LifetimeDependenceKind kind) {
451+
switch (kind) {
452+
case LifetimeDependenceKind::Copy:
453+
return "copy";
454+
case LifetimeDependenceKind::Consume:
455+
return "consume";
456+
case LifetimeDependenceKind::Borrow:
457+
return "borrow";
458+
case LifetimeDependenceKind::Mutate:
459+
return "mutate";
460+
}
461+
llvm_unreachable("Invalid lifetime dependence kind\n");
462+
}
463+
450464
//===----------------------------------------------------------------------===//
451465
// Decl printing.
452466
//===----------------------------------------------------------------------===//
@@ -3514,6 +3528,21 @@ class PrintTypeRepr : public TypeReprVisitor<PrintTypeRepr, void, StringRef>,
35143528

35153529
printFoot();
35163530
}
3531+
3532+
void visitLifetimeDependentReturnTypeRepr(LifetimeDependentReturnTypeRepr *T,
3533+
StringRef label) {
3534+
printCommon("type_lifetime_dependent_return", label);
3535+
for (auto &dep : T->getLifetimeDependencies()) {
3536+
printFieldRaw(
3537+
[&](raw_ostream &out) {
3538+
out << getDumpString(dep.getLifetimeDependenceKind()) << "(";
3539+
out << dep.getParamString() << ")";
3540+
},
3541+
"");
3542+
}
3543+
printRec(T->getBase());
3544+
printFoot();
3545+
}
35173546
};
35183547

35193548
void PrintBase::printRec(Decl *D, StringRef label) {

lib/AST/ASTWalker.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -2266,6 +2266,11 @@ bool Traversal::visitSILBoxTypeRepr(SILBoxTypeRepr *T) {
22662266
return false;
22672267
}
22682268

2269+
bool Traversal::visitLifetimeDependentReturnTypeRepr(
2270+
LifetimeDependentReturnTypeRepr *T) {
2271+
return doIt(T->getBase());
2272+
}
2273+
22692274
Expr *Expr::walk(ASTWalker &walker) {
22702275
return Traversal(walker).doIt(this);
22712276
}

lib/AST/NameLookup.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -3047,6 +3047,7 @@ directReferencesForTypeRepr(Evaluator &evaluator,
30473047
case TypeReprKind::Existential:
30483048
case TypeReprKind::Inverse:
30493049
case TypeReprKind::ResultDependsOn:
3050+
case TypeReprKind::LifetimeDependentReturn:
30503051
return { };
30513052

30523053
case TypeReprKind::Fixed:

lib/AST/TypeRepr.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,31 @@ SourceLoc SILBoxTypeRepr::getLocImpl() const {
470470
return LBraceLoc;
471471
}
472472

473+
LifetimeDependentReturnTypeRepr *LifetimeDependentReturnTypeRepr::create(
474+
ASTContext &C, TypeRepr *base,
475+
ArrayRef<LifetimeDependenceSpecifier> specifiers) {
476+
auto size = totalSizeToAlloc<LifetimeDependenceSpecifier>(specifiers.size());
477+
auto mem = C.Allocate(size, alignof(LifetimeDependenceSpecifier));
478+
return new (mem) LifetimeDependentReturnTypeRepr(base, specifiers);
479+
}
480+
481+
SourceLoc LifetimeDependentReturnTypeRepr::getStartLocImpl() const {
482+
return getLifetimeDependencies().front().getLoc();
483+
}
484+
485+
SourceLoc LifetimeDependentReturnTypeRepr::getEndLocImpl() const {
486+
return getLifetimeDependencies().back().getLoc();
487+
}
488+
489+
SourceLoc LifetimeDependentReturnTypeRepr::getLocImpl() const {
490+
return getBase()->getLoc();
491+
}
492+
493+
void LifetimeDependentReturnTypeRepr::printImpl(
494+
ASTPrinter &Printer, const PrintOptions &Opts) const {
495+
printTypeRepr(getBase(), Printer, Opts);
496+
}
497+
473498
void VarargTypeRepr::printImpl(ASTPrinter &Printer,
474499
const PrintOptions &Opts) const {
475500
printTypeRepr(Element, Printer, Opts);

lib/Parse/ParseType.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ Parser::ParsedTypeAttributeList::applyAttributesToType(Parser &p,
5757
ty = new (p.Context) ResultDependsOnTypeRepr(ty, ResultDependsOnLoc);
5858
}
5959

60+
if (!lifetimeDependenceSpecifiers.empty()) {
61+
ty = LifetimeDependentReturnTypeRepr::create(p.Context, ty,
62+
lifetimeDependenceSpecifiers);
63+
}
6064
return ty;
6165
}
6266

0 commit comments

Comments
 (0)