Skip to content

Commit 728be36

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) (cherry picked from commit ae31edc)
1 parent f589a7f commit 728be36

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
@@ -529,6 +529,9 @@ EXPERIMENTAL_FEATURE(DefaultIsolationPerFile, false)
529529
/// Enable @_lifetime attribute
530530
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(Lifetimes, true)
531531

532+
/// Enable UnsafeMutablePointer.mutableSpan
533+
EXPERIMENTAL_FEATURE(NonescapableAccessorOnTrivial, true)
534+
532535
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
533536
#undef EXPERIMENTAL_FEATURE
534537
#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
@@ -334,9 +334,26 @@ static bool usesFeatureLifetimeDependenceMutableAccessors(Decl *decl) {
334334
return false;
335335
}
336336
if (auto dc = var->getDeclContext()) {
337-
if (auto nominal = dc->getSelfNominalTypeDecl()) {
338-
auto sig = nominal->getGenericSignature();
339-
return !var->getInterfaceType()->isEscapable(sig);
337+
auto sig = dc->getGenericSignatureOfContext();
338+
return !var->getInterfaceType()->isEscapable(sig);
339+
}
340+
return false;
341+
}
342+
343+
static bool usesFeatureNonescapableAccessorOnTrivial(Decl *decl) {
344+
if (!isa<VarDecl>(decl)) {
345+
return false;
346+
}
347+
auto var = cast<VarDecl>(decl);
348+
if (!var->hasParsedAccessors()) {
349+
return false;
350+
}
351+
if (auto dc = var->getDeclContext()) {
352+
auto sig = dc->getGenericSignatureOfContext();
353+
if (!var->getInterfaceType()->isEscapable(sig)) {
354+
auto selfTy = dc->getSelfTypeInContext();
355+
// Consider 'self' trivial if it is BitwiseCopyable and Escapable.
356+
return selfTy->isBitwiseCopyable() && selfTy->isEscapable();
340357
}
341358
}
342359
return false;

0 commit comments

Comments
 (0)