Skip to content

Commit c96cfe9

Browse files
committed
treat move-only storage decls like @_borrowed
This change makes sure a _read accessor is always available for properties of move-only type. If programmers define a `get`, a `_read` will be synthesized to call it and then return a borrow of the owned value.
1 parent 796d247 commit c96cfe9

File tree

1 file changed

+22
-4
lines changed

1 file changed

+22
-4
lines changed

lib/Sema/TypeCheckStorage.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,20 @@ StoredPropertiesAndMissingMembersRequest::evaluate(Evaluator &evaluator,
282282
/// This query is careful not to trigger accessor macro expansion, which
283283
/// creates a cycle. It conservatively assumes that all accessor macros
284284
/// produce computed properties, which is... incorrect.
285+
///
286+
/// The query also avoids triggering a `StorageImplInfoRequest` for patterns
287+
/// involved in a ProtocolDecl, because we know they can never contain storage.
288+
/// For background, vars of noncopyable type have their OpaqueReadOwnership
289+
/// determined by the type of the var decl, but that type hasn't always been
290+
/// determined when this query is made.
285291
static bool mayHaveStorage(Pattern *pattern) {
286-
// Check whether there are any accessor macros.
292+
// Check whether there are any accessor macros, or it's a protocol member.
287293
bool hasAccessorMacros = false;
294+
bool inProtocolDecl = false;
288295
pattern->forEachVariable([&](VarDecl *VD) {
296+
if (isa<ProtocolDecl>(VD->getDeclContext()))
297+
inProtocolDecl = true;
298+
289299
VD->forEachAttachedMacro(MacroRole::Accessor,
290300
[&](CustomAttr *customAttr, MacroDecl *macro) {
291301
hasAccessorMacros = true;
@@ -295,6 +305,10 @@ static bool mayHaveStorage(Pattern *pattern) {
295305
if (hasAccessorMacros)
296306
return false;
297307

308+
// protocol members can never contain storage; avoid triggering request.
309+
if (inProtocolDecl)
310+
return false;
311+
298312
return pattern->hasStorage();
299313
}
300314

@@ -599,9 +613,13 @@ IsSetterMutatingRequest::evaluate(Evaluator &evaluator,
599613
OpaqueReadOwnership
600614
OpaqueReadOwnershipRequest::evaluate(Evaluator &evaluator,
601615
AbstractStorageDecl *storage) const {
602-
return (storage->getAttrs().hasAttribute<BorrowedAttr>()
603-
? OpaqueReadOwnership::Borrowed
604-
: OpaqueReadOwnership::Owned);
616+
if (storage->getAttrs().hasAttribute<BorrowedAttr>())
617+
return OpaqueReadOwnership::Borrowed;
618+
619+
if (storage->getValueInterfaceType()->isPureMoveOnly())
620+
return OpaqueReadOwnership::Borrowed;
621+
622+
return OpaqueReadOwnership::Owned;
605623
}
606624

607625
/// Insert the specified decl into the DeclContext's member list. If the hint

0 commit comments

Comments
 (0)