[NCGenerics] ensure builtins are Escapable

This commit is contained in:
Kavon Farvardin
2023-12-12 23:09:42 -08:00
parent 5e0bcabc8b
commit 0c5748fa15
3 changed files with 47 additions and 8 deletions

View File

@@ -1828,13 +1828,20 @@ static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance(
/// appropriate.
static ProtocolConformanceRef getBuiltinBuiltinTypeConformance(
Type type, const BuiltinType *builtinType, ProtocolDecl *protocol) {
// All builtin are Sendable and Copyable
if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable) ||
protocol->isSpecificProtocol(KnownProtocolKind::Copyable)) {
ASTContext &ctx = protocol->getASTContext();
return ProtocolConformanceRef(
ctx.getBuiltinConformance(type, protocol,
// All builtin are Sendable, Copyable, and Escapable
if (auto kp = protocol->getKnownProtocolKind()) {
switch (*kp) {
case KnownProtocolKind::Sendable:
case KnownProtocolKind::Copyable:
case KnownProtocolKind::Escapable: {
ASTContext &ctx = protocol->getASTContext();
return ProtocolConformanceRef(
ctx.getBuiltinConformance(type, protocol,
BuiltinConformanceKind::Synthesized));
}
default:
break;
}
}
return ProtocolConformanceRef::forMissingOrInvalid(type, protocol);

View File

@@ -301,8 +301,11 @@ void InverseRequirement::expandDefaults(
for (auto gp : gps) {
auto protos = InverseRequirement::expandDefault(gp);
for (auto ip : protos) {
auto protoTy =
ctx.getProtocol(getKnownProtocolKind(ip))->getDeclaredInterfaceType();
auto proto = ctx.getProtocol(getKnownProtocolKind(ip));
if (!proto)
llvm_unreachable("failed to load Copyable/Escapable/etc from stdlib!");
auto protoTy = proto->getDeclaredInterfaceType();
result.push_back({{RequirementKind::Conformance, gp, protoTy},
SourceLoc(),
/*inferred=*/true,

View File

@@ -0,0 +1,29 @@
// RUN: %target-typecheck-verify-swift -parse-stdlib -module-name Swift -enable-experimental-feature BuiltinModule -enable-experimental-feature NoncopyableGenerics -enable-experimental-feature NonEscapableTypes
// REQUIRES: asserts
/// This test specifically covers constructs that are only valid in the stdlib.
import Builtin
@_marker public protocol Copyable: ~Escapable {}
@_marker public protocol Escapable: ~Copyable {}
struct NC: ~Copyable {}
@frozen public struct UnsafePointer<T: ~Copyable>: Copyable {
var value: Builtin.RawPointer
}
@frozen
public enum Optional<T: ~Copyable> {
case some(T)
case none
}
public func wrapping<T: ~Copyable>(_ t: consuming T) -> T? {
return .some(t)
}
// No ownership required.
func checkCopyability(_ t: UnsafePointer<NC>) {}