Skip to content

Commit ae31edc

Browse files
committed
Add Feature: NonescapableAccessorOnTrivial
To guard the new UnsafeMutablePointer.mutableSpan APIs. This allows older compilers to ignore the new APIs. Otherwise, the type checker will crash on the synthesized _read accessor for a non-Escapable type: error: cannot infer lifetime dependence on the '_read' accessor because 'self' is BitwiseCopyable, specify '@Lifetime(borrow self)' I don't know why the _read is synthesized in these cases, but apparently it's always been that way. Fixes: rdar://153773093 ([nonescapable] add a compiler feature to guard ~Escapable accessors when self is trivial)
1 parent 5eb85ac commit ae31edc

File tree

4 files changed

+48
-3
lines changed

4 files changed

+48
-3
lines changed

include/swift/AST/Types.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,13 @@ class alignas(1 << TypeAlignInBits) TypeBase
700700
/// Returns true if this contextual type is (Escapable && !isNoEscape).
701701
bool mayEscape() { return !isNoEscape() && isEscapable(); }
702702

703+
/// Returns true if this contextual type satisfies a conformance to Escapable.
704+
bool isBitwiseCopyable();
705+
706+
/// Returns true if this type satisfies a conformance to Escapable in the
707+
/// given generic signature.
708+
bool isBitwiseCopyable(GenericSignature sig);
709+
703710
/// Are values of this type essentially just class references,
704711
/// possibly with some sort of additional information?
705712
///

include/swift/Basic/Features.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,9 @@ EXPERIMENTAL_FEATURE(DefaultIsolationPerFile, false)
530530
/// Enable @_lifetime attribute
531531
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(Lifetimes, true)
532532

533+
/// Enable UnsafeMutablePointer.mutableSpan
534+
EXPERIMENTAL_FEATURE(NonescapableAccessorOnTrivial, true)
535+
533536
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
534537
#undef EXPERIMENTAL_FEATURE
535538
#undef UPCOMING_FEATURE

lib/AST/ConformanceLookup.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,3 +963,21 @@ bool TypeBase::isEscapable(GenericSignature sig) {
963963
}
964964
return contextTy->isEscapable();
965965
}
966+
967+
bool TypeBase::isBitwiseCopyable() {
968+
auto &ctx = getASTContext();
969+
auto *bitwiseCopyableProtocol =
970+
ctx.getProtocol(KnownProtocolKind::BitwiseCopyable);
971+
if (!bitwiseCopyableProtocol) {
972+
return false;
973+
}
974+
return (bool)checkConformance(this, bitwiseCopyableProtocol);
975+
}
976+
977+
bool TypeBase::isBitwiseCopyable(GenericSignature sig) {
978+
Type contextTy = this;
979+
if (sig) {
980+
contextTy = sig.getGenericEnvironment()->mapTypeIntoContext(contextTy);
981+
}
982+
return contextTy->isBitwiseCopyable();
983+
}

lib/AST/FeatureSet.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,26 @@ static bool usesFeatureLifetimeDependenceMutableAccessors(Decl *decl) {
335335
return false;
336336
}
337337
if (auto dc = var->getDeclContext()) {
338-
if (auto nominal = dc->getSelfNominalTypeDecl()) {
339-
auto sig = nominal->getGenericSignature();
340-
return !var->getInterfaceType()->isEscapable(sig);
338+
auto sig = dc->getGenericSignatureOfContext();
339+
return !var->getInterfaceType()->isEscapable(sig);
340+
}
341+
return false;
342+
}
343+
344+
static bool usesFeatureNonescapableAccessorOnTrivial(Decl *decl) {
345+
if (!isa<VarDecl>(decl)) {
346+
return false;
347+
}
348+
auto var = cast<VarDecl>(decl);
349+
if (!var->hasParsedAccessors()) {
350+
return false;
351+
}
352+
if (auto dc = var->getDeclContext()) {
353+
auto sig = dc->getGenericSignatureOfContext();
354+
if (!var->getInterfaceType()->isEscapable(sig)) {
355+
auto selfTy = dc->getSelfTypeInContext();
356+
// Consider 'self' trivial if it is BitwiseCopyable and Escapable.
357+
return selfTy->isBitwiseCopyable() && selfTy->isEscapable();
341358
}
342359
}
343360
return false;

0 commit comments

Comments
 (0)